face-validator-sdk 1.3.3 → 1.3.4
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/CHANGELOG.md +8 -0
- package/dist/face-validator-sdk-core.cjs.js +1 -1
- package/dist/face-validator-sdk-core.cjs.js.map +1 -1
- package/dist/face-validator-sdk-core.esm.js +1 -1
- package/dist/face-validator-sdk-core.esm.js.map +1 -1
- package/dist/face-validator-sdk-core.umd.js +1 -1
- package/dist/face-validator-sdk-core.umd.js.map +1 -1
- package/dist/face-validator-sdk.cjs.js +1 -1
- package/dist/face-validator-sdk.cjs.js.map +1 -1
- package/dist/face-validator-sdk.esm.js +1 -1
- package/dist/face-validator-sdk.esm.js.map +1 -1
- package/dist/face-validator-sdk.umd.js +1 -1
- package/dist/face-validator-sdk.umd.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/*! For license information please see face-validator-sdk.esm.js.LICENSE.txt */
|
|
2
|
-
import*as e from"react";import{FaceLandmarker as t,FilesetResolver as n,HandLandmarker as a}from"@mediapipe/tasks-vision";var i,o={462(e,t,n){var a=n(649),i=Symbol.for("react.element"),o=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,r=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var a,o={},c=null,d=null;for(a in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,a)&&!l.hasOwnProperty(a)&&(o[a]=t[a]);if(e&&e.defaultProps)for(a in t=e.defaultProps)void 0===o[a]&&(o[a]=t[a]);return{$$typeof:i,type:e,key:c,ref:d,props:o,_owner:r.current}}t.Fragment=o,t.jsx=c,t.jsxs=c},70(e,t,n){e.exports=n(462)},649(t){t.exports=e}},s={};function r(e){var t=s[e];if(void 0!==t)return t.exports;var n=s[e]={exports:{}};return o[e](n,n.exports,r),n.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),function(e){e.INITIALIZING="INITIALIZING",e.NO_FACE_DETECTED="NO_FACE_DETECTED",e.FACE_DETECTED="FACE_DETECTED",e.TOO_CLOSE="TOO_CLOSE",e.TOO_FAR="TOO_FAR",e.OFF_CENTER="OFF_CENTER",e.FACE_OBSTRUCTED="FACE_OBSTRUCTED",e.HEAD_NOT_STRAIGHT="HEAD_NOT_STRAIGHT",e.MULTIPLE_FACES="MULTIPLE_FACES",e.POOR_ILLUMINATION="POOR_ILLUMINATION",e.NOT_NEUTRAL_EXPRESSION="NOT_NEUTRAL_EXPRESSION",e.DARK_GLASSES="DARK_GLASSES",e.STAY_STILL="STAY_STILL",e.CAPTURING="CAPTURING",e.SUCCESS="SUCCESS",e.ERROR="ERROR"}(i||(i={}));const l={"pt-BR":{[i.INITIALIZING]:"Inicializando câmera e detector...",[i.NO_FACE_DETECTED]:"Posicione seu rosto no centro do oval.",[i.FACE_DETECTED]:"Analisando...",[i.TOO_CLOSE]:"Afaste-se um pouco",[i.TOO_FAR]:"Aproxime-se da câmera",[i.OFF_CENTER]:"Centralize o rosto no centro do oval",[i.FACE_OBSTRUCTED]:"Mantenha o rosto totalmente visível. Remova as mãos do rosto.",[i.HEAD_NOT_STRAIGHT]:"Olhe diretamente para a câmera e mantenha a cabeça reta.",[i.MULTIPLE_FACES]:"Mantenha apenas uma pessoa no quadro.",[i.POOR_ILLUMINATION]:"Procure um ambiente com boa iluminação.",[i.NOT_NEUTRAL_EXPRESSION]:"Mantenha expressão neutra: boca fechada, sem sorrir e olhos abertos.",[i.DARK_GLASSES]:"Remova os óculos escuros. Óculos de grau são permitidos.",[i.STAY_STILL]:"Fique imóvel para capturar a foto",[i.CAPTURING]:"Capturando...",[i.SUCCESS]:"Captura realizada!",[i.ERROR]:"Ocorreu um erro."},en:{[i.INITIALIZING]:"Initializing camera and detector...",[i.NO_FACE_DETECTED]:"Position your face in the center of the oval.",[i.FACE_DETECTED]:"Analyzing...",[i.TOO_CLOSE]:"Move back a little",[i.TOO_FAR]:"Move closer to the camera",[i.OFF_CENTER]:"Center your face in the center of the oval",[i.FACE_OBSTRUCTED]:"Keep your face fully visible. Remove your hands from your face.",[i.HEAD_NOT_STRAIGHT]:"Look directly at the camera and keep your head straight.",[i.MULTIPLE_FACES]:"Keep only one person in the frame.",[i.POOR_ILLUMINATION]:"Find a well-lit environment and center your face in the oval.",[i.NOT_NEUTRAL_EXPRESSION]:"Keep a neutral expression: mouth closed, no smiling, and eyes open.",[i.DARK_GLASSES]:"Remove sunglasses. Prescription glasses are allowed.",[i.STAY_STILL]:"Stay still to capture the photo",[i.CAPTURING]:"Capturing...",[i.SUCCESS]:"Capture complete!",[i.ERROR]:"An error occurred."},es:{[i.INITIALIZING]:"Inicializando cámara y detector...",[i.NO_FACE_DETECTED]:"Coloque su rostro en el centro del óvalo.",[i.FACE_DETECTED]:"Analizando...",[i.TOO_CLOSE]:"Aléjese un poco",[i.TOO_FAR]:"Acérquese a la cámara",[i.OFF_CENTER]:"Centre el rostro en el centro del óvalo",[i.FACE_OBSTRUCTED]:"Mantenga el rostro totalmente visible. Quite las manos del rostro.",[i.HEAD_NOT_STRAIGHT]:"Mire directamente a la cámara y mantenga la cabeza recta.",[i.MULTIPLE_FACES]:"Mantenga solo una persona en el encuadre.",[i.POOR_ILLUMINATION]:"Busque un ambiente con buena iluminación y centre su rostro en el óvalo.",[i.NOT_NEUTRAL_EXPRESSION]:"Mantenga expresión neutra: boca cerrada, sin sonreír y ojos abiertos.",[i.DARK_GLASSES]:"Quite las gafas de sol. Las gafas graduadas están permitidas.",[i.STAY_STILL]:"Permanezca quieto para capturar la foto",[i.CAPTURING]:"Capturando...",[i.SUCCESS]:"¡Captura realizada!",[i.ERROR]:"Ocurrió un error."}},c={"pt-BR":"Status desconhecido.",en:"Unknown status.",es:"Estado desconhecido."};function d(e){return Object.assign({},l[e])}function h(e,t){var n;return null!==(n=l[t][e])&&void 0!==n?n:c[t]}function u(e){return{"pt-BR":"Carregando...",en:"Loading...",es:"Cargando..."}[e]}function m(e){const t=e.data;let n=0;for(let e=0;e<t.length;e+=4)n+=.2126*t[e]+.7152*t[e+1]+.0722*t[e+2];return n/(t.length/4)}const f=[33,133,159,145],E=[263,362,386,374],p=[61,291,0,17,39,269,270,409],g=.34;var v=function(e,t,n,a){return new(n||(n=Promise))(function(i,o){function s(e){try{l(a.next(e))}catch(e){o(e)}}function r(e){try{l(a.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,r)}l((a=a.apply(e,t||[])).next())})};const S={container:void 0,ui:"default",autoStart:!0,mirror:!0,videoConstraints:void 0,overlayCanvasElement:void 0,videoWidth:512,videoHeight:384,minDetectionConfidence:.4,minIlluminationThreshold:50,minFaceSizeFactor:.15,maxFaceSizeFactor:.75,stabilizationTimeThreshold:1e3,stabilityMovementThreshold:5,minFaceVisibilityScore:.4,maxHeadTiltDegrees:30,maxHandFaceDistance:.15,debugMode:!1,locale:"en",customMessages:{},onStatusUpdate:void 0,onCaptureSuccess:void 0,onError:void 0};class y{constructor(e){this.faceLandmarker=null,this.handLandmarker=null,this.animationFrameId=null,this.lastDetection=null,this.stableSince=null,this.isCapturing=!1,this.containerElement=null,this.statusElement=null,this.uiRootElement=null,this.cameraStream=null,this.cameraReadyPromise=null,this.managedElements=!1,this.managedCamera=!1,this.injectedStyleElement=null,this.options=this.resolveOptions(e),this.setupElements(),this.setStatus(i.INITIALIZING),this.cameraReadyPromise=this.options.autoStart?this.initCamera():Promise.resolve(),this.init()}resolveOptions(e){const t=e.modelPath||"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm";return Object.assign(Object.assign(Object.assign({},S),e),{modelPath:t,locale:e.locale||"en",customMessages:e.customMessages||{},onStatusUpdate:e.onStatusUpdate||(()=>{}),onCaptureSuccess:e.onCaptureSuccess||(()=>{}),onError:e.onError||(()=>{}),videoConstraints:e.videoConstraints||{width:{ideal:e.videoWidth||S.videoWidth},height:{ideal:e.videoHeight||S.videoHeight},facingMode:"user"}})}setupElements(){const e=this.resolveContainer(this.options.container);if(this.containerElement=e,"default"===this.options.ui&&e&&this.ensureDefaultUI(e),this.options.videoElement){if(!this.options.overlayCanvasElement&&e){const t=document.createElement("canvas");t.className="fv-sdk-canvas",this.attachMediaElements(e,this.options.videoElement,t),this.options.overlayCanvasElement=t,this.managedElements=!0}}else{if(!e)throw new Error("FaceValidator requires either videoElement or container.");const t=document.createElement("video");t.autoplay=!0,t.playsInline=!0,t.muted=!0,t.className="fv-sdk-video";const n=document.createElement("canvas");n.className="fv-sdk-canvas",this.attachMediaElements(e,t,n),this.options.videoElement=t,this.options.overlayCanvasElement=n,this.managedElements=!0}this.options.mirror&&this.applyMirrorStyles()}resolveContainer(e){return e?"string"==typeof e?document.querySelector(e):e:null}ensureDefaultUI(e){e.innerHTML="",e.classList.add("fv-sdk-root");const t=document.createElement("div");t.className="fv-sdk-media",e.appendChild(t);const n=document.createElement("div");n.className="fv-sdk-status",e.appendChild(n),this.statusElement=n,this.uiRootElement=e,this.injectDefaultStyles()}attachMediaElements(e,t,n){const a=e.querySelector(".fv-sdk-media");if(a)return a.appendChild(t),void a.appendChild(n);const i=document.createElement("div");i.className="fv-sdk-media",i.appendChild(t),i.appendChild(n),e.appendChild(i)}injectDefaultStyles(){if(this.injectedStyleElement||document.querySelector('style[data-fv-sdk="true"]'))return;const e=document.createElement("style");e.setAttribute("data-fv-sdk","true"),e.textContent="\n .fv-sdk-root { display: flex; flex-direction: column; gap: 12px; width: 100%; }\n .fv-sdk-media { position: relative; width: 100%; max-width: 512px; height: 384px; margin: 0 auto; background: #000; border-radius: 10px; overflow: hidden; }\n .fv-sdk-video, .fv-sdk-canvas { width: 100%; height: 100%; display: block; object-fit: cover; }\n .fv-sdk-canvas { position: absolute; top: 0; left: 0; }\n .fv-sdk-status { text-align: center; display: flex; align-items: center; justify-content: center; font-size: 14px; padding: 10px 12px; border-radius: 8px; font-weight: 600; background: #f8f9fa; color: #555; }\n .fv-sdk-status.success { background: #d4edda; color: #155724; }\n .fv-sdk-status.error { background: #f8d7da; color: #721c24; }\n .fv-sdk-status.warning { background: #fff3cd; color: #856404; }\n ",document.head.appendChild(e),this.injectedStyleElement=e}applyMirrorStyles(){const e=this.options.videoElement,t=this.options.overlayCanvasElement;e&&(e.style.transform="scaleX(-1)"),t&&(t.style.transform="scaleX(-1)")}init(){return v(this,void 0,void 0,function*(){try{const e=u(this.options.locale);this.setStatus(i.INITIALIZING,void 0,e);const o=yield n.forVisionTasks(this.options.modelPath);this.faceLandmarker=yield t.createFromOptions(o,{baseOptions:{modelAssetPath:"https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task",delegate:"GPU"},runningMode:"VIDEO",numFaces:2,minFaceDetectionConfidence:this.options.minDetectionConfidence,minFacePresenceConfidence:this.options.minFaceVisibilityScore,minTrackingConfidence:this.options.minFaceVisibilityScore}),this.handLandmarker=yield a.createFromOptions(o,{baseOptions:{modelAssetPath:"https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task",delegate:"GPU"},runningMode:"VIDEO",numHands:2,minHandDetectionConfidence:.5,minHandPresenceConfidence:.5,minTrackingConfidence:.5}),this.cameraReadyPromise&&(yield this.cameraReadyPromise),this.startDetectionLoop()}catch(e){const t=e instanceof Error?e:new Error(String(e));this.setStatus(i.ERROR,t)}})}getMessageForStatus(e,t){return t||(this.options.customMessages[e]?this.options.customMessages[e]:h(e,this.options.locale))}setStatus(e,t,n){const a=this.getMessageForStatus(e,n);this.updateStatusUI(e,a),this.options.onStatusUpdate(e,a),e===i.ERROR&&t&&this.options.onError(e,t)}updateStatusUI(e,t){if(!this.statusElement)return;this.statusElement.textContent=t,this.statusElement.classList.remove("success","warning","error");const n=this.getStatusClass(e);n&&this.statusElement.classList.add(n)}getStatusClass(e){return e===i.SUCCESS?"success":e===i.ERROR?"error":[i.NO_FACE_DETECTED,i.MULTIPLE_FACES,i.TOO_CLOSE,i.TOO_FAR,i.OFF_CENTER,i.HEAD_NOT_STRAIGHT,i.FACE_OBSTRUCTED,i.POOR_ILLUMINATION,i.NOT_NEUTRAL_EXPRESSION,i.DARK_GLASSES,i.STAY_STILL,i.CAPTURING].includes(e)?"warning":""}initCamera(){return v(this,void 0,void 0,function*(){const e=this.options.videoElement;if(e&&!e.srcObject)try{const t=yield navigator.mediaDevices.getUserMedia({video:this.options.videoConstraints});this.cameraStream=t,this.managedCamera=!0,e.srcObject=t,yield this.waitForVideoReady(e),yield e.play();const n=this.options.overlayCanvasElement;n&&(n.width=e.videoWidth||this.options.videoWidth||S.videoWidth,n.height=e.videoHeight||this.options.videoHeight||S.videoHeight)}catch(e){const t=e instanceof Error?e:new Error(String(e));this.setStatus(i.ERROR,t)}})}waitForVideoReady(e){return v(this,void 0,void 0,function*(){e.readyState>=2||(yield new Promise((t,n)=>{const a=()=>{e.removeEventListener("loadedmetadata",a),t()},i=t=>{e.removeEventListener("error",i),n(t)};e.addEventListener("loadedmetadata",a),e.addEventListener("error",i),setTimeout(()=>{e.removeEventListener("loadedmetadata",a),e.removeEventListener("error",i),t()},5e3)}))})}startDetectionLoop(){const e=this.getVideoElement(),t=this.options.videoWidth||640,n=this.options.videoHeight||480,a=()=>v(this,void 0,void 0,function*(){var o;if(this.faceLandmarker&&this.handLandmarker&&e.videoWidth){try{const a=performance.now();let s=i.NO_FACE_DETECTED,r=null,l=[];const c=this.faceLandmarker.detectForVideo(e,a),d=this.handLandmarker.detectForVideo(e,a);if(d.landmarks&&d.landmarks.length>0&&(l=d.landmarks.map((e,t)=>{var n,a,i;return{landmarks:e,handedness:(null===(i=null===(a=null===(n=d.handednesses)||void 0===n?void 0:n[t])||void 0===a?void 0:a[0])||void 0===i?void 0:i.categoryName)||"Unknown"}})),c.faceLandmarks&&c.faceLandmarks.length>1){s=i.MULTIPLE_FACES,this.stableSince=null;const e=c.faceLandmarks[0],t=(null===(o=c.faceBlendshapes)||void 0===o?void 0:o[0])?this.estimateBoundingBox(e):null;t&&(r={boundingBox:t,landmarks:e,timestamp:a})}else if(c.faceLandmarks&&1===c.faceLandmarks.length){const o=c.faceLandmarks[0],d=this.estimateBoundingBox(o);r={boundingBox:d,landmarks:o,timestamp:a};const h=function(e,t=.18,n=.7){const a=e.width;return a<t?"TOO_FAR":a>n?"TOO_CLOSE":"OK"}(d,this.options.minFaceSizeFactor,this.options.maxFaceSizeFactor);if("OK"!==h)s="TOO_CLOSE"===h?i.TOO_CLOSE:i.TOO_FAR,this.stableSince=null;else{const c=o[4],h=function(e,t,n,a){const i=(e*n-n/2)/(.2*n),o=(t*a-a/2)/(a*g);return i*i+o*o<=.6}(c.x,c.y,t,n),u=function(e,t,n){const a=t/2,i=n/2,o=.2*t,s=n*g,r=e.xMin*t,l=(e.xMin+e.width)*t,c=e.yMin*n,d=(e.yMin+e.height)*n,h=((r+l)/2-a)/o,u=((c+d)/2-i)/s;if(h*h+u*u>1)return!1;const m=[{x:r,y:c},{x:l,y:c},{x:r,y:d},{x:l,y:d}];let f=0;for(const e of m){const t=(e.x-a)/o,n=(e.y-i)/s;t*t+n*n>1&&f++}return 0===f}(d,t,n);if(h&&u)if(function(e,t){if(e.length<478)return!1;const n=e[4],a=p.map(t=>e[t]),i=a.reduce((e,t)=>e+t.y,0)/a.length,o=Math.min(...a.map(e=>e.y)),s=Math.max(...a.map(e=>e.y))-o,r=t.height;return!(i<n.y-.01||i-n.y<.06*r||s<.02*r)}(o,d))if(function(e,t=25){if(e.length<478)return!1;const n=e[f[0]],a=e[E[0]],i=e[4],o=e[13],s=e[14],r=e[152],l=e[10],c=Math.abs(n.y-a.y),d=Math.abs(n.x-a.x);if(d<.01)return!1;const h=c/d;if(Math.atan(h)*(180/Math.PI)>t)return!1;const u=(n.x+a.x)/2,m=i.x-u,p=Math.abs(n.x-a.x);if(p<.01)return!1;const g=Math.abs(m)/p;if(Math.atan(g)*(180/Math.PI)>t)return!1;if(!function(e){if(e.length<478)return!1;const t=e[234],n=e[454],a=e[4],i=Math.abs(t.x-a.x),o=Math.abs(n.x-a.x);return!((i>.01&&o>.01?Math.max(i,o)/Math.min(i,o):1)>1.4||void 0!==t.z&&void 0!==n.z&&Math.abs(t.z-n.z)>.05)}(e))return!1;const v=(n.y+a.y)/2,S=(o.y+s.y)/2,y=r.y-l.y;if(y<.1)return!1;if(l.y>v+.02)return!1;if(v>i.y+.02)return!1;if(i.y>S+.02)return!1;if(S>=r.y)return!1;const C=(v-l.y)/y,T=(i.y-v)/y,I=(S-i.y)/y,O=(r.y-S)/y;return!(C<.06||C>.38||T<.03||T>.3||I<.02||I>.25||O<.04||O>.38)}(o,this.options.maxHeadTiltDegrees))if(l.length>0&&function(e,t,n=.15){const a=t.xMin+t.width/2,i=t.yMin+t.height/2;for(const t of e.landmarks){const e=t.x-a,o=t.y-i;if(Math.sqrt(e*e+o*o)<n)return!0}return!1}(l[0],d,this.options.maxHandFaceDistance))s=i.FACE_OBSTRUCTED,this.stableSince=null;else if(function(e){if(e.length<478)return!1;const t=e[159],n=e[144],a=e[386],i=e[373],o=Math.abs(t.y-n.y),s=Math.abs(a.y-i.y);if(o<.01||s<.01)return!1;const r=e[13],l=e[14];if(Math.abs(r.y-l.y)>.025)return!1;const c=e[61],d=e[291],h=e[4];return!((c.y+d.y)/2-h.y<.05)}(o))if(function(e,t){if(t.length<478)return!1;try{const n=document.createElement("canvas"),a=n.getContext("2d");if(!a)return!1;const i=e.videoWidth,o=e.videoHeight,s=[t[33],t[133],t[159],t[144],t[145]],r=[t[263],t[362],t[386],t[373],t[374]],l=e=>{const t=e.map(e=>e.x*i),n=e.map(e=>e.y*o),a=Math.max(0,Math.min(...t)-5),s=Math.min(i,Math.max(...t)+5),r=Math.max(0,Math.min(...n)-5);return{x:a,y:r,width:s-a,height:Math.min(o,Math.max(...n)+5)-r}},c=t=>(n.width=t.width,n.height=t.height,a.drawImage(e,t.x,t.y,t.width,t.height,0,0,t.width,t.height),m(a.getImageData(0,0,t.width,t.height))),d=l(s),h=l(r);return(c(d)+c(h))/2<35}catch(e){return console.warn("Erro ao detectar óculos escuros:",e),!1}}(e,o))s=i.DARK_GLASSES,this.stableSince=null;else{const o=document.createElement("canvas"),l=d.xMin*e.videoWidth,c=d.yMin*e.videoHeight,h=d.width*e.videoWidth,u=d.height*e.videoHeight;o.width=h,o.height=u;const f=o.getContext("2d",{willReadFrequently:!0});if(f){f.drawImage(e,l,c,h,u,0,0,h,u);m(f.getImageData(0,0,o.width,o.height))<this.options.minIlluminationThreshold?(s=i.POOR_ILLUMINATION,this.stableSince=null):function(e,t,n=5,a=512,i=384){if(!e||!t)return!1;const o=(e.boundingBox.xMin+e.boundingBox.width/2)*a,s=(e.boundingBox.yMin+e.boundingBox.height/2)*i,r=(t.boundingBox.xMin+t.boundingBox.width/2)*a,l=(t.boundingBox.yMin+t.boundingBox.height/2)*i,c=Math.abs(o-r),d=Math.abs(s-l),h=Math.abs(e.boundingBox.width-t.boundingBox.width)*a,u=Math.abs(e.boundingBox.height-t.boundingBox.height)*i;return c<=n&&d<=n&&h<=2*n&&u<=2*n}(r,this.lastDetection,this.options.stabilityMovementThreshold,t,n)?(this.stableSince||(this.stableSince=a),s=a-this.stableSince>=this.options.stabilizationTimeThreshold?i.CAPTURING:i.STAY_STILL):(this.stableSince=null,s=i.STAY_STILL)}else s=i.FACE_DETECTED,this.stableSince=null}else s=i.NOT_NEUTRAL_EXPRESSION,this.stableSince=null;else s=i.HEAD_NOT_STRAIGHT,this.stableSince=null;else s=i.FACE_OBSTRUCTED,this.stableSince=null;else s=i.OFF_CENTER,this.stableSince=null}}else this.lastDetection=null,this.stableSince=null;if(this.lastDetection=r,this.setStatus(s),this.options.overlayCanvasElement&&function(e,t,n,a,o){const s=e.getContext("2d");if(!s)return;const r=e.width,l=e.height,c=r/2,d=l/2;s.clearRect(0,0,r,l);const h=.2*r,u=l*g;if(s.fillStyle="rgba(255, 255, 255, 0.35)",s.fillRect(0,0,r,l),s.save(),s.beginPath(),s.ellipse(c,d,h,u,0,0,2*Math.PI),s.closePath(),s.globalCompositeOperation="destination-out",s.fill(),s.restore(),s.strokeStyle="rgba(255, 255, 255, 0.9)",s.lineWidth=3,s.beginPath(),s.ellipse(c,d,h,u,0,0,2*Math.PI),s.stroke(),s.strokeStyle="rgba(255, 255, 255, 0.45)",s.lineWidth=1,s.beginPath(),s.moveTo(c-6,d),s.lineTo(c+6,d),s.moveTo(c,d-6),s.lineTo(c,d+6),s.stroke(),t&&a){const e=a.landmarks;if(e.length>=478){const t=e[10],a=e[152],o=e[234],c=e[454],d=e.map(e=>e.x),h=e.map(e=>e.y),u=Math.min(...d),m=Math.max(...d),p=Math.min(...h),g=m-u,v=Math.max(...h)-p,S=.08,y=(u-g*S)*r,C=(p-v*S)*l,T=g*(1+2*S)*r,I=v*(1+2*S)*l;let O="red";n===i.STAY_STILL||n===i.CAPTURING?O="lime":n===i.FACE_DETECTED&&(O="yellow"),s.strokeStyle=O,s.lineWidth=3,s.strokeRect(y,C,T,I);const b=e[4];e[f[0]],e[E[0]],s.fillStyle="cyan",s.beginPath(),s.arc(b.x*r,b.y*l,5,0,2*Math.PI),s.fill(),s.fillStyle="magenta",s.beginPath(),s.arc(t.x*r,t.y*l,4,0,2*Math.PI),s.fill(),s.fillStyle="lime",s.beginPath(),s.arc(a.x*r,a.y*l,4,0,2*Math.PI),s.fill(),s.fillStyle="yellow",[e[33],e[133],e[159],e[144],e[145]].forEach(e=>{s.beginPath(),s.arc(e.x*r,e.y*l,3,0,2*Math.PI),s.fill()}),s.fillStyle="yellow",[e[263],e[362],e[386],e[373],e[374]].forEach(e=>{s.beginPath(),s.arc(e.x*r,e.y*l,3,0,2*Math.PI),s.fill()}),s.fillStyle="purple",s.beginPath(),s.arc(o.x*r,o.y*l,3,0,2*Math.PI),s.fill(),s.beginPath(),s.arc(c.x*r,c.y*l,3,0,2*Math.PI),s.fill()}}t&&o&&o.length>0&&o.forEach(e=>{s.fillStyle="orange",e.landmarks.forEach(e=>{s.beginPath(),s.arc(e.x*r,e.y*l,3,0,2*Math.PI),s.fill()})})}(this.options.overlayCanvasElement,this.options.debugMode||!1,s,r||void 0,l.length>0?l:void 0),s===i.CAPTURING&&!this.isCapturing)return this.isCapturing=!0,yield this.captureImage(),this.setStatus(i.SUCCESS),void this.stop()}catch(e){const t=e instanceof Error?e:new Error(String(e));this.setStatus(i.ERROR,t)}this.animationFrameId=requestAnimationFrame(a)}else this.animationFrameId=requestAnimationFrame(a)});this.animationFrameId=requestAnimationFrame(a)}estimateBoundingBox(e){const t=e.map(e=>e.x),n=e.map(e=>e.y),a=Math.min(...t),i=Math.max(...t),o=Math.min(...n);return{xMin:a,yMin:o,width:i-a,height:Math.max(...n)-o}}captureImage(){return v(this,void 0,void 0,function*(){const e=this.getVideoElement(),t=document.createElement("canvas");t.width=e.videoWidth,t.height=e.videoHeight;const n=t.getContext("2d");n?(n.drawImage(e,0,0,t.width,t.height),t.toBlob(e=>{e?this.options.onCaptureSuccess(e):this.setStatus(i.ERROR,new Error("Failed to generate image blob"))},"image/jpeg",.95)):this.setStatus(i.ERROR,new Error("Failed to get canvas context"))})}stop(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.faceLandmarker&&this.faceLandmarker.close(),this.handLandmarker&&this.handLandmarker.close(),this.managedCamera&&this.stopCamera()}destroy(){this.stop(),this.managedElements&&this.containerElement&&(this.containerElement.innerHTML=""),this.statusElement=null,this.uiRootElement=null}stopCamera(){this.cameraStream&&(this.cameraStream.getTracks().forEach(e=>e.stop()),this.cameraStream=null)}getVideoElement(){if(!this.options.videoElement)throw new Error("Video element is not available. Provide videoElement or container.");return this.options.videoElement}}var C=r(70),T=r(649);const I=[i.SUCCESS,i.ERROR,i.CAPTURING,i.INITIALIZING],O={"pt-BR":{previewQuestion:"O que você achou?",savePhoto:"Salvar foto",tryAgain:"Tentar novamente",cancel:"Cancelar"},en:{previewQuestion:"What do you think?",savePhoto:"Save photo",tryAgain:"Try again",cancel:"Cancel"},es:{previewQuestion:"¿Qué te pareció?",savePhoto:"Guardar foto",tryAgain:"Intentar de nuevo",cancel:"Cancelar"}},b=({onCapture:e,onDismiss:t,locale:n,videoWidth:a=512,videoHeight:o=384,debugMode:s=!1,modelPath:r,styles:l,labels:c})=>{const d=(e=>{if(!e)return"pt-BR";const t=e.toLowerCase();return t.startsWith("en")?"en":t.startsWith("es")?"es":"pt-BR"})(n),u=O[d],m=Object.assign(Object.assign({},u),null!=c?c:{}),f=(0,T.useRef)(null),E=(0,T.useRef)(null),p=(0,T.useRef)(null),g=(0,T.useRef)(null),v=(0,T.useRef)(0),S=(0,T.useRef)(""),[b,R]=(0,T.useState)(i.INITIALIZING),[x,A]=(0,T.useState)(h(i.INITIALIZING,d)),[_,L]=(0,T.useState)(h(i.INITIALIZING,d)),[M,k]=(0,T.useState)(!0),[N,F]=(0,T.useState)(null),P=(0,T.useCallback)((e,t)=>{R(e),A(t)},[]);(0,T.useEffect)(()=>{if(S.current=x,x===_)return;if(I.includes(b))return g.current&&(clearTimeout(g.current),g.current=null),L(x),void(v.current=Date.now());const e=Date.now(),t=e-v.current;if(t>=1500)return L(x),void(v.current=e);if(g.current)return;const n=1500-t;g.current=setTimeout(()=>{L(S.current),v.current=Date.now(),g.current=null},n)},[x,b,_]);const w=(0,T.useCallback)(e=>{var t;R(i.SUCCESS),A(h(i.SUCCESS,d)),(t=e,new Promise((e,n)=>{const a=new FileReader;a.onloadend=()=>e(a.result),a.onerror=n,a.readAsDataURL(t)})).then(e=>{F(e),k(!1)})},[d]),D=(0,T.useCallback)(()=>{e(null!=N?N:null),null==t||t()},[e,t,N]),U=(0,T.useCallback)(()=>{F(null),R(i.INITIALIZING),A(h(i.INITIALIZING,d)),k(!0)},[d]),j=(0,T.useCallback)((e,t)=>{A(t.message),R(i.ERROR)},[]);(0,T.useEffect)(()=>{const e=f.current;if(!M)return void(p.current&&(p.current.destroy(),p.current=null));if(!e)return;let t=!1;return(n=void 0,l=void 0,c=void 0,h=function*(){var n;try{const i=E.current;if(i&&!i.width&&(i.width=a,i.height=o),p.current||t)return;const l={videoElement:e,overlayCanvasElement:null!==(n=E.current)&&void 0!==n?n:void 0,locale:d,debugMode:s,onStatusUpdate:P,onCaptureSuccess:w,onError:j,videoWidth:a,videoHeight:o,ui:"none",autoStart:!0,mirror:!0};r&&(l.modelPath=r);const c=new y(l);p.current=c}catch(e){if(t)return;A(e.message),R(i.ERROR)}},new(c||(c=Promise))(function(e,t){function a(e){try{o(h.next(e))}catch(e){t(e)}}function i(e){try{o(h.throw(e))}catch(e){t(e)}}function o(t){var n;t.done?e(t.value):(n=t.value,n instanceof c?n:new c(function(e){e(n)})).then(a,i)}o((h=h.apply(n,l||[])).next())})).catch(()=>{}),()=>{t=!0,p.current&&(p.current.destroy(),p.current=null)};var n,l,c,h},[M,d,a,o,s,r,P,w,j]);const B=!M&&Boolean(N),G=M,H=Object.assign({width:"100%",maxWidth:640,boxSizing:"border-box",backgroundColor:"#ffffff",padding:"16px",borderRadius:16},null==l?void 0:l.container),z=Object.assign({textAlign:"center",display:"flex",alignItems:"center",justifyContent:"center",fontSize:16,padding:"10px 12px",marginBottom:10,borderRadius:10,fontWeight:600,marginTop:30,height:52,boxSizing:"border-box",transition:"all 0.4s ease-in-out"},null==l?void 0:l.messageBanner),W=Object.assign(Object.assign({},z),{backgroundColor:"#fff7df",color:"#b67219"});G&&(b===i.SUCCESS?(W.backgroundColor="#e0ffdf",W.color="#26c026"):b===i.ERROR&&(W.backgroundColor="#ffdfdf",W.color="#c02626"));const q=Object.assign({width:"100%",maxWidth:512,height:384,margin:"0 auto",borderRadius:10,overflow:"hidden",position:"relative",backgroundColor:"#1a1a1a"},null==l?void 0:l.media),V={display:"block",width:"100%",padding:"8px 12px",borderRadius:4,border:"1px solid #d9d9d9",backgroundColor:"#ffffff",cursor:"pointer",fontSize:14},Z=Object.assign(Object.assign(Object.assign({},V),{backgroundColor:"#1dbe32",color:"#ffffff",borderColor:"#1dbe32"}),null==l?void 0:l.primaryButton),K=Object.assign(Object.assign({},V),null==l?void 0:l.secondaryButton);return(0,C.jsxs)("div",{style:H,children:[(0,C.jsx)("div",{style:W,children:B?m.previewQuestion:_}),(0,C.jsx)("div",{style:q,children:G?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("video",{ref:f,autoPlay:!0,playsInline:!0,muted:!0,style:{width:"100%",height:"100%",objectFit:"cover"}}),(0,C.jsx)("canvas",{ref:E,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none",transform:"scaleX(-1)"}})]}):B&&N?(0,C.jsx)("img",{src:N,alt:"Selfie preview",style:{display:"block",width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)",backgroundColor:"transparent",border:"none"}}):(0,C.jsx)("div",{"aria-hidden":!0})}),(0,C.jsx)("div",{style:{marginTop:10},children:B?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("button",{type:"button",onClick:U,style:K,children:m.tryAgain}),(0,C.jsx)("div",{style:{height:8}}),(0,C.jsx)("button",{type:"button",onClick:D,disabled:!N,style:Object.assign(Object.assign({},Z),{opacity:N?1:.6,cursor:N?"pointer":"not-allowed"}),children:m.savePhoto})]}):(0,C.jsx)("button",{type:"button",onClick:()=>{null==t||t(),e(null),k(!1)},style:K,children:m.cancel})})]})},R=y;export{y as FaceValidator,b as ReactSelfieCapture,i as ValidationStatus,R as default,u as getLoadingModelsMessage,h as getMessage,d as getValidationMessages};
|
|
2
|
+
import*as e from"react";import{FaceLandmarker as t,FilesetResolver as n,HandLandmarker as a}from"@mediapipe/tasks-vision";var i,o={462(e,t,n){var a=n(649),i=Symbol.for("react.element"),o=Symbol.for("react.fragment"),s=Object.prototype.hasOwnProperty,r=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var a,o={},c=null,d=null;for(a in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(d=t.ref),t)s.call(t,a)&&!l.hasOwnProperty(a)&&(o[a]=t[a]);if(e&&e.defaultProps)for(a in t=e.defaultProps)void 0===o[a]&&(o[a]=t[a]);return{$$typeof:i,type:e,key:c,ref:d,props:o,_owner:r.current}}t.Fragment=o,t.jsx=c,t.jsxs=c},70(e,t,n){e.exports=n(462)},649(t){t.exports=e}},s={};function r(e){var t=s[e];if(void 0!==t)return t.exports;var n=s[e]={exports:{}};return o[e](n,n.exports,r),n.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),function(e){e.INITIALIZING="INITIALIZING",e.NO_FACE_DETECTED="NO_FACE_DETECTED",e.FACE_DETECTED="FACE_DETECTED",e.TOO_CLOSE="TOO_CLOSE",e.TOO_FAR="TOO_FAR",e.OFF_CENTER="OFF_CENTER",e.FACE_OBSTRUCTED="FACE_OBSTRUCTED",e.HEAD_NOT_STRAIGHT="HEAD_NOT_STRAIGHT",e.MULTIPLE_FACES="MULTIPLE_FACES",e.POOR_ILLUMINATION="POOR_ILLUMINATION",e.NOT_NEUTRAL_EXPRESSION="NOT_NEUTRAL_EXPRESSION",e.DARK_GLASSES="DARK_GLASSES",e.STAY_STILL="STAY_STILL",e.CAPTURING="CAPTURING",e.SUCCESS="SUCCESS",e.ERROR="ERROR"}(i||(i={}));const l={"pt-BR":{[i.INITIALIZING]:"Inicializando câmera e detector...",[i.NO_FACE_DETECTED]:"Posicione seu rosto no centro do oval.",[i.FACE_DETECTED]:"Analisando...",[i.TOO_CLOSE]:"Afaste-se um pouco",[i.TOO_FAR]:"Aproxime-se da câmera",[i.OFF_CENTER]:"Centralize o rosto no centro do oval",[i.FACE_OBSTRUCTED]:"Mantenha o rosto totalmente visível. Remova as mãos do rosto.",[i.HEAD_NOT_STRAIGHT]:"Olhe diretamente para a câmera e mantenha a cabeça reta.",[i.MULTIPLE_FACES]:"Mantenha apenas uma pessoa no quadro.",[i.POOR_ILLUMINATION]:"Procure um ambiente com boa iluminação.",[i.NOT_NEUTRAL_EXPRESSION]:"Mantenha expressão neutra: boca fechada, sem sorrir e olhos abertos.",[i.DARK_GLASSES]:"Remova os óculos escuros. Óculos de grau são permitidos.",[i.STAY_STILL]:"Fique imóvel para capturar a foto",[i.CAPTURING]:"Capturando...",[i.SUCCESS]:"Captura realizada!",[i.ERROR]:"Ocorreu um erro."},en:{[i.INITIALIZING]:"Initializing camera and detector...",[i.NO_FACE_DETECTED]:"Position your face in the center of the oval.",[i.FACE_DETECTED]:"Analyzing...",[i.TOO_CLOSE]:"Move back a little",[i.TOO_FAR]:"Move closer to the camera",[i.OFF_CENTER]:"Center your face in the center of the oval",[i.FACE_OBSTRUCTED]:"Keep your face fully visible. Remove your hands from your face.",[i.HEAD_NOT_STRAIGHT]:"Look directly at the camera and keep your head straight.",[i.MULTIPLE_FACES]:"Keep only one person in the frame.",[i.POOR_ILLUMINATION]:"Find a well-lit environment and center your face in the oval.",[i.NOT_NEUTRAL_EXPRESSION]:"Keep a neutral expression: mouth closed, no smiling, and eyes open.",[i.DARK_GLASSES]:"Remove sunglasses. Prescription glasses are allowed.",[i.STAY_STILL]:"Stay still to capture the photo",[i.CAPTURING]:"Capturing...",[i.SUCCESS]:"Capture complete!",[i.ERROR]:"An error occurred."},es:{[i.INITIALIZING]:"Inicializando cámara y detector...",[i.NO_FACE_DETECTED]:"Coloque su rostro en el centro del óvalo.",[i.FACE_DETECTED]:"Analizando...",[i.TOO_CLOSE]:"Aléjese un poco",[i.TOO_FAR]:"Acérquese a la cámara",[i.OFF_CENTER]:"Centre el rostro en el centro del óvalo",[i.FACE_OBSTRUCTED]:"Mantenga el rostro totalmente visible. Quite las manos del rostro.",[i.HEAD_NOT_STRAIGHT]:"Mire directamente a la cámara y mantenga la cabeza recta.",[i.MULTIPLE_FACES]:"Mantenga solo una persona en el encuadre.",[i.POOR_ILLUMINATION]:"Busque un ambiente con buena iluminación y centre su rostro en el óvalo.",[i.NOT_NEUTRAL_EXPRESSION]:"Mantenga expresión neutra: boca cerrada, sin sonreír y ojos abiertos.",[i.DARK_GLASSES]:"Quite las gafas de sol. Las gafas graduadas están permitidas.",[i.STAY_STILL]:"Permanezca quieto para capturar la foto",[i.CAPTURING]:"Capturando...",[i.SUCCESS]:"¡Captura realizada!",[i.ERROR]:"Ocurrió un error."}},c={"pt-BR":"Status desconhecido.",en:"Unknown status.",es:"Estado desconhecido."};function d(e){return Object.assign({},l[e])}function h(e,t){var n;return null!==(n=l[t][e])&&void 0!==n?n:c[t]}function u(e){return{"pt-BR":"Carregando...",en:"Loading...",es:"Cargando..."}[e]}function m(e){const t=e.data;let n=0;for(let e=0;e<t.length;e+=4)n+=.2126*t[e]+.7152*t[e+1]+.0722*t[e+2];return n/(t.length/4)}const f=[33,133,159,145],E=[263,362,386,374],p=[61,291,0,17,39,269,270,409],g=.34;var v=function(e,t,n,a){return new(n||(n=Promise))(function(i,o){function s(e){try{l(a.next(e))}catch(e){o(e)}}function r(e){try{l(a.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,r)}l((a=a.apply(e,t||[])).next())})};const S={container:void 0,ui:"default",autoStart:!0,mirror:!0,videoConstraints:void 0,overlayCanvasElement:void 0,videoWidth:512,videoHeight:384,minDetectionConfidence:.4,minIlluminationThreshold:50,minFaceSizeFactor:.15,maxFaceSizeFactor:.75,stabilizationTimeThreshold:1e3,stabilityMovementThreshold:5,minFaceVisibilityScore:.4,maxHeadTiltDegrees:30,maxHandFaceDistance:.15,debugMode:!1,locale:"en",customMessages:{},onStatusUpdate:void 0,onCaptureSuccess:void 0,onError:void 0};class y{constructor(e){this.faceLandmarker=null,this.handLandmarker=null,this.animationFrameId=null,this.lastDetection=null,this.stableSince=null,this.isCapturing=!1,this.containerElement=null,this.statusElement=null,this.uiRootElement=null,this.cameraStream=null,this.cameraReadyPromise=null,this.managedElements=!1,this.managedCamera=!1,this.injectedStyleElement=null,this.options=this.resolveOptions(e),this.setupElements(),this.setStatus(i.INITIALIZING),this.cameraReadyPromise=this.options.autoStart?this.initCamera():Promise.resolve(),this.init()}resolveOptions(e){const t=e.modelPath||"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm";return Object.assign(Object.assign(Object.assign({},S),e),{modelPath:t,locale:e.locale||"en",customMessages:e.customMessages||{},onStatusUpdate:e.onStatusUpdate||(()=>{}),onCaptureSuccess:e.onCaptureSuccess||(()=>{}),onError:e.onError||(()=>{}),videoConstraints:e.videoConstraints||{width:{ideal:e.videoWidth||S.videoWidth},height:{ideal:e.videoHeight||S.videoHeight},facingMode:"user"}})}setupElements(){const e=this.resolveContainer(this.options.container);if(this.containerElement=e,"default"===this.options.ui&&e&&this.ensureDefaultUI(e),this.options.videoElement){if(!this.options.overlayCanvasElement&&e){const t=document.createElement("canvas");t.className="fv-sdk-canvas",this.attachMediaElements(e,this.options.videoElement,t),this.options.overlayCanvasElement=t,this.managedElements=!0}}else{if(!e)throw new Error("FaceValidator requires either videoElement or container.");const t=document.createElement("video");t.autoplay=!0,t.playsInline=!0,t.muted=!0,t.className="fv-sdk-video";const n=document.createElement("canvas");n.className="fv-sdk-canvas",this.attachMediaElements(e,t,n),this.options.videoElement=t,this.options.overlayCanvasElement=n,this.managedElements=!0}this.options.mirror&&this.applyMirrorStyles()}resolveContainer(e){return e?"string"==typeof e?document.querySelector(e):e:null}ensureDefaultUI(e){e.innerHTML="",e.classList.add("fv-sdk-root");const t=document.createElement("div");t.className="fv-sdk-media",e.appendChild(t);const n=document.createElement("div");n.className="fv-sdk-status",e.appendChild(n),this.statusElement=n,this.uiRootElement=e,this.injectDefaultStyles()}attachMediaElements(e,t,n){const a=e.querySelector(".fv-sdk-media");if(a)return a.appendChild(t),void a.appendChild(n);const i=document.createElement("div");i.className="fv-sdk-media",i.appendChild(t),i.appendChild(n),e.appendChild(i)}injectDefaultStyles(){if(this.injectedStyleElement||document.querySelector('style[data-fv-sdk="true"]'))return;const e=document.createElement("style");e.setAttribute("data-fv-sdk","true"),e.textContent="\n .fv-sdk-root { display: flex; flex-direction: column; gap: 12px; width: 100%; }\n .fv-sdk-media { position: relative; width: 100%; max-width: 512px; height: 384px; margin: 0 auto; background: #000; border-radius: 10px; overflow: hidden; }\n .fv-sdk-video, .fv-sdk-canvas { width: 100%; height: 100%; display: block; object-fit: cover; }\n .fv-sdk-canvas { position: absolute; top: 0; left: 0; }\n .fv-sdk-status { text-align: center; display: flex; align-items: center; justify-content: center; font-size: 14px; padding: 10px 12px; border-radius: 8px; font-weight: 600; background: #f8f9fa; color: #555; }\n .fv-sdk-status.success { background: #d4edda; color: #155724; }\n .fv-sdk-status.error { background: #f8d7da; color: #721c24; }\n .fv-sdk-status.warning { background: #fff3cd; color: #856404; }\n ",document.head.appendChild(e),this.injectedStyleElement=e}applyMirrorStyles(){const e=this.options.videoElement,t=this.options.overlayCanvasElement;e&&(e.style.transform="scaleX(-1)"),t&&(t.style.transform="scaleX(-1)")}init(){return v(this,void 0,void 0,function*(){try{const e=u(this.options.locale);this.setStatus(i.INITIALIZING,void 0,e);const o=yield n.forVisionTasks(this.options.modelPath);this.faceLandmarker=yield t.createFromOptions(o,{baseOptions:{modelAssetPath:"https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task",delegate:"GPU"},runningMode:"VIDEO",numFaces:2,minFaceDetectionConfidence:this.options.minDetectionConfidence,minFacePresenceConfidence:this.options.minFaceVisibilityScore,minTrackingConfidence:this.options.minFaceVisibilityScore}),this.handLandmarker=yield a.createFromOptions(o,{baseOptions:{modelAssetPath:"https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task",delegate:"GPU"},runningMode:"VIDEO",numHands:2,minHandDetectionConfidence:.5,minHandPresenceConfidence:.5,minTrackingConfidence:.5}),this.cameraReadyPromise&&(yield this.cameraReadyPromise),this.startDetectionLoop()}catch(e){const t=e instanceof Error?e:new Error(String(e));this.setStatus(i.ERROR,t)}})}getMessageForStatus(e,t){return t||(this.options.customMessages[e]?this.options.customMessages[e]:h(e,this.options.locale))}setStatus(e,t,n){const a=this.getMessageForStatus(e,n);this.updateStatusUI(e,a),this.options.onStatusUpdate(e,a),e===i.ERROR&&t&&this.options.onError(e,t)}updateStatusUI(e,t){if(!this.statusElement)return;this.statusElement.textContent=t,this.statusElement.classList.remove("success","warning","error");const n=this.getStatusClass(e);n&&this.statusElement.classList.add(n)}getStatusClass(e){return e===i.SUCCESS?"success":e===i.ERROR?"error":[i.NO_FACE_DETECTED,i.MULTIPLE_FACES,i.TOO_CLOSE,i.TOO_FAR,i.OFF_CENTER,i.HEAD_NOT_STRAIGHT,i.FACE_OBSTRUCTED,i.POOR_ILLUMINATION,i.NOT_NEUTRAL_EXPRESSION,i.DARK_GLASSES,i.STAY_STILL,i.CAPTURING].includes(e)?"warning":""}initCamera(){return v(this,void 0,void 0,function*(){const e=this.options.videoElement;if(e&&!e.srcObject)try{const t=yield navigator.mediaDevices.getUserMedia({video:this.options.videoConstraints});this.cameraStream=t,this.managedCamera=!0,e.srcObject=t,yield this.waitForVideoReady(e),yield e.play();const n=this.options.overlayCanvasElement;n&&(n.width=e.videoWidth||this.options.videoWidth||S.videoWidth,n.height=e.videoHeight||this.options.videoHeight||S.videoHeight)}catch(e){const t=e instanceof Error?e:new Error(String(e));this.setStatus(i.ERROR,t)}})}waitForVideoReady(e){return v(this,void 0,void 0,function*(){e.readyState>=2||(yield new Promise((t,n)=>{const a=()=>{e.removeEventListener("loadedmetadata",a),t()},i=t=>{e.removeEventListener("error",i),n(t)};e.addEventListener("loadedmetadata",a),e.addEventListener("error",i),setTimeout(()=>{e.removeEventListener("loadedmetadata",a),e.removeEventListener("error",i),t()},5e3)}))})}startDetectionLoop(){const e=this.getVideoElement(),t=this.options.videoWidth||640,n=this.options.videoHeight||480,a=()=>v(this,void 0,void 0,function*(){var o;if(this.faceLandmarker&&this.handLandmarker&&e.videoWidth){try{const a=performance.now();let s=i.NO_FACE_DETECTED,r=null,l=[];const c=this.faceLandmarker.detectForVideo(e,a),d=this.handLandmarker.detectForVideo(e,a);if(d.landmarks&&d.landmarks.length>0&&(l=d.landmarks.map((e,t)=>{var n,a,i;return{landmarks:e,handedness:(null===(i=null===(a=null===(n=d.handednesses)||void 0===n?void 0:n[t])||void 0===a?void 0:a[0])||void 0===i?void 0:i.categoryName)||"Unknown"}})),c.faceLandmarks&&c.faceLandmarks.length>1){s=i.MULTIPLE_FACES,this.stableSince=null;const e=c.faceLandmarks[0],t=(null===(o=c.faceBlendshapes)||void 0===o?void 0:o[0])?this.estimateBoundingBox(e):null;t&&(r={boundingBox:t,landmarks:e,timestamp:a})}else if(c.faceLandmarks&&1===c.faceLandmarks.length){const o=c.faceLandmarks[0],d=this.estimateBoundingBox(o);r={boundingBox:d,landmarks:o,timestamp:a};const h=function(e,t=.18,n=.7){const a=e.width;return a<t?"TOO_FAR":a>n?"TOO_CLOSE":"OK"}(d,this.options.minFaceSizeFactor,this.options.maxFaceSizeFactor);if("OK"!==h)s="TOO_CLOSE"===h?i.TOO_CLOSE:i.TOO_FAR,this.stableSince=null;else{const c=o[4],h=function(e,t,n,a){const i=(e*n-n/2)/(.2*n),o=(t*a-a/2)/(a*g);return i*i+o*o<=.6}(c.x,c.y,t,n),u=function(e,t,n){const a=t/2,i=n/2,o=.2*t,s=n*g,r=e.xMin*t,l=(e.xMin+e.width)*t,c=e.yMin*n,d=(e.yMin+e.height)*n,h=((r+l)/2-a)/o,u=((c+d)/2-i)/s;if(h*h+u*u>1)return!1;const m=[{x:r,y:c},{x:l,y:c},{x:r,y:d},{x:l,y:d}];let f=0;for(const e of m){const t=(e.x-a)/o,n=(e.y-i)/s;t*t+n*n>1&&f++}return 0===f}(d,t,n);if(h&&u)if(function(e,t){if(e.length<478)return!1;const n=e[4],a=p.map(t=>e[t]),i=a.reduce((e,t)=>e+t.y,0)/a.length,o=Math.min(...a.map(e=>e.y)),s=Math.max(...a.map(e=>e.y))-o,r=t.height;return!(i<n.y-.01||i-n.y<.06*r||s<.02*r)}(o,d))if(function(e,t=25){if(e.length<478)return!1;const n=e[f[0]],a=e[E[0]],i=e[4],o=e[13],s=e[14],r=e[152],l=e[10],c=Math.abs(n.y-a.y),d=Math.abs(n.x-a.x);if(d<.01)return!1;const h=c/d;if(Math.atan(h)*(180/Math.PI)>t)return!1;const u=(n.x+a.x)/2,m=i.x-u,p=Math.abs(n.x-a.x);if(p<.01)return!1;const g=Math.abs(m)/p;if(Math.atan(g)*(180/Math.PI)>t)return!1;if(!function(e){if(e.length<478)return!1;const t=e[234],n=e[454],a=e[4],i=Math.abs(t.x-a.x),o=Math.abs(n.x-a.x);return!((i>.01&&o>.01?Math.max(i,o)/Math.min(i,o):1)>1.4||void 0!==t.z&&void 0!==n.z&&Math.abs(t.z-n.z)>.05)}(e))return!1;const v=(n.y+a.y)/2,S=(o.y+s.y)/2,y=r.y-l.y;if(y<.1)return!1;if(l.y>v+.02)return!1;if(v>i.y+.02)return!1;if(i.y>S+.02)return!1;if(S>=r.y)return!1;const C=(v-l.y)/y,T=(i.y-v)/y,O=(S-i.y)/y,b=(r.y-S)/y;return!(C<.06||C>.38||T<.03||T>.3||O<.02||O>.25||b<.04||b>.38)}(o,this.options.maxHeadTiltDegrees))if(l.length>0&&function(e,t,n=.15){const a=t.xMin+t.width/2,i=t.yMin+t.height/2;for(const t of e.landmarks){const e=t.x-a,o=t.y-i;if(Math.sqrt(e*e+o*o)<n)return!0}return!1}(l[0],d,this.options.maxHandFaceDistance))s=i.FACE_OBSTRUCTED,this.stableSince=null;else if(function(e){if(e.length<478)return!1;const t=e[159],n=e[144],a=e[386],i=e[373],o=Math.abs(t.y-n.y),s=Math.abs(a.y-i.y);if(o<.01||s<.01)return!1;const r=e[13],l=e[14];if(Math.abs(r.y-l.y)>.025)return!1;const c=e[61],d=e[291],h=e[4];return!((c.y+d.y)/2-h.y<.05)}(o))if(function(e,t){if(t.length<478)return!1;try{const n=document.createElement("canvas"),a=n.getContext("2d");if(!a)return!1;const i=e.videoWidth,o=e.videoHeight,s=[t[33],t[133],t[159],t[144],t[145]],r=[t[263],t[362],t[386],t[373],t[374]],l=e=>{const t=e.map(e=>e.x*i),n=e.map(e=>e.y*o),a=Math.max(0,Math.min(...t)-5),s=Math.min(i,Math.max(...t)+5),r=Math.max(0,Math.min(...n)-5);return{x:a,y:r,width:s-a,height:Math.min(o,Math.max(...n)+5)-r}},c=t=>(n.width=t.width,n.height=t.height,a.drawImage(e,t.x,t.y,t.width,t.height,0,0,t.width,t.height),m(a.getImageData(0,0,t.width,t.height))),d=l(s),h=l(r);return(c(d)+c(h))/2<35}catch(e){return console.warn("Erro ao detectar óculos escuros:",e),!1}}(e,o))s=i.DARK_GLASSES,this.stableSince=null;else{const o=document.createElement("canvas"),l=d.xMin*e.videoWidth,c=d.yMin*e.videoHeight,h=d.width*e.videoWidth,u=d.height*e.videoHeight;o.width=h,o.height=u;const f=o.getContext("2d",{willReadFrequently:!0});if(f){f.drawImage(e,l,c,h,u,0,0,h,u);m(f.getImageData(0,0,o.width,o.height))<this.options.minIlluminationThreshold?(s=i.POOR_ILLUMINATION,this.stableSince=null):function(e,t,n=5,a=512,i=384){if(!e||!t)return!1;const o=(e.boundingBox.xMin+e.boundingBox.width/2)*a,s=(e.boundingBox.yMin+e.boundingBox.height/2)*i,r=(t.boundingBox.xMin+t.boundingBox.width/2)*a,l=(t.boundingBox.yMin+t.boundingBox.height/2)*i,c=Math.abs(o-r),d=Math.abs(s-l),h=Math.abs(e.boundingBox.width-t.boundingBox.width)*a,u=Math.abs(e.boundingBox.height-t.boundingBox.height)*i;return c<=n&&d<=n&&h<=2*n&&u<=2*n}(r,this.lastDetection,this.options.stabilityMovementThreshold,t,n)?(this.stableSince||(this.stableSince=a),s=a-this.stableSince>=this.options.stabilizationTimeThreshold?i.CAPTURING:i.STAY_STILL):(this.stableSince=null,s=i.STAY_STILL)}else s=i.FACE_DETECTED,this.stableSince=null}else s=i.NOT_NEUTRAL_EXPRESSION,this.stableSince=null;else s=i.HEAD_NOT_STRAIGHT,this.stableSince=null;else s=i.FACE_OBSTRUCTED,this.stableSince=null;else s=i.OFF_CENTER,this.stableSince=null}}else this.lastDetection=null,this.stableSince=null;if(this.lastDetection=r,this.setStatus(s),this.options.overlayCanvasElement&&function(e,t,n,a,o){const s=e.getContext("2d");if(!s)return;const r=e.width,l=e.height,c=r/2,d=l/2;s.clearRect(0,0,r,l);const h=.2*r,u=l*g;if(s.fillStyle="rgba(255, 255, 255, 0.35)",s.fillRect(0,0,r,l),s.save(),s.beginPath(),s.ellipse(c,d,h,u,0,0,2*Math.PI),s.closePath(),s.globalCompositeOperation="destination-out",s.fill(),s.restore(),s.strokeStyle="rgba(255, 255, 255, 0.9)",s.lineWidth=3,s.beginPath(),s.ellipse(c,d,h,u,0,0,2*Math.PI),s.stroke(),s.strokeStyle="rgba(255, 255, 255, 0.45)",s.lineWidth=1,s.beginPath(),s.moveTo(c-6,d),s.lineTo(c+6,d),s.moveTo(c,d-6),s.lineTo(c,d+6),s.stroke(),t&&a){const e=a.landmarks;if(e.length>=478){const t=e[10],a=e[152],o=e[234],c=e[454],d=e.map(e=>e.x),h=e.map(e=>e.y),u=Math.min(...d),m=Math.max(...d),p=Math.min(...h),g=m-u,v=Math.max(...h)-p,S=.08,y=(u-g*S)*r,C=(p-v*S)*l,T=g*(1+2*S)*r,O=v*(1+2*S)*l;let b="red";n===i.STAY_STILL||n===i.CAPTURING?b="lime":n===i.FACE_DETECTED&&(b="yellow"),s.strokeStyle=b,s.lineWidth=3,s.strokeRect(y,C,T,O);const I=e[4];e[f[0]],e[E[0]],s.fillStyle="cyan",s.beginPath(),s.arc(I.x*r,I.y*l,5,0,2*Math.PI),s.fill(),s.fillStyle="magenta",s.beginPath(),s.arc(t.x*r,t.y*l,4,0,2*Math.PI),s.fill(),s.fillStyle="lime",s.beginPath(),s.arc(a.x*r,a.y*l,4,0,2*Math.PI),s.fill(),s.fillStyle="yellow",[e[33],e[133],e[159],e[144],e[145]].forEach(e=>{s.beginPath(),s.arc(e.x*r,e.y*l,3,0,2*Math.PI),s.fill()}),s.fillStyle="yellow",[e[263],e[362],e[386],e[373],e[374]].forEach(e=>{s.beginPath(),s.arc(e.x*r,e.y*l,3,0,2*Math.PI),s.fill()}),s.fillStyle="purple",s.beginPath(),s.arc(o.x*r,o.y*l,3,0,2*Math.PI),s.fill(),s.beginPath(),s.arc(c.x*r,c.y*l,3,0,2*Math.PI),s.fill()}}t&&o&&o.length>0&&o.forEach(e=>{s.fillStyle="orange",e.landmarks.forEach(e=>{s.beginPath(),s.arc(e.x*r,e.y*l,3,0,2*Math.PI),s.fill()})})}(this.options.overlayCanvasElement,this.options.debugMode||!1,s,r||void 0,l.length>0?l:void 0),s===i.CAPTURING&&!this.isCapturing)return this.isCapturing=!0,yield this.captureImage(),this.setStatus(i.SUCCESS),void this.stop()}catch(e){const t=e instanceof Error?e:new Error(String(e));this.setStatus(i.ERROR,t)}this.animationFrameId=requestAnimationFrame(a)}else this.animationFrameId=requestAnimationFrame(a)});this.animationFrameId=requestAnimationFrame(a)}estimateBoundingBox(e){const t=e.map(e=>e.x),n=e.map(e=>e.y),a=Math.min(...t),i=Math.max(...t),o=Math.min(...n);return{xMin:a,yMin:o,width:i-a,height:Math.max(...n)-o}}captureImage(){return v(this,void 0,void 0,function*(){const e=this.getVideoElement(),t=document.createElement("canvas");t.width=e.videoWidth,t.height=e.videoHeight;const n=t.getContext("2d");if(!n)return void this.setStatus(i.ERROR,new Error("Failed to get canvas context"));n.drawImage(e,0,0,t.width,t.height);const a=yield new Promise(e=>{t.toBlob(e,"image/jpeg",.95)});a?this.options.onCaptureSuccess(a):this.setStatus(i.ERROR,new Error("Failed to generate image blob"))})}stop(){null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.faceLandmarker&&this.faceLandmarker.close(),this.handLandmarker&&this.handLandmarker.close(),this.managedCamera&&this.stopCamera()}destroy(){this.stop(),this.managedElements&&this.containerElement&&(this.containerElement.innerHTML=""),this.statusElement=null,this.uiRootElement=null}stopCamera(){this.cameraStream&&(this.cameraStream.getTracks().forEach(e=>e.stop()),this.cameraStream=null);const e=this.options.videoElement;e&&e.srcObject&&(e.srcObject=null)}getVideoElement(){if(!this.options.videoElement)throw new Error("Video element is not available. Provide videoElement or container.");return this.options.videoElement}}var C=r(70),T=r(649);const O=[i.SUCCESS,i.ERROR,i.CAPTURING,i.INITIALIZING],b={"pt-BR":{previewQuestion:"O que você achou?",savePhoto:"Salvar foto",tryAgain:"Tentar novamente",cancel:"Cancelar"},en:{previewQuestion:"What do you think?",savePhoto:"Save photo",tryAgain:"Try again",cancel:"Cancel"},es:{previewQuestion:"¿Qué te pareció?",savePhoto:"Guardar foto",tryAgain:"Intentar de nuevo",cancel:"Cancelar"}},I=({onCapture:e,onDismiss:t,locale:n,videoWidth:a=512,videoHeight:o=384,debugMode:s=!1,modelPath:r,styles:l,labels:c})=>{const d=(e=>{if(!e)return"pt-BR";const t=e.toLowerCase();return t.startsWith("en")?"en":t.startsWith("es")?"es":"pt-BR"})(n),u=b[d],m=Object.assign(Object.assign({},u),null!=c?c:{}),f=(0,T.useRef)(null),E=(0,T.useRef)(null),p=(0,T.useRef)(null),g=(0,T.useRef)(null),v=(0,T.useRef)(0),S=(0,T.useRef)(""),[I,R]=(0,T.useState)(i.INITIALIZING),[x,A]=(0,T.useState)(h(i.INITIALIZING,d)),[_,L]=(0,T.useState)(h(i.INITIALIZING,d)),[M,k]=(0,T.useState)(!0),[N,F]=(0,T.useState)(null),P=(0,T.useCallback)((e,t)=>{R(e),A(t)},[]);(0,T.useEffect)(()=>{if(S.current=x,x===_)return;if(O.includes(I))return g.current&&(clearTimeout(g.current),g.current=null),L(x),void(v.current=Date.now());const e=Date.now(),t=e-v.current;if(t>=1500)return L(x),void(v.current=e);if(g.current)return;const n=1500-t;g.current=setTimeout(()=>{L(S.current),v.current=Date.now(),g.current=null},n)},[x,I,_]);const w=(0,T.useCallback)(e=>{var t;R(i.SUCCESS),A(h(i.SUCCESS,d)),(t=e,new Promise((e,n)=>{const a=new FileReader;a.onloadend=()=>e(a.result),a.onerror=n,a.readAsDataURL(t)})).then(e=>{F(e),k(!1)})},[d]),D=(0,T.useCallback)(()=>{e(null!=N?N:null),null==t||t()},[e,t,N]),U=(0,T.useCallback)(()=>{F(null),R(i.INITIALIZING),A(h(i.INITIALIZING,d)),k(!0)},[d]),j=(0,T.useCallback)((e,t)=>{A(t.message),R(i.ERROR)},[]);(0,T.useEffect)(()=>{const e=f.current;if(!M){p.current&&(p.current.destroy(),p.current=null);const e=f.current;return void(e&&e.srcObject&&(e.srcObject.getTracks().forEach(e=>e.stop()),e.srcObject=null))}if(!e)return;let t=!1;return(n=void 0,l=void 0,c=void 0,h=function*(){var n;try{const i=E.current;if(i&&!i.width&&(i.width=a,i.height=o),p.current||t)return;const l={videoElement:e,overlayCanvasElement:null!==(n=E.current)&&void 0!==n?n:void 0,locale:d,debugMode:s,onStatusUpdate:P,onCaptureSuccess:w,onError:j,videoWidth:a,videoHeight:o,ui:"none",autoStart:!0,mirror:!0};r&&(l.modelPath=r);const c=new y(l);p.current=c}catch(e){if(t)return;A(e.message),R(i.ERROR)}},new(c||(c=Promise))(function(e,t){function a(e){try{o(h.next(e))}catch(e){t(e)}}function i(e){try{o(h.throw(e))}catch(e){t(e)}}function o(t){var n;t.done?e(t.value):(n=t.value,n instanceof c?n:new c(function(e){e(n)})).then(a,i)}o((h=h.apply(n,l||[])).next())})).catch(()=>{}),()=>{t=!0,p.current&&(p.current.destroy(),p.current=null);const e=f.current;e&&e.srcObject&&(e.srcObject.getTracks().forEach(e=>e.stop()),e.srcObject=null)};var n,l,c,h},[M,d,a,o,s,r,P,w,j]);const B=!M&&Boolean(N),G=M,H=Object.assign({width:"100%",maxWidth:640,boxSizing:"border-box",backgroundColor:"#ffffff",padding:"16px",borderRadius:16},null==l?void 0:l.container),z=Object.assign({textAlign:"center",display:"flex",alignItems:"center",justifyContent:"center",fontSize:16,padding:"10px 12px",marginBottom:10,borderRadius:10,fontWeight:600,marginTop:30,height:52,boxSizing:"border-box",transition:"all 0.4s ease-in-out"},null==l?void 0:l.messageBanner),W=Object.assign(Object.assign({},z),{backgroundColor:"#fff7df",color:"#b67219"});G&&(I===i.SUCCESS?(W.backgroundColor="#e0ffdf",W.color="#26c026"):I===i.ERROR&&(W.backgroundColor="#ffdfdf",W.color="#c02626"));const q=Object.assign({width:"100%",maxWidth:512,height:384,margin:"0 auto",borderRadius:10,overflow:"hidden",position:"relative",backgroundColor:"#1a1a1a"},null==l?void 0:l.media),V={display:"block",width:"100%",padding:"8px 12px",borderRadius:4,border:"1px solid #d9d9d9",backgroundColor:"#ffffff",cursor:"pointer",fontSize:14},Z=Object.assign(Object.assign(Object.assign({},V),{backgroundColor:"#1dbe32",color:"#ffffff",borderColor:"#1dbe32"}),null==l?void 0:l.primaryButton),K=Object.assign(Object.assign({},V),null==l?void 0:l.secondaryButton);return(0,C.jsxs)("div",{style:H,children:[(0,C.jsx)("div",{style:W,children:B?m.previewQuestion:_}),(0,C.jsx)("div",{style:q,children:G?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("video",{ref:f,autoPlay:!0,playsInline:!0,muted:!0,style:{width:"100%",height:"100%",objectFit:"cover"}}),(0,C.jsx)("canvas",{ref:E,style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none",transform:"scaleX(-1)"}})]}):B&&N?(0,C.jsx)("img",{src:N,alt:"Selfie preview",style:{display:"block",width:"100%",height:"100%",objectFit:"cover",transform:"scaleX(-1)",backgroundColor:"transparent",border:"none"}}):(0,C.jsx)("div",{"aria-hidden":!0})}),(0,C.jsx)("div",{style:{marginTop:10},children:B?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("button",{type:"button",onClick:U,style:K,children:m.tryAgain}),(0,C.jsx)("div",{style:{height:8}}),(0,C.jsx)("button",{type:"button",onClick:D,disabled:!N,style:Object.assign(Object.assign({},Z),{opacity:N?1:.6,cursor:N?"pointer":"not-allowed"}),children:m.savePhoto})]}):(0,C.jsx)("button",{type:"button",onClick:()=>{null==t||t(),e(null),k(!1)},style:K,children:m.cancel})})]})},R=y;export{y as FaceValidator,I as ReactSelfieCapture,i as ValidationStatus,R as default,u as getLoadingModelsMessage,h as getMessage,d as getValidationMessages};
|
|
3
3
|
//# sourceMappingURL=face-validator-sdk.esm.js.map
|