@nice2dev/ui-security 1.0.10 → 1.0.12
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 +3 -3
- package/dist/index.mjs +203 -203
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),h=require("react"),He={low:.7,medium:.8,high:.85,critical:.95},Ue={matchThreshold:.85,timeout:3e4,maxRetries:3,livenessDetection:!0,verifyEndpoint:"",authToken:"",showFeedback:!0,hapticFeedback:!0,locale:"en",securityLevel:"high",antiSpoofing:!0};function ie(e){const t={...Ue,...e};return e!=null&&e.matchThreshold||(t.matchThreshold=He[t.securityLevel]),t}async function ae(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(n=>n.toString(16).padStart(2,"0")).join("")}function le(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t).map(r=>r.toString(36).padStart(2,"0")).join("").slice(0,e)}function Oe(e){const t=new Uint32Array(1);return crypto.getRandomValues(t),t[0]%e}function qe(e,t){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}async function oe(e="user"){return navigator.mediaDevices.getUserMedia({video:{facingMode:e,width:{ideal:1280},height:{ideal:720}},audio:!1})}function te(e,t,r){const n=t??e.videoWidth,i=r??e.videoHeight,a=document.createElement("canvas");a.width=n,a.height=i;const o=a.getContext("2d");o.drawImage(e,0,0,n,i);const c=o.getImageData(0,0,n,i);return{canvas:a,ctx:o,imageData:c}}function re(e){const t=new Uint8Array(e.width*e.height),r=e.data;for(let n=0;n<t.length;n++){const i=n*4;t[n]=Math.round(.299*r[i]+.587*r[i+1]+.114*r[i+2])}return t}function Se(e,t,r){const n=new Uint8Array(t*r),i=[1,2,1,2,4,2,1,2,1],a=16;for(let o=1;o<r-1;o++)for(let c=1;c<t-1;c++){let m=0,x=0;for(let y=-1;y<=1;y++)for(let v=-1;v<=1;v++)m+=e[(o+y)*t+(c+v)]*i[x++];n[o*t+c]=Math.round(m/a)}return n}function Ke(e,t,r){const n=new Uint8Array(t*r);for(let i=1;i<r-1;i++)for(let a=1;a<t-1;a++){const o=-e[(i-1)*t+(a-1)]+e[(i-1)*t+(a+1)]+-2*e[i*t+(a-1)]+2*e[i*t+(a+1)]+-e[(i+1)*t+(a-1)]+e[(i+1)*t+(a+1)],c=-e[(i-1)*t+(a-1)]-2*e[(i-1)*t+a]-e[(i-1)*t+(a+1)]+e[(i+1)*t+(a-1)]+2*e[(i+1)*t+a]+e[(i+1)*t+(a+1)];n[i*t+a]=Math.min(255,Math.round(Math.sqrt(o*o+c*c)))}return n}function Ge(e){const t=new Array(256).fill(0);for(const x of e)t[x]++;const r=e.length;let n=0;for(let x=0;x<256;x++)n+=x*t[x];let i=0,a=0,o=0,c=0;for(let x=0;x<256;x++){if(a+=t[x],a===0)continue;const y=r-a;if(y===0)break;i+=x*t[x];const v=i/a,A=(n-i)/y,g=a*y*(v-A)**2;g>o&&(o=g,c=x)}const m=new Uint8Array(e.length);for(let x=0;x<e.length;x++)m[x]=e[x]>c?255:0;return{threshold:c,binary:m}}function ke(e,t=.3){var p;const r=e.width,n=e.height,i=re(e),a=Se(i,r,n),o=Ke(a,r,n),{binary:c}=Ge(o),m=[],x=[],y=[];for(let k=2;k<n-2;k++)for(let u=2;u<r-2;u++){if(c[k*r+u]===0)continue;const w=[c[(k-1)*r+u],c[(k-1)*r+(u+1)],c[k*r+(u+1)],c[(k+1)*r+(u+1)],c[(k+1)*r+u],c[(k+1)*r+(u-1)],c[k*r+(u-1)],c[(k-1)*r+(u-1)]];let l=0;for(let B=0;B<8;B++){const H=w[B]>0?1:0,G=w[(B+1)%8]>0?1:0;l+=Math.abs(H-G)}l/=2;let f=0,z=0;for(let B=-2;B<=2;B++)for(let H=-2;H<=2;H++)f+=o[(k+B)*r+(u+H)],z++;const O=f/z/255;if(O<t)continue;const J=Math.atan2(i[(k+1)*r+u]-i[(k-1)*r+u],i[k*r+(u+1)]-i[k*r+(u-1)]);l===1?m.push({x:u/r,y:k/n,angle:J,type:"ending",quality:O}):l===3&&m.push({x:u/r,y:k/n,angle:J,type:"bifurcation",quality:O})}m.sort((k,u)=>u.quality-k.quality);const v=m.slice(0,120);if(v.length>5){const k=v.reduce((w,l)=>w+l.x,0)/v.length,u=v.reduce((w,l)=>w+l.y,0)/v.length;x.push({x:k,y:u})}const A=v.length,g=v.filter(k=>k.type==="ending").length,D=v.filter(k=>k.type==="bifurcation").length/(g+1);let b="loop-right";D>1.5?b="whorl":D<.5?b="arch":((p=x[0])==null?void 0:p.x)<.45&&(b="loop-left");const T=v.length>20?v.reduce((k,u)=>k+u.quality,0)/v.length:0;return{minutiae:v,corePoints:x,deltaPoints:y,ridgeCount:A,patternType:b,quality:T}}function Ae(e,t){if(e.minutiae.length<5||t.minutiae.length<5)return 0;let r=0;const n=.05,i=.5,a=new Set;for(const c of e.minutiae){let m=1/0,x=-1;for(let y=0;y<t.minutiae.length;y++){if(a.has(y))continue;const v=t.minutiae[y];if(c.type!==v.type)continue;const A=qe(c,v),g=Math.abs(c.angle-v.angle);A<n&&g<i&&A<m&&(m=A,x=y)}x>=0&&(r++,a.add(x))}const o=Math.min(e.minutiae.length,t.minutiae.length);return o>0?r/o:0}async function je(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`fp_${Date.now()}_${le()}`,method:"fingerprint",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function Te(e){return JSON.parse(atob(e.templateData))}function Ce(e,t="left"){const r=e.width,n=e.height,i=re(e),a=Se(i,r,n);let o={cx:r/2,cy:n/2,r:Math.min(r,n)*.08,score:1/0};for(let I=Math.round(n*.3);I<Math.round(n*.7);I+=2)for(let D=Math.round(r*.3);D<Math.round(r*.7);D+=2)for(let b=Math.round(Math.min(r,n)*.04);b<Math.round(Math.min(r,n)*.15);b+=2){let T=0,p=0;for(let l=0;l<Math.PI*2;l+=.3){const f=Math.round(D+b*Math.cos(l)),z=Math.round(I+b*Math.sin(l));f>=0&&f<r&&z>=0&&z<n&&(T+=a[z*r+f],p++)}const k=p>0?T/p:255,u=a[I*r+D],w=k*.5+u*.5;w<o.score&&(o={cx:D,cy:I,r:b,score:w})}const c=o.r*3,m={cx:o.cx,cy:o.cy,r:Math.min(c,Math.min(r,n)*.4)},x=256,y=[];for(let I=0;I<x;I++){const D=I/x*Math.PI*2,b=o.r+(m.r-o.r)*.5,T=Math.round(o.cx+b*Math.cos(D)),p=Math.round(o.cy+b*Math.sin(D));if(T>=0&&T<r&&p>=0&&p<n){const k=Math.round(o.cx+b*Math.cos(D+.1)),u=Math.round(o.cy+b*Math.sin(D+.1)),w=a[p*r+T],l=k>=0&&k<r&&u>=0&&u<n?a[u*r+k]:w;y.push(w>l?1:0)}else y.push(0)}const v=y.join(""),A=Math.PI*o.r**2,g=Math.min(1,Math.max(0,A/(r*n)*100));return{irisCode:v,pupil:o,iris:m,quality:g,eye:t}}function Ie(e,t){if(!e.irisCode||!t.irisCode)return 0;const r=Math.min(e.irisCode.length,t.irisCode.length);if(r===0)return 0;let n=0,i=r;for(let o=-8;o<=8;o++){let c=0;for(let m=0;m<r;m++){const x=(m+o+r)%r;e.irisCode[m]!==t.irisCode[x]&&c++}c<i&&(i=c)}n=i;const a=n/r;return Math.max(0,1-a*2.5)}async function Re(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`iris_${Date.now()}_${le()}`,method:"iris",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function De(e){return JSON.parse(atob(e.templateData))}function ne(e){const t=e.width,r=e.height,n=e.data,i=new Uint8Array(t*r);for(let u=0;u<t*r;u++){const w=u*4,l=n[w],f=n[w+1],z=n[w+2],O=.299*l+.587*f+.114*z,J=128-.169*l-.331*f+.5*z,B=128+.5*l-.419*f-.081*z;J>=77&&J<=127&&B>=133&&B<=173&&O>80&&(i[u]=1)}let a=t,o=r,c=0,m=0,x=0;for(let u=0;u<r;u++)for(let w=0;w<t;w++)i[u*t+w]&&(x++,w<a&&(a=w),w>c&&(c=w),u<o&&(o=u),u>m&&(m=u));const y=c-a,v=m-o;if(y<t*.1||v<r*.1)return null;const A={x:a,y:o,width:y,height:v},g=[],I=re(e),D=Math.max(1,Math.floor(y/8)),b=Math.max(1,Math.floor(v/16));for(let u=0;u<16;u++)for(let w=0;w<8;w++){const l=a+w*D+Math.floor(D/2),f=o+u*b+Math.floor(b/2);l<t&&f<r?g.push(I[f*t+l]/255):g.push(0)}const T=[],p={x:a+y/2,y:o+v/2};for(let u=0;u<68;u++){const w=u/68*Math.PI*2,l=y*.4*Math.cos(w),f=v*.45*Math.sin(w);T.push({x:(p.x+l)/t,y:(p.y+f)/r})}const k=Math.min(1,x/(y*v)*2);return{embedding:g,boundingBox:A,landmarks:T,headPose:{yaw:0,pitch:0,roll:0},quality:k}}function ue(e,t){if(e.embedding.length!==t.embedding.length)return 0;let r=0,n=0,i=0;for(let o=0;o<e.embedding.length;o++)r+=e.embedding[o]*t.embedding[o],n+=e.embedding[o]**2,i+=t.embedding[o]**2;const a=Math.sqrt(n)*Math.sqrt(i);return a>0?(r/a+1)/2:0}function Me(e,t){const r=ne(e),n=ne(t);return!r||!n?{similarity:0,cameraFeatures:r,refFeatures:n}:{similarity:ue(r,n),cameraFeatures:r,refFeatures:n}}async function Pe(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`face_${Date.now()}_${le()}`,method:"face",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function Ee(e){return JSON.parse(atob(e.templateData))}function Je(){const e=["blink","smile","turn-left","turn-right","nod","raise-eyebrows"],t=e[Oe(e.length)];return{type:t,instruction:{blink:"Please blink your eyes",smile:"Please smile","turn-left":"Please turn your head left","turn-right":"Please turn your head right",nod:"Please nod your head","raise-eyebrows":"Please raise your eyebrows"}[t],completed:!1,confidence:0}}function de(e,t=.02){if(e.length<2)return{isLive:!1,confidence:0,motionScore:0};let r=0;for(let o=1;o<e.length;o++){const c=re(e[o-1]),m=re(e[o]);let x=0;for(let y=0;y<c.length;y++)x+=Math.abs(c[y]-m[y]);r+=x/(c.length*255)}const n=r/(e.length-1),i=n>t,a=Math.min(1,n/(t*3));return{isLive:i,confidence:a,motionScore:n}}function he(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:[screen.width,screen.height],timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,touchSupport:"ontouchstart"in window||navigator.maxTouchPoints>0,hardwareConcurrency:navigator.hardwareConcurrency??0}}async function se(){const e=he(),t=JSON.stringify(e);return ae(t)}function fe(){return typeof window<"u"&&!!window.PublicKeyCredential}async function Fe(){if(!fe())return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Ne(e){const t={rp:{name:e.rpName,id:e.rpId},user:{id:new TextEncoder().encode(e.userId),name:e.userName,displayName:e.userDisplayName},challenge:e.challenge,pubKeyCredParams:[{alg:-7,type:"public-key"},{alg:-257,type:"public-key"}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"preferred"},timeout:e.timeout??6e4,attestation:"none"};return await navigator.credentials.create({publicKey:t})}async function ze(e){const t={rpId:e.rpId,challenge:e.challenge,allowCredentials:e.allowCredentials,userVerification:"required",timeout:e.timeout??6e4};return await navigator.credentials.get({publicKey:t})}async function ce(e,t,r){const n={"Content-Type":"application/json"};r&&(n.Authorization=`Bearer ${r}`);const i=await fetch(e,{method:"POST",headers:n,body:JSON.stringify(t)});return i.ok?i.json():{verified:!1,message:`Server error: ${i.status}`}}const Ye=(e,t)=>t,Le=h.createContext(Ye),Ze=({t:e,children:t})=>s.jsx(Le.Provider,{value:e,children:t});function X(){return{t:h.useContext(Le)}}const Xe={sm:200,md:280,lg:380},Qe=e=>{const{mode:t,enrolledTemplates:r=[],fingerPosition:n="right-index",onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showMinutiae:A=!1,instructionText:g,cameraFacing:I="environment",...D}=e,{t:b}=X(),T=ie(D),p=Xe[x],k=h.useRef(null),u=h.useRef(null),w=h.useRef(null),[l,f]=h.useState("idle"),[z,O]=h.useState(0),[J,B]=h.useState(null),[H,G]=h.useState(0),[W,L]=h.useState(""),$=h.useCallback(P=>{f(P),o==null||o(P)},[o]),E=h.useCallback(async()=>{try{const P=await oe(I);w.current=P,k.current&&(k.current.srcObject=P,await k.current.play()),$("idle"),L(b("security.fingerprint.placeFingerPrompt","Place your finger on the scanner"))}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.cameraError","Camera access denied")),$("error")}},[I,b,$,c]),q=h.useCallback(()=>{var P;(P=w.current)==null||P.getTracks().forEach(C=>C.stop()),w.current=null},[]);h.useEffect(()=>(E(),q),[E,q]);const _=h.useCallback(async()=>{if(!(!k.current||l==="processing"||l==="success")){$("scanning"),L(b("security.fingerprint.scanning","Scanning…"));try{const{imageData:P}=te(k.current);$("processing"),L(b("security.fingerprint.processing","Processing fingerprint…"));const C=ke(P);if(B(C),O(C.quality),C.quality<.2){L(b("security.fingerprint.lowQuality","Low quality — try again")),$("idle");return}if(t==="enroll"){const F=await je(C,y??n);i==null||i(F,C),L(b("security.fingerprint.enrolled","Fingerprint enrolled successfully")),$("success")}else{let F=0;for(const d of r){const j=Te(d),N=Ae(C,j);N>F&&(F=N)}const R=F>=T.matchThreshold,S={success:R,confidence:F,method:"fingerprint",timestamp:Date.now(),duration:0,payload:btoa(JSON.stringify(C))};if(R&&T.verifyEndpoint){const d=await se(),j=await ce(T.verifyEndpoint,{method:"fingerprint",templateData:S.payload,matchScore:F,deviceFingerprint:d},T.authToken);S.success=j.verified}S.success?(L(b("security.fingerprint.verified","Fingerprint verified")),$("success")):(G(d=>d+1),H+1>=T.maxRetries?(L(b("security.fingerprint.maxAttempts","Maximum attempts reached")),$("failure")):(L(b("security.fingerprint.noMatch","No match — try again")),$("idle"))),a==null||a(S)}}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.error","Scan error — try again")),$("error")}}},[l,t,r,T,b,$,i,a,c,y,n,H]);h.useEffect(()=>{if(!A||!J||!u.current)return;const P=u.current.getContext("2d");P&&(P.clearRect(0,0,p,p),J.minutiae.forEach(C=>{P.beginPath(),P.arc(C.x*p,C.y*p,2,0,Math.PI*2),P.fillStyle=C.type==="ending"?"#10b981":"#f59e0b",P.fill(),P.beginPath(),P.moveTo(C.x*p,C.y*p),P.lineTo(C.x*p+Math.cos(C.angle)*8,C.y*p+Math.sin(C.angle)*8),P.strokeStyle=P.fillStyle,P.lineWidth=1,P.stroke()}))},[J,A,p]);const Y=l==="success"?"var(--security-success)":l==="failure"||l==="error"?"var(--security-error)":l==="scanning"||l==="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:{width:p,height:p,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${Y}`,boxShadow:l==="scanning"?`0 0 20px ${Y}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&s.jsx("canvas",{ref:u,width:p,height:p,style:{position:"absolute",inset:0,pointerEvents:"none"}}),s.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:[s.jsx("ellipse",{cx:"50",cy:"50",rx:"28",ry:"38",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"4 3"}),s.jsx("ellipse",{cx:"50",cy:"50",rx:"20",ry:"28",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"2 3"})]}),(l==="scanning"||l==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.3)"},children:s.jsx("div",{style:{width:60,height:60,borderRadius:"50%",border:"3px solid transparent",borderTopColor:Y,animation:"spin 0.8s linear infinite"}})})]}),v&&z>0&&s.jsx("div",{style:{width:p,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:s.jsx("div",{style:{width:`${z*100}%`,height:"100%",background:z>.6?"var(--security-success)":z>.3?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:g??W}),l!=="success"&&l!=="failure"&&s.jsx("button",{onClick:_,disabled:l==="scanning"||l==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"#fff",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:l==="scanning"||l==="processing"?.6:1},children:t==="enroll"?b("security.fingerprint.captureBtn","🖐️ Capture Fingerprint"):b("security.fingerprint.verifyBtn","🖐️ Verify Fingerprint")}),(l==="failure"||l==="error")&&s.jsx("button",{onClick:()=>{G(0),$("idle"),L("")},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:b("security.common.retry","Try Again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},Ve={sm:220,md:300,lg:400},et=e=>{const{mode:t,enrolledTemplates:r=[],eye:n="right",onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showSegmentation:A=!0,showGuide:g=!0,instructionText:I,...D}=e,{t:b}=X(),T=ie(D),p=Ve[x],k=h.useRef(null),u=h.useRef(null),w=h.useRef(null),l=h.useRef([]),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[B,H]=h.useState(null),[G,W]=h.useState(0),[L,$]=h.useState(""),E=h.useCallback(C=>{z(C),o==null||o(C)},[o]),q=h.useCallback(async()=>{try{const C=await oe("user");w.current=C,k.current&&(k.current.srcObject=C,await k.current.play()),E("idle"),$(b("security.iris.alignEyePrompt","Align your eye with the circle"))}catch(C){c==null||c(C instanceof Error?C:new Error(String(C))),$(b("security.iris.cameraError","Camera access denied")),E("error")}},[b,E,c]),_=h.useCallback(()=>{var C;(C=w.current)==null||C.getTracks().forEach(F=>F.stop()),w.current=null},[]);h.useEffect(()=>(q(),_),[q,_]);const Y=h.useCallback(async()=>{if(!(!k.current||f==="processing"||f==="success")){E("scanning"),$(b("security.iris.scanning","Scanning iris…"));try{const C=[];for(let S=0;S<5;S++){const{imageData:d}=te(k.current);C.push(d),await new Promise(j=>setTimeout(j,200))}if(l.current=C,T.livenessDetection&&!de(C).isLive){$(b("security.iris.notLive","Liveness check failed — please blink or move slightly")),E("idle");return}E("processing"),$(b("security.iris.processing","Processing iris pattern…"));const F=C[C.length-1],R=Ce(F,n==="both"?"left":n);if(!R){$(b("security.iris.noIrisDetected","No iris detected — adjust position")),E("idle");return}if(H(R),J(R.quality),R.quality<.1){$(b("security.iris.lowQuality","Low quality — move closer")),E("idle");return}if(A&&u.current){const S=u.current.getContext("2d");if(S){S.clearRect(0,0,p,p);const d=p/F.width,j=p/F.height;S.beginPath(),S.arc(R.pupil.cx*d,R.pupil.cy*j,R.pupil.r*d,0,Math.PI*2),S.strokeStyle="#ef4444",S.lineWidth=2,S.stroke(),S.beginPath(),S.arc(R.iris.cx*d,R.iris.cy*j,R.iris.r*d,0,Math.PI*2),S.strokeStyle="#3b82f6",S.lineWidth=2,S.stroke()}}if(t==="enroll"){const S=await Re(R,y??`${n} eye`);i==null||i(S,R),$(b("security.iris.enrolled","Iris enrolled successfully")),E("success")}else{let S=0;for(const N of r){const M=De(N),U=Ie(R,M);U>S&&(S=U)}const d=S>=T.matchThreshold,j={success:d,confidence:S,method:"iris",timestamp:Date.now(),duration:0,livenessPassed:T.livenessDetection?!0:void 0,payload:btoa(JSON.stringify(R))};if(d&&T.verifyEndpoint){const N=await se(),M=await ce(T.verifyEndpoint,{method:"iris",templateData:j.payload,matchScore:S,deviceFingerprint:N},T.authToken);j.success=M.verified}j.success?($(b("security.iris.verified","Iris verified")),E("success")):(W(N=>N+1),G+1>=T.maxRetries?($(b("security.iris.maxAttempts","Maximum attempts reached")),E("failure")):($(b("security.iris.noMatch","No match — try again")),E("idle"))),a==null||a(j)}}catch(C){c==null||c(C instanceof Error?C:new Error(String(C))),$(b("security.iris.error","Scan error")),E("error")}}},[f,t,r,T,b,E,i,a,c,y,n,G,A,p]),P=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:{width:p,height:p,position:"relative",borderRadius:"50%",overflow:"hidden",border:`3px solid ${P}`,boxShadow:f==="scanning"?`0 0 30px ${P}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&s.jsx("canvas",{ref:u,width:p,height:p,style:{position:"absolute",inset:0,pointerEvents:"none"}}),g&&f==="idle"&&s.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.4},children:[s.jsx("circle",{cx:"50",cy:"50",r:"35",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"5 3"}),s.jsx("circle",{cx:"50",cy:"50",r:"15",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"3 3"}),s.jsx("line",{x1:"50",y1:"10",x2:"50",y2:"25",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"50",y1:"75",x2:"50",y2:"90",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"10",y1:"50",x2:"25",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"75",y1:"50",x2:"90",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"})]}),(f==="scanning"||f==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.2)"},children:s.jsx("div",{style:{width:p*.7,height:3,background:P,animation:"irisLineAnim 1.5s ease-in-out infinite",position:"absolute",opacity:.7}})})]}),s.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",textTransform:"uppercase",letterSpacing:1},children:n==="both"?b("security.iris.bothEyes","Both eyes"):n==="left"?b("security.iris.leftEye","Left eye"):b("security.iris.rightEye","Right eye")}),v&&O>0&&s.jsx("div",{style:{width:p*.6,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:s.jsx("div",{style:{width:`${Math.min(100,O*300)}%`,height:"100%",background:O>.3?"var(--security-success)":O>.1?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:I??L}),f!=="success"&&f!=="failure"&&s.jsx("button",{onClick:Y,disabled:f==="scanning"||f==="processing",style:{padding:"10px 24px",fontSize:14,fontWeight:600,background:"var(--security-biometric)",color:"#fff",border:"none",borderRadius:"var(--security-radius)",cursor:"pointer",opacity:f==="scanning"||f==="processing"?.6:1},children:t==="enroll"?b("security.iris.captureBtn","👁️ Capture Iris"):b("security.iris.verifyBtn","👁️ Verify Iris")}),(f==="failure"||f==="error")&&s.jsx("button",{onClick:()=>{W(0),E("idle"),$("")},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:b("security.common.retry","Try Again")}),s.jsx("style",{children:`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),h=require("react"),He={low:.7,medium:.8,high:.85,critical:.95},Ue={matchThreshold:.85,timeout:3e4,maxRetries:3,livenessDetection:!0,verifyEndpoint:"",authToken:"",showFeedback:!0,hapticFeedback:!0,locale:"en",securityLevel:"high",antiSpoofing:!0};function ie(e){const t={...Ue,...e};return e!=null&&e.matchThreshold||(t.matchThreshold=He[t.securityLevel]),t}async function ae(e){const t=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(r)).map(n=>n.toString(16).padStart(2,"0")).join("")}function le(e=8){const t=new Uint8Array(e);return crypto.getRandomValues(t),Array.from(t).map(r=>r.toString(36).padStart(2,"0")).join("").slice(0,e)}function Oe(e){const t=new Uint32Array(1);return crypto.getRandomValues(t),t[0]%e}function qe(e,t){return Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2)}async function oe(e="user"){return navigator.mediaDevices.getUserMedia({video:{facingMode:e,width:{ideal:1280},height:{ideal:720}},audio:!1})}function te(e,t,r){const n=t??e.videoWidth,i=r??e.videoHeight,a=document.createElement("canvas");a.width=n,a.height=i;const o=a.getContext("2d");o.drawImage(e,0,0,n,i);const c=o.getImageData(0,0,n,i);return{canvas:a,ctx:o,imageData:c}}function re(e){const t=new Uint8Array(e.width*e.height),r=e.data;for(let n=0;n<t.length;n++){const i=n*4;t[n]=Math.round(.299*r[i]+.587*r[i+1]+.114*r[i+2])}return t}function Se(e,t,r){const n=new Uint8Array(t*r),i=[1,2,1,2,4,2,1,2,1],a=16;for(let o=1;o<r-1;o++)for(let c=1;c<t-1;c++){let m=0,x=0;for(let y=-1;y<=1;y++)for(let v=-1;v<=1;v++)m+=e[(o+y)*t+(c+v)]*i[x++];n[o*t+c]=Math.round(m/a)}return n}function Ke(e,t,r){const n=new Uint8Array(t*r);for(let i=1;i<r-1;i++)for(let a=1;a<t-1;a++){const o=-e[(i-1)*t+(a-1)]+e[(i-1)*t+(a+1)]+-2*e[i*t+(a-1)]+2*e[i*t+(a+1)]+-e[(i+1)*t+(a-1)]+e[(i+1)*t+(a+1)],c=-e[(i-1)*t+(a-1)]-2*e[(i-1)*t+a]-e[(i-1)*t+(a+1)]+e[(i+1)*t+(a-1)]+2*e[(i+1)*t+a]+e[(i+1)*t+(a+1)];n[i*t+a]=Math.min(255,Math.round(Math.sqrt(o*o+c*c)))}return n}function Ge(e){const t=new Array(256).fill(0);for(const x of e)t[x]++;const r=e.length;let n=0;for(let x=0;x<256;x++)n+=x*t[x];let i=0,a=0,o=0,c=0;for(let x=0;x<256;x++){if(a+=t[x],a===0)continue;const y=r-a;if(y===0)break;i+=x*t[x];const v=i/a,A=(n-i)/y,g=a*y*(v-A)**2;g>o&&(o=g,c=x)}const m=new Uint8Array(e.length);for(let x=0;x<e.length;x++)m[x]=e[x]>c?255:0;return{threshold:c,binary:m}}function ke(e,t=.3){var p;const r=e.width,n=e.height,i=re(e),a=Se(i,r,n),o=Ke(a,r,n),{binary:c}=Ge(o),m=[],x=[],y=[];for(let k=2;k<n-2;k++)for(let u=2;u<r-2;u++){if(c[k*r+u]===0)continue;const w=[c[(k-1)*r+u],c[(k-1)*r+(u+1)],c[k*r+(u+1)],c[(k+1)*r+(u+1)],c[(k+1)*r+u],c[(k+1)*r+(u-1)],c[k*r+(u-1)],c[(k-1)*r+(u-1)]];let l=0;for(let _=0;_<8;_++){const H=w[_]>0?1:0,G=w[(_+1)%8]>0?1:0;l+=Math.abs(H-G)}l/=2;let f=0,z=0;for(let _=-2;_<=2;_++)for(let H=-2;H<=2;H++)f+=o[(k+_)*r+(u+H)],z++;const O=f/z/255;if(O<t)continue;const J=Math.atan2(i[(k+1)*r+u]-i[(k-1)*r+u],i[k*r+(u+1)]-i[k*r+(u-1)]);l===1?m.push({x:u/r,y:k/n,angle:J,type:"ending",quality:O}):l===3&&m.push({x:u/r,y:k/n,angle:J,type:"bifurcation",quality:O})}m.sort((k,u)=>u.quality-k.quality);const v=m.slice(0,120);if(v.length>5){const k=v.reduce((w,l)=>w+l.x,0)/v.length,u=v.reduce((w,l)=>w+l.y,0)/v.length;x.push({x:k,y:u})}const A=v.length,g=v.filter(k=>k.type==="ending").length,D=v.filter(k=>k.type==="bifurcation").length/(g+1);let b="loop-right";D>1.5?b="whorl":D<.5?b="arch":((p=x[0])==null?void 0:p.x)<.45&&(b="loop-left");const T=v.length>20?v.reduce((k,u)=>k+u.quality,0)/v.length:0;return{minutiae:v,corePoints:x,deltaPoints:y,ridgeCount:A,patternType:b,quality:T}}function Ae(e,t){if(e.minutiae.length<5||t.minutiae.length<5)return 0;let r=0;const n=.05,i=.5,a=new Set;for(const c of e.minutiae){let m=1/0,x=-1;for(let y=0;y<t.minutiae.length;y++){if(a.has(y))continue;const v=t.minutiae[y];if(c.type!==v.type)continue;const A=qe(c,v),g=Math.abs(c.angle-v.angle);A<n&&g<i&&A<m&&(m=A,x=y)}x>=0&&(r++,a.add(x))}const o=Math.min(e.minutiae.length,t.minutiae.length);return o>0?r/o:0}async function je(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`fp_${Date.now()}_${le()}`,method:"fingerprint",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function Te(e){return JSON.parse(atob(e.templateData))}function Ce(e,t="left"){const r=e.width,n=e.height,i=re(e),a=Se(i,r,n);let o={cx:r/2,cy:n/2,r:Math.min(r,n)*.08,score:1/0};for(let I=Math.round(n*.3);I<Math.round(n*.7);I+=2)for(let D=Math.round(r*.3);D<Math.round(r*.7);D+=2)for(let b=Math.round(Math.min(r,n)*.04);b<Math.round(Math.min(r,n)*.15);b+=2){let T=0,p=0;for(let l=0;l<Math.PI*2;l+=.3){const f=Math.round(D+b*Math.cos(l)),z=Math.round(I+b*Math.sin(l));f>=0&&f<r&&z>=0&&z<n&&(T+=a[z*r+f],p++)}const k=p>0?T/p:255,u=a[I*r+D],w=k*.5+u*.5;w<o.score&&(o={cx:D,cy:I,r:b,score:w})}const c=o.r*3,m={cx:o.cx,cy:o.cy,r:Math.min(c,Math.min(r,n)*.4)},x=256,y=[];for(let I=0;I<x;I++){const D=I/x*Math.PI*2,b=o.r+(m.r-o.r)*.5,T=Math.round(o.cx+b*Math.cos(D)),p=Math.round(o.cy+b*Math.sin(D));if(T>=0&&T<r&&p>=0&&p<n){const k=Math.round(o.cx+b*Math.cos(D+.1)),u=Math.round(o.cy+b*Math.sin(D+.1)),w=a[p*r+T],l=k>=0&&k<r&&u>=0&&u<n?a[u*r+k]:w;y.push(w>l?1:0)}else y.push(0)}const v=y.join(""),A=Math.PI*o.r**2,g=Math.min(1,Math.max(0,A/(r*n)*100));return{irisCode:v,pupil:o,iris:m,quality:g,eye:t}}function Ie(e,t){if(!e.irisCode||!t.irisCode)return 0;const r=Math.min(e.irisCode.length,t.irisCode.length);if(r===0)return 0;let n=0,i=r;for(let o=-8;o<=8;o++){let c=0;for(let m=0;m<r;m++){const x=(m+o+r)%r;e.irisCode[m]!==t.irisCode[x]&&c++}c<i&&(i=c)}n=i;const a=n/r;return Math.max(0,1-a*2.5)}async function Re(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`iris_${Date.now()}_${le()}`,method:"iris",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function De(e){return JSON.parse(atob(e.templateData))}function ne(e){const t=e.width,r=e.height,n=e.data,i=new Uint8Array(t*r);for(let u=0;u<t*r;u++){const w=u*4,l=n[w],f=n[w+1],z=n[w+2],O=.299*l+.587*f+.114*z,J=128-.169*l-.331*f+.5*z,_=128+.5*l-.419*f-.081*z;J>=77&&J<=127&&_>=133&&_<=173&&O>80&&(i[u]=1)}let a=t,o=r,c=0,m=0,x=0;for(let u=0;u<r;u++)for(let w=0;w<t;w++)i[u*t+w]&&(x++,w<a&&(a=w),w>c&&(c=w),u<o&&(o=u),u>m&&(m=u));const y=c-a,v=m-o;if(y<t*.1||v<r*.1)return null;const A={x:a,y:o,width:y,height:v},g=[],I=re(e),D=Math.max(1,Math.floor(y/8)),b=Math.max(1,Math.floor(v/16));for(let u=0;u<16;u++)for(let w=0;w<8;w++){const l=a+w*D+Math.floor(D/2),f=o+u*b+Math.floor(b/2);l<t&&f<r?g.push(I[f*t+l]/255):g.push(0)}const T=[],p={x:a+y/2,y:o+v/2};for(let u=0;u<68;u++){const w=u/68*Math.PI*2,l=y*.4*Math.cos(w),f=v*.45*Math.sin(w);T.push({x:(p.x+l)/t,y:(p.y+f)/r})}const k=Math.min(1,x/(y*v)*2);return{embedding:g,boundingBox:A,landmarks:T,headPose:{yaw:0,pitch:0,roll:0},quality:k}}function ue(e,t){if(e.embedding.length!==t.embedding.length)return 0;let r=0,n=0,i=0;for(let o=0;o<e.embedding.length;o++)r+=e.embedding[o]*t.embedding[o],n+=e.embedding[o]**2,i+=t.embedding[o]**2;const a=Math.sqrt(n)*Math.sqrt(i);return a>0?(r/a+1)/2:0}function Me(e,t){const r=ne(e),n=ne(t);return!r||!n?{similarity:0,cameraFeatures:r,refFeatures:n}:{similarity:ue(r,n),cameraFeatures:r,refFeatures:n}}async function Pe(e,t){const r=JSON.stringify(e),n=await ae(r);return{id:`face_${Date.now()}_${le()}`,method:"face",templateData:btoa(r),enrolled:Date.now(),label:t,hash:n}}function Ee(e){return JSON.parse(atob(e.templateData))}function Je(){const e=["blink","smile","turn-left","turn-right","nod","raise-eyebrows"],t=e[Oe(e.length)];return{type:t,instruction:{blink:"Please blink your eyes",smile:"Please smile","turn-left":"Please turn your head left","turn-right":"Please turn your head right",nod:"Please nod your head","raise-eyebrows":"Please raise your eyebrows"}[t],completed:!1,confidence:0}}function de(e,t=.02){if(e.length<2)return{isLive:!1,confidence:0,motionScore:0};let r=0;for(let o=1;o<e.length;o++){const c=re(e[o-1]),m=re(e[o]);let x=0;for(let y=0;y<c.length;y++)x+=Math.abs(c[y]-m[y]);r+=x/(c.length*255)}const n=r/(e.length-1),i=n>t,a=Math.min(1,n/(t*3));return{isLive:i,confidence:a,motionScore:n}}function he(){return{userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language,screenResolution:[screen.width,screen.height],timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,touchSupport:"ontouchstart"in window||navigator.maxTouchPoints>0,hardwareConcurrency:navigator.hardwareConcurrency??0}}async function se(){const e=he(),t=JSON.stringify(e);return ae(t)}function fe(){return typeof window<"u"&&!!window.PublicKeyCredential}async function Fe(){if(!fe())return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}async function Ne(e){const t={rp:{name:e.rpName,id:e.rpId},user:{id:new TextEncoder().encode(e.userId),name:e.userName,displayName:e.userDisplayName},challenge:e.challenge,pubKeyCredParams:[{alg:-7,type:"public-key"},{alg:-257,type:"public-key"}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"preferred"},timeout:e.timeout??6e4,attestation:"none"};return await navigator.credentials.create({publicKey:t})}async function ze(e){const t={rpId:e.rpId,challenge:e.challenge,allowCredentials:e.allowCredentials,userVerification:"required",timeout:e.timeout??6e4};return await navigator.credentials.get({publicKey:t})}async function ce(e,t,r){const n={"Content-Type":"application/json"};r&&(n.Authorization=`Bearer ${r}`);const i=await fetch(e,{method:"POST",headers:n,body:JSON.stringify(t)});return i.ok?i.json():{verified:!1,message:`Server error: ${i.status}`}}const Ye=(e,t)=>t,Le=h.createContext(Ye),Ze=({t:e,children:t})=>s.jsx(Le.Provider,{value:e,children:t});function X(){return{t:h.useContext(Le)}}const Xe={sm:200,md:280,lg:380},Qe=e=>{const{mode:t,enrolledTemplates:r=[],fingerPosition:n="right-index",onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showMinutiae:A=!1,instructionText:g,cameraFacing:I="environment",...D}=e,{t:b}=X(),T=ie(D),p=Xe[x],k=h.useRef(null),u=h.useRef(null),w=h.useRef(null),[l,f]=h.useState("idle"),[z,O]=h.useState(0),[J,_]=h.useState(null),[H,G]=h.useState(0),[B,L]=h.useState(""),$=h.useCallback(P=>{f(P),o==null||o(P)},[o]),E=h.useCallback(async()=>{try{const P=await oe(I);w.current=P,k.current&&(k.current.srcObject=P,await k.current.play()),$("idle"),L(b("security.fingerprint.placeFingerPrompt","Place your finger on the scanner"))}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.cameraError","Camera access denied")),$("error")}},[I,b,$,c]),q=h.useCallback(()=>{var P;(P=w.current)==null||P.getTracks().forEach(C=>C.stop()),w.current=null},[]);h.useEffect(()=>(E(),q),[E,q]);const W=h.useCallback(async()=>{if(!(!k.current||l==="processing"||l==="success")){$("scanning"),L(b("security.fingerprint.scanning","Scanning…"));try{const{imageData:P}=te(k.current);$("processing"),L(b("security.fingerprint.processing","Processing fingerprint…"));const C=ke(P);if(_(C),O(C.quality),C.quality<.2){L(b("security.fingerprint.lowQuality","Low quality — try again")),$("idle");return}if(t==="enroll"){const F=await je(C,y??n);i==null||i(F,C),L(b("security.fingerprint.enrolled","Fingerprint enrolled successfully")),$("success")}else{let F=0;for(const d of r){const j=Te(d),N=Ae(C,j);N>F&&(F=N)}const R=F>=T.matchThreshold,S={success:R,confidence:F,method:"fingerprint",timestamp:Date.now(),duration:0,payload:btoa(JSON.stringify(C))};if(R&&T.verifyEndpoint){const d=await se(),j=await ce(T.verifyEndpoint,{method:"fingerprint",templateData:S.payload,matchScore:F,deviceFingerprint:d},T.authToken);S.success=j.verified}S.success?(L(b("security.fingerprint.verified","Fingerprint verified")),$("success")):(G(d=>d+1),H+1>=T.maxRetries?(L(b("security.fingerprint.maxAttempts","Maximum attempts reached")),$("failure")):(L(b("security.fingerprint.noMatch","No match — try again")),$("idle"))),a==null||a(S)}}catch(P){c==null||c(P instanceof Error?P:new Error(String(P))),L(b("security.fingerprint.error","Scan error — try again")),$("error")}}},[l,t,r,T,b,$,i,a,c,y,n,H]);h.useEffect(()=>{if(!A||!J||!u.current)return;const P=u.current.getContext("2d");P&&(P.clearRect(0,0,p,p),J.minutiae.forEach(C=>{P.beginPath(),P.arc(C.x*p,C.y*p,2,0,Math.PI*2),P.fillStyle=C.type==="ending"?"var(--nice-success, #10b981)":"var(--nice-warning, #f59e0b)",P.fill(),P.beginPath(),P.moveTo(C.x*p,C.y*p),P.lineTo(C.x*p+Math.cos(C.angle)*8,C.y*p+Math.sin(C.angle)*8),P.strokeStyle=P.fillStyle,P.lineWidth=1,P.stroke()}))},[J,A,p]);const Y=l==="success"?"var(--security-success)":l==="failure"||l==="error"?"var(--security-error)":l==="scanning"||l==="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:{width:p,height:p,position:"relative",borderRadius:"var(--security-radius-lg)",overflow:"hidden",border:`3px solid ${Y}`,boxShadow:l==="scanning"?`0 0 20px ${Y}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&s.jsx("canvas",{ref:u,width:p,height:p,style:{position:"absolute",inset:0,pointerEvents:"none"}}),s.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.3},children:[s.jsx("ellipse",{cx:"50",cy:"50",rx:"28",ry:"38",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"4 3"}),s.jsx("ellipse",{cx:"50",cy:"50",rx:"20",ry:"28",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"2 3"})]}),(l==="scanning"||l==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"var(--nice-overlay-30, rgba(0, 0, 0, 0.3))"},children:s.jsx("div",{style:{width:60,height:60,borderRadius:"50%",border:"3px solid transparent",borderTopColor:Y,animation:"spin 0.8s linear infinite"}})})]}),v&&z>0&&s.jsx("div",{style:{width:p,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:s.jsx("div",{style:{width:`${z*100}%`,height:"100%",background:z>.6?"var(--security-success)":z>.3?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:g??B}),l!=="success"&&l!=="failure"&&s.jsx("button",{onClick:W,disabled:l==="scanning"||l==="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:l==="scanning"||l==="processing"?.6:1},children:t==="enroll"?b("security.fingerprint.captureBtn","🖐️ Capture Fingerprint"):b("security.fingerprint.verifyBtn","🖐️ Verify Fingerprint")}),(l==="failure"||l==="error")&&s.jsx("button",{onClick:()=>{G(0),$("idle"),L("")},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:b("security.common.retry","Try Again")}),s.jsx("style",{children:"@keyframes spin { to { transform: rotate(360deg); } }"})]})},Ve={sm:220,md:300,lg:400},et=e=>{const{mode:t,enrolledTemplates:r=[],eye:n="right",onEnroll:i,onVerify:a,onStatusChange:o,onError:c,className:m,size:x="md",label:y,showQuality:v=!0,showSegmentation:A=!0,showGuide:g=!0,instructionText:I,...D}=e,{t:b}=X(),T=ie(D),p=Ve[x],k=h.useRef(null),u=h.useRef(null),w=h.useRef(null),l=h.useRef([]),[f,z]=h.useState("idle"),[O,J]=h.useState(0),[_,H]=h.useState(null),[G,B]=h.useState(0),[L,$]=h.useState(""),E=h.useCallback(C=>{z(C),o==null||o(C)},[o]),q=h.useCallback(async()=>{try{const C=await oe("user");w.current=C,k.current&&(k.current.srcObject=C,await k.current.play()),E("idle"),$(b("security.iris.alignEyePrompt","Align your eye with the circle"))}catch(C){c==null||c(C instanceof Error?C:new Error(String(C))),$(b("security.iris.cameraError","Camera access denied")),E("error")}},[b,E,c]),W=h.useCallback(()=>{var C;(C=w.current)==null||C.getTracks().forEach(F=>F.stop()),w.current=null},[]);h.useEffect(()=>(q(),W),[q,W]);const Y=h.useCallback(async()=>{if(!(!k.current||f==="processing"||f==="success")){E("scanning"),$(b("security.iris.scanning","Scanning iris…"));try{const C=[];for(let S=0;S<5;S++){const{imageData:d}=te(k.current);C.push(d),await new Promise(j=>setTimeout(j,200))}if(l.current=C,T.livenessDetection&&!de(C).isLive){$(b("security.iris.notLive","Liveness check failed — please blink or move slightly")),E("idle");return}E("processing"),$(b("security.iris.processing","Processing iris pattern…"));const F=C[C.length-1],R=Ce(F,n==="both"?"left":n);if(!R){$(b("security.iris.noIrisDetected","No iris detected — adjust position")),E("idle");return}if(H(R),J(R.quality),R.quality<.1){$(b("security.iris.lowQuality","Low quality — move closer")),E("idle");return}if(A&&u.current){const S=u.current.getContext("2d");if(S){S.clearRect(0,0,p,p);const d=p/F.width,j=p/F.height;S.beginPath(),S.arc(R.pupil.cx*d,R.pupil.cy*j,R.pupil.r*d,0,Math.PI*2),S.strokeStyle="var(--nice-danger, #ef4444)",S.lineWidth=2,S.stroke(),S.beginPath(),S.arc(R.iris.cx*d,R.iris.cy*j,R.iris.r*d,0,Math.PI*2),S.strokeStyle="var(--nice-primary, #3b82f6)",S.lineWidth=2,S.stroke()}}if(t==="enroll"){const S=await Re(R,y??`${n} eye`);i==null||i(S,R),$(b("security.iris.enrolled","Iris enrolled successfully")),E("success")}else{let S=0;for(const N of r){const M=De(N),U=Ie(R,M);U>S&&(S=U)}const d=S>=T.matchThreshold,j={success:d,confidence:S,method:"iris",timestamp:Date.now(),duration:0,livenessPassed:T.livenessDetection?!0:void 0,payload:btoa(JSON.stringify(R))};if(d&&T.verifyEndpoint){const N=await se(),M=await ce(T.verifyEndpoint,{method:"iris",templateData:j.payload,matchScore:S,deviceFingerprint:N},T.authToken);j.success=M.verified}j.success?($(b("security.iris.verified","Iris verified")),E("success")):(B(N=>N+1),G+1>=T.maxRetries?($(b("security.iris.maxAttempts","Maximum attempts reached")),E("failure")):($(b("security.iris.noMatch","No match — try again")),E("idle"))),a==null||a(j)}}catch(C){c==null||c(C instanceof Error?C:new Error(String(C))),$(b("security.iris.error","Scan error")),E("error")}}},[f,t,r,T,b,E,i,a,c,y,n,G,A,p]),P=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:{width:p,height:p,position:"relative",borderRadius:"50%",overflow:"hidden",border:`3px solid ${P}`,boxShadow:f==="scanning"?`0 0 30px ${P}`:"var(--security-shadow)",transition:"border-color 0.3s, box-shadow 0.3s"},children:[s.jsx("video",{ref:k,style:{width:"100%",height:"100%",objectFit:"cover"},playsInline:!0,muted:!0}),A&&s.jsx("canvas",{ref:u,width:p,height:p,style:{position:"absolute",inset:0,pointerEvents:"none"}}),g&&f==="idle"&&s.jsxs("svg",{viewBox:"0 0 100 100",style:{position:"absolute",inset:0,width:"100%",height:"100%",pointerEvents:"none",opacity:.4},children:[s.jsx("circle",{cx:"50",cy:"50",r:"35",fill:"none",stroke:"white",strokeWidth:"1",strokeDasharray:"5 3"}),s.jsx("circle",{cx:"50",cy:"50",r:"15",fill:"none",stroke:"white",strokeWidth:"0.5",strokeDasharray:"3 3"}),s.jsx("line",{x1:"50",y1:"10",x2:"50",y2:"25",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"50",y1:"75",x2:"50",y2:"90",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"10",y1:"50",x2:"25",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"}),s.jsx("line",{x1:"75",y1:"50",x2:"90",y2:"50",stroke:"white",strokeWidth:"0.5",opacity:"0.5"})]}),(f==="scanning"||f==="processing")&&s.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"var(--nice-overlay-20, rgba(0, 0, 0, 0.2))"},children:s.jsx("div",{style:{width:p*.7,height:3,background:P,animation:"irisLineAnim 1.5s ease-in-out infinite",position:"absolute",opacity:.7}})})]}),s.jsx("div",{style:{fontSize:11,color:"var(--security-text-muted)",textTransform:"uppercase",letterSpacing:1},children:n==="both"?b("security.iris.bothEyes","Both eyes"):n==="left"?b("security.iris.leftEye","Left eye"):b("security.iris.rightEye","Right eye")}),v&&O>0&&s.jsx("div",{style:{width:p*.6,height:4,background:"var(--security-bg-panel)",borderRadius:2,overflow:"hidden"},children:s.jsx("div",{style:{width:`${Math.min(100,O*300)}%`,height:"100%",background:O>.3?"var(--security-success)":O>.1?"var(--security-warning)":"var(--security-error)",transition:"width 0.3s"}})}),s.jsx("div",{style:{fontSize:13,color:"var(--security-text-secondary)",textAlign:"center",minHeight:20},children:I??L}),f!=="success"&&f!=="failure"&&s.jsx("button",{onClick:Y,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"?b("security.iris.captureBtn","👁️ Capture Iris"):b("security.iris.verifyBtn","👁️ Verify Iris")}),(f==="failure"||f==="error")&&s.jsx("button",{onClick:()=>{B(0),E("idle"),$("")},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:b("security.common.retry","Try Again")}),s.jsx("style",{children:`
|
|
2
2
|
@keyframes irisLineAnim {
|
|
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),[B,H]=h.useState(0),[G,W]=h.useState(""),[L,$]=h.useState(null),[E,q]=h.useState(0),_=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()),_("idle"),W(T("security.face.lookAtCamera","Look at the camera"))}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),W(T("security.face.cameraError","Camera access denied")),_("error")}},[T,_,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"?"#10b981":"#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")){_("scanning"),W(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){W(T("security.face.notLive","Liveness check failed — move naturally")),_("idle");return}}_("processing"),W(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?(W(T("security.face.matchFound",`Match: ${(N*100).toFixed(0)}%`)),_("success")):(H(Q=>Q+1),B+1>=p.maxRetries?(W(T("security.face.maxAttempts","Maximum attempts reached")),_("failure")):(W(T("security.face.noMatch","No match — try again")),_("idle"))),a==null||a(Z);return}const d=ne(S);if(!d){W(T("security.face.noFaceDetected","No face detected")),_("idle");return}if(J(d.quality),C(d),t==="enroll"){const j=await Pe(d,y??"face");i==null||i(j,d),W(T("security.face.enrolled","Face enrolled successfully")),_("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?(W(T("security.face.verified","Face verified")),_("success")):(H(U=>U+1),B+1>=p.maxRetries?(W(T("security.face.maxAttempts","Maximum attempts reached")),_("failure")):(W(T("security.face.noMatch","No match — try again")),_("idle"))),a==null||a(M)}}catch(S){c==null||c(S instanceof Error?S:new Error(String(S))),W(T("security.face.error","Error — try again")),_("error")}}},[f,t,r,n,p,T,_,i,a,c,y,B,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:"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:"#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),_("idle"),W("")},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),[B,H]=h.useState(0),[G,W]=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(!(B<=Date.now()))return L.current=setInterval(()=>{Date.now()>=B&&(clearInterval(L.current),E("idle"),J(0),l([]))},500),()=>clearInterval(L.current)},[B,E]);const q=B>Date.now(),_=h.useCallback(()=>{c&&navigator.vibrate&&navigator.vibrate(20)},[c]),Y=h.useCallback(async F=>{if(q||f==="success")return;if(_(),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){W(S),l([]),E("idle");return}if(G!==S){W(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,_,E,A,g,D]),P=Math.max(0,Math.ceil((B-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,B]=h.useState(0),[H,G]=h.useState(null),[W,L]=h.useState(null),$=T??t*80,E=$/t,q=h.useCallback(d=>{O(d),g==null||g(d)},[g]),_=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=_(),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},[_,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=_(),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&&W&&d.lineTo(W.x,W.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&&W&&(d.beginPath(),d.moveTo(j[u[0]].x,j[u[0]].y),d.lineTo(W.x,W.y),d.strokeStyle=c??"var(--security-biometric)",d.lineWidth=3,d.globalAlpha=.4,d.stroke(),d.globalAlpha=1)},[$,_,o,u,l,W,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;B(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([]),B(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),[B,H]=h.useState(!1),G=h.useCallback(C=>{z(C),I==null||I(C)},[I]);h.useEffect(()=>{J(fe()),Fe().then(H)},[]);const W=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=W(),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:W(),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,W,G,v,A,g,D]),$=t==="register"?B?l("security.webauthn.registerPasskey","🔑 Register Passkey"):l("security.webauthn.register","🔐 Register Security Key"):B?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"},_={primary:"none",outline:"2px solid var(--security-biometric)",ghost:"none"},Y={primary:"#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:_[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:"#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:"#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=["#ef4444","#f97316","#eab308","#22c55e","#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),B=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(B<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(_=>_.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 _=l+1;f(_),_>=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,B,r,n,l,A,g,H,i,a,c]),W={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:W,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<B?we[B]:"var(--security-border)",transition:"background 0.2s"}},L))}),s.jsx("div",{style:{fontSize:11,marginTop:4,color:we[B]},children:g(`security.passphrase.strength${B}`,Tt[B])})]}),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:W,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:"#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={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};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 Be(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 Bt(e){const t=Be(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 We(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 Wt(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=We(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 _t(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 _e(){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=_e();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:"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={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};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:
|
|
@@ -289,4 +289,4 @@ We will not pursue legal action against researchers who:
|
|
|
289
289
|
- Do not access, modify, or delete user data
|
|
290
290
|
- Do not disrupt our services
|
|
291
291
|
- Do not disclose vulnerabilities before they are fixed
|
|
292
|
-
`}exports.NiceDeviceTrust=At;exports.NiceFaceRecognition=rt;exports.NiceFingerprintScanner=Qe;exports.NiceI18nProvider=Ze;exports.NiceIrisScanner=et;exports.NiceMfaSelector=St;exports.NicePassphraseInput=Ct;exports.NicePatternLock=ft;exports.NicePinKeypad=ct;exports.NiceSecurityAuditLog=xt;exports.NiceSessionManager=kt;exports.NiceWebAuthnButton=gt;exports.SECRET_PATTERNS=sr;exports.SECURITY_PATTERNS=er;exports.authenticateWebAuthn=ze;exports.captureFrame=te;exports.checkColorContrast=Yt;exports.checkHeadingHierarchy=Xt;exports.checkLiveness=de;exports.clearNonEssentialCookies=Ot;exports.collectDeviceInfo=he;exports.compareFaceToPhoto=Me;exports.createAuditLogger=Qt;exports.createCSRFFetch=Lt;exports.createHIPAASession=Jt;exports.createRateLimiter=
|
|
292
|
+
`}exports.NiceDeviceTrust=At;exports.NiceFaceRecognition=rt;exports.NiceFingerprintScanner=Qe;exports.NiceI18nProvider=Ze;exports.NiceIrisScanner=et;exports.NiceMfaSelector=St;exports.NicePassphraseInput=Ct;exports.NicePatternLock=ft;exports.NicePinKeypad=ct;exports.NiceSecurityAuditLog=xt;exports.NiceSessionManager=kt;exports.NiceWebAuthnButton=gt;exports.SECRET_PATTERNS=sr;exports.SECURITY_PATTERNS=er;exports.authenticateWebAuthn=ze;exports.captureFrame=te;exports.checkColorContrast=Yt;exports.checkHeadingHierarchy=Xt;exports.checkLiveness=de;exports.clearNonEssentialCookies=Ot;exports.collectDeviceInfo=he;exports.compareFaceToPhoto=Me;exports.createAuditLogger=Qt;exports.createCSRFFetch=Lt;exports.createHIPAASession=Jt;exports.createRateLimiter=_e;exports.createSafeHtml=Nt;exports.detectIris=Ce;exports.escapeHtml=$e;exports.extractFaceFeatures=ne;exports.extractMinutiae=ke;exports.faceToTemplate=Pe;exports.fingerprintToTemplate=je;exports.generateCSPHeader=It;exports.generateCSRFToken=zt;exports.generateDataExport=qt;exports.generateDeviceFingerprint=se;exports.generateLivenessChallenge=Je;exports.generateNonce=Dt;exports.generatePreCommitHook=nr;exports.generateSASTConfig=tr;exports.generateSCAConfig=rr;exports.generateSecretScanningConfig=ir;exports.generateSecurityAdvisory=ar;exports.generateSecurityMd=or;exports.getCSRFTokenFromCookie=pe;exports.getCameraStream=oe;exports.getConsentPreferences=We;exports.getRecommendedCSP=Rt;exports.getSOC2Checklist=Vt;exports.hasAccessibleName=Zt;exports.hasConsent=Ut;exports.irisToTemplate=Re;exports.isPasskeyAvailable=Fe;exports.isWebAuthnAvailable=fe;exports.logPHIAccess=Gt;exports.matchFaces=ue;exports.matchFingerprints=Ae;exports.matchIris=Ie;exports.registerWebAuthn=Ne;exports.requestDataDeletion=Kt;exports.resolveConfig=ie;exports.sanitizeInput=Pt;exports.sanitizeSvg=Ft;exports.sanitizeUrl=Et;exports.saveConsentPreferences=Ht;exports.scanFileForViruses=Wt;exports.templateToFace=Ee;exports.templateToFingerprint=Te;exports.templateToIris=De;exports.useCSRFToken=$t;exports.useNiceTranslation=X;exports.useRateLimiter=_t;exports.validateFile=Be;exports.validateFiles=Bt;exports.verifyWithBackend=ce;
|