secure-redact 1.0.0 โ†’ 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -104,5 +104,5 @@ Valid types: NAME, PHONE_NUMBER, EMAIL, ADDRESS, AADHAAR, PAN, CREDIT_CARD, DOB,
104
104
  If no sensitive information is found, return an empty array: []
105
105
 
106
106
  Here is the document data:
107
- ${JSON.stringify(s)}`,e=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contents:[{parts:[{text:i}]}],generationConfig:{temperature:.1,topP:.8,maxOutputTokens:4096}})});if(!e.ok){const b=await e.text().catch(()=>"");throw new Error(`Gemini API error ${e.status}: ${b||e.statusText}`)}const d=(await e.json())?.candidates?.[0]?.content?.parts?.[0]?.text??"",a=d.match(/\[[\s\S]*\]/);if(!a)return[];let n=[];try{n=JSON.parse(a[0])}catch{return console.warn("[Gemini WordID] Returned invalid JSON:",d),[]}const Z=n.filter(b=>b&&typeof b.type=="string"&&typeof b.value=="string"&&Array.isArray(b.wordIds)&&b.wordIds.length>0&&b.wordIds.every(h=>typeof h=="number"));return console.log(`[Gemini WordID] Detected ${Z.length} PII entities`),Z}function G2(s,t){return!t||t.length===0?[]:t.map(l=>{const i=s.filter((n,Z)=>l.wordIds.includes(Z));if(i.length===0)return console.warn(`[Redaction Masks] No matching words found for entity: ${l.value}`),null;const e=Math.min(...i.map(n=>n.bbox.x)),c=Math.min(...i.map(n=>n.bbox.y)),d=Math.max(...i.map(n=>n.bbox.x+n.bbox.w)),a=Math.max(...i.map(n=>n.bbox.y+n.bbox.h));return{id:crypto.randomUUID(),type:m2(l.type),textValue:l.value,coordinates:{startX:e,startY:c,endX:d,endY:a},selectedForMasking:!0}}).filter(l=>l!==null)}const Ld=4;function r2(s,t=0){return s.map(l=>({id:"wid_"+l.id.substring(0,8),type:l.type,value:l.textValue,confidence:.95,bbox:{x:Math.max(0,l.coordinates.startX-Ld),y:Math.max(0,l.coordinates.startY-Ld),w:l.coordinates.endX-l.coordinates.startX+Ld*2,h:l.coordinates.endY-l.coordinates.startY+Ld*2,pageIndex:t},masked:l.selectedForMasking,layer:4}))}async function N2(s,t,l=0,i){if(!t||s.length===0)return[];i?.("Running word-ID PII detection...");const e=await u2(s,t,i);if(e.length===0)return console.log("[WordID Pipeline] No PII detected by Gemini"),[];i?.("Calculating redaction coordinates...");const c=G2(s,e),d=r2(c,l);return console.log(`[WordID Pipeline] Generated ${d.length} entities from ${e.length} PII detections`),d}const yi=5;function X2(s,t=0){return s.map(l=>({text:l.text,left:l.bbox.x,top:l.bbox.y,width:l.bbox.w,height:l.bbox.h,pageIndex:l.bbox.pageIndex??t,redact:!1}))}function M2(s,t,l=[]){const i=[],e=a=>a.toLowerCase().replace(/[^a-z0-9\u0900-\u097F]/g,""),c=new Set,d=[];for(const a of t){const Z=a.trim().split(/\s+/).filter(b=>b.length>0).map(e).filter(b=>b.length>0);Z.length!==0&&(Z.length===1?c.add(Z[0]):d.push({original:a.trim(),tokens:Z}))}for(const a of d){const{tokens:n,original:Z}=a;for(let b=0;b<=s.length-n.length;b++){let h=!0;for(let m=0;m<n.length;m++)if(e(s[b+m].text)!==n[m]){h=!1;break}if(h){const m=s.slice(b,b+n.length);for(let r=0;r<n.length;r++)s[b+r].redact=!0;const o=Math.min(...m.map(r=>r.left)),u=Math.min(...m.map(r=>r.top)),W=Math.max(...m.map(r=>r.left+r.width)),N=Math.max(...m.map(r=>r.top+r.height));i.push({x:o-yi,y:u-yi,w:W-o+yi*2,h:N-u+yi*2,pageIndex:m[0].pageIndex,matchedPhrase:Z,matchedWords:m.map(r=>r.text)})}}if(!i.some(b=>b.matchedPhrase===Z)){const b=n[0];for(let h=0;h<s.length;h++){if(e(s[h].text)!==b)continue;const m=[s[h]];let o=1;for(let u=h+1;u<Math.min(s.length,h+n.length*2)&&o<n.length;u++)e(s[u].text)===n[o]&&(m.push(s[u]),o++);if(m.length>=Math.ceil(n.length*.6)){for(const X of m)X.redact=!0;const u=Math.min(...m.map(X=>X.left)),W=Math.min(...m.map(X=>X.top)),N=Math.max(...m.map(X=>X.left+X.width)),r=Math.max(...m.map(X=>X.top+X.height));i.push({x:u-yi,y:W-yi,w:N-u+yi*2,h:r-W+yi*2,pageIndex:m[0].pageIndex,matchedPhrase:Z,matchedWords:m.map(X=>X.text)});break}}}}for(let a=0;a<s.length;a++){const n=s[a];if(n.redact)continue;const Z=e(n.text);Z.length!==0&&c.has(Z)&&(n.redact=!0,i.push({x:n.left-yi,y:n.top-yi,w:n.width+yi*2,h:n.height+yi*2,pageIndex:n.pageIndex,matchedPhrase:n.text,matchedWords:[n.text]}))}return y2(i)}function y2(s){if(s.length<=1)return s;const t=[...s].sort((i,e)=>i.pageIndex!==e.pageIndex?i.pageIndex-e.pageIndex:Math.abs(i.y-e.y)>5?i.y-e.y:i.x-e.x),l=[t[0]];for(let i=1;i<t.length;i++){const e=t[i],c=l[l.length-1];if(e.pageIndex===c.pageIndex&&e.x<=c.x+c.w+2&&e.y<=c.y+c.h+2&&e.y+e.h>=c.y-2){const d=Math.min(c.x,e.x),a=Math.min(c.y,e.y),n=Math.max(c.x+c.w,e.x+e.w),Z=Math.max(c.y+c.h,e.y+e.h);c.x=d,c.y=a,c.w=n-d,c.h=Z-a,c.matchedWords=[...c.matchedWords,...e.matchedWords],c.matchedPhrase+=" | "+e.matchedPhrase}else l.push({...e})}return l}function Y2(s){return s.map(t=>({id:"mz_"+crypto.randomUUID().substring(0,8),type:"SENSITIVE",value:t.matchedPhrase,confidence:.9,bbox:{x:Math.max(0,t.x),y:Math.max(0,t.y),w:t.w,h:t.h,pageIndex:t.pageIndex},masked:!0,layer:3}))}async function p2(s,t,l,i=.5,e=[],c=0,d){const a=X2(t,c);console.log(`[Pipeline] Spatial map: ${a.length} entries`),console.log(`[Pipeline] fullText length: ${s.length}, first 100 chars: "${s.substring(0,100)}"`),d?.("Running deterministic detection...");const n=s2(s,t,c);console.log("[Pipeline] Layer 1 entities:",n.length),d?.("Running local NLP analysis...");let Z=[];try{Z=await T2(t,c),console.log("[Pipeline] NLP heuristic entities:",Z.length)}catch(u){console.warn("[Pipeline] NLP worker failed:",u)}let b=[];if(l){try{d?.("Running Gemini word-ID detection...");const u=await un(()=>N2(t,l,c,d),2,5e3);u.length>0&&(b=u,console.log(`[Pipeline] Word-ID detection: ${b.length} entities (pixel-perfect)`))}catch(u){console.warn("[Pipeline] Gemini word-ID detection failed:",u)}if(b.length===0)try{d?.("Trying semantic filter fallback...");const u=await un(()=>Z2(s,e,l,d),2,5e3);if(u.length>0&&a.length>0){d?.("Calculating redaction zones...");const W=M2(a,u,e);b=Y2(W),console.log("[Pipeline] Semantic filter fallback:",b.length,"entities")}}catch(u){console.warn("[Pipeline] Semantic filter fallback failed:",u);try{b=await un(()=>b2(s,t,l,c,d),1,5e3),console.log("[Pipeline] Legacy Gemini fallback:",b.length,"entities")}catch{console.warn("[Pipeline] All Gemini strategies failed. Using Layer 1 + NLP only.")}}}const h=[...n,...Z,...b],o=V2(h).filter(u=>u.confidence>=i);for(const u of o)e.includes(u.type)&&(u.masked=!1);return console.log(`[Pipeline] Final: ${o.length} entities (${o.filter(u=>u.masked).length} masked, ${o.filter(u=>!u.masked).length} visible)`),o}function T2(s,t){return new Promise((l,i)=>{const e=new Worker(new URL("/assets/nlp.worker-u7Lr_A3c.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:al&&al.tagName.toUpperCase()==="SCRIPT"&&al.src||new URL("secure-redact.umd.js",document.baseURI).href),{type:"module"}),c=setTimeout(()=>{e.terminate(),i(new Error("NLP worker timed out"))},1e4);e.onmessage=d=>{clearTimeout(c),e.terminate(),d.data.type==="NLP_ERROR"?i(new Error(d.data.error)):d.data.type==="NLP_RESULT"&&l(d.data.entities??[])},e.onerror=d=>{clearTimeout(c),e.terminate(),i(d)},e.postMessage({type:"NLP_ANALYZE",text:s.map(d=>d.text).join(" "),words:s,pageIndex:t})})}async function un(s,t,l){let i,e=l;for(let c=0;c<=t;c++)try{return await s()}catch(d){i=d instanceof Error?d:new Error(String(d));const a=i.message.toLowerCase();if(a.includes("resource_exhausted")||a.includes("quota")||a.includes("daily limit")||a.includes("rate limit exceeded"))throw console.warn("[Pipeline] Quota/resource exhausted, skipping retries"),i;if(!a.includes("429")||c>=t)throw i;console.log(`[Pipeline] Rate limited, retrying in ${e/1e3}s (attempt ${c+1}/${t})...`),await new Promise(n=>setTimeout(n,e)),e*=1.5}throw i}function V2(s){const t=[...s].sort((i,e)=>e.confidence-i.confidence),l=[];for(const i of t)l.some(c=>c.bbox.pageIndex===i.bbox.pageIndex&&L2(c.bbox,i.bbox,.5))||l.push(i);return l}function L2(s,t,l){const i=Math.max(0,Math.min(s.x+s.w,t.x+t.w)-Math.max(s.x,t.x)),e=Math.max(0,Math.min(s.y+s.h,t.y+t.h)-Math.max(s.y,t.y)),c=i*e,d=Math.min(s.w*s.h,t.w*t.h);return d>0&&c/d>l}const Wn=[{key:"loading",label:"Loading"},{key:"ocr",label:"Text Extraction"},{key:"detection",label:"PII Detection"},{key:"review",label:"Review"}],I2=({stage:s,progress:t,message:l})=>{const i=Wn.findIndex(e=>e.key===s);return C.jsxs("div",{className:"su-progress-container",children:[C.jsx("div",{className:"su-progress-steps",children:Wn.map((e,c)=>{let d="pending";return c<i?d="done":c===i&&(d="active"),C.jsxs("div",{className:"su-progress-step-wrapper",children:[C.jsxs("div",{className:`su-progress-step su-progress-step--${d}`,children:[C.jsx("div",{className:"su-progress-dot",children:d==="done"?C.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:C.jsx("path",{d:"M2 6L5 9L10 3",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):d==="active"?C.jsx("div",{className:"su-progress-pulse"}):null}),C.jsx("span",{className:"su-progress-label",children:e.label})]}),c<Wn.length-1&&C.jsx("div",{className:`su-progress-line su-progress-line--${c<i?"done":"pending"}`})]},e.key)})}),s==="ocr"&&C.jsxs("div",{className:"su-progress-bar-wrapper",children:[C.jsx("div",{className:"su-progress-bar",children:C.jsx("div",{className:"su-progress-bar-fill",style:{width:`${Math.round(t*100)}%`}})}),C.jsxs("span",{className:"su-progress-percent",children:[Math.round(t*100),"%"]})]}),C.jsx("p",{className:"su-progress-message",children:l})]})},xh={AADHAAR:"Aadhaar Number",PAN:"PAN",CREDIT_CARD:"Credit Card",PHONE:"Phone Number",NAME:"Name",ADDRESS:"Address",MEDICAL:"Medical Information",EMAIL:"Email Address",DOB:"Date of Birth",SENSITIVE:"Sensitive Info"},Dh={AADHAAR:"#ef4444",PAN:"#f97316",CREDIT_CARD:"#eab308",PHONE:"#22c55e",NAME:"#3b82f6",ADDRESS:"#8b5cf6",MEDICAL:"#ec4899",EMAIL:"#06b6d4",DOB:"#14b8a6",SENSITIVE:"#6b7280"},z2=({entities:s,imageDataUrl:t,fileName:l,onConfirm:i,onCancel:e,requiredFields:c,confidenceThreshold:d})=>{const a=Xt.useRef(null),[n,Z]=Xt.useState(s),[b,h]=Xt.useState({width:0,height:0}),[m,o]=Xt.useState(1);Xt.useEffect(()=>{Z(s)},[s]),Xt.useEffect(()=>{if(!t||!a.current)return;const X=a.current,M=X.getContext("2d");if(!M)return;const p=new Image;p.onload=()=>{const V=X.parentElement?.clientWidth??800,T=Math.min(1,V/p.naturalWidth);o(T),h({width:p.naturalWidth,height:p.naturalHeight}),X.width=p.naturalWidth*T,X.height=p.naturalHeight*T,M.drawImage(p,0,0,X.width,X.height),u(M,n,T)},p.src=t},[t,n]);function u(X,M,p){for(const V of M){const{x:T,y:L,w:S,h:x}=V.bbox,j=T*p,g=L*p,f=S*p,F=x*p,H=Dh[V.type]||"#888";V.masked?(X.fillStyle=H+"33",X.fillRect(j,g,f,F),X.strokeStyle=H,X.lineWidth=2,X.strokeRect(j,g,f,F),X.beginPath(),X.moveTo(j,g),X.lineTo(j+f,g+F),X.moveTo(j+f,g),X.lineTo(j,g+F),X.strokeStyle=H+"66",X.lineWidth=1,X.stroke()):(X.strokeStyle=H,X.lineWidth=2,X.setLineDash([4,4]),X.strokeRect(j,g,f,F),X.setLineDash([]));const A=V.type;X.font=`${Math.max(10,11*p)}px Inter, system-ui, sans-serif`;const k=X.measureText(A),O=16*p,st=g-O;X.fillStyle=H,X.fillRect(j,Math.max(0,st),k.width+8*p,O),X.fillStyle="#ffffff",X.fillText(A,j+4*p,Math.max(O-4*p,st+O-4*p))}}function W(X){Z(M=>M.map(p=>p.id!==X||c.includes(p.type)&&p.masked?p:{...p,masked:!p.masked}))}const N=n.filter(X=>X.masked).length,r=n.filter(X=>!X.masked).length;return C.jsx("div",{className:"su-modal-overlay",onClick:e,children:C.jsxs("div",{className:"su-modal",onClick:X=>X.stopPropagation(),children:[C.jsxs("div",{className:"su-modal-header",children:[C.jsxs("div",{children:[C.jsx("h2",{className:"su-modal-title",children:"Review Detected Information"}),C.jsx("p",{className:"su-modal-subtitle",children:l})]}),C.jsx("button",{className:"su-modal-close",onClick:e,"aria-label":"Close",children:C.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:C.jsx("path",{d:"M5 5L15 15M15 5L5 15",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})})]}),C.jsxs("div",{className:"su-modal-body",children:[C.jsx("div",{className:"su-modal-preview",children:C.jsx("canvas",{ref:a,className:"su-modal-canvas"})}),C.jsxs("div",{className:"su-modal-sidebar",children:[C.jsxs("div",{className:"su-modal-stats",children:[C.jsxs("div",{className:"su-modal-stat",children:[C.jsx("span",{className:"su-modal-stat-value",children:N}),C.jsx("span",{className:"su-modal-stat-label",children:"Masked"})]}),C.jsxs("div",{className:"su-modal-stat",children:[C.jsx("span",{className:"su-modal-stat-value",children:r}),C.jsx("span",{className:"su-modal-stat-label",children:"Visible"})]})]}),C.jsxs("div",{className:"su-modal-entities",children:[C.jsx("h3",{className:"su-modal-section-title",children:"Detected Entities"}),n.length===0&&C.jsx("p",{className:"su-modal-empty",children:"No sensitive information detected."}),n.map(X=>{const M=c.includes(X.type),p=X.confidence<d+.15&&X.confidence>=d;return C.jsxs("div",{className:`su-entity-card ${p?"su-entity-card--warning":""}`,children:[C.jsxs("div",{className:"su-entity-header",children:[C.jsx("div",{className:"su-entity-type",style:{color:Dh[X.type]},children:xh[X.type]||X.type}),C.jsxs("div",{className:"su-entity-confidence",children:[Math.round(X.confidence*100),"%"]})]}),C.jsx("div",{className:"su-entity-value",children:X.masked?w2(X.value):X.value}),M&&!X.masked&&C.jsx("div",{className:"su-entity-required-badge",children:"Required Field"}),p&&!M&&C.jsx("div",{className:"su-entity-warning",children:"Low confidence detection. Please verify this is correct."}),C.jsx("div",{className:"su-entity-actions",children:C.jsxs("button",{className:`su-toggle ${X.masked?"su-toggle--masked":"su-toggle--visible"}`,onClick:()=>W(X.id),disabled:M&&!X.masked,children:[C.jsx("span",{className:"su-toggle-track",children:C.jsx("span",{className:"su-toggle-thumb"})}),C.jsx("span",{className:"su-toggle-label",children:X.masked?"Masked":"Visible"})]})}),!X.masked&&!M&&C.jsxs("div",{className:"su-entity-liability",children:["You are choosing to keep this ",xh[X.type]?.toLowerCase()||"information"," visible."]})]},X.id)})]})]})]}),C.jsxs("div",{className:"su-modal-footer",children:[C.jsx("button",{className:"su-btn su-btn--secondary",onClick:e,children:"Cancel"}),C.jsxs("button",{className:"su-btn su-btn--primary",onClick:()=>i(n),children:["Confirm and Redact (",N," items)"]})]})]})})};function w2(s){return s.length<=4?"*".repeat(s.length):s.substring(0,2)+"*".repeat(s.length-4)+s.substring(s.length-2)}const R2={},S2=25,x2=.5,gh=({requiredFields:s=[],confidenceThreshold:t=x2,onUpload:l,maxFileSizeMB:i=S2,acceptedTypes:e,apiKey:c})=>{const d=c??(typeof{url:typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:al&&al.tagName.toUpperCase()==="SCRIPT"&&al.src||new URL("secure-redact.umd.js",document.baseURI).href}<"u"?R2?.VITE_GEMINI_API_KEY??"":""),[a,n]=Xt.useState("idle"),[Z,b]=Xt.useState(0),[h,m]=Xt.useState(""),[o,u]=Xt.useState(null),[W,N]=Xt.useState(!1),[r,X]=Xt.useState([]),[M,p]=Xt.useState(null),[V,T]=Xt.useState(null),[L,S]=Xt.useState(null),[x,j]=Xt.useState(null),[g,f]=Xt.useState(null),F=Xt.useRef(null),H=Xt.useRef(null),A=Xt.useRef({width:612,height:792});Xt.useEffect(()=>()=>{F.current?.terminate()},[]);const k=Xt.useCallback(()=>(F.current||(F.current=new xd,F.current.setProgressCallback((lt,tt)=>{b(lt),m(tt)})),F.current),[]),O=Xt.useCallback(async lt=>{u(null),n("loading"),m("Preparing document..."),b(0),T(lt);try{if(!kh(lt))throw new Error("Unsupported file type. Please upload an image or PDF.");if(lt.size>i*1024*1024)throw new Error(`File too large. Maximum size is ${i}MB.`);const tt=await Mn(lt);S(tt.buffer),n("ocr"),m("Extracting text from document...");const el=k();let dl=null,Nl=tt.buffer,It=tt.mimeType;if(tt.type==="image"){const{canvas:wl}=await yn(tt.buffer,tt.mimeType);dl=wl.toDataURL()}else{m("Rendering PDF page for OCR...");const{imageBuffer:wl,width:nl,height:gt,canvas:_l}=await Ih(tt.buffer,0);Nl=wl,It="image/png",dl=_l.toDataURL(),A.current={width:nl,height:gt}}const{words:Wl,fullText:gl}=await el.runOCR(Nl,It,0);if(Wl.length===0&&gl.trim().length===0){n("review"),m("No text detected in document."),X([]),p(dl);return}n("detection"),m("Analyzing for sensitive information...");const Ol=await p2(gl,Wl,d,t,s,0,wl=>m(wl));X(Ol),p(dl),n("review"),m(`Found ${Ol.length} item(s). Please review before proceeding.`)}catch(tt){n("error"),u(tt instanceof Error?tt.message:"An unexpected error occurred."),m("")}},[t,s,i,k]),st=Xt.useCallback(async lt=>{if(!(!V||!L)){n("redacting"),m("Applying redaction...");try{const tt=await Mn(V);let el,dl=null;if(tt.type==="image"){const{canvas:It}=await yn(tt.buffer,tt.mimeType);Kh(It,lt),dl=It.toDataURL(),el=await fh(It,`redacted_${V.name}`,tt.mimeType)}else{const It=A.current.width,Wl=A.current.height,gl=await Qo(tt.buffer,lt,It,Wl);el=Bo(gl,`redacted_${V.name}`);try{const{canvas:Ol}=await Ih(gl.buffer.slice(gl.byteOffset,gl.byteOffset+gl.byteLength),0);dl=Ol.toDataURL()}catch{dl=null}}const Nl={timestamp:new Date().toISOString(),fileName:V.name,detectedEntities:lt.map(It=>({type:It.type,confidence:It.confidence,action:It.masked?"masked":"kept_visible",userConfirmed:!0})),requiredFields:s};j(dl),f(el),n("complete"),m("Redaction complete."),l(el,JSON.stringify(Nl,null,2))}catch(tt){n("error"),u(tt instanceof Error?tt.message:"Redaction failed.")}}},[V,L,s,l]),mt=Xt.useCallback(()=>{n("idle"),b(0),m(""),u(null),X([]),p(null),j(null),f(null),T(null),S(null),N(!1)},[]),ft=Xt.useCallback(lt=>{lt.preventDefault(),lt.stopPropagation(),N(!0)},[]),Wt=Xt.useCallback(lt=>{lt.preventDefault(),lt.stopPropagation(),N(!1)},[]),bt=Xt.useCallback(lt=>{lt.preventDefault(),lt.stopPropagation(),N(!1);const tt=lt.dataTransfer.files[0];tt&&O(tt)},[O]),ut=Xt.useCallback(lt=>{const tt=lt.target.files?.[0];tt&&O(tt)},[O]),Ct=Xt.useCallback(()=>{a==="idle"&&H.current?.click()},[a]),vt=["loading","ocr","detection","redacting"].includes(a),wt=e?.join(",")??"image/png,image/jpeg,image/webp,image/bmp,application/pdf";return C.jsxs("div",{className:"su-root",children:[C.jsxs("div",{className:`su-dropzone ${W?"su-dropzone--active":""} ${vt?"su-dropzone--processing":""} ${a==="complete"?"su-dropzone--complete":""} ${a==="error"?"su-dropzone--error":""}`,onDragOver:ft,onDragLeave:Wt,onDrop:bt,onClick:Ct,role:"button",tabIndex:0,"aria-label":"Upload document for PII detection",children:[C.jsx("input",{ref:H,type:"file",className:"su-file-input",accept:wt,onChange:ut}),a==="idle"&&C.jsxs("div",{className:"su-dropzone-content",children:[C.jsx("div",{className:"su-dropzone-icon",children:C.jsxs("svg",{width:"40",height:"40",viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[C.jsx("path",{d:"M20 5L20 25M20 5L13 12M20 5L27 12",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"}),C.jsx("path",{d:"M6 25V31C6 33.2091 7.79086 35 10 35H30C32.2091 35 34 33.2091 34 31V25",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}),C.jsx("p",{className:"su-dropzone-title",children:"Drop your document here"}),C.jsx("p",{className:"su-dropzone-hint",children:"or click to browse"}),C.jsxs("p",{className:"su-dropzone-formats",children:["Supports PNG, JPEG, WebP, BMP, PDF (max ",i,"MB)"]})]}),vt&&C.jsx("div",{className:"su-dropzone-processing",children:C.jsx(I2,{stage:a,progress:Z,message:h})}),a==="complete"&&C.jsxs("div",{className:"su-dropzone-content su-dropzone-content--complete",children:[C.jsx("div",{className:"su-dropzone-icon su-dropzone-icon--success",children:C.jsxs("svg",{width:"40",height:"40",viewBox:"0 0 40 40",fill:"none",children:[C.jsx("circle",{cx:"20",cy:"20",r:"16",stroke:"currentColor",strokeWidth:"2.5"}),C.jsx("path",{d:"M13 20L18 25L27 15",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}),C.jsx("p",{className:"su-dropzone-title",children:"Redaction Complete"}),C.jsx("p",{className:"su-dropzone-hint",children:"Document has been securely processed"})]}),a==="error"&&C.jsxs("div",{className:"su-dropzone-content su-dropzone-content--error",children:[C.jsx("div",{className:"su-dropzone-icon su-dropzone-icon--error",children:C.jsxs("svg",{width:"40",height:"40",viewBox:"0 0 40 40",fill:"none",children:[C.jsx("circle",{cx:"20",cy:"20",r:"16",stroke:"currentColor",strokeWidth:"2.5"}),C.jsx("path",{d:"M15 15L25 25M25 15L15 25",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round"})]})}),C.jsx("p",{className:"su-dropzone-title",children:"Processing Failed"}),C.jsx("p",{className:"su-dropzone-hint",children:o}),C.jsx("button",{className:"su-btn su-btn--secondary su-btn--sm",onClick:lt=>{lt.stopPropagation(),mt()},children:"Try Again"})]}),V&&a!=="idle"&&a!=="error"&&a!=="complete"&&C.jsxs("div",{className:"su-file-badge",children:[C.jsx("span",{className:"su-file-badge-name",children:V.name}),C.jsx("span",{className:"su-file-badge-size",children:Eh(V.size)})]})]}),a==="complete"&&g&&C.jsxs("div",{className:"su-result-panel",children:[C.jsxs("div",{className:"su-result-header",children:[C.jsxs("div",{className:"su-result-title-row",children:[C.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",className:"su-result-check",children:[C.jsx("circle",{cx:"10",cy:"10",r:"8",stroke:"currentColor",strokeWidth:"1.8"}),C.jsx("path",{d:"M6.5 10L9 12.5L13.5 7.5",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})]}),C.jsx("span",{className:"su-result-title",children:"Redacted Document"})]}),C.jsx("span",{className:"su-result-filename",children:g.name})]}),x&&C.jsx("div",{className:"su-result-preview",children:C.jsx("img",{src:x,alt:"Redacted document preview",className:"su-result-img"})}),C.jsxs("div",{className:"su-result-actions",children:[C.jsxs("a",{href:URL.createObjectURL(g),download:g.name,className:"su-btn su-btn--primary",children:[C.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",style:{marginRight:6},children:[C.jsx("path",{d:"M8 2v8M8 10L5 7M8 10l3-3",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"}),C.jsx("path",{d:"M2 13h12",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round"})]}),"Download"]}),C.jsx("button",{className:"su-btn su-btn--secondary",onClick:mt,children:"Process Another Document"})]})]}),a==="review"&&C.jsx(z2,{entities:r,imageDataUrl:M,fileName:V?.name??"document",onConfirm:st,onCancel:mt,requiredFields:s,confidenceThreshold:t})]})},Gn=[{id:"aadhaar",label:"Aadhaar Card",icon:"๐Ÿชช",fields:[{id:"NAME",label:"Name",description:"Full name of the cardholder"},{id:"ADDRESS",label:"Address",description:"Residential address"},{id:"DOB",label:"Date of Birth",description:"Birth date"},{id:"AADHAAR",label:"Aadhaar Number",description:"12-digit UID number"},{id:"PHONE",label:"Phone Number",description:"Registered mobile number"},{id:"GENDER",label:"Gender",description:"Male/Female/Other"},{id:"PHOTO",label:"Photo",description:"Passport-size photograph"},{id:"QR_CODE",label:"QR Code",description:"Machine-readable QR code"}]},{id:"pan",label:"PAN Card",icon:"๐Ÿ’ณ",fields:[{id:"NAME",label:"Name",description:"Name of the cardholder"},{id:"FATHER_NAME",label:"Father's Name",description:"Father's full name"},{id:"DOB",label:"Date of Birth",description:"Birth date"},{id:"PAN",label:"PAN Number",description:"10-character alphanumeric PAN"},{id:"PHOTO",label:"Photo",description:"Photograph on the card"},{id:"SIGNATURE",label:"Signature",description:"Cardholder signature"}]},{id:"health_report",label:"Health Report",icon:"๐Ÿฅ",fields:[{id:"NAME",label:"Patient Name",description:"Name of the patient"},{id:"AGE",label:"Age",description:"Patient age"},{id:"DOB",label:"Date of Birth",description:"Birth date"},{id:"DOCTOR",label:"Doctor Name",description:"Attending physician"},{id:"HOSPITAL",label:"Hospital/Clinic",description:"Institution name"},{id:"DIAGNOSIS",label:"Diagnosis",description:"Medical diagnosis"},{id:"MEDICAL",label:"Medications",description:"Prescribed medications"},{id:"TEST_RESULTS",label:"Test Results",description:"Lab test values"},{id:"BLOOD_GROUP",label:"Blood Group",description:"Patient blood group"}]},{id:"income_tax",label:"Income Tax Return",icon:"๐Ÿ“Š",fields:[{id:"NAME",label:"Name",description:"Taxpayer name"},{id:"PAN",label:"PAN Number",description:"PAN of the taxpayer"},{id:"ADDRESS",label:"Address",description:"Taxpayer address"},{id:"INCOME",label:"Income Details",description:"Gross/net income"},{id:"TAX_AMOUNT",label:"Tax Amount",description:"Tax payable/refund"},{id:"ASSESSMENT_YEAR",label:"Assessment Year",description:"Tax assessment year"},{id:"TAN",label:"TAN",description:"Tax deduction account number"},{id:"EMPLOYER",label:"Employer",description:"Employer name"}]},{id:"invoice",label:"Invoice",icon:"๐Ÿงพ",fields:[{id:"COMPANY",label:"Company Name",description:"Issuing company"},{id:"CUSTOMER",label:"Customer Name",description:"Bill-to customer"},{id:"ADDRESS",label:"Address",description:"Billing/shipping address"},{id:"INVOICE_NO",label:"Invoice Number",description:"Unique invoice ID"},{id:"DATE",label:"Date",description:"Invoice date"},{id:"AMOUNT",label:"Amount",description:"Total amount/subtotals"},{id:"GST",label:"GST Number",description:"GSTIN of the company"},{id:"ITEMS",label:"Line Items",description:"Product/service details"},{id:"BANK",label:"Bank Details",description:"Payment bank account info"}]},{id:"bank_statement",label:"Bank Statement",icon:"๐Ÿฆ",fields:[{id:"NAME",label:"Account Holder Name",description:"Name on the account"},{id:"ACCOUNT_NO",label:"Account Number",description:"Bank account number"},{id:"IFSC",label:"IFSC Code",description:"Bank branch IFSC code"},{id:"ADDRESS",label:"Address",description:"Account holder address"},{id:"TRANSACTIONS",label:"Transaction Details",description:"Transaction history"},{id:"BALANCE",label:"Account Balance",description:"Opening/closing balance"},{id:"BANK_NAME",label:"Bank Name",description:"Name of the bank"},{id:"BRANCH",label:"Branch",description:"Branch name/address"},{id:"DATE",label:"Statement Date",description:"Statement period dates"}]}],jh=({selectedDocType:s,selectedFields:t,onDocTypeChange:l,onFieldsChange:i})=>{const e=Gn.find(n=>n.id===s),c=n=>{t.includes(n)?i(t.filter(Z=>Z!==n)):i([...t,n])},d=()=>{e&&i(e.fields.map(n=>n.id))},a=()=>{i([])};return C.jsxs("div",{className:"doc-selector",children:[C.jsxs("div",{className:"doc-selector__section",children:[C.jsxs("h3",{className:"doc-selector__heading",children:[C.jsx("span",{className:"doc-selector__step",children:"1"}),"Select Document Type"]}),C.jsx("div",{className:"doc-selector__radio-group",children:Gn.map(n=>C.jsxs("label",{className:`doc-selector__radio-card ${s===n.id?"doc-selector__radio-card--active":""}`,children:[C.jsx("input",{type:"radio",name:"docType",value:n.id,checked:s===n.id,onChange:()=>{l(n.id),i([])},className:"doc-selector__radio-input"}),C.jsx("span",{className:"doc-selector__radio-icon",children:n.icon}),C.jsx("span",{className:"doc-selector__radio-label",children:n.label})]},n.id))})]}),e&&C.jsxs("div",{className:"doc-selector__section",children:[C.jsxs("h3",{className:"doc-selector__heading",children:[C.jsx("span",{className:"doc-selector__step",children:"2"}),"Select Fields to Keep Visible"]}),C.jsxs("p",{className:"doc-selector__hint",children:["Checked fields will remain ",C.jsx("strong",{children:"visible"}),". Everything else will be ",C.jsx("strong",{children:"redacted"}),"."]}),C.jsxs("div",{className:"doc-selector__actions",children:[C.jsx("button",{type:"button",className:"doc-selector__action-btn",onClick:d,children:"Select All"}),C.jsx("button",{type:"button",className:"doc-selector__action-btn",onClick:a,children:"Deselect All"})]}),C.jsx("div",{className:"doc-selector__checkbox-grid",children:e.fields.map(n=>C.jsxs("label",{className:`doc-selector__checkbox-card ${t.includes(n.id)?"doc-selector__checkbox-card--checked":""}`,children:[C.jsx("input",{type:"checkbox",checked:t.includes(n.id),onChange:()=>c(n.id),className:"doc-selector__checkbox-input"}),C.jsxs("div",{className:"doc-selector__checkbox-content",children:[C.jsx("span",{className:"doc-selector__checkbox-label",children:n.label}),C.jsx("span",{className:"doc-selector__checkbox-desc",children:n.description})]})]},n.id))}),t.length===0&&C.jsxs("div",{className:"doc-selector__warning",children:["โš ๏ธ No fields selected โ€” ",C.jsx("strong",{children:"everything"})," in the document will be redacted."]})]})]})},D2=({apiKey:s,requiredFields:t=[],onComplete:l,confidenceThreshold:i=.5,maxFileSizeMB:e=25,acceptedTypes:c,showDocTypeSelector:d=!1,className:a})=>{const[n,Z]=Xt.useState(null),[b,h]=Xt.useState([]),m=d?b:t,o=Xt.useCallback((u,W)=>{const N=JSON.parse(W);l(u,N)},[l]);return C.jsxs("div",{className:`su-root ${a??""}`,children:[d&&C.jsx(jh,{selectedDocType:n,selectedFields:b,onDocTypeChange:Z,onFieldsChange:h}),C.jsx(gh,{apiKey:s,requiredFields:m,confidenceThreshold:i,onUpload:o,maxFileSizeMB:e,acceptedTypes:c})]})};Pt.DOCUMENT_TYPES=Gn,Pt.DocTypeSelector=jh,Pt.SecureRedact=D2,Pt.SecureUploader=gh,Object.defineProperty(Pt,Symbol.toStringTag,{value:"Module"})}));
107
+ ${JSON.stringify(s)}`,e=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({contents:[{parts:[{text:i}]}],generationConfig:{temperature:.1,topP:.8,maxOutputTokens:4096}})});if(!e.ok){const b=await e.text().catch(()=>"");throw new Error(`Gemini API error ${e.status}: ${b||e.statusText}`)}const d=(await e.json())?.candidates?.[0]?.content?.parts?.[0]?.text??"",a=d.match(/\[[\s\S]*\]/);if(!a)return[];let n=[];try{n=JSON.parse(a[0])}catch{return console.warn("[Gemini WordID] Returned invalid JSON:",d),[]}const Z=n.filter(b=>b&&typeof b.type=="string"&&typeof b.value=="string"&&Array.isArray(b.wordIds)&&b.wordIds.length>0&&b.wordIds.every(h=>typeof h=="number"));return console.log(`[Gemini WordID] Detected ${Z.length} PII entities`),Z}function G2(s,t){return!t||t.length===0?[]:t.map(l=>{const i=s.filter((n,Z)=>l.wordIds.includes(Z));if(i.length===0)return console.warn(`[Redaction Masks] No matching words found for entity: ${l.value}`),null;const e=Math.min(...i.map(n=>n.bbox.x)),c=Math.min(...i.map(n=>n.bbox.y)),d=Math.max(...i.map(n=>n.bbox.x+n.bbox.w)),a=Math.max(...i.map(n=>n.bbox.y+n.bbox.h));return{id:crypto.randomUUID(),type:m2(l.type),textValue:l.value,coordinates:{startX:e,startY:c,endX:d,endY:a},selectedForMasking:!0}}).filter(l=>l!==null)}const Ld=4;function r2(s,t=0){return s.map(l=>({id:"wid_"+l.id.substring(0,8),type:l.type,value:l.textValue,confidence:.95,bbox:{x:Math.max(0,l.coordinates.startX-Ld),y:Math.max(0,l.coordinates.startY-Ld),w:l.coordinates.endX-l.coordinates.startX+Ld*2,h:l.coordinates.endY-l.coordinates.startY+Ld*2,pageIndex:t},masked:l.selectedForMasking,layer:4}))}async function N2(s,t,l=0,i){if(!t||s.length===0)return[];i?.("Running word-ID PII detection...");const e=await u2(s,t,i);if(e.length===0)return console.log("[WordID Pipeline] No PII detected by Gemini"),[];i?.("Calculating redaction coordinates...");const c=G2(s,e),d=r2(c,l);return console.log(`[WordID Pipeline] Generated ${d.length} entities from ${e.length} PII detections`),d}const yi=5;function X2(s,t=0){return s.map(l=>({text:l.text,left:l.bbox.x,top:l.bbox.y,width:l.bbox.w,height:l.bbox.h,pageIndex:l.bbox.pageIndex??t,redact:!1}))}function M2(s,t,l=[]){const i=[],e=a=>a.toLowerCase().replace(/[^a-z0-9\u0900-\u097F]/g,""),c=new Set,d=[];for(const a of t){const Z=a.trim().split(/\s+/).filter(b=>b.length>0).map(e).filter(b=>b.length>0);Z.length!==0&&(Z.length===1?c.add(Z[0]):d.push({original:a.trim(),tokens:Z}))}for(const a of d){const{tokens:n,original:Z}=a;for(let b=0;b<=s.length-n.length;b++){let h=!0;for(let m=0;m<n.length;m++)if(e(s[b+m].text)!==n[m]){h=!1;break}if(h){const m=s.slice(b,b+n.length);for(let r=0;r<n.length;r++)s[b+r].redact=!0;const o=Math.min(...m.map(r=>r.left)),u=Math.min(...m.map(r=>r.top)),W=Math.max(...m.map(r=>r.left+r.width)),N=Math.max(...m.map(r=>r.top+r.height));i.push({x:o-yi,y:u-yi,w:W-o+yi*2,h:N-u+yi*2,pageIndex:m[0].pageIndex,matchedPhrase:Z,matchedWords:m.map(r=>r.text)})}}if(!i.some(b=>b.matchedPhrase===Z)){const b=n[0];for(let h=0;h<s.length;h++){if(e(s[h].text)!==b)continue;const m=[s[h]];let o=1;for(let u=h+1;u<Math.min(s.length,h+n.length*2)&&o<n.length;u++)e(s[u].text)===n[o]&&(m.push(s[u]),o++);if(m.length>=Math.ceil(n.length*.6)){for(const X of m)X.redact=!0;const u=Math.min(...m.map(X=>X.left)),W=Math.min(...m.map(X=>X.top)),N=Math.max(...m.map(X=>X.left+X.width)),r=Math.max(...m.map(X=>X.top+X.height));i.push({x:u-yi,y:W-yi,w:N-u+yi*2,h:r-W+yi*2,pageIndex:m[0].pageIndex,matchedPhrase:Z,matchedWords:m.map(X=>X.text)});break}}}}for(let a=0;a<s.length;a++){const n=s[a];if(n.redact)continue;const Z=e(n.text);Z.length!==0&&c.has(Z)&&(n.redact=!0,i.push({x:n.left-yi,y:n.top-yi,w:n.width+yi*2,h:n.height+yi*2,pageIndex:n.pageIndex,matchedPhrase:n.text,matchedWords:[n.text]}))}return y2(i)}function y2(s){if(s.length<=1)return s;const t=[...s].sort((i,e)=>i.pageIndex!==e.pageIndex?i.pageIndex-e.pageIndex:Math.abs(i.y-e.y)>5?i.y-e.y:i.x-e.x),l=[t[0]];for(let i=1;i<t.length;i++){const e=t[i],c=l[l.length-1];if(e.pageIndex===c.pageIndex&&e.x<=c.x+c.w+2&&e.y<=c.y+c.h+2&&e.y+e.h>=c.y-2){const d=Math.min(c.x,e.x),a=Math.min(c.y,e.y),n=Math.max(c.x+c.w,e.x+e.w),Z=Math.max(c.y+c.h,e.y+e.h);c.x=d,c.y=a,c.w=n-d,c.h=Z-a,c.matchedWords=[...c.matchedWords,...e.matchedWords],c.matchedPhrase+=" | "+e.matchedPhrase}else l.push({...e})}return l}function Y2(s){return s.map(t=>({id:"mz_"+crypto.randomUUID().substring(0,8),type:"SENSITIVE",value:t.matchedPhrase,confidence:.9,bbox:{x:Math.max(0,t.x),y:Math.max(0,t.y),w:t.w,h:t.h,pageIndex:t.pageIndex},masked:!0,layer:3}))}async function p2(s,t,l,i=.5,e=[],c=0,d){const a=X2(t,c);console.log(`[Pipeline] Spatial map: ${a.length} entries`),console.log(`[Pipeline] fullText length: ${s.length}, first 100 chars: "${s.substring(0,100)}"`),d?.("Running deterministic detection...");const n=s2(s,t,c);console.log("[Pipeline] Layer 1 entities:",n.length),d?.("Running local NLP analysis...");let Z=[];try{Z=await T2(t,c),console.log("[Pipeline] NLP heuristic entities:",Z.length)}catch(u){console.warn("[Pipeline] NLP worker failed:",u)}let b=[];if(l){try{d?.("Running Gemini word-ID detection...");const u=await un(()=>N2(t,l,c,d),2,5e3);u.length>0&&(b=u,console.log(`[Pipeline] Word-ID detection: ${b.length} entities (pixel-perfect)`))}catch(u){console.warn("[Pipeline] Gemini word-ID detection failed:",u)}if(b.length===0)try{d?.("Trying semantic filter fallback...");const u=await un(()=>Z2(s,e,l,d),2,5e3);if(u.length>0&&a.length>0){d?.("Calculating redaction zones...");const W=M2(a,u,e);b=Y2(W),console.log("[Pipeline] Semantic filter fallback:",b.length,"entities")}}catch(u){console.warn("[Pipeline] Semantic filter fallback failed:",u);try{b=await un(()=>b2(s,t,l,c,d),1,5e3),console.log("[Pipeline] Legacy Gemini fallback:",b.length,"entities")}catch{console.warn("[Pipeline] All Gemini strategies failed. Using Layer 1 + NLP only.")}}}const h=[...n,...Z,...b],o=V2(h).filter(u=>u.confidence>=i);for(const u of o)e.includes(u.type)&&(u.masked=!1);return console.log(`[Pipeline] Final: ${o.length} entities (${o.filter(u=>u.masked).length} masked, ${o.filter(u=>!u.masked).length} visible)`),o}function T2(s,t){return new Promise((l,i)=>{const e=new Worker(new URL("/assets/nlp.worker-u7Lr_A3c.js",typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:al&&al.tagName.toUpperCase()==="SCRIPT"&&al.src||new URL("secure-redact.umd.js",document.baseURI).href),{type:"module"}),c=setTimeout(()=>{e.terminate(),i(new Error("NLP worker timed out"))},1e4);e.onmessage=d=>{clearTimeout(c),e.terminate(),d.data.type==="NLP_ERROR"?i(new Error(d.data.error)):d.data.type==="NLP_RESULT"&&l(d.data.entities??[])},e.onerror=d=>{clearTimeout(c),e.terminate(),i(d)},e.postMessage({type:"NLP_ANALYZE",text:s.map(d=>d.text).join(" "),words:s,pageIndex:t})})}async function un(s,t,l){let i,e=l;for(let c=0;c<=t;c++)try{return await s()}catch(d){i=d instanceof Error?d:new Error(String(d));const a=i.message.toLowerCase();if(a.includes("resource_exhausted")||a.includes("quota")||a.includes("daily limit")||a.includes("rate limit exceeded"))throw console.warn("[Pipeline] Quota/resource exhausted, skipping retries"),i;if(!a.includes("429")||c>=t)throw i;console.log(`[Pipeline] Rate limited, retrying in ${e/1e3}s (attempt ${c+1}/${t})...`),await new Promise(n=>setTimeout(n,e)),e*=1.5}throw i}function V2(s){const t=[...s].sort((i,e)=>e.confidence-i.confidence),l=[];for(const i of t)l.some(c=>c.bbox.pageIndex===i.bbox.pageIndex&&L2(c.bbox,i.bbox,.5))||l.push(i);return l}function L2(s,t,l){const i=Math.max(0,Math.min(s.x+s.w,t.x+t.w)-Math.max(s.x,t.x)),e=Math.max(0,Math.min(s.y+s.h,t.y+t.h)-Math.max(s.y,t.y)),c=i*e,d=Math.min(s.w*s.h,t.w*t.h);return d>0&&c/d>l}const Wn=[{key:"loading",label:"Loading"},{key:"ocr",label:"Text Extraction"},{key:"detection",label:"PII Detection"},{key:"review",label:"Review"}],I2=({stage:s,progress:t,message:l})=>{const i=Wn.findIndex(e=>e.key===s);return C.jsxs("div",{className:"su-progress-container",children:[C.jsx("div",{className:"su-progress-steps",children:Wn.map((e,c)=>{let d="pending";return c<i?d="done":c===i&&(d="active"),C.jsxs("div",{className:"su-progress-step-wrapper",children:[C.jsxs("div",{className:`su-progress-step su-progress-step--${d}`,children:[C.jsx("div",{className:"su-progress-dot",children:d==="done"?C.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:C.jsx("path",{d:"M2 6L5 9L10 3",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}):d==="active"?C.jsx("div",{className:"su-progress-pulse"}):null}),C.jsx("span",{className:"su-progress-label",children:e.label})]}),c<Wn.length-1&&C.jsx("div",{className:`su-progress-line su-progress-line--${c<i?"done":"pending"}`})]},e.key)})}),s==="ocr"&&C.jsxs("div",{className:"su-progress-bar-wrapper",children:[C.jsx("div",{className:"su-progress-bar",children:C.jsx("div",{className:"su-progress-bar-fill",style:{width:`${Math.round(t*100)}%`}})}),C.jsxs("span",{className:"su-progress-percent",children:[Math.round(t*100),"%"]})]}),C.jsx("p",{className:"su-progress-message",children:l})]})},xh={AADHAAR:"Aadhaar Number",PAN:"PAN",CREDIT_CARD:"Credit Card",PHONE:"Phone Number",NAME:"Name",ADDRESS:"Address",MEDICAL:"Medical Information",EMAIL:"Email Address",DOB:"Date of Birth",SENSITIVE:"Sensitive Info"},Dh={AADHAAR:"#ef4444",PAN:"#f97316",CREDIT_CARD:"#eab308",PHONE:"#22c55e",NAME:"#3b82f6",ADDRESS:"#8b5cf6",MEDICAL:"#ec4899",EMAIL:"#06b6d4",DOB:"#14b8a6",SENSITIVE:"#6b7280"},z2=({entities:s,imageDataUrl:t,fileName:l,onConfirm:i,onCancel:e,requiredFields:c,confidenceThreshold:d})=>{const a=Xt.useRef(null),[n,Z]=Xt.useState(s),[b,h]=Xt.useState({width:0,height:0}),[m,o]=Xt.useState(1);Xt.useEffect(()=>{Z(s)},[s]),Xt.useEffect(()=>{if(!t||!a.current)return;const X=a.current,M=X.getContext("2d");if(!M)return;const p=new Image;p.onload=()=>{const V=X.parentElement?.clientWidth??800,T=Math.min(1,V/p.naturalWidth);o(T),h({width:p.naturalWidth,height:p.naturalHeight}),X.width=p.naturalWidth*T,X.height=p.naturalHeight*T,M.drawImage(p,0,0,X.width,X.height),u(M,n,T)},p.src=t},[t,n]);function u(X,M,p){for(const V of M){const{x:T,y:L,w:S,h:x}=V.bbox,j=T*p,g=L*p,f=S*p,F=x*p,H=Dh[V.type]||"#888";V.masked?(X.fillStyle=H+"33",X.fillRect(j,g,f,F),X.strokeStyle=H,X.lineWidth=2,X.strokeRect(j,g,f,F),X.beginPath(),X.moveTo(j,g),X.lineTo(j+f,g+F),X.moveTo(j+f,g),X.lineTo(j,g+F),X.strokeStyle=H+"66",X.lineWidth=1,X.stroke()):(X.strokeStyle=H,X.lineWidth=2,X.setLineDash([4,4]),X.strokeRect(j,g,f,F),X.setLineDash([]));const A=V.type;X.font=`${Math.max(10,11*p)}px Inter, system-ui, sans-serif`;const k=X.measureText(A),O=16*p,st=g-O;X.fillStyle=H,X.fillRect(j,Math.max(0,st),k.width+8*p,O),X.fillStyle="#ffffff",X.fillText(A,j+4*p,Math.max(O-4*p,st+O-4*p))}}function W(X){Z(M=>M.map(p=>p.id!==X||c.includes(p.type)&&p.masked?p:{...p,masked:!p.masked}))}const N=n.filter(X=>X.masked).length,r=n.filter(X=>!X.masked).length;return C.jsx("div",{className:"su-modal-overlay",onClick:e,children:C.jsxs("div",{className:"su-modal",onClick:X=>X.stopPropagation(),children:[C.jsxs("div",{className:"su-modal-header",children:[C.jsxs("div",{children:[C.jsx("h2",{className:"su-modal-title",children:"Review Detected Information"}),C.jsx("p",{className:"su-modal-subtitle",children:l})]}),C.jsx("button",{className:"su-modal-close",onClick:e,"aria-label":"Close",children:C.jsx("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",children:C.jsx("path",{d:"M5 5L15 15M15 5L5 15",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})})]}),C.jsxs("div",{className:"su-modal-body",children:[C.jsx("div",{className:"su-modal-preview",children:C.jsx("canvas",{ref:a,className:"su-modal-canvas"})}),C.jsxs("div",{className:"su-modal-sidebar",children:[C.jsxs("div",{className:"su-modal-stats",children:[C.jsxs("div",{className:"su-modal-stat",children:[C.jsx("span",{className:"su-modal-stat-value",children:N}),C.jsx("span",{className:"su-modal-stat-label",children:"Masked"})]}),C.jsxs("div",{className:"su-modal-stat",children:[C.jsx("span",{className:"su-modal-stat-value",children:r}),C.jsx("span",{className:"su-modal-stat-label",children:"Visible"})]})]}),C.jsxs("div",{className:"su-modal-entities",children:[C.jsx("h3",{className:"su-modal-section-title",children:"Detected Entities"}),n.length===0&&C.jsx("p",{className:"su-modal-empty",children:"No sensitive information detected."}),n.map(X=>{const M=c.includes(X.type),p=X.confidence<d+.15&&X.confidence>=d;return C.jsxs("div",{className:`su-entity-card ${p?"su-entity-card--warning":""}`,children:[C.jsxs("div",{className:"su-entity-header",children:[C.jsx("div",{className:"su-entity-type",style:{color:Dh[X.type]},children:xh[X.type]||X.type}),C.jsxs("div",{className:"su-entity-confidence",children:[Math.round(X.confidence*100),"%"]})]}),C.jsx("div",{className:"su-entity-value",children:X.masked?w2(X.value):X.value}),M&&!X.masked&&C.jsx("div",{className:"su-entity-required-badge",children:"Required Field"}),p&&!M&&C.jsx("div",{className:"su-entity-warning",children:"Low confidence detection. Please verify this is correct."}),C.jsx("div",{className:"su-entity-actions",children:C.jsxs("button",{className:`su-toggle ${X.masked?"su-toggle--masked":"su-toggle--visible"}`,onClick:()=>W(X.id),disabled:M&&!X.masked,children:[C.jsx("span",{className:"su-toggle-track",children:C.jsx("span",{className:"su-toggle-thumb"})}),C.jsx("span",{className:"su-toggle-label",children:X.masked?"Masked":"Visible"})]})}),!X.masked&&!M&&C.jsxs("div",{className:"su-entity-liability",children:["You are choosing to keep this ",xh[X.type]?.toLowerCase()||"information"," visible."]})]},X.id)})]})]})]}),C.jsxs("div",{className:"su-modal-footer",children:[C.jsx("button",{className:"su-btn su-btn--secondary",onClick:e,children:"Cancel"}),C.jsxs("button",{className:"su-btn su-btn--primary",onClick:()=>i(n),children:["Confirm and Redact (",N," items)"]})]})]})})};function w2(s){return s.length<=4?"*".repeat(s.length):s.substring(0,2)+"*".repeat(s.length-4)+s.substring(s.length-2)}const R2={},S2=25,x2=.5,gh=({requiredFields:s=[],confidenceThreshold:t=x2,onUpload:l,maxFileSizeMB:i=S2,acceptedTypes:e,apiKey:c})=>{const d=c??(typeof{url:typeof document>"u"&&typeof location>"u"?require("url").pathToFileURL(__filename).href:typeof document>"u"?location.href:al&&al.tagName.toUpperCase()==="SCRIPT"&&al.src||new URL("secure-redact.umd.js",document.baseURI).href}<"u"?R2?.VITE_GEMINI_API_KEY??"":""),[a,n]=Xt.useState("idle"),[Z,b]=Xt.useState(0),[h,m]=Xt.useState(""),[o,u]=Xt.useState(null),[W,N]=Xt.useState(!1),[r,X]=Xt.useState([]),[M,p]=Xt.useState(null),[V,T]=Xt.useState(null),[L,S]=Xt.useState(null),[x,j]=Xt.useState(null),[g,f]=Xt.useState(null),F=Xt.useRef(null),H=Xt.useRef(null),A=Xt.useRef({width:612,height:792});Xt.useEffect(()=>()=>{F.current?.terminate()},[]);const k=Xt.useCallback(()=>(F.current||(F.current=new xd,F.current.setProgressCallback((lt,tt)=>{b(lt),m(tt)})),F.current),[]),O=Xt.useCallback(async lt=>{u(null),n("loading"),m("Preparing document..."),b(0),T(lt);try{if(!kh(lt))throw new Error("Unsupported file type. Please upload an image or PDF.");if(lt.size>i*1024*1024)throw new Error(`File too large. Maximum size is ${i}MB.`);const tt=await Mn(lt);S(tt.buffer),n("ocr"),m("Extracting text from document...");const el=k();let dl=null,Nl=tt.buffer,It=tt.mimeType;if(tt.type==="image"){const{canvas:wl}=await yn(tt.buffer,tt.mimeType);dl=wl.toDataURL()}else{m("Rendering PDF page for OCR...");const{imageBuffer:wl,width:nl,height:gt,canvas:_l}=await Ih(tt.buffer,0);Nl=wl,It="image/png",dl=_l.toDataURL(),A.current={width:nl,height:gt}}const{words:Wl,fullText:gl}=await el.runOCR(Nl,It,0);if(Wl.length===0&&gl.trim().length===0){n("review"),m("No text detected in document."),X([]),p(dl);return}n("detection"),m("Analyzing for sensitive information...");const Ol=await p2(gl,Wl,d,t,s,0,wl=>m(wl));X(Ol),p(dl),n("review"),m(`Found ${Ol.length} item(s). Please review before proceeding.`)}catch(tt){n("error"),u(tt instanceof Error?tt.message:"An unexpected error occurred."),m("")}},[t,s,i,k]),st=Xt.useCallback(async lt=>{if(!(!V||!L)){n("redacting"),m("Applying redaction...");try{const tt=await Mn(V);let el,dl=null;if(tt.type==="image"){const{canvas:It}=await yn(tt.buffer,tt.mimeType);Kh(It,lt),dl=It.toDataURL(),el=await fh(It,`redacted_${V.name}`,tt.mimeType)}else{const It=A.current.width,Wl=A.current.height,gl=await Qo(tt.buffer,lt,It,Wl);el=Bo(gl,`redacted_${V.name}`);try{const{canvas:Ol}=await Ih(gl.buffer.slice(gl.byteOffset,gl.byteOffset+gl.byteLength),0);dl=Ol.toDataURL()}catch{dl=null}}const Nl={timestamp:new Date().toISOString(),fileName:V.name,detectedEntities:lt.map(It=>({type:It.type,confidence:It.confidence,action:It.masked?"masked":"kept_visible",userConfirmed:!0})),requiredFields:s};j(dl),f(el),n("complete"),m("Redaction complete."),l(el,JSON.stringify(Nl,null,2))}catch(tt){n("error"),u(tt instanceof Error?tt.message:"Redaction failed.")}}},[V,L,s,l]),mt=Xt.useCallback(()=>{n("idle"),b(0),m(""),u(null),X([]),p(null),j(null),f(null),T(null),S(null),N(!1)},[]),ft=Xt.useCallback(lt=>{lt.preventDefault(),lt.stopPropagation(),N(!0)},[]),Wt=Xt.useCallback(lt=>{lt.preventDefault(),lt.stopPropagation(),N(!1)},[]),bt=Xt.useCallback(lt=>{lt.preventDefault(),lt.stopPropagation(),N(!1);const tt=lt.dataTransfer.files[0];tt&&O(tt)},[O]),ut=Xt.useCallback(lt=>{const tt=lt.target.files?.[0];tt&&O(tt)},[O]),Ct=Xt.useCallback(()=>{a==="idle"&&H.current?.click()},[a]),vt=["loading","ocr","detection","redacting"].includes(a),wt=e?.join(",")??"image/png,image/jpeg,image/webp,image/bmp,application/pdf";return C.jsxs("div",{className:"su-root",children:[C.jsxs("div",{className:`su-dropzone ${W?"su-dropzone--active":""} ${vt?"su-dropzone--processing":""} ${a==="complete"?"su-dropzone--complete":""} ${a==="error"?"su-dropzone--error":""}`,onDragOver:ft,onDragLeave:Wt,onDrop:bt,onClick:Ct,role:"button",tabIndex:0,"aria-label":"Upload document for PII detection",children:[C.jsx("input",{ref:H,type:"file",className:"su-file-input",accept:wt,onChange:ut}),a==="idle"&&C.jsxs("div",{className:"su-dropzone-content",children:[C.jsx("div",{className:"su-dropzone-icon",children:C.jsxs("svg",{width:"40",height:"40",viewBox:"0 0 40 40",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[C.jsx("path",{d:"M20 5L20 25M20 5L13 12M20 5L27 12",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"}),C.jsx("path",{d:"M6 25V31C6 33.2091 7.79086 35 10 35H30C32.2091 35 34 33.2091 34 31V25",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}),C.jsx("p",{className:"su-dropzone-title",children:"Drop your document here"}),C.jsx("p",{className:"su-dropzone-hint",children:"or click to browse"}),C.jsxs("p",{className:"su-dropzone-formats",children:["Supports PNG, JPEG, WebP, BMP, PDF (max ",i,"MB)"]})]}),vt&&C.jsx("div",{className:"su-dropzone-processing",children:C.jsx(I2,{stage:a,progress:Z,message:h})}),a==="complete"&&C.jsxs("div",{className:"su-dropzone-content su-dropzone-content--complete",children:[C.jsx("div",{className:"su-dropzone-icon su-dropzone-icon--success",children:C.jsxs("svg",{width:"40",height:"40",viewBox:"0 0 40 40",fill:"none",children:[C.jsx("circle",{cx:"20",cy:"20",r:"16",stroke:"currentColor",strokeWidth:"2.5"}),C.jsx("path",{d:"M13 20L18 25L27 15",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})]})}),C.jsx("p",{className:"su-dropzone-title",children:"Redaction Complete"}),C.jsx("p",{className:"su-dropzone-hint",children:"Document has been securely processed"})]}),a==="error"&&C.jsxs("div",{className:"su-dropzone-content su-dropzone-content--error",children:[C.jsx("div",{className:"su-dropzone-icon su-dropzone-icon--error",children:C.jsxs("svg",{width:"40",height:"40",viewBox:"0 0 40 40",fill:"none",children:[C.jsx("circle",{cx:"20",cy:"20",r:"16",stroke:"currentColor",strokeWidth:"2.5"}),C.jsx("path",{d:"M15 15L25 25M25 15L15 25",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round"})]})}),C.jsx("p",{className:"su-dropzone-title",children:"Processing Failed"}),C.jsx("p",{className:"su-dropzone-hint",children:o}),C.jsx("button",{className:"su-btn su-btn--secondary su-btn--sm",onClick:lt=>{lt.stopPropagation(),mt()},children:"Try Again"})]}),V&&a!=="idle"&&a!=="error"&&a!=="complete"&&C.jsxs("div",{className:"su-file-badge",children:[C.jsx("span",{className:"su-file-badge-name",children:V.name}),C.jsx("span",{className:"su-file-badge-size",children:Eh(V.size)})]})]}),a==="complete"&&g&&C.jsxs("div",{className:"su-result-panel",children:[C.jsxs("div",{className:"su-result-header",children:[C.jsxs("div",{className:"su-result-title-row",children:[C.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",className:"su-result-check",children:[C.jsx("circle",{cx:"10",cy:"10",r:"8",stroke:"currentColor",strokeWidth:"1.8"}),C.jsx("path",{d:"M6.5 10L9 12.5L13.5 7.5",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})]}),C.jsx("span",{className:"su-result-title",children:"Redacted Document"})]}),C.jsx("span",{className:"su-result-filename",children:g.name})]}),x&&C.jsx("div",{className:"su-result-preview",children:C.jsx("img",{src:x,alt:"Redacted document preview",className:"su-result-img"})}),C.jsxs("div",{className:"su-result-actions",children:[C.jsxs("a",{href:URL.createObjectURL(g),download:g.name,className:"su-btn su-btn--primary",children:[C.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",style:{marginRight:6},children:[C.jsx("path",{d:"M8 2v8M8 10L5 7M8 10l3-3",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"}),C.jsx("path",{d:"M2 13h12",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round"})]}),"Download"]}),C.jsx("button",{className:"su-btn su-btn--secondary",onClick:mt,children:"Process Another Document"})]})]}),a==="review"&&C.jsx(z2,{entities:r,imageDataUrl:M,fileName:V?.name??"document",onConfirm:st,onCancel:mt,requiredFields:s,confidenceThreshold:t})]})},Gn=[{id:"aadhaar",label:"Aadhaar Card",icon:"๐Ÿชช",fields:[{id:"NAME",label:"Name",description:"Full name of the cardholder"},{id:"ADDRESS",label:"Address",description:"Residential address"},{id:"DOB",label:"Date of Birth",description:"Birth date"},{id:"AADHAAR",label:"Aadhaar Number",description:"12-digit UID number"},{id:"PHONE",label:"Phone Number",description:"Registered mobile number"},{id:"GENDER",label:"Gender",description:"Male/Female/Other"},{id:"PHOTO",label:"Photo",description:"Passport-size photograph"},{id:"QR_CODE",label:"QR Code",description:"Machine-readable QR code"}]},{id:"pan",label:"PAN Card",icon:"๐Ÿ’ณ",fields:[{id:"NAME",label:"Name",description:"Name of the cardholder"},{id:"FATHER_NAME",label:"Father's Name",description:"Father's full name"},{id:"DOB",label:"Date of Birth",description:"Birth date"},{id:"PAN",label:"PAN Number",description:"10-character alphanumeric PAN"},{id:"PHOTO",label:"Photo",description:"Photograph on the card"},{id:"SIGNATURE",label:"Signature",description:"Cardholder signature"}]},{id:"health_report",label:"Health Report",icon:"๐Ÿฅ",fields:[{id:"NAME",label:"Patient Name",description:"Name of the patient"},{id:"AGE",label:"Age",description:"Patient age"},{id:"DOB",label:"Date of Birth",description:"Birth date"},{id:"DOCTOR",label:"Doctor Name",description:"Attending physician"},{id:"HOSPITAL",label:"Hospital/Clinic",description:"Institution name"},{id:"DIAGNOSIS",label:"Diagnosis",description:"Medical diagnosis"},{id:"MEDICAL",label:"Medications",description:"Prescribed medications"},{id:"TEST_RESULTS",label:"Test Results",description:"Lab test values"},{id:"BLOOD_GROUP",label:"Blood Group",description:"Patient blood group"}]},{id:"income_tax",label:"Income Tax Return",icon:"๐Ÿ“Š",fields:[{id:"NAME",label:"Name",description:"Taxpayer name"},{id:"PAN",label:"PAN Number",description:"PAN of the taxpayer"},{id:"ADDRESS",label:"Address",description:"Taxpayer address"},{id:"INCOME",label:"Income Details",description:"Gross/net income"},{id:"TAX_AMOUNT",label:"Tax Amount",description:"Tax payable/refund"},{id:"ASSESSMENT_YEAR",label:"Assessment Year",description:"Tax assessment year"},{id:"TAN",label:"TAN",description:"Tax deduction account number"},{id:"EMPLOYER",label:"Employer",description:"Employer name"}]},{id:"invoice",label:"Invoice",icon:"๐Ÿงพ",fields:[{id:"COMPANY",label:"Company Name",description:"Issuing company"},{id:"CUSTOMER",label:"Customer Name",description:"Bill-to customer"},{id:"ADDRESS",label:"Address",description:"Billing/shipping address"},{id:"INVOICE_NO",label:"Invoice Number",description:"Unique invoice ID"},{id:"DATE",label:"Date",description:"Invoice date"},{id:"AMOUNT",label:"Amount",description:"Total amount/subtotals"},{id:"GST",label:"GST Number",description:"GSTIN of the company"},{id:"ITEMS",label:"Line Items",description:"Product/service details"},{id:"BANK",label:"Bank Details",description:"Payment bank account info"}]},{id:"bank_statement",label:"Bank Statement",icon:"๐Ÿฆ",fields:[{id:"NAME",label:"Account Holder Name",description:"Name on the account"},{id:"ACCOUNT_NO",label:"Account Number",description:"Bank account number"},{id:"IFSC",label:"IFSC Code",description:"Bank branch IFSC code"},{id:"ADDRESS",label:"Address",description:"Account holder address"},{id:"TRANSACTIONS",label:"Transaction Details",description:"Transaction history"},{id:"BALANCE",label:"Account Balance",description:"Opening/closing balance"},{id:"BANK_NAME",label:"Bank Name",description:"Name of the bank"},{id:"BRANCH",label:"Branch",description:"Branch name/address"},{id:"DATE",label:"Statement Date",description:"Statement period dates"}]}],jh=({selectedDocType:s,selectedFields:t,onDocTypeChange:l,onFieldsChange:i})=>{const e=Gn.find(n=>n.id===s),c=n=>{t.includes(n)?i(t.filter(Z=>Z!==n)):i([...t,n])},d=()=>{e&&i(e.fields.map(n=>n.id))},a=()=>{i([])};return C.jsxs("div",{className:"doc-selector",children:[C.jsxs("div",{className:"doc-selector__section",children:[C.jsxs("h3",{className:"doc-selector__heading",children:[C.jsx("span",{className:"doc-selector__step",children:"1"}),"Select Document Type"]}),C.jsx("div",{className:"doc-selector__radio-group",children:Gn.map(n=>C.jsxs("label",{className:`doc-selector__radio-card ${s===n.id?"doc-selector__radio-card--active":""}`,children:[C.jsx("input",{type:"radio",name:"docType",value:n.id,checked:s===n.id,onChange:()=>{l(n.id),i([])},className:"doc-selector__radio-input"}),C.jsx("span",{className:"doc-selector__radio-icon",children:n.icon}),C.jsx("span",{className:"doc-selector__radio-label",children:n.label})]},n.id))})]}),e&&C.jsxs("div",{className:"doc-selector__section",children:[C.jsxs("h3",{className:"doc-selector__heading",children:[C.jsx("span",{className:"doc-selector__step",children:"2"}),"Select Fields to Keep Visible"]}),C.jsxs("p",{className:"doc-selector__hint",children:["Checked fields will remain ",C.jsx("strong",{children:"visible"}),". Everything else will be ",C.jsx("strong",{children:"redacted"}),"."]}),C.jsxs("div",{className:"doc-selector__actions",children:[C.jsx("button",{type:"button",className:"doc-selector__action-btn",onClick:d,children:"Select All"}),C.jsx("button",{type:"button",className:"doc-selector__action-btn",onClick:a,children:"Deselect All"})]}),C.jsx("div",{className:"doc-selector__checkbox-grid",children:e.fields.map(n=>C.jsxs("label",{className:`doc-selector__checkbox-card ${t.includes(n.id)?"doc-selector__checkbox-card--checked":""}`,children:[C.jsx("input",{type:"checkbox",checked:t.includes(n.id),onChange:()=>c(n.id),className:"doc-selector__checkbox-input"}),C.jsxs("div",{className:"doc-selector__checkbox-content",children:[C.jsx("span",{className:"doc-selector__checkbox-label",children:n.label}),C.jsx("span",{className:"doc-selector__checkbox-desc",children:n.description})]})]},n.id))}),t.length===0&&C.jsxs("div",{className:"doc-selector__warning",children:["โš ๏ธ No fields selected โ€” ",C.jsx("strong",{children:"everything"})," in the document will be redacted."]})]})]})},D2=({apiKey:s,requiredFields:t=[],onComplete:l,confidenceThreshold:i=.5,maxFileSizeMB:e=25,acceptedTypes:c,showDocTypeSelector:d=!0,className:a})=>{const[n,Z]=Xt.useState(null),[b,h]=Xt.useState([]),m=d?b:t,o=Xt.useCallback((u,W)=>{const N=JSON.parse(W);l(u,N)},[l]);return C.jsxs("div",{className:`su-root ${a??""}`,children:[d&&C.jsx(jh,{selectedDocType:n,selectedFields:b,onDocTypeChange:Z,onFieldsChange:h}),C.jsx(gh,{apiKey:s,requiredFields:m,confidenceThreshold:i,onUpload:o,maxFileSizeMB:e,acceptedTypes:c})]})};Pt.DOCUMENT_TYPES=Gn,Pt.DocTypeSelector=jh,Pt.SecureRedact=D2,Pt.SecureUploader=gh,Object.defineProperty(Pt,Symbol.toStringTag,{value:"Module"})}));
108
108
  //# sourceMappingURL=secure-redact.umd.js.map