1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[8259],{26551:(e,t,r)=>{r.d(t,{b:()=>a});var s=r(97306);function a(e){return!(0,s.CwX)(e.source_url)?.flattenTransparency&&(null!=e.width&&null!=e.height?Math.max(e.width,e.height)>2500:!!e.has_canonical)}},47362:(e,t,r)=>{r.r(t),r.d(t,{default:()=>w});var s=r(54568),a=r(7620),n=r(47167),i=r(26551);function l({imageId:e,apiUrl:t,hasHigherRes:r}){let[n,i]=(0,a.useState)(1),[l,c]=(0,a.useState)({x:0,y:0}),[o,d]=(0,a.useState)(!1),u=(0,a.useRef)(null);(0,a.useEffect)(()=>{i(1),c({x:0,y:0}),d(!1)},[e]),(0,a.useEffect)(()=>{if(n<=1||!r||o)return;let s=!1,a=new window.Image;a.onload=()=>{s||d(!0)},a.onerror=()=>{s=!0,console.warn("[ModerationViewer] Original preload failed for image",e)},a.src=`${t}/v1/images/${e}`},[n,r,o,e,t]);let x=o&&r?`${t}/v1/images/${e}`:`${t}/v1/images/${e}/canonical`;(0,a.useEffect)(()=>{let e=u.current;if(!e)return;let t=e=>{e.preventDefault(),i(t=>{let r=Math.max(1,Math.min(8,t*(e.deltaY<0?1.1:.9)));return 1===r&&c({x:0,y:0}),r})};return e.addEventListener("wheel",t,{passive:!1}),()=>e.removeEventListener("wheel",t)},[]);let m=(0,a.useRef)(null);return(0,s.jsxs)("div",{ref:u,className:"relative flex flex-1 items-center justify-center overflow-hidden bg-neutral-950",onPointerDown:e=>{n<=1||(m.current={x:e.clientX,y:e.clientY,panX:l.x,panY:l.y},e.target.setPointerCapture(e.pointerId))},onPointerMove:e=>{m.current&&c({x:m.current.panX+(e.clientX-m.current.x),y:m.current.panY+(e.clientY-m.current.y)})},onPointerUp:()=>{m.current=null},onDoubleClick:()=>{i(1),c({x:0,y:0})},children:[(0,s.jsx)("img",{src:x,alt:"",draggable:!1,style:{transform:`translate(${l.x}px, ${l.y}px) scale(${n})`,transformOrigin:"center center",transition:m.current?"none":"transform 60ms ease-out",cursor:n>
11?"grab":"zoom-in"},className:"max-h-full max-w-full select-none object-contain"}),(0,s.jsx)("button",{onClick:()=>{u.current?.requestFullscreen?.().catch(()=>{})},className:"absolute right-3 top-3 rounded-md bg-black/60 px-2.5 py-1 text-xs text-white/90 hover:bg-black/80","aria-label":"Enter fullscreen",children:"â¶ Fullscreen"}),n>1&&(0,s.jsxs)("span",{className:"absolute left-3 top-3 rounded bg-black/60 px-2 py-1 text-[11px] text-white/80",children:[o&&r?"Original":"Canonical"," \xb7 ",Math.round(100*n),"%"]})]})}function c({similar:e,apiUrl:t,selected:r,onClick:n,onDoubleClick:i}){let[l,c]=(0,a.useState)(!1),o=`${t}/v1/images/${e.id}/thumbnail`;return(0,s.jsxs)("button",{type:"button",onClick:n,onDoubleClick:i,onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),className:`relative block w-full overflow-hidden rounded-md transition 2 ${r?"border-4 border-accent shadow-[0_0_0_2px_rgba(247,147,26,0.5)]":"border-2 border-white/10 hover:border-white/30"}`,"aria-label":`Similar image (${e.similarity}% match)`,children:[(0,s.jsx)("img",{src:o,alt:"",loading:"lazy",className:"block w-full max-h-[180px] object-contain bg-black"}),(0,s.jsxs)("span",{className:"absolute left-1 top-1 rounded bg-black/75 px-1.5 py-0.5 text-[10px] font-semibold text-white",children:[e.similarity,"%"]}),r&&(0,s.jsxs)("span",{className:"absolute bottom-1 right-1 rounded bg-accent px-1.5 py-0.5 text-[10px] font-bold uppercase text-black",children:["REF \xb7 ",e.similarity,"%"]}),l&&!r&&(0,s.jsx)("span",{className:"absolute right-1 top-1 rounded bg-black/75 px-1.5 py-0.5 text-[10px] text-white",children:"Double-click to compare"})]})}var o=r(6603);function d({image:e,meta:t,similars:r,selectedSimilarId:n,uploaderStrikeCount:i,onSelectSimilar:l,onOpenCompare:d,apiUrl:m}){var h;let[p,f]=(0,a.useState)(!1),b=(0,a.useMemo)(()=>{let e=t?.risk_flags;return e?.nsfw||e?.gore||e?.spam?{tint:"bg-red-900/40 border-red-600/50 text-red-100",text:"LLM flagged risk â review before rejecting"}:(t?.quality_score??99)<=4?{tint:"bg-yellow-900/30 border-yellow-600/40 text-yellow-100",text:`Borderline quality (${t?.quality_score}/10)`}:{tint:"bg-blue-900/30 border-blue-600/40 text-blue-100",text:"Routed for admin review"}},[t]);return(0,s.jsxs)("aside",{className:"flex h-full w-[260px] shrink-0 flex-col overflow-y-auto border-l border-white/10 bg-neutral-950/70 p-3 text-sm text-white/85",children:[(0,s.jsxs)("div",{className:`rounded-md border px-3 py-2 text-xs ${b.tint}`,children:[(0,s.jsx)("p",{className:"font-semibold uppercase text-[10px] opacity-70",children:"Why it's here"}),(0,s.jsx)("p",{className:"mt-1",children:b.text})]}),t?.risk_flags&&(t.risk_flags.nsfw||t.risk_flags.gore||t.risk_flags.spam)&&(0,s.jsxs)("div",{className:"mt-2 flex gap-1.5",children:[t.risk_flags.nsfw&&(0,s.jsx)(u,{label:"NSFW"}),t.risk_flags.gore&&(0,s.jsx)(u,{label:"Gore"}),t.risk_flags.spam&&(0,s.jsx)(u,{label:"Spam"})]}),t?.review_note&&(0,s.jsx)(x,{label:"Review note",text:t.review_note,tint:"bg-white/5 border-white/15 text-white/85"}),(t?.risk_flags?.nsfw||t?.risk_flags?.gore||t?.risk_flags?.spam)&&t?.moderation_reasoning&&(0,s.jsx)(x,{label:"Moderation reasoning",text:t.moderation_reasoning,tint:"bg-red-900/30 border-red-600/40 text-red-100"}),(t?.quality_score??99)<=5&&t?.quality_reasoning&&(0,s.jsx)(x,{label:"Quality reasoning",text:t.quality_reasoning,tint:"bg-yellow-900/25 border-yellow-600/40 text-yellow-100"}),(0,s.jsxs)("div",{className:"mt-3 flex items-center gap-2 rounded-md bg-white/5 p-2",children:[e.uploader_has_avatar?(0,s.jsx)("img",{src:`${m}/v1/users/${e.uploader_id}/avatar`,alt:"",className:"h-6 w-6 rounded-full object-cover"}):(0,s.jsx)("div",{className:"h-6 w-6 rounded-full bg-white/10"}),(0,s.jsx)(o.SafeLink,{href:`/u/${e.uploader_pubkey??e.uploader_id}`,target:"_blank",rel:"noopener noreferrer",className:"truncate text-sm font-medium text-white hover:text-accent-text",children:e.uploader_display_name||"Anonymous"}),(0,s.jsxs)("span",{className:`ml-auto text-xs font-semibold ${i>0?"text-red-400":"text-white/40"}`,children:[i," strike",1===i?"":"s"]})]}),(e.caption||e.alt_text)&&(0,s.jsxs)("div",{className:"mt-3",children:[e.caption&&(0,s.jsx)("p",{className:"font-semibold text-white",children:e.caption}),e.alt_text&&(0,s.jsx)("p",{className:"mt-1 text-xs text-white/60 italic",children:e.alt_text})]}),(e.tags?.length??0)+(e.free_tags?.length??0)>0&&(0,s.jsxs)("div",{className:"mt-3",children:[(0,s.jsx)("p",{className:"text-[10px] uppercase text-white/50",children:"Tags"}),(0,s.jsxs)("div",{className:"mt-1 flex flex-wrap gap-1",children:[(e.tags??[]).map(e=>(0,s.jsxs)("span",{className:"rounded-full bg-accent/20 px-2 py-0.5 text-xs text-accent-text",children:[e.name??e.tag," ",(0,s.jsx)("span",{className:"opacity-50",children:e.score})]},e.tag)),(e.free_tags??[]).map(e=>(0,s.jsxs)("span",{className:"rounded-full border border-white/20 px-2 py-0.5 text-xs text-white/70",children:[e.name??e.tag," ",(0,s.jsx)("span",{className:"opacity-50",children:e.score})]},`f-${e.tag}`))]})]}),t?.text_in_image&&(0,s.jsxs)("div",{className:"mt-3",children:[(0,s.jsxs)("button",{onClick:()=>f(e=>!e),className:"text-[10px] uppercase text-white/50 hover:text-white/80",children:["Text in image ",p?"â¾":"â¸"]}),p&&(0,s.jsx)("pre",{className:"mt-1 whitespace-pre-wrap break-words rounded bg-black/30 p-2 text-xs text-white/80",children:t.text_in_image})]}),r.length>0&&(0,s.jsxs)("div",{className:"mt-3",children:[(0,s.jsxs)("p",{className:"text-[10px] uppercase text-white/50",children:["Similar (",r.length,")"]}),(0,s.jsx)("div",{className:"mt-1 space-y-1.5",children:r.map(e=>(0,s.jsx)(c,{similar:e,apiUrl:m,selected:e.id===n,onClick:()=>l(e.id),onDoubleClick:()=>d(e.id)},e.id))})]}),(0,s.jsxs)("p",{className:"mt-auto pt-3 text-[10px] text-white/40",children:[e.width,"\xd7",e.height," \xb7 ",(h=t?.size??e.size??0)<1024?`${h} B`:h<1048576?`${Math.round(h/1024)} KB`:`${(h/1024/1024).toFixed(1)} MB`," \xb7 ",t?.mime_type||e.mime_type,t?.filename&&` \xb7 ${t.filename}`]})]})}function u({label:e}){return(0,s.jsx)("span",{className:"rounded bg-red-600/80 px-1.5 py-0.5 text-[10px] font-bold uppercase text-white",children:e})}function x({label:e,text:t,tint:r}){return(0,s.jsxs)("div",{className:`mt-2 rounded-md border px-3 py-2 ${r}`,children:[(0,s.jsx)("p",{className:"font-semibold uppercase text-[10px] opacity-70",children:e}),(0,s.jsx)("p",{className:"mt-1 text-xs leading-snug whitespace-pre-wrap break-words",children:t})]})}let m="flex items-center gap-1.5 rounded-full px-3.5 py-2 text-sm font-semibold transition";function h({mode:e,canUndo:t,selectedSimilar:r,onDecision:a,onArmRisk:n,onCancelRisk:i,onUndo:l}){return"risk-armed"===e?(0,s.jsxs)("div",{className:"flex shrink-0 items-center gap-2 bg-red-950/50 p-3 border-t border-red-600/40",children:[(0,s.jsx)("span",{className:"mr-2 text-xs font-bold uppercase text-red-400 animate-pulse",children:"Risk reason?"}),(0,s.jsxs)("button",{onClick:()=>a({kind:"reject-nsfw"}),className:`${m} bg-red-600 text-white shadow-[0_0_20px_rgba(239,68,68,0.6)] hover:bg-red-700`,children:["NSFW ",(0,s.jsx)(p,{children:"T"})]}),(0,s.jsxs)("button",{onClick:()=>a({kind:"reject-gore"}),className:`${m} bg-red-600 text-white shadow-[0_0_20px_rgba(239,68,68,0.6)] hover:bg-red-700`,children:["Gore ",(0,s.jsx)(p,{children:"G"})]}),(0,s.jsxs)("button",{onClick:()=>a({kind:"reject-spam"}),className:`${m} bg-red-600 text-white shadow-[0_0_20px_rgba(239,68,68,0.6)] hover:bg-red-700`,children:["Spam ",(0,s.jsx)(p,{children:"H"})]}),(0,s.jsxs)("button",{onClick:i,className:`${m} ml-auto bg-neutral-700 text-white hover:bg-neutral-600`,children:["Cancel ",(0,s.jsx)(p,{children:"Esc"})]})]}):(0,s.jsxs)("div",{className:"flex shrink-0 items-center gap-2 bg-neutral-900/80 p-3 border-t border-white/10",children:[(0,s.jsxs)("button",{onClick:()=>a({kind:"approve"}),className:`${m} bg-green-700 text-white hover:bg-green-600`,children:["Approve ",(0,s.jsx)(p,{children:"A"})]}),(0,s.jsx)("button",{onClick:()=>{r&&a({kind:"reject-duplicate",similar_image_id:null})},disabled:!r,className:`${m} ${r?"bg-red-700/90 text-white hover:bg-red-600":"bg-red-900/40 text-white/40 cursor-not-allowed"}`,title:r?`Will reject as duplicate of #${r.index} (${r.similarity}%)`:"No similar match available",children:r?(0,s.jsxs)(s.Fragment,{children:["Reject as Dup of #",r.index," (",r.similarity,"%) ",(0,s.jsx)(p,{children:"D"})]}):(0,s.jsxs)(s.Fragment,{children:["Reject Duplicate ",(0,s.jsx)(p,{children:"D"})]})}),(0,s.jsxs)("button",{onClick:()=>a({kind:"reject-low-quality"}),className:`${m} bg-red-700/90 text-white hover:bg-red-600`,children:["Reject Low-Q ",(0,s.jsx)(p,{children:"F"})]}),(0,s.jsxs)("button",{onClick:n,className:`${m} bg-red-700/90 text-white hover:bg-red-600`,children:["Reject Risk ",(0,s.jsx)(p,{children:"R"})]}),(0,s.jsxs)("button",{onClick:()=>a({kind:"skip"}),className:`${m} bg-neutral-800 text-white/90 hover:bg-neutral-700`,children:["Skip ",(0,s.jsx)(p,{children:"Space"})]}),(0,s.jsxs)("button",{onClick:l,disabled:!t,className:`${m} ml-auto border border-white/20 bg-transparent text-white/80 ${t?"hover:bg-white/10":"opacity-40 cursor-not-allowed"}`,children:["Undo ",(0,s.jsx)(p,{children:"â«"})]})]})}function p({children:e}){return(0,s.jsx)("span",{className:"rounded bg-black/40 px-1.5 py-0.5 text-[10px] font-mono",children:e})}function f({onClose:e}){return(0,s.jsxs)("div",{className:"pointer-events-auto fixed bottom-20 right-4 z-30 w-[280px] rounded-lg border border-white/10 bg-neutral-950/95 p-3 text-xs text-white/80 shadow-lg backdrop-blur","aria-label":"Keyboard shortcuts",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between pb-2",children:[(0,s.jsx)("span",{className:"font-semibold text-white",children:"Hotkeys"}),(0,s.jsx)("button",{onClick:e,className:"rounded bg-white/10 px-2 hover:bg-white/20","aria-label":"Hide cheat sheet",children:"\xd7"})]}),(0,s.jsxs)(t,{title:"Decide",children:[(0,s.jsx)(r,{k:"A",label:"Approve"}),(0,s.jsx)(r,{k:"F",label:"Reject â Low quality"}),(0,s.jsx)(r,{k:"D",label:"Reject â Duplicate"}),(0,s.jsx)(r,{k:"R",label:"Reject â Risk (â T/G/H)"}),(0,s.jsx)(r,{k:"Space",label:"Skip"})]}),(0,s.jsxs)(t,{title:"Risk sub-menu (after R)",children:[(0,s.jsx)(r,{k:"T",label:"NSFW"}),(0,s.jsx)(r,{k:"G",label:"Gore"}),(0,s.jsx)(r,{k:"H",label:"Spam"}),(0,s.jsx)(r,{k:"Esc",label:"Cancel"})]}),(0,s.jsxs)(t,{title:"Modify",children:[(0,s.jsx)(r,{k:"â« / Ctrl+Z",label:"Undo"}),(0,s.jsx)(r,{k:"1-5",label:"Select similar"})]}),(0,s.jsxs)(t,{title:"Navigate & View",children:[(0,s.jsx)(r,{k:"â â",label:"Prev / next (no decision)"}),(0,s.jsx)(r,{k:"?",label:"Toggle this sheet"}),(0,s.jsx)(r,{k:"Esc",label:"Exit moderation"})]})]});function t({title:e,children:t}){return(0,s.jsxs)("div",{className:"mb-2",children:[(0,s.jsx)("p",{className:"mb-1 text-[10px] uppercase tracking-wide text-white/50",children:e}),(0,s.jsx)("div",{className:"space-y-1",children:t})]})}function r({k:e,label:t}){return(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"inline-block rounded border border-white/20 bg-white/10 px-1.5 py-0.5 text-[11px] font-mono font-semibold text-white",children:e}),(0,s.jsx)("span",{className:"flex-1 text-right text-white/70",children:t})]})}}function b({apiUrl:e,currentImageId:t,duplicateImageId:r,hammingDistance:n,onClose:i}){return(0,a.useEffect)(()=>{let e=e=>{"Escape"===e.key&&(e.preventDefault(),i())};return window.addEventListener("keydown",e,!0),()=>window.removeEventListener("keydown",e,!0)},[i]),(0,s.jsxs)("div",{role:"dialog","aria-modal":"true","aria-label":"Side-by-side comparison",className:"fixed inset-0 z-[100] flex flex-col bg-black/95",onClick:i,children:[(0,s.jsxs)("div",{className:"flex items-center justify-between px-4 py-2 text-sm text-white/80",children:[(0,s.jsxs)("span",{children:["Comparison â hamming distance ",n," / 256"]}),(0,s.jsx)("button",{onClick:i,className:"rounded bg-white/10 px-3 py-1 hover:bg-white/20",children:"Close (Esc)"})]}),(0,s.jsxs)("div",{className:"grid flex-1 grid-cols-2 gap-2 p-2",onClick:e=>e.stopPropagation(),children:[(0,s.jsxs)("div",{className:"flex flex-col",children:[(0,s.jsx)("p",{className:"mb-1 text-center text-xs uppercase text-white/60",children:"Current"}),(0,s.jsx)("div",{className:"flex flex-1 items-center justify-center overflow-hidden bg-neutral-900 rounded",children:(0,s.jsx)("img",{src:`${e}/v1/images/${t}/canonical`,alt:"Current image",className:"max-h-full max-w-full object-contain"})})]}),(0,s.jsxs)("div",{className:"flex flex-col",children:[(0,s.jsx)("p",{className:"mb-1 text-center text-xs uppercase text-white/60",children:"Reference"}),(0,s.jsx)("div",{className:"flex flex-1 items-center justify-center overflow-hidden bg-neutral-900 rounded",children:(0,s.jsx)("img",{src:`${e}/v1/images/${r}/canonical`,alt:"Reference image",className:"max-h-full max-w-full object-contain"})})]})]})]})}function g({counters:e,onCheckAgain:t}){(0,a.useEffect)(()=>{let e=setInterval(t,3e4);return()=>clearInterval(e)},[t]);let r=e.approved+e.rejected+e.skipped;return(0,s.jsxs)("div",{className:"flex min-h-[80vh] flex-col items-center justify-center p-6 text-center text-white",children:[(0,s.jsx)("div",{className:"text-5xl",children:"â"}),(0,s.jsx)("h1",{className:"mt-4 text-2xl font-bold",children:"All caught up"}),(0,s.jsx)("p",{className:"mt-2 text-white/60",children:"No images in needs_review."}),r>0&&(0,s.jsxs)("p",{className:"mt-4 text-sm text-white/80",children:["This session: ",(0,s.jsxs)("span",{className:"font-semibold",children:[r," moderated"]}),(0,s.jsxs)("span",{className:"ml-2 text-green-400",children:[e.approved," approved"]}),(0,s.jsxs)("span",{className:"ml-2 text-red-400",children:[e.rejected," rejected"]}),e.skipped>0&&(0,s.jsxs)("span",{className:"ml-2 text-white/50",children:[e.skipped," skipped"]})]}),(0,s.jsx)("p",{className:"mt-6 text-xs text-white/40",children:"Auto-refreshing every 30 secondsâ¦"}),(0,s.jsxs)("div",{className:"mt-6 flex gap-3",children:[(0,s.jsx)("button",{onClick:t,className:"rounded-md bg-accent px-4 py-2 text-sm font-semibold text-black hover:bg-accent/80",children:"Check again"}),(0,s.jsx)(o.SafeLink,{href:"/admin",className:"rounded-md border border-white/20 px-4 py-2 text-sm font-semibold text-white hover:bg-white/10",children:"Back to admin"})]})]})}let j="moderation_cheatsheet_hidden";function k({apiUrl:e}){let t=function({apiUrl:e}){let[t,r]=(0,a.useState)([]),[s,i]=(0,a.useState)(0),[l,c]=(0,a.useState)(!0),[o,d]=(0,a.useState)([]),u=(0,a.useRef)([]),x=(0,a.useRef)(!1),m=(0,a.useCallback)(async t=>{let r=new URLSearchParams({status:"needs_review",sort_by:"created_at",sort_order:"asc",limit:String(50),offset:String(t)}),s=await fetch(`${e}/v1/images/search?${r}`,{headers:(0,n.Pw)(),credentials:"include"});return s.ok?(await s.json()).images??[]:[]},[e]);(0,a.useEffect)(()=>{let e=!1;return c(!0),m(0).then(t=>{e||(r(t),i(0),c(!1))}),()=>{e=!0}},[m]),(0,a.useEffect)(()=>{l||0===t.length||t.length<50||s<Math.max(0,t.length-10)||x.current||(x.current=!0,m(t.length).then(e=>{e.length>0&&r(t=>[...t,...e]),x.current=!1}
2).catch(()=>{x.current=!1}))},[s,t.length,l,m]);let h=(0,a.useCallback)(()=>{i(e=>Math.min(e+1,Number.MAX_SAFE_INTEGER))},[]),p=(0,a.useCallback)(e=>{r(t=>{let r=t.findIndex(t=>t.id===e);if(-1===r)return t;let s=t.slice();return s.splice(r,1),i(e=>r<e?e-1:e),s})},[]),f=(0,a.useCallback)(e=>{d(t=>{let r=[...t,e];return r.length>10&&r.shift(),u.current=r,r})},[]),b=(0,a.useCallback)(()=>{let e=u.current;if(0===e.length)return null;let t=e[e.length-1],s=e.slice(0,-1);return u.current=s,d(s),r(e=>{let r=e.slice();return r.splice(t.cursorBefore,0,t.image),r}),i(t.cursorBefore),t},[]),g=(0,a.useCallback)(async()=>{c(!0),r(await m(0)),i(0),c(!1)},[m]),j=t[s]??null;return{queue:t,cursor:s,current:j,loading:l,history:o,advance:h,setCursor:i,removeStale:p,pushHistory:f,undo:b,refetch:g}}({apiUrl:e}),[r,c]=(0,a.useState)(null),[o,u]=(0,a.useState)(null),[x,m]=(0,a.useState)(()=>"1"!==window.localStorage.getItem(j)),[p,k]=(0,a.useState)(null),[w,v]=(0,a.useState)({approved:0,rejected:0,skipped:0}),y=(0,a.useRef)({}),[_,N]=(0,a.useState)({});(0,a.useEffect)(()=>{let e=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=e}},[]);let C=(0,a.useCallback)(()=>{m(e=>{let t=!e;return window.localStorage.setItem(j,t?"0":"1"),t})},[]),$=(0,a.useCallback)(async t=>{if(y.current[t.id])return;let[r,s,a]=await Promise.all([fetch(`${e}/v1/images/${t.id}/meta`,{headers:(0,n.Pw)(),credentials:"include"}).catch(()=>null),fetch(`${e}/v1/images/${t.id}/similar?limit=5`,{headers:(0,n.Pw)(),credentials:"include"}).catch(()=>null),t.uploader_id?fetch(`${e}/v1/admin/users/${t.uploader_id}`,{headers:(0,n.Pw)(),credentials:"include"}).catch(()=>null):Promise.resolve(null)]),i=r&&r.ok?await r.json():null,l=s&&s.ok?await s.json():null,c=a&&a.ok?await a.json():null,o=c?.user?.active_strike_count??0,d=i?{text_in_image:i.text_in_image??null,review_note:i.review_note??null,quality_reasoning:i.quality_reasoning??null,moderation_reasoning:i.moderation_reasoning??null,risk_flags:i.risk_flags??null,quality_score:i.quality_score??null,filename:i.filename??t.filename,mime_type:i.mime_type??t.mime_type,size:i.size??t.size}:null,u=l?.similar_images??[];y.current={...y.current,[t.id]:{meta:d,similars:u,uploaderStrikeCount:o}},N(y.current)},[e]);(0,a.useEffect)(()=>{if(t.current){$(t.current);for(let r=1;r<=3;r++){let s=t.queue[t.cursor+r];if(!s)break;new window.Image().src=`${e}/v1/images/${s.id}/canonical`,$(s)}c(null)}},[t.current?.id,t.cursor,t.queue,$,e]);let S=t.current?_[t.current.id]??null:null,R=(0,a.useMemo)(()=>{let e=S?.similars??[];if(0===e.length)return null;let t=e.findIndex(e=>e.id===r);return t<0?null:{index:t+1,similarity:e[t].similarity}},[S,r]);(0,a.useEffect)(()=>{S&&S.similars.length>0&&null===r&&c(S.similars[0].id)},[S,r]);let E=(0,a.useCallback)(e=>{k(e),setTimeout(()=>k(t=>t?.id===e.id?null:t),4e3)},[]),D=(0,a.useCallback)(async(t,r)=>{if("skip"===r.kind)return null;let s={status:"rejected"};switch(r.kind){case"approve":s.status="approved";break;case"reject-low-quality":s.rejection_reason="low_quality";break;case"reject-duplicate":s.rejection_reason="duplicate",s.similar_image_id=r.similar_image_id;break;case"reject-nsfw":s.rejection_reason="nsfw",s.issue_strike=!0,s.strike_reason="nsfw";break;case"reject-gore":s.rejection_reason="gore",s.issue_strike=!0,s.strike_reason="gore";break;case"reject-spam":s.rejection_reason="spam",s.issue_strike=!0,s.strike_reason="spam"}return fetch(`${e}/v1/images/${t.id}`,{method:"PATCH",headers:{"Content-Type":"application/json",...(0,n.Pw)()},credentials:"include",body:JSON.stringify(s)})},[e]),P=(0,a.useCallback)(e=>{let s=t.current;if(!s||"reject-duplicate"===e.kind&&!r)return;let a="reject-duplicate"===e.kind?{kind:"reject-duplicate",similar_image_id:r}:e,n=t.cursor,i=D(s,a).then(async r=>{if(!r)return;if(404===r.status||409===r.status)return void t.removeStale(s.id);if(!r.ok)return void E({id:`err-${s.id}-${Date.now()}`,kind:"error",text:`Failed to moderate image â retry?`,onRetry:()=>P(e)});let n=await r.json();v(e=>"approve"===a.kind?{...e,approved:e.approved+1}:"skip"===a.kind?{...e,skipped:e.skipped+1}:{...e,rejected:e.rejected+1});let i=n?.strike&&["reject-nsfw","reject-gore","reject-spam"].includes(a.kind)?` \xb7 strike issued (${n.strike.active_strike_count}/3${"frozen"===n.strike.new_user_status?" â frozen":""})`:"";E({id:`ok-${s.id}-${Date.now()}`,kind:"success",text:`${function(e){switch(e.kind){case"approve":return"Approved";case"reject-low-quality":return"Rejected (low quality)";case"reject-duplicate":return"Rejected (duplicate)";case"reject-nsfw":return"Rejected (NSFW)";case"reject-gore":return"Rejected (gore)";case"reject-spam":return"Rejected (spam)";
2case"skip":return"Skipped"}}(a)}${i} \xb7 Undo (â«)`})});t.pushHistory({image:s,decision:a,cursorBefore:n,serverApplied:"skip"===a.kind,serverPromise:i??Promise.resolve()}),"skip"===a.kind&&(v(e=>({...e,skipped:e.skipped+1})),E({id:`skip-${s.id}-${Date.now()}`,kind:"success",text:"Skipped \xb7 Undo (â«)"})),t.advance()},[t,r,D,E]),q=(0,a.useCallback)(async()=>{if(0===t.history.length)return;let r=t.history[t.history.length-1];try{await r.serverPromise}catch{}if(t.undo(),"skip"===r.decision.kind){v(e=>({...e,skipped:Math.max(0,e.skipped-1)})),E({id:`undo-${Date.now()}`,kind:"success",text:"Undone â image back in queue"});return}let s={status:"needs_review"};["reject-nsfw","reject-gore","reject-spam"].includes(r.decision.kind)&&(s.revoke_strike=!0),fetch(`${e}/v1/images/${r.image.id}`,{method:"PATCH",headers:{"Content-Type":"application/json",...(0,n.Pw)()},credentials:"include",body:JSON.stringify(s)}).then(e=>{e.ok?(v(e=>"approve"===r.decision.kind?{...e,approved:Math.max(0,e.approved-1)}:{...e,rejected:Math.max(0,e.rejected-1)}),E({id:`undo-${Date.now()}`,kind:"success",text:"Undone â image back in queue"})):E({id:`err-undo-${Date.now()}`,kind:"error",text:"Undo failed on server"})}).catch(()=>{E({id:`err-undo-${Date.now()}`,kind:"error",text:"Undo network error"})})},[t,e,E]),M=(0,a.useCallback)(()=>{window.dispatchEvent(new KeyboardEvent("keydown",{key:"r"}))},[]),T=(0,a.useCallback)(()=>{window.dispatchEvent(new KeyboardEvent("keydown",{key:"Escape"}))},[]),U=(0,a.useCallback)(e=>{t.setCursor(Math.max(0,Math.min(t.queue.length-1,t.cursor+e)))},[t]),I=(0,a.useCallback)(()=>{let e=w.approved+w.rejected+w.skipped;(!(e>0)||window.confirm(`Exit moderation? ${e} decisions in this session.`))&&(window.location.href="/admin")},[w]),{mode:A}=function(e){let{enabled:t,onDecision:r,onUndo:s,onNavigate:n,onSelectSimilar:i,onToggleCheatSheet:l,onExit:c}=e,[o,d]=(0,a.useState)("normal"),u=(0,a.useRef)(o),x=(0,a.useRef)(null),m=(0,a.useRef)(r),h=(0,a.useRef)(s),p=(0,a.useRef)(n),f=(0,a.useRef)(i),b=(0,a.useRef)(l),g=(0,a.useRef)(c);(0,a.useEffect)(()=>{m.current=r,h.current=s,p.current=n,f.current=i,b.current=l,g.current=c},[r,s,n,i,l,c]),(0,a.useEffect)(()=>{u.current=o},[o]);let j=(0,a.useCallback)(()=>{x.current&&(clearTimeout(x.current),x.current=null),d("normal")},[]),k=(0,a.useCallback)(()=>{d("risk-armed"),x.current&&clearTimeout(x.current),x.current=setTimeout(()=>{d("normal"),x.current=null},3e3)},[]);return(0,a.useEffect)(()=>{if(!t)return;let e=e=>{let t=e.target;if(t&&("INPUT"===t.tagName||"TEXTAREA"===t.tagName||t.isContentEditable)||e.repeat)return;let r=e.key.toLowerCase();if((e.ctrlKey||e.metaKey)&&"z"===r){e.preventDefault(),h.current();return}if("risk-armed"===u.current){if("t"===r){j(),m.current({kind:"reject-nsfw"});return}if("g"===r){j(),m.current({kind:"reject-gore"});return}if("h"===r){j(),m.current({kind:"reject-spam"});return}"escape"===r&&(e.preventDefault(),j());return}switch(r){case"a":m.current({kind:"approve"});return;case"d":m.current({kind:"reject-duplicate",similar_image_id:null});return;case"f":m.current({kind:"reject-low-quality"});return;case"r":k();return;case" ":e.preventDefault(),m.current({kind:"skip"});return;case"backspace":e.preventDefault(),h.current();return;case"arrowleft":e.preventDefault(),p.current(-1);return;case"arrowright":e.preventDefault(),p.current(1);return;case"1":case"2":case"3":case"4":case"5":f.current(parseInt(r,10)-1);return;case"?":b.current();return;case"escape":g.current();return}};return window.addEventListener("keydown",e),()=>{window.removeEventListener("keydown",e),x.current&&(clearTimeout(x.current),x.current=null)}},[t,j,k]),{mode:o}}({enabled:null===o,onDecision:P,onUndo:q,onNavigate:U,onSelectSimilar:(0,a.useCallback)(e=>{let t=S?.similars??[];t[e]&&c(t[e].id)},[S]),onToggleCheatSheet:C,onExit:I});if(t.loading)return(0,s.jsx)("div",{className:"flex min-h-screen items-center justify-center bg-neutral-950 text-white/60",children:"Loading queueâ¦"});if(!t.current)return(0,s.jsx)(g,{counters:w,onCheckAgain:t.refetch});let L=t.current,z=S??{meta:null,similars:[],uploaderStrikeCount:0};return(0,s.jsxs)("div",{className:"fixed inset-0 z-[60] flex flex-col bg-neutral-950 text-white",children:[(0,s.jsxs)("header",{className:"flex shrink-0 items-center justify-between border-b border-white/10 bg-neutral-900/90 px-4 py-2 text-sm",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("span",{className:"font-semibold",children:"Moderation Queue"}),(0,s.jsxs)("span",{className:"ml-3 text-white/60",children:[t.queue.length-t.cursor," remaining"]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[!x&&(0,s.jsx)("button",{onClick:C,className:"rounded border border-white/20 px-2 py-1 text-xs hover:bg-white/10",children:"? Hotkeys"}),(0,s.jsx)("button",{onClick:I,className:"rounded bg-white/10 px-3 py-1 text-xs hover:bg-white/20",children:"Exit (Esc)"})]})]}),(0,s.jsxs)("div",{className:"flex flex-1 overflow-hidden",children:[(0,s.jsx)(l,{imageId:L.id,apiUrl:e,hasHigherRes:(0,i.b)(L)}),(0,s.jsx)(d,{image:L,meta:z.meta,similars:z.similars,selectedSimilarId:r,uploaderStrikeCount:z.uploaderStrikeCount,onSelectSimilar:c,onOpenCompare:u,apiUrl:e})]}),(0,s.jsx)(h,{mode:A,canUndo:t.history.length>0,selectedSimilar:R,onDecision:P,onArmRisk:M,onCancelRisk:T,onUndo:q}),x&&(0,s.jsx)(f,{onClose:C}),p&&(0,s.jsxs)("div",{className:`fixed left-1/2 top-16 z-50 -translate-x-1/2 roun
2ded-md px-4 py-2 shadow-lg ${"error"===p.kind?"bg-red-600 text-white":"bg-green-700/90 text-white"}`,role:"status",children:[p.text,p.onRetry&&(0,s.jsx)("button",{onClick:p.onRetry,className:"ml-3 underline",children:"Retry"})]}),o&&(0,s.jsx)(b,{apiUrl:e,currentImageId:L.id,duplicateImageId:o,hammingDistance:z.similars.find(e=>e.id===o)?.hamming_distance??0,onClose:()=>u(null)})]})}function w(){return(0,s.jsx)(k,{apiUrl:"https://api.memestack.ai"})}},79748:(e,t,r)=>{var s=r(79796);r.o(s,"useParams")&&r.d(t,{useParams:function(){return s.useParams}}),r.o(s,"usePathname")&&r.d(t,{usePathname:function(){return s.usePathname}}),r.o(s,"useRouter")&&r.d(t,{useRouter:function(){return s.useRouter}}),r.o(s,"useSearchParams")&&r.d(t,{useSearchParams:function(){return s.useSearchParams}})}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.