@swan-admin/swan-web-component 1.0.121 → 1.0.122

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.
Files changed (169) hide show
  1. package/dist/BodyScan-B5BvnBHj.js +3 -0
  2. package/dist/BodyScan-B5BvnBHj.js.map +1 -0
  3. package/dist/BodyScan-CL9reolN.mjs +3 -0
  4. package/dist/BodyScan-CL9reolN.mjs.map +1 -0
  5. package/dist/FaceScan-BdcqQIJ5.mjs +3 -0
  6. package/dist/FaceScan-BdcqQIJ5.mjs.map +1 -0
  7. package/dist/{FaceScan-BRdpV_Yn.js → FaceScan-lUHosRqk.js} +3 -2
  8. package/dist/{FaceScan-BRdpV_Yn.js.map → FaceScan-lUHosRqk.js.map} +1 -1
  9. package/dist/{Modal-HTYYx7sM.js → Modal-DxgejzjH.js} +3 -2
  10. package/dist/{Modal-YZScjwEm.js.map → Modal-DxgejzjH.js.map} +1 -1
  11. package/dist/{Modal-BPtRtRVC.js → Modal-TzaSySDr.mjs} +3 -2
  12. package/dist/Modal-TzaSySDr.mjs.map +1 -0
  13. package/dist/bodyScan.d.ts +2 -2
  14. package/dist/bodyScan.js +2 -1
  15. package/dist/bodyScan.mjs +2 -1
  16. package/dist/faceScan.js +2 -1
  17. package/dist/faceScan.mjs +2 -1
  18. package/dist/index.css +1 -1
  19. package/dist/index.js +2 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +2 -1
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/{pose-detection.esm-Bc8T4UAD.js → pose-detection.esm-BV7VgekA.js} +2 -1
  24. package/dist/{pose-detection.esm-Bc8T4UAD.js.map → pose-detection.esm-BV7VgekA.js.map} +1 -1
  25. package/dist/{pose-detection.esm-DC0_P6R7.js → pose-detection.esm-D8r1CbkV.mjs} +2 -1
  26. package/dist/pose-detection.esm-D8r1CbkV.mjs.map +1 -0
  27. package/package.json +3 -2
  28. package/dist/BodyScan-3YoMZG7n.js +0 -2
  29. package/dist/BodyScan-8qgqyl5-.js +0 -2
  30. package/dist/BodyScan-B0qqqK3C.js +0 -2
  31. package/dist/BodyScan-B1VBoA6S.js +0 -2
  32. package/dist/BodyScan-B1afPG1Q.js +0 -2
  33. package/dist/BodyScan-B1afPG1Q.js.map +0 -1
  34. package/dist/BodyScan-B4-sO3R2.js +0 -2
  35. package/dist/BodyScan-B87W6dpH.js +0 -2
  36. package/dist/BodyScan-B8pglBAp.js +0 -2
  37. package/dist/BodyScan-BEFwluXG.js +0 -2
  38. package/dist/BodyScan-BHgnqB6A.js +0 -2
  39. package/dist/BodyScan-BLvWlYnA.js +0 -2
  40. package/dist/BodyScan-BMAkl5Iw.js +0 -2
  41. package/dist/BodyScan-BMTK6e-E.js +0 -2
  42. package/dist/BodyScan-BQri8pAO.js +0 -2
  43. package/dist/BodyScan-BVNPC7bJ.js +0 -2
  44. package/dist/BodyScan-BfLKF5PU.js +0 -2
  45. package/dist/BodyScan-BjYHCskz.js +0 -2
  46. package/dist/BodyScan-BoAbG01d.js +0 -2
  47. package/dist/BodyScan-Bq64fsmL.js +0 -2
  48. package/dist/BodyScan-Bre1BIHK.js +0 -2
  49. package/dist/BodyScan-BsDJmy0G.js +0 -2
  50. package/dist/BodyScan-ByMGumuH.js +0 -2
  51. package/dist/BodyScan-C0V-EDdB.js +0 -2
  52. package/dist/BodyScan-C1dWJ2qu.js +0 -2
  53. package/dist/BodyScan-C43x2o2T.js +0 -2
  54. package/dist/BodyScan-C57PuQgF.js +0 -2
  55. package/dist/BodyScan-C9hQU-dK.js +0 -2
  56. package/dist/BodyScan-CA4rNyqL.js +0 -2
  57. package/dist/BodyScan-CH-_x55M.js +0 -2
  58. package/dist/BodyScan-CKH_WyTt.js +0 -2
  59. package/dist/BodyScan-CKmPcrkx.js +0 -2
  60. package/dist/BodyScan-CLpL3Uwx.js +0 -2
  61. package/dist/BodyScan-CM12T_-T.js +0 -2
  62. package/dist/BodyScan-CNhb6UOX.js +0 -2
  63. package/dist/BodyScan-CWsaPB8W.js +0 -2
  64. package/dist/BodyScan-CXwtxfOd.js +0 -2
  65. package/dist/BodyScan-CYn7eLoz.js +0 -2
  66. package/dist/BodyScan-CYnHFqsR.js +0 -2
  67. package/dist/BodyScan-CZTiQzpy.js +0 -2
  68. package/dist/BodyScan-Cc68SnU1.js +0 -2
  69. package/dist/BodyScan-CfS4bPCN.js +0 -2
  70. package/dist/BodyScan-CiG19l_n.js +0 -2
  71. package/dist/BodyScan-CjvyMLT9.js +0 -2
  72. package/dist/BodyScan-CkmrPAq9.js +0 -2
  73. package/dist/BodyScan-CoObDhac.js +0 -2
  74. package/dist/BodyScan-Cyfo46EK.js +0 -2
  75. package/dist/BodyScan-Cz9ggKm6.js +0 -2
  76. package/dist/BodyScan-D6Y_W5e2.js +0 -2
  77. package/dist/BodyScan-DCEgmVbG.js +0 -2
  78. package/dist/BodyScan-DEDdENv7.js +0 -2
  79. package/dist/BodyScan-DEdrK-ld.js +0 -2
  80. package/dist/BodyScan-DHMf2V5R.js +0 -2
  81. package/dist/BodyScan-DK9UmNBr.js +0 -2
  82. package/dist/BodyScan-DPCd26i-.js +0 -2
  83. package/dist/BodyScan-DPCd26i-.js.map +0 -1
  84. package/dist/BodyScan-DPSQ1hKh.js +0 -2
  85. package/dist/BodyScan-DVKnmJuJ.js +0 -2
  86. package/dist/BodyScan-DX_KbG5U.js +0 -2
  87. package/dist/BodyScan-DbfP9-G3.js +0 -2
  88. package/dist/BodyScan-DeBJWo0L.js +0 -2
  89. package/dist/BodyScan-DgZpiChn.js +0 -2
  90. package/dist/BodyScan-DkPwUgVu.js +0 -2
  91. package/dist/BodyScan-DntA0MBx.js +0 -2
  92. package/dist/BodyScan-DxidLEhk.js +0 -2
  93. package/dist/BodyScan-DyDxGqfI.js +0 -2
  94. package/dist/BodyScan-Dysj7b77.js +0 -2
  95. package/dist/BodyScan-DzyamZmb.js +0 -2
  96. package/dist/BodyScan-Ehsr_cYc.js +0 -2
  97. package/dist/BodyScan-MSB66I12.js +0 -2
  98. package/dist/BodyScan-Ot6nAH1j.js +0 -2
  99. package/dist/BodyScan-Srq29PK8.js +0 -2
  100. package/dist/BodyScan-SzaquTgH.js +0 -2
  101. package/dist/BodyScan-TPpfyief.js +0 -2
  102. package/dist/BodyScan-XW2vsiE3.js +0 -2
  103. package/dist/BodyScan-eUuIC3jY.js +0 -2
  104. package/dist/BodyScan-enDyqSjO.js +0 -2
  105. package/dist/BodyScan-iOXndWaO.js +0 -2
  106. package/dist/BodyScan-qVHOWabf.js +0 -2
  107. package/dist/BodyScan-t9qdQAL-.js +0 -2
  108. package/dist/BodyScan-twE2YOwy.js +0 -2
  109. package/dist/BodyScan-z6h5fueJ.js +0 -2
  110. package/dist/FaceScan-3rVSqkKB.js +0 -2
  111. package/dist/FaceScan-6Aoz5uUy.js +0 -2
  112. package/dist/FaceScan-7fl5pLnb.js +0 -2
  113. package/dist/FaceScan-9kUfXRSv.js +0 -2
  114. package/dist/FaceScan-AHZ-ajep.js +0 -2
  115. package/dist/FaceScan-B0pFv4Us.js +0 -2
  116. package/dist/FaceScan-BE0PB0fZ.js +0 -2
  117. package/dist/FaceScan-BWSeJEqI.js +0 -2
  118. package/dist/FaceScan-BdjT7nMG.js +0 -2
  119. package/dist/FaceScan-Bji5lGcQ.js +0 -2
  120. package/dist/FaceScan-Bji5lGcQ.js.map +0 -1
  121. package/dist/FaceScan-BmDNM8tt.js +0 -2
  122. package/dist/FaceScan-CNoW9DIE.js +0 -2
  123. package/dist/FaceScan-CPf6-siO.js +0 -2
  124. package/dist/FaceScan-CQayY4q-.js +0 -2
  125. package/dist/FaceScan-CQkfSMC2.js +0 -2
  126. package/dist/FaceScan-CaxQ6fGF.js +0 -2
  127. package/dist/FaceScan-CxDcvM4f.js +0 -2
  128. package/dist/FaceScan-D2PL8KpZ.js +0 -2
  129. package/dist/FaceScan-D3T_l4nN.js +0 -2
  130. package/dist/FaceScan-DCm43Nrq.js +0 -2
  131. package/dist/FaceScan-DKP93c3l.js +0 -2
  132. package/dist/FaceScan-DW6Ix1a1.js +0 -2
  133. package/dist/FaceScan-DYJVZoZ4.js +0 -2
  134. package/dist/FaceScan-Da2XEApH.js +0 -2
  135. package/dist/FaceScan-DrW2yUSA.js +0 -2
  136. package/dist/FaceScan-DxnydFcx.js +0 -2
  137. package/dist/FaceScan-Gm4F4cO1.js +0 -2
  138. package/dist/FaceScan-Nhc7myLG.js +0 -2
  139. package/dist/FaceScan-VFLJ9h_T.js +0 -2
  140. package/dist/FaceScan-iUXyDuza.js +0 -2
  141. package/dist/LoadingScreen-BILrJVZm.js +0 -2
  142. package/dist/LoadingScreen-FKDLJRUj.js +0 -2
  143. package/dist/Modal-4T_aWWPQ.js +0 -2
  144. package/dist/Modal-BHfJVhRi.js +0 -2
  145. package/dist/Modal-BitizIvu.js +0 -2
  146. package/dist/Modal-BpgpPVxR.js +0 -2
  147. package/dist/Modal-BzH-_ch3.js +0 -2
  148. package/dist/Modal-CB_MHF7l.js +0 -2
  149. package/dist/Modal-CDiBoVXR.js +0 -2
  150. package/dist/Modal-CWoUZTh4.js +0 -2
  151. package/dist/Modal-CaPtqgjI.js +0 -2
  152. package/dist/Modal-CbZJwbLZ.js +0 -2
  153. package/dist/Modal-DRjJKUrw.js +0 -2
  154. package/dist/Modal-DU2Jymve.js +0 -2
  155. package/dist/Modal-D_XGokez.js +0 -2
  156. package/dist/Modal-DnweWp6L.js +0 -2
  157. package/dist/Modal-Do--CErH.js +0 -2
  158. package/dist/Modal-Do--CErH.js.map +0 -1
  159. package/dist/Modal-YZScjwEm.js +0 -2
  160. package/dist/fonts/Switzer-Regular.eot +0 -0
  161. package/dist/fonts/Switzer-Regular.svg +0 -0
  162. package/dist/fonts/Switzer-Regular.ttf +0 -0
  163. package/dist/fonts/Switzer-Regular.woff +0 -0
  164. package/dist/fonts/Switzer-Regular.woff2 +0 -0
  165. package/dist/interfaces-B5ysRXpa.d.ts +0 -209
  166. package/dist/interfaces-CaaERZjZ.d.ts +0 -209
  167. package/dist/pose-detection.esm-D08ZA0zl.js +0 -18
  168. package/dist/pose-detection.esm-DejsYGYM.js +0 -18
  169. package/dist/pose-detection.esm-DejsYGYM.js.map +0 -1
