@nuralogix.ai/web-measurement-embedded-app 0.1.0-alpha.9 → 0.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -86
- package/dist/app.css +66 -52
- package/dist/app.mjs +99 -89
- package/dist/assets/extraction/extraction_wasm_0.1.0-beta.1.json +1 -0
- package/dist/assets/extraction_worker_0.1.0-beta.1_js.json +1 -0
- package/dist/assets/facetracker_worker_0.1.0-beta.1_js.json +1 -0
- package/dist/assets/models/detectorModel_bin.json +1 -0
- package/dist/assets/models/detectorModel_json.json +1 -0
- package/dist/assets/models/landmarkModel_bin.json +1 -0
- package/dist/assets/models/landmarkModel_json.json +1 -0
- package/dist/language/strings.de.json +9 -12
- package/dist/language/strings.en.json +14 -27
- package/dist/language/strings.es.json +9 -12
- package/dist/language/strings.fr.json +7 -24
- package/dist/language/strings.it.json +11 -14
- package/dist/language/strings.ja.json +10 -13
- package/dist/language/strings.pt-BR.json +25 -0
- package/dist/language/strings.pt.json +9 -12
- package/dist/language/strings.zh.json +25 -0
- package/dist/stylex.css +30 -18
- package/lib/index.d.ts +52 -6
- package/lib/index.mjs +739 -1
- package/package.json +4 -2
- package/dist/assets/extraction/extraction_wasm_0.1.0-alpha.25.json +0 -1
- package/dist/assets/extraction_worker_0.1.0-alpha.25_js.json +0 -1
- package/dist/assets/facetracker_worker_0.1.0-alpha.25_js.json +0 -1
- package/dist/assets/taskVision/model/face_landmarker.task +0 -0
- package/dist/assets/taskVision/wasm/vision_wasm_internal_js.json +0 -1
- package/dist/assets/taskVision/wasm/vision_wasm_internal_wasm.json +0 -1
- package/dist/assets/taskVision/wasm/vision_wasm_nosimd_internal_js.json +0 -1
- package/dist/assets/taskVision/wasm/vision_wasm_nosimd_internal_wasm.json +0 -1
- package/dist/language/strings.br.json +0 -28
- package/dist/language/strings.cn.json +0 -28
package/lib/index.mjs
CHANGED
|
@@ -1 +1,739 @@
|
|
|
1
|
-
const l={RESULTS:"results",ERROR:"error",APPEVENT:"appEvent",CANCELLED:"cancelled",LOGS:"logs"};var f=(e=>(e.measurement="Measurement",e.collector="Collector",e.camera="Camera",e.app="App",e))(f||{});const o={INFO:"INFO",WARN:"WARN",ERROR:"ERROR"},i={CAMERA_STARTED:"CAMERA_STARTED",APP_LOADED:"APP_LOADED",MEASUREMENT_STARTED:"MEASUREMENT_STARTED",MEASUREMENT_COMPLETED:"MEASUREMENT_COMPLETED",CAMERA_PERMISSION_GRANTED:"CAMERA_PERMISSION_GRANTED",INTERMEDIATE_RESULTS:"INTERMEDIATE_RESULTS",RESULTS_RECEIVED:"RESULTS_RECEIVED",MEASUREMENT_CANCELED:"MEASUREMENT_CANCELED",CONSTRAINT_VIOLATION:"CONSTRAINT_VIOLATION",PAGE_UNLOADED:"PAGE_UNLOADED",PAGE_VISIBILITY_CHANGE:"PAGE_VISIBILITY_CHANGE"},g={CAMERA_STARTED:{event:i.CAMERA_STARTED,level:o.INFO},APP_LOADED:{event:i.APP_LOADED,level:o.INFO},MEASUREMENT_STARTED:{event:i.MEASUREMENT_STARTED,level:o.INFO},MEASUREMENT_COMPLETED:{event:i.MEASUREMENT_COMPLETED,level:o.INFO},CAMERA_PERMISSION_GRANTED:{event:i.CAMERA_PERMISSION_GRANTED,level:o.INFO},INTERMEDIATE_RESULTS:{event:i.INTERMEDIATE_RESULTS,level:o.INFO},RESULTS_RECEIVED:{event:i.RESULTS_RECEIVED,level:o.INFO},MEASUREMENT_CANCELED:{event:i.MEASUREMENT_CANCELED,level:o.WARN},CONSTRAINT_VIOLATION:{event:i.CONSTRAINT_VIOLATION,level:o.ERROR},PAGE_UNLOADED:{event:i.PAGE_UNLOADED,level:o.INFO},PAGE_VISIBILITY_CHANGE:{event:i.PAGE_VISIBILITY_CHANGE,level:o.INFO}},_={DESTROY:"destroy",CANCEL:"cancel",SET_THEME:"setTheme",SET_LANGUAGE:"setLanguage",GET_LOGS:"getLogs"};var v=(e=>(e.CAMERA_PERMISSION_DENIED="CAMERA_PERMISSION_DENIED",e.WORKER_ERROR="WORKER_ERROR",e.PROFILE_INFO_NOT_SET="PROFILE_INFO_NOT_SET",e.NO_DEVICES_FOUND="NO_DEVICES_FOUND",e.PAGE_NOT_VISIBLE="PAGE_NOT_VISIBLE",e.CAMERA_START_FAILED="CAMERA_START_FAILED",e.MEASUREMENT_LOW_SNR="MEASUREMENT_LOW_SNR",e.COLLECTOR="COLLECTOR",e.WEBSOCKET_DISCONNECTED="WEBSOCKET_DISCONNECTED",e))(v||{}),u=e=>{throw TypeError(e)},M=(e,t,E)=>t.has(e)||u("Cannot "+E),n=(e,t,E)=>(M(e,t,"read from private field"),E?E.call(e):t.get(e)),O=(e,t,E)=>t.has(e)?u("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,E),F=(e,t,E,s)=>(M(e,t,"write to private field"),t.set(e,E),E),r,T,c,A;const C=class a{constructor(t){O(this,A),F(this,A,new Int32Array(t))}lock(){for(;;){if(Atomics.compareExchange(n(this,A),n(a,c),n(a,T),n(a,r))==n(a,T))return;Atomics.wait(n(this,A),n(a,c),n(a,r))}}unlock(){if(Atomics.compareExchange(n(this,A),n(a,c),n(a,r),n(a,T))!=n(a,r))throw new Error("Tried to unlock while not holding the mutex");Atomics.notify(n(this,A),n(a,c))}AsyncLock(t){const E=this;async function s(){for(;;){if(Atomics.compareExchange(n(E,A),n(a,c),n(a,T),n(a,r))==n(a,T)){t(),E.unlock();return}await Atomics.waitAsync(n(E,A),n(a,c),n(a,r)).value}}s()}};r=new WeakMap,T=new WeakMap,c=new WeakMap,A=new WeakMap,O(C,r,1),O(C,T,0),O(C,c,0);const B={SEX_NOT_PROVIDED:1,SEX_ASSIGNED_MALE_AT_BIRTH:2,SEX_ASSIGNED_FEMALE_AT_BIRTH:3,DIABETES_NONE:4,DIABETES_TYPE1:5,DIABETES_TYPE2:6,SMOKER_TRUE:0,SMOKER_FALSE:1,BLOOD_PRESSURE_MEDICATION_TRUE:1,BLOOD_PRESSURE_MEDICATION_FALSE:0},k=document.documentElement.style.overflow;class W{#e=document.createElement("div");#t=document.createElement("div");on={results:null,error:null,event:null};constructor(){this.#e.style.height="100%"}init(t){const{container:E,appPath:s,settings:R,profile:h,config:P,loadError:N,top:D=0,language:U,apiUrl:G="api.deepaffex.ai"}=t;this.#t=E,Object.assign(E.style,{position:"fixed",top:D,left:"0",width:"100vw",height:`calc(100vh - ${D})`}),document.body.appendChild(E);const I=E.attachShadow({mode:"open"});document.documentElement.style.overflow="hidden";const m="app",L=document.createElement("link");L.rel="stylesheet",L.href=`${s}/stylex.css`,I.appendChild(L);const p=document.createElement("link");p.rel="stylesheet",p.href=`${s}/${m}.css`,I.appendChild(p);const w=d=>{this.on.results&&this.on.results({...d.detail})},V=d=>{this.on.error&&this.on.error({...d.detail})},y=d=>{this.on.event&&this.on.event({...d.detail})};this.#e.addEventListener(l.RESULTS,w),this.#e.addEventListener(l.ERROR,V),this.#e.addEventListener(l.APPEVENT,y),I.appendChild(this.#e);const S=document.createElement("script");S.type="module",S.src=`${s}/${m}.mjs`,S.onload=()=>{import(S.src).then(d=>{d.app.init(this.#e,s,R,h,G,P,U)}).catch(()=>{N&&N("Failed to initialize Measurement Embedded React app")})},S.onerror=()=>{N&&N("Failed to load the measurement embedded app script")},I.appendChild(S)}destroy(){const t=new CustomEvent("measurement-embedded-app-action",{detail:{action:_.DESTROY,data:{}}});this.#e.dispatchEvent(t),document.documentElement.style.overflow=k,this.#t&&document.body.contains(this.#t)&&document.body.removeChild(this.#t)}setTheme(t){const E=new CustomEvent("measurement-embedded-app-action",{detail:{action:_.SET_THEME,data:{theme:t}}});this.#e.dispatchEvent(E)}setLanguage(t){const E=new CustomEvent("measurement-embedded-app-action",{detail:{action:_.SET_LANGUAGE,data:{language:t}}});this.#e.dispatchEvent(E)}async cancel(){return new Promise(t=>{const E=R=>{this.#e.removeEventListener(l.CANCELLED,E),t(R.detail.success)};this.#e.addEventListener(l.CANCELLED,E);const s=new CustomEvent("measurement-embedded-app-action",{detail:{action:_.CANCEL,data:{}}});this.#e.dispatchEvent(s)})}getLogs(){return new Promise(t=>{const E=R=>{this.#e.removeEventListener(l.LOGS,E),t(R.detail.logs)};this.#e.addEventListener(l.LOGS,E);const s=new CustomEvent("measurement-embedded-app-action",{detail:{action:_.GET_LOGS,data:{}}});this.#e.dispatchEvent(s)})}}export{v as ErrorCodes,g as appEvents,W as default,B as faceAttributeValue,l as measurementEmbeddedAppEvents};
|
|
1
|
+
var Nt="0.1.0-beta.2";const $={RESULTS:"results",ERROR:"error",APPEVENT:"appEvent",CANCELLED:"cancelled",LOGS:"logs"};var je=(t=>(t.measurement="Measurement",t.collector="Collector",t.camera="Camera",t.app="App",t))(je||{});const D={INFO:"INFO",WARN:"WARN",ERROR:"ERROR"},I={CAMERA_STARTED:"CAMERA_STARTED",APP_LOADED:"APP_LOADED",MEASUREMENT_STARTED:"MEASUREMENT_STARTED",MEASUREMENT_COMPLETED:"MEASUREMENT_COMPLETED",CAMERA_PERMISSION_GRANTED:"CAMERA_PERMISSION_GRANTED",INTERMEDIATE_RESULTS:"INTERMEDIATE_RESULTS",RESULTS_RECEIVED:"RESULTS_RECEIVED",MEASUREMENT_CANCELED:"MEASUREMENT_CANCELED",CONSTRAINT_VIOLATION:"CONSTRAINT_VIOLATION",PAGE_UNLOADED:"PAGE_UNLOADED",PAGE_VISIBILITY_CHANGE:"PAGE_VISIBILITY_CHANGE"},Lt={CAMERA_STARTED:{event:I.CAMERA_STARTED,level:D.INFO},APP_LOADED:{event:I.APP_LOADED,level:D.INFO},MEASUREMENT_STARTED:{event:I.MEASUREMENT_STARTED,level:D.INFO},MEASUREMENT_COMPLETED:{event:I.MEASUREMENT_COMPLETED,level:D.INFO},CAMERA_PERMISSION_GRANTED:{event:I.CAMERA_PERMISSION_GRANTED,level:D.INFO},INTERMEDIATE_RESULTS:{event:I.INTERMEDIATE_RESULTS,level:D.INFO},RESULTS_RECEIVED:{event:I.RESULTS_RECEIVED,level:D.INFO},MEASUREMENT_CANCELED:{event:I.MEASUREMENT_CANCELED,level:D.WARN},CONSTRAINT_VIOLATION:{event:I.CONSTRAINT_VIOLATION,level:D.ERROR},PAGE_UNLOADED:{event:I.PAGE_UNLOADED,level:D.INFO},PAGE_VISIBILITY_CHANGE:{event:I.PAGE_VISIBILITY_CHANGE,level:D.INFO}},re={DESTROY:"destroy",CANCEL:"cancel",SET_THEME:"setTheme",SET_LANGUAGE:"setLanguage",GET_LOGS:"getLogs"};var Ye=(t=>(t.CAMERA_PERMISSION_DENIED="CAMERA_PERMISSION_DENIED",t.WORKER_ERROR="WORKER_ERROR",t.PROFILE_INFO_NOT_SET="PROFILE_INFO_NOT_SET",t.NO_DEVICES_FOUND="NO_DEVICES_FOUND",t.PAGE_NOT_VISIBLE="PAGE_NOT_VISIBLE",t.CAMERA_START_FAILED="CAMERA_START_FAILED",t.MEASUREMENT_LOW_SNR="MEASUREMENT_LOW_SNR",t.COLLECTOR="COLLECTOR",t.WEBSOCKET_DISCONNECTED="WEBSOCKET_DISCONNECTED",t))(Ye||{}),Je="0.1.0-beta.1",J=(t=>(t.DELETE="DELETE",t.GET="GET",t.PATCH="PATCH",t.POST="POST",t.PUT="PUT",t.CONNECT="CONNECT",t))(J||{}),V=(t=>(t.ON_BEFORE_REST_CALL_ERROR="ON_BEFORE_REST_CALL_ERROR",t))(V||{});const Xe=typeof DedicatedWorkerGlobalScope<"u",be=async({baseUrl:t,urlFragment:e,method:i,headers:r,data:c},d)=>{const n=`${t}/${e}`;let a={Code:"",Message:""};try{const u=await fetch(n,{method:i,cache:"no-store",credentials:"include",headers:r,...c!=null&&{body:JSON.stringify(c)}}),h=u.headers.get("content-type"),p=u.status.toString();a={Code:"UNSUPPORTED_RESPONSE_CONTENT_TYPE",Message:"UNSUPPORTED_RESPONSE_CONTENT_TYPE"},p==="503"&&(a={Code:"SERVICE_UNAVAILABLE",Message:"Service unavailable"}),p==="429"&&(a={Code:"TOO_MANY_REQUESTS",Message:"Too many requests"}),h!=null&&(h.startsWith("application/json;")&&(a=await u.json()),h.startsWith("text/plain;")&&(a={data:await u.text()}));let _=u.headers;if(Xe){const R={};u.headers.forEach((k,L)=>{R[L]=k}),_=R}try{d(p,p==="200"?void 0:a)}catch(R){console.error("Error running onAfterRESTCall callback",R)}return{status:p,headers:_,body:a}}catch(u){return u instanceof SyntaxError?a={Code:"SYNTAX_ERROR",Message:"SYNTAX_ERROR"}:a={Code:"UNEXPECTED_ERROR",Message:"UNEXPECTED_ERROR"},{status:"UNKNOWN",headers:Xe?{}:new Headers,body:a}}},_e=()=>new Headers({"Content-Type":"application/json"});var Dt=Object.defineProperty,It=(t,e,i)=>e in t?Dt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,xt=(t,e,i)=>It(t,e+"",i);class Fe{constructor(e){xt(this,"parent"),this.parent=e}async onBeforeRESTCall(){try{return this.parent.onBeforeRESTCall(),{Code:"SUCCESS",Message:"SUCCESS"}}catch{return{Code:V.ON_BEFORE_REST_CALL_ERROR,Message:V.ON_BEFORE_REST_CALL_ERROR}}}getDefaults(e){return{baseUrl:JSON.parse(this.parent.getUrl()).http.slice(0,-1),method:J[e],headers:_e()}}getHeaderWithDeviceToken(){const e=_e();return e.set("Authorization",`Bearer ${this.parent.getSession().deviceToken}`),e}getHeaderWithUserToken(){const e=_e();return e.set("Authorization",`Bearer ${this.parent.getSession().userToken}`),e}getHeaderWithSessionEnabled(){const e=_e();return e.set("x-nura-session","true"),e}}class Ft extends Fe{async create(e,i){const{Code:r,Message:c}=await this.onBeforeRESTCall();if(r===V.ON_BEFORE_REST_CALL_ERROR)return{status:r,body:{Code:r,Message:c},headers:new Headers};const{status:d,body:n,headers:a}=await be({...this.getDefaults(J.POST),headers:i==="device"?this.getHeaderWithDeviceToken():this.getHeaderWithUserToken(),urlFragment:"measurements",data:e},this.parent.onAfterRESTCall);return d==="200"&&this.parent.setSession({lastMeasurementId:n.ID}),{status:d,body:n,headers:a}}}class Mt extends Fe{async retrieveSdkConfigData(e,i){const{Code:r,Message:c}=await this.onBeforeRESTCall();if(r===V.ON_BEFORE_REST_CALL_ERROR)return{status:r,body:{Code:r,Message:c},headers:new Headers};const{status:d,body:n,headers:a}=await be({...this.getDefaults(J.POST),headers:i==="device"?this.getHeaderWithDeviceToken():this.getHeaderWithUserToken(),urlFragment:"studies/sdkconfig",data:e},this.parent.onAfterRESTCall);return d==="200"&&this.parent.setSession({studyCfgData:n.ConfigFile,studyCfgHash:n.MD5Hash}),{status:d,body:n,headers:a}}}class Pt extends Fe{async renew(e,i){const{Code:r,Message:c}=await this.onBeforeRESTCall();if(r===V.ON_BEFORE_REST_CALL_ERROR)return{status:r,body:{Code:r,Message:c},headers:new Headers};const{status:d,body:n,headers:a}=await be({...this.getDefaults(J.POST),headers:i==="device"?this.getHeaderWithDeviceToken():this.getHeaderWithUserToken(),urlFragment:"auths/renew",data:e},this.parent.onAfterRESTCall);if(d==="200"){const u=n.Token,h=n.RefreshToken,p={...i==="user"&&{userToken:u,userRefreshToken:h},...i==="device"&&{deviceToken:u,deviceRefreshToken:h}};this.parent.setSession(p)}return{status:d,body:n,headers:a}}async validate(e){const{Code:i,Message:r}=await this.onBeforeRESTCall();return i===V.ON_BEFORE_REST_CALL_ERROR?{status:i,body:{Code:i,Message:r},headers:new Headers}:await be({...this.getDefaults(J.GET),headers:e==="device"?this.getHeaderWithDeviceToken():this.getHeaderWithUserToken(),urlFragment:"auth/v1/validate"},this.parent.onAfterRESTCall)}}var Wt=Object.defineProperty,ze=t=>{throw TypeError(t)},Ut=(t,e,i)=>e in t?Wt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,Me=(t,e,i)=>Ut(t,typeof e!="symbol"?e+"":e,i),qe=(t,e,i)=>e.has(t)||ze("Cannot "+i),Pe=(t,e,i)=>(qe(t,e,"read from private field"),i?i.call(t):e.get(t)),Ze=(t,e,i)=>e.has(t)?ze("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,i),ge=(t,e,i,r)=>(qe(t,e,"write to private field"),e.set(t,i),i),ne,X;class $t{constructor(e){Ze(this,ne,{http:new URL("https://api.deepaffex.ai")}),Ze(this,X),Me(this,"onBeforeRESTCall"),Me(this,"onAfterRESTCall"),Me(this,"http"),ge(this,X,{deviceToken:"",deviceRefreshToken:"",userToken:"",userRefreshToken:"",deviceId:"",roleId:"",userId:"",selectedStudy:"",lastMeasurementId:"",studyCfgHash:"",studyCfgData:""}),this.http={measurements:new Ft(this),studies:new Mt(this),auths:new Pt(this)},this.onBeforeRESTCall=e?.onBeforeRESTCall?e.onBeforeRESTCall:()=>{},this.onAfterRESTCall=e?.onAfterRESTCall?e.onAfterRESTCall:()=>{},e?.url!=null&&ge(this,ne,e.url)}static new(e){return new this(e??void 0)}getUrl(){return JSON.stringify(Pe(this,ne))}setUrl(e){ge(this,ne,{http:new URL(e)})}getSession(){return Pe(this,X)}setSession(e){const i=["deviceToken","deviceRefreshToken","userToken","userRefreshToken","deviceId","userId","roleId","selectedStudy","lastMeasurementId","studyCfgHash","studyCfgData"];Object.keys(e).every(d=>i.includes(d)&&typeof e[d]=="string")&&ge(this,X,{...Pe(this,X),...e})}}ne=new WeakMap,X=new WeakMap;const Bt=t=>$t.new(t);var Gt=Object.defineProperty,Qe=t=>{throw TypeError(t)},Ht=(t,e,i)=>e in t?Gt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,Vt=(t,e,i)=>Ht(t,e+"",i),Kt=(t,e,i)=>e.has(t)||Qe("Cannot "+i),jt=(t,e,i)=>e.has(t)?Qe("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,i),We=(t,e,i)=>(Kt(t,e,"access private method"),i),oe,Ue,et;let tt=t=>new Int8Array(t);class Yt extends EventTarget{constructor(){super(...arguments),jt(this,oe),Vt(this,"canDecompress",!1)}static init(){return new this}dispatch(e,i){this.dispatchEvent(new CustomEvent(e,{detail:i}))}getBytesDownloadedEvent(e,i,r,c){return new CustomEvent("bytesDownloaded",{detail:{bytes:e,uncompressedSize:i,url:r,done:c}})}getBytesDownloadErrorEvent(e,i){return new CustomEvent("downloadedError",{detail:{url:e,error:i}})}decompressBrotli(e){const i=atob(e),r=new Uint8Array(i.length);for(let n=0;n<i.length;n++)r[n]=i.charCodeAt(n);const c=new Int8Array(r.length);for(let n=0;n<r.length;n++)c[n]=r[n]>=128?r[n]-256:r[n];return tt(c).buffer}async fetchAsset(e,i,r,c,d){const n=i+r,a=e.find(h=>h.file===r).uncompressedSize,u=(h,p,_,R)=>We(this,oe,Ue).call(this,this.getBytesDownloadedEvent(h,p,_,R));try{const p=(await fetch(n)).body?.getReader();if(!p)throw new Error("Failed to get reader from response body.");let _=0;const R=new ReadableStream({async start(L){await W();async function W(){const{done:G,value:M}=await p.read();if(G){L.close(),u(_,a,n,!0);return}M&&(L.enqueue(M),_+=M.length,u(_,a,n,!1)),await W()}}}),k=new Response(R);if(c){const L=await k.json(),{base64EncodedValue:W}=L;if(d==="gzip"){await We(this,oe,et).call(this,W);return}return this.decompressBrotli(W)}else return await k.arrayBuffer()}catch(h){We(this,oe,Ue).call(this,this.getBytesDownloadErrorEvent(n,h))}}}oe=new WeakSet,Ue=function(t){this.dispatchEvent(t)},et=async function(t){const e=Uint8Array.from(atob(t),h=>h.charCodeAt(0)),r=new Blob([e]).stream().pipeThrough(new DecompressionStream("gzip")),c=await new Response(r).arrayBuffer(),d=new TextDecoder().decode(new Uint8Array(c)),n=new Blob([d],{type:"application/javascript"}),a=URL.createObjectURL(n);tt=(await import(a)).BrotliDecode,this.canDecompress=!0,URL.revokeObjectURL(a)};var Jt=Object.defineProperty,Xt=(t,e,i)=>e in t?Jt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,it=(t,e,i)=>Xt(t,typeof e!="symbol"?e+"":e,i);class zt{constructor(){it(this,"version",{webSDK:"",extractionLib:{version:"",sdkId:""},faceTracker:""}),it(this,"debugLogs",[])}appendLog(e){this.debugLogs.push(e)}transferLogs(){}generateHTMLTable(){return`
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Anura Web Core SDK - Logs</title>
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<style>
|
|
8
|
+
body {
|
|
9
|
+
font-family: Arial, sans-serif;
|
|
10
|
+
margin: 20px;
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
}
|
|
14
|
+
.header { display: flex; justify-content: space-between;}
|
|
15
|
+
.box { padding: 20px; margin-bottom: 20px; border-radius: 5px; border: 1px solid #ccc; }
|
|
16
|
+
svg {
|
|
17
|
+
display: block;
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: auto;
|
|
20
|
+
margin: 20px 0;
|
|
21
|
+
}
|
|
22
|
+
.tooltip {
|
|
23
|
+
position: absolute;
|
|
24
|
+
background-color: rgba(0, 0, 0, 0.7);
|
|
25
|
+
color: white;
|
|
26
|
+
padding: 5px;
|
|
27
|
+
border-radius: 5px;
|
|
28
|
+
display: none;
|
|
29
|
+
}
|
|
30
|
+
.axis-label {
|
|
31
|
+
font-size: 14px;
|
|
32
|
+
text-anchor: middle;
|
|
33
|
+
}
|
|
34
|
+
label {
|
|
35
|
+
font-size: 16px;
|
|
36
|
+
margin-bottom: 10px;
|
|
37
|
+
}
|
|
38
|
+
select {
|
|
39
|
+
font-size: 16px;
|
|
40
|
+
padding: 8px 12px;
|
|
41
|
+
border: 1px solid #ccc;
|
|
42
|
+
border-radius: 4px;
|
|
43
|
+
background-color: #f9f9f9;
|
|
44
|
+
outline: none;
|
|
45
|
+
transition: all 0.3s ease;
|
|
46
|
+
width: 320px;
|
|
47
|
+
}
|
|
48
|
+
select:hover {
|
|
49
|
+
border-color: #888;
|
|
50
|
+
}
|
|
51
|
+
select:focus {
|
|
52
|
+
border-color: #555;
|
|
53
|
+
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
|
|
54
|
+
}
|
|
55
|
+
#download {width: 200px;}
|
|
56
|
+
table {width: 100%; max-width: 100%; table-layout: fixed; border-collapse: collapse;}
|
|
57
|
+
th, td {border: 1px solid #ccc; padding: 8px; text-align: left; word-wrap: break-word;}
|
|
58
|
+
td pre {
|
|
59
|
+
margin: 0;
|
|
60
|
+
white-space: pre-wrap; /* Preserve whitespace and line breaks */
|
|
61
|
+
}
|
|
62
|
+
.json-key {
|
|
63
|
+
color: blue;
|
|
64
|
+
}
|
|
65
|
+
th {background-color: #f2f2f2;}
|
|
66
|
+
.odd-row { background-color: #f9f9f9; } /* Light grey for odd rows */
|
|
67
|
+
.even-row { background-color: #ffffff; } /* White for even rows */
|
|
68
|
+
.col-60 { width: 60px }
|
|
69
|
+
.col-200 { width: 200px }
|
|
70
|
+
.col-230 { width: 230px }
|
|
71
|
+
.col-350 { width: 350px }
|
|
72
|
+
.chart-container { width: 100%; margin-top: 40px;}
|
|
73
|
+
</style>
|
|
74
|
+
</head>
|
|
75
|
+
<body>
|
|
76
|
+
<div class="header">
|
|
77
|
+
<div>
|
|
78
|
+
<h1>Anura Web Core SDK</h1>
|
|
79
|
+
</div>
|
|
80
|
+
<div>
|
|
81
|
+
<button type="button" id="download">Download</button>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
<br><br>
|
|
85
|
+
<div id="info-table"></div>
|
|
86
|
+
<br><br>
|
|
87
|
+
<h4>Network Delays</h4>
|
|
88
|
+
<div id="network-table"></div>
|
|
89
|
+
<br><br>
|
|
90
|
+
<div class="chart-container">
|
|
91
|
+
<div class="box">
|
|
92
|
+
<h2>Instantaneous video playback FPS between consecutive frames</h2>
|
|
93
|
+
FPS = 1 / time difference between consecutive frames.
|
|
94
|
+
<br><br>
|
|
95
|
+
The time difference is the gap between the
|
|
96
|
+
<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement/requestVideoFrameCallback#capturetime" target="_blank" rel="noopener noreferrer">capturetime</a> values of two consecutive frames.
|
|
97
|
+
This method will provide a better representation of the FPS at any given point in time,
|
|
98
|
+
as it accounts for variations in frame rate over time (e.g., if the video slows down or
|
|
99
|
+
experiences drops). It is generally more useful for tracking real-time performance.
|
|
100
|
+
<svg id="fps-chart" viewBox="0 0 800 400"></svg>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="box">
|
|
103
|
+
<h2>Tracking Time per Frame by Face Tracker Worker</h2>
|
|
104
|
+
To track every frame in a video with a playback speed of 30 frames per second (FPS), the face tracking time
|
|
105
|
+
per frame should be less than or equal to the time allocated for each frame, which is:
|
|
106
|
+
<br><br>
|
|
107
|
+
Frame time= 1 / FPS = 1 / 30 \u2248 0.0333 seconds or 33.3 milliseconds.
|
|
108
|
+
<br><br>
|
|
109
|
+
To ensure smooth and consistent face tracking, the face tracking process should ideally complete in less
|
|
110
|
+
than 33.3 milliseconds per frame.
|
|
111
|
+
<svg id="ft-tracking-time-chart" viewBox="0 0 800 400"></svg>
|
|
112
|
+
</div>
|
|
113
|
+
<div class="box">
|
|
114
|
+
<h2>Face tracking Throughput Over Time</h2>
|
|
115
|
+
This chart will help you monitor the system's face tracking capacity over time. It displays the number of frames tracked per unit time (1 second).
|
|
116
|
+
<svg id="ft-throughput-chart" viewBox="0 0 800 400"></svg>
|
|
117
|
+
</div>
|
|
118
|
+
<div class="box">
|
|
119
|
+
<h2>Frame Latency Per Frame</h2>
|
|
120
|
+
This chart shows total processing delay per frame, including face tracking time and DFX processing time.
|
|
121
|
+
<br>
|
|
122
|
+
<br>
|
|
123
|
+
<div id="total-latency"></div>
|
|
124
|
+
<svg id="frame-latency-chart" viewBox="0 0 800 400"></svg>
|
|
125
|
+
</div>
|
|
126
|
+
<div class="tooltip" id="tooltip"></div>
|
|
127
|
+
</div>
|
|
128
|
+
<label for="thread-filter">Filter by Thread:</label>
|
|
129
|
+
<select id="thread-filter">
|
|
130
|
+
<option value="none">None</option>
|
|
131
|
+
${[...new Set(this.debugLogs.map(r=>r.thread))].map(r=>`<option value="${r}">${r}</option>`).join("")}
|
|
132
|
+
</select>
|
|
133
|
+
<br>
|
|
134
|
+
<br>
|
|
135
|
+
<div id="logs-table"></div>
|
|
136
|
+
<script>
|
|
137
|
+
const logs = ${JSON.stringify(this.debugLogs,null,2)};
|
|
138
|
+
const logsTable = document.getElementById('logs-table');
|
|
139
|
+
const infoTable = document.getElementById('info-table');
|
|
140
|
+
const networkTable = document.getElementById('network-table');
|
|
141
|
+
const filter = document.getElementById('thread-filter');
|
|
142
|
+
const fpsChart = document.getElementById('fps-chart');
|
|
143
|
+
const ftTrackingTimeChart = document.getElementById('ft-tracking-time-chart');
|
|
144
|
+
const ftThroughputChart = document.getElementById('ft-throughput-chart');
|
|
145
|
+
const frameLatencyChart = document.getElementById('frame-latency-chart');
|
|
146
|
+
const totalLatency = document.getElementById('total-latency');
|
|
147
|
+
const tooltip = document.getElementById('tooltip');
|
|
148
|
+
|
|
149
|
+
const frameNumCaptureTimeArr = logs.filter(
|
|
150
|
+
item => item.category === 'SDK' && "captureTime" in item.meta && "presentedFrames" in item.meta
|
|
151
|
+
).map((item) => item.meta);
|
|
152
|
+
|
|
153
|
+
const ftResolution = logs.find(
|
|
154
|
+
item => item.category === 'SDK' && "ftWidth" in item.meta && "ftHeight" in item.meta
|
|
155
|
+
).meta;
|
|
156
|
+
|
|
157
|
+
const frameMetrics = logs.find(
|
|
158
|
+
item => item.category === 'SDK' &&
|
|
159
|
+
"numOfFramesPresented" in item.meta &&
|
|
160
|
+
"warmupFrameNumber" in item.meta &&
|
|
161
|
+
"numOftrackedVideoFrames" in item.meta
|
|
162
|
+
).meta;
|
|
163
|
+
const { numOfFramesPresented, warmupFrameNumber, numOftrackedVideoFrames } = frameMetrics;
|
|
164
|
+
|
|
165
|
+
const numOfFramesPresentedSinceWarmUp =
|
|
166
|
+
numOfFramesPresented - warmupFrameNumber;
|
|
167
|
+
const numOfDroppedFrames = Math.max(
|
|
168
|
+
numOfFramesPresented -
|
|
169
|
+
numOftrackedVideoFrames -
|
|
170
|
+
warmupFrameNumber,
|
|
171
|
+
0
|
|
172
|
+
);
|
|
173
|
+
const percentageOfDroppedFrames =
|
|
174
|
+
numOfDroppedFrames === 0 || numOfFramesPresented === warmupFrameNumber
|
|
175
|
+
? 0
|
|
176
|
+
: (numOfDroppedFrames * 100) /
|
|
177
|
+
(numOfFramesPresented - warmupFrameNumber);
|
|
178
|
+
|
|
179
|
+
const wsCallDelayArr = logs.filter(
|
|
180
|
+
item => item.category === 'WebSocket' && "delay" in item.meta && "actionId" in item.meta
|
|
181
|
+
).map(item => ({ protocol: "WebSocket", timestamp: item.timestamp.slice(1, -1), ...item.meta }));
|
|
182
|
+
|
|
183
|
+
const restCallDelayArr = logs.filter(
|
|
184
|
+
item => item.category === 'DFX API client' && "delay" in item.meta && "actionId" in item.meta
|
|
185
|
+
).map(item => ({ protocol: "HTTP", timestamp: item.timestamp.slice(1, -1), ...item.meta }));
|
|
186
|
+
|
|
187
|
+
const measurement = restCallDelayArr.find(item => "measurementId" in item);
|
|
188
|
+
const measurementId = measurement ? measurement.measurementId : 'N/A';
|
|
189
|
+
|
|
190
|
+
const ftTrackingTimeArr = logs.filter(
|
|
191
|
+
item => item.category === 'MediaPipe'
|
|
192
|
+
&& item.meta
|
|
193
|
+
&& "frameNumber" in item.meta
|
|
194
|
+
&& "frameTimestamp" in item.meta
|
|
195
|
+
&& "frameTrackingTime" in item.meta
|
|
196
|
+
).map(item => ({thread: item.thread, ...item.meta})
|
|
197
|
+
).sort((a, b) => a.frameNumber - b.frameNumber);
|
|
198
|
+
|
|
199
|
+
const ftChartData = ftTrackingTimeArr.slice(4); // remove the first 4 elements (warm-up frames) from the array
|
|
200
|
+
|
|
201
|
+
const frameThroughput = calculateThroughput(ftChartData, 1000);
|
|
202
|
+
|
|
203
|
+
const frameLatencyArr = logs.filter(
|
|
204
|
+
item => item.category === 'DFX Worker'
|
|
205
|
+
&& item.meta
|
|
206
|
+
&& "frameNumber" in item.meta
|
|
207
|
+
&& "frameTrackingTime" in item.meta
|
|
208
|
+
&& "dfxProcessingTime" in item.meta)
|
|
209
|
+
.map(item => ({overall: item.meta.frameTrackingTime + item.meta.dfxProcessingTime, ...item.meta}))
|
|
210
|
+
.sort((a, b) => a.frameNumber - b.frameNumber);
|
|
211
|
+
|
|
212
|
+
const latency = frameLatencyArr.reduce((sum, frame) => sum + frame.overall, 0);
|
|
213
|
+
totalLatency.innerHTML = \`Total Frames Processed: <strong>\${frameLatencyArr.length}</strong><br><br>Total Latency: <strong>\${(latency / 1000).toFixed(2)} seconds</strong>\`;
|
|
214
|
+
|
|
215
|
+
const getCategoryColor = (category) => {
|
|
216
|
+
switch (category) {
|
|
217
|
+
case 'Before REST call event':
|
|
218
|
+
return 'red';
|
|
219
|
+
case 'After REST call event':
|
|
220
|
+
return 'orange';
|
|
221
|
+
case 'MediaPipe':
|
|
222
|
+
return 'green';
|
|
223
|
+
case 'DFX Extraction lib WASM':
|
|
224
|
+
return 'violet';
|
|
225
|
+
case 'DFX API client':
|
|
226
|
+
return '#d34110';
|
|
227
|
+
case 'WebSocket':
|
|
228
|
+
return '#d34110';
|
|
229
|
+
case 'SDK':
|
|
230
|
+
return '#d34110';
|
|
231
|
+
case 'DFX Worker':
|
|
232
|
+
return '#ad4393';
|
|
233
|
+
default:
|
|
234
|
+
return 'black';
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// Function to escape HTML special characters
|
|
239
|
+
function escapeHTML(html) {
|
|
240
|
+
const div = document.createElement('div');
|
|
241
|
+
div.textContent = html;
|
|
242
|
+
return div.innerHTML;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function formatJsonWithKeyStyling(jsonString) {
|
|
246
|
+
return jsonString.replace(/"(.*?)":/g, (match, p1) => \`<span class="json-key">"\${p1}"</span>:\`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Function to find and extract the JSON string
|
|
250
|
+
function extractJson(str) {
|
|
251
|
+
let jsonStart = str.indexOf('{');
|
|
252
|
+
if (jsonStart === -1) return null; // No JSON found
|
|
253
|
+
|
|
254
|
+
let stack = [];
|
|
255
|
+
let jsonEnd = jsonStart;
|
|
256
|
+
|
|
257
|
+
for (let i = jsonStart; i < str.length; i++) {
|
|
258
|
+
if (str[i] === '{') stack.push('{');
|
|
259
|
+
if (str[i] === '}') stack.pop();
|
|
260
|
+
|
|
261
|
+
if (stack.length === 0) {
|
|
262
|
+
jsonEnd = i + 1;
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return str.slice(jsonStart, jsonEnd);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Function to format and display the string
|
|
271
|
+
function formatString(str) {
|
|
272
|
+
const jsonPart = extractJson(str);
|
|
273
|
+
let formattedString = escapeHTML(str);
|
|
274
|
+
|
|
275
|
+
if (jsonPart) {
|
|
276
|
+
try {
|
|
277
|
+
const jsonObject = JSON.parse(jsonPart);
|
|
278
|
+
const formattedJson = JSON.stringify(jsonObject, null, 4);
|
|
279
|
+
const styledJson = formatJsonWithKeyStyling(formattedJson);
|
|
280
|
+
|
|
281
|
+
// Replace the JSON part with formatted JSON
|
|
282
|
+
formattedString = str.replace(jsonPart, \`<pre>\${styledJson}</pre>\`);
|
|
283
|
+
} catch (e) {
|
|
284
|
+
console.error('Invalid JSON:', e);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return formattedString;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function renderInfoTable(data) {
|
|
291
|
+
const tableHtml = \`
|
|
292
|
+
<table>
|
|
293
|
+
<thead>
|
|
294
|
+
<tr>
|
|
295
|
+
<th class="col-350">Title</th>
|
|
296
|
+
<th>Description</th>
|
|
297
|
+
</tr>
|
|
298
|
+
</thead>
|
|
299
|
+
<tbody>
|
|
300
|
+
\${data.map((item, index) => {
|
|
301
|
+
const rowClass = index % 2 === 0 ? 'even-row' : 'odd-row';
|
|
302
|
+
const [title, description] = item;
|
|
303
|
+
return \`
|
|
304
|
+
<tr class="\${rowClass}">
|
|
305
|
+
<td class="col-350">\${title}</td>
|
|
306
|
+
<td>\${description}</td>
|
|
307
|
+
</tr>
|
|
308
|
+
\`;
|
|
309
|
+
}).join("")}
|
|
310
|
+
</tbody>
|
|
311
|
+
</table>
|
|
312
|
+
\`;
|
|
313
|
+
infoTable.innerHTML = tableHtml;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function renderNetworkTable(data) {
|
|
317
|
+
const tableHtml = \`
|
|
318
|
+
<table>
|
|
319
|
+
<thead>
|
|
320
|
+
<tr>
|
|
321
|
+
<th class="col-230">Timestamp</th>
|
|
322
|
+
<th class="col-200">Protocol</th>
|
|
323
|
+
<th class="col-200">Delay (ms)</th>
|
|
324
|
+
<th>Info</th>
|
|
325
|
+
</tr>
|
|
326
|
+
</thead>
|
|
327
|
+
<tbody>
|
|
328
|
+
\${data.map((item, index) => {
|
|
329
|
+
const rowClass = index % 2 === 0 ? 'even-row' : 'odd-row';
|
|
330
|
+
const { timestamp, protocol, delay, actionId, description } = item;
|
|
331
|
+
return \`
|
|
332
|
+
<tr class="\${rowClass}">
|
|
333
|
+
<td class="col-230">\${timestamp}</td>
|
|
334
|
+
<td class="col-200">\${protocol}</td>
|
|
335
|
+
<td class="col-200">\${delay.toFixed(2)}</td>
|
|
336
|
+
<td>\${description} - Action ID: \${actionId}</td>
|
|
337
|
+
</tr>
|
|
338
|
+
\`;
|
|
339
|
+
}).join("")}
|
|
340
|
+
</tbody>
|
|
341
|
+
</table>
|
|
342
|
+
\`;
|
|
343
|
+
networkTable.innerHTML = tableHtml;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function renderLogsTable(data) {
|
|
347
|
+
const tableHtml = \`
|
|
348
|
+
<table>
|
|
349
|
+
<thead>
|
|
350
|
+
<tr>
|
|
351
|
+
<th class="col-60">Index</th>
|
|
352
|
+
<th class="col-230">Timestamp</th>
|
|
353
|
+
<th class="col-230">Thread</th>
|
|
354
|
+
<th class="col-200">Category</th>
|
|
355
|
+
<th>Message</th>
|
|
356
|
+
</tr>
|
|
357
|
+
</thead>
|
|
358
|
+
<tbody>
|
|
359
|
+
\${data.map((item, index) => {
|
|
360
|
+
const rowClass = index % 2 === 0 ? 'even-row' : 'odd-row';
|
|
361
|
+
const categoryColor = getCategoryColor(item.category);
|
|
362
|
+
return \`
|
|
363
|
+
<tr class="\${rowClass}">
|
|
364
|
+
<td class="col-60">\${index + 1}</td>
|
|
365
|
+
<td class="col-230">\${item.timestamp.slice(1, -1)}</td>
|
|
366
|
+
<td class="col-230">\${item.thread}</td>
|
|
367
|
+
<td class="col-200" style="color: \${categoryColor};">\${item.category}</td>
|
|
368
|
+
<td>\${formatString(item.message)}</td>
|
|
369
|
+
</tr>
|
|
370
|
+
\`;
|
|
371
|
+
}).join("")}
|
|
372
|
+
</tbody>
|
|
373
|
+
</table>
|
|
374
|
+
\`;
|
|
375
|
+
logsTable.innerHTML = tableHtml;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Instantaneous FPS (between consecutive frames)
|
|
379
|
+
const instantaneousFrameRates = frameNumCaptureTimeArr.map((point, index) => {
|
|
380
|
+
if (index === 0) {
|
|
381
|
+
return { captureTime: point.captureTime, frameRate: 0 }; // No FPS for the first frame
|
|
382
|
+
} else {
|
|
383
|
+
const prevPoint = frameNumCaptureTimeArr[index - 1];
|
|
384
|
+
const timeDifference = point.captureTime - prevPoint.captureTime; // Time difference in seconds
|
|
385
|
+
const fps = timeDifference > 0 ? 1000 / timeDifference : 0; // Convert to FPS by multiplying by 1000
|
|
386
|
+
return { captureTime: point.captureTime, frameRate: fps };
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
function calculateThroughput(frameData, intervalMs = 1000) {
|
|
391
|
+
// Sort frame data by frameTimestamp
|
|
392
|
+
frameData.sort((a, b) => a.frameTimestamp - b.frameTimestamp);
|
|
393
|
+
|
|
394
|
+
// Find the time range
|
|
395
|
+
const startTime = frameData[0].frameTimestamp;
|
|
396
|
+
const endTime = frameData[frameData.length - 1].frameTimestamp;
|
|
397
|
+
|
|
398
|
+
// Group frames into time intervals
|
|
399
|
+
const throughputData = [];
|
|
400
|
+
for (let t = startTime; t <= endTime; t += intervalMs) {
|
|
401
|
+
const nextInterval = t + intervalMs;
|
|
402
|
+
const framesInInterval = frameData.filter(
|
|
403
|
+
frame => frame.frameTimestamp >= t && frame.frameTimestamp < nextInterval
|
|
404
|
+
).length;
|
|
405
|
+
|
|
406
|
+
throughputData.push({
|
|
407
|
+
time: t - startTime, // Time offset in milliseconds
|
|
408
|
+
throughput: framesInInterval,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return throughputData;
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
// Function to render the SVG chart
|
|
416
|
+
function renderChart(data, svg, xKey, yKey, xAxisLabel, yAxisLabel, lineColor, getCircleColor, xValuesCallback, tooltipCallback) {
|
|
417
|
+
const width = svg.getAttribute("viewBox").split(" ")[2];
|
|
418
|
+
const height = svg.getAttribute("viewBox").split(" ")[3];
|
|
419
|
+
const padding = 70; // Increase padding to provide more space for y-axis title
|
|
420
|
+
const titlePadding = 30; // Adjust this for more space between title and axis
|
|
421
|
+
|
|
422
|
+
const maxTime = Math.max(...data.map(d => d[xKey]));
|
|
423
|
+
const minTime = Math.min(...data.map(d => d[xKey]));
|
|
424
|
+
const maxFrameRate = Math.max(...data.map(d => d[yKey]));
|
|
425
|
+
const minFrameRate = Math.min(...data.map(d => d[yKey]));
|
|
426
|
+
|
|
427
|
+
const xScale = (value) => padding + (value / maxTime) * (width - 2 * padding);
|
|
428
|
+
const yScale = (value) => height - padding - (value / maxFrameRate) * (height - 2 * padding);
|
|
429
|
+
|
|
430
|
+
// Clear existing SVG content
|
|
431
|
+
svg.innerHTML = "";
|
|
432
|
+
|
|
433
|
+
// Draw grid lines
|
|
434
|
+
function drawGridLines() {
|
|
435
|
+
const gridLines = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
436
|
+
for (let i = 1; i <= 5; i++) {
|
|
437
|
+
const x = xScale(i * (maxTime / 5));
|
|
438
|
+
const y1 = padding;
|
|
439
|
+
const y2 = height - padding;
|
|
440
|
+
const gridLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
441
|
+
gridLine.setAttribute("x1", x);
|
|
442
|
+
gridLine.setAttribute("y1", y1);
|
|
443
|
+
gridLine.setAttribute("x2", x);
|
|
444
|
+
gridLine.setAttribute("y2", y2);
|
|
445
|
+
gridLine.setAttribute("stroke", "#ccc");
|
|
446
|
+
gridLine.setAttribute("stroke-width", 1);
|
|
447
|
+
gridLine.setAttribute("stroke-dasharray", "5,5");
|
|
448
|
+
gridLines.appendChild(gridLine);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
for (let i = 1; i <= 5; i++) {
|
|
452
|
+
const y = yScale(i * (maxFrameRate / 5));
|
|
453
|
+
const x1 = padding;
|
|
454
|
+
const x2 = width - padding;
|
|
455
|
+
const gridLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
456
|
+
gridLine.setAttribute("x1", x1);
|
|
457
|
+
gridLine.setAttribute("y1", y);
|
|
458
|
+
gridLine.setAttribute("x2", x2);
|
|
459
|
+
gridLine.setAttribute("y2", y);
|
|
460
|
+
gridLine.setAttribute("stroke", "#ccc");
|
|
461
|
+
gridLine.setAttribute("stroke-width", 1);
|
|
462
|
+
gridLine.setAttribute("stroke-dasharray", "5,5");
|
|
463
|
+
gridLines.appendChild(gridLine);
|
|
464
|
+
}
|
|
465
|
+
svg.appendChild(gridLines);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
drawGridLines();
|
|
469
|
+
|
|
470
|
+
// Draw axes
|
|
471
|
+
const xAxis = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
472
|
+
xAxis.setAttribute("x1", padding);
|
|
473
|
+
xAxis.setAttribute("y1", height - padding);
|
|
474
|
+
xAxis.setAttribute("x2", width - padding);
|
|
475
|
+
xAxis.setAttribute("y2", height - padding);
|
|
476
|
+
xAxis.setAttribute("stroke", "black");
|
|
477
|
+
svg.appendChild(xAxis);
|
|
478
|
+
|
|
479
|
+
const yAxis = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
480
|
+
yAxis.setAttribute("x1", padding);
|
|
481
|
+
yAxis.setAttribute("y1", padding);
|
|
482
|
+
yAxis.setAttribute("x2", padding);
|
|
483
|
+
yAxis.setAttribute("y2", height - padding);
|
|
484
|
+
yAxis.setAttribute("stroke", "black");
|
|
485
|
+
svg.appendChild(yAxis);
|
|
486
|
+
|
|
487
|
+
// Add axis labels
|
|
488
|
+
const xLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
489
|
+
xLabel.setAttribute("x", width / 2);
|
|
490
|
+
xLabel.setAttribute("y", height - padding / 3);
|
|
491
|
+
xLabel.setAttribute("class", "axis-label");
|
|
492
|
+
xLabel.textContent = xAxisLabel;
|
|
493
|
+
svg.appendChild(xLabel);
|
|
494
|
+
|
|
495
|
+
// Add axis label for Y (Frame Rate)
|
|
496
|
+
const yLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
497
|
+
yLabel.setAttribute("x", -height / 2); // Rotate around the center of the y-axis
|
|
498
|
+
yLabel.setAttribute("y", padding / 2 - 24); // Adjust vertical position to add space
|
|
499
|
+
yLabel.setAttribute("class", "axis-label");
|
|
500
|
+
yLabel.setAttribute("transform", "rotate(-90)");
|
|
501
|
+
yLabel.setAttribute("text-anchor", "middle");
|
|
502
|
+
yLabel.textContent = yAxisLabel;
|
|
503
|
+
svg.appendChild(yLabel);
|
|
504
|
+
|
|
505
|
+
// Add axis ticks and labels for X (time)
|
|
506
|
+
const numXTicks = 5;
|
|
507
|
+
for (let i = 0; i <= numXTicks; i++) {
|
|
508
|
+
const xValue = minTime + (i * (maxTime - minTime) / numXTicks);
|
|
509
|
+
const x = xScale(xValue);
|
|
510
|
+
const tick = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
511
|
+
tick.setAttribute("x1", x);
|
|
512
|
+
tick.setAttribute("y1", height - padding);
|
|
513
|
+
tick.setAttribute("x2", x);
|
|
514
|
+
tick.setAttribute("y2", height - padding + 6);
|
|
515
|
+
tick.setAttribute("stroke", "black");
|
|
516
|
+
svg.appendChild(tick);
|
|
517
|
+
|
|
518
|
+
const tickLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
519
|
+
tickLabel.setAttribute("x", x);
|
|
520
|
+
tickLabel.setAttribute("y", height - padding + 20);
|
|
521
|
+
tickLabel.setAttribute("class", "axis-label");
|
|
522
|
+
tickLabel.textContent = xValuesCallback(xValue);
|
|
523
|
+
svg.appendChild(tickLabel);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Add axis ticks and labels for Y (frame rate)
|
|
527
|
+
const numYTicks = 5;
|
|
528
|
+
for (let i = 0; i <= numYTicks; i++) {
|
|
529
|
+
const yValue = minFrameRate + (i * (maxFrameRate - minFrameRate) / numYTicks);
|
|
530
|
+
const y = yScale(yValue);
|
|
531
|
+
const tick = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
532
|
+
tick.setAttribute("x1", padding - 6); // Move ticks to the left a bit
|
|
533
|
+
tick.setAttribute("y1", y);
|
|
534
|
+
tick.setAttribute("x2", padding); // Position ticks a bit further from the axis line
|
|
535
|
+
tick.setAttribute("y2", y);
|
|
536
|
+
tick.setAttribute("stroke", "black");
|
|
537
|
+
svg.appendChild(tick);
|
|
538
|
+
|
|
539
|
+
const tickLabel = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
540
|
+
tickLabel.setAttribute("x", padding - 10); // Adjust the label placement to shift it to the right
|
|
541
|
+
tickLabel.setAttribute("y", y + 5); // Center the label vertically on the tick
|
|
542
|
+
tickLabel.setAttribute("text-anchor", "end");
|
|
543
|
+
tickLabel.textContent = yValue.toFixed(1);
|
|
544
|
+
svg.appendChild(tickLabel);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Draw the line chart
|
|
548
|
+
const line = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
549
|
+
const lineData = data.map((point, index) => {
|
|
550
|
+
const x = xScale(point[xKey]);
|
|
551
|
+
const y = yScale(point[yKey]);
|
|
552
|
+
return index === 0 ? 'M' + x + ',' + y : 'L' + x + ',' + y;
|
|
553
|
+
}).join(" ");
|
|
554
|
+
line.setAttribute("d", lineData);
|
|
555
|
+
line.setAttribute("fill", "none");
|
|
556
|
+
line.setAttribute("stroke", lineColor);
|
|
557
|
+
line.setAttribute("stroke-width", 2);
|
|
558
|
+
svg.appendChild(line);
|
|
559
|
+
|
|
560
|
+
// Add tooltip on hover
|
|
561
|
+
data.forEach((point) => {
|
|
562
|
+
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
563
|
+
circle.setAttribute("cx", xScale(point[xKey]));
|
|
564
|
+
circle.setAttribute("cy", yScale(point[yKey]));
|
|
565
|
+
circle.setAttribute("r", 4);
|
|
566
|
+
circle.setAttribute("fill", getCircleColor(point));
|
|
567
|
+
circle.addEventListener("mouseover", (event) => {
|
|
568
|
+
tooltip.style.display = "block";
|
|
569
|
+
tooltip.style.left = event.pageX + 10 + 'px';
|
|
570
|
+
tooltip.style.top = event.pageY + 10 + 'px';
|
|
571
|
+
tooltip.innerHTML = tooltipCallback(point);
|
|
572
|
+
});
|
|
573
|
+
circle.addEventListener("mouseout", () => {
|
|
574
|
+
tooltip.style.display = "none";
|
|
575
|
+
});
|
|
576
|
+
svg.appendChild(circle);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
const renderFpsTooltip = (point) => {
|
|
581
|
+
return \`Time: \${(point.captureTime/1000).toFixed(4)}s, Frame Rate: \${point.frameRate.toFixed(2)} FPS\`;
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
const renderTrackingTimeTooltip = (point) => {
|
|
585
|
+
return \`Frame: \${point.frameNumber}, Tracking Time: \${point.frameTrackingTime.toFixed(2)} ms, Thread: \${point.thread}\`;
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
const renderThroughputTooltip = (point) => {
|
|
589
|
+
return \`Time: \${point.time / 1000}s, Throughput: \${point.throughput} FPS\`;
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
const renderFrameLatencyTooltip = (point) => {
|
|
593
|
+
return \`Frame: \${point.frameNumber}, Overall: \${point.overall.toFixed(2)} ms, Face Tracking Time: \${point.frameTrackingTime.toFixed(2)} ms, DFX processing: \${point.dfxProcessingTime.toFixed(2)} ms\`;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
const getFTCircleColor = (point) => {
|
|
597
|
+
const colors = ['#c7e9c0' ,'#74c476', '#31a354', '#006d2c'];
|
|
598
|
+
const index = parseInt(point.thread.slice(-1));
|
|
599
|
+
return colors[index];
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
const getUTCDate = () => {
|
|
603
|
+
const now = new Date();
|
|
604
|
+
const year = now.getUTCFullYear();
|
|
605
|
+
const month = String(now.getUTCMonth() + 1).padStart(2, '0'); // Months are 0-indexed
|
|
606
|
+
const date = String(now.getUTCDate()).padStart(2, '0');
|
|
607
|
+
const hours = String(now.getUTCHours()).padStart(2, '0');
|
|
608
|
+
const minutes = String(now.getUTCMinutes()).padStart(2, '0');
|
|
609
|
+
const seconds = String(now.getUTCSeconds()).padStart(2, '0');
|
|
610
|
+
return year + '-' + month + '-' + date + ' ' + hours + ':' + minutes + ':' + seconds + ' UTC';
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const info = [
|
|
614
|
+
['Report date', getUTCDate()],
|
|
615
|
+
['SDK Version', '${this.version.webSDK}'],
|
|
616
|
+
['Face Tracker Version', '${this.version.faceTracker}'],
|
|
617
|
+
['Extraction Lib Version', '${this.version.extractionLib.version}'],
|
|
618
|
+
['Extraction Lib SDK ID', '${this.version.extractionLib.sdkId}'],
|
|
619
|
+
['Video Resolution (w x h)', ftResolution.frameWidth + ' x ' + ftResolution.frameHeight + ' pixels'],
|
|
620
|
+
['Face Tracker Resolution (w x h)', ftResolution.ftWidth + ' x ' + ftResolution.ftHeight + ' pixels'],
|
|
621
|
+
['Measurement ID', measurementId],
|
|
622
|
+
['Number of Frames Presented', numOfFramesPresented],
|
|
623
|
+
['Face Trackers Warmup Frame Number', warmupFrameNumber],
|
|
624
|
+
['Number of Tracked Video Frames', numOftrackedVideoFrames],
|
|
625
|
+
['Number of Frames Presented Since Warmup', numOfFramesPresentedSinceWarmUp],
|
|
626
|
+
['Number of dropped Frames', numOfDroppedFrames],
|
|
627
|
+
['Percentage of dropped frames', percentageOfDroppedFrames.toFixed(2) + '%'],
|
|
628
|
+
];
|
|
629
|
+
info.push([
|
|
630
|
+
'Touch screen',
|
|
631
|
+
'maxTouchPoints' in navigator && navigator.maxTouchPoints > 0
|
|
632
|
+
? 'Available'
|
|
633
|
+
: 'Not available',
|
|
634
|
+
]);
|
|
635
|
+
info.push([
|
|
636
|
+
'Window size (w x h)',
|
|
637
|
+
'${window.innerWidth} x ${window.innerHeight} pixels',
|
|
638
|
+
]);
|
|
639
|
+
info.push([
|
|
640
|
+
'Screen orientation',
|
|
641
|
+
window.innerHeight > window.innerWidth ? 'Portrait' : 'Landscape',
|
|
642
|
+
]);
|
|
643
|
+
info.push([
|
|
644
|
+
'User agent',
|
|
645
|
+
window.navigator.userAgent,
|
|
646
|
+
]);
|
|
647
|
+
info.push([
|
|
648
|
+
'Time Zone',
|
|
649
|
+
Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
650
|
+
]);
|
|
651
|
+
info.push([
|
|
652
|
+
'Locale',
|
|
653
|
+
Intl.DateTimeFormat().resolvedOptions().locale,
|
|
654
|
+
]);
|
|
655
|
+
renderInfoTable(info);
|
|
656
|
+
|
|
657
|
+
renderNetworkTable([...restCallDelayArr, ...wsCallDelayArr]);
|
|
658
|
+
|
|
659
|
+
renderLogsTable(logs);
|
|
660
|
+
renderChart(
|
|
661
|
+
instantaneousFrameRates,
|
|
662
|
+
fpsChart,
|
|
663
|
+
'captureTime',
|
|
664
|
+
'frameRate',
|
|
665
|
+
'Time (s)',
|
|
666
|
+
'Frame Rate (FPS)',
|
|
667
|
+
'blue',
|
|
668
|
+
(point) => 'blue',
|
|
669
|
+
(xValue) => (xValue / 1000).toFixed(1),
|
|
670
|
+
renderFpsTooltip
|
|
671
|
+
);
|
|
672
|
+
|
|
673
|
+
renderChart(
|
|
674
|
+
ftChartData,
|
|
675
|
+
ftTrackingTimeChart,
|
|
676
|
+
'frameNumber',
|
|
677
|
+
'frameTrackingTime',
|
|
678
|
+
'Frame Number',
|
|
679
|
+
'Frame Tracking Time (ms)',
|
|
680
|
+
'green',
|
|
681
|
+
getFTCircleColor,
|
|
682
|
+
(xValue) => Math.trunc(xValue),
|
|
683
|
+
renderTrackingTimeTooltip
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
renderChart(
|
|
687
|
+
frameThroughput,
|
|
688
|
+
ftThroughputChart,
|
|
689
|
+
'time',
|
|
690
|
+
'throughput',
|
|
691
|
+
'Time (s)',
|
|
692
|
+
'Face tracking throughput (FPS)',
|
|
693
|
+
'orange',
|
|
694
|
+
(point) => 'orange',
|
|
695
|
+
(xValue) => xValue / 1000,
|
|
696
|
+
renderThroughputTooltip
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
renderChart(
|
|
700
|
+
frameLatencyArr,
|
|
701
|
+
frameLatencyChart,
|
|
702
|
+
'frameNumber',
|
|
703
|
+
'overall',
|
|
704
|
+
'Frame Number',
|
|
705
|
+
'Frame Latency (ms)',
|
|
706
|
+
'#f93e3e',
|
|
707
|
+
(point) => '#f93e3e',
|
|
708
|
+
(xValue) => Math.trunc(xValue),
|
|
709
|
+
renderFrameLatencyTooltip
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
filter.addEventListener('change', () => {
|
|
713
|
+
const selectedThread = filter.value;
|
|
714
|
+
if (selectedThread === 'none') {
|
|
715
|
+
renderLogsTable(logs);
|
|
716
|
+
} else {
|
|
717
|
+
const filteredData = logs.filter(item => item.thread === selectedThread);
|
|
718
|
+
renderLogsTable(filteredData);
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
function downloadFile() {
|
|
723
|
+
const now = new Date();
|
|
724
|
+
const formattedDate = now.toISOString().replace(/[-:T]/g, '_').split('.')[0];
|
|
725
|
+
const blob = new Blob([document.documentElement.outerHTML], { type: 'text/html' });
|
|
726
|
+
const link = document.createElement('a');
|
|
727
|
+
link.href = URL.createObjectURL(blob);
|
|
728
|
+
link.download = \`log_\${formattedDate}.html\`;
|
|
729
|
+
document.body.appendChild(link);
|
|
730
|
+
link.click();
|
|
731
|
+
URL.revokeObjectURL(link.href);
|
|
732
|
+
document.body.removeChild(link);
|
|
733
|
+
}
|
|
734
|
+
const download = document.getElementById('download');
|
|
735
|
+
download.onclick = downloadFile;
|
|
736
|
+
<\/script>
|
|
737
|
+
</body>
|
|
738
|
+
</html>
|
|
739
|
+
`}openLogInNewWindow(){const e=this.generateHTMLTable(),i=new Blob([e],{type:"text/html"}),r=URL.createObjectURL(i);window.open(r,"_blank")}}var qt=Object.defineProperty,Zt=(t,e,i)=>e in t?qt(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,we=(t,e,i)=>Zt(t,typeof e!="symbol"?e+"":e,i);class xe{constructor(e,i){we(this,"workerUrl"),we(this,"worker"),this.worker=e,this.workerUrl=i}static init(e,i,r){const c=new Blob([e],{type:"application/javascript"}),d=URL.createObjectURL(c),n=r||`WORKER${String(new Date().getTime())}`,a=new Worker(new URL(d,import.meta.url),{name:n,type:i});return new xe(a,d)}destroy(){this.worker&&(this.worker.terminate(),URL.revokeObjectURL(this.worker))}}const Qt=(t,e,i,r)=>{const c=t/e,d=i/r;let n=0,a=0;c>d?(n=t,a=t/d):(a=e,n=e*d);const u=(t-n)/2,h=(e-a)/2;return{width:n||0,height:a||0,offsetX:u||0,offsetY:h||0}},ei=(t,e,i,r)=>{const c=(t-i)/2,d=(e-r)/2;return{width:i||0,height:r||0,offsetX:c||0,offsetY:d||0}},ti=(t,e,i,r)=>{const c=t/e,d=i/r;let n=0,a=0;c>d?(a=e,n=e*d):(n=t,a=t/d);const u=(t-n)/2,h=(e-a)/2;return{width:n||0,height:a||0,offsetX:u||0,offsetY:h||0}},ii=(t,e)=>{switch(t){case"none":return ei(...e);case"cover":return Qt(...e);case"contain":default:return ti(...e)}},st=t=>/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(t),si=t=>t===void 0?!0:!(typeof t.mediaPipe<"u"&&typeof t.mediaPipe!="boolean"||typeof t.beforeRESTCall<"u"&&typeof t.beforeRESTCall!="boolean"||typeof t.afterRESTCall<"u"&&typeof t.afterRESTCall!="boolean"||typeof t.extractionLibWasm<"u"&&typeof t.extractionLibWasm!="boolean"||typeof t.apiClient<"u"&&typeof t.apiClient!="boolean"||typeof t.extractionWorker<"u"&&typeof t.extractionWorker!="boolean"||typeof t.faceTrackerWorkers<"u"&&typeof t.faceTrackerWorkers!="boolean"||typeof t.sdk<"u"&&typeof t.sdk!="boolean"),ai=(t,e)=>{const i={...t};if(e.logger)if(si(e.logger))i.logger={...i.logger,...e.logger};else return{results:"invalid"};if(e.apiUrl!==void 0)if(typeof e.apiUrl=="string")i.apiUrl=e.apiUrl;else return{results:"invalid"};if(e.metrics!==void 0)if(typeof e.metrics=="boolean")i.metrics=e.metrics;else return{results:"invalid"};if(e.mirrorVideo!==void 0)if(typeof e.mirrorVideo=="boolean")i.mirrorVideo=e.mirrorVideo;else return{results:"invalid"};if(e.displayMediaStream!==void 0)if(typeof e.displayMediaStream=="boolean")i.displayMediaStream=e.displayMediaStream;else return{results:"invalid"};if(e.assetFolder!==void 0)if(typeof e.assetFolder=="string")i.assetFolder=e.assetFolder;else return{results:"invalid"};if(e.mediaElement!==void 0)if(e.mediaElement instanceof HTMLDivElement)i.mediaElement=e.mediaElement;else return{results:"invalid"};if(e.constraintOverrides!==void 0){let r=function(n,a){if(!(n in d))return!1;const u=d[n];return typeof a===u};const d=Object.fromEntries(Object.entries({backLightMaxPixels_pct:30,backLightSearchMult:1.5,backLightThresh:240,boxCenterX_pct:50,boxCenterY_pct:50,boxHeight_pct:99,boxWidth_pct:50,cameraRot_chunkThresh:.7853981633974483,cameraRot_windowThresh:.2617993877991494,checkBackLight:!1,checkCameraMovement:!1,checkCentered:!1,checkDistance:!1,checkEyebrowMovement:!1,checkFaceDirection:!1,checkLighting:!1,checkMaxDistance:!1,checkMinFps:!1,checkMovement:!1,chunkMovementThresh_pct:60,enableDebugLog:!1,enableFigures:!1,faceRotLR_thresh:.33,faceRotUD_lowerthresh:.25,faceRotUD_upperThresh:5,hy_faceRotLR_thresh:.05,hy_maxFaceRotLR_deg:2,hy_maxFaceRotUD_deg:2,hy_minInterPupilDist_px:5,hy_minimumFps:1,maxEyebrowMovement_mm:3,maxFaceRotLR_deg:12.5,maxFaceRotUD_deg:25,maxMovement_mm:10,minInterPupilDist_px:100,minimumFps:26,movementWindow_ms:2e3,threshBright:225,threshDark:48}).map(([n,a])=>[n,typeof a]));for(const n in e.constraintOverrides){const a=e.constraintOverrides[n];if(!r(n,a))return{results:"invalid"}}i.constraintOverrides=e.constraintOverrides}return{results:"valid",settings:i}},ri=t=>typeof t.age!="number"||t.age<13||t.age>120?(console.error("Invalid age. It should be a number between 13 and 120."),!1):typeof t.height!="number"||t.height<120||t.height>220?(console.error("Invalid height. It should be a number between 120 and 220."),!1):typeof t.weight!="number"||t.weight<30||t.weight>300?(console.error("Invalid weight. It should be a number between 30 and 300."),!1):typeof t.sex!="number"||t.sex<1||t.sex>3?(console.error("Invalid sex. It should be a number between 1 and 3."),!1):typeof t.diabetes!="number"||t.diabetes<4||t.diabetes>6?(console.error("Invalid diabetes. It should be a number between 4 and 6."),!1):typeof t.bloodPressureMedication!="number"||t.bloodPressureMedication!==0&&t.bloodPressureMedication!==1?(console.error("Invalid bloodPressureMedication. It should be either 0 or 1."),!1):typeof t.smoking!="number"||t.smoking!==0&&t.smoking!==1?(console.error("Invalid smoking. It should be either 0 or 1."),!1):!0;var m=(t=>(t.beforeRESTCall="Before REST call event",t.afterRESTCall="After REST call event",t.mediaPipe="MediaPipe",t.extractionLibWasm="DFX Extraction lib WASM",t.apiClient="DFX API client",t.webSocket="WebSocket",t.sdk="SDK",t.dfxWorker="DFX Worker",t))(m||{});const ni=t=>{switch(t){case"Before REST call event":return"red";case"After REST call event":return"orange";case"MediaPipe":return"green";case"DFX Extraction lib WASM":return"violet";case"DFX API client":return"#d34110";case"WebSocket":return"#d34110";case"SDK":return"#d34110";case"DFX Worker":return"#ad4393";default:return"black"}};class at{constructor(e=1e3){we(this,"timestamps",[]),we(this,"windowMs"),this.windowMs=e}tick(e=performance.now()){for(this.timestamps.push(e);this.timestamps.length>0&&e-this.timestamps[0]>this.windowMs;)this.timestamps.shift()}get fps(){const e=this.timestamps.length,i=this.timestamps.at(-1)-this.timestamps[0]||1;return e/i*1e3}get frameCount(){return this.timestamps.length}reset(){this.timestamps=[]}}var oi=Object.defineProperty,li=(t,e,i)=>e in t?oi(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,rt=(t,e,i)=>li(t,typeof e!="symbol"?e+"":e,i);const ci=()=>{const t=new Date,e=(t.getMonth()+1).toString().padStart(2,"0"),i=t.getDate().toString().padStart(2,"0"),r=t.getFullYear();let c=t.getHours();const d=t.getMinutes().toString().padStart(2,"0"),n=t.getSeconds().toString().padStart(2,"0"),a=t.getMilliseconds().toString().padStart(3,"0"),u=c>=12?"PM":"AM";return c=c%12||12,`[${e}/${i}/${r}, ${c}:${d}:${n}.${a} ${u}]`};class nt{constructor(){rt(this,"mertics",new zt),rt(this,"version",{webSDK:"",extractionLib:{version:"",sdkId:""},faceTracker:""})}retrieveLogs(){this.mertics.transferLogs(),this.mertics.openLogInNewWindow(),this.mertics.debugLogs=[]}setVersion(e){this.version=e,this.mertics.version=e}log(e,i,r,c=!1,d={}){const n=ci();if(c)this.mertics.appendLog({thread:"Main",timestamp:n,category:i,message:e,meta:d});else{const a=`[${i}]`,u=" ",h=e,p=`color:${r}; font-weight:800;`,_=`color:${ni(i)}; font-weight:700;`;console.log("%c%s%c%s%c%s%c%s",p,n,_,a,"background:inherit;",u,"font-style: italic;",h)}}info(e,i){this.log(e,i,"blue")}warn(e,i){this.log(e,i,"orange")}error(e,i){this.log(e,i,"red")}debug(e,i){this.log(e,i,"green")}start(){console.log("%c%s","color: #5e5e5e; background-color: #2d2d2d; letter-spacing: 0.1em; text-shadow: -1px -1px 1px #111, 2px 2px 1px #363636; font-size: 36px; padding: 20px 40px; text-align: center; text-transform: uppercase; text-rendering: optimizeLegibility;","Anura Web Core SDK"),console.log(`Version: ${this.version.webSDK}`),console.log("https://www.deepaffex.ai")}}const di={SEX_NOT_PROVIDED:1,SEX_ASSIGNED_MALE_AT_BIRTH:2,SEX_ASSIGNED_FEMALE_AT_BIRTH:3,DIABETES_NONE:4,DIABETES_TYPE1:5,DIABETES_TYPE2:6,SMOKER_TRUE:0,SMOKER_FALSE:1,BLOOD_PRESSURE_MEDICATION_TRUE:1,BLOOD_PRESSURE_MEDICATION_FALSE:0},K={SEX_ASSIGNED_AT_BIRTH:1,AGE_YEARS:2,HEIGHT_CM:3,WEIGHT_KG:4,SMOKER:5,BLOOD_PRESSURE_MEDICATION:7,DIABETES:8};var ot=(t=>(t[t.BGR=1]="BGR",t[t.RGB=2]="RGB",t[t.BGRA=3]="BGRA",t[t.RGBA=4]="RGBA",t[t.Infrared=5]="Infrared",t[t.Infrared888=6]="Infrared888",t[t.BGR_Infrared=7]="BGR_Infrared",t[t.RGB_Infrared=8]="RGB_Infrared",t[t.Gray=9]="Gray",t))(ot||{});const j={ASSETS_NOT_DOWNLOADED:"ASSETS_NOT_DOWNLOADED",NOT_LOADED:"NOT_LOADED",LOADING:"LOADING",LOADED:"LOADED",READY:"READY"},Ce={COLLECTOR:"COLLECTOR",ASSET_DOWNLOAD:"ASSET_DOWNLOAD",WEB_SOCKET:"WEB_SOCKET"},Re={CONTAIN:"contain",COVER:"cover",NONE:"none"};var U=(t=>(t.INIT="INIT",t.READY="READY",t.INIT_TFJS="INIT_TFJS",t.SET_PORT="SET_PORT",t.TRACK="TRACK",t.RESULTS_READY="RESULTS_READY",t.WARM_UP="WARM_UP",t.DESTROY="DESTROY",t.LANDMARKS="LANDMARKS",t.VIDEO_FRAME="VIDEO_FRAME",t.SCALE_FACTOR_CHANGED="SCALE_FACTOR_CHANGED",t))(U||{}),hi=Object.defineProperty,lt=t=>{throw TypeError(t)},mi=(t,e,i)=>e in t?hi(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,w=(t,e,i)=>mi(t,typeof e!="symbol"?e+"":e,i),$e=(t,e,i)=>e.has(t)||lt("Cannot "+i),ct=(t,e,i)=>($e(t,e,"read from private field"),i?i.call(t):e.get(t)),dt=(t,e,i)=>e.has(t)?lt("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,i),ui=(t,e,i,r)=>($e(t,e,"write to private field"),e.set(t,i),i),fi=(t,e,i)=>($e(t,e,"access private method"),i),le,Be,ht;const pi=class yt{constructor(e,i,r){dt(this,Be),dt(this,le),w(this,"mediaElement"),w(this,"numOfFramesPresented",0),w(this,"workers",[]),w(this,"numOftrackedVideoFrames",0),w(this,"warmupFrameNumber",0),w(this,"videoCallbackId",0),w(this,"numOfWorkers",4),w(this,"isLoggingFaceTrackerWorkers",!1),w(this,"isLoggingSdk",!1),w(this,"workerIndex",0),w(this,"metrics",!1),w(this,"videoFpsTracker",new at(1e3)),w(this,"faceTrackerFpsTracker",new at(1e3)),w(this,"videoElementSize",{width:0,height:0,offsetX:0,offsetY:0}),w(this,"videoElement",document.createElement("video")),w(this,"frameWidth",0),w(this,"frameHeight",0),w(this,"mirrorVideo",!0),w(this,"settings",{faceTrackerWidth:0,faceTrackerHeight:0,displayMediaStream:!0,objectFit:Re.COVER}),w(this,"isExtracting",!1),w(this,"starRating",0),w(this,"scaleFactor",1),w(this,"warmupIndex",0),w(this,"warmingUp",!0),w(this,"ftWorkerIndex",0),w(this,"lastFrameNumber",-1),w(this,"on",{faceTrackersReady:null,frameAvailable:null,landmarksAvailable:null,scaleFactorChanged:null});const{mediaElement:c,mirrorVideo:d,numOfWorkers:n,isLoggingFaceTrackerWorkers:a,isLoggingSdk:u,metrics:h,displayMediaStream:p}=i;this.numOfWorkers=n,this.isLoggingFaceTrackerWorkers=a,this.isLoggingSdk=u,this.metrics=h,ui(this,le,r),this.settings.displayMediaStream=p,this.mirrorVideo=d,this.mediaElement=c,this.videoFrameCallback=this.videoFrameCallback.bind(this),this.workers=e,this.scaleFactor=i.scaleFactor,this.initWorkerOnMessage(i.models),this.videoElement.muted=!0,this.videoElement.playsInline=!0,this.videoElement.preload="auto"}static async init(e,i){const{numOfWorkers:r,faceTrackerCode:c}=e,d=[],n=new TextDecoder().decode(new Uint8Array(c));if(r>0)for(let a=1;a<=r;a+=1){const u=xe.init(n,"module",`FACE_TRACKER_WORKER_${a-1}`);d.push({ft:u,channel:new MessageChannel,isBusy:!1})}return new yt(d,e,i)}initWorkerOnMessage(e){const i=window.matchMedia("(orientation: portrait)").matches,r=i?360:640,c=i?640:360;this.workers.forEach(d=>{d.ft.worker.postMessage({action:U.INIT_TFJS,payload:{width:r,height:c,models:e,scaleFactor:this.scaleFactor}}),d.ft.worker.postMessage({action:U.SET_PORT,payload:{port:d.channel.port2}},[d.channel.port2]),d.ft.worker.onmessage=n=>{const{action:a,payload:u}=n.data;switch(a){case U.INIT_TFJS:break;case U.READY:{const{workerName:h,version:p,workerId:_,backend:R}=u;this.on.faceTrackersReady&&this.on.faceTrackersReady(h,p,_,R);break}case U.LANDMARKS:{this.faceTrackerFpsTracker.tick(),d.isBusy=!1,this.warmingUp&&this.warmupIndex++;const{face:h,annotations:p,frameTimestamp:_}=u;this.on.landmarksAvailable&&this.on.landmarksAvailable(h,p,_);break}case U.DESTROY:{const{workerId:h}=u;this.workers[h].ft.destroy();break}}}})}getMediaElement(){return this.mediaElement}setIsExtracting(e){this.isExtracting=e}destroyWorkers(){setTimeout(async()=>{this.videoCallbackId&&this.videoElement.cancelVideoFrameCallback(this.videoCallbackId),this.workers.forEach(e=>e.ft.worker.postMessage({action:U.DESTROY}))},200)}createMediaElements(){this.videoElement.addEventListener("ended",async()=>{this.destroyWorkers()});const e=document.createElement("div"),i=this.settings.displayMediaStream?this.videoElement:e,r="white";this.mediaElement.appendChild(i),i.style.width="100%",i.style.height="100%",i.style.boxSizing="border-box",this.settings.displayMediaStream&&(i.style.border=`1px solid ${r}`),i.style.objectFit=this.settings.objectFit,i.style.transform=`scale(${this.mirrorVideo?"-1":"1"},1)`,this.settings.displayMediaStream||(i.style.height=`${this.frameHeight}px`,i.style.width=`${this.frameWidth}px`),new ResizeObserver(d=>{const{contentRect:n,target:a}=d[0],{width:u,height:h}=n,{x:p,y:_}=a.getBoundingClientRect(),{faceTrackerWidth:R,faceTrackerHeight:k}=this.settings;this.videoElementSize=ii(this.settings.objectFit,[u,h,this.frameWidth,this.frameHeight]);const{width:L,height:W}=this.videoElementSize;if(!this.settings.displayMediaStream){const G=this.settings.objectFit===Re.NONE;i.style.height=`${Math.trunc(G?W:h)}px`,i.style.width=`${Math.trunc(G?L:u)}px`}this.mediaElement.dispatchEvent(new CustomEvent("mediaElementSizeChanged",{detail:{mediaElementSize:{width:u,height:h,x:p,y:_},videoElementSize:this.videoElementSize,frameInfo:{mediaStreamWidth:this.frameWidth,mediaStreamHeight:this.frameHeight,faceTrackerWidth:R,faceTrackerHeight:k},isPortrait:h>u,aspectRatio:u/h}}))}).observe(this.mediaElement)}log(e,i,r){this.isLoggingSdk&&ct(this,le).info(e,i),this.metrics&&ct(this,le).log(e,i,"",!0,r)}videoFrameCallback(e,i){const{presentedFrames:r,captureTime:c,expectedDisplayTime:d,mediaTime:n}=i;this.videoFpsTracker.tick();const a=c===void 0?d:c;this.numOfFramesPresented=r;const u=`Number of frames presented: ${this.numOfFramesPresented} - time: ${a}`;let h=0;if(n&&n>0?h=n*1e3:c&&c>0?h=c>1e6?c-performance.timeOrigin:c:h=e,this.log(u,m.sdk,{captureTime:a,presentedFrames:r}),this.warmingUp)if(this.warmupIndex>=this.numOfWorkers)this.warmingUp=!1;else{const p=this.workers[this.warmupIndex];if(!p.isBusy){p.isBusy=!0;const _=new VideoFrame(this.videoElement,{timestamp:h});p.ft.worker.postMessage({action:"TRACK",payload:{frame:_,frameTimestamp:h,frameNumber:this.numOfFramesPresented}},[_])}}if(!this.warmingUp){const p=new VideoFrame(this.videoElement,{timestamp:h});let _=!1;for(let R=0;R<this.numOfWorkers;R++){this.ftWorkerIndex=(this.ftWorkerIndex+1)%this.numOfWorkers;const k=this.workers[this.ftWorkerIndex];if(k&&!k.isBusy){k.isBusy=!0,this.on.frameAvailable(h,this.numOfFramesPresented,this.lastFrameNumber,!0),k.ft.worker.postMessage({action:"TRACK",payload:{frame:p,frameTimestamp:h,frameNumber:this.numOfFramesPresented}},[p]),_=!0;break}}_||this.on.frameAvailable(h,this.numOfFramesPresented,this.lastFrameNumber,!1,p)}this.lastFrameNumber=this.numOfFramesPresented,this.videoCallbackId=this.videoElement.requestVideoFrameCallback(this.videoFrameCallback)}setFaceTrackerMediaStreamResolution(e,i){(e<=360||i<=360)&&(this.scaleFactor=1),this.settings.faceTrackerWidth=e*this.scaleFactor,this.settings.faceTrackerHeight=i*this.scaleFactor,this.workers.forEach(r=>r.ft.worker.postMessage({action:U.SCALE_FACTOR_CHANGED,payload:{scaleFactor:this.scaleFactor}})),this.on.scaleFactorChanged&&this.on.scaleFactorChanged(this.scaleFactor)}async setMediaStream(e){if(e instanceof MediaStream)try{const{settings:i,constraints:r}=await fi(this,Be,ht).call(this,e,this.videoElement);await this.videoElement.play(),this.settings.displayMediaStream||(this.videoElement.style.visibility="none");const{width:c,height:d}=i;return this.setFaceTrackerMediaStreamResolution(c??0,d??0),this.frameWidth=c||1,this.frameHeight=d||1,this.log(`Face tracker resolution: ${c} x ${d} pixels. Video resolution: ${this.frameWidth} x ${this.frameHeight} pixels`,m.sdk,{ftWidth:c,ftHeight:d,frameWidth:this.frameWidth,frameHeight:this.frameHeight}),this.createMediaElements(),this.videoCallbackId=this.videoElement.requestVideoFrameCallback(this.videoFrameCallback),!0}catch(i){return console.log("Error applying face tracker video track constraints",i),!1}return!1}stopTracking(){this.videoCallbackId&&this.videoElement.cancelVideoFrameCallback(this.videoCallbackId),this.videoElement.pause(),this.videoElement.srcObject=null}};le=new WeakMap,Be=new WeakSet,ht=async function(t,e){e.srcObject=t,await new Promise(r=>e.onloadedmetadata=r);const[i]=t.getVideoTracks();return{constraints:i.getConstraints(),settings:i.getSettings()}};let Ei=pi;var T=(t=>(t.INIT="INIT",t.READY="READY",t.SET_MODE="SET_MODE",t.SET_NUMBER_OF_CHUNKS="SET_NUMBER_OF_CHUNKS",t.SET_TARGET_FPS="SET_TARGET_FPS",t.SET_CHUNK_DURATION_SECONDS="SET_CHUNK_DURATION_SECONDS",t.SET_FRAME_ORDER="SET_FRAME_ORDER",t.GET_CONSTRAINTS_CONFIG="GET_CONSTRAINTS_CONFIG",t.SET_CONSTRAINTS_CONFIG="SET_CONSTRAINTS_CONFIG",t.SET_FACE_ATTRIBUTE="SET_FACE_ATTRIBUTE",t.RESET_COLLECTION="RESET_COLLECTION",t.CANCEL_COLLECTION="CANCEL_COLLECTION",t.START_COLLECTION="START_COLLECTION",t.SET_PORTS="SET_PORTS",t.COLLECTOR_ERROR="COLLECTOR_ERROR",t.STAR_RATING="STAR_RATING",t.ALL_FACE_TRACKERS_WARMED_UP="ALL_FACE_TRACKERS_WARMED_UP",t.CONSTRAINTS_UPDATED="CONSTRAINTS_UPDATED",t.SHOULD_END_MEASUREMENT_EARLY="SHOULD_END_MEASUREMENT_EARLY",t.GET_LOGS="GET_LOGS",t.NEW_FRAME="NEW_FRAME",t.TRACKING_STATUS="TRACKING_STATUS",t.SCALE_FACTOR_CHANGED="SCALE_FACTOR_CHANGED",t))(T||{}),y=(t=>(t.CONNECT="CONNECT",t.DISCONNECT="DISCONNECT",t.DISCONNECTED="DISCONNECTED",t.LOGIN_WITH_TOKEN_SUCCESS="LOGIN_WITH_TOKEN_SUCCESS",t.SUBSCRIBED_TO_RESULTS="SUBSCRIBED_TO_RESULTS",t.CHUNK_SENT="CHUNK_SENT",t.RESULTS_RECEIVED="RESULTS_RECEIVED",t.CHUNK_ACKNOWLEDGED="CHUNK_ACKNOWLEDGED",t.ERROR="ERROR",t.NETWORK_DELAY="NETWORK_DELAY",t))(y||{}),Ti=Object.defineProperty,mt=t=>{throw TypeError(t)},Si=(t,e,i)=>e in t?Ti(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,ut=(t,e,i)=>Si(t,typeof e!="symbol"?e+"":e,i),Ge=(t,e,i)=>e.has(t)||mt("Cannot "+i),s=(t,e,i)=>(Ge(t,e,"read from private field"),i?i.call(t):e.get(t)),S=(t,e,i)=>e.has(t)?mt("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,i),f=(t,e,i,r)=>(Ge(t,e,"write to private field"),e.set(t,i),i),l=(t,e,i)=>(Ge(t,e,"access private method"),i),bi=(t,e,i,r)=>({set _(c){f(t,e,c)},get _(){return s(t,e,r)}}),x,g,P,v,O,ke,ve,Ae,ye,ce,z,Oe,de,he,b,q,N,me,F,Ne,Z,Q,ee,te,ue,fe,Y,pe,Le,ie,De,se,Ee,A,Te,B,Se,o,ft,pt,Et,He,Ve,Tt,St,bt,_t,gt,wt,Ie,Ke,E,Ct,Rt,kt,vt,ae,C;const At=Symbol("instance_creation_key"),_i=class Ot{constructor(e){if(S(this,o),S(this,x),S(this,g,{mediaElement:document.createElement("div"),assetFolder:"",apiUrl:"",metrics:!1,logger:{sdk:!1,mediaPipe:!1,beforeRESTCall:!1,afterRESTCall:!1,extractionLibWasm:!1,apiClient:!1,extractionWorker:!1,faceTrackerWorkers:!1},mirrorVideo:!0,displayMediaStream:!0,constraintOverrides:{}}),S(this,P,[{file:"decompress.json",uncompressedSize:89469},{file:"extraction_worker_0.1.0-beta.1_js.json",uncompressedSize:59624},{file:"facetracker_worker_0.1.0-beta.1_js.json",uncompressedSize:306553},{file:"extraction_wasm_0.1.0-beta.1.json",uncompressedSize:1926126},{file:"detectorModel_json.json",uncompressedSize:4640},{file:"detectorModel_bin.json",uncompressedSize:242046},{file:"landmarkModel_json.json",uncompressedSize:5036},{file:"landmarkModel_bin.json",uncompressedSize:1704814}]),S(this,v,new nt),S(this,O,Yt.init()),S(this,ke),S(this,ve),S(this,Ae),S(this,ye),S(this,ce),S(this,z),S(this,Oe),S(this,de,{version:"",sdkId:""}),S(this,he,""),S(this,b),S(this,q,0),S(this,N),S(this,me,j.ASSETS_NOT_DOWNLOADED),S(this,F,""),S(this,Ne,""),S(this,Z,!1),S(this,Q,5),S(this,ee,30),S(this,te,5),S(this,ue,!1),S(this,fe,4),S(this,Y),S(this,pe),S(this,Le),S(this,ie,1e7),S(this,De,0),S(this,se,new Map),S(this,Ee,Promise.resolve()),S(this,A,0),S(this,Te,-1),S(this,B,-1),S(this,Se,.5),ut(this,"on",{beforeRESTCall:null,afterRESTCall:null,bytesDownloaded:null,faceTrackerStateChanged:null,resultsReceived:null,constraintsUpdated:null,mediaElementResize:null,facialLandmarksUpdated:null,chunkSent:null,error:null}),e!==At)throw new Error("Use await Measurement.init() to create an instance of Measurement class.")}static async init(e){if(!e)throw new Error("Missing `settings` object");const i=new Ot(At);if(!i.setSettings(e))throw new Error("Invalid settings object");f(i,x,Bt({url:{http:new URL("https://api.deepaffex.ai")},onBeforeRESTCall:()=>{var n,a;l(n=i,o,St).call(n),l(a=i,o,bt).call(a)},onAfterRESTCall:(n,a)=>{var u,h;l(u=i,o,_t).call(u,n,a),l(h=i,o,gt).call(h,n,a)}}));const c=n=>{var a;const{bytes:u,url:h,uncompressedSize:p,done:_}=n.detail;l(a=i,o,E).call(a,`bytesDownloaded event, ${u}, ${p}, ${h}, ${_}`,m.mediaPipe),i.on.bytesDownloaded&&i.on.bytesDownloaded(u,p,h,_)},d=n=>{var a;const{error:u,url:h}=n.detail;l(a=i,o,E).call(a,`downloadError event, ${h}, ${u}`,m.mediaPipe),i.on.error&&i.on.error(Ce.ASSET_DOWNLOAD,{url:h,error:u})};return s(i,O).addEventListener("downloadedError",d),s(i,O).addEventListener("bytesDownloaded",c),s(i,v).setVersion(i.getVersion()),s(i,g).logger&&Object.values(s(i,g).logger).some(n=>n===!0)&&s(i,v).start(),setTimeout(()=>{var n;l(n=i,o,ae).call(n,j.ASSETS_NOT_DOWNLOADED)},500),new Proxy(i,{get(n,a,u){const h=a;return typeof n[h]=="function"?n[h].bind(n):Reflect.get(n,h,u)},set(n,a,u){return console.log(`Setting property "${String(a)}" to "${u}" is not allowed`),!0}})}loadMask(e){if(s(this,b)){let i=!1;const r=s(this,b).mediaElement.querySelector("svg");r&&(i=!0,s(this,b).mediaElement.removeChild(r)),s(this,b).mediaElement.appendChild(e),i&&(s(this,b).mediaElement.style.setProperty("border","1px solid transparent"),setTimeout(()=>{s(this,b).mediaElement.removeAttribute("style")},100))}}setSettings(e){const i=ai(s(this,g),e);return i.results==="valid"?(f(this,g,i.settings),!0):!1}getVersion(){return{webSDK:Je,extractionLib:s(this,de),faceTracker:s(this,he)}}async downloadAssets(){const{assetFolder:e}=s(this,g);try{if(l(this,o,E).call(this,`Asset base URL ${e}`,m.sdk),l(this,o,E).call(this,"Start downloading decompressor...",m.sdk),await s(this,O).fetchAsset(s(this,P),`${e}/`,"decompress.json",!0,"gzip"),s(this,O).canDecompress){await l(this,o,pt).call(this,e),s(this,z)&&await l(this,o,Ve).call(this),l(this,o,E).call(this,"Start downloading TFJS worker...",m.mediaPipe);const i=await s(this,O).fetchAsset(s(this,P),`${e}/`,`facetracker_worker_${this.getVersion().webSDK}_js.json`,!0,"brotli");return i&&(f(this,Oe,i),await l(this,o,ft).call(this,e),await l(this,o,He).call(this)),l(this,o,Et).call(this),!0}}catch{return l(this,o,E).call(this,"Failed to download TFJS face tracker or DFX extraction worker WASM assets",m.mediaPipe),!1}}setExtractionLibSettings(e=6,i=30,r=5){f(this,Q,e-1),f(this,ee,i),f(this,te,r)}async setNextChunkAsFinal(){f(this,ue,!0),await l(this,o,C).call(this,T.SHOULD_END_MEASUREMENT_EARLY,{},!0),l(this,o,E).call(this,"Set the action for the next chunk to LAST::PROCESS",m.extractionLibWasm)}async startTracking(){s(this,b)&&(s(this,b).isExtracting||(s(this,b).setIsExtracting(!0),l(this,o,E).call(this,"Start tracking frames",m.mediaPipe),await l(this,o,C).call(this,T.SET_NUMBER_OF_CHUNKS,{value:s(this,ie)},!0),await l(this,o,Ie).call(this)))}async stopTracking(){if(s(this,b)){s(this,b).stopTracking(),await l(this,o,wt).call(this),s(this,b).setIsExtracting(!1),l(this,o,E).call(this,"Stop extracting frames",m.mediaPipe);const{numOfFramesPresented:e,warmupFrameNumber:i,numOftrackedVideoFrames:r}=s(this,b);l(this,o,E).call(this,"Tracking metrics",m.sdk,{numOfFramesPresented:e,warmupFrameNumber:i,numOftrackedVideoFrames:r}),f(this,F,"")}}async disconnect(){s(this,Z)&&await l(this,o,C).call(this,y.DISCONNECT,{},!0),s(this,g).metrics&&(await l(this,o,C).call(this,T.GET_LOGS,{},!0),s(this,v).retrieveLogs())}async destroy(){s(this,N)&&(s(this,N).destroy(),l(this,o,E).call(this,"Destroyed",m.extractionLibWasm)),s(this,b)&&(s(this,b).destroyWorkers(),l(this,o,E).call(this,"Destroyed",m.mediaPipe))}async reset(){return s(this,me)===j.READY?(await this.stopTracking(),await this.destroy(),f(this,v,new nt),f(this,de,{version:"",sdkId:""}),f(this,he,""),f(this,q,0),f(this,F,""),f(this,Z,!1),f(this,Q,5),f(this,ee,30),f(this,te,5),f(this,ue,!1),f(this,Y,void 0),f(this,ie,1e7),f(this,De,0),f(this,se,new Map),f(this,Ee,Promise.resolve()),f(this,A,0),f(this,Te,-1),f(this,B,-1),s(this,g).mediaElement.innerHTML="",await l(this,o,Ve).call(this),await l(this,o,He).call(this),!0):!1}async setMediaStream(e){if(s(this,b)&&!s(this,b).isExtracting&&s(this,N)){await s(this,b).setMediaStream(e);const i=Object.fromEntries(s(this,b).workers.map((r,c)=>[`port${c+1}`,r.channel.port1]));s(this,N).worker.postMessage({action:T.SET_PORTS,payload:{numOfWorkers:s(this,fe),workerPorts:i}},[...s(this,b).workers.map(r=>r.channel.port1)])}}async prepare(e,i,r,c){s(this,x).setSession({userToken:e,userRefreshToken:i});const{region:d,status:n}=await l(this,o,Ct).call(this,"user");let a=`api.${d}.deepaffex.ai`;s(this,g).apiUrl?a=s(this,g).apiUrl:s(this,g).apiUrl=a,s(this,x).setUrl(`https://${a}`);const u=await l(this,o,Rt).call(this,e,i,"user"),h=await l(this,o,kt).call(this,r,c);return u&&h&&n==="200"}async setConstraintsConfig(e){await l(this,o,C).call(this,T.SET_CONSTRAINTS_CONFIG,{...s(this,Le),...e&&{...s(this,g).constraintOverrides}},!0)}async startMeasurement(e=!1,i={}){if(f(this,ue,!1),f(this,F,""),await l(this,o,vt).call(this,i),s(this,N)&&s(this,F)!==""){await l(this,o,Ke).call(this),await l(this,o,C).call(this,T.SET_NUMBER_OF_CHUNKS,{value:s(this,Q)+1},!0),await this.setConstraintsConfig(e),await l(this,o,Tt).call(this),await l(this,o,Ie).call(this);const{userToken:r}=s(this,x).getSession();r?await l(this,o,C).call(this,y.CONNECT,{token:r,measurementId:s(this,F)},!0):l(this,o,E).call(this,"User token is missing. Unable to connect.",m.webSocket)}}setDemographics(e){ri(e)?(f(this,Y,e),l(this,o,E).call(this,`Demographics updated ${JSON.stringify(e)}`,m.extractionLibWasm)):l(this,o,E).call(this,`Error updating Demographics ${JSON.stringify(e)}`,m.extractionLibWasm)}setObjectFit(e){return s(this,b)&&Re!==void 0&&Object.values(Re).includes(e)?(s(this,b).settings.objectFit=e,!0):!1}};x=new WeakMap,g=new WeakMap,P=new WeakMap,v=new WeakMap,O=new WeakMap,ke=new WeakMap,ve=new WeakMap,Ae=new WeakMap,ye=new WeakMap,ce=new WeakMap,z=new WeakMap,Oe=new WeakMap,de=new WeakMap,he=new WeakMap,b=new WeakMap,q=new WeakMap,N=new WeakMap,me=new WeakMap,F=new WeakMap,Ne=new WeakMap,Z=new WeakMap,Q=new WeakMap,ee=new WeakMap,te=new WeakMap,ue=new WeakMap,fe=new WeakMap,Y=new WeakMap,pe=new WeakMap,Le=new WeakMap,ie=new WeakMap,De=new WeakMap,se=new WeakMap,Ee=new WeakMap,A=new WeakMap,Te=new WeakMap,B=new WeakMap,Se=new WeakMap,o=new WeakSet,ft=async function(t){l(this,o,E).call(this,"Start downloading TFJS face tracker assets...",m.mediaPipe);const e=`${t}/models/`,[i,r,c,d]=await Promise.all([s(this,O).fetchAsset(s(this,P),e,"detectorModel_json.json",!0,"brotli"),s(this,O).fetchAsset(s(this,P),e,"detectorModel_bin.json",!0,"brotli"),s(this,O).fetchAsset(s(this,P),e,"landmarkModel_json.json",!0,"brotli"),s(this,O).fetchAsset(s(this,P),e,"landmarkModel_bin.json",!0,"brotli")]);l(this,o,E).call(this,"TFJS face tracker assets successfully downloaded",m.mediaPipe),f(this,ke,i),f(this,ve,r),f(this,Ae,c),f(this,ye,d)},pt=async function(t){l(this,o,E).call(this,"Start downloading DFX extraction worker assets...",m.extractionLibWasm);const[e,i]=await Promise.all([s(this,O).fetchAsset(s(this,P),`${t}/extraction/`,`extraction_wasm_${this.getVersion().webSDK}.json`,!0,"brotli"),s(this,O).fetchAsset(s(this,P),`${t}/`,`extraction_worker_${this.getVersion().webSDK}_js.json`,!0,"brotli")]);l(this,o,E).call(this,"DFX extraction worker assets successfully downloaded",m.extractionLibWasm),f(this,ce,e),f(this,z,i)},Et=function(){if(s(this,b)){const t=e=>{this.on.mediaElementResize&&this.on.mediaElementResize(e)};s(this,g).mediaElement.addEventListener("mediaElementSizeChanged",t)}},He=async function(){s(this,g),l(this,o,ae).call(this,j.NOT_LOADED);const t={faceTrackerCode:s(this,Oe),numOfWorkers:s(this,fe),mediaElement:s(this,g).mediaElement,mirrorVideo:s(this,g).mirrorVideo,metrics:s(this,g).metrics,displayMediaStream:s(this,g).displayMediaStream,isLoggingFaceTrackerWorkers:s(this,g).logger?.faceTrackerWorkers??!1,isLoggingSdk:s(this,g).logger?.sdk??!1,scaleFactor:s(this,Se),models:{detectorJson:s(this,ke),detectorBin:s(this,ve),landmarkJson:s(this,Ae),landmarkBin:s(this,ye)}};l(this,o,ae).call(this,j.LOADING),f(this,b,await Ei.init(t,s(this,v))),s(this,b).on.faceTrackersReady=(e,i,r,c)=>{l(this,o,E).call(this,`TFJS face tracker version ${i} loaded. Worker name: ${e} - workerId: ${r} - backend: ${c}`,m.mediaPipe),f(this,he,`${i}-${c}`),f(this,q,s(this,q)+1),s(this,v).setVersion(this.getVersion()),s(this,q)===s(this,fe)&&l(this,o,ae).call(this,j.LOADED)},s(this,b).on.frameAvailable=(e,i,r,c,d)=>{!c&&d?s(this,N).worker.postMessage({action:T.NEW_FRAME,payload:{frameNumber:i,frameTimestamp:e,frame:d,lastFrameNumber:r,tracked:c}},[d]):s(this,N).worker.postMessage({action:T.TRACKING_STATUS,payload:{frameNumber:i,frameTimestamp:e,lastFrameNumber:r,tracked:c}})},s(this,b).on.landmarksAvailable=(e,i,r)=>{const c=r/1e3;s(this,B)===0&&f(this,B,c),f(this,Te,c),s(this,b).numOftrackedVideoFrames+=1;const{starRating:d}=s(this,b),n=30,a=Math.min(s(this,Te)-s(this,B),n),u=s(this,B)>0?a/n*100:0,h={video:s(this,b).videoFpsTracker.fps.toFixed(1),faceTracker:s(this,b).faceTrackerFpsTracker.fps.toFixed(1)},p={face:e,annotations:i,starRating:d,percentCompleted:u,fps:h};this.on.facialLandmarksUpdated&&this.on.facialLandmarksUpdated(p)},s(this,b).on.scaleFactorChanged=e=>{f(this,Se,e),s(this,b).scaleFactor=e,s(this,N).worker.postMessage({action:T.SCALE_FACTOR_CHANGED,payload:{scaleFactor:e}})}},Ve=async function(){const t=new TextDecoder().decode(new Uint8Array(s(this,z)));f(this,N,xe.init(t,"module","EXTRACTION_WORKER"));const{studyCfgData:e}=s(this,x).getSession();e&&s(this,ce)&&s(this,z)&&(s(this,N).worker.onmessage=async i=>{const{data:r}=i,{id:c,result:d}=r,{action:n,payload:a}=d,u=s(this,se).get(c);if(u||c===-1){switch(n){case T.READY:{const{sdkId:h,version:p,workerName:_}=a;f(this,de,{version:p,sdkId:h}),l(this,o,E).call(this,`DFX extraction worker WASM loaded. SDK ID: ${h} - Version: ${p} - Worker Name: ${_}`,m.extractionLibWasm),await l(this,o,C).call(this,T.SET_MODE,{value:"discrete"},!0),await l(this,o,C).call(this,T.SET_NUMBER_OF_CHUNKS,{value:s(this,ie)},!0),await l(this,o,C).call(this,T.SET_TARGET_FPS,{value:s(this,ee)},!0),await l(this,o,C).call(this,T.SET_CHUNK_DURATION_SECONDS,{value:s(this,te)},!0),await l(this,o,C).call(this,T.SET_FRAME_ORDER,{value:ot.RGBA},!0),await l(this,o,C).call(this,T.GET_CONSTRAINTS_CONFIG,{},!0),f(this,Le,s(this,pe));break}case T.SET_MODE:{a&&l(this,o,E).call(this,`Set mode to ${a.mode}`,m.extractionLibWasm);break}case T.SET_NUMBER_OF_CHUNKS:{a&&l(this,o,E).call(this,`Set number of chunks to ${d.number}`,m.extractionLibWasm);break}case T.SET_TARGET_FPS:{a&&l(this,o,E).call(this,`Set target FPS to ${s(this,ee)}`,m.extractionLibWasm);break}case T.SET_CHUNK_DURATION_SECONDS:{a&&l(this,o,E).call(this,`Set chunk duration to ${s(this,te)} Seconds`,m.extractionLibWasm);break}case T.SET_FRAME_ORDER:{a&&l(this,o,E).call(this,"Set channel order RGBA",m.extractionLibWasm);break}case T.GET_CONSTRAINTS_CONFIG:{a&&(f(this,pe,a),l(this,o,E).call(this,`Get constraints ${JSON.stringify(a)}`,m.extractionLibWasm));break}case T.SET_CONSTRAINTS_CONFIG:{a&&(f(this,pe,a),l(this,o,E).call(this,`Set constraints ${JSON.stringify(a)}`,m.extractionLibWasm));break}case T.SET_FACE_ATTRIBUTE:{const{success:h,faceId:p,attribute:_,value:R}=a;h&&l(this,o,E).call(this,`Set face attribute: faceId: ${p}, attribute: ${_}, value: ${R}`,m.extractionLibWasm);break}case T.RESET_COLLECTION:{a&&l(this,o,E).call(this,"Reset collection",m.extractionLibWasm);break}case T.CANCEL_COLLECTION:{a&&l(this,o,E).call(this,"Collecttion cancelled",m.extractionLibWasm);break}case T.START_COLLECTION:{a&&l(this,o,E).call(this,`Collector started - state: ${a}`,m.extractionLibWasm);break}case T.SET_PORTS:{a&&l(this,o,E).call(this,"Ports set",m.extractionLibWasm);break}case T.COLLECTOR_ERROR:{if(a){const{error:h,frameNumber:p}=a;l(this,o,E).call(this,`Collector error on frame ${p}: ${h}`,m.extractionLibWasm),this.on.error&&this.on.error(Ce.COLLECTOR,a),await this.stopTracking()}break}case T.STAR_RATING:{s(this,b).starRating=a.rating;break}case T.ALL_FACE_TRACKERS_WARMED_UP:{const{frameNumber:h}=d;s(this,b).warmupFrameNumber=h,l(this,o,E).call(this,"All face tracker workers are warmed up.",m.mediaPipe),l(this,o,ae).call(this,j.READY);break}case T.CONSTRAINTS_UPDATED:{const{feedback:h,status:p}=a;this.on.constraintsUpdated&&this.on.constraintsUpdated(h,p);break}case T.SHOULD_END_MEASUREMENT_EARLY:{const{currentFinalChunkNumber:h,currentResultsOrder:p,newFinalChunkNumber:_}=d;l(this,o,E).call(this,`Request the end measurement early. Current final chunk number: ${h}, Current results order: ${p}, New final chunk number: ${_}`,m.extractionLibWasm);break}case T.GET_LOGS:{console.log(`DFX Log: ${a}`);break}case y.CONNECT:{f(this,Z,!0),f(this,B,0),l(this,o,E).call(this,a?"Connected":"Connection error",m.webSocket);break}case y.LOGIN_WITH_TOKEN_SUCCESS:{l(this,o,E).call(this,"Successfully logged in with token",m.webSocket);break}case y.SUBSCRIBED_TO_RESULTS:{l(this,o,E).call(this,"Subscribed to the results",m.webSocket);break}case y.CHUNK_SENT:{l(this,o,E).call(this,`Chunk sent ${JSON.stringify(a)}`,m.webSocket),this.on.chunkSent&&this.on.chunkSent(a);break}case y.DISCONNECT:{f(this,Z,!1),l(this,o,E).call(this,"Disconnect",m.webSocket);break}case y.DISCONNECTED:{l(this,o,E).call(this,`Disconnected! - code: ${a.code}, reason: ${a.reason}, wasClean: ${a.wasClean}`,m.webSocket),this.on.error&&this.on.error(Ce.WEB_SOCKET,a);break}case y.CHUNK_ACKNOWLEDGED:{l(this,o,E).call(this,`Chunk number ${a.chunkOrder} received by the server!`,m.webSocket),s(this,Q)===a.chunkOrder&&await this.stopTracking();break}case y.RESULTS_RECEIVED:{const{resultsOrder:h,finalChunkNumber:p}=a;this.on.resultsReceived&&this.on.resultsReceived(a),l(this,o,E).call(this,`Results received: ${JSON.stringify(a)}`,m.webSocket),h===p&&(await l(this,o,C).call(this,y.DISCONNECT,{},!0),await l(this,o,Ke).call(this),await l(this,o,Ie).call(this));break}case y.NETWORK_DELAY:{const{delay:h,description:p,actionId:_}=a;l(this,o,E).call(this,`Round-trip delay for ${p} call with Action ID ${_} was ${h.toFixed(2)} ms`,m.webSocket,{delay:h,actionId:_,description:p});break}case y.ERROR:{l(this,o,E).call(this,"Error",m.webSocket),this.on.error&&this.on.error(Ce.WEB_SOCKET,a);break}}u&&(u.resolve(d),s(this,se).delete(c))}},await l(this,o,C).call(this,T.INIT,{wasm:s(this,ce),studyConfigData:e,isLogging:s(this,g).logger?.extractionWorker||!1,metrics:s(this,g).metrics||!1,apiUrl:s(this,g).apiUrl,scaleFactor:s(this,Se)},!0))},Tt=async function(){if(s(this,b)&&s(this,Y)){const{age:e,height:i,weight:r,sex:c,smoking:d,bloodPressureMedication:n,diabetes:a}=s(this,Y);await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.SEX_ASSIGNED_AT_BIRTH,value:c},!0),await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.AGE_YEARS,value:e},!0),await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.HEIGHT_CM,value:i},!0),await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.WEIGHT_KG,value:r},!0),await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.SMOKER,value:d},!0),await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.BLOOD_PRESSURE_MEDICATION,value:n},!0),await l(this,o,C).call(this,T.SET_FACE_ATTRIBUTE,{faceId:"1",attribute:K.DIABETES,value:a},!0),l(this,o,E).call(this,`Set demographics for Face ID 1, ${JSON.stringify(s(this,Y))}`,m.extractionLibWasm)}},St=function(){},bt=function(){const t=new Date().toISOString();st(t)&&(l(this,o,E).call(this,`Action ID: ${s(this,A)}`,m.beforeRESTCall),this.on.beforeRESTCall&&this.on.beforeRESTCall(t,s(this,A)))},_t=function(t,e){},gt=function(t,e){const i=new Date().toISOString();st(i)&&(l(this,o,E).call(this,`Action ID: ${s(this,A)}, HTTP status code: ${t}, error: ${JSON.stringify(e)}`,m.afterRESTCall),this.on.afterRESTCall&&this.on.afterRESTCall(i,s(this,A),t,e))},wt=async function(){await l(this,o,C).call(this,T.CANCEL_COLLECTION,{},!0)},Ie=async function(){await l(this,o,C).call(this,T.START_COLLECTION,{},!0)},Ke=async function(){await l(this,o,C).call(this,T.RESET_COLLECTION,{},!0),await l(this,o,C).call(this,T.SET_NUMBER_OF_CHUNKS,{value:s(this,ie)},!0)},E=function(t,e,i){s(this,g).metrics&&s(this,v).log(t,e,"",!0,i),s(this,g).logger?.mediaPipe&&e===m.mediaPipe&&s(this,v).info(t,e),s(this,g).logger?.beforeRESTCall&&e===m.beforeRESTCall&&s(this,v).info(t,e),s(this,g).logger?.afterRESTCall&&e===m.afterRESTCall&&s(this,v).info(t,e),s(this,g).logger?.extractionLibWasm&&e===m.extractionLibWasm&&s(this,v).info(t,e),s(this,g).logger?.apiClient&&e===m.apiClient&&s(this,v).info(t,e),s(this,g).logger?.webSocket&&e===m.webSocket&&s(this,v).info(t,e),s(this,g).logger?.sdk&&e===m.sdk&&s(this,v).info(t,e)},Ct=async function(t){f(this,A,0);const e=performance.now(),i=await s(this,x).http.auths.validate(t),r=performance.now()-e,{status:c,body:d}=i;if(l(this,o,E).call(this,c==="200"?"Successfully validated the Token":`Failed to validate token. Status: ${c}`,m.apiClient,{delay:r,actionId:s(this,A),description:"Validate Token"}),c==="200"){const{Region:n}=d;return{region:n,status:c}}else return{status:c,region:""}},Rt=async function(t,e,i){f(this,A,2304);const r=performance.now(),c=await s(this,x).http.auths.renew({Token:t,RefreshToken:e},i),d=performance.now()-r,{status:n}=c;return l(this,o,E).call(this,n==="200"?"Successfully refreshed the Token":`Failed to refresh token. Status: ${n}`,m.apiClient,{delay:d,actionId:s(this,A),description:"Refresh Token"}),n==="200"},kt=async function(t,e){f(this,A,806);const i=performance.now();f(this,Ne,t);const r=await s(this,x).http.studies.retrieveSdkConfigData({StudyID:t,...e&&{sdkId:e}},"user"),c=performance.now()-i,{status:d}=r;return l(this,o,E).call(this,d==="200"?"Retrieve SDK Config Data - success":"Retrieve SDK Config Data - failure",m.apiClient,{delay:c,actionId:s(this,A),description:"Retrieve SDK Config Data"}),d==="200"},vt=async function(t){l(this,o,E).call(this,"Get Measurement ID",m.apiClient),f(this,A,504);const e=performance.now(),i={StudyID:s(this,Ne),Resolution:100};t.partnerId&&(i.PartnerID=t.partnerId),t.userProfileId&&(i.UserProfileID=t.userProfileId);const r=await s(this,x).http.measurements.create(i,"user"),c=performance.now()-e,{status:d,body:n}=r;let a="";d==="200"?(f(this,F,n.ID),a=`Successfully obtained measurement ID: ${s(this,F)}`):(f(this,F,""),a=`Failed to obtain measurement ID. Status: ${d}`),l(this,o,E).call(this,a,m.apiClient,{delay:c,actionId:s(this,A),measurementId:s(this,F),description:"Get Measurement ID"})},ae=function(t){f(this,me,t),l(this,o,E).call(this,`Face tracker state changed: ${t}`,m.mediaPipe),this.on.faceTrackerStateChanged&&this.on.faceTrackerStateChanged(s(this,me))},C=function(t,e,i=!1){return new Promise(r=>{const c=bi(this,De)._++;s(this,se).set(c,{resolve:r,action:t});const d=()=>s(this,N).worker.postMessage({id:c,action:t,payload:e});i?f(this,Ee,s(this,Ee).then(d).catch(n=>console.error(n))):d()})},ut(_i,"VERSION",Je);const gi=document.documentElement.style.overflow;class wi{static VERSION=Nt;#e=document.createElement("div");#t=document.createElement("div");on={results:null,error:null,event:null};constructor(){this.#e.style.height="100%"}init(e){const{container:i,appPath:r,settings:c,profile:d,config:n,loadError:a,language:u,apiUrl:h}=e;this.#t=i,document.body.appendChild(i);const p=i.attachShadow({mode:"open"});document.documentElement.style.overflow="hidden";const _="app",R=document.createElement("link");R.rel="stylesheet",R.href=`${r}/stylex.css`,p.appendChild(R);const k=document.createElement("link");k.rel="stylesheet",k.href=`${r}/${_}.css`,p.appendChild(k);const L=H=>{this.on.results&&this.on.results({...H.detail})},W=H=>{this.on.error&&this.on.error({...H.detail})},G=H=>{this.on.event&&this.on.event({...H.detail})};this.#e.addEventListener($.RESULTS,L),this.#e.addEventListener($.ERROR,W),this.#e.addEventListener($.APPEVENT,G),p.appendChild(this.#e);const M=document.createElement("script");M.type="module",M.src=`${r}/${_}.mjs`,M.onload=()=>{import(M.src).then(H=>{H.app.init(this.#e,r,c,d,h,n,u)}).catch(()=>{a&&a("Failed to initialize Measurement Embedded React app")})},M.onerror=()=>{a&&a("Failed to load the measurement embedded app script")},p.appendChild(M)}destroy(){const e=new CustomEvent("measurement-embedded-app-action",{detail:{action:re.DESTROY,data:{}}});this.#e.dispatchEvent(e),document.documentElement.style.overflow=gi,this.#t&&document.body.contains(this.#t)&&document.body.removeChild(this.#t)}setTheme(e){const i=new CustomEvent("measurement-embedded-app-action",{detail:{action:re.SET_THEME,data:{theme:e}}});this.#e.dispatchEvent(i)}setLanguage(e){const i=new CustomEvent("measurement-embedded-app-action",{detail:{action:re.SET_LANGUAGE,data:{language:e}}});this.#e.dispatchEvent(i)}async cancel(e){return new Promise(i=>{const r=d=>{this.#e.removeEventListener($.CANCELLED,r),i(d.detail.reset)};this.#e.addEventListener($.CANCELLED,r);const c=new CustomEvent("measurement-embedded-app-action",{detail:{action:re.CANCEL,data:{reset:e}}});this.#e.dispatchEvent(c)})}getLogs(){return new Promise(e=>{const i=c=>{this.#e.removeEventListener($.LOGS,i),e(c.detail.logs)};this.#e.addEventListener($.LOGS,i);const r=new CustomEvent("measurement-embedded-app-action",{detail:{action:re.GET_LOGS,data:{}}});this.#e.dispatchEvent(r)})}}export{Ye as ErrorCodes,Lt as appEvents,wi as default,di as faceAttributeValue,je as logCategory,$ as measurementEmbeddedAppEvents};
|