diff --git a/public/asset-manifest.json b/public/asset-manifest.json index 66a9b3e..94fe1b9 100644 --- a/public/asset-manifest.json +++ b/public/asset-manifest.json @@ -1,6 +1,6 @@ { "core.min.js": "core.c5bd53363a.min.js", - "vendor.min.js": "vendor.af902bc3b4.min.js", + "vendor.min.js": "vendor.741a424da5.min.js", "mermaid.min.js": "mermaid.f848a72d16.min.js", "all.min.css": "all.076c089579.min.css", "markdown.min.js": "markdown.ad7b1d71c3.min.js", diff --git a/public/partials/anonymize.htm b/public/partials/anonymize.htm index 1da9f9f..2a2e8ad 100644 --- a/public/partials/anonymize.htm +++ b/public/partials/anonymize.htm @@ -63,7 +63,7 @@ -
Loading GitHub info for "+k.repoId+"..."),t.get("/api/admin/repos/"+k.repoId+"/github").then(R=>{b&&(b.document.open(),b.document.write('
'+JSON.stringify(R.data,null,2).replace(/[<>]/g,N=>N==="<"?"<":">")+""),b.document.close())},R=>{let N=R&&R.data?JSON.stringify(R.data,null,2):String(R);b&&(b.document.body.innerHTML='
'+N+"")})},e.statusCountFor=k=>{let b=(e.statusCounts||[]).find(R=>R._id===k);return b?b.count:0},e.statusStorageFor=k=>{let b=(e.statusCounts||[]).find(R=>R._id===k);return b?b.storage:0},e.isErrorsOnly=()=>e.query&&e.query.error&&!e.query.ready&&!e.query.preparing&&!e.query.expired&&!e.query.removed,e.toggleErrorsOnly=()=>{e.isErrorsOnly()?Object.assign(e.query,{ready:!1,preparing:!0,expired:!1,removed:!1,error:!0}):Object.assign(e.query,{ready:!1,preparing:!1,expired:!1,removed:!1,error:!0}),e.query.page=1},e.toggleSortDirection=()=>{e.query.direction=e.query.direction==="asc"?"desc":"asc"},e.sortBy=k=>{e.query.sort===k?e.query.direction=e.query.direction==="asc"?"desc":"asc":(e.query.sort=k,e.query.direction="desc"),e.query.page=1},e.sortIcon=k=>e.query.sort===k?e.query.direction==="asc"?"fa-arrow-up":"fa-arrow-down":"";let u="admin.repos.filterPrefs",p={page:1,limit:25,sort:"lastView",direction:"desc",search:"",owner:"",conference:"",dateFrom:"",dateTo:"",ready:!1,expired:!1,removed:!1,error:!0,preparing:!0},h=loadFilterPrefs(u)||{};e.query=Object.assign({},p,h,{page:1,search:""});let v=o.search();v.owner&&(e.query.owner=v.owner),v.conference&&(e.query.conference=v.conference),v.search&&(e.query.search=v.search);let g="admin.repos.presets";e.presets=JSON.parse(localStorage.getItem(g)||"[]"),e.savePreset=()=>{let k=window.prompt("Preset name:");if(!k)return;let b=Object.assign({},e.query);delete b.page,e.presets=(e.presets||[]).filter(R=>R.name!==k),e.presets.push({name:k,query:b}),localStorage.setItem(g,JSON.stringify(e.presets))},e.applyPreset=k=>{Object.assign(e.query,k.query,{page:1})},e.deletePreset=k=>{e.presets=(e.presets||[]).filter(b=>b.name!==k.name),localStorage.setItem(g,JSON.stringify(e.presets))},e.selectAllOnPage=()=>{e.allSelected=!e.allSelected,e.repositories.forEach(k=>{e.selected[k.repoId]=e.allSelected})},e.selectedCount=()=>Object.values(e.selected||{}).filter(Boolean).length,e.selectedRepos=()=>e.repositories.filter(k=>e.selected[k.repoId]),e.bulkRefresh=()=>{let k=e.selectedRepos();k.length&&confirm(`Force refresh ${k.length} repositories?`)&&k.forEach(b=>e.updateRepository(b))},e.bulkRemoveCache=()=>{let k=e.selectedRepos();k.length&&confirm(`Purge cache for ${k.length} repositories?`)&&k.forEach(b=>e.removeCache(b))},e.clearSelection=()=>{e.selected={},e.allSelected=!1},e.exportCsv=()=>{let k=new URLSearchParams(Object.entries(e.query).filter(([,b])=>b!==""&&b!==!1&&b!=null));k.set("format","csv"),k.set("limit","10000"),window.open("/api/admin/repos?"+k.toString(),"_blank")},e.removeCache=k=>{confirm("Remove cached files for "+k.repoId+"?")&&t.delete("/api/admin/repos/"+k.repoId).then(()=>f(),b=>console.error(b))},e.removeRepository=k=>{confirm("Remove repository "+k.repoId+"?")&&t.delete("/api/repo/"+k.repoId+"/").then(()=>f(),b=>console.error(b))},e.updateRepository=k=>{let b=Ue({title:`Refreshing ${k.repoId}...`,date:new Date,body:`The repository ${k.repoId} is going to be refreshed.`});e.toasts.push(b),t.post(`/api/repo/${k.repoId}/refresh`).then(R=>{R.data.status=="ready"?b.title=`${k.repoId} is refreshed.`:b.title=`Refreshing of ${k.repoId}.`},R=>{b.title=`Error during the refresh of ${k.repoId}.`,b.body=R.body})},e.fetchError=null;function f(){e.fetchError=null,t.get("/api/admin/repos",{params:e.query}).then(k=>{e.total=k.data.total,e.totalPage=Math.ceil(k.data.total/e.query.limit),e.repositories=k.data.results,e.statusCounts=k.data.statusCounts||[],e.totalSize=k.data.totalSize||0,e.allSelected=!1},k=>{e.fetchError=k&&k.data&&k.data.error||"Failed to load repositories",console.error(k)})}f();let w=null;e.watch("query",()=>{r.timeout.cancel(w),w=r.timeout(f,500);let{page:k,search:b,...R}=e.query;saveFilterPrefs(u,R),a()},!0),a()},$a=function(e,t,o){let r=mt(),n=as();e.Math=Math,e.watch("user.status",()=>{e.user==null&&o.url("/")}),e.user==null&&o.url("/"),e.users=[],e.total=-1,e.totalPage=0,e.statusCounts=[],e.selected={},e.allSelected=!1;let i=f=>{if(f.key==="/"&&!["INPUT","TEXTAREA","SELECT"].includes(document.activeElement?.tagName)){f.preventDefault();let w=document.querySelector('.admin-filter-toolbar input[type="search"]');w&&w.focus()}};n(document,"keydown",i),e.on("dispose",()=>document.removeEventListener("keydown",i)),e.clearFilter=f=>{f==="dateRange"?(e.query.dateFrom="",e.query.dateTo=""):e.query[f]="",e.query.page=1},e.chips=[];let a=()=>{let f=[];e.query.role&&f.push({key:"role",label:"Role",value:e.query.role}),e.chips=f};e.statusCountFor=f=>{let w=(e.statusCounts||[]).find(k=>k._id===f);return w?w.count:0},e.toggleSortDirection=()=>{e.query.direction=e.query.direction==="asc"?"desc":"asc"},e.sortBy=f=>{e.query.sort===f?e.query.direction=e.query.direction==="asc"?"desc":"asc":(e.query.sort=f,e.query.direction="desc"),e.query.page=1},e.sortIcon=f=>e.query.sort===f?e.query.direction==="asc"?"fa-arrow-up":"fa-arrow-down":"";let u="admin.users.filterPrefs",p={page:1,limit:25,sort:"username",direction:"asc",search:"",status:"",role:"",dateFrom:"",dateTo:""},h=loadFilterPrefs(u)||{};e.query=Object.assign({},p,h,{page:1,search:""}),e.selectAllOnPage=()=>{e.allSelected=!e.allSelected,e.users.forEach(f=>{e.selected[f.username]=e.allSelected})},e.selectedCount=()=>Object.values(e.selected||{}).filter(Boolean).length,e.selectedUsers=()=>e.users.filter(f=>e.selected[f.username]),e.banUser=f=>{confirm(`Ban user ${f.username}?`)&&t.post(`/api/admin/users/${f.username}/ban`).then(v,w=>console.error(w))},e.activateUser=f=>{t.post(`/api/admin/users/${f.username}/activate`).then(v,w=>console.error(w))},e.bulkBan=()=>{let f=e.selectedUsers();f.length&&confirm(`Ban ${f.length} users?`)&&f.forEach(w=>e.banUser(w))},e.exportCsv=()=>{let f=new URLSearchParams(Object.entries(e.query).filter(([,w])=>w!==""&&w!==!1&&w!=null));f.set("format","csv"),f.set("limit","10000"),window.open("/api/admin/users?"+f.toString(),"_blank")},e.fetchError=null;function v(){e.fetchError=null,t.get("/api/admin/users",{params:e.query}).then(f=>{e.total=f.data.total,e.totalPage=Math.ceil(f.data.total/e.query.limit),e.users=f.data.results,e.statusCounts=f.data.statusCounts||[],e.allSelected=!1},f=>{e.fetchError=f&&f.data&&f.data.error||"Failed to load users",console.error(f)})}v();let g=null;e.watch("query",()=>{r.timeout.cancel(g),g=r.timeout(v,500);let{page:f,search:w,...k}=e.query;saveFilterPrefs(u,k),a()},!0),a()},Fa=function(e,t,o,r){let n=mt();e.watch("user.status",()=>{e.user==null&&o.url("/")}),e.user==null&&o.url("/"),e.userInfo,e.repositories=[],e.search="",e.selected={},e.allSelected=!1;let i="admin.user.filterPrefs",a={filters:{status:{ready:!0,expired:!0,removed:!0,error:!0,preparing:!0}},sort:"anonymizeDate",direction:"desc"},u=loadFilterPrefs(i)||{};e.filters={status:Object.assign({},a.filters.status,u.filters&&u.filters.status||{})},e.query={sort:u.sort||a.sort,direction:u.direction||a.direction},e.orderBy=(e.query.direction==="asc"?"":"-")+e.query.sort,e.sortBy=f=>{e.query.sort===f?e.query.direction=e.query.direction==="asc"?"desc":"asc":(e.query.sort=f,e.query.direction="desc"),e.orderBy=(e.query.direction==="asc"?"":"-")+e.query.sort},e.sortIcon=f=>e.query.sort===f?e.query.direction==="asc"?"fa-arrow-up":"fa-arrow-down":"",e.watch("query",()=>{saveFilterPrefs(i,{filters:e.filters,sort:e.query.sort,direction:e.query.direction})},!0),e.watch("filters",()=>{saveFilterPrefs(i,{filters:e.filters,sort:e.query.sort,direction:e.query.direction})},!0),e.statusCountFor=f=>(e.repositories||[]).filter(w=>w.status===f).length,e.repoFiler=f=>e.filters.status[f.status]==!1?!1:!!(e.search.trim().length==0||f.source.fullName.indexOf(e.search)>-1||f.repoId.indexOf(e.search)>-1||f.statusMessage&&f.statusMessage.indexOf(e.search)>-1||f.conference&&f.conference.indexOf(e.search)>-1),e.selectAllOnPage=()=>{e.allSelected=!e.allSelected,(e.filteredRepositories||e.repositories).forEach(f=>{e.selected[f.repoId]=e.allSelected})},e.selectedCount=()=>Object.values(e.selected||{}).filter(Boolean).length,e.selectedRepos=()=>e.repositories.filter(f=>e.selected[f.repoId]),e.bulkRefresh=()=>{let f=e.selectedRepos();f.length&&confirm(`Force refresh ${f.length} repositories?`)&&f.forEach(w=>e.updateRepository(w))},e.bulkRemoveCache=()=>{let f=e.selectedRepos();f.length&&confirm(`Purge cache for ${f.length} repositories?`)&&f.forEach(w=>e.removeCache(w))},e.clearSelection=()=>{e.selected={},e.allSelected=!1},e.exportCsv=()=>{let f=e.filteredRepositories||e.repositories,k=["repoId","status","statusMessage","pageView","anonymizeDate","source.fullName","conference","size.storage"].join(","),b=f.map(D=>[D.repoId,D.status,D.statusMessage||"",D.pageView||0,D.anonymizeDate||"",D.source&&D.source.fullName||"",D.conference||"",D.size&&D.size.storage||0].map(I=>{let C=String(I??"");return/[",\n\r]/.test(C)?'"'+C.replace(/"/g,'""')+'"':C}).join(",")),R=new Blob([k+` `+b.join(` -`)],{type:"text/csv"}),N=document.createElement("a");N.href=URL.createObjectURL(R),N.download=r.username+"-repositories.csv",N.click()},e.showStatusMessage=f=>{let w=f.statusMessage||"(no message)";window.prompt(`Status message for ${f.repoId} (${f.status}):`,w)},e.fetchGithubInfo=f=>{let w=window.open("","_blank");w&&w.document.write("
Loading GitHub info for "+f.repoId+"..."),t.get("/api/admin/repos/"+f.repoId+"/github").then(k=>{w&&(w.document.open(),w.document.write('
'+JSON.stringify(k.data,null,2).replace(/[<>]/g,b=>b==="<"?"<":">")+""),w.document.close())},k=>{let b=k&&k.data?JSON.stringify(k.data,null,2):String(k);w&&(w.document.body.innerHTML='
'+b+"")})};function p(f){t.get("/api/admin/users/"+f+"/repos",{}).then(w=>{e.repositories=w.data},w=>{console.error(w)})}function h(f){t.get("/api/admin/users/"+f,{}).then(w=>{e.userInfo=w.data},w=>{console.error(w)})}h(r.username),p(r.username),e.banUser=()=>{confirm(`Ban user ${r.username}?`)&&t.post(`/api/admin/users/${r.username}/ban`).then(()=>h(r.username),f=>console.error(f))},e.activateUser=()=>{t.post(`/api/admin/users/${r.username}/activate`).then(()=>h(r.username),f=>console.error(f))},e.promoteUser=()=>{confirm(`Promote ${r.username} to admin?`)&&t.post(`/api/admin/users/${r.username}/promote`).then(()=>h(r.username),f=>console.error(f))},e.demoteUser=()=>{confirm(`Remove admin privileges from ${r.username}?`)&&t.post(`/api/admin/users/${r.username}/demote`).then(()=>h(r.username),f=>console.error(f))},e.tokens=[],e.tokenForm={name:"",plaintext:null};function v(){t.get("/api/admin/tokens").then(f=>{e.tokens=f.data||[]},f=>{f.status!==401&&f.status!==403&&console.error(f)})}v(),e.createToken=()=>{e.tokenForm.name&&t.post("/api/admin/tokens",{name:e.tokenForm.name}).then(f=>{e.tokenForm.plaintext=f.data.token,e.tokenForm.name="",v()},f=>console.error(f))},e.revokeToken=f=>{confirm(`Revoke token "${f.name}"?`)&&t.delete("/api/admin/tokens/"+f.id).then(()=>v(),w=>console.error(w))},e.removeCache=f=>{confirm("Remove cached files for "+f.repoId+"?")&&t.delete("/api/admin/repos/"+f.repoId).then(()=>p(r.username),w=>console.error(w))},e.removeRepository=f=>{confirm("Remove repository "+f.repoId+"?")&&t.delete("/api/repo/"+f.repoId+"/").then(()=>p(r.username),w=>console.error(w))},e.updateRepository=f=>{let w=Ue({title:`Refreshing ${f.repoId}...`,date:new Date,body:`The repository ${f.repoId} is going to be refreshed.`});e.toasts.push(w),t.post(`/api/repo/${f.repoId}/refresh`).then(k=>{k.data.status=="ready"?w.title=`${f.repoId} is refreshed.`:w.title=`Refreshing of ${f.repoId}.`},k=>{w.title=`Error during the refresh of ${f.repoId}.`,w.body=k.body})},e.getGitHubRepositories=f=>{t.get(`/api/user/${e.userInfo.username}/all_repositories`,{params:{force:"1"}}).then(w=>{e.userInfo.repositories=w.data})};let g=null;e.watch("query",()=>{n.timeout.cancel(g),g=n.timeout(()=>{p(r.username)},500)},!0)},La=function(e,t,o){let r=mt(),n=as();e.Math=Math,e.watch("user.status",()=>{e.user==null&&o.url("/")}),e.user==null&&o.url("/"),e.conferences=[],e.total=-1,e.totalPage=0,e.statusCounts=[];let i=k=>{if(k.key==="/"&&!["INPUT","TEXTAREA","SELECT"].includes(document.activeElement?.tagName)){k.preventDefault();let b=document.querySelector('.admin-filter-toolbar input[type="search"]');b&&b.focus()}};n(document,"keydown",i),e.on("dispose",()=>document.removeEventListener("keydown",i)),e.clearFilter=k=>{k==="dateRange"?(e.query.dateFrom="",e.query.dateTo=""):e.query[k]="",e.query.page=1},e.chips=[];let a=()=>{let k=[];(e.query.dateFrom||e.query.dateTo)&&k.push({key:"dateRange",label:"Date",value:(e.query.dateFrom||"\u2026")+" \u2013 "+(e.query.dateTo||"\u2026")}),e.chips=k};e.statusCountFor=k=>{let b=(e.statusCounts||[]).find(R=>R._id===k);return b?b.count:0},e.toggleSortDirection=()=>{e.query.direction=e.query.direction==="asc"?"desc":"asc"},e.sortBy=k=>{e.query.sort===k?e.query.direction=e.query.direction==="asc"?"desc":"asc":(e.query.sort=k,e.query.direction="desc"),e.query.page=1},e.sortIcon=k=>e.query.sort===k?e.query.direction==="asc"?"fa-arrow-up":"fa-arrow-down":"";let u="admin.conferences.filterPrefs",p={page:1,limit:25,sort:"name",direction:"asc",search:"",dateFrom:"",dateTo:"",ready:!1,expired:!1,removed:!1,error:!0,preparing:!0},h=loadFilterPrefs(u)||{};e.query=Object.assign({},p,h,{page:1,search:""});let v=o.search();v.search&&(e.query.search=v.search);let g="admin.conferences.presets";e.presets=JSON.parse(localStorage.getItem(g)||"[]"),e.savePreset=()=>{let k=window.prompt("Preset name:");if(!k)return;let b=Object.assign({},e.query);delete b.page,e.presets=(e.presets||[]).filter(R=>R.name!==k),e.presets.push({name:k,query:b}),localStorage.setItem(g,JSON.stringify(e.presets))},e.applyPreset=k=>{Object.assign(e.query,k.query,{page:1})},e.deletePreset=k=>{e.presets=(e.presets||[]).filter(b=>b.name!==k.name),localStorage.setItem(g,JSON.stringify(e.presets))},e.removeConference=k=>{confirm("Remove conference "+k.conferenceID+"?")&&t.delete("/api/admin/conferences/"+k.conferenceID).then(()=>f(),b=>console.error(b))},e.exportCsv=()=>{let k=new URLSearchParams(Object.entries(e.query).filter(([,b])=>b!==""&&b!==!1&&b!=null));k.set("format","csv"),k.set("limit","10000"),window.open("/api/admin/conferences?"+k.toString(),"_blank")},e.fetchError=null;function f(){e.fetchError=null,t.get("/api/admin/conferences",{params:e.query}).then(k=>{e.total=k.data.total,e.totalPage=Math.ceil(k.data.total/e.query.limit),e.conferences=k.data.results,e.statusCounts=k.data.statusCounts||[]},k=>{e.fetchError=k&&k.data&&k.data.error||"Failed to load conferences",console.error(k)})}f();let w=null;e.watch("query",()=>{r.timeout.cancel(w),w=r.timeout(f,500);let{page:k,search:b,...R}=e.query;saveFilterPrefs(u,R),a()},!0),a()},Ua=function(e,t,o,r,n){let i=mt();e.watch("user.status",()=>{e.user==null&&o.url("/")}),e.user==null&&o.url("/"),e.queueList=[],e.jobs=[],e.selectedQueue="download",e.selectedStats=null,e.range="1h",e.allStates=["active","waiting","delayed","failed","completed"],e.stateFilter={active:!0,waiting:!0,delayed:!0,failed:!0,completed:!0},e.query={search:"",autoRefresh:!0},e.filteredJobs=()=>(e.jobs||[]).filter(b=>e.stateFilter[b._state]),e.jobProgressPct=b=>b&&b.progress&&typeof b.progress=="object"&&typeof b.progress.percent=="number"?Math.max(0,Math.min(100,Math.round(b.progress.percent))):typeof b.progress=="number"?Math.max(0,Math.min(100,Math.round(b.progress))):null,e.jobDuration=b=>{if(!b.processedOn)return"-";let N=(b.finishedOn||Date.now())-b.processedOn;return N<1e3?N+"ms":(N/1e3).toFixed(1)+"s"},e.metricsPoints=[],e.selectQueue=b=>{e.selectedQueue=b,a(),u()},e.setRange=b=>{e.range=b,u()};function a(){let b={queue:e.selectedQueue,search:e.query.search};t.get("/api/admin/queues",{params:b}).then(R=>{e.queueList=R.data.queues||[],e.jobs=R.data.jobs||[],e.selectedStats=e.queueList.find(N=>N.key===e.selectedQueue)||e.queueList[0]||null},R=>console.error(R))}function u(){t.get("/api/admin/queues/metrics",{params:{queue:e.selectedQueue,range:e.range}}).then(b=>{e.metricsPoints=b.data.points||[],n(f,0)},b=>console.error(b))}a(),u();let p=r(()=>{e.query.autoRefresh&&(a(),u())},15e3);e.on("dispose",()=>r.cancel(p)),e.refreshNow=function(){a(),u()};function h(b){let R=b&&b.data&&(b.data.message||b.data.error)||"Request failed";e.actionError=R,n(()=>{e.actionError=null},5e3),console.error(b)}e.actionError=null,e.removeJob=b=>{t.delete(`/api/admin/queue/${e.selectedQueue}/${b.id}`).then(a,h)},e.retryJob=b=>{t.post(`/api/admin/queue/${e.selectedQueue}/${b.id}`).then(a,h)},e.retryFailed=()=>{confirm(`Retry all failed jobs in ${e.selectedQueue}?`)&&t.post(`/api/admin/queue/${e.selectedQueue}/retry-failed`).then(a,b=>console.error(b))},e.drainSelected=()=>{confirm(`Drain the ${e.selectedQueue} queue?`)&&t.post(`/api/admin/queue/${e.selectedQueue}/drain`).then(a,b=>console.error(b))},e.togglePause=()=>{let b=e.selectedStats&&e.selectedStats.paused?"resume":"pause";t.post(`/api/admin/queue/${e.selectedQueue}/${b}`).then(a,R=>console.error(R))},e.emptyQueue=()=>{confirm(`Empty the ${e.selectedQueue} queue? This removes ALL jobs.`)&&t.post(`/api/admin/queue/${e.selectedQueue}/empty`).then(a,b=>console.error(b))},e.pauseAll=()=>{confirm("Pause all queues?")&&t.post("/api/admin/queues/pause-all").then(a,b=>console.error(b))};let v=null;e.watch("query.search",()=>{i.timeout.cancel(v),v=i.timeout(a,350)}),e.expanded={},e.toggleJob=b=>{e.expanded[b.id]=!e.expanded[b.id]},e.humanTime=b=>{if(!b)return"";let R=new Date(b);return R.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})+" "+R.toLocaleDateString([],{month:"short",day:"numeric"})},e.delayCountdown=b=>{if(!b)return"";var R=Math.max(0,Math.ceil((b-Date.now())/1e3));if(R<=0)return"resuming soon";var N=Math.floor(R/60),D=R%60;return"in "+(N>0?N+"m "+D+"s":D+"s")};function g(b){if(b<=0)return{ticks:[0],niceMax:1};let R=Math.pow(10,Math.floor(Math.log10(b))),N=R;b/N<2?N=R/2:b/N>5&&(N=R*2);let D=Math.ceil(b/N)*N,I=[];for(let C=0;C<=D;C+=N)I.push(C);return{ticks:I,niceMax:D}}function f(){var b=document.getElementById("q-throughput-chart");if(!b)return;var R=b.getContext("2d"),N=window.devicePixelRatio||1,D=b.parentElement.getBoundingClientRect(),I=44,C=50,O=20,P=D.width-40,ee=180,J=P-I-C,K=ee-O;b.width=P*N,b.height=ee*N,b.style.width=P+"px",b.style.height=ee+"px",R.setTransform(N,0,0,N,0,0);var U=document.body.classList.contains("dark-mode"),de="#8A857C",se=U?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",ie=U?"#A7B2FF":"#3B4AD6",ce=U?"rgba(167,178,255,0.12)":"rgba(59,74,214,0.08)",we=U?"#F08A82":"#B42318",he=U?"rgba(240,138,130,0.08)":"rgba(180,35,24,0.06)",me=U?"#F5C842":"#B8860B",ae=e.metricsPoints||[];if(ae.length===0){R.fillStyle=de,R.font="12px monospace",R.textAlign="center",R.fillText("No metrics data yet",P/2,ee/2),w=null;return}var A=ae.map(function(M){return M.completed}),V=ae.map(function(M){return M.failed}),j=ae.map(function(M){return M.avgMs}),Z=ae.length,oe=J/(Z-1||1),qe=Math.max(1,Math.max.apply(null,A),Math.max.apply(null,V)),ze=g(qe),Fe=Math.max.apply(null,j),F=Fe>0?g(Fe):{ticks:[0],niceMax:1},ne=function(M){return K-M/ze.niceMax*(K-10)},L=function(M){return K-M/F.niceMax*(K-10)},W=function(M){return I+M*oe};R.textAlign="right",R.textBaseline="middle",R.font="10px monospace",ze.ticks.forEach(function(M){var Y=ne(M);R.strokeStyle=se,R.lineWidth=1,R.beginPath(),R.moveTo(I,Y),R.lineTo(P-C,Y),R.stroke(),R.fillStyle=de,R.fillText(M>=1e3?(M/1e3).toFixed(1)+"k":String(M),I-6,Y)}),Fe>0&&(R.textAlign="left",F.ticks.forEach(function(M){var Y=L(M);R.fillStyle=me,R.fillText(M>=1e3?(M/1e3).toFixed(1)+"s":M+"ms",P-C+6,Y)}));var fe=Date.now(),Ce=Math.min(6,Z);R.textAlign="center",R.textBaseline="top";for(var pe=0;pe
Loading GitHub info for "+f.repoId+"..."),t.get("/api/admin/repos/"+f.repoId+"/github").then(k=>{w&&(w.document.open(),w.document.write('
'+JSON.stringify(k.data,null,2).replace(/[<>]/g,b=>b==="<"?"<":">")+""),w.document.close())},k=>{let b=k&&k.data?JSON.stringify(k.data,null,2):String(k);w&&(w.document.body.innerHTML='
'+b+"")})};function p(f){t.get("/api/admin/users/"+f+"/repos",{}).then(w=>{e.repositories=w.data},w=>{console.error(w)})}function h(f){t.get("/api/admin/users/"+f,{}).then(w=>{e.userInfo=w.data},w=>{console.error(w)})}h(r.username),p(r.username),e.banUser=()=>{confirm(`Ban user ${r.username}?`)&&t.post(`/api/admin/users/${r.username}/ban`).then(()=>h(r.username),f=>console.error(f))},e.activateUser=()=>{t.post(`/api/admin/users/${r.username}/activate`).then(()=>h(r.username),f=>console.error(f))},e.promoteUser=()=>{confirm(`Promote ${r.username} to admin?`)&&t.post(`/api/admin/users/${r.username}/promote`).then(()=>h(r.username),f=>console.error(f))},e.demoteUser=()=>{confirm(`Remove admin privileges from ${r.username}?`)&&t.post(`/api/admin/users/${r.username}/demote`).then(()=>h(r.username),f=>console.error(f))},e.tokens=[],e.tokenForm={name:"",plaintext:null};function v(){t.get("/api/admin/tokens").then(f=>{e.tokens=f.data||[]},f=>{f.status!==401&&f.status!==403&&console.error(f)})}v(),e.createToken=()=>{e.tokenForm.name&&t.post("/api/admin/tokens",{name:e.tokenForm.name}).then(f=>{e.tokenForm.plaintext=f.data.token,e.tokenForm.name="",v()},f=>console.error(f))},e.revokeToken=f=>{confirm(`Revoke token "${f.name}"?`)&&t.delete("/api/admin/tokens/"+f.id).then(()=>v(),w=>console.error(w))},e.removeCache=f=>{confirm("Remove cached files for "+f.repoId+"?")&&t.delete("/api/admin/repos/"+f.repoId).then(()=>p(r.username),w=>console.error(w))},e.removeRepository=f=>{confirm("Remove repository "+f.repoId+"?")&&t.delete("/api/repo/"+f.repoId+"/").then(()=>p(r.username),w=>console.error(w))},e.updateRepository=f=>{let w=Ue({title:`Refreshing ${f.repoId}...`,date:new Date,body:`The repository ${f.repoId} is going to be refreshed.`});e.toasts.push(w),t.post(`/api/repo/${f.repoId}/refresh`).then(k=>{k.data.status=="ready"?w.title=`${f.repoId} is refreshed.`:w.title=`Refreshing of ${f.repoId}.`},k=>{w.title=`Error during the refresh of ${f.repoId}.`,w.body=k.body})},e.getGitHubRepositories=f=>{t.get(`/api/user/${e.userInfo.username}/all_repositories`,{params:{force:"1"}}).then(w=>{e.userInfo.repositories=w.data})};let g=null;e.watch("query",()=>{n.timeout.cancel(g),g=n.timeout(()=>{p(r.username)},500)},!0)},La=function(e,t,o){let r=mt(),n=as();e.Math=Math,e.watch("user.status",()=>{e.user==null&&o.url("/")}),e.user==null&&o.url("/"),e.conferences=[],e.total=-1,e.totalPage=0,e.statusCounts=[];let i=k=>{if(k.key==="/"&&!["INPUT","TEXTAREA","SELECT"].includes(document.activeElement?.tagName)){k.preventDefault();let b=document.querySelector('.admin-filter-toolbar input[type="search"]');b&&b.focus()}};n(document,"keydown",i),e.on("dispose",()=>document.removeEventListener("keydown",i)),e.clearFilter=k=>{k==="dateRange"?(e.query.dateFrom="",e.query.dateTo=""):e.query[k]="",e.query.page=1},e.chips=[];let a=()=>{let k=[];(e.query.dateFrom||e.query.dateTo)&&k.push({key:"dateRange",label:"Date",value:(e.query.dateFrom||"\u2026")+" \u2013 "+(e.query.dateTo||"\u2026")}),e.chips=k};e.statusCountFor=k=>{let b=(e.statusCounts||[]).find(R=>R._id===k);return b?b.count:0},e.toggleSortDirection=()=>{e.query.direction=e.query.direction==="asc"?"desc":"asc"},e.sortBy=k=>{e.query.sort===k?e.query.direction=e.query.direction==="asc"?"desc":"asc":(e.query.sort=k,e.query.direction="desc"),e.query.page=1},e.sortIcon=k=>e.query.sort===k?e.query.direction==="asc"?"fa-arrow-up":"fa-arrow-down":"";let u="admin.conferences.filterPrefs",p={page:1,limit:25,sort:"name",direction:"asc",search:"",dateFrom:"",dateTo:"",ready:!1,expired:!1,removed:!1,error:!0,preparing:!0},h=loadFilterPrefs(u)||{};e.query=Object.assign({},p,h,{page:1,search:""});let v=o.search();v.search&&(e.query.search=v.search);let g="admin.conferences.presets";e.presets=JSON.parse(localStorage.getItem(g)||"[]"),e.savePreset=()=>{let k=window.prompt("Preset name:");if(!k)return;let b=Object.assign({},e.query);delete b.page,e.presets=(e.presets||[]).filter(R=>R.name!==k),e.presets.push({name:k,query:b}),localStorage.setItem(g,JSON.stringify(e.presets))},e.applyPreset=k=>{Object.assign(e.query,k.query,{page:1})},e.deletePreset=k=>{e.presets=(e.presets||[]).filter(b=>b.name!==k.name),localStorage.setItem(g,JSON.stringify(e.presets))},e.removeConference=k=>{confirm("Remove conference "+k.conferenceID+"?")&&t.delete("/api/admin/conferences/"+k.conferenceID).then(()=>f(),b=>console.error(b))},e.exportCsv=()=>{let k=new URLSearchParams(Object.entries(e.query).filter(([,b])=>b!==""&&b!==!1&&b!=null));k.set("format","csv"),k.set("limit","10000"),window.open("/api/admin/conferences?"+k.toString(),"_blank")},e.fetchError=null;function f(){e.fetchError=null,t.get("/api/admin/conferences",{params:e.query}).then(k=>{e.total=k.data.total,e.totalPage=Math.ceil(k.data.total/e.query.limit),e.conferences=k.data.results,e.statusCounts=k.data.statusCounts||[]},k=>{e.fetchError=k&&k.data&&k.data.error||"Failed to load conferences",console.error(k)})}f();let w=null;e.watch("query",()=>{r.timeout.cancel(w),w=r.timeout(f,500);let{page:k,search:b,...R}=e.query;saveFilterPrefs(u,R),a()},!0),a()},Ua=function(e,t,o,r,n){let i=mt();e.watch("user.status",()=>{e.user==null&&o.url("/")}),e.user==null&&o.url("/"),e.queueList=[],e.jobs=[],e.selectedQueue="download",e.selectedStats=null,e.range="1h",e.allStates=["active","waiting","delayed","failed","completed"],e.stateFilter={active:!0,waiting:!0,delayed:!0,failed:!0,completed:!0},e.query={search:"",autoRefresh:!0},e.filteredJobs=()=>(e.jobs||[]).filter(b=>e.stateFilter[b._state]),e.jobProgressPct=b=>b&&b.progress&&typeof b.progress=="object"&&typeof b.progress.percent=="number"?Math.max(0,Math.min(100,Math.round(b.progress.percent))):typeof b.progress=="number"?Math.max(0,Math.min(100,Math.round(b.progress))):null,e.jobDuration=b=>{if(!b.processedOn)return"-";let N=(b.finishedOn||Date.now())-b.processedOn;return N<1e3?N+"ms":(N/1e3).toFixed(1)+"s"},e.metricsPoints=[],e.selectQueue=b=>{e.selectedQueue=b,a(),u()},e.setRange=b=>{e.range=b,u()};function a(){let b={queue:e.selectedQueue,search:e.query.search};t.get("/api/admin/queues",{params:b}).then(R=>{e.queueList=R.data.queues||[],e.jobs=R.data.jobs||[],e.selectedStats=e.queueList.find(N=>N.key===e.selectedQueue)||e.queueList[0]||null},R=>console.error(R))}function u(){t.get("/api/admin/queues/metrics",{params:{queue:e.selectedQueue,range:e.range}}).then(b=>{e.metricsPoints=b.data.points||[],n(f,0)},b=>console.error(b))}a(),u();let p=r(()=>{e.query.autoRefresh&&(a(),u())},15e3);e.on("dispose",()=>r.cancel(p)),e.refreshNow=function(){a(),u()};function h(b){let R=b&&b.data&&(b.data.message||b.data.error)||"Request failed";e.actionError=R,n(()=>{e.actionError=null},5e3),console.error(b)}e.actionError=null,e.removeJob=b=>{t.delete(`/api/admin/queue/${e.selectedQueue}/${b.id}`).then(a,h)},e.retryJob=b=>{t.post(`/api/admin/queue/${e.selectedQueue}/${b.id}`).then(a,h)},e.retryFailed=()=>{confirm(`Retry all failed jobs in ${e.selectedQueue}?`)&&t.post(`/api/admin/queue/${e.selectedQueue}/retry-failed`).then(a,b=>console.error(b))},e.drainSelected=()=>{confirm(`Drain the ${e.selectedQueue} queue?`)&&t.post(`/api/admin/queue/${e.selectedQueue}/drain`).then(a,b=>console.error(b))},e.togglePause=()=>{let b=e.selectedStats&&e.selectedStats.paused?"resume":"pause";t.post(`/api/admin/queue/${e.selectedQueue}/${b}`).then(a,R=>console.error(R))},e.emptyQueue=()=>{confirm(`Empty the ${e.selectedQueue} queue? This removes ALL jobs.`)&&t.post(`/api/admin/queue/${e.selectedQueue}/empty`).then(a,b=>console.error(b))},e.pauseAll=()=>{confirm("Pause all queues?")&&t.post("/api/admin/queues/pause-all").then(a,b=>console.error(b))};let v=null;e.watch("query.search",()=>{i.timeout.cancel(v),v=i.timeout(a,350)}),e.expanded={},e.toggleJob=b=>{e.expanded[b.id]=!e.expanded[b.id]},e.humanTime=b=>{if(!b)return"";let R=new Date(b);return R.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})+" "+R.toLocaleDateString([],{month:"short",day:"numeric"})},e.delayCountdown=b=>{if(!b)return"";var R=Math.max(0,Math.ceil((b-Date.now())/1e3));if(R<=0)return"resuming soon";var N=Math.floor(R/60),D=R%60;return"in "+(N>0?N+"m "+D+"s":D+"s")};function g(b){if(b<=0)return{ticks:[0],niceMax:1};let R=Math.pow(10,Math.floor(Math.log10(b))),N=R;b/N<2?N=R/2:b/N>5&&(N=R*2);let D=Math.ceil(b/N)*N,I=[];for(let C=0;C<=D;C+=N)I.push(C);return{ticks:I,niceMax:D}}function f(){var b=document.getElementById("q-throughput-chart");if(!b)return;var R=b.getContext("2d"),N=window.devicePixelRatio||1,D=b.parentElement.getBoundingClientRect(),I=44,C=50,O=20,P=D.width-40,ee=180,J=P-I-C,K=ee-O;b.width=P*N,b.height=ee*N,b.style.width=P+"px",b.style.height=ee+"px",R.setTransform(N,0,0,N,0,0);var U=document.body.classList.contains("dark-mode"),de="#8A857C",se=U?"rgba(255,255,255,0.06)":"rgba(0,0,0,0.06)",ie=U?"#A7B2FF":"#3B4AD6",ce=U?"rgba(167,178,255,0.12)":"rgba(59,74,214,0.08)",we=U?"#F08A82":"#B42318",he=U?"rgba(240,138,130,0.08)":"rgba(180,35,24,0.06)",me=U?"#F5C842":"#B8860B",ae=e.metricsPoints||[];if(ae.length===0){R.fillStyle=de,R.font="12px monospace",R.textAlign="center",R.fillText("No metrics data yet",P/2,ee/2),w=null;return}var A=ae.map(function(M){return M.completed}),V=ae.map(function(M){return M.failed}),j=ae.map(function(M){return M.avgMs}),Z=ae.length,oe=J/(Z-1||1),qe=Math.max(1,Math.max.apply(null,A),Math.max.apply(null,V)),ze=g(qe),Fe=Math.max.apply(null,j),F=Fe>0?g(Fe):{ticks:[0],niceMax:1},ne=function(M){return K-M/ze.niceMax*(K-10)},L=function(M){return K-M/F.niceMax*(K-10)},W=function(M){return I+M*oe};R.textAlign="right",R.textBaseline="middle",R.font="10px monospace",ze.ticks.forEach(function(M){var Y=ne(M);R.strokeStyle=se,R.lineWidth=1,R.beginPath(),R.moveTo(I,Y),R.lineTo(P-C,Y),R.stroke(),R.fillStyle=de,R.fillText(M>=1e3?(M/1e3).toFixed(1)+"k":String(M),I-6,Y)}),Fe>0&&(R.textAlign="left",F.ticks.forEach(function(M){var Y=L(M);R.fillStyle=me,R.fillText(M>=1e3?(M/1e3).toFixed(1)+"s":M+"ms",P-C+6,Y)}));var fe=Date.now(),Ce=Math.min(6,Z);R.textAlign="center",R.textBaseline="top";for(var pe=0;pe
The anonymous mirror you\u2019re looking for has expired, been removed by its owner, or never existed. If you received this URL from an author, ask them to re-issue it.
Fill in the details \u2014 it only takes a minute.
Take ownership of an existing anonymized repository so it appears on your dashboard.
',3)),s("div",zC,[t[5]||(t[5]=s("p",{class:"paper-section-copy"},"Use this when an anonymization was created by a co-author or from another account. You must have access to the GitHub repository it was made from.",-1)),E((l(),d("form",{class:"form needs-validation",name:"claimForm",novalidate:"",onSubmit:t[0]||(t[0]=be(n=>e.submitForm(n,()=>{e.claim()}),["prevent"]))},[s("div",HC,[t[1]||(t[1]=s("label",{class:"paper-field-label",for:"repoUrl"},"GitHub repository URL",-1)),E(s("input",{type:"text",class:T(["form-control",{"is-invalid":e.claimForm?.repoUrl?.invalid&&(e.claimForm?.repoUrl?.touched||e.claimForm?.submitted)}]),name:"repoUrl",id:"repoUrl",required:""},null,2),[[o,{state:e.viewState,set:n=>{e.repoUrl=n},value:e.repoUrl,form:"claimForm",options:{}}]]),E(s("div",BC," No anonymization matches this repository and ID. Check both values and that you can access the repository on GitHub. ",512),[[H,e.claimForm?.repoUrl?.errors?.not_found]])]),s("div",GC,[t[2]||(t[2]=s("label",{class:"paper-field-label",for:"repoId"},"Anonymized repository ID",-1)),E(s("input",{type:"text",class:T(["form-control",{"is-invalid":e.claimForm?.repoId?.invalid&&(e.claimForm?.repoId?.touched||e.claimForm?.submitted)}]),name:"repoId",id:"repoId",required:""},null,2),[[o,{state:e.viewState,set:n=>{e.repoId=n},value:e.repoId,form:"claimForm",options:{}}]]),t[3]||(t[3]=s("small",{id:"idHelp",class:"form-text text-muted"},[y("The ID is the last part of the anonymized URL: "),s("code",null,"anonymous.4open.science/r/Group anonymizations by venue, give chairs a shared dashboard, and set one expiry for every submission.
Every repository, pull request, and gist you\u2019ve mirrored, with live status and stats.
If something's missing, write to us \u2014 report a bug on GitHub.
The anonymous mirror you\u2019re looking for has expired, been removed by its owner, or never existed. If you received this URL from an author, ask them to re-issue it.
Fill in the details \u2014 it only takes a minute.
Take ownership of an existing anonymized repository so it appears on your dashboard.
',3)),s("div",zC,[t[5]||(t[5]=s("p",{class:"paper-section-copy"},"Use this when an anonymization was created by a co-author or from another account. You must have access to the GitHub repository it was made from.",-1)),E((l(),d("form",{class:"form needs-validation",name:"claimForm",novalidate:"",onSubmit:t[0]||(t[0]=be(n=>e.submitForm(n,()=>{e.claim()}),["prevent"]))},[s("div",HC,[t[1]||(t[1]=s("label",{class:"paper-field-label",for:"repoUrl"},"GitHub repository URL",-1)),E(s("input",{type:"text",class:T(["form-control",{"is-invalid":e.claimForm?.repoUrl?.invalid&&(e.claimForm?.repoUrl?.touched||e.claimForm?.submitted)}]),name:"repoUrl",id:"repoUrl",required:""},null,2),[[o,{state:e.viewState,set:n=>{e.repoUrl=n},value:e.repoUrl,form:"claimForm",options:{}}]]),E(s("div",BC," No anonymization matches this repository and ID. Check both values and that you can access the repository on GitHub. ",512),[[B,e.claimForm?.repoUrl?.errors?.not_found]])]),s("div",GC,[t[2]||(t[2]=s("label",{class:"paper-field-label",for:"repoId"},"Anonymized repository ID",-1)),E(s("input",{type:"text",class:T(["form-control",{"is-invalid":e.claimForm?.repoId?.invalid&&(e.claimForm?.repoId?.touched||e.claimForm?.submitted)}]),name:"repoId",id:"repoId",required:""},null,2),[[o,{state:e.viewState,set:n=>{e.repoId=n},value:e.repoId,form:"claimForm",options:{}}]]),t[3]||(t[3]=s("small",{id:"idHelp",class:"form-text text-muted"},[y("The ID is the last part of the anonymized URL: "),s("code",null,"anonymous.4open.science/r/Group anonymizations by venue, give chairs a shared dashboard, and set one expiry for every submission.
Every repository, pull request, and gist you\u2019ve mirrored, with live status and stats.
If something's missing, write to us \u2014 report a bug on GitHub.

GitHub's OAuth scopes have no read-only option for private repositories. Anonymous GitHub only ever reads your repositories; it never pushes, modifies, or deletes anything.
Source code with syntax highlighting, Markdown, Jupyter notebooks, PDFs, images, and GitHub Pages sites. Everything passes through the same redaction filter.
You choose: the mirror is removed, or visitors are redirected to the original GitHub repository once the review is over.
Track PR mirrors you\u2019ve created and their reviewer traffic.

GitHub's OAuth scopes have no read-only option for private repositories. Anonymous GitHub only ever reads your repositories; it never pushes, modifies, or deletes anything.
Source code with syntax highlighting, Markdown, Jupyter notebooks, PDFs, images, and GitHub Pages sites. Everything passes through the same redaction filter.
You choose: the mirror is removed, or visitors are redirected to the original GitHub repository once the review is over.
Track PR mirrors you\u2019ve created and their reviewer traffic.
Defaults applied to every new anonymization, your quotas, and your account.
',3)),s("div",eV,[E((l(),d("aside",tV,[...t[2]||(t[2]=[Ee('A small team keeps this running. If it helps you, please consider contributing back \u2014 in code, ideas, or coffee.
Collaborate by implementing new features and fixing bugs. Help with new file formats or deployment is welcome.
Open on GitHubTell us about bugs and missing features in Anonymous GitHub itself. Questions about an anonymized repository go to its authors.
File an issueServer costs hover around $25 a month. Any contribution helps keep the lights on.
GitHub Sponsors| '+(u.oldNo||"")+' | '+(u.newNo||"")+' | '+(u.kind==="add"?"+":u.kind==="remove"?"-":u.kind==="hunk"?"@":"")+' | '+t(u.text)+" |
r[n])}function E3(e,t){return(t?.[e]??t?.[e===1?"one":"other"]??"").replace(/\{\}/g,e??0)}var wl={ERRORS:{repository_job_cancelled:"The repository changed or was removed while processing.",storage_delete_failed:"Unable to remove cached files. Please try again later.",unknown_error:"Unknown error, contact the admin.",unreachable:"Anonymous GitHub is unreachable, contact the admin.",request_error:"Unable to download the file, check your connection or contact the admin.",not_found:"The requested resource could not be found.",not_connected:"You must be logged in to perform this action.",not_authorized:"You do not have permission to perform this action.",unable_to_connect_user:"Unable to connect your account. Please try again later.",user_not_found:"The requested user could not be found.",user_banned:"Your account has been banned. Contact the admin for more information.",repo_access_limited:"GitHub blocked access because the repository's organization restricts third-party OAuth apps. Ask an org owner to approve Anonymous GitHub under Settings \u2192 Third-party Access \u2192 OAuth app policy, or anonymize a personal fork instead.",repo_saml_enforcement:"The repository's organization enforces SAML single sign-on. Authorize your token for that organization (GitHub \u2192 Settings \u2192 Applications, or re-run the org's SSO sign-in), then retry. Alternatively, anonymize a personal fork.",repo_not_found:"The repository was not found on GitHub. Check the URL and spelling, make sure you are signed in to the account that can see it, and confirm the repo isn't hidden under an org that restricts third-party app access.",repo_empty:"The selected branch has no commits on GitHub. Push at least one commit, or pick a different branch, then retry.",repo_not_accessible:"Anonymous GitHub cannot access this repository. Verify the repository exists and that Anonymous GitHub has been authorized for the owning organization.",repository_archived:"This repository has been archived and its files are no longer available.",repository_expired:"The repository is expired.",invalid_status:"This action cannot be performed while the resource is in its current state.",repository_not_ready:"Anonymous GitHub is still processing the repository, it can take several minutes.",repository_not_accessible:"This repository is currently not accessible.",repo_is_updating:"Anonymous GitHub is still processing the repository, it can take several minutes.",invalid_repo:"The provided repository is not valid.",invalid_source_repository:"The repository source name is invalid; expected the form 'owner/name'.",repoId_not_defined:"A repository ID must be provided.",repoUrl_not_defined:"The repository URL needs to be defined.",source_not_provided:"A repository source must be provided.",github_rate_limit_exceeded:"GitHub temporarily blocked the request because we hit its API rate limit. Wait a few minutes and try again. If the problem persists and you contact GitHub Support, include the request ID and timestamp shown in GitHub's response (the 'X-GitHub-Request-Id' header).",rate_limited:"GitHub API rate limit reached. The repository will be available shortly \u2014 please wait a moment and refresh.",repoId_already_used:"The repository ID is already used.",invalid_repoId:"The format of the repository ID is invalid.",unsupported_source:"The repository source type is not supported.",branch_not_specified:"The branch is not specified.",branch_not_found:"The branch of the repository cannot be found.",commit_not_specified:"A commit must be specified.",commit_not_found:"The configured commit no longer exists in the source repository. It may have been force-pushed, rebased, or removed.",repo_renamed:"The source repository appears to have been renamed or moved on GitHub. Please refresh and try again \u2014 the cached name has been updated.",invalid_commit_format:"The commit hash format is invalid. It must be a hexadecimal string.",pull_request_not_found:"The requested pull request could not be found.",pull_request_expired:"This pull request has expired and is no longer available.",pull_request_not_ready:"This pull request is still being prepared. Please try again shortly.",pull_request_not_available:"This pull request is currently not available.",invalid_pullRequestId:"The pull request ID is invalid.",pullRequestId_already_used:"This pull request ID is already in use. Please choose a different one.",repository_not_specified:"A repository must be specified for this pull request.",pullRequestId_not_specified:"A pull request ID must be specified.",pullRequestId_is_not_a_number:"The source pull request ID must be a number.",options_not_provided:"Anonymization options are mandatory.",terms_not_specified:"Anonymization terms must be specified.",invalid_terms_format:"Terms are in an invalid format.",missing_content:"No content was provided to the anonymization preview.",unable_to_anonymize:"An error happened during the anonymization process. Please try later or report the issue.",non_supported_mode:"The selected anonymization mode is invalid, only download and stream are supported.",invalid_path:"The provided path is invalid or missing.",path_not_specified:"A file path must be specified.",path_not_defined:"The file path has not been resolved yet.",invalid_file_path:"The requested file path is not valid.",invalid_request:"The request is missing required fields or is malformed.",no_file_selected:"Please select a file.",file_not_found:"The requested file is not found.",file_not_accessible:"The requested file is not accessible.",file_not_supported:"The file type is not supported. Anonymous GitHub cannot handle it.",file_too_big:"The file size exceeds the limit of Anonymous GitHub.",is_folder:"The path points to a folder.",folder_not_supported:"The path points to a folder. Please select a file.",unable_to_write_file:"Unable to write file on disk.",download_not_enabled:"Repository downloads are not enabled on this server.",unable_to_download:"The repository could not be downloaded. Please try again later.",s3_config_not_provided:"Object storage has not been configured on this server.",stats_unsupported:"Statistics are only supported in download mode.",branches_not_found:"The requested branch is not found.",readme_not_available:"No README for the repository is found.",page_not_supported_on_different_branch:"GitHub Pages is served from a different branch than the one selected. Pick the branch that GitHub Pages is configured to use.",page_not_activated:"GitHub Pages is not enabled on this repository. Enable it in the repository settings on GitHub before anonymizing.",is_removed:"This resource has been removed and is no longer available.",conf_name_missing:"A conference name is required.",conf_id_missing:"A conference ID is required.",conf_id_used:"This conference ID is already in use. Please choose a different one.",conf_start_date_missing:"A start date is required for the conference.",conf_end_date_missing:"An end date is required for the conference.",conf_start_date_invalid:"The start date must be before the end date.",conf_end_date_invalid:"The end date must be in the future.",invalid_plan:"The selected plan is not valid.",conference_not_found:"The requested conference could not be found.",conf_not_found:"The requested conference could not be found.",conf_not_activated:"The conference is not activated.",billing_missing:"Billing information is required for this plan.",billing_name_missing:"A billing name is required.",billing_email_missing:"A billing email is required.",billing_address_missing:"A billing address is required.",billing_city_missing:"A billing city is required.",billing_zip_missing:"A billing ZIP/postal code is required.",billing_country_missing:"A billing country is required.",queue_not_found:"The specified queue could not be found.",job_not_found:"The specified job could not be found in the queue.",error_retrying_job:"An error occurred while retrying the job.",gist_expired:"The gist is expired.",gist_not_ready:"Anonymous GitHub is still processing the gist, it can take several minutes.",gist_not_found:"The requested gist could not be found.",gist_not_available:"This gist is currently not available.",invalid_gistId:"The format of the gist ID is invalid.",gistId_not_specified:"A gist ID must be provided.",gistId_already_used:"The gist ID is already used.",missing_token:"An authentication token is required.",invalid_token:"The provided authentication token is invalid.",login_failed:"Login failed. Please try again.",server_error:"An unexpected server error occurred. Please try again later.",username_not_defined:"A username must be provided.",github_user_not_found:"The specified GitHub user could not be found.",cannot_coauthor_self:"You cannot add yourself as a co-author.",storage_write_size_mismatch:"The downloaded file was smaller than expected. The upstream source may have returned an incomplete response \u2014 please try again.",storage_read_error:"An error occurred while reading the file from storage \u2014 please try again.",upstream_error:"A temporary error occurred while fetching from GitHub \u2014 please try again.",token_expired:"Your GitHub access token has expired. Please log out and log in again to refresh it.",job_is_active:"This job is currently running \u2014 wait for it to finish or remove it first."},WARNINGS:{page_not_enabled_on_repo:"GitHub Pages is not enabled on this repository. Enable it in the repository's Settings \u2192 Pages on GitHub, then refresh.",page_branch_mismatch:"GitHub Pages on this repository is served from the '{{pageBranch}}' branch, but you selected '{{selectedBranch}}'. Switch the branch above to '{{pageBranch}}' to anonymize the Pages site.",folder_truncated:"This folder has more than 10,000 entries; only a partial listing is shown.",repo_truncated:"Some folders in this repository have too many files to be fully listed. Affected folders are marked with a warning icon.",submodules_not_included:"This repository uses git submodules. Submodule contents are not included in the anonymized repository and appear as empty folders."}};var kl={name:"htmlDoc",props:["content","baseUrl","allowScripts"],setup(e){let t=Xe(null);return It(()=>{let r=[t.value][0];r.classList.add("html-doc");function n(){r.innerHTML="";let i=e.content;if(typeof i!="string")return;let a=document.createElement("iframe");a.className="html-doc-frame",a.setAttribute("title","Rendered HTML document");let u=["allow-popups","allow-popups-to-escape-sandbox"];e.allowScripts&&u.push("allow-scripts","allow-forms","allow-modals"),a.setAttribute("sandbox",u.join(" ")),a.setAttribute("referrerpolicy","no-referrer"),r.appendChild(a);let p="";e.baseUrl&&(p=' Defaults applied to every new anonymization, your quotas, and your account. A small team keeps this running. If it helps you, please consider contributing back \u2014 in code, ideas, or coffee. Collaborate by implementing new features and fixing bugs. Help with new file formats or deployment is welcome. Tell us about bugs and missing features in Anonymous GitHub itself. Questions about an anonymized repository go to its authors. Server costs hover around $25 a month. Any contribution helps keep the lights on.Your settings
| '+(u.oldNo||"")+' | '+(u.newNo||"")+' | '+(u.kind==="add"?"+":u.kind==="remove"?"-":u.kind==="hunk"?"@":"")+' | '+t(u.text)+" |
r[n])}function E3(e,t){return(t?.[e]??t?.[e===1?"one":"other"]??"").replace(/\{\}/g,e??0)}var wl={ERRORS:{repository_job_cancelled:"The repository changed or was removed while processing.",storage_delete_failed:"Unable to remove cached files. Please try again later.",unknown_error:"Unknown error, contact the admin.",unreachable:"Anonymous GitHub is unreachable, contact the admin.",request_error:"Unable to download the file, check your connection or contact the admin.",not_found:"The requested resource could not be found.",not_connected:"You must be logged in to perform this action.",not_authorized:"You do not have permission to perform this action.",unable_to_connect_user:"Unable to connect your account. Please try again later.",user_not_found:"The requested user could not be found.",user_banned:"Your account has been banned. Contact the admin for more information.",repo_access_limited:"GitHub blocked access because the repository's organization restricts third-party OAuth apps. Ask an org owner to approve Anonymous GitHub under Settings \u2192 Third-party Access \u2192 OAuth app policy, or anonymize a personal fork instead.",repo_saml_enforcement:"The repository's organization enforces SAML single sign-on. Authorize your token for that organization (GitHub \u2192 Settings \u2192 Applications, or re-run the org's SSO sign-in), then retry. Alternatively, anonymize a personal fork.",repo_not_found:"The repository was not found on GitHub. Check the URL and spelling, make sure you are signed in to the account that can see it, and confirm the repo isn't hidden under an org that restricts third-party app access.",repo_empty:"The selected branch has no commits on GitHub. Push at least one commit, or pick a different branch, then retry.",repo_not_accessible:"Anonymous GitHub cannot access this repository. Verify the repository exists and that Anonymous GitHub has been authorized for the owning organization.",repository_archived:"This repository has been archived and its files are no longer available.",repository_expired:"The repository is expired.",invalid_status:"This action cannot be performed while the resource is in its current state.",repository_not_ready:"Anonymous GitHub is still processing the repository, it can take several minutes.",repository_not_accessible:"This repository is currently not accessible.",repo_is_updating:"Anonymous GitHub is still processing the repository, it can take several minutes.",invalid_repo:"The provided repository is not valid.",invalid_source_repository:"The repository source name is invalid; expected the form 'owner/name'.",repoId_not_defined:"A repository ID must be provided.",repoUrl_not_defined:"The repository URL needs to be defined.",source_not_provided:"A repository source must be provided.",github_rate_limit_exceeded:"GitHub temporarily blocked the request because we hit its API rate limit. Wait a few minutes and try again. If the problem persists and you contact GitHub Support, include the request ID and timestamp shown in GitHub's response (the 'X-GitHub-Request-Id' header).",rate_limited:"GitHub API rate limit reached. The repository will be available shortly \u2014 please wait a moment and refresh.",repoId_already_used:"The repository ID is already used.",invalid_repoId:"The format of the repository ID is invalid.",unsupported_source:"The repository source type is not supported.",branch_not_specified:"The branch is not specified.",branch_not_found:"The branch of the repository cannot be found.",commit_not_specified:"A commit must be specified.",commit_not_found:"The configured commit no longer exists in the source repository. It may have been force-pushed, rebased, or removed.",repo_renamed:"The source repository appears to have been renamed or moved on GitHub. Please refresh and try again \u2014 the cached name has been updated.",invalid_commit_format:"The commit hash format is invalid. It must be a hexadecimal string.",pull_request_not_found:"The requested pull request could not be found.",pull_request_expired:"This pull request has expired and is no longer available.",pull_request_not_ready:"This pull request is still being prepared. Please try again shortly.",pull_request_not_available:"This pull request is currently not available.",invalid_pullRequestId:"The pull request ID is invalid.",pullRequestId_already_used:"This pull request ID is already in use. Please choose a different one.",repository_not_specified:"A repository must be specified for this pull request.",pullRequestId_not_specified:"A pull request ID must be specified.",pullRequestId_is_not_a_number:"The source pull request ID must be a number.",options_not_provided:"Anonymization options are mandatory.",terms_not_specified:"Anonymization terms must be specified.",invalid_terms_format:"Terms are in an invalid format.",missing_content:"No content was provided to the anonymization preview.",unable_to_anonymize:"An error happened during the anonymization process. Please try later or report the issue.",non_supported_mode:"The selected anonymization mode is invalid, only download and stream are supported.",invalid_path:"The provided path is invalid or missing.",path_not_specified:"A file path must be specified.",path_not_defined:"The file path has not been resolved yet.",invalid_file_path:"The requested file path is not valid.",invalid_request:"The request is missing required fields or is malformed.",no_file_selected:"Please select a file.",file_not_found:"The requested file is not found.",file_not_accessible:"The requested file is not accessible.",file_not_supported:"The file type is not supported. Anonymous GitHub cannot handle it.",file_too_big:"The file size exceeds the limit of Anonymous GitHub.",is_folder:"The path points to a folder.",folder_not_supported:"The path points to a folder. Please select a file.",unable_to_write_file:"Unable to write file on disk.",download_not_enabled:"Repository downloads are not enabled on this server.",unable_to_download:"The repository could not be downloaded. Please try again later.",s3_config_not_provided:"Object storage has not been configured on this server.",stats_unsupported:"Statistics are only supported in download mode.",branches_not_found:"The requested branch is not found.",readme_not_available:"No README for the repository is found.",page_not_supported_on_different_branch:"GitHub Pages is served from a different branch than the one selected. Pick the branch that GitHub Pages is configured to use.",page_not_activated:"GitHub Pages is not enabled on this repository. Enable it in the repository settings on GitHub before anonymizing.",is_removed:"This resource has been removed and is no longer available.",conf_name_missing:"A conference name is required.",conf_id_missing:"A conference ID is required.",conf_id_used:"This conference ID is already in use. Please choose a different one.",conf_start_date_missing:"A start date is required for the conference.",conf_end_date_missing:"An end date is required for the conference.",conf_start_date_invalid:"The start date must be before the end date.",conf_end_date_invalid:"The end date must be in the future.",invalid_plan:"The selected plan is not valid.",conference_not_found:"The requested conference could not be found.",conf_not_found:"The requested conference could not be found.",conf_not_activated:"The conference is not activated.",billing_missing:"Billing information is required for this plan.",billing_name_missing:"A billing name is required.",billing_email_missing:"A billing email is required.",billing_address_missing:"A billing address is required.",billing_city_missing:"A billing city is required.",billing_zip_missing:"A billing ZIP/postal code is required.",billing_country_missing:"A billing country is required.",queue_not_found:"The specified queue could not be found.",job_not_found:"The specified job could not be found in the queue.",error_retrying_job:"An error occurred while retrying the job.",gist_expired:"The gist is expired.",gist_not_ready:"Anonymous GitHub is still processing the gist, it can take several minutes.",gist_not_found:"The requested gist could not be found.",gist_not_available:"This gist is currently not available.",invalid_gistId:"The format of the gist ID is invalid.",gistId_not_specified:"A gist ID must be provided.",gistId_already_used:"The gist ID is already used.",missing_token:"An authentication token is required.",invalid_token:"The provided authentication token is invalid.",login_failed:"Login failed. Please try again.",server_error:"An unexpected server error occurred. Please try again later.",username_not_defined:"A username must be provided.",github_user_not_found:"The specified GitHub user could not be found.",cannot_coauthor_self:"You cannot add yourself as a co-author.",storage_write_size_mismatch:"The downloaded file was smaller than expected. The upstream source may have returned an incomplete response \u2014 please try again.",storage_read_error:"An error occurred while reading the file from storage \u2014 please try again.",upstream_error:"A temporary error occurred while fetching from GitHub \u2014 please try again.",token_expired:"Your GitHub access token has expired. Please log out and log in again to refresh it.",job_is_active:"This job is currently running \u2014 wait for it to finish or remove it first."},WARNINGS:{page_not_enabled_on_repo:"GitHub Pages is not enabled on this repository. Enable it in the repository's Settings \u2192 Pages on GitHub, then refresh.",page_branch_mismatch:"GitHub Pages on this repository is served from the '{{pageBranch}}' branch, but you selected '{{selectedBranch}}'. Switch the branch above to '{{pageBranch}}' to anonymize the Pages site.",folder_truncated:"This folder has more than 10,000 entries; only a partial listing is shown.",repo_truncated:"Some folders in this repository have too many files to be fully listed. Affected folders are marked with a warning icon.",submodules_not_included:"This repository uses git submodules. Submodule contents are not included in the anonymized repository and appear as empty folders."}};var kl={name:"htmlDoc",props:["content","baseUrl","allowScripts"],setup(e){let t=Xe(null);return It(()=>{let r=[t.value][0];r.classList.add("html-doc");function n(){r.innerHTML="";let i=e.content;if(typeof i!="string")return;let a=document.createElement("iframe");a.className="html-doc-frame",a.setAttribute("title","Rendered HTML document");let u=["allow-popups","allow-popups-to-escape-sandbox"];e.allowScripts&&u.push("allow-scripts","allow-forms","allow-modals"),a.setAttribute("sandbox",u.join(" ")),a.setAttribute("referrerpolicy","no-referrer"),r.appendChild(a);let p="";e.baseUrl&&(p='