@nice2dev/ui-security 1.0.14 → 1.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  0%, 100% { transform: translateY(-${p*.3}px); opacity: 0.3; }
4
4
  50% { transform: translateY(${p*.3}px); opacity: 0.8; }
5
5
  }
6
- `})]})},tt={sm:240,md:320,lg:440},rt=e=>{const{mode:t,enrolledTemplates:r=[],referencePhoto:n,onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showBoundingBox:A=!0,livenessSteps:g=1,showReference:I=!0,instructionText:D,...b}=e,{t:T}=X(),p=ie(b),k=tt[x],u=h.useRef(null),w=h.useRef(null),l=h.useRef(null),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[_,H]=h.useState(0),[G,B]=h.useState(""),[L,$]=h.useState(null),[E,q]=h.useState(0),W=h.useCallback(S=>{z(S),o==null||o(S)},[o]),Y=h.useCallback(async()=>{try{const S=await oe("user");l.current=S,u.current&&(u.current.srcObject=S,await u.current.play()),W("idle"),B(T("security.face.lookAtCamera","Look at the camera"))}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),B(T("security.face.cameraError","Camera access denied")),W("error")}},[T,W,c]),P=h.useCallback(()=>{var S;(S=l.current)==null||S.getTracks().forEach(d=>d.stop()),l.current=null},[]);h.useEffect(()=>(Y(),P),[Y,P]);const C=h.useCallback(S=>{var ge,me,ve;const d=(ge=w.current)==null?void 0:ge.getContext("2d");if(!d)return;const j=w.current.width,N=w.current.height;if(d.clearRect(0,0,j,N),!S||!A)return;const M=S.boundingBox,U=j/(((me=u.current)==null?void 0:me.videoWidth)??j),K=N/(((ve=u.current)==null?void 0:ve.videoHeight)??N);d.strokeStyle=f==="success"?"var(--nice-success, #10b981)":"var(--nice-primary, #3b82f6)",d.lineWidth=2,d.setLineDash([6,4]),d.strokeRect(M.x*U,M.y*K,M.width*U,M.height*K),d.setLineDash([]);const Z=[[M.x*U,M.y*K],[(M.x+M.width)*U,M.y*K],[M.x*U,(M.y+M.height)*K],[(M.x+M.width)*U,(M.y+M.height)*K]],Q=12;d.lineWidth=3;for(const[V,ee]of Z)d.beginPath(),d.moveTo(V===M.x*U?V:V-Q,ee),d.lineTo(V,ee),d.lineTo(V,ee===M.y*K?ee+Q:ee-Q),d.stroke()},[A,f]),F=h.useCallback(async()=>{if(!(!u.current||f==="processing"||f==="success")){W("scanning"),B(T("security.face.scanning","Scanning face…"));try{if(p.livenessDetection){const j=[];for(let M=0;M<8;M++)j.push(te(u.current).imageData),await new Promise(U=>setTimeout(U,200));if(!de(j).isLive){B(T("security.face.notLive","Liveness check failed — move naturally")),W("idle");return}}W("processing"),B(T("security.face.processing","Analysing face…"));const{imageData:S}=te(u.current);if(t==="compare"&&n){const j=typeof n=="string"?await st(n):nt(n),{similarity:N,cameraFeatures:M,refFeatures:U}=Me(S,j);q(N),J((M==null?void 0:M.quality)??0),C(M);const Z={success:N>=p.matchThreshold,confidence:N,method:"face",timestamp:Date.now(),duration:0,livenessPassed:p.livenessDetection};Z.success?(B(T("security.face.matchFound",`Match: ${(N*100).toFixed(0)}%`)),W("success")):(H(Q=>Q+1),_+1>=p.maxRetries?(B(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(B(T("security.face.noMatch","No match — try again")),W("idle"))),a==null||a(Z);return}const d=ne(S);if(!d){B(T("security.face.noFaceDetected","No face detected")),W("idle");return}if(J(d.quality),C(d),t==="enroll"){const j=await Pe(d,y??"face");i==null||i(j,d),B(T("security.face.enrolled","Face enrolled successfully")),W("success")}else{let j=0;for(const U of r){const K=Ee(U),Z=ue(d,K);Z>j&&(j=Z)}q(j);const N=j>=p.matchThreshold,M={success:N,confidence:j,method:"face",timestamp:Date.now(),duration:0,livenessPassed:p.livenessDetection};if(N&&p.verifyEndpoint){const U=await se(),K=await ce(p.verifyEndpoint,{method:"face",templateData:btoa(JSON.stringify(d)),matchScore:j,deviceFingerprint:U},p.authToken);M.success=K.verified}M.success?(B(T("security.face.verified","Face verified")),W("success")):(H(U=>U+1),_+1>=p.maxRetries?(B(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(B(T("security.face.noMatch","No match — try again")),W("idle"))),a==null||a(M)}}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),B(T("security.face.error","Error — try again")),W("error")}}},[f,t,r,n,p,T,W,i,a,c,y,_,C]),R=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return s.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),s.jsxs("div",{style:{display:"flex",gap:16,alignItems:"center"},children:[s.jsxs("div",{style:{width:k,height:k*.75,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${R}`,boxShadow:f==="scanning"?`0 0 20px ${R}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:u,style:{width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)"},playsInline:!0,muted:!0}),s.jsx("canvas",{ref:w,width:k,height:k*.75,style:{position:"absolute",inset:0,pointerEvents:"none",transform:"scaleX(-1)"}}),s.jsx("svg",{viewBox:"0 0 100 75",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:s.jsx("ellipse",{cx:"50",cy:"37",rx:"22",ry:"30",fill:"none",stroke:"white",strokeWidth:"0.8",strokeDasharray:"4 3"})}),(f==="scanning"||f==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,background:"var(--nice-overlay-15, rgba(0, 0, 0, 0.15))",display:"flex",alignItems:"center",justifyContent:"center"},children:s.jsx("div",{style:{width:50,height:50,borderRadius:"50%",border:"3px solid transparent",borderTopColor:R,animation:"spin 0.8s linear infinite"}})})]}),t==="compare"&&I&&n&&s.jsxs("div",{style:{width:k*.4,height:k*.5,borderRadius:"var(--security-radius)",overflow:"hidden",border:"2px solid var(--security-border)"},children:[s.jsx("img",{src:typeof n=="string"?n:void 0,alt:"Reference",style:{width:"100%",height:"100%",objectFit:"cover"}}),s.jsx("div",{style:{textAlign:"center",fontSize:10,padding:4,color:"var(--security-text-muted)",background:"var(--security-bg-panel)"},children:T("security.face.reference","Reference")})]})]}),E>0&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13},children:[s.jsxs("span",{style:{color:"var(--security-text-secondary)"},children:[T("security.face.confidence","Confidence"),":"]}),s.jsx("div",{style:{width:100,height:6,background:"var(--security-bg-panel)",borderRadius:3,overflow:"hidden"},children:s.jsx("div",{style:{width:`${E*100}%`,height:"100%",background:E>=p.matchThreshold?"var(--security-success)":"var(--security-warning)"}})}),s.jsxs("span",{style:{fontWeight:600,color:E>=p.matchThreshold?"var(--security-success)":"var(--security-warning)"},children:[(E*100).toFixed(0),"%"]})]}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:D??G}),f!=="success"&&f!=="failure"&&s.jsx("button",{onClick:F,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-bg, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?T("security.face.captureBtn","📸 Capture Face"):t==="compare"?T("security.face.compareBtn","📸 Compare"):T("security.face.verifyBtn","📸 Verify Face")}),(f==="failure"||f==="error")&&s.jsx("button",{onClick:()=>{H(0),q(0),W("idle"),B("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:T("security.common.retry","Try Again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})};async function st(e){return new Promise((t,r)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{const i=document.createElement("canvas");i.width=n.naturalWidth,i.height=n.naturalHeight;const a=i.getContext("2d");a.drawImage(n,0,0),t(a.getImageData(0,0,i.width,i.height))},n.onerror=()=>r(new Error("Failed to load reference image")),n.src=e})}function nt(e){const t=document.createElement("canvas");t.width=e.naturalWidth||e.width,t.height=e.naturalHeight||e.height;const r=t.getContext("2d");return r.drawImage(e,0,0),r.getImageData(0,0,t.width,t.height)}const it=4,at=5,ot=3e4,ct=e=>{const{length:t=it,scramble:r=!1,showDigits:n=!1,maxAttempts:i=at,lockoutDuration:a=ot,keySize:o=64,haptic:c=!0,keyLabels:m,expectedHash:x,expectedPin:y,mode:v="verify",onComplete:A,onVerify:g,onStatusChange:I,onError:D,showBiometricFallback:b=!1,onBiometricFallback:T,label:p,className:k}=e,{t:u}=X(),[w,l]=h.useState([]),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[_,H]=h.useState(0),[G,B]=h.useState(null),L=h.useRef(),$=h.useMemo(()=>{const F=["1","2","3","4","5","6","7","8","9","","0","back"];if(!r)return F;const R=["0","1","2","3","4","5","6","7","8","9"];for(let S=R.length-1;S>0;S--){const d=new Uint32Array(1);crypto.getRandomValues(d);const j=d[0]%(S+1);[R[S],R[j]]=[R[j],R[S]]}return[R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7],R[8],"",R[9],"back"]},[r,f]),E=h.useCallback(F=>{z(F),I==null||I(F)},[I]);h.useEffect(()=>{if(!(_<=Date.now()))return L.current=setInterval(()=>{Date.now()>=_&&(clearInterval(L.current),E("idle"),J(0),l([]))},500),()=>clearInterval(L.current)},[_,E]);const q=_>Date.now(),W=h.useCallback(()=>{c&&navigator.vibrate&&navigator.vibrate(20)},[c]),Y=h.useCallback(async F=>{if(q||f==="success")return;if(W(),F==="back"){l(j=>j.slice(0,-1));return}if(F==="")return;const R=[...w,F];if(l(R),R.length<t)return;const S=R.join("");if(E("processing"),v==="set"){if(G===null){B(S),l([]),E("idle");return}if(G!==S){B(null),l([]),E("failure"),setTimeout(()=>E("idle"),1200);return}A==null||A(S),E("success");return}let d=!1;if(x){const j=new TextEncoder,N=await crypto.subtle.digest("SHA-256",j.encode(S));d=Array.from(new Uint8Array(N)).map(U=>U.toString(16).padStart(2,"0")).join("")===x}else if(y)d=S===y;else{A==null||A(S),E("success");return}if(d)E("success"),g==null||g({success:!0,confidence:1,method:"pin",timestamp:Date.now(),duration:0}),A==null||A(S);else{const j=O+1;if(J(j),j>=i){const N=Date.now()+a;H(N),E("failure"),D==null||D(new Error("Too many failed PIN attempts"))}else E("failure"),setTimeout(()=>{E("idle"),l([])},800);g==null||g({success:!1,confidence:0,method:"pin",timestamp:Date.now(),duration:0})}},[w,t,q,f,v,G,x,y,O,i,a,W,E,A,g,D]),P=Math.max(0,Math.ceil((_-Date.now())/1e3)),C=f==="success"?"var(--security-success)":f==="failure"?"var(--security-error)":"var(--security-border)";return s.jsxs("div",{className:k,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:16,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[p&&s.jsx("div",{style:{fontSize:14,fontWeight:600},children:p}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:q?u("security.pin.locked",`Locked — try again in ${P}s`):v==="set"&&G!==null?u("security.pin.confirm","Confirm your PIN"):v==="set"?u("security.pin.setNew","Enter a new PIN"):u("security.pin.enter","Enter your PIN")}),s.jsx("div",{style:{display:"flex",gap:12},children:Array.from({length:t},(F,R)=>s.jsx("div",{style:{width:16,height:16,borderRadius:"50%",border:`2px solid ${C}`,background:R<w.length?C:"transparent",transition:"background 0.15s, border-color 0.15s"}},R))}),s.jsx("div",{style:{display:"grid",gridTemplateColumns:`repeat(3, ${o}px)`,gap:10,opacity:q?.4:1,pointerEvents:q?"none":"auto"},children:$.map((F,R)=>{if(F==="")return s.jsx("div",{},R);const S=F==="back";return s.jsx("button",{onClick:()=>Y(F),disabled:q||f==="success","aria-label":S?"Backspace":F,style:{width:o,height:o,borderRadius:"var(--security-key-border-radius, 50%)",border:"1px solid var(--security-key-border, var(--security-border))",background:"var(--security-key-bg, var(--security-bg-panel))",color:"var(--security-key-text, var(--security-text))",fontSize:S?20:22,fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background 0.1s, transform 0.1s",userSelect:"none"},onMouseDown:d=>{d.currentTarget.style.transform="scale(0.92)"},onMouseUp:d=>{d.currentTarget.style.transform=""},onMouseLeave:d=>{d.currentTarget.style.transform=""},children:S?"⌫":(m==null?void 0:m[F])??F},R)})}),w.length>0&&f!=="success"&&s.jsx("button",{onClick:()=>l([]),style:{fontSize:12,background:"none",border:"none",color:"var(--security-text-secondary)",cursor:"pointer",textDecoration:"underline"},children:u("security.pin.clear","Clear")}),b&&s.jsxs("button",{onClick:T,style:{fontSize:13,padding:"8px 16px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-biometric)",cursor:"pointer"},children:["🔐 ",u("security.pin.biometricFallback","Use biometrics instead")]}),O>0&&f!=="success"&&!q&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:u("security.pin.attempts",`${O}/${i} attempts`)})]})},lt=3,ut=4,dt=5,ht=14,ft=e=>{const{gridSize:t=lt,minLength:r=ut,showTrail:n=!0,showError:i=!0,maxAttempts:a=dt,dotSize:o=ht,trailColor:c,mode:m="verify",expectedHash:x,expectedPattern:y,onComplete:v,onVerify:A,onStatusChange:g,onError:I,label:D,className:b,canvasSize:T}=e,{t:p}=X(),k=h.useRef(null),[u,w]=h.useState([]),[l,f]=h.useState(!1),[z,O]=h.useState("idle"),[J,_]=h.useState(0),[H,G]=h.useState(null),[B,L]=h.useState(null),$=T??t*80,E=$/t,q=h.useCallback(d=>{O(d),g==null||g(d)},[g]),W=h.useCallback(()=>{const d=[];for(let j=0;j<t;j++)for(let N=0;N<t;N++)d.push({x:N*E+E/2,y:j*E+E/2});return d},[t,E]),Y=h.useCallback(d=>{const j=k.current.getBoundingClientRect(),N="touches"in d?d.touches[0].clientX:d.clientX,M="touches"in d?d.touches[0].clientY:d.clientY;return{x:N-j.left,y:M-j.top}},[]),P=h.useCallback((d,j)=>{const N=W(),M=E*.38;for(let U=0;U<N.length;U++){const K=N[U].x-d,Z=N[U].y-j;if(K*K+Z*Z<M*M)return U}return-1},[W,E]),C=h.useCallback(()=>{var U;const d=(U=k.current)==null?void 0:U.getContext("2d");if(!d)return;d.clearRect(0,0,$,$);const j=W(),M=z==="failure"&&i?"var(--security-error)":c??"var(--security-biometric)";for(let K=0;K<j.length;K++){const Z=u.includes(K);d.beginPath(),d.arc(j[K].x,j[K].y,Z?o*.75:o*.5,0,Math.PI*2),d.fillStyle=Z?M:"var(--security-border)",d.fill(),Z&&(d.beginPath(),d.arc(j[K].x,j[K].y,o*1.2,0,Math.PI*2),d.strokeStyle=M,d.lineWidth=1.5,d.globalAlpha=.3,d.stroke(),d.globalAlpha=1)}if(n&&u.length>1){d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y);for(let K=1;K<u.length;K++)d.lineTo(j[u[K]].x,j[u[K]].y);l&&B&&d.lineTo(B.x,B.y),d.strokeStyle=M,d.lineWidth=3,d.lineCap="round",d.lineJoin="round",d.globalAlpha=.5,d.stroke(),d.globalAlpha=1}else n&&u.length===1&&l&&B&&(d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y),d.lineTo(B.x,B.y),d.strokeStyle=c??"var(--security-biometric)",d.lineWidth=3,d.globalAlpha=.4,d.stroke(),d.globalAlpha=1)},[$,W,o,u,l,B,z,n,i,c]);h.useEffect(()=>{C()},[C]);const F=h.useCallback(d=>{if(z==="success"||z==="failure")return;d.preventDefault();const{x:j,y:N}=Y(d),M=P(j,N);M>=0&&(f(!0),w([M]),L({x:j,y:N}))},[z,Y,P]),R=h.useCallback(d=>{if(!l)return;d.preventDefault();const{x:j,y:N}=Y(d);L({x:j,y:N});const M=P(j,N);M>=0&&!u.includes(M)&&w(U=>[...U,M])},[l,Y,P,u]),S=h.useCallback(async()=>{if(!l)return;if(f(!1),L(null),u.length<r){w([]);return}const d=u.join(",");if(m==="set"){if(H===null){G([...u]),w([]);return}if(H.join(",")!==d){G(null),q("failure"),setTimeout(()=>{q("idle"),w([])},800);return}v==null||v([...u]),q("success");return}q("processing");let j=!1;if(x){const N=new TextEncoder,M=await crypto.subtle.digest("SHA-256",N.encode(d));j=Array.from(new Uint8Array(M)).map(K=>K.toString(16).padStart(2,"0")).join("")===x}else if(y)j=d===y;else{v==null||v([...u]),q("success");return}if(j)q("success"),A==null||A({success:!0,confidence:1,method:"pattern",timestamp:Date.now(),duration:0}),v==null||v([...u]);else{const N=J+1;_(N),q("failure"),N>=a&&(I==null||I(new Error("Too many failed pattern attempts"))),setTimeout(()=>{q("idle"),w([])},900),A==null||A({success:!1,confidence:0,method:"pattern",timestamp:Date.now(),duration:0})}},[l,u,r,m,H,x,y,J,a,q,v,A,I]);return s.jsxs("div",{className:b,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[D&&s.jsx("div",{style:{fontSize:14,fontWeight:600},children:D}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:z==="success"?p("security.pattern.success","Pattern accepted"):z==="failure"?p("security.pattern.wrong","Wrong pattern"):m==="set"&&H!==null?p("security.pattern.confirm","Draw pattern again to confirm"):m==="set"?p("security.pattern.setNew","Draw a new pattern"):p("security.pattern.draw","Draw your pattern")}),s.jsx("canvas",{ref:k,width:$,height:$,style:{touchAction:"none",borderRadius:"var(--security-radius-lg)",background:"var(--security-bg-panel)",border:`1px solid ${z==="failure"?"var(--security-error)":"var(--security-border)"}`,cursor:"pointer",transition:"border-color 0.3s"},onMouseDown:F,onMouseMove:R,onMouseUp:S,onMouseLeave:S,onTouchStart:F,onTouchMove:R,onTouchEnd:S}),(z==="failure"||z==="success")&&s.jsx("button",{onClick:()=>{w([]),_(0),G(null),q("idle")},style:{fontSize:13,padding:"6px 16px",background:"var(--security-bg-panel)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-text)",cursor:"pointer"},children:p("security.common.retry","Try Again")}),J>0&&z!=="success"&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:p("security.pattern.attempts",`${J}/${a} attempts`)})]})},yt={sm:"8px 16px",md:"12px 24px",lg:"14px 32px"},pt={sm:13,md:14,lg:16},gt=e=>{const{mode:t,credentialIds:r=[],challenge:n,rpName:i=window.location.hostname,rpId:a=window.location.hostname,user:o,attestation:c="none",authenticatorAttachment:m,residentKey:x="preferred",userVerification:y="preferred",onRegister:v,onAuthenticate:A,onVerify:g,onStatusChange:I,onError:D,label:b,className:T,variant:p="primary",size:k="md",fullWidth:u=!1,icon:w}=e,{t:l}=X(),[f,z]=h.useState("idle"),[O,J]=h.useState(!0),[_,H]=h.useState(!1),G=h.useCallback(C=>{z(C),I==null||I(C)},[I]);h.useEffect(()=>{J(fe()),Fe().then(H)},[]);const B=h.useCallback(()=>{if(n){const C=atob(n.replace(/-/g,"+").replace(/_/g,"/")),F=new Uint8Array(C.length);for(let R=0;R<C.length;R++)F[R]=C.charCodeAt(R);return F.buffer}return crypto.getRandomValues(new Uint8Array(32)).buffer},[n]),L=h.useCallback(async()=>{if(!O){D==null||D(new Error("WebAuthn not available"));return}G("processing");try{if(t==="register"){const C=(o==null?void 0:o.id)??crypto.getRandomValues(new Uint8Array(16)),F=(o==null?void 0:o.name)??"user",R=(o==null?void 0:o.displayName)??F,S=B(),d=await Ne({rpName:i,rpId:a,userId:typeof C=="string"?C:Array.from(C).join(""),userName:F,userDisplayName:R,challenge:S});G("success"),d&&(v==null||v(d)),g==null||g({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}else{const C=await ze({rpId:a,challenge:B(),allowCredentials:r==null?void 0:r.map(F=>({id:new TextEncoder().encode(F),type:"public-key"}))});G("success"),C&&(A==null||A(C)),g==null||g({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}}catch(C){const F=C instanceof Error?C:new Error(String(C));F.name==="NotAllowedError"?G("idle"):(G("error"),D==null||D(F),g==null||g({success:!1,confidence:0,method:"webauthn",timestamp:Date.now(),duration:0}))}},[O,t,r,o,i,a,c,m,x,y,B,G,v,A,g,D]),$=t==="register"?_?l("security.webauthn.registerPasskey","🔑 Register Passkey"):l("security.webauthn.register","🔐 Register Security Key"):_?l("security.webauthn.signInPasskey","🔑 Sign in with Passkey"):l("security.webauthn.signIn","🔐 Sign in with Security Key"),E=b??$,q={primary:"var(--security-biometric)",outline:"transparent",ghost:"transparent"},W={primary:"none",outline:"2px solid var(--security-biometric)",ghost:"none"},Y={primary:"var(--nice-bg, #fff)",outline:"var(--security-biometric)",ghost:"var(--security-biometric)"},P=!O||f==="processing"||f==="success";return s.jsxs("div",{className:T,style:{display:u?"block":"inline-block",textAlign:"center"},children:[s.jsxs("button",{onClick:L,disabled:P,style:{width:u?"100%":"auto",padding:yt[k],fontSize:pt[k],fontWeight:600,fontFamily:"var(--security-font)",background:q[p],color:Y[p],border:W[p],borderRadius:"var(--security-radius)",cursor:P?"not-allowed":"pointer",opacity:P?.6:1,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,transition:"opacity 0.2s, transform 0.1s"},children:[f==="processing"&&s.jsx("span",{style:{display:"inline-block",width:16,height:16,borderRadius:"50%",border:"2px solid transparent",borderTopColor:"currentColor",animation:"spin 0.6s linear infinite"}}),f==="success"&&s.jsx("span",{children:"✓"}),w&&f!=="processing"&&f!=="success"&&w,E]}),!O&&s.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-warning)"},children:l("security.webauthn.notAvailable","WebAuthn is not supported in this browser")}),f==="error"&&s.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-error)"},children:l("security.webauthn.error","Authentication failed — try again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},mt={success:"✅",failure:"❌",error:"⚠️",idle:"⏸️",scanning:"🔍",processing:"⏳",timeout:"⏰"},vt=e=>e>=80?"var(--security-error)":e>=50?"var(--security-warning)":"var(--security-success)",xt=({entries:e,pageSize:t=20,showExport:r=!0,filterMethods:n,onEntryClick:i,className:a,label:o})=>{const{t:c}=X(),[m,x]=h.useState("all"),[y,v]=h.useState("all"),[A,g]=h.useState(0),I=h.useMemo(()=>{let l=[...e];return m!=="all"&&(l=l.filter(f=>f.method===m)),y!=="all"&&(l=l.filter(f=>f.status===y)),l.sort((f,z)=>z.timestamp-f.timestamp),l},[e,m,y]),D=Math.max(1,Math.ceil(I.length/t)),b=I.slice(A*t,(A+1)*t),T=h.useMemo(()=>n||Array.from(new Set(e.map(l=>l.method))),[e,n]),p=h.useMemo(()=>Array.from(new Set(e.map(l=>l.status))),[e]),k=h.useCallback(()=>{const l=new Blob([JSON.stringify(I,null,2)],{type:"application/json"}),f=URL.createObjectURL(l),z=document.createElement("a");z.href=f,z.download=`security-audit-${new Date().toISOString().slice(0,10)}.json`,z.click(),URL.revokeObjectURL(f)},[I]),u=l=>new Date(l).toLocaleString(),w={padding:"8px 12px",borderBottom:"1px solid var(--security-border)",fontSize:13,whiteSpace:"nowrap"};return s.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[s.jsx("div",{style:{fontWeight:600,fontSize:15},children:o??c("security.audit.title","🔒 Security Audit Log")}),s.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[s.jsxs("select",{value:m,onChange:l=>{x(l.target.value),g(0)},style:xe,children:[s.jsx("option",{value:"all",children:c("security.audit.allMethods","All methods")}),T.map(l=>s.jsx("option",{value:l,children:l},l))]}),s.jsxs("select",{value:y,onChange:l=>{v(l.target.value),g(0)},style:xe,children:[s.jsx("option",{value:"all",children:c("security.audit.allStatuses","All statuses")}),p.map(l=>s.jsx("option",{value:l,children:l},l))]}),r&&s.jsx("button",{onClick:k,style:bt,title:"Export JSON",children:"📥"})]})]}),s.jsx("div",{style:{overflowX:"auto"},children:s.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[s.jsx("thead",{children:s.jsxs("tr",{style:{background:"var(--security-bg-panel)",fontSize:12,color:"var(--security-text-secondary)",textTransform:"uppercase",letterSpacing:.5},children:[s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.time","Time")}),s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.action","Action")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.method","Method")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.status","Status")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.risk","Risk")}),s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.device","Device")})]})}),s.jsxs("tbody",{children:[b.length===0&&s.jsx("tr",{children:s.jsx("td",{colSpan:6,style:{...w,textAlign:"center",color:"var(--security-text-muted)",padding:24},children:c("security.audit.noEntries","No entries to show")})}),b.map(l=>s.jsxs("tr",{onClick:()=>i==null?void 0:i(l),style:{cursor:i?"pointer":"default"},onMouseEnter:f=>{f.currentTarget.style.background="var(--security-bg-panel)"},onMouseLeave:f=>{f.currentTarget.style.background=""},children:[s.jsx("td",{style:w,children:u(l.timestamp)}),s.jsx("td",{style:w,children:l.action}),s.jsx("td",{style:{...w,textAlign:"center"},children:s.jsx("span",{style:{padding:"2px 8px",borderRadius:12,fontSize:11,fontWeight:600,background:"var(--security-bg-panel)",border:"1px solid var(--security-border)"},children:l.method})}),s.jsxs("td",{style:{...w,textAlign:"center"},children:[mt[l.status]??"•"," ",l.status]}),s.jsx("td",{style:{...w,textAlign:"center"},children:l.riskScore!=null&&s.jsx("span",{style:{color:vt(l.riskScore),fontWeight:600},children:l.riskScore})}),s.jsx("td",{style:{...w,maxWidth:200,overflow:"hidden",textOverflow:"ellipsis"},children:l.device??"—"})]},l.id))]})]})}),D>1&&s.jsxs("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:12,padding:"10px 16px",fontSize:13,color:"var(--security-text-secondary)",borderTop:"1px solid var(--security-border)"},children:[s.jsxs("button",{disabled:A===0,onClick:()=>g(A-1),style:be,children:["← ",c("security.audit.prev","Prev")]}),s.jsxs("span",{children:[A+1," / ",D]}),s.jsxs("button",{disabled:A>=D-1,onClick:()=>g(A+1),style:be,children:[c("security.audit.next","Next")," →"]})]}),s.jsx("div",{style:{padding:"6px 16px",fontSize:11,color:"var(--security-text-muted)",textAlign:"right"},children:c("security.audit.total",`${I.length} entries`)})]})},xe={fontSize:12,padding:"4px 8px",background:"var(--security-bg)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)"},bt={background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",padding:"4px 8px",cursor:"pointer",fontSize:16},be={background:"none",border:"none",cursor:"pointer",color:"var(--security-biometric)",fontWeight:600,fontSize:13},wt={fingerprint:"👆",iris:"👁️",face:"🧑",voice:"🎙️",webauthn:"🔑",pattern:"✦",pin:"🔢",passphrase:"🔤"},St=({options:e,requiredCount:t=1,onSelect:r,onComplete:n,className:i,label:a,layout:o="grid"})=>{const{t:c}=X(),m=e.filter(y=>y.verified).length,x=m>=t;return s.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",display:"flex",flexDirection:"column",gap:16},children:[a&&s.jsx("div",{style:{fontSize:15,fontWeight:600},children:a}),t>1&&s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)"},children:c("security.mfa.progress",`Verified ${m} of ${t} required`)}),s.jsx("div",{style:{display:o==="grid"?"grid":"flex",gridTemplateColumns:o==="grid"?"repeat(auto-fill, minmax(140px, 1fr))":void 0,flexDirection:o==="list"?"column":void 0,gap:12},children:e.map(y=>{const v=y.verified??!1,A=y.disabled||x;return s.jsxs("button",{onClick:()=>!A&&!v&&(r==null?void 0:r(y.method)),disabled:A||v,style:{display:"flex",flexDirection:o==="grid"?"column":"row",alignItems:"center",gap:o==="grid"?8:12,padding:o==="grid"?"20px 16px":"12px 16px",background:v?"rgba(16,185,129,0.08)":"var(--security-bg-panel)",border:`2px solid ${v?"var(--security-success)":"var(--security-border)"}`,borderRadius:"var(--security-radius-lg)",cursor:A||v?"default":"pointer",opacity:A&&!v?.5:1,transition:"border-color 0.2s, background 0.2s",textAlign:o==="grid"?"center":"left"},children:[s.jsx("span",{style:{fontSize:28},children:v?"✅":y.icon??wt[y.method]??"🔐"}),s.jsxs("div",{children:[s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y.label??y.method}),y.description&&s.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:2},children:y.description})]})]},y.method)})}),x&&s.jsxs("div",{style:{textAlign:"center",fontSize:14,fontWeight:600,color:"var(--security-success)",padding:8},children:["✅ ",c("security.mfa.complete","All factors verified")]})]})},kt=({sessions:e,onRevoke:t,onRevokeAll:r,onTrust:n,className:i,label:a,showRevokeAll:o=!0})=>{const{t:c}=X(),[m,x]=h.useState(new Set),y=h.useMemo(()=>[...e].sort((g,I)=>(I.current?1:0)-(g.current?1:0)||I.lastActive-g.lastActive),[e]),v=g=>{const I=new Date(g),b=Date.now()-g;return b<6e4?c("security.session.justNow","Just now"):b<36e5?`${Math.floor(b/6e4)}m ago`:b<864e5?`${Math.floor(b/36e5)}h ago`:I.toLocaleDateString()},A=g=>{x(I=>new Set(I).add(g)),t==null||t(g)};return s.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[s.jsx("div",{style:{fontSize:15,fontWeight:600},children:a??c("security.session.title","🖥️ Active Sessions")}),o&&e.length>1&&s.jsx("button",{onClick:r,style:{fontSize:12,padding:"4px 12px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",color:"var(--security-error)",cursor:"pointer"},children:c("security.session.revokeAll","Revoke all others")})]}),s.jsxs("div",{children:[y.map(g=>s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",borderBottom:"1px solid var(--security-border)",opacity:m.has(g.id)?.5:1,background:g.current?"rgba(59,130,246,0.04)":void 0},children:[s.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center"},children:[s.jsx("span",{style:{fontSize:24},children:g.device.toLowerCase().includes("mobile")?"📱":"💻"}),s.jsxs("div",{children:[s.jsxs("div",{style:{fontSize:14,fontWeight:500},children:[g.device,g.current&&s.jsx("span",{style:{marginLeft:8,fontSize:10,padding:"1px 6px",background:"var(--security-biometric)",color:"var(--nice-bg, #fff)",borderRadius:8},children:c("security.session.current","Current")}),g.trusted&&s.jsx("span",{style:{marginLeft:6,fontSize:10,padding:"1px 6px",background:"var(--security-success)",color:"var(--nice-bg, #fff)",borderRadius:8},children:c("security.session.trusted","Trusted")})]}),s.jsx("div",{style:{fontSize:12,color:"var(--security-text-muted)",marginTop:2},children:[g.browser,g.os,g.location].filter(Boolean).join(" · ")}),s.jsxs("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:1},children:[c("security.session.lastActive","Last active"),":"," ",v(g.lastActive)]})]})]}),s.jsxs("div",{style:{display:"flex",gap:6},children:[n&&!g.current&&s.jsx("button",{onClick:()=>n(g.id,!g.trusted),style:{fontSize:11,padding:"4px 8px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-text-secondary)"},children:g.trusted?"🚫":"✅"}),!g.current&&s.jsx("button",{onClick:()=>A(g.id),disabled:m.has(g.id),style:{fontSize:11,padding:"4px 10px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-error)"},children:c("security.session.revoke","Revoke")})]})]},g.id)),e.length===0&&s.jsx("div",{style:{padding:24,textAlign:"center",color:"var(--security-text-muted)",fontSize:13},children:c("security.session.noSessions","No active sessions")})]})]})},At=({trustScore:e,onScoreComputed:t,trustThreshold:r=60,showFactors:n=!0,showFingerprint:i=!1,className:a,label:o})=>{const{t:c}=X(),[m,x]=h.useState(e??null),[y,v]=h.useState(!e),A=h.useCallback(async()=>{var I;v(!0);try{const D=he(),b=await se(),T=[];let p=50;D.platform&&!D.platform.includes("Linux")&&(T.push({name:"Known platform",score:5,description:"Running on a recognized platform",weight:.05}),p+=5),navigator.cookieEnabled&&(T.push({name:"Cookies enabled",score:5,description:"Browser cookies are enabled",weight:.05}),p+=5),D.screenResolution[0]>=360&&D.screenResolution[1]>=640&&(T.push({name:"Standard resolution",score:5,description:"Screen resolution within normal range",weight:.05}),p+=5),typeof window<"u"&&window.isSecureContext&&(T.push({name:"Secure context",score:10,description:"Running in HTTPS secure context",weight:.1}),p+=10),((I=navigator.languages)==null?void 0:I.length)>0&&(T.push({name:"Language configured",score:5,description:"Browser language is set",weight:.05}),p+=5),D.touchSupport&&(T.push({name:"Touch device",score:5,description:"Touch input is supported",weight:.05}),p+=5);try{const l=document.createElement("canvas").getContext("webgl");l&&l.getExtension("WEBGL_debug_renderer_info")&&(T.push({name:"Hardware GPU",score:10,description:"Hardware GPU detected",weight:.1}),p+=10)}catch{}navigator.credentials&&(T.push({name:"Credential API",score:5,description:"Credential Management API available",weight:.05}),p+=5),p=Math.min(100,Math.max(0,p));const k=Date.now(),u={score:p,factors:T,trusted:p>=r,firstSeen:k,lastSeen:k,fingerprint:b};x(u),t==null||t(u)}finally{v(!1)}},[r,t]);h.useEffect(()=>{e||A()},[e,A]),h.useEffect(()=>{e&&x(e)},[e]);const g=m?m.score>=80?"var(--security-success)":m.score>=50?"var(--security-warning)":"var(--security-error)":"var(--security-text-muted)";return s.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg-panel)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",padding:20,display:"flex",flexDirection:"column",gap:14,alignItems:"center"},children:[s.jsx("div",{style:{fontSize:15,fontWeight:600},children:o??c("security.trust.title","🛡️ Device Trust")}),y?s.jsx("div",{style:{fontSize:13,color:"var(--security-text-muted)"},children:c("security.trust.computing","Analysing device…")}):m?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{position:"relative",width:100,height:100},children:[s.jsxs("svg",{viewBox:"0 0 36 36",style:{width:"100%",height:"100%",transform:"rotate(-90deg)"},children:[s.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:"var(--security-border)",strokeWidth:"2.5"}),s.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:g,strokeWidth:"2.5",strokeDasharray:`${m.score}, 100`,strokeLinecap:"round"})]}),s.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[s.jsx("span",{style:{fontSize:24,fontWeight:700,color:g},children:m.score}),s.jsx("span",{style:{fontSize:10,color:"var(--security-text-muted)"},children:"/100"})]})]}),s.jsx("div",{style:{fontSize:14,fontWeight:600,color:m.trusted?"var(--security-success)":"var(--security-warning)"},children:m.trusted?c("security.trust.trusted","✅ Device Trusted"):c("security.trust.untrusted","⚠️ Low Trust Score")}),n&&m.factors.length>0&&s.jsxs("div",{style:{width:"100%",fontSize:12},children:[s.jsxs("div",{style:{fontWeight:600,marginBottom:6,color:"var(--security-text-secondary)"},children:[c("security.trust.factors","Contributing factors"),":"]}),s.jsx("ul",{style:{margin:0,paddingLeft:18,color:"var(--security-text-muted)"},children:m.factors.map((I,D)=>s.jsx("li",{style:{marginBottom:2},children:I.name},D))})]}),i&&m.fingerprint&&s.jsx("div",{style:{fontSize:10,color:"var(--security-text-muted)",wordBreak:"break-all",textAlign:"center",maxWidth:280,fontFamily:"monospace"},children:m.fingerprint})]}):null]})};function jt(e){if(!e)return 0;let t=0;return e.length>=8&&t++,e.length>=12&&t++,/[a-z]/.test(e)&&/[A-Z]/.test(e)&&t++,/\d/.test(e)&&t++,/[^a-zA-Z0-9]/.test(e)&&t++,/(.)\1{3,}/.test(e)&&t--,Math.max(0,Math.min(4,t))}const Tt=["Very weak","Weak","Fair","Strong","Very strong"],we=["var(--nice-danger, #ef4444)","var(--nice-warning, #f97316)","var(--nice-warning, #eab308)","var(--nice-success, #22c55e)","var(--nice-success, #10b981)"],Ct=({mode:e="verify",expectedHash:t,minStrength:r=2,minLength:n=8,onComplete:i,onVerify:a,onStatusChange:o,onError:c,label:m,placeholder:x,className:y,showStrength:v=!0,maxAttempts:A=5})=>{const{t:g}=X(),[I,D]=h.useState(""),[b,T]=h.useState(""),[p,k]=h.useState(!1),[u,w]=h.useState("idle"),[l,f]=h.useState(0),[z,O]=h.useState(""),J=h.useRef(null),_=jt(I),H=h.useCallback(L=>{w(L),o==null||o(L)},[o]),G=h.useCallback(async()=>{if(O(""),H("processing"),e==="set"){if(I.length<n){O(g("security.passphrase.tooShort",`Minimum ${n} characters`)),H("idle");return}if(_<r){O(g("security.passphrase.tooWeak","Passphrase is too weak")),H("idle");return}if(I!==b){O(g("security.passphrase.noMatch","Passphrases do not match")),H("failure"),setTimeout(()=>H("idle"),1e3);return}i==null||i(I),H("success");return}if(t){const L=new TextEncoder,$=await crypto.subtle.digest("SHA-256",L.encode(I));if(Array.from(new Uint8Array($)).map(W=>W.toString(16).padStart(2,"0")).join("")===t)H("success"),a==null||a({success:!0,confidence:1,method:"passphrase",timestamp:Date.now(),duration:0}),i==null||i(I);else{const W=l+1;f(W),W>=A?(H("failure"),c==null||c(new Error("Too many failed attempts"))):(O(g("security.passphrase.incorrect","Incorrect passphrase")),H("idle")),a==null||a({success:!1,confidence:0,method:"passphrase",timestamp:Date.now(),duration:0})}}else i==null||i(I),H("success")},[I,b,e,t,_,r,n,l,A,g,H,i,a,c]),B={width:"100%",padding:"10px 14px",fontSize:14,background:"var(--security-bg)",color:"var(--security-text)",border:`1px solid ${u==="failure"?"var(--security-error)":"var(--security-border)"}`,borderRadius:"var(--security-radius)",boxSizing:"border-box",fontFamily:"var(--security-font)"};return s.jsxs("div",{className:y,style:{display:"flex",flexDirection:"column",gap:10,maxWidth:340,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[m&&s.jsx("label",{style:{fontSize:14,fontWeight:600},children:m}),s.jsxs("div",{style:{position:"relative"},children:[s.jsx("input",{ref:J,type:p?"text":"password",value:I,onChange:L=>D(L.target.value),placeholder:x??g("security.passphrase.placeholder","Enter passphrase"),style:B,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&G()}),s.jsx("button",{type:"button",onClick:()=>k(!p),style:{position:"absolute",right:8,top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",fontSize:16,color:"var(--security-text-muted)"},tabIndex:-1,children:p?"🙈":"👁️"})]}),e==="set"&&v&&I.length>0&&s.jsxs("div",{children:[s.jsx("div",{style:{display:"flex",gap:3,height:4},children:[0,1,2,3].map(L=>s.jsx("div",{style:{flex:1,borderRadius:2,background:L<_?we[_]:"var(--security-border)",transition:"background 0.2s"}},L))}),s.jsx("div",{style:{fontSize:11,marginTop:4,color:we[_]},children:g(`security.passphrase.strength${_}`,Tt[_])})]}),e==="set"&&s.jsx("input",{type:p?"text":"password",value:b,onChange:L=>T(L.target.value),placeholder:g("security.passphrase.confirmPlaceholder","Confirm passphrase"),style:B,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&G(),onPaste:L=>L.preventDefault()}),z&&s.jsx("div",{style:{fontSize:12,color:"var(--security-error)"},children:z}),s.jsx("button",{onClick:G,disabled:!I||u==="processing"||u==="success",style:{padding:"10px 20px",fontSize:14,fontWeight:600,background:u==="success"?"var(--security-success)":"var(--security-biometric)",color:"var(--nice-bg, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:u==="success"?"default":"pointer",opacity:!I||u==="processing"?.6:1},children:u==="success"?"✓ "+g("security.passphrase.accepted","Accepted"):e==="set"?g("security.passphrase.setBtn","Set Passphrase"):g("security.passphrase.verifyBtn","Verify")}),l>0&&u!=="success"&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:g("security.passphrase.attempts",`${l}/${A} attempts`)})]})};function It(e){const t=[],r={defaultSrc:"default-src",scriptSrc:"script-src",styleSrc:"style-src",imgSrc:"img-src",fontSrc:"font-src",connectSrc:"connect-src",frameSrc:"frame-src",objectSrc:"object-src",mediaSrc:"media-src",workerSrc:"worker-src",childSrc:"child-src",formAction:"form-action",frameAncestors:"frame-ancestors",baseUri:"base-uri",reportUri:"report-uri",reportTo:"report-to",upgradeInsecureRequests:"upgrade-insecure-requests",blockAllMixedContent:"block-all-mixed-content"};return Object.entries(e.directives).forEach(([n,i])=>{const a=r[n];if(a){if(typeof i=="boolean")i&&t.push(a);else if(typeof i=="string")t.push(`${a} ${i}`);else if(Array.isArray(i)){let o=i;e.nonce&&(n==="scriptSrc"||n==="styleSrc")&&(o=[...o,`'nonce-${e.nonce}'`]),t.push(`${a} ${o.join(" ")}`)}}}),t.join("; ")}function Rt(e){const t="'self'";return{defaultSrc:[t],scriptSrc:[t],styleSrc:[t,"'unsafe-inline'"],imgSrc:[t,"data:","blob:",e==null?void 0:e.cdnDomain].filter(Boolean),fontSrc:[t,"data:",e==null?void 0:e.cdnDomain].filter(Boolean),connectSrc:[t,e==null?void 0:e.apiDomain,"wss:"].filter(Boolean),frameSrc:["'none'"],objectSrc:["'none'"],baseUri:[t],formAction:[t],frameAncestors:["'none'"],upgradeInsecureRequests:!0,reportUri:e==null?void 0:e.reportUri}}function Dt(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):Math.random().toString(36).substring(2)+Date.now().toString(36)}const Mt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};function $e(e){return e.replace(/[&<>"'`=/]/g,t=>Mt[t]||t)}function Pt(e,t){let r=$e(e);return t!=null&&t.maxLength&&r.length>t.maxLength&&(r=r.substring(0,t.maxLength)),r}function Et(e){if(!e)return null;try{const t=new URL(e);return!["http:","https:","mailto:","tel:"].includes(t.protocol)||e.toLowerCase().includes("javascript:")?null:t.toString()}catch{return null}}function Ft(e){const t=["script","iframe","object","embed","form"];let r=e;t.forEach(a=>{const o=new RegExp(`<${a}[^>]*>.*?</${a}>`,"gi");r=r.replace(o,"");const c=new RegExp(`<${a}[^>]*/>`,"gi");r=r.replace(c,"")});const n=/\s+on\w+\s*=/gi;r=r.replace(n," data-removed=");const i=/javascript:/gi;return r=r.replace(i,""),r}function Nt(e,t){let r=e;if(t!=null&&t.allowedTags){const n=/<\/?([a-z][a-z0-9]*)[^>]*>/gi;r=r.replace(n,(i,a)=>t.allowedTags.includes(a.toLowerCase())?i:"")}return r=r.replace(/\s+on\w+\s*=/gi," data-removed="),r=r.replace(/javascript:/gi,""),{__html:r}}const ye={headerName:"X-CSRF-Token",cookieName:"XSRF-TOKEN",fieldName:"_csrf"};function zt(){if(typeof crypto<"u"){const e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}return Math.random().toString(36).substring(2)+Date.now().toString(36)}function pe(e=ye.cookieName){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp(`(^| )${e}=([^;]+)`));return t?decodeURIComponent(t[2]):null}function Lt(e=ye){return async function(r,n={}){const i=pe(e.cookieName);i||console.warn("CSRF token not found");const a=new Headers(n.headers);return i&&e.headerName&&a.set(e.headerName,i),fetch(r,{...n,headers:a})}}function $t(e=ye){const t=pe(e.cookieName);return{token:t,inputProps:{type:"hidden",name:e.fieldName,value:t||""},headerName:e.headerName}}function _e(e){const t=new Map,r=e.keyGenerator||(a=>a.url);function n(a){const o=r(a),c=Date.now();let m=t.get(o);(!m||c>m.resetAt)&&(m={count:0,resetAt:c+e.windowMs}),m.count++,t.set(o,m);const x=m.count<=e.maxRequests,y=Math.max(0,e.maxRequests-m.count);return{allowed:x,remaining:y,resetAt:m.resetAt}}function i(a){a?t.delete(a):t.clear()}return{checkLimit:n,reset:i}}function _t(e){const t=_e(e);return{checkAndFetch:async(n,i)=>{const a=t.checkLimit({url:n,method:i==null?void 0:i.method});if(!a.allowed){const o=Math.ceil((a.resetAt-Date.now())/1e3);throw new Error(`Rate limit exceeded. Retry after ${o} seconds.`)}return fetch(n,i)},checkLimit:t.checkLimit,reset:t.reset}}function Be(e,t){const r=[];if(t.allowedTypes&&t.allowedTypes.length>0&&(t.allowedTypes.includes(e.type)||r.push(`File type '${e.type}' is not allowed. Allowed types: ${t.allowedTypes.join(", ")}`)),t.maxSize&&e.size>t.maxSize){const a=(t.maxSize/1048576).toFixed(2),o=(e.size/(1024*1024)).toFixed(2);r.push(`File size (${o}MB) exceeds maximum allowed size (${a}MB)`)}const n=[".exe",".bat",".cmd",".sh",".ps1",".vbs",".js",".jar"],i=e.name.toLowerCase();for(const a of n)if(i.includes(a+".")||i.endsWith(a)){r.push(`File extension '${a}' is not allowed`);break}return{valid:r.length===0,errors:r,file:r.length===0?e:void 0}}function Bt(e,t){const r=[],n=[],i=[];t.maxFiles&&e.length>t.maxFiles&&r.push(`Too many files. Maximum allowed: ${t.maxFiles}`);const a=e.reduce((o,c)=>o+c.size,0);if(t.maxTotalSize&&a>t.maxTotalSize){const o=(t.maxTotalSize/1048576).toFixed(2),c=(a/(1024*1024)).toFixed(2);r.push(`Total file size (${c}MB) exceeds maximum (${o}MB)`)}return e.forEach(o=>{const c=Be(o,t);c.valid?n.push(o):i.push({file:o,errors:c.errors})}),{valid:r.length===0&&i.length===0,errors:[...r,...i.flatMap(o=>o.errors)],validFiles:n,invalidFiles:i}}async function Wt(e,t){const r=new FormData;r.append("file",e);try{const n=await fetch(t,{method:"POST",body:r});if(!n.ok)throw new Error("Virus scan failed");return await n.json()}catch(n){return console.error("Virus scan error:",n),{clean:!1,threat:"Scan failed"}}}function We(){if(typeof localStorage>"u")return null;const e=localStorage.getItem("nice2dev_consent");if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Ht(e){typeof localStorage>"u"||localStorage.setItem("nice2dev_consent",JSON.stringify({...e,necessary:!0,timestamp:new Date().toISOString()}))}function Ut(e){const t=We();return t?t[e]===!0:!1}function Ot(e){if(typeof document>"u")return;document.cookie.split(";").forEach(r=>{const[n]=r.trim().split("=");e.includes(n)||(document.cookie=`${n}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`)})}async function qt(e,t,r=fetch){const n={exportDate:new Date().toISOString(),userId:e};return await Promise.all(Object.entries(t).map(async([i,a])=>{try{const o=await r(a);o.ok&&(n[i]=await o.json())}catch(o){console.error(`Failed to fetch ${i} data:`,o),n[i]={error:"Failed to retrieve data"}}})),n}async function Kt(e,t,r=fetch){try{const n=await r(t,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:e,timestamp:new Date().toISOString()})});return n.ok?{success:!0,confirmationId:(await n.json()).confirmationId}:{success:!1,error:"Deletion request failed"}}catch(n){return{success:!1,error:String(n)}}}function Gt(e,t){var n;const r={...e,id:((n=crypto.randomUUID)==null?void 0:n.call(crypto))||Math.random().toString(36),timestamp:new Date};return t&&fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}).catch(console.error),process.env.NODE_ENV==="development"&&console.warn("[HIPAA] PHI Access:",r),r}function Jt(e){let t=null,r=null,n=Date.now();const i=e.timeoutMinutes*60*1e3,a=e.warningBeforeMs||6e4;function o(){n=Date.now(),t&&clearTimeout(t),r&&clearTimeout(r),e.onWarning&&(r=setTimeout(()=>{var y;const x=i-(Date.now()-n);(y=e.onWarning)==null||y.call(e,x)},i-a)),t=setTimeout(e.onTimeout,i)}function c(){t&&clearTimeout(t),r&&clearTimeout(r)}function m(){return Math.max(0,i-(Date.now()-n))}return o(),typeof window<"u"&&["mousedown","keypress","touchstart","scroll"].forEach(y=>{window.addEventListener(y,o,{passive:!0})}),{resetTimer:o,destroy:c,getTimeRemaining:m}}function Yt(e,t){const r=o=>{const c=o.replace("#",""),m=parseInt(c.substr(0,2),16)/255,x=parseInt(c.substr(2,2),16)/255,y=parseInt(c.substr(4,2),16)/255,v=A=>A<=.03928?A/12.92:Math.pow((A+.055)/1.055,2.4);return .2126*v(m)+.7152*v(x)+.0722*v(y)},n=r(e),i=r(t),a=(Math.max(n,i)+.05)/(Math.min(n,i)+.05);return{ratio:Math.round(a*100)/100,passesAA:a>=4.5,passesAAA:a>=7,passesAALarge:a>=3,passesAAALarge:a>=4.5}}function Zt(e){var r,n,i;if(e.getAttribute("aria-label"))return!0;const t=e.getAttribute("aria-labelledby");if(t){const a=document.getElementById(t);if((r=a==null?void 0:a.textContent)!=null&&r.trim())return!0}if(e.id){const a=document.querySelector(`label[for="${e.id}"]`);if((n=a==null?void 0:a.textContent)!=null&&n.trim())return!0}return!!((i=e.textContent)!=null&&i.trim()||e.getAttribute("title")||e.placeholder)}function Xt(e){const r=(e||document.body).querySelectorAll("h1, h2, h3, h4, h5, h6"),n=[];let i=0,a=!1;return r.forEach(o=>{const c=parseInt(o.tagName[1]);c===1&&(a&&n.push({level:c,element:o,issue:"Multiple H1 elements found"}),a=!0),c>i+1&&i!==0&&n.push({level:c,element:o,issue:`Skipped heading level: H${i} to H${c}`}),i=c}),!a&&r.length>0&&n.push({level:0,element:r[0],issue:"Missing H1 element"}),{valid:n.length===0,issues:n}}function Qt(e){const t=[];let r=null;const n=e.batchSize||10,i=e.flushInterval||5e3;async function a(){if(t.length===0)return;const x=t.splice(0,n);try{await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:x})})}catch(y){console.error("Failed to send audit logs:",y),t.unshift(...x)}}function o(){r||(r=setTimeout(()=>{r=null,a()},i))}function c(x){var v;const y={...x,id:((v=crypto.randomUUID)==null?void 0:v.call(crypto))||Math.random().toString(36),timestamp:new Date,userAgent:e.includeUserAgent&&typeof navigator<"u"?navigator.userAgent:void 0};t.push(y),t.length>=n?a():o()}function m(){r&&clearTimeout(r),a()}return{log:c,flush:a,destroy:m}}function Vt(){return[{controlId:"CC6.1",name:"Logical and Physical Access Controls",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.2",name:"User Registration and Authorization",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.3",name:"Access Control Removal",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"A1.1",name:"System Capacity",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"A1.2",name:"Backup and Recovery",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"C1.1",name:"Confidential Information Classification",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"C1.2",name:"Confidential Information Disposal",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"P1.1",name:"Privacy Notice",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P2.1",name:"Consent",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P3.1",name:"Collection",category:"privacy",status:"in_progress",lastAssessed:new Date}]}const er={hardcodedSecrets:[{pattern:/password\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded password"},{pattern:/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded API key"},{pattern:/secret\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded secret"},{pattern:/token\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded token"}],sqlInjection:[{pattern:/execute\s*\(\s*["'`].*\$\{/gi,name:"Potential SQL injection (template literal)"},{pattern:/query\s*\(\s*["'`].*\+/gi,name:"Potential SQL injection (string concatenation)"}],xss:[{pattern:/dangerouslySetInnerHTML/g,name:"dangerouslySetInnerHTML usage"},{pattern:/innerHTML\s*=/g,name:"innerHTML assignment"},{pattern:/document\.write\s*\(/g,name:"document.write usage"},{pattern:/eval\s*\(/g,name:"eval usage"}],insecureFunctions:[{pattern:/Math\.random\s*\(\)/g,name:"Insecure random (use crypto)"},{pattern:/new Function\s*\(/g,name:"Function constructor (code injection risk)"},{pattern:/setTimeout\s*\(\s*["']/g,name:"setTimeout with string (code injection)"},{pattern:/setInterval\s*\(\s*["']/g,name:"setInterval with string (code injection)"}],infoExposure:[{pattern:/console\.(log|info|warn|error)\s*\(/g,name:"Console logging (remove in production)"},{pattern:/debugger/g,name:"Debugger statement"},{pattern:/TODO.*password/gi,name:"TODO mentioning password"}]};function tr(){return`# .github/workflows/sast.yml
6
+ `})]})},tt={sm:240,md:320,lg:440},rt=e=>{const{mode:t,enrolledTemplates:r=[],referencePhoto:n,onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showBoundingBox:A=!0,livenessSteps:g=1,showReference:I=!0,instructionText:D,...b}=e,{t:T}=X(),p=ie(b),k=tt[x],u=h.useRef(null),w=h.useRef(null),l=h.useRef(null),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[_,H]=h.useState(0),[G,B]=h.useState(""),[L,$]=h.useState(null),[E,q]=h.useState(0),W=h.useCallback(S=>{z(S),o==null||o(S)},[o]),Y=h.useCallback(async()=>{try{const S=await oe("user");l.current=S,u.current&&(u.current.srcObject=S,await u.current.play()),W("idle"),B(T("security.face.lookAtCamera","Look at the camera"))}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),B(T("security.face.cameraError","Camera access denied")),W("error")}},[T,W,c]),P=h.useCallback(()=>{var S;(S=l.current)==null||S.getTracks().forEach(d=>d.stop()),l.current=null},[]);h.useEffect(()=>(Y(),P),[Y,P]);const C=h.useCallback(S=>{var ge,me,ve;const d=(ge=w.current)==null?void 0:ge.getContext("2d");if(!d)return;const j=w.current.width,N=w.current.height;if(d.clearRect(0,0,j,N),!S||!A)return;const M=S.boundingBox,U=j/(((me=u.current)==null?void 0:me.videoWidth)??j),K=N/(((ve=u.current)==null?void 0:ve.videoHeight)??N);d.strokeStyle=f==="success"?"var(--nice-success, #10b981)":"var(--nice-primary, #3b82f6)",d.lineWidth=2,d.setLineDash([6,4]),d.strokeRect(M.x*U,M.y*K,M.width*U,M.height*K),d.setLineDash([]);const Z=[[M.x*U,M.y*K],[(M.x+M.width)*U,M.y*K],[M.x*U,(M.y+M.height)*K],[(M.x+M.width)*U,(M.y+M.height)*K]],Q=12;d.lineWidth=3;for(const[V,ee]of Z)d.beginPath(),d.moveTo(V===M.x*U?V:V-Q,ee),d.lineTo(V,ee),d.lineTo(V,ee===M.y*K?ee+Q:ee-Q),d.stroke()},[A,f]),F=h.useCallback(async()=>{if(!(!u.current||f==="processing"||f==="success")){W("scanning"),B(T("security.face.scanning","Scanning face…"));try{if(p.livenessDetection){const j=[];for(let M=0;M<8;M++)j.push(te(u.current).imageData),await new Promise(U=>setTimeout(U,200));if(!de(j).isLive){B(T("security.face.notLive","Liveness check failed — move naturally")),W("idle");return}}W("processing"),B(T("security.face.processing","Analysing face…"));const{imageData:S}=te(u.current);if(t==="compare"&&n){const j=typeof n=="string"?await st(n):nt(n),{similarity:N,cameraFeatures:M,refFeatures:U}=Me(S,j);q(N),J((M==null?void 0:M.quality)??0),C(M);const Z={success:N>=p.matchThreshold,confidence:N,method:"face",timestamp:Date.now(),duration:0,livenessPassed:p.livenessDetection};Z.success?(B(T("security.face.matchFound",`Match: ${(N*100).toFixed(0)}%`)),W("success")):(H(Q=>Q+1),_+1>=p.maxRetries?(B(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(B(T("security.face.noMatch","No match — try again")),W("idle"))),a==null||a(Z);return}const d=ne(S);if(!d){B(T("security.face.noFaceDetected","No face detected")),W("idle");return}if(J(d.quality),C(d),t==="enroll"){const j=await Pe(d,y??"face");i==null||i(j,d),B(T("security.face.enrolled","Face enrolled successfully")),W("success")}else{let j=0;for(const U of r){const K=Ee(U),Z=ue(d,K);Z>j&&(j=Z)}q(j);const N=j>=p.matchThreshold,M={success:N,confidence:j,method:"face",timestamp:Date.now(),duration:0,livenessPassed:p.livenessDetection};if(N&&p.verifyEndpoint){const U=await se(),K=await ce(p.verifyEndpoint,{method:"face",templateData:btoa(JSON.stringify(d)),matchScore:j,deviceFingerprint:U},p.authToken);M.success=K.verified}M.success?(B(T("security.face.verified","Face verified")),W("success")):(H(U=>U+1),_+1>=p.maxRetries?(B(T("security.face.maxAttempts","Maximum attempts reached")),W("failure")):(B(T("security.face.noMatch","No match — try again")),W("idle"))),a==null||a(M)}}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),B(T("security.face.error","Error — try again")),W("error")}}},[f,t,r,n,p,T,W,i,a,c,y,_,C]),R=f==="success"?"var(--security-success)":f==="failure"||f==="error"?"var(--security-error)":f==="scanning"||f==="processing"?"var(--security-biometric)":"var(--security-border)";return s.jsxs("div",{className:m,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12},children:[y&&s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y}),s.jsxs("div",{style:{display:"flex",gap:16,alignItems:"center"},children:[s.jsxs("div",{style:{width:k,height:k*.75,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${R}`,boxShadow:f==="scanning"?`0 0 20px ${R}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:u,style:{width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)"},playsInline:!0,muted:!0}),s.jsx("canvas",{ref:w,width:k,height:k*.75,style:{position:"absolute",inset:0,pointerEvents:"none",transform:"scaleX(-1)"}}),s.jsx("svg",{viewBox:"0 0 100 75",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:s.jsx("ellipse",{cx:"50",cy:"37",rx:"22",ry:"30",fill:"none",stroke:"white",strokeWidth:"0.8",strokeDasharray:"4 3"})}),(f==="scanning"||f==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,background:"var(--nice-overlay-15, rgba(0, 0, 0, 0.15))",display:"flex",alignItems:"center",justifyContent:"center"},children:s.jsx("div",{style:{width:50,height:50,borderRadius:"50%",border:"3px solid transparent",borderTopColor:R,animation:"spin 0.8s linear infinite"}})})]}),t==="compare"&&I&&n&&s.jsxs("div",{style:{width:k*.4,height:k*.5,borderRadius:"var(--security-radius)",overflow:"hidden",border:"2px solid var(--security-border)"},children:[s.jsx("img",{src:typeof n=="string"?n:void 0,alt:T("security.face.referenceAlt","Reference"),style:{width:"100%",height:"100%",objectFit:"cover"}}),s.jsx("div",{style:{textAlign:"center",fontSize:10,padding:4,color:"var(--security-text-muted)",background:"var(--security-bg-panel)"},children:T("security.face.reference","Reference")})]})]}),E>0&&s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,fontSize:13},children:[s.jsxs("span",{style:{color:"var(--security-text-secondary)"},children:[T("security.face.confidence","Confidence"),":"]}),s.jsx("div",{style:{width:100,height:6,background:"var(--security-bg-panel)",borderRadius:3,overflow:"hidden"},children:s.jsx("div",{style:{width:`${E*100}%`,height:"100%",background:E>=p.matchThreshold?"var(--security-success)":"var(--security-warning)"}})}),s.jsxs("span",{style:{fontWeight:600,color:E>=p.matchThreshold?"var(--security-success)":"var(--security-warning)"},children:[(E*100).toFixed(0),"%"]})]}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:D??G}),f!=="success"&&f!=="failure"&&s.jsx("button",{onClick:F,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"var(--nice-bg, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?T("security.face.captureBtn","📸 Capture Face"):t==="compare"?T("security.face.compareBtn","📸 Compare"):T("security.face.verifyBtn","📸 Verify Face")}),(f==="failure"||f==="error")&&s.jsx("button",{onClick:()=>{H(0),q(0),W("idle"),B("")},style:{padding:"8px 20px",fontSize:13,background:"var(--security-bg-panel)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer"},children:T("security.common.retry","Try Again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})};async function st(e){return new Promise((t,r)=>{const n=new Image;n.crossOrigin="anonymous",n.onload=()=>{const i=document.createElement("canvas");i.width=n.naturalWidth,i.height=n.naturalHeight;const a=i.getContext("2d");a.drawImage(n,0,0),t(a.getImageData(0,0,i.width,i.height))},n.onerror=()=>r(new Error("Failed to load reference image")),n.src=e})}function nt(e){const t=document.createElement("canvas");t.width=e.naturalWidth||e.width,t.height=e.naturalHeight||e.height;const r=t.getContext("2d");return r.drawImage(e,0,0),r.getImageData(0,0,t.width,t.height)}const it=4,at=5,ot=3e4,ct=e=>{const{length:t=it,scramble:r=!1,showDigits:n=!1,maxAttempts:i=at,lockoutDuration:a=ot,keySize:o=64,haptic:c=!0,keyLabels:m,expectedHash:x,expectedPin:y,mode:v="verify",onComplete:A,onVerify:g,onStatusChange:I,onError:D,showBiometricFallback:b=!1,onBiometricFallback:T,label:p,className:k}=e,{t:u}=X(),[w,l]=h.useState([]),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[_,H]=h.useState(0),[G,B]=h.useState(null),L=h.useRef(),$=h.useMemo(()=>{const F=["1","2","3","4","5","6","7","8","9","","0","back"];if(!r)return F;const R=["0","1","2","3","4","5","6","7","8","9"];for(let S=R.length-1;S>0;S--){const d=new Uint32Array(1);crypto.getRandomValues(d);const j=d[0]%(S+1);[R[S],R[j]]=[R[j],R[S]]}return[R[0],R[1],R[2],R[3],R[4],R[5],R[6],R[7],R[8],"",R[9],"back"]},[r,f]),E=h.useCallback(F=>{z(F),I==null||I(F)},[I]);h.useEffect(()=>{if(!(_<=Date.now()))return L.current=setInterval(()=>{Date.now()>=_&&(clearInterval(L.current),E("idle"),J(0),l([]))},500),()=>clearInterval(L.current)},[_,E]);const q=_>Date.now(),W=h.useCallback(()=>{c&&navigator.vibrate&&navigator.vibrate(20)},[c]),Y=h.useCallback(async F=>{if(q||f==="success")return;if(W(),F==="back"){l(j=>j.slice(0,-1));return}if(F==="")return;const R=[...w,F];if(l(R),R.length<t)return;const S=R.join("");if(E("processing"),v==="set"){if(G===null){B(S),l([]),E("idle");return}if(G!==S){B(null),l([]),E("failure"),setTimeout(()=>E("idle"),1200);return}A==null||A(S),E("success");return}let d=!1;if(x){const j=new TextEncoder,N=await crypto.subtle.digest("SHA-256",j.encode(S));d=Array.from(new Uint8Array(N)).map(U=>U.toString(16).padStart(2,"0")).join("")===x}else if(y)d=S===y;else{A==null||A(S),E("success");return}if(d)E("success"),g==null||g({success:!0,confidence:1,method:"pin",timestamp:Date.now(),duration:0}),A==null||A(S);else{const j=O+1;if(J(j),j>=i){const N=Date.now()+a;H(N),E("failure"),D==null||D(new Error("Too many failed PIN attempts"))}else E("failure"),setTimeout(()=>{E("idle"),l([])},800);g==null||g({success:!1,confidence:0,method:"pin",timestamp:Date.now(),duration:0})}},[w,t,q,f,v,G,x,y,O,i,a,W,E,A,g,D]),P=Math.max(0,Math.ceil((_-Date.now())/1e3)),C=f==="success"?"var(--security-success)":f==="failure"?"var(--security-error)":"var(--security-border)";return s.jsxs("div",{className:k,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:16,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[p&&s.jsx("div",{style:{fontSize:14,fontWeight:600},children:p}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:q?u("security.pin.locked",`Locked — try again in ${P}s`):v==="set"&&G!==null?u("security.pin.confirm","Confirm your PIN"):v==="set"?u("security.pin.setNew","Enter a new PIN"):u("security.pin.enter","Enter your PIN")}),s.jsx("div",{style:{display:"flex",gap:12},children:Array.from({length:t},(F,R)=>s.jsx("div",{style:{width:16,height:16,borderRadius:"50%",border:`2px solid ${C}`,background:R<w.length?C:"transparent",transition:"background 0.15s, border-color 0.15s"}},R))}),s.jsx("div",{style:{display:"grid",gridTemplateColumns:`repeat(3, ${o}px)`,gap:10,opacity:q?.4:1,pointerEvents:q?"none":"auto"},children:$.map((F,R)=>{if(F==="")return s.jsx("div",{},R);const S=F==="back";return s.jsx("button",{onClick:()=>Y(F),disabled:q||f==="success","aria-label":S?"Backspace":F,style:{width:o,height:o,borderRadius:"var(--security-key-border-radius, 50%)",border:"1px solid var(--security-key-border, var(--security-border))",background:"var(--security-key-bg, var(--security-bg-panel))",color:"var(--security-key-text, var(--security-text))",fontSize:S?20:22,fontWeight:600,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background 0.1s, transform 0.1s",userSelect:"none"},onMouseDown:d=>{d.currentTarget.style.transform="scale(0.92)"},onMouseUp:d=>{d.currentTarget.style.transform=""},onMouseLeave:d=>{d.currentTarget.style.transform=""},children:S?"⌫":(m==null?void 0:m[F])??F},R)})}),w.length>0&&f!=="success"&&s.jsx("button",{onClick:()=>l([]),style:{fontSize:12,background:"none",border:"none",color:"var(--security-text-secondary)",cursor:"pointer",textDecoration:"underline"},children:u("security.pin.clear","Clear")}),b&&s.jsxs("button",{onClick:T,style:{fontSize:13,padding:"8px 16px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-biometric)",cursor:"pointer"},children:["🔐 ",u("security.pin.biometricFallback","Use biometrics instead")]}),O>0&&f!=="success"&&!q&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:u("security.pin.attempts",`${O}/${i} attempts`)})]})},lt=3,ut=4,dt=5,ht=14,ft=e=>{const{gridSize:t=lt,minLength:r=ut,showTrail:n=!0,showError:i=!0,maxAttempts:a=dt,dotSize:o=ht,trailColor:c,mode:m="verify",expectedHash:x,expectedPattern:y,onComplete:v,onVerify:A,onStatusChange:g,onError:I,label:D,className:b,canvasSize:T}=e,{t:p}=X(),k=h.useRef(null),[u,w]=h.useState([]),[l,f]=h.useState(!1),[z,O]=h.useState("idle"),[J,_]=h.useState(0),[H,G]=h.useState(null),[B,L]=h.useState(null),$=T??t*80,E=$/t,q=h.useCallback(d=>{O(d),g==null||g(d)},[g]),W=h.useCallback(()=>{const d=[];for(let j=0;j<t;j++)for(let N=0;N<t;N++)d.push({x:N*E+E/2,y:j*E+E/2});return d},[t,E]),Y=h.useCallback(d=>{const j=k.current.getBoundingClientRect(),N="touches"in d?d.touches[0].clientX:d.clientX,M="touches"in d?d.touches[0].clientY:d.clientY;return{x:N-j.left,y:M-j.top}},[]),P=h.useCallback((d,j)=>{const N=W(),M=E*.38;for(let U=0;U<N.length;U++){const K=N[U].x-d,Z=N[U].y-j;if(K*K+Z*Z<M*M)return U}return-1},[W,E]),C=h.useCallback(()=>{var U;const d=(U=k.current)==null?void 0:U.getContext("2d");if(!d)return;d.clearRect(0,0,$,$);const j=W(),M=z==="failure"&&i?"var(--security-error)":c??"var(--security-biometric)";for(let K=0;K<j.length;K++){const Z=u.includes(K);d.beginPath(),d.arc(j[K].x,j[K].y,Z?o*.75:o*.5,0,Math.PI*2),d.fillStyle=Z?M:"var(--security-border)",d.fill(),Z&&(d.beginPath(),d.arc(j[K].x,j[K].y,o*1.2,0,Math.PI*2),d.strokeStyle=M,d.lineWidth=1.5,d.globalAlpha=.3,d.stroke(),d.globalAlpha=1)}if(n&&u.length>1){d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y);for(let K=1;K<u.length;K++)d.lineTo(j[u[K]].x,j[u[K]].y);l&&B&&d.lineTo(B.x,B.y),d.strokeStyle=M,d.lineWidth=3,d.lineCap="round",d.lineJoin="round",d.globalAlpha=.5,d.stroke(),d.globalAlpha=1}else n&&u.length===1&&l&&B&&(d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y),d.lineTo(B.x,B.y),d.strokeStyle=c??"var(--security-biometric)",d.lineWidth=3,d.globalAlpha=.4,d.stroke(),d.globalAlpha=1)},[$,W,o,u,l,B,z,n,i,c]);h.useEffect(()=>{C()},[C]);const F=h.useCallback(d=>{if(z==="success"||z==="failure")return;d.preventDefault();const{x:j,y:N}=Y(d),M=P(j,N);M>=0&&(f(!0),w([M]),L({x:j,y:N}))},[z,Y,P]),R=h.useCallback(d=>{if(!l)return;d.preventDefault();const{x:j,y:N}=Y(d);L({x:j,y:N});const M=P(j,N);M>=0&&!u.includes(M)&&w(U=>[...U,M])},[l,Y,P,u]),S=h.useCallback(async()=>{if(!l)return;if(f(!1),L(null),u.length<r){w([]);return}const d=u.join(",");if(m==="set"){if(H===null){G([...u]),w([]);return}if(H.join(",")!==d){G(null),q("failure"),setTimeout(()=>{q("idle"),w([])},800);return}v==null||v([...u]),q("success");return}q("processing");let j=!1;if(x){const N=new TextEncoder,M=await crypto.subtle.digest("SHA-256",N.encode(d));j=Array.from(new Uint8Array(M)).map(K=>K.toString(16).padStart(2,"0")).join("")===x}else if(y)j=d===y;else{v==null||v([...u]),q("success");return}if(j)q("success"),A==null||A({success:!0,confidence:1,method:"pattern",timestamp:Date.now(),duration:0}),v==null||v([...u]);else{const N=J+1;_(N),q("failure"),N>=a&&(I==null||I(new Error("Too many failed pattern attempts"))),setTimeout(()=>{q("idle"),w([])},900),A==null||A({success:!1,confidence:0,method:"pattern",timestamp:Date.now(),duration:0})}},[l,u,r,m,H,x,y,J,a,q,v,A,I]);return s.jsxs("div",{className:b,style:{display:"inline-flex",flexDirection:"column",alignItems:"center",gap:12,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[D&&s.jsx("div",{style:{fontSize:14,fontWeight:600},children:D}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",minHeight:18,textAlign:"center"},children:z==="success"?p("security.pattern.success","Pattern accepted"):z==="failure"?p("security.pattern.wrong","Wrong pattern"):m==="set"&&H!==null?p("security.pattern.confirm","Draw pattern again to confirm"):m==="set"?p("security.pattern.setNew","Draw a new pattern"):p("security.pattern.draw","Draw your pattern")}),s.jsx("canvas",{ref:k,width:$,height:$,style:{touchAction:"none",borderRadius:"var(--security-radius-lg)",background:"var(--security-bg-panel)",border:`1px solid ${z==="failure"?"var(--security-error)":"var(--security-border)"}`,cursor:"pointer",transition:"border-color 0.3s"},onMouseDown:F,onMouseMove:R,onMouseUp:S,onMouseLeave:S,onTouchStart:F,onTouchMove:R,onTouchEnd:S}),(z==="failure"||z==="success")&&s.jsx("button",{onClick:()=>{w([]),_(0),G(null),q("idle")},style:{fontSize:13,padding:"6px 16px",background:"var(--security-bg-panel)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",color:"var(--security-text)",cursor:"pointer"},children:p("security.common.retry","Try Again")}),J>0&&z!=="success"&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:p("security.pattern.attempts",`${J}/${a} attempts`)})]})},yt={sm:"8px 16px",md:"12px 24px",lg:"14px 32px"},pt={sm:13,md:14,lg:16},gt=e=>{const{mode:t,credentialIds:r=[],challenge:n,rpName:i=window.location.hostname,rpId:a=window.location.hostname,user:o,attestation:c="none",authenticatorAttachment:m,residentKey:x="preferred",userVerification:y="preferred",onRegister:v,onAuthenticate:A,onVerify:g,onStatusChange:I,onError:D,label:b,className:T,variant:p="primary",size:k="md",fullWidth:u=!1,icon:w}=e,{t:l}=X(),[f,z]=h.useState("idle"),[O,J]=h.useState(!0),[_,H]=h.useState(!1),G=h.useCallback(C=>{z(C),I==null||I(C)},[I]);h.useEffect(()=>{J(fe()),Fe().then(H)},[]);const B=h.useCallback(()=>{if(n){const C=atob(n.replace(/-/g,"+").replace(/_/g,"/")),F=new Uint8Array(C.length);for(let R=0;R<C.length;R++)F[R]=C.charCodeAt(R);return F.buffer}return crypto.getRandomValues(new Uint8Array(32)).buffer},[n]),L=h.useCallback(async()=>{if(!O){D==null||D(new Error("WebAuthn not available"));return}G("processing");try{if(t==="register"){const C=(o==null?void 0:o.id)??crypto.getRandomValues(new Uint8Array(16)),F=(o==null?void 0:o.name)??"user",R=(o==null?void 0:o.displayName)??F,S=B(),d=await Ne({rpName:i,rpId:a,userId:typeof C=="string"?C:Array.from(C).join(""),userName:F,userDisplayName:R,challenge:S});G("success"),d&&(v==null||v(d)),g==null||g({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}else{const C=await ze({rpId:a,challenge:B(),allowCredentials:r==null?void 0:r.map(F=>({id:new TextEncoder().encode(F),type:"public-key"}))});G("success"),C&&(A==null||A(C)),g==null||g({success:!0,confidence:1,method:"webauthn",timestamp:Date.now(),duration:0})}}catch(C){const F=C instanceof Error?C:new Error(String(C));F.name==="NotAllowedError"?G("idle"):(G("error"),D==null||D(F),g==null||g({success:!1,confidence:0,method:"webauthn",timestamp:Date.now(),duration:0}))}},[O,t,r,o,i,a,c,m,x,y,B,G,v,A,g,D]),$=t==="register"?_?l("security.webauthn.registerPasskey","🔑 Register Passkey"):l("security.webauthn.register","🔐 Register Security Key"):_?l("security.webauthn.signInPasskey","🔑 Sign in with Passkey"):l("security.webauthn.signIn","🔐 Sign in with Security Key"),E=b??$,q={primary:"var(--security-biometric)",outline:"transparent",ghost:"transparent"},W={primary:"none",outline:"2px solid var(--security-biometric)",ghost:"none"},Y={primary:"var(--nice-bg, #fff)",outline:"var(--security-biometric)",ghost:"var(--security-biometric)"},P=!O||f==="processing"||f==="success";return s.jsxs("div",{className:T,style:{display:u?"block":"inline-block",textAlign:"center"},children:[s.jsxs("button",{onClick:L,disabled:P,style:{width:u?"100%":"auto",padding:yt[k],fontSize:pt[k],fontWeight:600,fontFamily:"var(--security-font)",background:q[p],color:Y[p],border:W[p],borderRadius:"var(--security-radius)",cursor:P?"not-allowed":"pointer",opacity:P?.6:1,display:"inline-flex",alignItems:"center",justifyContent:"center",gap:8,transition:"opacity 0.2s, transform 0.1s"},children:[f==="processing"&&s.jsx("span",{style:{display:"inline-block",width:16,height:16,borderRadius:"50%",border:"2px solid transparent",borderTopColor:"currentColor",animation:"spin 0.6s linear infinite"}}),f==="success"&&s.jsx("span",{children:"✓"}),w&&f!=="processing"&&f!=="success"&&w,E]}),!O&&s.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-warning)"},children:l("security.webauthn.notAvailable","WebAuthn is not supported in this browser")}),f==="error"&&s.jsx("div",{style:{fontSize:11,marginTop:6,color:"var(--security-error)"},children:l("security.webauthn.error","Authentication failed — try again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},mt={success:"✅",failure:"❌",error:"⚠️",idle:"⏸️",scanning:"🔍",processing:"⏳",timeout:"⏰"},vt=e=>e>=80?"var(--security-error)":e>=50?"var(--security-warning)":"var(--security-success)",xt=({entries:e,pageSize:t=20,showExport:r=!0,filterMethods:n,onEntryClick:i,className:a,label:o})=>{const{t:c}=X(),[m,x]=h.useState("all"),[y,v]=h.useState("all"),[A,g]=h.useState(0),I=h.useMemo(()=>{let l=[...e];return m!=="all"&&(l=l.filter(f=>f.method===m)),y!=="all"&&(l=l.filter(f=>f.status===y)),l.sort((f,z)=>z.timestamp-f.timestamp),l},[e,m,y]),D=Math.max(1,Math.ceil(I.length/t)),b=I.slice(A*t,(A+1)*t),T=h.useMemo(()=>n||Array.from(new Set(e.map(l=>l.method))),[e,n]),p=h.useMemo(()=>Array.from(new Set(e.map(l=>l.status))),[e]),k=h.useCallback(()=>{const l=new Blob([JSON.stringify(I,null,2)],{type:"application/json"}),f=URL.createObjectURL(l),z=document.createElement("a");z.href=f,z.download=`security-audit-${new Date().toISOString().slice(0,10)}.json`,z.click(),URL.revokeObjectURL(f)},[I]),u=l=>new Date(l).toLocaleString(),w={padding:"8px 12px",borderBottom:"1px solid var(--security-border)",fontSize:13,whiteSpace:"nowrap"};return s.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[s.jsx("div",{style:{fontWeight:600,fontSize:15},children:o??c("security.audit.title","🔒 Security Audit Log")}),s.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center"},children:[s.jsxs("select",{value:m,onChange:l=>{x(l.target.value),g(0)},style:xe,children:[s.jsx("option",{value:"all",children:c("security.audit.allMethods","All methods")}),T.map(l=>s.jsx("option",{value:l,children:l},l))]}),s.jsxs("select",{value:y,onChange:l=>{v(l.target.value),g(0)},style:xe,children:[s.jsx("option",{value:"all",children:c("security.audit.allStatuses","All statuses")}),p.map(l=>s.jsx("option",{value:l,children:l},l))]}),r&&s.jsx("button",{onClick:k,style:bt,title:c("security.audit.exportJson","Export JSON"),children:"📥"})]})]}),s.jsx("div",{style:{overflowX:"auto"},children:s.jsxs("table",{style:{width:"100%",borderCollapse:"collapse"},children:[s.jsx("thead",{children:s.jsxs("tr",{style:{background:"var(--security-bg-panel)",fontSize:12,color:"var(--security-text-secondary)",textTransform:"uppercase",letterSpacing:.5},children:[s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.time","Time")}),s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.action","Action")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.method","Method")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.status","Status")}),s.jsx("th",{style:{...w,textAlign:"center"},children:c("security.audit.risk","Risk")}),s.jsx("th",{style:{...w,textAlign:"left"},children:c("security.audit.device","Device")})]})}),s.jsxs("tbody",{children:[b.length===0&&s.jsx("tr",{children:s.jsx("td",{colSpan:6,style:{...w,textAlign:"center",color:"var(--security-text-muted)",padding:24},children:c("security.audit.noEntries","No entries to show")})}),b.map(l=>s.jsxs("tr",{onClick:()=>i==null?void 0:i(l),style:{cursor:i?"pointer":"default"},onMouseEnter:f=>{f.currentTarget.style.background="var(--security-bg-panel)"},onMouseLeave:f=>{f.currentTarget.style.background=""},children:[s.jsx("td",{style:w,children:u(l.timestamp)}),s.jsx("td",{style:w,children:l.action}),s.jsx("td",{style:{...w,textAlign:"center"},children:s.jsx("span",{style:{padding:"2px 8px",borderRadius:12,fontSize:11,fontWeight:600,background:"var(--security-bg-panel)",border:"1px solid var(--security-border)"},children:l.method})}),s.jsxs("td",{style:{...w,textAlign:"center"},children:[mt[l.status]??"•"," ",l.status]}),s.jsx("td",{style:{...w,textAlign:"center"},children:l.riskScore!=null&&s.jsx("span",{style:{color:vt(l.riskScore),fontWeight:600},children:l.riskScore})}),s.jsx("td",{style:{...w,maxWidth:200,overflow:"hidden",textOverflow:"ellipsis"},children:l.device??"—"})]},l.id))]})]})}),D>1&&s.jsxs("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",gap:12,padding:"10px 16px",fontSize:13,color:"var(--security-text-secondary)",borderTop:"1px solid var(--security-border)"},children:[s.jsxs("button",{disabled:A===0,onClick:()=>g(A-1),style:be,children:["← ",c("security.audit.prev","Prev")]}),s.jsxs("span",{children:[A+1," / ",D]}),s.jsxs("button",{disabled:A>=D-1,onClick:()=>g(A+1),style:be,children:[c("security.audit.next","Next")," →"]})]}),s.jsx("div",{style:{padding:"6px 16px",fontSize:11,color:"var(--security-text-muted)",textAlign:"right"},children:c("security.audit.total",`${I.length} entries`)})]})},xe={fontSize:12,padding:"4px 8px",background:"var(--security-bg)",color:"var(--security-text)",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)"},bt={background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",padding:"4px 8px",cursor:"pointer",fontSize:16},be={background:"none",border:"none",cursor:"pointer",color:"var(--security-biometric)",fontWeight:600,fontSize:13},wt={fingerprint:"👆",iris:"👁️",face:"🧑",voice:"🎙️",webauthn:"🔑",pattern:"✦",pin:"🔢",passphrase:"🔤"},St=({options:e,requiredCount:t=1,onSelect:r,onComplete:n,className:i,label:a,layout:o="grid"})=>{const{t:c}=X(),m=e.filter(y=>y.verified).length,x=m>=t;return s.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",display:"flex",flexDirection:"column",gap:16},children:[a&&s.jsx("div",{style:{fontSize:15,fontWeight:600},children:a}),t>1&&s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)"},children:c("security.mfa.progress",`Verified ${m} of ${t} required`)}),s.jsx("div",{style:{display:o==="grid"?"grid":"flex",gridTemplateColumns:o==="grid"?"repeat(auto-fill, minmax(140px, 1fr))":void 0,flexDirection:o==="list"?"column":void 0,gap:12},children:e.map(y=>{const v=y.verified??!1,A=y.disabled||x;return s.jsxs("button",{onClick:()=>!A&&!v&&(r==null?void 0:r(y.method)),disabled:A||v,style:{display:"flex",flexDirection:o==="grid"?"column":"row",alignItems:"center",gap:o==="grid"?8:12,padding:o==="grid"?"20px 16px":"12px 16px",background:v?"rgba(16,185,129,0.08)":"var(--security-bg-panel)",border:`2px solid ${v?"var(--security-success)":"var(--security-border)"}`,borderRadius:"var(--security-radius-lg)",cursor:A||v?"default":"pointer",opacity:A&&!v?.5:1,transition:"border-color 0.2s, background 0.2s",textAlign:o==="grid"?"center":"left"},children:[s.jsx("span",{style:{fontSize:28},children:v?"✅":y.icon??wt[y.method]??"🔐"}),s.jsxs("div",{children:[s.jsx("div",{style:{fontSize:14,fontWeight:600,color:"var(--security-text)"},children:y.label??y.method}),y.description&&s.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:2},children:y.description})]})]},y.method)})}),x&&s.jsxs("div",{style:{textAlign:"center",fontSize:14,fontWeight:600,color:"var(--security-success)",padding:8},children:["✅ ",c("security.mfa.complete","All factors verified")]})]})},kt=({sessions:e,onRevoke:t,onRevokeAll:r,onTrust:n,className:i,label:a,showRevokeAll:o=!0})=>{const{t:c}=X(),[m,x]=h.useState(new Set),y=h.useMemo(()=>[...e].sort((g,I)=>(I.current?1:0)-(g.current?1:0)||I.lastActive-g.lastActive),[e]),v=g=>{const I=new Date(g),b=Date.now()-g;return b<6e4?c("security.session.justNow","Just now"):b<36e5?`${Math.floor(b/6e4)}m ago`:b<864e5?`${Math.floor(b/36e5)}h ago`:I.toLocaleDateString()},A=g=>{x(I=>new Set(I).add(g)),t==null||t(g)};return s.jsxs("div",{className:i,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",overflow:"hidden"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",background:"var(--security-bg-panel)",borderBottom:"1px solid var(--security-border)"},children:[s.jsx("div",{style:{fontSize:15,fontWeight:600},children:a??c("security.session.title","🖥️ Active Sessions")}),o&&e.length>1&&s.jsx("button",{onClick:r,style:{fontSize:12,padding:"4px 12px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",color:"var(--security-error)",cursor:"pointer"},children:c("security.session.revokeAll","Revoke all others")})]}),s.jsxs("div",{children:[y.map(g=>s.jsxs("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",padding:"12px 16px",borderBottom:"1px solid var(--security-border)",opacity:m.has(g.id)?.5:1,background:g.current?"rgba(59,130,246,0.04)":void 0},children:[s.jsxs("div",{style:{display:"flex",gap:12,alignItems:"center"},children:[s.jsx("span",{style:{fontSize:24},children:g.device.toLowerCase().includes("mobile")?"📱":"💻"}),s.jsxs("div",{children:[s.jsxs("div",{style:{fontSize:14,fontWeight:500},children:[g.device,g.current&&s.jsx("span",{style:{marginLeft:8,fontSize:10,padding:"1px 6px",background:"var(--security-biometric)",color:"var(--nice-bg, #fff)",borderRadius:8},children:c("security.session.current","Current")}),g.trusted&&s.jsx("span",{style:{marginLeft:6,fontSize:10,padding:"1px 6px",background:"var(--security-success)",color:"var(--nice-bg, #fff)",borderRadius:8},children:c("security.session.trusted","Trusted")})]}),s.jsx("div",{style:{fontSize:12,color:"var(--security-text-muted)",marginTop:2},children:[g.browser,g.os,g.location].filter(Boolean).join(" · ")}),s.jsxs("div",{style:{fontSize:11,color:"var(--security-text-muted)",marginTop:1},children:[c("security.session.lastActive","Last active"),":"," ",v(g.lastActive)]})]})]}),s.jsxs("div",{style:{display:"flex",gap:6},children:[n&&!g.current&&s.jsx("button",{onClick:()=>n(g.id,!g.trusted),style:{fontSize:11,padding:"4px 8px",background:"none",border:"1px solid var(--security-border)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-text-secondary)"},children:g.trusted?"🚫":"✅"}),!g.current&&s.jsx("button",{onClick:()=>A(g.id),disabled:m.has(g.id),style:{fontSize:11,padding:"4px 10px",background:"none",border:"1px solid var(--security-error)",borderRadius:"var(--security-radius)",cursor:"pointer",color:"var(--security-error)"},children:c("security.session.revoke","Revoke")})]})]},g.id)),e.length===0&&s.jsx("div",{style:{padding:24,textAlign:"center",color:"var(--security-text-muted)",fontSize:13},children:c("security.session.noSessions","No active sessions")})]})]})},At=({trustScore:e,onScoreComputed:t,trustThreshold:r=60,showFactors:n=!0,showFingerprint:i=!1,className:a,label:o})=>{const{t:c}=X(),[m,x]=h.useState(e??null),[y,v]=h.useState(!e),A=h.useCallback(async()=>{var I;v(!0);try{const D=he(),b=await se(),T=[];let p=50;D.platform&&!D.platform.includes("Linux")&&(T.push({name:"Known platform",score:5,description:"Running on a recognized platform",weight:.05}),p+=5),navigator.cookieEnabled&&(T.push({name:"Cookies enabled",score:5,description:"Browser cookies are enabled",weight:.05}),p+=5),D.screenResolution[0]>=360&&D.screenResolution[1]>=640&&(T.push({name:"Standard resolution",score:5,description:"Screen resolution within normal range",weight:.05}),p+=5),typeof window<"u"&&window.isSecureContext&&(T.push({name:"Secure context",score:10,description:"Running in HTTPS secure context",weight:.1}),p+=10),((I=navigator.languages)==null?void 0:I.length)>0&&(T.push({name:"Language configured",score:5,description:"Browser language is set",weight:.05}),p+=5),D.touchSupport&&(T.push({name:"Touch device",score:5,description:"Touch input is supported",weight:.05}),p+=5);try{const l=document.createElement("canvas").getContext("webgl");l&&l.getExtension("WEBGL_debug_renderer_info")&&(T.push({name:"Hardware GPU",score:10,description:"Hardware GPU detected",weight:.1}),p+=10)}catch{}navigator.credentials&&(T.push({name:"Credential API",score:5,description:"Credential Management API available",weight:.05}),p+=5),p=Math.min(100,Math.max(0,p));const k=Date.now(),u={score:p,factors:T,trusted:p>=r,firstSeen:k,lastSeen:k,fingerprint:b};x(u),t==null||t(u)}finally{v(!1)}},[r,t]);h.useEffect(()=>{e||A()},[e,A]),h.useEffect(()=>{e&&x(e)},[e]);const g=m?m.score>=80?"var(--security-success)":m.score>=50?"var(--security-warning)":"var(--security-error)":"var(--security-text-muted)";return s.jsxs("div",{className:a,style:{fontFamily:"var(--security-font)",color:"var(--security-text)",background:"var(--security-bg-panel)",borderRadius:"var(--security-radius-lg)",border:"1px solid var(--security-border)",padding:20,display:"flex",flexDirection:"column",gap:14,alignItems:"center"},children:[s.jsx("div",{style:{fontSize:15,fontWeight:600},children:o??c("security.trust.title","🛡️ Device Trust")}),y?s.jsx("div",{style:{fontSize:13,color:"var(--security-text-muted)"},children:c("security.trust.computing","Analysing device…")}):m?s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{position:"relative",width:100,height:100},children:[s.jsxs("svg",{viewBox:"0 0 36 36",style:{width:"100%",height:"100%",transform:"rotate(-90deg)"},children:[s.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:"var(--security-border)",strokeWidth:"2.5"}),s.jsx("circle",{cx:"18",cy:"18",r:"15.9",fill:"none",stroke:g,strokeWidth:"2.5",strokeDasharray:`${m.score}, 100`,strokeLinecap:"round"})]}),s.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},children:[s.jsx("span",{style:{fontSize:24,fontWeight:700,color:g},children:m.score}),s.jsx("span",{style:{fontSize:10,color:"var(--security-text-muted)"},children:"/100"})]})]}),s.jsx("div",{style:{fontSize:14,fontWeight:600,color:m.trusted?"var(--security-success)":"var(--security-warning)"},children:m.trusted?c("security.trust.trusted","✅ Device Trusted"):c("security.trust.untrusted","⚠️ Low Trust Score")}),n&&m.factors.length>0&&s.jsxs("div",{style:{width:"100%",fontSize:12},children:[s.jsxs("div",{style:{fontWeight:600,marginBottom:6,color:"var(--security-text-secondary)"},children:[c("security.trust.factors","Contributing factors"),":"]}),s.jsx("ul",{style:{margin:0,paddingLeft:18,color:"var(--security-text-muted)"},children:m.factors.map((I,D)=>s.jsx("li",{style:{marginBottom:2},children:I.name},D))})]}),i&&m.fingerprint&&s.jsx("div",{style:{fontSize:10,color:"var(--security-text-muted)",wordBreak:"break-all",textAlign:"center",maxWidth:280,fontFamily:"monospace"},children:m.fingerprint})]}):null]})};function jt(e){if(!e)return 0;let t=0;return e.length>=8&&t++,e.length>=12&&t++,/[a-z]/.test(e)&&/[A-Z]/.test(e)&&t++,/\d/.test(e)&&t++,/[^a-zA-Z0-9]/.test(e)&&t++,/(.)\1{3,}/.test(e)&&t--,Math.max(0,Math.min(4,t))}const Tt=["Very weak","Weak","Fair","Strong","Very strong"],we=["var(--nice-danger, #ef4444)","var(--nice-warning, #f97316)","var(--nice-warning, #eab308)","var(--nice-success, #22c55e)","var(--nice-success, #10b981)"],Ct=({mode:e="verify",expectedHash:t,minStrength:r=2,minLength:n=8,onComplete:i,onVerify:a,onStatusChange:o,onError:c,label:m,placeholder:x,className:y,showStrength:v=!0,maxAttempts:A=5})=>{const{t:g}=X(),[I,D]=h.useState(""),[b,T]=h.useState(""),[p,k]=h.useState(!1),[u,w]=h.useState("idle"),[l,f]=h.useState(0),[z,O]=h.useState(""),J=h.useRef(null),_=jt(I),H=h.useCallback(L=>{w(L),o==null||o(L)},[o]),G=h.useCallback(async()=>{if(O(""),H("processing"),e==="set"){if(I.length<n){O(g("security.passphrase.tooShort",`Minimum ${n} characters`)),H("idle");return}if(_<r){O(g("security.passphrase.tooWeak","Passphrase is too weak")),H("idle");return}if(I!==b){O(g("security.passphrase.noMatch","Passphrases do not match")),H("failure"),setTimeout(()=>H("idle"),1e3);return}i==null||i(I),H("success");return}if(t){const L=new TextEncoder,$=await crypto.subtle.digest("SHA-256",L.encode(I));if(Array.from(new Uint8Array($)).map(W=>W.toString(16).padStart(2,"0")).join("")===t)H("success"),a==null||a({success:!0,confidence:1,method:"passphrase",timestamp:Date.now(),duration:0}),i==null||i(I);else{const W=l+1;f(W),W>=A?(H("failure"),c==null||c(new Error("Too many failed attempts"))):(O(g("security.passphrase.incorrect","Incorrect passphrase")),H("idle")),a==null||a({success:!1,confidence:0,method:"passphrase",timestamp:Date.now(),duration:0})}}else i==null||i(I),H("success")},[I,b,e,t,_,r,n,l,A,g,H,i,a,c]),B={width:"100%",padding:"10px 14px",fontSize:14,background:"var(--security-bg)",color:"var(--security-text)",border:`1px solid ${u==="failure"?"var(--security-error)":"var(--security-border)"}`,borderRadius:"var(--security-radius)",boxSizing:"border-box",fontFamily:"var(--security-font)"};return s.jsxs("div",{className:y,style:{display:"flex",flexDirection:"column",gap:10,maxWidth:340,fontFamily:"var(--security-font)",color:"var(--security-text)"},children:[m&&s.jsx("label",{style:{fontSize:14,fontWeight:600},children:m}),s.jsxs("div",{style:{position:"relative"},children:[s.jsx("input",{ref:J,type:p?"text":"password",value:I,onChange:L=>D(L.target.value),placeholder:x??g("security.passphrase.placeholder","Enter passphrase"),style:B,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&G()}),s.jsx("button",{type:"button",onClick:()=>k(!p),style:{position:"absolute",right:8,top:"50%",transform:"translateY(-50%)",background:"none",border:"none",cursor:"pointer",fontSize:16,color:"var(--security-text-muted)"},tabIndex:-1,children:p?"🙈":"👁️"})]}),e==="set"&&v&&I.length>0&&s.jsxs("div",{children:[s.jsx("div",{style:{display:"flex",gap:3,height:4},children:[0,1,2,3].map(L=>s.jsx("div",{style:{flex:1,borderRadius:2,background:L<_?we[_]:"var(--security-border)",transition:"background 0.2s"}},L))}),s.jsx("div",{style:{fontSize:11,marginTop:4,color:we[_]},children:g(`security.passphrase.strength${_}`,Tt[_])})]}),e==="set"&&s.jsx("input",{type:p?"text":"password",value:b,onChange:L=>T(L.target.value),placeholder:g("security.passphrase.confirmPlaceholder","Confirm passphrase"),style:B,disabled:u==="success",onKeyDown:L=>L.key==="Enter"&&G(),onPaste:L=>L.preventDefault()}),z&&s.jsx("div",{style:{fontSize:12,color:"var(--security-error)"},children:z}),s.jsx("button",{onClick:G,disabled:!I||u==="processing"||u==="success",style:{padding:"10px 20px",fontSize:14,fontWeight:600,background:u==="success"?"var(--security-success)":"var(--security-biometric)",color:"var(--nice-bg, #fff)",border:"none",borderRadius:"var(--security-radius)",cursor:u==="success"?"default":"pointer",opacity:!I||u==="processing"?.6:1},children:u==="success"?"✓ "+g("security.passphrase.accepted","Accepted"):e==="set"?g("security.passphrase.setBtn","Set Passphrase"):g("security.passphrase.verifyBtn","Verify")}),l>0&&u!=="success"&&s.jsx("div",{style:{fontSize:11,color:"var(--security-warning)"},children:g("security.passphrase.attempts",`${l}/${A} attempts`)})]})};function It(e){const t=[],r={defaultSrc:"default-src",scriptSrc:"script-src",styleSrc:"style-src",imgSrc:"img-src",fontSrc:"font-src",connectSrc:"connect-src",frameSrc:"frame-src",objectSrc:"object-src",mediaSrc:"media-src",workerSrc:"worker-src",childSrc:"child-src",formAction:"form-action",frameAncestors:"frame-ancestors",baseUri:"base-uri",reportUri:"report-uri",reportTo:"report-to",upgradeInsecureRequests:"upgrade-insecure-requests",blockAllMixedContent:"block-all-mixed-content"};return Object.entries(e.directives).forEach(([n,i])=>{const a=r[n];if(a){if(typeof i=="boolean")i&&t.push(a);else if(typeof i=="string")t.push(`${a} ${i}`);else if(Array.isArray(i)){let o=i;e.nonce&&(n==="scriptSrc"||n==="styleSrc")&&(o=[...o,`'nonce-${e.nonce}'`]),t.push(`${a} ${o.join(" ")}`)}}}),t.join("; ")}function Rt(e){const t="'self'";return{defaultSrc:[t],scriptSrc:[t],styleSrc:[t,"'unsafe-inline'"],imgSrc:[t,"data:","blob:",e==null?void 0:e.cdnDomain].filter(Boolean),fontSrc:[t,"data:",e==null?void 0:e.cdnDomain].filter(Boolean),connectSrc:[t,e==null?void 0:e.apiDomain,"wss:"].filter(Boolean),frameSrc:["'none'"],objectSrc:["'none'"],baseUri:[t],formAction:[t],frameAncestors:["'none'"],upgradeInsecureRequests:!0,reportUri:e==null?void 0:e.reportUri}}function Dt(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):Math.random().toString(36).substring(2)+Date.now().toString(36)}const Mt={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};function $e(e){return e.replace(/[&<>"'`=/]/g,t=>Mt[t]||t)}function Pt(e,t){let r=$e(e);return t!=null&&t.maxLength&&r.length>t.maxLength&&(r=r.substring(0,t.maxLength)),r}function Et(e){if(!e)return null;try{const t=new URL(e);return!["http:","https:","mailto:","tel:"].includes(t.protocol)||e.toLowerCase().includes("javascript:")?null:t.toString()}catch{return null}}function Ft(e){const t=["script","iframe","object","embed","form"];let r=e;t.forEach(a=>{const o=new RegExp(`<${a}[^>]*>.*?</${a}>`,"gi");r=r.replace(o,"");const c=new RegExp(`<${a}[^>]*/>`,"gi");r=r.replace(c,"")});const n=/\s+on\w+\s*=/gi;r=r.replace(n," data-removed=");const i=/javascript:/gi;return r=r.replace(i,""),r}function Nt(e,t){let r=e;if(t!=null&&t.allowedTags){const n=/<\/?([a-z][a-z0-9]*)[^>]*>/gi;r=r.replace(n,(i,a)=>t.allowedTags.includes(a.toLowerCase())?i:"")}return r=r.replace(/\s+on\w+\s*=/gi," data-removed="),r=r.replace(/javascript:/gi,""),{__html:r}}const ye={headerName:"X-CSRF-Token",cookieName:"XSRF-TOKEN",fieldName:"_csrf"};function zt(){if(typeof crypto<"u"){const e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(16).padStart(2,"0")).join("")}return Math.random().toString(36).substring(2)+Date.now().toString(36)}function pe(e=ye.cookieName){if(typeof document>"u")return null;const t=document.cookie.match(new RegExp(`(^| )${e}=([^;]+)`));return t?decodeURIComponent(t[2]):null}function Lt(e=ye){return async function(r,n={}){const i=pe(e.cookieName);i||console.warn("CSRF token not found");const a=new Headers(n.headers);return i&&e.headerName&&a.set(e.headerName,i),fetch(r,{...n,headers:a})}}function $t(e=ye){const t=pe(e.cookieName);return{token:t,inputProps:{type:"hidden",name:e.fieldName,value:t||""},headerName:e.headerName}}function _e(e){const t=new Map,r=e.keyGenerator||(a=>a.url);function n(a){const o=r(a),c=Date.now();let m=t.get(o);(!m||c>m.resetAt)&&(m={count:0,resetAt:c+e.windowMs}),m.count++,t.set(o,m);const x=m.count<=e.maxRequests,y=Math.max(0,e.maxRequests-m.count);return{allowed:x,remaining:y,resetAt:m.resetAt}}function i(a){a?t.delete(a):t.clear()}return{checkLimit:n,reset:i}}function _t(e){const t=_e(e);return{checkAndFetch:async(n,i)=>{const a=t.checkLimit({url:n,method:i==null?void 0:i.method});if(!a.allowed){const o=Math.ceil((a.resetAt-Date.now())/1e3);throw new Error(`Rate limit exceeded. Retry after ${o} seconds.`)}return fetch(n,i)},checkLimit:t.checkLimit,reset:t.reset}}function Be(e,t){const r=[];if(t.allowedTypes&&t.allowedTypes.length>0&&(t.allowedTypes.includes(e.type)||r.push(`File type '${e.type}' is not allowed. Allowed types: ${t.allowedTypes.join(", ")}`)),t.maxSize&&e.size>t.maxSize){const a=(t.maxSize/1048576).toFixed(2),o=(e.size/(1024*1024)).toFixed(2);r.push(`File size (${o}MB) exceeds maximum allowed size (${a}MB)`)}const n=[".exe",".bat",".cmd",".sh",".ps1",".vbs",".js",".jar"],i=e.name.toLowerCase();for(const a of n)if(i.includes(a+".")||i.endsWith(a)){r.push(`File extension '${a}' is not allowed`);break}return{valid:r.length===0,errors:r,file:r.length===0?e:void 0}}function Bt(e,t){const r=[],n=[],i=[];t.maxFiles&&e.length>t.maxFiles&&r.push(`Too many files. Maximum allowed: ${t.maxFiles}`);const a=e.reduce((o,c)=>o+c.size,0);if(t.maxTotalSize&&a>t.maxTotalSize){const o=(t.maxTotalSize/1048576).toFixed(2),c=(a/(1024*1024)).toFixed(2);r.push(`Total file size (${c}MB) exceeds maximum (${o}MB)`)}return e.forEach(o=>{const c=Be(o,t);c.valid?n.push(o):i.push({file:o,errors:c.errors})}),{valid:r.length===0&&i.length===0,errors:[...r,...i.flatMap(o=>o.errors)],validFiles:n,invalidFiles:i}}async function Wt(e,t){const r=new FormData;r.append("file",e);try{const n=await fetch(t,{method:"POST",body:r});if(!n.ok)throw new Error("Virus scan failed");return await n.json()}catch(n){return console.error("Virus scan error:",n),{clean:!1,threat:"Scan failed"}}}function We(){if(typeof localStorage>"u")return null;const e=localStorage.getItem("nice2dev_consent");if(!e)return null;try{return JSON.parse(e)}catch{return null}}function Ht(e){typeof localStorage>"u"||localStorage.setItem("nice2dev_consent",JSON.stringify({...e,necessary:!0,timestamp:new Date().toISOString()}))}function Ut(e){const t=We();return t?t[e]===!0:!1}function Ot(e){if(typeof document>"u")return;document.cookie.split(";").forEach(r=>{const[n]=r.trim().split("=");e.includes(n)||(document.cookie=`${n}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`)})}async function qt(e,t,r=fetch){const n={exportDate:new Date().toISOString(),userId:e};return await Promise.all(Object.entries(t).map(async([i,a])=>{try{const o=await r(a);o.ok&&(n[i]=await o.json())}catch(o){console.error(`Failed to fetch ${i} data:`,o),n[i]={error:"Failed to retrieve data"}}})),n}async function Kt(e,t,r=fetch){try{const n=await r(t,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({userId:e,timestamp:new Date().toISOString()})});return n.ok?{success:!0,confirmationId:(await n.json()).confirmationId}:{success:!1,error:"Deletion request failed"}}catch(n){return{success:!1,error:String(n)}}}function Gt(e,t){var n;const r={...e,id:((n=crypto.randomUUID)==null?void 0:n.call(crypto))||Math.random().toString(36),timestamp:new Date};return t&&fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}).catch(console.error),process.env.NODE_ENV==="development"&&console.warn("[HIPAA] PHI Access:",r),r}function Jt(e){let t=null,r=null,n=Date.now();const i=e.timeoutMinutes*60*1e3,a=e.warningBeforeMs||6e4;function o(){n=Date.now(),t&&clearTimeout(t),r&&clearTimeout(r),e.onWarning&&(r=setTimeout(()=>{var y;const x=i-(Date.now()-n);(y=e.onWarning)==null||y.call(e,x)},i-a)),t=setTimeout(e.onTimeout,i)}function c(){t&&clearTimeout(t),r&&clearTimeout(r)}function m(){return Math.max(0,i-(Date.now()-n))}return o(),typeof window<"u"&&["mousedown","keypress","touchstart","scroll"].forEach(y=>{window.addEventListener(y,o,{passive:!0})}),{resetTimer:o,destroy:c,getTimeRemaining:m}}function Yt(e,t){const r=o=>{const c=o.replace("#",""),m=parseInt(c.substr(0,2),16)/255,x=parseInt(c.substr(2,2),16)/255,y=parseInt(c.substr(4,2),16)/255,v=A=>A<=.03928?A/12.92:Math.pow((A+.055)/1.055,2.4);return .2126*v(m)+.7152*v(x)+.0722*v(y)},n=r(e),i=r(t),a=(Math.max(n,i)+.05)/(Math.min(n,i)+.05);return{ratio:Math.round(a*100)/100,passesAA:a>=4.5,passesAAA:a>=7,passesAALarge:a>=3,passesAAALarge:a>=4.5}}function Zt(e){var r,n,i;if(e.getAttribute("aria-label"))return!0;const t=e.getAttribute("aria-labelledby");if(t){const a=document.getElementById(t);if((r=a==null?void 0:a.textContent)!=null&&r.trim())return!0}if(e.id){const a=document.querySelector(`label[for="${e.id}"]`);if((n=a==null?void 0:a.textContent)!=null&&n.trim())return!0}return!!((i=e.textContent)!=null&&i.trim()||e.getAttribute("title")||e.placeholder)}function Xt(e){const r=(e||document.body).querySelectorAll("h1, h2, h3, h4, h5, h6"),n=[];let i=0,a=!1;return r.forEach(o=>{const c=parseInt(o.tagName[1]);c===1&&(a&&n.push({level:c,element:o,issue:"Multiple H1 elements found"}),a=!0),c>i+1&&i!==0&&n.push({level:c,element:o,issue:`Skipped heading level: H${i} to H${c}`}),i=c}),!a&&r.length>0&&n.push({level:0,element:r[0],issue:"Missing H1 element"}),{valid:n.length===0,issues:n}}function Qt(e){const t=[];let r=null;const n=e.batchSize||10,i=e.flushInterval||5e3;async function a(){if(t.length===0)return;const x=t.splice(0,n);try{await fetch(e.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({entries:x})})}catch(y){console.error("Failed to send audit logs:",y),t.unshift(...x)}}function o(){r||(r=setTimeout(()=>{r=null,a()},i))}function c(x){var v;const y={...x,id:((v=crypto.randomUUID)==null?void 0:v.call(crypto))||Math.random().toString(36),timestamp:new Date,userAgent:e.includeUserAgent&&typeof navigator<"u"?navigator.userAgent:void 0};t.push(y),t.length>=n?a():o()}function m(){r&&clearTimeout(r),a()}return{log:c,flush:a,destroy:m}}function Vt(){return[{controlId:"CC6.1",name:"Logical and Physical Access Controls",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.2",name:"User Registration and Authorization",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"CC6.3",name:"Access Control Removal",category:"security",status:"in_progress",lastAssessed:new Date},{controlId:"A1.1",name:"System Capacity",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"A1.2",name:"Backup and Recovery",category:"availability",status:"in_progress",lastAssessed:new Date},{controlId:"C1.1",name:"Confidential Information Classification",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"C1.2",name:"Confidential Information Disposal",category:"confidentiality",status:"in_progress",lastAssessed:new Date},{controlId:"P1.1",name:"Privacy Notice",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P2.1",name:"Consent",category:"privacy",status:"in_progress",lastAssessed:new Date},{controlId:"P3.1",name:"Collection",category:"privacy",status:"in_progress",lastAssessed:new Date}]}const er={hardcodedSecrets:[{pattern:/password\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded password"},{pattern:/api[_-]?key\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded API key"},{pattern:/secret\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded secret"},{pattern:/token\s*[:=]\s*["'][^"']+["']/gi,name:"Hardcoded token"}],sqlInjection:[{pattern:/execute\s*\(\s*["'`].*\$\{/gi,name:"Potential SQL injection (template literal)"},{pattern:/query\s*\(\s*["'`].*\+/gi,name:"Potential SQL injection (string concatenation)"}],xss:[{pattern:/dangerouslySetInnerHTML/g,name:"dangerouslySetInnerHTML usage"},{pattern:/innerHTML\s*=/g,name:"innerHTML assignment"},{pattern:/document\.write\s*\(/g,name:"document.write usage"},{pattern:/eval\s*\(/g,name:"eval usage"}],insecureFunctions:[{pattern:/Math\.random\s*\(\)/g,name:"Insecure random (use crypto)"},{pattern:/new Function\s*\(/g,name:"Function constructor (code injection risk)"},{pattern:/setTimeout\s*\(\s*["']/g,name:"setTimeout with string (code injection)"},{pattern:/setInterval\s*\(\s*["']/g,name:"setInterval with string (code injection)"}],infoExposure:[{pattern:/console\.(log|info|warn|error)\s*\(/g,name:"Console logging (remove in production)"},{pattern:/debugger/g,name:"Debugger statement"},{pattern:/TODO.*password/gi,name:"TODO mentioning password"}]};function tr(){return`# .github/workflows/sast.yml
7
7
  name: Security Scan (SAST)
8
8
 
9
9
  on:
package/dist/index.mjs CHANGED
@@ -1134,7 +1134,11 @@ const Ve = { sm: 200, md: 280, lg: 380 }, Mt = (e) => {
1134
1134
  U("processing"), W(T("security.face.processing", "Analysing face…"));
1135
1135
  const { imageData: w } = ae(u.current);
1136
1136
  if (t === "compare" && n) {
1137
- const A = typeof n == "string" ? await rt(n) : nt(n), { similarity: N, cameraFeatures: P, refFeatures: O } = Ke(w, A);
1137
+ const A = typeof n == "string" ? await rt(n) : nt(n), {
1138
+ similarity: N,
1139
+ cameraFeatures: P,
1140
+ refFeatures: O
1141
+ } = Ke(w, A);
1138
1142
  K(N), Y((P == null ? void 0 : P.quality) ?? 0), I(P);
1139
1143
  const Q = {
1140
1144
  success: N >= y.matchThreshold,
@@ -1325,7 +1329,7 @@ const Ve = { sm: 200, md: 280, lg: 380 }, Mt = (e) => {
1325
1329
  "img",
1326
1330
  {
1327
1331
  src: typeof n == "string" ? n : void 0,
1328
- alt: "Reference",
1332
+ alt: T("security.face.referenceAlt", "Reference"),
1329
1333
  style: { width: "100%", height: "100%", objectFit: "cover" }
1330
1334
  }
1331
1335
  ),
@@ -2224,7 +2228,15 @@ const it = 4, st = 5, ot = 3e4, Pt = (e) => {
2224
2228
  ]
2225
2229
  }
2226
2230
  ),
2227
- r && /* @__PURE__ */ c("button", { onClick: S, style: pt, title: "Export JSON", children: "📥" })
2231
+ r && /* @__PURE__ */ c(
2232
+ "button",
2233
+ {
2234
+ onClick: S,
2235
+ style: pt,
2236
+ title: a("security.audit.exportJson", "Export JSON"),
2237
+ children: "📥"
2238
+ }
2239
+ )
2228
2240
  ] })
2229
2241
  ]
2230
2242
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nice2dev/ui-security",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "Nice2Dev Security — Biometric authentication (fingerprint, iris, face), security keypads, PIN entry, pattern lock, liveness detection for React. Frontend-first with optional backend verification.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",