@@ -1,2 +0,0 @@
1
- import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as r,useMemo as o,useCallback as c,useEffect as i,useContext as s}from"react";import{v as l,p as d,s as u,a as m,L as f,u as h,H as g,b as p,S as y,m as S,g as b,G as v,d as w,F as x,P as F,c as N,M as I,e as _,f as k,h as E,i as C,j as M,k as D,l as P,n as T,o as z,q as R,r as L,t as $,w as j,C as V,x as O,y as W,z as A,A as U}from"./Modal-BzH-_ch3.js";import{ArrowRight as B}from"lucide-react";import{Drawer as q}from"@mui/material";let J=null,G=!1;const H=async()=>{if("undefined"==typeof window)return null;if(J)return J;if(G)for(;G;)if(await new Promise(e=>setTimeout(e,100)),J)return J;G=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-DC0_P6R7.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof l.width?l.width:l.width.ideal??l.width.max??1280,n.height="number"==typeof l.height?l.height:l.height.ideal??l.height.max??720;const r=n.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return J=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{G=!1}};function K({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:l,shopDomain:f,isError:h,isSuccess:g}){const p=n(null),[y,S]=r(0),[b,v]=r(0),[w,x]=r(!1),[F,N]=r(!1),I=n(!1),_=n(null),k=n(null),E=n(y),C=n(b),M=n([]),D=n(""),P=n(0),T=n(!1),z=n(0),R="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),L=o(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),$=o(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{d.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),j=c((t,a,n,r,o,c)=>{const i=Date.now();if(!(i-z.current<4e3)){z.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),f=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,h=a.map(e=>e[2]).filter(e=>e>0),g=h.length>0?h.reduce((e,t)=>e+t,0)/h.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const v={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:r,bodyInvalid:o,consecutiveValid:c,avgFaceScore:parseFloat(f.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:h.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};$(v)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,$]),V=()=>{d.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:L[E.current]}),setTimeout(()=>{N(!0)},1500)};return i(()=>{if(!h&&!g)return(async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await H();e&&(p.current=e,console.log("Face scan model loaded successfully"),x(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}})(),()=>{(async()=>{try{x(!1)}catch(e){console.error("Error disposing resources:",e)}finally{S(0),v(0),E.current=0,C.current=0,M.current=[]}})()}},[h,g]),i(()=>{E.current=y},[y]),i(()=>{C.current=b},[b]),{faceScanDetector:async(n,r)=>{if(p.current&&n.current&&w&&F&&!(n.current.readyState<2||I.current)){I.current=!0;try{const o=n.current.videoWidth||720,c=n.current.videoHeight||1280;_.current||(_.current=document.createElement("canvas"),_.current.width=o,_.current.height=c);const i=_.current.getContext("2d");i&&i.drawImage(n.current,0,0,o,c);const s=await p.current.estimatePoses(i?_.current:n.current);if(s.length>0){const n=[],o=[];if(s[0].keypoints.forEach((e,t)=>{const a=e.score??0,r=[e.x??-1,e.y??-1,a];t<=10?n.push(r):o.push(r)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),r=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,r+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const c=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,r=n>.7||n<.3,o=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!r&&o&&s;case 1:return!r&&o&&l;case 2:return!r&&o&&d;default:return!1}})(E.current,n),i=o.slice(2).filter(e=>e[2]>.7).length<=2;M.current.push(c&&i),M.current.length>10&&M.current.shift();if(M.current.filter(Boolean).length>=2){const e=C.current+1;v(e)}else v(Math.max(0,C.current-1));if(C.current>=2){t?.();const n=E.current+1;v(0),M.current=[],S(n),N(!1),(async()=>{if(await u.playAudio(`${m}face-scan-vos/Sound-effect.mp3`),d.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:E.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:L[E.current]}),1===n&&l&&l(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await u.playAudio(`${m}face-scan-vos/${e}`),V()}})()}j(n,o,E.current,c,i,C.current)}}catch(e){console.error("Pose detection error:",e)}finally{I.current=!1}}},scanStage:y,setScanStage:S,consecutiveValid:b,isModelLoaded:w,resetScan:()=>{d.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:L[E.current],consecutiveValid:C.current}),S(0),v(0),N(!1),E.current=0,C.current=0,M.current=[],D.current="",P.current=0,T.current=!1,k.current&&(speechSynthesis.cancel(),k.current=null)},enableVoiceCommands:()=>{if(T.current=!0,"undefined"!=typeof window&&R&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:V,isScanningActive:F}}function X({onRetry:a,loading:n}){const{translate:r}=s(f)||{},o=h();return e("div",{"data-testid":"face-scan-error-screen",className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:o?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:o?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:o?.style?.heading?.headingFontSize||"32px",color:o?.style?.heading?.headingColor||"#000",fontWeight:o?.style?.heading?.headingFontWeight||"normal"},children:r?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:o?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:o?.style?.subheading?.subheadingFontSize||"14px",color:o?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:o?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(p.clickToResetScan)}),e(y,{"data-testid":"face-scan-retry-btn",disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(p.resetScan),postfixIcon:e(B,{}),buttonFunc:()=>a?.()})]})]})})}function Q({stage:a,videoLoading:n,setVideoLoading:r,videoError:o,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(f)||{},u=h();return-1===a?t("div",{"data-testid":"face-scan-guide",className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),o&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!o&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===v.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{"data-testid":"face-scan-start-btn",disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(w[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===v.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===v.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===v.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===v.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const Y=({webcamRef:n,canvasRef:r})=>{const{isError:o,isSuccess:c,showLoader:i,hasError:d,errorType:u,resetScanState:m,showGuideCard:f,scanStage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:v,getButtonText:w,isScanning:x,startScan:k,isModelLoaded:E,isLandscape:C,onRetry:M}=s(F),D=h();return o?e(X,{onRetry:M}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:D?.style?.base?.backgroundColor},children:e(N,{url:D?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),C&&!i&&!d&&e("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e(I,{variant:"portrait",config:D})}),i&&!d&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:D?.style?.base?.backgroundColor},children:e(N,{url:D?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:D?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:l.width.ideal,height:l.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)",visibility:C?"hidden":"visible"}}),e("canvas",{ref:r,width:l.width.ideal,height:l.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&d&&u===_.Camera&&e(I,{testId:"face-scan-camera-error-screen",config:D}),!i&&d&&u!==_.Camera&&e(X,{loading:i,onRetry:m}),f&&!d&&!i&&!C&&e(q,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e(Q,{stage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:v,btnConfig:{label:w(),onClick:x?m:k,isDisabled:i||!E,icon:e(x?B:a,{})}})})]})},Z=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:d,onCaptureComplete:f,onUploadStart:h,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:v,isSuccess:w}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:"",callbackUrl:null},N=t.token??"",I=n(null),B=n(null),q=n(null),J=n([]),G=n(null),H=n(null),X=n(0),Q=n(null),[Z,ee]=r(!1),[te,ae]=r(!1),[ne,re]=r(!1),[oe,ce]=r(!0),[ie,se]=r(!1),[le,de]=r(!1),[ue,me]=r(!1),[fe,he]=r(null),[ge,pe]=r(k()),ye=o(()=>E(N),[N]),{isLandscape:Se}=C(),{email:be,gender:ve,deviceFocalLength:we,shopDomain:xe,callbackUrl:Fe,bodyScanId:Ne}=x,[Ie,_e]=r([]),[ke,Ee]=r(M),Ce=o(()=>D(),[]),Me=P(Ie),De=T(Me);z();const Pe=c(()=>{console.log("Stopping recording..."),cancelAnimationFrame(X.current),Q.current&&(Q.current.pause(),Q.current.srcObject=null,Q.current=null),q.current&&"recording"===q.current.state&&q.current.stop(),q.current=null},[]),Te=async()=>{if(f?.(),J.current){if(0===J.current.length)return console.error("No video data recorded"),he(_.Scan),me(!0),void ee(!1);h?.(),ee(!0);const e=new File(J.current,`${ge}.${De}`,{type:Me}),t=H.current??await W(e),a=e.size,n=(a/1048576).toFixed(2),r=Math.round(a/1e4),o={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:J.current.length,estimated_duration_seconds:r},c=[{gender:ve},{face_scan_id:ge},{focal_length:`${we}`},{customer_store_url:xe},{scan_type:"face_scan"},{body_scan_id:Ne}];Fe&&c.push({callback_url:Fe}),A({eventName:`${xe}/face_scan_meta_data`,faceScanId:ge,email:be,data:JSON.stringify({metaData:c,videoData:o})});const i=Date.now();A({eventName:`${xe}/face_scan_upload_start`,faceScanId:ge,email:be,startTime:i});try{const t=await ye.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:ge,email:be,contentType:e.type}),a=Date.now();A({eventName:`${xe}/face_scan_upload_complete`,faceScanId:ge,email:be,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t);let n=!1;ye.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),U({eventName:`${xe}/webSocket`,faceScanID:ge,connection:"pre_open",type:"faceScan_recommendation",email:be})},faceScanId:ge,onOpen:()=>{U({eventName:`${xe}/webSocket`,faceScanID:ge,connection:"open",type:"faceScan_recommendation",email:be})},onError:e=>{n=!0,U({eventName:`${xe}/webSocket`,faceScanID:ge,connection:"error",type:"faceScan_recommendation",email:be}),Be(e)},onSuccess:e=>{n=!0,U({eventName:`${xe}/webSocket`,faceScanID:ge,connection:"success",type:"faceScan_recommendation",email:be}),qe(e)},onClose:()=>{S?.(),U({eventName:`${xe}/webSocket`,faceScanID:ge,connection:"close",type:"faceScan_recommendation",email:be}),n||Be({message:"Connection closed. Please try again."})}})}catch(e){g?.(),Be(e)}}},ze=c(()=>{const e=I.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,r=document.createElement("canvas"),o=r.getContext("2d");a>n?(r.width=n,r.height=a):(r.width=a,r.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play(),Q.current=c;const i=()=>{a>n?(o?.save(),o?.translate(r.width,0),o?.rotate(Math.PI/2),o?.drawImage(c,0,0,n,a),o?.restore()):o?.drawImage(c,0,0,a,n),X.current=requestAnimationFrame(i)};X.current=requestAnimationFrame(i);const s=t.frameRate??10;H.current=s;const l=r.captureStream(s),d={videoBitsPerSecond:15e5};let u;Ie.length>0&&(d.mimeType=Ie[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),he(_.Scan),me(!0),void ee(!1)}J.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&J.current&&J.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",J?.current?.length),Te()},u.start(100),q.current=u,console.log("Recording started successfully (portrait normalized)")},[Ie,Te]),{faceScanDetector:Re,scanStage:Le,setScanStage:$e,resetScan:je,isModelLoaded:Ve,startScanSequence:Oe}=K({faceScanId:ge,shopDomain:xe,isError:v,isSuccess:w,onScanComplete:()=>{Pe()},onModelReady:()=>{ae(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),ze()}}),We=c(()=>{Ve&&(d?.(),$e(0),u.playAudio(`${m}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{re(!0),setTimeout(()=>{Oe()},200)},200))},[$e,re,Oe,Ve,d]),Ae=c(()=>{re(!1),ce(!0),Pe(),je(),l?.(),J.current=[],H.current=null,q.current&&(q.current=null),me(!1),he(null),$e(-1),pe(k()),I.current&&G.current&&(I.current.srcObject=G.current,console.log("Camera stream restored after reset"))},[$e,re,ce,Pe,je,pe]),Ue=n(!1);i(()=>{!Se||Ue.current||Z||v||w||ue||(u.stopAudio(),q.current&&(q.current.onstop=null,"recording"===q.current.state&&q.current.stop(),q.current=null),J.current=[],H.current=null,Ae()),Ue.current=Se},[Se,Z,v,w,ue,Ae]);const Be=e=>{console.log(e,"ws error"),s?.(e),he(_.Scan),me(!0),ee(!1),ce(!1),A({eventName:`${xe}/faceScan`,faceScanId:ge,status:"failed",email:be,data:JSON.stringify(e)})},qe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&A({eventName:`${xe}/faceScan_success/intermediate`,faceScanId:ge,status:"success",email:be,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!v&&!w)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:ke}).then(e=>{G.current=e,I.current&&(I.current.srcObject=e)}).catch(e=>{if(console.error("Error accessing webcam:",e),ke===M)return void Ee(R);const t=["NotAllowedError","PermissionDeniedError","NotFoundError","DevicesNotFoundError","NotReadableError","TrackStartError"].includes(e?.name);he(t?_.Camera:_.Scan),me(!0)}),()=>{G.current&&G.current.getTracks().forEach(e=>e.stop())}},[v,w,ke]),i(()=>{if(!te||!ne)return;const e=setInterval(()=>{Re(I,B)},500);return()=>clearInterval(e)},[Re,te,ne]);return console.log("Model ready:",te,"Has error:",ue,"Is scanning:",ne,"showLoader",Z),i(()=>{const e=L(Ce,$);_e(e)},[Ce]),i(()=>{$e(-1)},[]),e("div",{"data-face-scan-stage":Le,children:e(j,{children:e(V,{config:b,children:e(F.Provider,{value:{isError:v,isSuccess:w,showLoader:Z,hasError:ue,errorType:fe,resetScanState:Ae,showGuideCard:oe,scanStage:Le,videoLoading:ie,setVideoLoading:se,videoError:le,setVideoError:de,gender:ve,getButtonText:()=>ne?p.reset:Ve?p.start:p.loading,isScanning:ne,startScan:We,isModelLoaded:Ve,isLandscape:Se,onRetry:l},children:e(O,{children:e(Y,{webcamRef:I,canvasRef:B})})})})})})};export{Z as F,H as p};
2
- //# sourceMappingURL=FaceScan-DrW2yUSA.js.map
@@ -1,2 +0,0 @@
1
- import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as r,useMemo as o,useCallback as c,useEffect as i,useContext as s}from"react";import{v as l,p as d,s as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,e as I,M as _,f as k,h as E,i as C,j as M,k as D,l as T,n as P,o as R,q as z,r as $,t as j,C as L,w as V,x as O,y as W}from"./Modal-CaPtqgjI.js";import{ArrowRight as U}from"lucide-react";import{Drawer as A}from"@mui/material";let B=null,q=!1;const J=async()=>{if("undefined"==typeof window)return null;if(B)return B;if(q)for(;q;)if(await new Promise(e=>setTimeout(e,100)),B)return B;q=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-DejsYGYM.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof l.width?l.width:l.width.ideal??l.width.max??1280,n.height="number"==typeof l.height?l.height:l.height.ideal??l.height.max??720;const r=n.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return B=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{q=!1}};function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:l,shopDomain:h,isError:f,isSuccess:g}){const p=n(null),[y,S]=r(0),[b,w]=r(0),[v,x]=r(!1),[F,N]=r(!1),I=n(!1),_=n(null),k=n(null),E=n(y),C=n(b),M=n([]),D=n(""),T=n(0),P=n(!1),R=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),$=o(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),j=o(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{d.capture(`${h}/face_scan_pose_detection`,e)},4e3),[h]),L=c((t,a,n,r,o,c)=>{const i=Date.now();if(!(i-R.current<4e3)){R.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:r,bodyInvalid:o,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};j(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,j]),V=()=>{d.capture(`${h}/face_scan_detection_started`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:$[E.current]}),setTimeout(()=>{N(!0)},1500)};return i(()=>{if(!f&&!g)return(async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await J();e&&(p.current=e,console.log("Face scan model loaded successfully"),x(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}})(),()=>{(async()=>{try{x(!1)}catch(e){console.error("Error disposing resources:",e)}finally{S(0),w(0),E.current=0,C.current=0,M.current=[]}})()}},[f,g]),i(()=>{E.current=y},[y]),i(()=>{C.current=b},[b]),{faceScanDetector:async(n,r)=>{if(p.current&&n.current&&v&&F&&!(n.current.readyState<2||I.current)){I.current=!0;try{const o=n.current.videoWidth||720,c=n.current.videoHeight||1280;_.current||(_.current=document.createElement("canvas"),_.current.width=o,_.current.height=c);const i=_.current.getContext("2d");i&&i.drawImage(n.current,0,0,o,c);const s=await p.current.estimatePoses(i?_.current:n.current);if(s.length>0){const n=[],o=[];if(s[0].keypoints.forEach((e,t)=>{const a=e.score??0,r=[e.x??-1,e.y??-1,a];t<=10?n.push(r):o.push(r)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),r=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,r+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const c=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,r=n>.7||n<.3,o=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!r&&o&&s;case 1:return!r&&o&&l;case 2:return!r&&o&&d;default:return!1}})(E.current,n),i=o.slice(2).filter(e=>e[2]>.7).length<=2;M.current.push(c&&i),M.current.length>10&&M.current.shift();if(M.current.filter(Boolean).length>=2){const e=C.current+1;w(e)}else w(Math.max(0,C.current-1));if(C.current>=2){t?.();const n=E.current+1;w(0),M.current=[],S(n),N(!1),(async()=>{if(await u.playAudio(`${m}face-scan-vos/Sound-effect.mp3`),d.capture(`${h}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:E.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:$[E.current]}),1===n&&l&&l(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await u.playAudio(`${m}face-scan-vos/${e}`),V()}})()}L(n,o,E.current,c,i,C.current)}}catch(e){console.error("Pose detection error:",e)}finally{I.current=!1}}},scanStage:y,setScanStage:S,consecutiveValid:b,isModelLoaded:v,resetScan:()=>{d.capture(`${h}/face_scan_reset`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:$[E.current],consecutiveValid:C.current}),S(0),w(0),N(!1),E.current=0,C.current=0,M.current=[],D.current="",T.current=0,P.current=!1,k.current&&(speechSynthesis.cancel(),k.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:V,isScanningActive:F}}function H({onRetry:a,loading:n}){const{translate:r}=s(h)||{},o=f();return e("div",{"data-testid":"face-scan-error-screen",className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:o?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl font-semibold text-gray-800 ",style:{fontFamily:o?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:o?.style?.heading?.headingFontSize||"32px",color:o?.style?.heading?.headingColor||"#000",fontWeight:o?.style?.heading?.headingFontWeight||"normal"},children:r?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:o?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:o?.style?.subheading?.subheadingFontSize||"14px",color:o?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:o?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(p.clickToResetScan)}),e(y,{"data-testid":"face-scan-retry-btn",disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(p.resetScan),postfixIcon:e(U,{}),buttonFunc:()=>a?.()})]})]})})}function K({stage:a,videoLoading:n,setVideoLoading:r,videoError:o,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{"data-testid":"face-scan-guide",className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),o&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!o&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{"data-testid":"face-scan-start-btn",disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:r})=>{const{isError:o,isSuccess:c,showLoader:i,hasError:d,errorType:u,resetScanState:m,showGuideCard:h,scanStage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,getButtonText:v,isScanning:x,startScan:k,isModelLoaded:E,onRetry:C}=s(F),M=f();return o?e(H,{onRetry:C}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),i&&!d&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:M?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:l.width.ideal,height:l.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:r,width:l.width.ideal,height:l.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&d&&u===I.Camera&&e(_,{testId:"face-scan-camera-error-screen",config:M}),!i&&d&&u!==I.Camera&&e(H,{loading:i,onRetry:m}),h&&!d&&!i&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},hideBackdrop:!0,children:e(K,{stage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,btnConfig:{label:v(),onClick:x?m:k,isDisabled:i||!E,icon:e(x?U:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:d,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:"",callbackUrl:null},N=t.token??"",_=n(null),U=n(null),A=n(null),B=n([]),q=n(null),J=n(null),H=n(0),K=n(null),[Q,Y]=r(!1),[Z,ee]=r(!1),[te,ae]=r(!1),[ne,re]=r(!0),[oe,ce]=r(!1),[ie,se]=r(!1),[le,de]=r(!1),[ue,me]=r(null),[he,fe]=r(k()),ge=o(()=>E(N),[N]),{email:pe,gender:ye,deviceFocalLength:Se,shopDomain:be,callbackUrl:we,bodyScanId:ve}=x,[xe,Fe]=r([]),[Ne,Ie]=r(C),_e=o(()=>M(),[]),ke=D(xe),Ee=T(ke);P();const Ce=c(()=>{console.log("Stopping recording..."),cancelAnimationFrame(H.current),K.current&&(K.current.pause(),K.current.srcObject=null,K.current=null),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),B.current){if(0===B.current.length)return console.error("No video data recorded"),me(I.Scan),de(!0),void Y(!1);f?.(),Y(!0);const e=new File(B.current,`${he}.${Ee}`,{type:ke}),t=J.current??await V(e),a=e.size,n=(a/1048576).toFixed(2),r=Math.round(a/1e4),o={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:B.current.length,estimated_duration_seconds:r},c=[{gender:ye},{face_scan_id:he},{focal_length:`${Se}`},{customer_store_url:be},{scan_type:"face_scan"},{body_scan_id:ve}];we&&c.push({callback_url:we}),O({eventName:`${be}/face_scan_meta_data`,faceScanId:he,email:pe,data:JSON.stringify({metaData:c,videoData:o})});const i=Date.now();O({eventName:`${be}/face_scan_upload_start`,faceScanId:he,email:pe,startTime:i});try{const t=await ge.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:he,email:pe,contentType:e.type}),a=Date.now();O({eventName:`${be}/face_scan_upload_complete`,faceScanId:he,email:pe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),ge.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"pre_open",type:"faceScan_recommendation",email:pe})},faceScanId:he,onOpen:()=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"open",type:"faceScan_recommendation",email:pe}),console.log("websocket connect open")},onError:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"error",type:"faceScan_recommendation",email:pe}),Oe(e)},onSuccess:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"success",type:"faceScan_recommendation",email:pe}),We(e)},onClose:()=>{S?.(),console.log("websocket connect close"),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"close",type:"faceScan_recommendation",email:pe})}})}catch(e){g?.(),Oe(e)}}},De=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,r=document.createElement("canvas"),o=r.getContext("2d");a>n?(r.width=n,r.height=a):(r.width=a,r.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play(),K.current=c;const i=()=>{a>n?(o?.save(),o?.translate(r.width,0),o?.rotate(Math.PI/2),o?.drawImage(c,0,0,n,a),o?.restore()):o?.drawImage(c,0,0,a,n),H.current=requestAnimationFrame(i)};H.current=requestAnimationFrame(i);const s=t.frameRate??10;J.current=s;const l=r.captureStream(s),d={videoBitsPerSecond:15e5};let u;xe.length>0&&(d.mimeType=xe[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),me(I.Scan),de(!0),void Y(!1)}B.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&B.current&&B.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",B?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[xe,Me]),{faceScanDetector:Te,scanStage:Pe,setScanStage:Re,resetScan:ze,isModelLoaded:$e,startScanSequence:je}=G({faceScanId:he,shopDomain:be,isError:w,isSuccess:v,onScanComplete:()=>{Ce()},onModelReady:()=>{ee(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),De()}}),Le=c(()=>{$e&&(d?.(),Re(0),u.playAudio(`${m}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{ae(!0),setTimeout(()=>{je()},200)},200))},[Re,ae,je,$e,d]),Ve=c(()=>{ae(!1),re(!0),Ce(),ze(),l?.(),B.current=[],J.current=null,A.current&&(A.current=null),de(!1),me(null),Re(-1),fe(k()),_.current&&q.current&&(_.current.srcObject=q.current,console.log("Camera stream restored after reset"))},[Re,ae,re,Ce,ze,fe]),Oe=e=>{console.log(e,"ws error"),s?.(e),me(I.Scan),de(!0),Y(!1),re(!1),O({eventName:`${be}/faceScan`,faceScanId:he,status:"failed",email:pe,data:JSON.stringify(e)})},We=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&O({eventName:`${be}/faceScan_success/intermediate`,faceScanId:he,status:"success",email:pe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Ne}).then(e=>{q.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{if(console.error("Error accessing webcam:",e),Ne===C)return void Ie(R);const t=["NotAllowedError","PermissionDeniedError","NotFoundError","DevicesNotFoundError","NotReadableError","TrackStartError"].includes(e?.name);me(t?I.Camera:I.Scan),de(!0)}),()=>{q.current&&q.current.getTracks().forEach(e=>e.stop())}},[w,v,Ne]),i(()=>{if(!Z||!te)return;const e=setInterval(()=>{Te(_,U)},500);return()=>clearInterval(e)},[Te,Z,te]);return console.log("Model ready:",Z,"Has error:",le,"Is scanning:",te,"showLoader",Q),i(()=>{const e=z(_e,$);Fe(e)},[_e]),i(()=>{Re(-1)},[]),e("div",{"data-face-scan-stage":Pe,children:e(j,{children:e(L,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:Q,hasError:le,errorType:ue,resetScanState:Ve,showGuideCard:ne,scanStage:Pe,videoLoading:oe,setVideoLoading:ce,videoError:ie,setVideoError:se,gender:ye,getButtonText:()=>te?p.reset:$e?p.start:p.loading,isScanning:te,startScan:Le,isModelLoaded:$e,onRetry:l},children:e(X,{webcamRef:_,canvasRef:U})})})})})};export{Q as F,J as p};
2
- //# sourceMappingURL=FaceScan-DxnydFcx.js.map
@@ -1,2 +0,0 @@
1
- import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as r,useMemo as o,useCallback as c,useEffect as i,useContext as s}from"react";import{v as l,p as d,s as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,e as I,M as _,f as k,h as E,i as C,j as M,k as D,l as T,n as P,o as R,q as z,r as $,t as j,C as L,w as V,x as O,y as W}from"./Modal-D_XGokez.js";import{ArrowRight as U}from"lucide-react";import{Drawer as A}from"@mui/material";let B=null,q=!1;const J=async()=>{if("undefined"==typeof window)return null;if(B)return B;if(q)for(;q;)if(await new Promise(e=>setTimeout(e,100)),B)return B;q=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-DejsYGYM.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof l.width?l.width:l.width.ideal??l.width.max??1280,n.height="number"==typeof l.height?l.height:l.height.ideal??l.height.max??720;const r=n.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return B=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{q=!1}};function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:l,shopDomain:h,isError:f,isSuccess:g}){const p=n(null),[y,S]=r(0),[b,w]=r(0),[v,x]=r(!1),[F,N]=r(!1),I=n(!1),_=n(null),k=n(null),E=n(y),C=n(b),M=n([]),D=n(""),T=n(0),P=n(!1),R=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),$=o(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),j=o(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{d.capture(`${h}/face_scan_pose_detection`,e)},4e3),[h]),L=c((t,a,n,r,o,c)=>{const i=Date.now();if(!(i-R.current<4e3)){R.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:r,bodyInvalid:o,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};j(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,j]),V=()=>{d.capture(`${h}/face_scan_detection_started`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:$[E.current]}),setTimeout(()=>{N(!0)},1500)};return i(()=>{if(!f&&!g)return(async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await J();e&&(p.current=e,console.log("Face scan model loaded successfully"),x(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}})(),()=>{(async()=>{try{x(!1)}catch(e){console.error("Error disposing resources:",e)}finally{S(0),w(0),E.current=0,C.current=0,M.current=[]}})()}},[f,g]),i(()=>{E.current=y},[y]),i(()=>{C.current=b},[b]),{faceScanDetector:async(n,r)=>{if(p.current&&n.current&&v&&F&&!(n.current.readyState<2||I.current)){I.current=!0;try{const o=n.current.videoWidth||720,c=n.current.videoHeight||1280;_.current||(_.current=document.createElement("canvas"),_.current.width=o,_.current.height=c);const i=_.current.getContext("2d");i&&i.drawImage(n.current,0,0,o,c);const s=await p.current.estimatePoses(i?_.current:n.current);if(s.length>0){const n=[],o=[];if(s[0].keypoints.forEach((e,t)=>{const a=e.score??0,r=[e.x??-1,e.y??-1,a];t<=10?n.push(r):o.push(r)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),r=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,r+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const c=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,r=n>.7||n<.3,o=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!r&&o&&s;case 1:return!r&&o&&l;case 2:return!r&&o&&d;default:return!1}})(E.current,n),i=o.slice(2).filter(e=>e[2]>.7).length<=2;M.current.push(c&&i),M.current.length>10&&M.current.shift();if(M.current.filter(Boolean).length>=2){const e=C.current+1;w(e)}else w(Math.max(0,C.current-1));if(C.current>=2){t?.();const n=E.current+1;w(0),M.current=[],S(n),N(!1),(async()=>{if(await u.playAudio(`${m}face-scan-vos/Sound-effect.mp3`),d.capture(`${h}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:E.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:$[E.current]}),1===n&&l&&l(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await u.playAudio(`${m}face-scan-vos/${e}`),V()}})()}L(n,o,E.current,c,i,C.current)}}catch(e){console.error("Pose detection error:",e)}finally{I.current=!1}}},scanStage:y,setScanStage:S,consecutiveValid:b,isModelLoaded:v,resetScan:()=>{d.capture(`${h}/face_scan_reset`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:$[E.current],consecutiveValid:C.current}),S(0),w(0),N(!1),E.current=0,C.current=0,M.current=[],D.current="",T.current=0,P.current=!1,k.current&&(speechSynthesis.cancel(),k.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:V,isScanningActive:F}}function H({onRetry:a,loading:n}){const{translate:r}=s(h)||{},o=f();return e("div",{"data-testid":"face-scan-error-screen",className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:o?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl font-semibold text-gray-800 ",style:{fontFamily:o?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:o?.style?.heading?.headingFontSize||"32px",color:o?.style?.heading?.headingColor||"#000",fontWeight:o?.style?.heading?.headingFontWeight||"normal"},children:r?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:o?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:o?.style?.subheading?.subheadingFontSize||"14px",color:o?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:o?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(p.clickToResetScan)}),e(y,{"data-testid":"face-scan-retry-btn",disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(p.resetScan),postfixIcon:e(U,{}),buttonFunc:()=>a?.()})]})]})})}function K({stage:a,videoLoading:n,setVideoLoading:r,videoError:o,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{"data-testid":"face-scan-guide",className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),o&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!o&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{"data-testid":"face-scan-start-btn",disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:r})=>{const{isError:o,isSuccess:c,showLoader:i,hasError:d,errorType:u,resetScanState:m,showGuideCard:h,scanStage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,getButtonText:v,isScanning:x,startScan:k,isModelLoaded:E,onRetry:C}=s(F),M=f();return o?e(H,{onRetry:C}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),i&&!d&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:M?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:l.width.ideal,height:l.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:r,width:l.width.ideal,height:l.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&d&&u===I.Camera&&e(_,{testId:"face-scan-camera-error-screen",config:M}),!i&&d&&u!==I.Camera&&e(H,{loading:i,onRetry:m}),h&&!d&&!i&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},hideBackdrop:!0,children:e(K,{stage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,btnConfig:{label:v(),onClick:x?m:k,isDisabled:i||!E,icon:e(x?U:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:d,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:"",callbackUrl:null},N=t.token??"",_=n(null),U=n(null),A=n(null),B=n([]),q=n(null),J=n(null),H=n(0),K=n(null),[Q,Y]=r(!1),[Z,ee]=r(!1),[te,ae]=r(!1),[ne,re]=r(!0),[oe,ce]=r(!1),[ie,se]=r(!1),[le,de]=r(!1),[ue,me]=r(null),[he,fe]=r(k()),ge=o(()=>E(N),[N]),{email:pe,gender:ye,deviceFocalLength:Se,shopDomain:be,callbackUrl:we,bodyScanId:ve}=x,[xe,Fe]=r([]),[Ne,Ie]=r(C),_e=o(()=>M(),[]),ke=D(xe),Ee=T(ke);P();const Ce=c(()=>{console.log("Stopping recording..."),cancelAnimationFrame(H.current),K.current&&(K.current.pause(),K.current.srcObject=null,K.current=null),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),B.current){if(0===B.current.length)return console.error("No video data recorded"),me(I.Scan),de(!0),void Y(!1);f?.(),Y(!0);const e=new File(B.current,`${he}.${Ee}`,{type:ke}),t=J.current??await V(e),a=e.size,n=(a/1048576).toFixed(2),r=Math.round(a/1e4),o={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:B.current.length,estimated_duration_seconds:r},c=[{gender:ye},{face_scan_id:he},{focal_length:`${Se}`},{customer_store_url:be},{scan_type:"face_scan"},{body_scan_id:ve}];we&&c.push({callback_url:we}),O({eventName:`${be}/face_scan_meta_data`,faceScanId:he,email:pe,data:JSON.stringify({metaData:c,videoData:o})});const i=Date.now();O({eventName:`${be}/face_scan_upload_start`,faceScanId:he,email:pe,startTime:i});try{const t=await ge.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:he,email:pe,contentType:e.type}),a=Date.now();O({eventName:`${be}/face_scan_upload_complete`,faceScanId:he,email:pe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),ge.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"pre_open",type:"faceScan_recommendation",email:pe})},faceScanId:he,onOpen:()=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"open",type:"faceScan_recommendation",email:pe}),console.log("websocket connect open")},onError:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"error",type:"faceScan_recommendation",email:pe}),Oe(e)},onSuccess:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"success",type:"faceScan_recommendation",email:pe}),We(e)},onClose:()=>{S?.(),console.log("websocket connect close"),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"close",type:"faceScan_recommendation",email:pe})}})}catch(e){g?.(),Oe(e)}}},De=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,r=document.createElement("canvas"),o=r.getContext("2d");a>n?(r.width=n,r.height=a):(r.width=a,r.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play(),K.current=c;const i=()=>{a>n?(o?.save(),o?.translate(r.width,0),o?.rotate(Math.PI/2),o?.drawImage(c,0,0,n,a),o?.restore()):o?.drawImage(c,0,0,a,n),H.current=requestAnimationFrame(i)};H.current=requestAnimationFrame(i);const s=t.frameRate??10;J.current=s;const l=r.captureStream(s),d={videoBitsPerSecond:15e5};let u;xe.length>0&&(d.mimeType=xe[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),me(I.Scan),de(!0),void Y(!1)}B.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&B.current&&B.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",B?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[xe,Me]),{faceScanDetector:Te,scanStage:Pe,setScanStage:Re,resetScan:ze,isModelLoaded:$e,startScanSequence:je}=G({faceScanId:he,shopDomain:be,isError:w,isSuccess:v,onScanComplete:()=>{Ce()},onModelReady:()=>{ee(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),De()}}),Le=c(()=>{$e&&(d?.(),Re(0),u.playAudio(`${m}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{ae(!0),setTimeout(()=>{je()},200)},200))},[Re,ae,je,$e,d]),Ve=c(()=>{ae(!1),re(!0),Ce(),ze(),l?.(),B.current=[],J.current=null,A.current&&(A.current=null),de(!1),me(null),Re(-1),fe(k()),_.current&&q.current&&(_.current.srcObject=q.current,console.log("Camera stream restored after reset"))},[Re,ae,re,Ce,ze,fe]),Oe=e=>{console.log(e,"ws error"),s?.(e),me(I.Scan),de(!0),Y(!1),re(!1),O({eventName:`${be}/faceScan`,faceScanId:he,status:"failed",email:pe,data:JSON.stringify(e)})},We=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&O({eventName:`${be}/faceScan_success/intermediate`,faceScanId:he,status:"success",email:pe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Ne}).then(e=>{q.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{if(console.error("Error accessing webcam:",e),Ne===C)return void Ie(R);const t=["NotAllowedError","PermissionDeniedError","NotFoundError","DevicesNotFoundError","NotReadableError","TrackStartError"].includes(e?.name);me(t?I.Camera:I.Scan),de(!0)}),()=>{q.current&&q.current.getTracks().forEach(e=>e.stop())}},[w,v,Ne]),i(()=>{if(!Z||!te)return;const e=setInterval(()=>{Te(_,U)},500);return()=>clearInterval(e)},[Te,Z,te]);return console.log("Model ready:",Z,"Has error:",le,"Is scanning:",te,"showLoader",Q),i(()=>{const e=z(_e,$);Fe(e)},[_e]),i(()=>{Re(-1)},[]),e("div",{"data-face-scan-stage":Pe,children:e(j,{children:e(L,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:Q,hasError:le,errorType:ue,resetScanState:Ve,showGuideCard:ne,scanStage:Pe,videoLoading:oe,setVideoLoading:ce,videoError:ie,setVideoError:se,gender:ye,getButtonText:()=>te?p.reset:$e?p.start:p.loading,isScanning:te,startScan:Le,isModelLoaded:$e,onRetry:l},children:e(X,{webcamRef:_,canvasRef:U})})})})})};export{Q as F,J as p};
2
- //# sourceMappingURL=FaceScan-Gm4F4cO1.js.map
@@ -1,2 +0,0 @@
1
- import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as r,useMemo as o,useCallback as c,useEffect as i,useContext as s}from"react";import{v as l,p as d,s as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,e as I,M as _,f as k,h as E,i as C,j as M,k as D,l as T,n as P,o as R,q as z,r as $,t as j,C as L,w as V,x as O,y as W}from"./Modal-BPtRtRVC.js";import{ArrowRight as U}from"lucide-react";import{Drawer as A}from"@mui/material";let B=null,q=!1;const J=async()=>{if("undefined"==typeof window)return null;if(B)return B;if(q)for(;q;)if(await new Promise(e=>setTimeout(e,100)),B)return B;q=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-DejsYGYM.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof l.width?l.width:l.width.ideal??l.width.max??1280,n.height="number"==typeof l.height?l.height:l.height.ideal??l.height.max??720;const r=n.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return B=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{q=!1}};function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:l,shopDomain:h,isError:f,isSuccess:g}){const p=n(null),[y,S]=r(0),[b,w]=r(0),[v,x]=r(!1),[F,N]=r(!1),I=n(!1),_=n(null),k=n(null),E=n(y),C=n(b),M=n([]),D=n(""),T=n(0),P=n(!1),R=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),$=o(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),j=o(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{d.capture(`${h}/face_scan_pose_detection`,e)},4e3),[h]),L=c((t,a,n,r,o,c)=>{const i=Date.now();if(!(i-R.current<4e3)){R.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:r,bodyInvalid:o,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};j(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,j]),V=()=>{d.capture(`${h}/face_scan_detection_started`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:$[E.current]}),setTimeout(()=>{N(!0)},1500)};return i(()=>{if(!f&&!g)return(async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await J();e&&(p.current=e,console.log("Face scan model loaded successfully"),x(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}})(),()=>{(async()=>{try{x(!1)}catch(e){console.error("Error disposing resources:",e)}finally{S(0),w(0),E.current=0,C.current=0,M.current=[]}})()}},[f,g]),i(()=>{E.current=y},[y]),i(()=>{C.current=b},[b]),{faceScanDetector:async(n,r)=>{if(p.current&&n.current&&v&&F&&!(n.current.readyState<2||I.current)){I.current=!0;try{const o=n.current.videoWidth||720,c=n.current.videoHeight||1280;_.current||(_.current=document.createElement("canvas"),_.current.width=o,_.current.height=c);const i=_.current.getContext("2d");i&&i.drawImage(n.current,0,0,o,c);const s=await p.current.estimatePoses(i?_.current:n.current);if(s.length>0){const n=[],o=[];if(s[0].keypoints.forEach((e,t)=>{const a=e.score??0,r=[e.x??-1,e.y??-1,a];t<=10?n.push(r):o.push(r)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),r=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,r+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const c=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,r=n>.7||n<.3,o=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!r&&o&&s;case 1:return!r&&o&&l;case 2:return!r&&o&&d;default:return!1}})(E.current,n),i=o.slice(2).filter(e=>e[2]>.7).length<=2;M.current.push(c&&i),M.current.length>10&&M.current.shift();if(M.current.filter(Boolean).length>=2){const e=C.current+1;w(e)}else w(Math.max(0,C.current-1));if(C.current>=2){t?.();const n=E.current+1;w(0),M.current=[],S(n),N(!1),(async()=>{if(await u.playAudio(`${m}face-scan-vos/Sound-effect.mp3`),d.capture(`${h}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:E.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:$[E.current]}),1===n&&l&&l(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await u.playAudio(`${m}face-scan-vos/${e}`),V()}})()}L(n,o,E.current,c,i,C.current)}}catch(e){console.error("Pose detection error:",e)}finally{I.current=!1}}},scanStage:y,setScanStage:S,consecutiveValid:b,isModelLoaded:v,resetScan:()=>{d.capture(`${h}/face_scan_reset`,{faceScanId:e,stage:E.current,timestamp:(new Date).toISOString(),stageName:$[E.current],consecutiveValid:C.current}),S(0),w(0),N(!1),E.current=0,C.current=0,M.current=[],D.current="",T.current=0,P.current=!1,k.current&&(speechSynthesis.cancel(),k.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:V,isScanningActive:F}}function H({onRetry:a,loading:n}){const{translate:r}=s(h)||{},o=f();return e("div",{"data-testid":"face-scan-error-screen",className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:o?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl font-semibold text-gray-800 ",style:{fontFamily:o?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:o?.style?.heading?.headingFontSize||"32px",color:o?.style?.heading?.headingColor||"#000",fontWeight:o?.style?.heading?.headingFontWeight||"normal"},children:r?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:o?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:o?.style?.subheading?.subheadingFontSize||"14px",color:o?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:o?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(p.clickToResetScan)}),e(y,{"data-testid":"face-scan-retry-btn",disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(p.resetScan),postfixIcon:e(U,{}),buttonFunc:()=>a?.()})]})]})})}function K({stage:a,videoLoading:n,setVideoLoading:r,videoError:o,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{"data-testid":"face-scan-guide",className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),o&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!o&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{"data-testid":"face-scan-start-btn",disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:r})=>{const{isError:o,isSuccess:c,showLoader:i,hasError:d,errorType:u,resetScanState:m,showGuideCard:h,scanStage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,getButtonText:v,isScanning:x,startScan:k,isModelLoaded:E,onRetry:C}=s(F),M=f();return o?e(H,{onRetry:C}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),i&&!d&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:M?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:l.width.ideal,height:l.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:r,width:l.width.ideal,height:l.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&d&&u===I.Camera&&e(_,{testId:"face-scan-camera-error-screen",config:M}),!i&&d&&u!==I.Camera&&e(H,{loading:i,onRetry:m}),h&&!d&&!i&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},hideBackdrop:!0,children:e(K,{stage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,btnConfig:{label:v(),onClick:x?m:k,isDisabled:i||!E,icon:e(x?U:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:d,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:"",callbackUrl:null},N=t.token??"",_=n(null),U=n(null),A=n(null),B=n([]),q=n(null),J=n(null),H=n(0),K=n(null),[Q,Y]=r(!1),[Z,ee]=r(!1),[te,ae]=r(!1),[ne,re]=r(!0),[oe,ce]=r(!1),[ie,se]=r(!1),[le,de]=r(!1),[ue,me]=r(null),[he,fe]=r(k()),ge=o(()=>E(N),[N]),{email:pe,gender:ye,deviceFocalLength:Se,shopDomain:be,callbackUrl:we,bodyScanId:ve}=x,[xe,Fe]=r([]),[Ne,Ie]=r(C),_e=o(()=>M(),[]),ke=D(xe),Ee=T(ke);P();const Ce=c(()=>{console.log("Stopping recording..."),cancelAnimationFrame(H.current),K.current&&(K.current.pause(),K.current.srcObject=null,K.current=null),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),B.current){if(0===B.current.length)return console.error("No video data recorded"),me(I.Scan),de(!0),void Y(!1);f?.(),Y(!0);const e=new File(B.current,`${he}.${Ee}`,{type:ke}),t=J.current??await V(e),a=e.size,n=(a/1048576).toFixed(2),r=Math.round(a/1e4),o={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:B.current.length,estimated_duration_seconds:r},c=[{gender:ye},{face_scan_id:he},{focal_length:`${Se}`},{customer_store_url:be},{scan_type:"face_scan"},{body_scan_id:ve}];we&&c.push({callback_url:we}),O({eventName:`${be}/face_scan_meta_data`,faceScanId:he,email:pe,data:JSON.stringify({metaData:c,videoData:o})});const i=Date.now();O({eventName:`${be}/face_scan_upload_start`,faceScanId:he,email:pe,startTime:i});try{const t=await ge.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:he,email:pe,contentType:e.type}),a=Date.now();O({eventName:`${be}/face_scan_upload_complete`,faceScanId:he,email:pe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),ge.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"pre_open",type:"faceScan_recommendation",email:pe})},faceScanId:he,onOpen:()=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"open",type:"faceScan_recommendation",email:pe}),console.log("websocket connect open")},onError:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"error",type:"faceScan_recommendation",email:pe}),Oe(e)},onSuccess:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"success",type:"faceScan_recommendation",email:pe}),We(e)},onClose:()=>{S?.(),console.log("websocket connect close"),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"close",type:"faceScan_recommendation",email:pe})}})}catch(e){g?.(),Oe(e)}}},De=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,r=document.createElement("canvas"),o=r.getContext("2d");a>n?(r.width=n,r.height=a):(r.width=a,r.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play(),K.current=c;const i=()=>{a>n?(o?.save(),o?.translate(r.width,0),o?.rotate(Math.PI/2),o?.drawImage(c,0,0,n,a),o?.restore()):o?.drawImage(c,0,0,a,n),H.current=requestAnimationFrame(i)};H.current=requestAnimationFrame(i);const s=t.frameRate??10;J.current=s;const l=r.captureStream(s),d={videoBitsPerSecond:15e5};let u;xe.length>0&&(d.mimeType=xe[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),me(I.Scan),de(!0),void Y(!1)}B.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&B.current&&B.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",B?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[xe,Me]),{faceScanDetector:Te,scanStage:Pe,setScanStage:Re,resetScan:ze,isModelLoaded:$e,startScanSequence:je}=G({faceScanId:he,shopDomain:be,isError:w,isSuccess:v,onScanComplete:()=>{Ce()},onModelReady:()=>{ee(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),De()}}),Le=c(()=>{$e&&(d?.(),Re(0),u.playAudio(`${m}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{ae(!0),setTimeout(()=>{je()},200)},200))},[Re,ae,je,$e,d]),Ve=c(()=>{ae(!1),re(!0),Ce(),ze(),l?.(),B.current=[],J.current=null,A.current&&(A.current=null),de(!1),me(null),Re(-1),fe(k()),_.current&&q.current&&(_.current.srcObject=q.current,console.log("Camera stream restored after reset"))},[Re,ae,re,Ce,ze,fe]),Oe=e=>{console.log(e,"ws error"),s?.(e),me(I.Scan),de(!0),Y(!1),re(!1),O({eventName:`${be}/faceScan`,faceScanId:he,status:"failed",email:pe,data:JSON.stringify(e)})},We=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&O({eventName:`${be}/faceScan_success/intermediate`,faceScanId:he,status:"success",email:pe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Ne}).then(e=>{q.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{if(console.error("Error accessing webcam:",e),Ne===C)return void Ie(R);const t=["NotAllowedError","PermissionDeniedError","NotFoundError","DevicesNotFoundError","NotReadableError","TrackStartError"].includes(e?.name);me(t?I.Camera:I.Scan),de(!0)}),()=>{q.current&&q.current.getTracks().forEach(e=>e.stop())}},[w,v,Ne]),i(()=>{if(!Z||!te)return;const e=setInterval(()=>{Te(_,U)},500);return()=>clearInterval(e)},[Te,Z,te]);return console.log("Model ready:",Z,"Has error:",le,"Is scanning:",te,"showLoader",Q),i(()=>{const e=z(_e,$);Fe(e)},[_e]),i(()=>{Re(-1)},[]),e("div",{"data-face-scan-stage":Pe,children:e(j,{children:e(L,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:Q,hasError:le,errorType:ue,resetScanState:Ve,showGuideCard:ne,scanStage:Pe,videoLoading:oe,setVideoLoading:ce,videoError:ie,setVideoError:se,gender:ye,getButtonText:()=>te?p.reset:$e?p.start:p.loading,isScanning:te,startScan:Le,isModelLoaded:$e,onRetry:l},children:e(X,{webcamRef:_,canvasRef:U})})})})})};export{Q as F,J as p};
2
- //# sourceMappingURL=FaceScan-Nhc7myLG.js.map
@@ -1,2 +0,0 @@
1
- import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as r,useMemo as o,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,e as I,M as _,f as k,h as E,i as C,j as M,k as D,l as T,n as P,o as R,q as z,r as $,t as j,C as L,w as V,x as O,y as W}from"./Modal-BHfJVhRi.js";import{ArrowRight as U}from"lucide-react";import{Drawer as A}from"@mui/material";let B=null,q=!1;function J({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:h,shopDomain:f,isError:g,isSuccess:p}){const y=n(null),[S,b]=r(0),[w,v]=r(0),[x,F]=r(!1),[N,I]=r(!1),_=n(!1),k=n(null),E=n(null),C=n(S),M=n(w),D=n([]),T=n(""),P=n(0),R=n(!1),z=n(0),$="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),j=o(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=o(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),V=c((t,a,n,r,o,c)=>{const i=Date.now();if(!(i-z.current<4e3)){z.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:r,bodyInvalid:o,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),O=()=>{l.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:C.current,timestamp:(new Date).toISOString(),stageName:j[C.current]}),setTimeout(()=>{I(!0)},1500)},W=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(B)return B;if(q)for(;q;)if(await new Promise(e=>setTimeout(e,100)),B)return B;q=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-DejsYGYM.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const r=n.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return B=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{q=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return W(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),C.current=0,M.current=0,D.current=[]}})()}},[g,p]),i(()=>{C.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,r)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2||_.current)){_.current=!0;try{const o=n.current.videoWidth||720,c=n.current.videoHeight||1280;k.current||(k.current=document.createElement("canvas"),k.current.width=o,k.current.height=c);const i=k.current.getContext("2d");i&&i.drawImage(n.current,0,0,o,c);const s=await y.current.estimatePoses(i?k.current:n.current);if(s.length>0){const n=[],o=[];if(s[0].keypoints.forEach((e,t)=>{const a=e.score??0,r=[e.x??-1,e.y??-1,a];t<=10?n.push(r):o.push(r)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),r=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,r+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const c=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,r=n>.7||n<.3,o=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!r&&o&&s;case 1:return!r&&o&&l;case 2:return!r&&o&&d;default:return!1}})(C.current,n),i=o.slice(2).filter(e=>e[2]>.7).length<=2;D.current.push(c&&i),D.current.length>10&&D.current.shift();if(D.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=C.current+1;v(0),D.current=[],b(n),I(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:C.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:j[C.current]}),1===n&&h&&h(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),O()}})()}V(n,o,C.current,c,i,M.current)}}catch(e){console.error("Pose detection error:",e)}finally{_.current=!1}}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:C.current,timestamp:(new Date).toISOString(),stageName:j[C.current],consecutiveValid:M.current}),b(0),v(0),I(!1),C.current=0,M.current=0,D.current=[],T.current="",P.current=0,R.current=!1,E.current&&(speechSynthesis.cancel(),E.current=null)},enableVoiceCommands:()=>{if(R.current=!0,"undefined"!=typeof window&&$&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:O,isScanningActive:N}}function G({onRetry:a,loading:n}){const{translate:r}=s(h)||{},o=f();return e("div",{"data-testid":"face-scan-error-screen",className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:o?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl font-semibold text-gray-800 ",style:{fontFamily:o?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:o?.style?.heading?.headingFontSize||"32px",color:o?.style?.heading?.headingColor||"#000",fontWeight:o?.style?.heading?.headingFontWeight||"normal"},children:r?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:o?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:o?.style?.subheading?.subheadingFontSize||"14px",color:o?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:o?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(p.clickToResetScan)}),e(y,{"data-testid":"face-scan-retry-btn",disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(p.resetScan),postfixIcon:e(U,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:r,videoError:o,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{"data-testid":"face-scan-guide",className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),o&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!o&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{"data-testid":"face-scan-start-btn",disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const K=({webcamRef:n,canvasRef:r})=>{const{isError:o,isSuccess:c,showLoader:i,hasError:l,errorType:d,resetScanState:u,showGuideCard:h,scanStage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,getButtonText:v,isScanning:x,startScan:k,isModelLoaded:E,onRetry:C}=s(F),M=f();return o?e(G,{onRetry:C}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:M?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:r,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&d===I.Camera&&e(_,{testId:"face-scan-camera-error-screen",config:M}),!i&&l&&d!==I.Camera&&e(G,{loading:i,onRetry:u}),h&&!l&&!i&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},hideBackdrop:!0,children:e(H,{stage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,btnConfig:{label:v(),onClick:x?u:k,isDisabled:i||!E,icon:e(x?U:a,{})}})})]})},X=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:m,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:"",callbackUrl:null},N=t.token??"",_=n(null),U=n(null),A=n(null),B=n([]),q=n(null),G=n(null),H=n(0),X=n(null),[Q,Y]=r(!1),[Z,ee]=r(!1),[te,ae]=r(!1),[ne,re]=r(!0),[oe,ce]=r(!1),[ie,se]=r(!1),[le,de]=r(!1),[ue,me]=r(null),[he,fe]=r(k()),ge=o(()=>E(N),[N]),{email:pe,gender:ye,deviceFocalLength:Se,shopDomain:be,callbackUrl:we,bodyScanId:ve}=x,[xe,Fe]=r([]),[Ne,Ie]=r(C),_e=o(()=>M(),[]),ke=D(xe),Ee=T(ke);P();const Ce=c(()=>{console.log("Stopping recording..."),cancelAnimationFrame(H.current),X.current&&(X.current.pause(),X.current.srcObject=null,X.current=null),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),B.current){if(0===B.current.length)return console.error("No video data recorded"),me(I.Scan),de(!0),void Y(!1);f?.(),Y(!0);const e=new File(B.current,`${he}.${Ee}`,{type:ke}),t=G.current??await V(e),a=e.size,n=(a/1048576).toFixed(2),r=Math.round(a/1e4),o={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:B.current.length,estimated_duration_seconds:r},c=[{gender:ye},{face_scan_id:he},{focal_length:`${Se}`},{customer_store_url:be},{scan_type:"face_scan"},{body_scan_id:ve}];we&&c.push({callback_url:we}),O({eventName:`${be}/face_scan_meta_data`,faceScanId:he,email:pe,data:JSON.stringify({metaData:c,videoData:o})});const i=Date.now();O({eventName:`${be}/face_scan_upload_start`,faceScanId:he,email:pe,startTime:i});try{const t=await ge.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:he,email:pe,contentType:e.type}),a=Date.now();O({eventName:`${be}/face_scan_upload_complete`,faceScanId:he,email:pe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),ge.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"pre_open",type:"faceScan_recommendation",email:pe})},faceScanId:he,onOpen:()=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"open",type:"faceScan_recommendation",email:pe}),console.log("websocket connect open")},onError:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"error",type:"faceScan_recommendation",email:pe}),Oe(e)},onSuccess:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"success",type:"faceScan_recommendation",email:pe}),We(e)},onClose:()=>{S?.(),console.log("websocket connect close"),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"close",type:"faceScan_recommendation",email:pe})}})}catch(e){g?.(),Oe(e)}}},De=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,r=document.createElement("canvas"),o=r.getContext("2d");a>n?(r.width=n,r.height=a):(r.width=a,r.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play(),X.current=c;const i=()=>{a>n?(o?.save(),o?.translate(r.width,0),o?.rotate(Math.PI/2),o?.drawImage(c,0,0,n,a),o?.restore()):o?.drawImage(c,0,0,a,n),H.current=requestAnimationFrame(i)};H.current=requestAnimationFrame(i);const s=t.frameRate??10;G.current=s;const l=r.captureStream(s),d={videoBitsPerSecond:15e5};let u;xe.length>0&&(d.mimeType=xe[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),me(I.Scan),de(!0),void Y(!1)}B.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&B.current&&B.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",B?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[xe,Me]),{faceScanDetector:Te,scanStage:Pe,setScanStage:Re,resetScan:ze,isModelLoaded:$e,startScanSequence:je}=J({faceScanId:he,shopDomain:be,isError:w,isSuccess:v,onScanComplete:()=>{Ce()},onModelReady:()=>{ee(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),De()}}),Le=c(()=>{$e&&(m?.(),Re(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{ae(!0),setTimeout(()=>{je()},200)},200))},[Re,ae,je,$e,m]),Ve=c(()=>{ae(!1),re(!0),Ce(),ze(),l?.(),B.current=[],G.current=null,A.current&&(A.current=null),de(!1),me(null),Re(-1),fe(k()),_.current&&q.current&&(_.current.srcObject=q.current,console.log("Camera stream restored after reset"))},[Re,ae,re,Ce,ze,fe]),Oe=e=>{console.log(e,"ws error"),s?.(e),me(I.Scan),de(!0),Y(!1),re(!1),O({eventName:`${be}/faceScan`,faceScanId:he,status:"failed",email:pe,data:JSON.stringify(e)})},We=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&O({eventName:`${be}/faceScan_success/intermediate`,faceScanId:he,status:"success",email:pe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Ne}).then(e=>{q.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{if(console.error("Error accessing webcam:",e),Ne===C)return void Ie(R);const t=["NotAllowedError","PermissionDeniedError","NotFoundError","DevicesNotFoundError","NotReadableError","TrackStartError"].includes(e?.name);me(t?I.Camera:I.Scan),de(!0)}),()=>{q.current&&q.current.getTracks().forEach(e=>e.stop())}},[w,v,Ne]),i(()=>{if(!Z||!te)return;const e=setInterval(()=>{Te(_,U)},500);return()=>clearInterval(e)},[Te,Z,te]);return console.log("Model ready:",Z,"Has error:",le,"Is scanning:",te,"showLoader",Q),i(()=>{const e=z(_e,$);Fe(e)},[_e]),i(()=>{Re(-1)},[]),e("div",{"data-face-scan-stage":Pe,children:e(j,{children:e(L,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:Q,hasError:le,errorType:ue,resetScanState:Ve,showGuideCard:ne,scanStage:Pe,videoLoading:oe,setVideoLoading:ce,videoError:ie,setVideoError:se,gender:ye,getButtonText:()=>te?p.reset:$e?p.start:p.loading,isScanning:te,startScan:Le,isModelLoaded:$e,onRetry:l},children:e(K,{webcamRef:_,canvasRef:U})})})})})};export{X as F};
2
- //# sourceMappingURL=FaceScan-VFLJ9h_T.js.map
@@ -1,2 +0,0 @@
1
- import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as r,useMemo as o,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,e as I,M as _,f as k,h as E,i as C,j as M,k as D,l as T,n as P,o as R,q as z,r as $,t as j,C as L,w as V,x as O,y as W}from"./Modal-BHfJVhRi.js";import{ArrowRight as A}from"lucide-react";import{Drawer as U}from"@mui/material";let B=null,q=!1;function J({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:h,shopDomain:f,isError:g,isSuccess:p}){const y=n(null),[S,b]=r(0),[w,v]=r(0),[x,F]=r(!1),[N,I]=r(!1),_=n(!1),k=n(null),E=n(null),C=n(S),M=n(w),D=n([]),T=n(""),P=n(0),R=n(!1),z=n(0),$="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),j=o(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=o(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),V=c((t,a,n,r,o,c)=>{const i=Date.now();if(!(i-z.current<4e3)){z.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:r,bodyInvalid:o,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),O=()=>{l.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:C.current,timestamp:(new Date).toISOString(),stageName:j[C.current]}),setTimeout(()=>{I(!0)},1500)},W=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(B)return B;if(q)for(;q;)if(await new Promise(e=>setTimeout(e,100)),B)return B;q=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-DejsYGYM.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const r=n.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return B=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{q=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return W(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),C.current=0,M.current=0,D.current=[]}})()}},[g,p]),i(()=>{C.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,r)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2||_.current)){_.current=!0;try{const o=n.current.videoWidth||720,c=n.current.videoHeight||1280;k.current||(k.current=document.createElement("canvas"),k.current.width=o,k.current.height=c);const i=k.current.getContext("2d");i&&i.drawImage(n.current,0,0,o,c);const s=await y.current.estimatePoses(i?k.current:n.current);if(s.length>0){const n=[],o=[];if(s[0].keypoints.forEach((e,t)=>{const a=e.score??0,r=[e.x??-1,e.y??-1,a];t<=10?n.push(r):o.push(r)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),r=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,r+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const c=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,r=n>.7||n<.3,o=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!r&&o&&s;case 1:return!r&&o&&l;case 2:return!r&&o&&d;default:return!1}})(C.current,n),i=o.slice(2).filter(e=>e[2]>.7).length<=2;D.current.push(c&&i),D.current.length>10&&D.current.shift();if(D.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=C.current+1;v(0),D.current=[],b(n),I(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:C.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:j[C.current]}),1===n&&h&&h(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),O()}})()}V(n,o,C.current,c,i,M.current)}}catch(e){console.error("Pose detection error:",e)}finally{_.current=!1}}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:C.current,timestamp:(new Date).toISOString(),stageName:j[C.current],consecutiveValid:M.current}),b(0),v(0),I(!1),C.current=0,M.current=0,D.current=[],T.current="",P.current=0,R.current=!1,E.current&&(speechSynthesis.cancel(),E.current=null)},enableVoiceCommands:()=>{if(R.current=!0,"undefined"!=typeof window&&$&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:O,isScanningActive:N}}function G({onRetry:a,loading:n}){const{translate:r}=s(h)||{},o=f();return e("div",{"data-testid":"face-scan-error-screen",className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:o?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl font-semibold text-gray-800 ",style:{fontFamily:o?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:o?.style?.heading?.headingFontSize||"32px",color:o?.style?.heading?.headingColor||"#000",fontWeight:o?.style?.heading?.headingFontWeight||"normal"},children:r?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:o?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:o?.style?.subheading?.subheadingFontSize||"14px",color:o?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:o?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(p.clickToResetScan)}),e(y,{"data-testid":"face-scan-retry-btn",disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(p.resetScan),postfixIcon:e(A,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:r,videoError:o,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{"data-testid":"face-scan-guide",className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),o&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!o&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{"data-testid":"face-scan-start-btn",disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const K=({webcamRef:n,canvasRef:r})=>{const{isError:o,isSuccess:c,showLoader:i,hasError:l,errorType:d,resetScanState:u,showGuideCard:h,scanStage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,getButtonText:v,isScanning:x,startScan:k,isModelLoaded:E,onRetry:C}=s(F),M=f();return o?e(G,{onRetry:C}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:M?.style?.base?.backgroundColor},children:e(N,{url:M?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:M?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:r,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&d===I.Camera&&e(_,{testId:"face-scan-camera-error-screen",config:M}),!i&&l&&d!==I.Camera&&e(G,{loading:i,onRetry:u}),h&&!l&&!i&&e(U,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},hideBackdrop:!0,children:e(H,{stage:g,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:b,gender:w,btnConfig:{label:v(),onClick:x?u:k,isDisabled:i||!E,icon:e(x?A:a,{})}})})]})},X=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:m,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},N=t.token??"",_=n(null),A=n(null),U=n(null),B=n([]),q=n(null),G=n(null),H=n(0),X=n(null),[Q,Y]=r(!1),[Z,ee]=r(!1),[te,ae]=r(!1),[ne,re]=r(!0),[oe,ce]=r(!1),[ie,se]=r(!1),[le,de]=r(!1),[ue,me]=r(null),[he,fe]=r(k()),ge=o(()=>E(N),[N]),{email:pe,gender:ye,deviceFocalLength:Se,shopDomain:be,callbackUrl:we,bodyScanId:ve}=x,[xe,Fe]=r([]),[Ne,Ie]=r(C),_e=o(()=>M(),[]),ke=D(xe),Ee=T(ke);P();const Ce=c(()=>{console.log("Stopping recording..."),cancelAnimationFrame(H.current),X.current&&(X.current.pause(),X.current.srcObject=null,X.current=null),U.current&&"recording"===U.current.state&&U.current.stop(),U.current=null},[]),Me=async()=>{if(h?.(),B.current){if(0===B.current.length)return console.error("No video data recorded"),me(I.Scan),de(!0),void Y(!1);f?.(),Y(!0);const e=new File(B.current,`${he}.${Ee}`,{type:ke}),t=G.current??await V(e),a=e.size,n=(a/1048576).toFixed(2),r=Math.round(a/1e4),o={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:B.current.length,estimated_duration_seconds:r},c=[{gender:ye},{face_scan_id:he},{focal_length:`${Se}`},{customer_store_url:be},{scan_type:"face_scan"},{body_scan_id:ve}];we&&c.push({callback_url:we}),O({eventName:`${be}/face_scan_meta_data`,faceScanId:he,email:pe,data:JSON.stringify({metaData:c,videoData:o})});const i=Date.now();O({eventName:`${be}/face_scan_upload_start`,faceScanId:he,email:pe,startTime:i});try{const t=await ge.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:he,email:pe,contentType:e.type}),a=Date.now();O({eventName:`${be}/face_scan_upload_complete`,faceScanId:he,email:pe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),ge.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"pre_open",type:"faceScan_recommendation",email:pe})},faceScanId:he,onOpen:()=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"open",type:"faceScan_recommendation",email:pe}),console.log("websocket connect open")},onError:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"error",type:"faceScan_recommendation",email:pe}),Oe(e)},onSuccess:e=>{W({eventName:`${be}/webSocket`,faceScanID:he,connection:"success",type:"faceScan_recommendation",email:pe}),We(e)},onClose:()=>{S?.(),console.log("websocket connect close"),W({eventName:`${be}/webSocket`,faceScanID:he,connection:"close",type:"faceScan_recommendation",email:pe})}})}catch(e){g?.(),Oe(e)}}},De=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,r=document.createElement("canvas"),o=r.getContext("2d");a>n?(r.width=n,r.height=a):(r.width=a,r.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play(),X.current=c;const i=()=>{a>n?(o?.save(),o?.translate(r.width,0),o?.rotate(Math.PI/2),o?.drawImage(c,0,0,n,a),o?.restore()):o?.drawImage(c,0,0,a,n),H.current=requestAnimationFrame(i)};H.current=requestAnimationFrame(i);const s=t.frameRate??10;G.current=s;const l=r.captureStream(s),d={videoBitsPerSecond:15e5};let u;xe.length>0&&(d.mimeType=xe[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),me(I.Scan),de(!0),void Y(!1)}B.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&B.current&&B.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",B?.current?.length),Me()},u.start(100),U.current=u,console.log("Recording started successfully (portrait normalized)")},[xe,Me]),{faceScanDetector:Te,scanStage:Pe,setScanStage:Re,resetScan:ze,isModelLoaded:$e,startScanSequence:je}=J({faceScanId:he,shopDomain:be,isError:w,isSuccess:v,onScanComplete:()=>{Ce()},onModelReady:()=>{ee(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),De()}}),Le=c(()=>{$e&&(m?.(),Re(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{ae(!0),setTimeout(()=>{je()},200)},200))},[Re,ae,je,$e,m]),Ve=c(()=>{ae(!1),re(!0),Ce(),ze(),l?.(),B.current=[],G.current=null,U.current&&(U.current=null),de(!1),me(null),Re(-1),fe(k()),_.current&&q.current&&(_.current.srcObject=q.current,console.log("Camera stream restored after reset"))},[Re,ae,re,Ce,ze,fe]),Oe=e=>{console.log(e,"ws error"),s?.(e),me(I.Scan),de(!0),Y(!1),re(!1),O({eventName:`${be}/faceScan`,faceScanId:he,status:"failed",email:pe,data:JSON.stringify(e)})},We=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&O({eventName:`${be}/faceScan_success/intermediate`,faceScanId:he,status:"success",email:pe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Ne}).then(e=>{q.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{if(console.error("Error accessing webcam:",e),Ne===C)return void Ie(R);const t=["NotAllowedError","PermissionDeniedError","NotFoundError","DevicesNotFoundError","NotReadableError","TrackStartError"].includes(e?.name);me(t?I.Camera:I.Scan),de(!0)}),()=>{q.current&&q.current.getTracks().forEach(e=>e.stop())}},[w,v,Ne]),i(()=>{if(!Z||!te)return;const e=setInterval(()=>{Te(_,A)},500);return()=>clearInterval(e)},[Te,Z,te]);return console.log("Model ready:",Z,"Has error:",le,"Is scanning:",te,"showLoader",Q),i(()=>{const e=z(_e,$);Fe(e)},[_e]),i(()=>{Re(-1)},[]),e("div",{"data-face-scan-stage":Pe,children:e(j,{children:e(L,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:Q,hasError:le,errorType:ue,resetScanState:Ve,showGuideCard:ne,scanStage:Pe,videoLoading:oe,setVideoLoading:ce,videoError:ie,setVideoError:se,gender:ye,getButtonText:()=>te?p.reset:$e?p.start:p.loading,isScanning:te,startScan:Le,isModelLoaded:$e,onRetry:l},children:e(K,{webcamRef:_,canvasRef:A})})})})})};export{X as F};
2
- //# sourceMappingURL=FaceScan-iUXyDuza.js.map