1"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[194],{40194:(e,t,s)=>{s.r(t),s.d(t,{AdminImageBrowser:()=>C});var a=s(54568),r=s(7620),l=s(96807),n=s(6603),i=s(99258),o=s(43656);let d=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,c=[50,100,200,500];var m=s(11168);let x="rounded border border-input-border bg-input-bg px-2 py-1.5 text-sm text-foreground";function u(e){return(0,a.jsxs)("div",{className:"mb-4 flex flex-wrap items-center gap-2",children:[(0,a.jsxs)("select",{className:x,value:e.statusFilter,onChange:t=>e.setStatusFilter(t.target.value),"aria-label":"Status filter",children:[(0,a.jsx)("option",{value:"",children:"All statuses"}),(0,a.jsx)("option",{value:"needs_review",children:"Needs Review"}),(0,a.jsx)("option",{value:"pending",children:"Processing"}),(0,a.jsx)("option",{value:"approved",children:"Approved"}),(0,a.jsx)("option",{value:"rejected",children:"Rejected"}),(0,a.jsx)("option",{value:"draft",children:"Draft"})]}),["nsfw","gore","spam"].map(t=>(0,a.jsx)("button",{type:"button",onClick:()=>e.setRiskFlags(e=>({...e,[t]:!e[t]})),"aria-pressed":e.riskFlags[t],className:`rounded border px-2 py-1.5 text-xs font-semibold uppercase ${e.riskFlags[t]?"border-red-500 bg-red-500/15 text-red-500":"border-input-border text-muted-foreground"}`,children:t},t)),(0,a.jsx)("button",{type:"button",onClick:()=>e.setHasSimilar(e=>!e),"aria-pressed":e.hasSimilar,className:`rounded border px-2 py-1.5 text-xs font-semibold ${e.hasSimilar?"border-accent bg-accent/15 text-accent-text":"border-input-border text-muted-foreground"}`,children:"Has duplicates"}),(0,a.jsx)("button",{type:"button",onClick:()=>e.setNeedsRehash(e=>!e),"aria-pressed":e.needsRehash,className:`rounded border px-2 py-1.5 text-xs font-semibold ${e.needsRehash?"border-orange-500 bg-orange-500/15 text-orange-500":"border-input-border text-muted-foreground"}`,children:"Needs rehash"}),(0,a.jsx)("button",{type:"button",onClick:()=>e.setHasUserContext(e=>!e),"aria-pressed":e.hasUserContext,className:`rounded border px-2 py-1.5 text-xs font-semibold ${e.hasUserContext?"border-accent bg-accent/15 text-accent-text":"border-input-border text-muted-foreground"}`,children:"Has context"}),(0,a.jsx)("button",{type:"button",onClick:()=>e.setUserContextAssessment("misleading"===e.userContextAssessment?null:"misleading"),"aria-pressed":"misleading"===e.userContextAssessment,className:`rounded border px-2 py-1.5 text-xs font-semibold ${"misleading"===e.userContextAssessment?"border-amber-500 bg-amber-500/15 text-amber-500":"border-input-border text-muted-foreground"}`,children:"â Misleading hint"}),(0,a.jsxs)("select",{className:x,value:e.modelFilter,onChange:t=>e.setModelFilter(t.target.value),"aria-label":"LLM model filter",children:[(0,a.jsx)("option",{value:"",children:"All models"}),(0,a.jsx)("option",{value:"gemini-3.5-flash-lite",children:"Gemini 3.5 Flash-Lite (current)"}),(0,a.jsx)("option",{value:"gemini-3-flash",children:"Gemini 3 Flash Preview"}),(0,a.jsx)("option",{value:"gemini-2.5-flash",children:"Gemini 2.5 Flash"}),(0,a.jsx)("option",{value:"gemma",children:"Gemma 4 (fallback)"}),(0,a.jsx)("option",{value:"llama",children:"Llama (legacy fallback)"}),(0,a.jsx)("option",{value:"unknown",children:"Unknown (legacy)"})]}),(0,a.jsx)("input",{className:`${x} flex-1 min-w-[200px]`,placeholder:"Search caption, tags, or paste image ID...",value:e.search,onChange:t=>e.setSearch(t.target.value),onKeyDown:t=>{"Enter"===t.key&&e.onSearchEnter?.()},"aria-label":"Search images"}),(0,a.jsxs)("select",{className:x,value:e.sort,onChange:t=>{let s=t.target.value;e.setSort(s),"closest_duplicate:asc"===s&&e.setHasSimilar(!0)},"aria-label":"Sort",children:[(0,a.jsx)("option",{value:"created_at:desc",children:"Newest"}),(0,a.jsx)("option",{value:"created_at:asc",children:"Oldest"}),(0,a.jsx)("option",{value:"zap_total_sats:desc",children:"Most zapped"}),(0,a.jsx)("option",{value:"quality_score:asc",children:"Lowest quality"}),(0,a.jsx)("option",{value:"quality_score:desc",children:"Highest quality"}),(0,a.jsx)("option",{value:"closest_duplicate:asc",children:"Closest duplicate"})]}),e.uploaderFilter&&(0,a.jsxs)("span",{className:"flex items-center gap-1 rounded-full border border-accent/30 bg-accent/10 px-2.5 py-1 text-xs font-medium text-accent-text",children:["Uploader: ",e.uploaderFilter.name,(0,a.jsx)("button",{type:"button",onClick:()=>e.setUploaderFilter(null),className:"ml-0.5 hover:text-foreground","aria-label":"Clear uploader filter",children:"\xd7"})]})]})}function p({selectedCount:e,bulkBusy:t,onBulkApprove:s,onBulkReject:r,onBulkDelete:l,onBulkRehash:n,onBulkHash:i,onBulkReprocess:o,onBulkRetag:d}){return 0===e?null:(0,a.jsxs)("div",{className:"mt-4 flex items-center gap-3 rounded-xl border border-accent/30 bg-accent/10 px-4 py-2",children:[(0,a.jsxs)("span",{className:"text-sm font-medium text-foreground",children:[e," selected"]}),(0,a.jsx)("button",{type:"button",onClick:s,disabled:t,className:"rounded bg-green-600 px-3 py-1 text-xs font-medium text-white hover:bg-green-700 disabled:opacity-50",title:"Ap
1prove selected images and make them publicly visible",children:"Approve"}),(0,a.jsx)("button",{type:"button",onClick:r,disabled:t,className:"rounded bg-orange-600 px-3 py-1 text-xs font-medium text-white hover:bg-orange-700 disabled:opacity-50",title:"Reject selected images (hidden from public, R2 files preserved)",children:"Reject"}),(0,a.jsx)("button",{type:"button",onClick:l,disabled:t,className:"rounded bg-red-600 px-3 py-1 text-xs font-medium text-white hover:bg-red-700 disabled:opacity-50",title:"Permanently delete selected images (DB row + R2 files removed)",children:"Delete"}),(0,a.jsx)("button",{type:"button",onClick:n,disabled:t,className:"rounded bg-blue-600 px-3 py-1 text-xs font-medium text-white hover:bg-blue-700 disabled:opacity-50",title:"Recalculate perceptual hash (dHash) from existing thumbnails for duplicate detection",children:"Recalculate phash"}),(0,a.jsx)("button",{type:"button",onClick:i,disabled:t,className:"rounded bg-blue-600 px-3 py-1 text-xs font-medium text-white hover:bg-blue-700 disabled:opacity-50",title:"Compute SHA-256 file hash for selected images",children:"Backfill Hash"}),(0,a.jsx)("button",{type:"button",onClick:o,disabled:t,className:"rounded bg-orange-600 px-3 py-1 text-xs font-medium text-white hover:bg-orange-700 disabled:opacity-50",title:"Reprocess selected images through full pipeline (canonical, thumbnail, phash, LLM, embedding)",children:"Full Reload"}),(0,a.jsx)("button",{type:"button",onClick:d,disabled:t,className:"rounded bg-accent-secondary px-3 py-1 text-xs font-medium text-white hover:bg-accent-secondary/90 disabled:opacity-50",title:"Re-run LLM tagging only (keeps existing canonical, thumbnail, and phash)",children:"Re-tag"})]})}function g(e){let t=t=>{let s=parseInt(t,10);!isNaN(s)&&s>=1&&s<=e.totalPages&&e.setPage(s-1)};return(0,a.jsxs)("div",{className:"mt-4 flex items-center justify-center gap-4",children:[e.totalPages>1&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("button",{onClick:()=>e.setPage(e=>Math.max(0,e-1)),disabled:0===e.page,className:"rounded border border-input-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-muted disabled:opacity-50",children:"Prev"}),(0,a.jsx)("span",{className:"text-sm text-muted-foreground",children:"Page"}),(0,a.jsx)("input",{type:"number",min:1,max:e.totalPages,value:e.page+1,onChange:e=>t(e.target.value),onKeyDown:e=>{"Enter"===e.key&&t(e.target.value)},disabled:0===e.totalPages,className:"w-16 rounded border border-input-border bg-input-bg px-2 py-1.5 text-center text-sm text-foreground disabled:opacity-50","aria-label":"Page number"}),(0,a.jsxs)("span",{className:"text-sm text-muted-foreground",children:["of ",e.totalPages]}),(0,a.jsx)("button",{onClick:()=>e.setPage(t=>Math.min(e.totalPages-1,t+1)),disabled:e.page>=e.totalPages-1,className:"rounded border border-input-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-muted disabled:opacity-50",children:"Next"})]}),(0,a.jsx)("select",{value:e.pageSize,onChange:t=>{e.setPageSize(Number(t.target.value)),e.setPage(0)},className:"rounded border border-input-border bg-input-bg px-2 py-1.5 text-sm text-foreground","aria-label":"Page size",children:e.pageSizeOptions.map(e=>(0,a.jsxs)("option",{value:e,children:[e," / page"]},e))})]})}var h=s(61303);let b={nsfw:{classes:"bg-pink-500/15 text-pink-500",label:"NSFW"},gore:{classes:"bg-red-500/15 text-red-500",label:"GORE"},spam:{classes:"bg-purple-500/15 text-purple-500",label:"SPAM"}};function f({flags:e,size:t="sm"}){if(!e)return null;let s=Object.keys(b).filter(t=>e[t]);if(0===s.length)return null;let r="sm"===t?"px-2 py-0.5 text-[0.7em]":"px-2.5 py-0.5 text-xs";return(0,a.jsx)("div",{className:`flex gap-1 ${"md"===t?"gap-1.5":""}`,children:s.map(e=>{let{classes:t,label:s}=b[e];return(0,a.jsx)("span",{className:`inline-block rounded-full font-semibold ${r} ${t}`,children:s},e)})})}var j=s(1694);function v({imageId:e}){let[t,s]=(0,r.useState)([]),[l,n]=(0,r.useState)(!0);(0,r.useEffect)(()=>{let t=!1;return(0,i.nr)(`/v1/images/${e}/similar`,{params:{limit:5}}).then(e=>{t||s(e?.similar_images||[])}).catch(()=>{}).finally(()=>{t||n(!1)}),()=>{t=!0}},[e]);let d=(0,o.e9)();return l?(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Similar Images"}),(0,a.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"Loadingâ¦"})]}):0===t.length?(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Similar Images"}),(0,a.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:"No similar images found"})]}):(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Similar Images"}),(0,a.jsx)("div",{className:"mt-1 flex gap-3",children:t.map(e=>(0,a.jsxs)("div",{role:"link",tabIndex:0,onClick:()=>window.open(`/gallery/${e.id}`,"_blank","noopener,noreferrer"),onKeyDown:t=>{("Enter"===t.key||" "===t.key)&&(t.preventDefault(),window.open(`/gallery/${e.id}`,"_blank","noopener,noreferrer"))},className:"group relative overflow-hidden rounded-lg border border-card-border hover:border-accent cursor-pointer",children:[(0,a.jsx)("img",{src:`${d}/v1/images/${e.id}/thumbnail`,alt:"",className:"h-[120px] w-[120px] object-cover bg-muted",loading:"lazy"}),(0,a.jsxs)("span",{className:"absolute bottom-0 left-0 right-0 bg-black/60 px-1 py-0.5 text-center text-[10px] text-white",children:[e.similarity,"% \xb7 d=",e.hamming_distance]})]},e.id))})]})}var y=s(36587);function N({image:e,expanded:t,busy:s,rejecting:l,onAction:n,onRejectSubmit:i,onRejectCancel:d,onRetag:c,onOpenModal:m}){let x=(0,o.e9)(),[u,p]=(0,r.useState)(!1);(0,r.useEffect)(()=>{p(!1)},[t]);let g=["pending","needs_review","rejected"].includes(e.status),h=Array.isArray(e.tags)?e.tags.map(e=>e.tag):[],b=Array.isArray(e.free_tags)?e.free_tags.map(e=>e.tag):[];return(0,a.jsx)("tr",{className:"border-b border-card-border bg-muted/20",children:(0,a.jsx)("td",{colSpan:10,className:"px-4 py-4",children:(0,a.jsxs)("div",{className:"flex gap-6",children:[(0,a.jsx)("div",{className:"flex-shrink-0",children:(0,a.jsx)("img",{src:`${x}
1/v1/images/${e.id}`,alt:e.alt_text||e.caption||"",className:"max-h-[400px] max-w-[400px] rounded-lg object-contain bg-muted cursor-pointer hover:opacity-90 transition-opacity",loading:"lazy",onClick:e=>{e.stopPropagation(),m()}})}),(0,a.jsxs)("div",{className:"flex-1 min-w-0 space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Caption"}),(0,a.jsx)("p",{className:"text-sm text-foreground",children:e.caption||"â"})]}),e.alt_text&&(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Alt text"}),(0,a.jsx)("p",{className:"text-sm text-foreground",children:e.alt_text})]}),e.text_in_image&&(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Text in image"}),(0,a.jsx)("p",{className:`text-sm text-foreground whitespace-pre-wrap ${u?"":"line-clamp-2"}`,children:e.text_in_image}),e.text_in_image.length>100&&(0,a.jsx)("button",{onClick:()=>p(e=>!e),className:"mt-1 text-xs text-accent-text hover:underline",children:u?"Show less":"Show more"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Tags"}),(0,a.jsxs)("div",{className:"flex flex-wrap gap-1 mt-1",children:[h.map((e,t)=>(0,a.jsx)("span",{className:"rounded-full bg-accent/15 px-2 py-0.5 text-xs font-medium text-accent-text",children:e},`c-${t}`)),b.map((e,t)=>(0,a.jsx)("span",{className:"rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground",children:e},`f-${t}`)),0===h.length&&0===b.length&&(0,a.jsx)("span",{className:"text-xs text-muted-foreground",children:"No tags"})]})]}),e.meme_template_name&&(0,a.jsxs)("div",{className:"text-sm",children:[(0,a.jsx)("span",{className:"font-medium",children:"Meme Template:"})," ",e.meme_template_name]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Risk flags"}),(0,a.jsx)(f,{flags:e.risk_flags,size:"md"}),!e.risk_flags&&(0,a.jsx)("span",{className:"text-xs text-muted-foreground",children:"None"})]}),e.rejection_reason&&(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Rejection reason"}),(0,a.jsxs)("p",{className:"text-sm text-foreground",children:["nsfw"===e.rejection_reason&&"NSFW content","gore"===e.rejection_reason&&"Violent/gore content","spam"===e.rejection_reason&&"Promotional/spam","duplicate"===e.rejection_reason&&"Duplicate","low_quality"===e.rejection_reason&&"Low quality","other"===e.rejection_reason&&"Other",e.rejection_note&&(0,a.jsxs)("span",{className:"text-muted-foreground",children:[" â ",e.rejection_note]})]}),"duplicate"===e.rejection_reason&&e.similar_image_id&&(0,a.jsxs)("a",{href:`/gallery/${e.similar_image_id}`,target:"_blank",rel:"noopener noreferrer",className:"mt-2 block rounded-lg border border-border/50 p-2 hover:bg-muted/30 transition-colors",onClick:e=>e.stopPropagation(),children:[(0,a.jsx)("p",{className:"text-xs text-muted-foreground mb-1.5",children:"Duplicate of:"}),(0,a.jsx)("img",{src:`${x}/v1/images/${e.similar_image_id}/thumbnail`,alt:"Original image",className:"w-full max-w-[768px] rounded object-contain",loading:"lazy"}),(0,a.jsxs)("p",{className:"mt-1 text-xs text-blue-500 hover:underline",children:[e.similar_image_id.slice(0,8),"... â"]})]})]}),e.review_note&&(0,a.jsxs)("div",{children:[(0,a.jsx)("p",{className:"text-xs font-medium text-muted-foreground",children:"Review reason"}),(0,a.jsx)("p",{className:"text-sm text-amber-500",children:e.review_note})]}),null!==e.user_context&&void 0!==e.user_context&&(0,a.jsxs)("div",{className:"rounded-md border border-card-border bg-muted/30 p-3",children:[(0,a.jsx)("div",{className:"mb-1 text-xs font-semibold uppercase tracking-wider text-muted-foreground",children:"User context"}),(0,a.jsxs)("div",{className:"text-sm text-foreground",children:['"',e.user_context,'"']}),e.user_context_updated_at&&(0,a.jsxs)("div",{className:"mt-1 text-xs text-muted-foreground",children:["Updated ",new Date(e.user_context_updated_at).toLocaleStr
1ing()]}),e.user_context_assessment&&"not_provided"!==e.user_context_assessment&&(0,a.jsxs)("div",{className:"mt-2 text-xs",children:["LLM assessment:"," ",(0,a.jsx)("span",{className:"helpful"===e.user_context_assessment?"text-green-600":"misleading"===e.user_context_assessment?"text-amber-500":"text-muted-foreground",children:e.user_context_assessment})]}),e.user_context_assessment_reasoning&&(0,a.jsxs)("div",{className:"mt-1 text-xs italic text-muted-foreground",children:['"',e.user_context_assessment_reasoning,'"']})]}),(0,a.jsxs)("div",{className:"flex gap-4 text-xs text-muted-foreground",children:[e.width&&e.height&&(0,a.jsxs)("span",{children:[e.width,"\xd7",e.height]}),e.size&&(0,a.jsxs)("span",{children:[(e.size/1024).toFixed(0)," KB"]}),(0,a.jsxs)("span",{children:["ID: ",e.id.slice(0,8),"..."]})]}),e.phash&&(0,a.jsx)(v,{imageId:e.id}),(0,a.jsxs)("div",{className:"flex gap-2 pt-2",children:[g&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("button",{onClick:()=>n("approve"),disabled:s,className:"rounded bg-green-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-green-700 disabled:opacity-50",children:"Approve"}),(0,a.jsx)("button",{onClick:()=>n("reject"),disabled:s,className:"rounded bg-orange-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-orange-700 disabled:opacity-50",children:"Reject"})]}),(0,a.jsx)("button",{onClick:c,disabled:s||"pending"===e.status,className:"rounded border border-accent px-3 py-1.5 text-xs font-medium text-accent-text hover:bg-accent/10 disabled:opacity-50",children:"Re-tag"}),(0,a.jsx)("button",{onClick:()=>n("delete"),disabled:s,className:"rounded bg-red-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-red-700 disabled:opacity-50",children:"Delete"})]}),l&&(0,a.jsx)(y.O,{busy:s,onSubmit:i,onCancel:d})]})]})})})}var _=s(69534);let w=(0,r.memo)(function({image:e,selected:t,expanded:s,busy:r,rejecting:l,onToggleSelect:n,onToggleExpand:i,onAction:d,onRejectSubmit:c,onRejectCancel:m,onRetag:x,onFilterUploader:u,onOpenModal:p,regeneratingSocialCard:g=!1,onRegenerateSocialCard:b,apiUrl:v}){let y=v??(0,o.e9)(),w=["pending","needs_review","rejected"].includes(e.status),S=`${y}/v1/images/${e.id}/thumbnail`,k=[...Array.isArray(e.tags)?e.tags.map(e=>e.tag):[],...Array.isArray(e.free_tags)?e.free_tags.map(e=>e.tag):[]],C=k.slice(0,3),R=k.length-C.length;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("tr",{className:`border-b border-card-border hover:bg-muted/50 ${s?"bg-muted/30":""} ${r?"opacity-50 pointer-events-none":""}`,onClick:i,style:{cursor:"pointer"},children:[(0,a.jsx)("td",{className:"px-2 py-2",onClick:e=>e.stopPropagation(),children:(0,a.jsx)("input",{type:"checkbox",checked:t,onChange:e=>n(e.nativeEvent instanceof MouseEvent&&e.nativeEvent.shiftKey),className:"accent-accent","aria-label":`Select image ${e.id}`})}),(0,a.jsx)("td",{className:"px-2 py-2",children:(0,a.jsx)("img",{src:S,alt:"",className:"h-12 w-12 rounded object-cover bg-muted",loading:"lazy",onError:t=>{let s=t.target,a=`${y}/v1/images/${e.id}`;s.src!==a?s.src=a:s.style.display="none"}})}),(0,a.jsx)("td",{className:"px-2 py-2",children:(0,a.jsxs)("div",{className:"flex items-center gap-1.5 flex-wrap",children:[(0,a.jsx)(h.W,{status:e.status}),(0,a.jsx)(_.x,{heldAt:e.takedown_hold_at}),null!=e.quality_score&&(0,a.jsxs)("span",{className:`text-xs px-1.5 py-0.5 rounded font-mono ${e.quality_score>=7?"bg-green-500/20 text-green-500":e.quality_score>=3?"bg-yellow-500/20 text-yellow-500":"bg-red-500/20 text-red-500"}`,children:["Q:",e.quality_score]}),e.review_note&&(0,a.jsx)("span",{className:"text-[0.65em] px-1.5 py-0.5 rounded bg-amber-500/15 text-amber-500 max-w-[160px] truncate",title:e.review_note,children:e.review_note})]})}),(0,a.jsx)("td",{className:"px-2 py-2",children:(0,a.jsx)(f,{flags:e.risk_flags})}),(0,a.jsx)("td",{className:"max-w-[200px] truncate px-2 py-2 text-foreground",title:e.caption||"",children:e.caption?e.caption.slice(0,60)+(e.caption.length>60?"...":""):(0,a.jsx)("span",{className:"text-muted-foreground",children:"â"})}),(0,a.jsx)("td",{className:"px-2 py-2",onClick:e=>e.stopPropagation(),children:e.uploader_id?(0,a.jsx)("button",{onClick:()=>u(e.uploader_id,e.uploader_display_name||e.uploader_pubkey?.slice(0,8)||e.uploader_id.slice(0,8)),className:"text-muted-foreground hover:text-accent-text hover:underline",title:"Filter by this uploader",children:e.uploader_display_name||(e.uploader_pubkey?e.uploader_pubkey.slice(0,8)+"...":"â")}):(0,a.jsx)("span",{className:"text-muted-foreground",children:"â"})}),(0,a.jsx)("td",{className:"px-2 py-2",children:(0,a.jsxs)("div",{className:"flex flex-wrap gap-1",children:[C.map(e=>(0,a.jsx)("span",{className:"rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground",children:e},e)),R>0&&(0,a.jsxs)("span",{className:"text-xs text-muted-foreground",children:["+",R]})]})}),(0,a.jsx)("td",{className:"px-2 py-2 text-muted-foreground",children:e.zap_total_sats?(0,a.jsxs)("span",{className:"inline-flex items-center gap-0.5",children:[(0,a.jsx)(j.Iv,{className:"h-3.5 w-3.5"}
1),e.zap_total_sats.toLocaleString()]}):"â"}),(0,a.jsx)("td",{className:"whitespace-nowrap px-2 py-2 text-muted-foreground",children:(e=>{let t=Math.floor((Date.now()-new Date(e).getTime())/6e4);if(t<60)return`${t}m ago`;let s=Math.floor(t/60);if(s<24)return`${s}h ago`;let a=Math.floor(s/24);return`${a}d ago`})(e.created_at)}),(0,a.jsx)("td",{className:"hidden md:table-cell px-2 py-2 text-center",onClick:e=>e.stopPropagation(),children:g?(0,a.jsx)("span",{className:"inline-block h-4 w-4 animate-spin rounded-full border-2 border-accent border-t-transparent"}):e.has_social_card?(0,a.jsx)("a",{href:`${y}/v1/images/${e.id}/social-card`,target:"_blank",rel:"noopener noreferrer",className:"inline-flex text-accent-text hover:text-accent",title:"View social card",children:(0,a.jsx)(j.nM,{className:"h-4 w-4"})}):(0,a.jsx)("button",{onClick:b,className:"inline-flex text-muted-foreground hover:text-accent",title:"Generate social card","aria-label":"Generate social card",children:(0,a.jsx)(j.PE,{className:"h-4 w-4"})})}),(0,a.jsx)("td",{className:"px-2 py-2",onClick:e=>e.stopPropagation(),children:(0,a.jsxs)("div",{className:"flex gap-1",children:[w&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("button",{onClick:()=>d("approve"),title:"Approve","aria-label":"Approve image",className:"rounded bg-green-600 px-2 py-1 text-xs text-white hover:bg-green-700",children:"â"}),(0,a.jsx)("button",{onClick:()=>d("reject"),title:"Reject","aria-label":"Reject image",className:"rounded bg-orange-600 px-2 py-1 text-xs text-white hover:bg-orange-700",children:"â"})]}),(0,a.jsx)("button",{onClick:()=>d("delete"),title:"Delete","aria-label":"Delete image",className:"rounded border border-red-500 px-2 py-1 text-xs text-red-500 hover:bg-red-500/10",children:"Del"})]})})]}),s&&(0,a.jsx)(N,{image:e,expanded:s,busy:r,rejecting:l,onAction:d,onRejectSubmit:c,onRejectCancel:m,onRetag:x,onOpenModal:p})]})});var S=s(91097);let k=[{label:"Thumb",className:"w-14 px-2 py-2"},{label:"Status",className:"px-2 py-2"},{label:"Risk",className:"px-2 py-2"},{label:"Caption",className:"px-2 py-2"},{label:"Uploader",className:"px-2 py-2"},{label:"Tags",className:"px-2 py-2"},{label:"Zaps",className:"px-2 py-2"},{label:"Created",className:"px-2 py-2"},{label:"Social",className:"hidden md:table-cell px-2 py-2 text-center"},{label:"Actions",className:"px-2 py-2"}];function C(){let e=function(){let[e,t]=(0,r.useState)([]),[s,a]=(0,r.useState)(0),[l,n]=(0,r.useState)(!0),[o,m]=(0,r.useState)(""),[x,u]=(0,r.useState)(""),[p,g]=(0,r.useState)(""),[h,b]=(0,r.useState)({nsfw:!1,gore:!1,spam:!1}),[f,j]=(0,r.useState)(!1),[v,y]=(0,r.useState)(!1),[N,_]=(0,r.useState)(!1),[w,S]=(0,r.useState)(null),[k,C]=(0,r.useState)("created_at:desc"),[R,$]=(0,r.useState)(null),[F,A]=(0,r.useState)(""),[P,D]=(0,r.useState)(0),[L,E]=(0,r.useState)(50),[z,M]=(0,r.useState)(0),I=(0,r.useCallback)(()=>M(e=>e+1),[]),[U,H]=(0,r.useState)(null),[O,B]=(0,r.useState)(new Set),T=(0,r.useRef)(null),[q,G]=(0,r.useState)(null);(0,r.useEffect)(()=>{D(0),B(new Set),H(null),T.current=null},[p,x,h,k,R,F,N,w]),(0,r.useEffect)(()=>{let e=!1;return(0,i.nr)("/v1/admin/moderation/queue-count").then(t=>{!e&&t&&"number"==typeof t.count&&G(t.count)}).catch(()=>{}),()=>{e=!0}},[]);let K=(0,r.useRef)(null);(0,r.useEffect)(()=>{K.current?.abort();let e=new AbortController;K.current=e,n(!0),m("");let s=x.trim();if(s&&d.test(s))return(0,i.nr)(`/v1/images/${s}/meta`,{signal:e.signal}).then(s=>{e.signal.aborted||(t([s]),a(1),n(!1))}).catch(s=>{if(!e.signal.aborted&&s?.name!=="AbortError"){if(s instanceof i.hD&&404===s.status){t([]),a(0),n(!1);return}m(s?.message||"Failed to load image"),n(!1)}}),()=>e.abort();let[r,l]=k.split(":");return(0,i.nr)("/v1/images/search",{params:{status:p||void 0,q:s||void 0,has_nsfw:h.nsfw||void 0,has_gore:h.gore||void 0,has_spam:h.spam||void 0,has_similar:f||void 0,needs_rehash:v||void 0,has_user_context:N||void 0,user_context_assessment:w||void 0,llm_model:F||void 0,uploader_id:R?.id||void 0,sort_by:r,sort_order:l,limit:L,offset:P*L},signal:e.signal}).then(s=>{e.signal.aborted||(t(s.images||[]),a(s.total||0),n(!1))}).catch(t=>{e.signal.aborted||t?.name!=="AbortError"&&(m(t?.message||"Failed to load images"),n(!1))}),()=>e.abort()},[x,p,h,f,v,N,w,k,R,F,P,L,z]);let W=(0,r.useCallback)((t,s)=>{let a=e.findIndex(e=>e.id===t);if(s&&null!==T.current&&T.current!==a){let t=Math.min(T.current,a),s=Math.max(T.current,a);B(a=>
1{let r=new Set(a);for(let a=t;a<=s;a++){let t=e[a];t&&r.add(t.id)}return r})}else B(e=>{let s=new Set(e);return s.has(t)?s.delete(t):s.add(t),s});T.current=a},[e]),Q=(0,r.useCallback)(()=>{B(t=>t.size===e.length?new Set:new Set(e.map(e=>e.id)))},[e]);return{images:e,total:s,loading:l,error:o,setError:m,search:x,setSearch:u,statusFilter:p,setStatusFilter:g,riskFlags:h,setRiskFlags:b,hasSimilar:f,setHasSimilar:j,needsRehash:v,setNeedsRehash:y,hasUserContext:N,setHasUserContext:_,userContextAssessment:w,setUserContextAssessment:S,sort:k,setSort:C,uploaderFilter:R,setUploaderFilter:$,modelFilter:F,setModelFilter:A,page:P,setPage:D,pageSize:L,setPageSize:E,pageSizeOptions:c,refetch:I,selected:O,setSelected:B,toggleSelect:W,toggleSelectAll:Q,expandedId:U,setExpandedId:H,queueCount:q}}(),t=(0,m.N)(()=>e.refetch()),[s,x]=(0,r.useState)(null),[h,b]=(0,r.useState)(null),[f,j]=(0,r.useState)(null),[v,y]=(0,r.useState)(null),[N,_]=(0,r.useState)(!1),[C,R]=(0,r.useState)({generated:0,failed:0}),[$,F]=(0,r.useState)(new Set),A=(0,r.useCallback)(async()=>{try{let e=await (0,i.nr)("/v1/admin/social-cards/stats");y(e)}catch{}},[]);(0,r.useEffect)(()=>{A()},[A]);let P=(0,r.useCallback)(async()=>{if(!v||0===v.without_card)return;_(!0),R({generated:0,failed:0});let t=null,s=0,a=0,r=setInterval(()=>void A(),5e3);try{for(;;){let e={limit:"30"};t&&(e.cursor=t);let r=await (0,i.nr)("/v1/admin/social-cards/backfill",{method:"POST",params:e});if(s+=r.generated,a+=r.failed,R({generated:s,failed:a}),t=r.last_id,r.isolate_corrupted){await new Promise(e=>setTimeout(e,3e4));continue}if(!r.has_more)break;await new Promise(e=>setTimeout(e,500))}}catch(e){console.error("Backfill failed:",e),alert(`Backfill stopped: ${e instanceof Error?e.message:"unknown"}`)}finally{clearInterval(r),_(!1),A(),e.refetch()}},[v,A,e]),D=(0,r.useCallback)(async t=>{F(e=>new Set(e).add(t));try{await (0,i.nr)(`/v1/admin/images/${t}/regenerate-social-card`,{method:"POST"}),e.refetch(),A()}catch(e){console.error("Regenerate social card failed:",e),alert(`Failed to regenerate: ${e instanceof Error?e.message:"unknown"}`)}finally{F(e=>{let s=new Set(e);return s.delete(t),s})}},[e,A]),L=(0,o.e9)(),E=e.error||t.error,z=t=>{e.setSelected(e=>{if(!e.has(t))return e;let s=new Set(e);return s.delete(t),s}),e.expandedId===t&&e.setExpandedId(null)},M=s=>{let a=Array.from(e.selected);if(0===a.length)return;let r=()=>{j(null),t.bulkAction(s,a).then(t=>{t&&e.setSelected(new Set)})};if("delete"===s)j({title:"Delete images",message:`Delete ${a.length} images permanently?`,confirmLabel:"Delete",destructive:!0,onConfirm:r});else{let e="approve"===s?"Approve":"Reject";j({title:`${e} images`,message:`${e} ${a.length} images?`,confirmLabel:e,destructive:"reject"===s,onConfirm:r})}};return(0,a.jsxs)("div",{className:"mt-4",children:[E&&(0,a.jsxs)("div",{className:"mb-4 flex items-center justify-between rounded-xl border border-red-500/30 bg-red-500/10 px-4 py-2 text-sm text-red-500",children:[E,(0,a.jsx)("button",{onClick:()=>{e.setError(""),t.setError("")},"aria-label":"Dismiss",className:"font-semibold hover:text-red-400",children:"\xd7"})]}),(0,a.jsxs)(n.SafeLink,{href:"/admin/moderate",className:"mb-4 flex items-center justify-between rounded-xl border-2 border-accent bg-accent/10 px-4 py-3 text-sm font-semibold text-accent-text transition hover:bg-accent/20",children:[(0,a.jsx)("span",{children:"Open Moderation Queue"}),(0,a.jsx)("span",{className:"rounded-full bg-accent/20 px-3 py-1 text-xs",children:null===e.queueCount?"â¦":`${e.queueCount} pending`})]}),(0,a.jsx)(u,{search:e.search,setSearch:e.setSearch,onSearchEnter:e.refetch,statusFilter:e.statusFilter,setStatusFilter:e.setStatusFilter,riskFlags:e.riskFlags,setRiskFlags:e.setRiskFlags,hasSimilar:e.hasSimilar,setHasSimilar:e.setHasSimilar,needsRehash:e.needsRehash,setNeedsRehash:e.setNeedsRehash,hasUserContext:e.hasUserContext,setHasUserContext:e.setHasUserContext,userContextAssessment:e.userContextAssessment,setUserContextAssessment:e.setUserContextAssessment,sort:e.sort,setSort:e.setSort,modelFilter:e.modelFilter,setModelFilter:e.setModelFilter,uploaderFilter:e.uploaderFilter,setUploaderFilter:e.setUploaderFilter}),v&&(0,a.jsxs)("div",{className:"mb-3 flex flex-wrap items-center gap-3 text-sm",children:[(0,a.jsxs)("span",{className:"text-muted-foreground",children:["Social cards:"," ",(0,a.jsx)("strong",{className:"text-foreground",children:v.with_card.toLocaleStr
1ing()})," / ",v.total.toLocaleString()]}),v.without_card>0&&(0,a.jsx)("button",{onClick:()=>void P(),disabled:N,className:"rounded-md bg-accent px-3 py-1.5 text-xs font-medium text-accent-foreground hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60",children:N?`Generating⦠${C.generated.toLocaleString()} / ${v.without_card.toLocaleString()}`:`Generate Missing (${v.without_card.toLocaleString()})`}),C.failed>0&&(0,a.jsxs)("span",{className:"text-danger",children:[C.failed," failed"]})]}),(0,a.jsxs)("p",{className:"mb-2 text-xs text-muted-foreground",children:[e.total," images"]}),e.search.trim()&&d.test(e.search.trim())&&e.images.length>0&&(0,a.jsxs)("div",{className:"mt-2 text-xs text-muted-foreground",children:["Showing exact match for ID: ",(0,a.jsx)("code",{className:"text-foreground",children:e.search.trim()})]}),e.loading?(0,a.jsx)("div",{className:"flex justify-center py-8",children:(0,a.jsx)("div",{className:"h-8 w-8 animate-spin rounded-full border-4 border-muted border-t-accent"})}):0===e.images.length?(0,a.jsx)("p",{className:"py-8 text-center text-sm text-muted-foreground",children:"No images found"}):(0,a.jsx)("div",{className:"overflow-x-auto",children:(0,a.jsxs)("table",{className:"w-full text-sm",children:[(0,a.jsx)("thead",{children:(0,a.jsxs)("tr",{className:"border-b-2 border-card-border text-left text-muted-foreground",children:[(0,a.jsx)("th",{scope:"col",className:"w-8 px-2 py-2",children:(0,a.jsx)("input",{type:"checkbox",checked:e.selected.size===e.images.length&&e.images.length>0,onChange:e.toggleSelectAll,className:"accent-accent","aria-label":"Select all images on page"})}),k.map(e=>(0,a.jsx)("th",{scope:"col",className:e.className,children:e.label},e.label))]})}),(0,a.jsx)("tbody",{children:e.images.map(l=>(0,a.jsx)(r.Fragment,{children:(0,a.jsx)(w,{image:l,selected:e.selected.has(l.id),expanded:e.expandedId===l.id,busy:t.busyIds.has(l.id),rejecting:s===l.id,onToggleSelect:t=>e.toggleSelect(l.id,t),onToggleExpand:()=>e.setExpandedId(e.expandedId===l.id?null:l.id),onAction:s=>{var a;return a=l.id,void(e.selected.size>1&&e.selected.has(a)?M(s):"reject"===s?x(a):"delete"===s?j({title:"Delete image",message:"Delete this image permanently?",confirmLabel:"Delete",destructive:!0,onConfirm:()=>{j(null),t.deleteImage(a).then(e=>{e&&z(a)})}}):t.approve(a).then(e=>{e&&z(a)}))},onRejectSubmit:e=>{var s;return s=l.id,void t.reject(s,e).then(e=>{e&&(x(null),z(s))})},onRejectCancel:()=>x(null),onRetag:()=>void t.retag(l.id),onFilterUploader:(t,s)=>e.setUploaderFilter({id:t,name:s}),onOpenModal:()=>b(l.id),regeneratingSocialCard:$.has(l.id),onRegenerateSocialCard:()=>void D(l.id),apiUrl:L})},l.id))})]})}),(0,a.jsx)(p,{selectedCount:e.selected.size,bulkBusy:t.bulkBusy,onBulkApprove:()=>M("approve"),onBulkReject:()=>M("reject"),onBulkDelete:()=>M("delete"),onBulkRehash:()=>void t.bulkRehash(Array.from(e.selected)),onBulkHash:()=>{t.bulkHash(Array.from(e.selected)).then(t=>{t&&e.setSelected(new Set)})},onBulkReprocess:()=>{let s=Array.from(e.selected);0!==s.length&&j({title:"Full Reload images",message:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("p",{children:["Full Reload ",s.length," image(s)?"]}),(0,a.jsx)("p",{className:"mt-2",children:"This will reprocess them through the entire pipeline (canonical, thumbnail, phash, LLM tags, embedding)."}),(0,a.jsx)("p",{className:"mt-2",children:"Old derived files will be deleted and regenerated."})]}),confirmLabel:"Full Reload",destructive:!0,onConfirm:()=>{j(null),t.bulkReprocess(s).then(t=>{t&&e.setSelected(new Set)})}})},onBulkRetag:()=>void t.bulkRetag(Array.from(e.selected))}),(0,a.jsx)(g,{page:e.page,setPage:e.setPage,pageSize:e.pageSize,setPageSize:e.setPageSize,totalPages:Math.ceil(e.total/e.pageSize),pageSizeOptions:e.pageSizeOptions}),h&&(0,a.jsx)(l.ImageModal,{images:e.images,selectedId:h,onClose:()=>b(null),onNavigate:e=>b(e),onTagClick:()=>{},onImageDeleted:()=>{b(null),e.refetch()}}),(0,a.jsx)(S.u,{open:null!==f,title:f?.title??"",message:f?.message??"",confirmLabel:f?.confirmLabel,destructive:f?.destructive??!1,onConfirm:()=>f?.onConfirm(),onCancel:()=>j(null)})]})}},69534:(e,t,s)=>{s.d(t,{x:()=>r});var a=s(54568);function r({heldAt:e}){if(!e)return null;let t=new Date(e),s=Number.isNaN(t.getTime())?"A takedown notice holds this image â decide it in Reports":`A takedown notice has held this image since ${t.toLocaleStr
1ing()} â decide it in Reports`;return(0,a.jsx)("span",{className:"rounded bg-red-600 px-1.5 py-0.5 text-xs font-semibold text-white",title:s,children:"Held by takedown"})}}}]);
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.