diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6c2c52f9..0b52ac54 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,10 +11,11 @@
### **HEAD -> main** 2022/04/11 mandic00@live.com
+- face attention model is available in human-models
+- beta release 2.7
+- refactor draw methods
- implement face attention model
-
-### **origin/main** 2022/04/10 mandic00@live.com
-
+- add electronjs demo
- rebuild
### **2.6.5** 2022/04/01 mandic00@live.com
diff --git a/dist/human.d.ts b/dist/human.d.ts
index d965b941..d82c1c15 100644
--- a/dist/human.d.ts
+++ b/dist/human.d.ts
@@ -1,3 +1,5 @@
+///
+
/** meta-function that performs draw for: canvas, face, body, hand */
declare function all(inCanvas: AnyCanvas, result: Result, drawOptions?: Partial): Promise<[void, void, void, void, void] | null>;
diff --git a/dist/human.esm-nobundle.d.ts b/dist/human.esm-nobundle.d.ts
index d965b941..d82c1c15 100644
--- a/dist/human.esm-nobundle.d.ts
+++ b/dist/human.esm-nobundle.d.ts
@@ -1,3 +1,5 @@
+///
+
/** meta-function that performs draw for: canvas, face, body, hand */
declare function all(inCanvas: AnyCanvas, result: Result, drawOptions?: Partial): Promise<[void, void, void, void, void] | null>;
diff --git a/dist/human.esm-nobundle.js b/dist/human.esm-nobundle.js
index fba4d53d..c1935034 100644
--- a/dist/human.esm-nobundle.js
+++ b/dist/human.esm-nobundle.js
@@ -4,7 +4,7 @@
author: '
*/
-var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Object.getOwnPropertyNames;var fr=Object.prototype.hasOwnProperty;var mr=(e,t,o)=>t in e?Ft(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var $0=(e,t)=>{for(var o in t)Ft(e,o,{get:t[o],enumerable:!0})},To=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let A of dr(t))!fr.call(e,A)&&A!==o&&Ft(e,A,{get:()=>t[A],enumerable:!(n=cr(t,A))||n.enumerable});return e},Z=(e,t,o)=>(To(e,t,"default"),o&&To(o,t,"default"));var k=(e,t,o)=>(mr(e,typeof t!="symbol"?t+"":t,o),o),wo=(e,t,o)=>{if(!t.has(e))throw TypeError("Cannot "+o)};var Le=(e,t,o)=>(wo(e,t,"read from private field"),o?o.call(e):t.get(e)),Ne=(e,t,o)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,o)},Ge=(e,t,o,n)=>(wo(e,t,"write to private field"),n?n.call(e,o):t.set(e,o),o);function b(...e){let t=new Date,o=`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}.${t.getMilliseconds().toString().padStart(3,"0")}`;e&&console.log(o,"Human:",...e)}function Ro(e,t){let o=e.endsWith("/")?"":"/",A=t.startsWith(".")||t.startsWith("/")||t.startsWith("http:")||t.startsWith("https:")||t.startsWith("file:")?`${t}`:`${e}${o}${t}`;if(!A.toLocaleLowerCase().includes(".json"))throw new Error(`modelpath error: expecting json file: ${A}`);return A}var g=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function Ht(e,t,o="config",n=[]){for(let A of Object.keys(t))if(typeof t[A]=="object")Ht(e[A],t[A],A,n);else{let s=e&&typeof e[A]!="undefined";s||n.push({reason:"unknown property",where:`${o}.${A} = ${t[A]}`});let a=e&&typeof e[A]==typeof t[A];s&&!a&&n.push({reason:"property type mismatch",where:`${o}.${A} = ${t[A]}`,expected:typeof e[A]})}return t.debug&&o==="config"&&n.length>0&&b("invalid configuration",n),n}function Y(...e){let t=o=>o&&typeof o=="object";return e.reduce((o,n)=>(Object.keys(n||{}).forEach(A=>{let s=o[A],a=n[A];Array.isArray(s)&&Array.isArray(a)?o[A]=s.concat(...a):t(s)&&t(a)?o[A]=Y(s,a):o[A]=a}),o),{})}var ee={backend:"",modelBasePath:"",cacheModels:!0,wasmPath:"",wasmPlatformFetch:!1,debug:!0,async:!0,warmup:"full",cacheSensitivity:.7,skipAllowed:!1,deallocate:!1,filter:{enabled:!0,equalization:!1,width:0,height:0,flip:!1,return:!0,brightness:0,contrast:0,sharpness:0,blur:0,saturation:0,hue:0,negative:!1,sepia:!1,vintage:!1,kodachrome:!1,technicolor:!1,polaroid:!1,pixelate:0},gesture:{enabled:!0},face:{enabled:!0,detector:{modelPath:"blazeface.json",rotation:!0,maxDetected:1,skipFrames:99,skipTime:2500,minConfidence:.2,iouThreshold:.1,mask:!1,return:!1},mesh:{enabled:!0,modelPath:"facemesh.json"},attention:{enabled:!1,modelPath:"facemesh-attention.json"},iris:{enabled:!0,modelPath:"iris.json"},emotion:{enabled:!0,minConfidence:.1,skipFrames:99,skipTime:1500,modelPath:"emotion.json"},description:{enabled:!0,modelPath:"faceres.json",skipFrames:99,skipTime:3e3,minConfidence:.1},antispoof:{enabled:!1,skipFrames:99,skipTime:4e3,modelPath:"antispoof.json"},liveness:{enabled:!1,skipFrames:99,skipTime:4e3,modelPath:"liveness.json"}},body:{enabled:!0,modelPath:"movenet-lightning.json",maxDetected:-1,minConfidence:.3,skipFrames:1,skipTime:200},hand:{enabled:!0,rotation:!0,skipFrames:99,skipTime:1e3,minConfidence:.5,iouThreshold:.2,maxDetected:-1,landmarks:!0,detector:{modelPath:"handtrack.json"},skeleton:{modelPath:"handlandmark-full.json"}},object:{enabled:!1,modelPath:"mb3-centernet.json",minConfidence:.2,iouThreshold:.4,maxDetected:10,skipFrames:99,skipTime:2e3},segmentation:{enabled:!1,modelPath:"selfie.json",blur:8}};var r={};$0(r,{GraphModel:()=>Vt,Tensor:()=>xe,version:()=>Be});Z(r,rs);Z(r,ss);import*as rs from"@tensorflow/tfjs/dist/index.js";import*as ss from"@tensorflow/tfjs-backend-webgl/dist/index.js";import{Tensor as xe}from"@tensorflow/tfjs/dist/index.js";import{GraphModel as Vt}from"@tensorflow/tfjs-converter/dist/index";var pr="3.15.0",ur="3.15.0",hr="3.15.0",br="3.15.0",gr="3.15.0",Mr="3.15.0",Pr="3.15.0",vr="3.15.0",Be={tfjs:pr,"tfjs-core":ur,"tfjs-data":hr,"tfjs-layers":br,"tfjs-converter":gr,"tfjs-backend-cpu":Mr,"tfjs-backend-webgl":Pr,"tfjs-backend-wasm":vr};var ko=`
+var Ht=Object.defineProperty;var dr=Object.getOwnPropertyDescriptor;var fr=Object.getOwnPropertyNames;var mr=Object.prototype.hasOwnProperty;var pr=(e,t,o)=>t in e?Ht(e,t,{enumerable:!0,configurable:!0,writable:!0,value:o}):e[t]=o;var ee=(e,t)=>{for(var o in t)Ht(e,o,{get:t[o],enumerable:!0})},Ro=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let A of fr(t))!mr.call(e,A)&&A!==o&&Ht(e,A,{get:()=>t[A],enumerable:!(n=dr(t,A))||n.enumerable});return e},Z=(e,t,o)=>(Ro(e,t,"default"),o&&Ro(o,t,"default"));var k=(e,t,o)=>(pr(e,typeof t!="symbol"?t+"":t,o),o),wo=(e,t,o)=>{if(!t.has(e))throw TypeError("Cannot "+o)};var Ne=(e,t,o)=>(wo(e,t,"read from private field"),o?o.call(e):t.get(e)),Ge=(e,t,o)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,o)},Be=(e,t,o,n)=>(wo(e,t,"write to private field"),n?n.call(e,o):t.set(e,o),o);function b(...e){let t=new Date,o=`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}.${t.getMilliseconds().toString().padStart(3,"0")}`;e&&console.log(o,"Human:",...e)}function ko(e,t){let o=e.endsWith("/")?"":"/",A=t.startsWith(".")||t.startsWith("/")||t.startsWith("http:")||t.startsWith("https:")||t.startsWith("file:")?`${t}`:`${e}${o}${t}`;if(!A.toLocaleLowerCase().includes(".json"))throw new Error(`modelpath error: expecting json file: ${A}`);return A}var g=()=>typeof performance!="undefined"?performance.now():parseInt((Number(process.hrtime.bigint())/1e3/1e3).toString());function Vt(e,t,o="config",n=[]){for(let A of Object.keys(t))if(typeof t[A]=="object")Vt(e[A],t[A],A,n);else{let s=e&&typeof e[A]!="undefined";s||n.push({reason:"unknown property",where:`${o}.${A} = ${t[A]}`});let a=e&&typeof e[A]==typeof t[A];s&&!a&&n.push({reason:"property type mismatch",where:`${o}.${A} = ${t[A]}`,expected:typeof e[A]})}return t.debug&&o==="config"&&n.length>0&&b("invalid configuration",n),n}function Y(...e){let t=o=>o&&typeof o=="object";return e.reduce((o,n)=>(Object.keys(n||{}).forEach(A=>{let s=o[A],a=n[A];Array.isArray(s)&&Array.isArray(a)?o[A]=s.concat(...a):t(s)&&t(a)?o[A]=Y(s,a):o[A]=a}),o),{})}var te={backend:"",modelBasePath:"",cacheModels:!0,wasmPath:"",wasmPlatformFetch:!1,debug:!0,async:!0,warmup:"full",cacheSensitivity:.7,skipAllowed:!1,deallocate:!1,filter:{enabled:!0,equalization:!1,width:0,height:0,flip:!1,return:!0,brightness:0,contrast:0,sharpness:0,blur:0,saturation:0,hue:0,negative:!1,sepia:!1,vintage:!1,kodachrome:!1,technicolor:!1,polaroid:!1,pixelate:0},gesture:{enabled:!0},face:{enabled:!0,detector:{modelPath:"blazeface.json",rotation:!0,maxDetected:1,skipFrames:99,skipTime:2500,minConfidence:.2,iouThreshold:.1,mask:!1,return:!1},mesh:{enabled:!0,modelPath:"facemesh.json"},attention:{enabled:!1,modelPath:"facemesh-attention.json"},iris:{enabled:!0,modelPath:"iris.json"},emotion:{enabled:!0,minConfidence:.1,skipFrames:99,skipTime:1500,modelPath:"emotion.json"},description:{enabled:!0,modelPath:"faceres.json",skipFrames:99,skipTime:3e3,minConfidence:.1},antispoof:{enabled:!1,skipFrames:99,skipTime:4e3,modelPath:"antispoof.json"},liveness:{enabled:!1,skipFrames:99,skipTime:4e3,modelPath:"liveness.json"}},body:{enabled:!0,modelPath:"movenet-lightning.json",maxDetected:-1,minConfidence:.3,skipFrames:1,skipTime:200},hand:{enabled:!0,rotation:!0,skipFrames:99,skipTime:1e3,minConfidence:.5,iouThreshold:.2,maxDetected:-1,landmarks:!0,detector:{modelPath:"handtrack.json"},skeleton:{modelPath:"handlandmark-full.json"}},object:{enabled:!1,modelPath:"mb3-centernet.json",minConfidence:.2,iouThreshold:.4,maxDetected:10,skipFrames:99,skipTime:2e3},segmentation:{enabled:!1,modelPath:"selfie.json",blur:8}};var r={};ee(r,{GraphModel:()=>Zt,Tensor:()=>ce,version:()=>Fe});Z(r,ss);Z(r,as);import*as ss from"@tensorflow/tfjs/dist/index.js";import*as as from"@tensorflow/tfjs-backend-webgl/dist/index.js";import{Tensor as ce}from"@tensorflow/tfjs/dist/index.js";import{GraphModel as Zt}from"@tensorflow/tfjs-converter/dist/index";var ur="3.15.0",hr="3.15.0",br="3.15.0",gr="3.15.0",Mr="3.15.0",Pr="3.15.0",vr="3.15.0",Tr="3.15.0",Fe={tfjs:ur,"tfjs-core":hr,"tfjs-data":br,"tfjs-layers":gr,"tfjs-converter":Mr,"tfjs-backend-cpu":Pr,"tfjs-backend-webgl":vr,"tfjs-backend-wasm":Tr};var Eo=`
precision highp float;
attribute vec2 pos;
attribute vec2 uv;
@@ -14,7 +14,7 @@ var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Objec
vUv = uv;
gl_Position = vec4(pos.x, pos.y*flipY, 0.0, 1.);
}
-`;var Eo=`
+`;var zo=`
precision highp float;
varying vec2 vUv;
uniform sampler2D texture;
@@ -26,7 +26,7 @@ var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Objec
gl_FragColor.b = m[10] * c.r + m[11] * c.g + m[12] * c.b + m[13] * c.a + m[14];
gl_FragColor.a = m[15] * c.r + m[16] * c.g + m[17] * c.b + m[18] * c.a + m[19];
}
-`,zo=`
+`,jo=`
precision highp float;
varying vec2 vUv;
uniform sampler2D texture;
@@ -38,7 +38,7 @@ var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Objec
gl_FragColor.b = m[10] * c.r + m[11] * c.g + m[12] * c.b + m[14];
gl_FragColor.a = c.a;
}
-`,jo=`
+`,So=`
precision highp float;
varying vec2 vUv;
uniform vec2 size;
@@ -51,7 +51,7 @@ var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Objec
vec2 coord = pixelate(vUv, size);
gl_FragColor += texture2D(texture, coord);
}
-`,So=`
+`,Wo=`
precision highp float;
varying vec2 vUv;
uniform sampler2D texture;
@@ -96,7 +96,7 @@ var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Objec
c31 * m[6] + c32 * m[7] + c33 * m[8];
gl_FragColor.a = c22.a;
}
-`;var Zt=(e,t,o)=>{let n=new RegExp("\\b"+t+" \\w+ (\\w+)","ig");e.replace(n,(A,s)=>(o[s]=0,A))},Xt=class{constructor(t,o,n){k(this,"uniform",{});k(this,"attribute",{});k(this,"gl");k(this,"id");k(this,"compile",(t,o)=>{let n=this.gl.createShader(o);return n?(this.gl.shaderSource(n,t),this.gl.compileShader(n),this.gl.getShaderParameter(n,this.gl.COMPILE_STATUS)?n:(b(`filter: gl compile failed: ${this.gl.getShaderInfoLog(n)}`),null)):(b("filter: could not create shader"),null)});this.gl=t;let A=this.compile(o,this.gl.VERTEX_SHADER),s=this.compile(n,this.gl.FRAGMENT_SHADER);if(this.id=this.gl.createProgram(),!(!A||!s)){if(!this.id){b("filter: could not create webgl program");return}if(this.gl.attachShader(this.id,A),this.gl.attachShader(this.id,s),this.gl.linkProgram(this.id),!this.gl.getProgramParameter(this.id,this.gl.LINK_STATUS)){b(`filter: gl link failed: ${this.gl.getProgramInfoLog(this.id)}`);return}this.gl.useProgram(this.id),Zt(o,"attribute",this.attribute);for(let a in this.attribute)this.attribute[a]=this.gl.getAttribLocation(this.id,a);Zt(o,"uniform",this.uniform),Zt(n,"uniform",this.uniform);for(let a in this.uniform)this.uniform[a]=this.gl.getUniformLocation(this.id,a)}}};function Wo(){let e=0,t=null,o=!1,n=-1,A=[null,null],s=[],a=null,i=null,x=a0(100,100),d={},l={INTERMEDIATE:1},y=x.getContext("webgl");if(!y){b("filter: cannot get webgl context");return}this.gl=y;function c(u,p){if(!(u===x.width&&p===x.height)){if(x.width=u,x.height=p,!a){let P=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,-1,1,0,0,1,-1,1,1,1,1,1,0]);a=y.createBuffer(),y.bindBuffer(y.ARRAY_BUFFER,a),y.bufferData(y.ARRAY_BUFFER,P,y.STATIC_DRAW),y.pixelStorei(y.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0)}y.viewport(0,0,x.width,x.height),A=[null,null]}}function f(u,p){let P=y.createFramebuffer();y.bindFramebuffer(y.FRAMEBUFFER,P);let R=y.createRenderbuffer();y.bindRenderbuffer(y.RENDERBUFFER,R);let S=y.createTexture();return y.bindTexture(y.TEXTURE_2D,S),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,u,p,0,y.RGBA,y.UNSIGNED_BYTE,null),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,y.CLAMP_TO_EDGE),y.framebufferTexture2D(y.FRAMEBUFFER,y.COLOR_ATTACHMENT0,y.TEXTURE_2D,S,0),y.bindTexture(y.TEXTURE_2D,null),y.bindFramebuffer(y.FRAMEBUFFER,null),{fbo:P,texture:S}}function h(u){return A[u]=A[u]||f(x.width,x.height),A[u]}function m(u=0){if(!i)return;let p=null,P=null,R=!1;e===0?p=t:p=h(n).texture||null,e++,o&&!(u&l.INTERMEDIATE)?(P=null,R=e%2===0):(n=(n+1)%2,P=h(n).fbo||null),y.bindTexture(y.TEXTURE_2D,p),y.bindFramebuffer(y.FRAMEBUFFER,P),y.uniform1f(i.uniform.flipY,R?-1:1),y.drawArrays(y.TRIANGLES,0,6)}function v(u){if(d[u])return i=d[u],y.useProgram((i?i.id:null)||null),i;if(i=new Xt(y,ko,u),!i)return b("filter: could not get webgl program"),null;let p=Float32Array.BYTES_PER_ELEMENT,P=4*p;return y.enableVertexAttribArray(i.attribute.pos),y.vertexAttribPointer(i.attribute.pos,2,y.FLOAT,!1,P,0*p),y.enableVertexAttribArray(i.attribute.uv),y.vertexAttribPointer(i.attribute.uv,2,y.FLOAT,!1,P,2*p),d[u]=i,i}let M={colorMatrix:u=>{let p=new Float32Array(u);p[4]/=255,p[9]/=255,p[14]/=255,p[19]/=255;let P=p[18]===1&&p[3]===0&&p[8]===0&&p[13]===0&&p[15]===0&&p[16]===0&&p[17]===0&&p[19]===0?zo:Eo,R=v(P);!R||(y.uniform1fv(R.uniform.m,p),m())},brightness:u=>{let p=(u||0)+1;M.colorMatrix([p,0,0,0,0,0,p,0,0,0,0,0,p,0,0,0,0,0,1,0])},saturation:u=>{let p=(u||0)*2/3+1,P=(p-1)*-.5;M.colorMatrix([p,P,P,0,0,P,p,P,0,0,P,P,p,0,0,0,0,0,1,0])},desaturate:()=>{M.saturation(-1)},contrast:u=>{let p=(u||0)+1,P=-128*(p-1);M.colorMatrix([p,0,0,0,P,0,p,0,0,P,0,0,p,0,P,0,0,0,1,0])},negative:()=>{M.contrast(-2)},hue:u=>{u=(u||0)/180*Math.PI;let p=Math.cos(u),P=Math.sin(u),R=.213,S=.715,O=.072;M.colorMatrix([R+p*(1-R)+P*-R,S+p*-S+P*-S,O+p*-O+P*(1-O),0,0,R+p*-R+P*.143,S+p*(1-S)+P*.14,O+p*-O+P*-.283,0,0,R+p*-R+P*-(1-R),S+p*-S+P*S,O+p*(1-O)+P*O,0,0,0,0,0,1,0])},desaturateLuminance:()=>{M.colorMatrix([.2764723,.929708,.0938197,0,-37.1,.2764723,.929708,.0938197,0,-37.1,.2764723,.929708,.0938197,0,-37.1,0,0,0,1,0])},sepia:()=>{M.colorMatrix([.393,.7689999,.18899999,0,0,.349,.6859999,.16799999,0,0,.272,.5339999,.13099999,0,0,0,0,0,1,0])},brownie:()=>{M.colorMatrix([.5997023498159715,.34553243048391263,-.2708298674538042,0,47.43192855600873,-.037703249837783157,.8609577587992641,.15059552388459913,0,-36.96841498319127,.24113635128153335,-.07441037908422492,.44972182064877153,0,-7.562075277591283,0,0,0,1,0])},vintagePinhole:()=>{M.colorMatrix([.6279345635605994,.3202183420819367,-.03965408211312453,0,9.651285835294123,.02578397704808868,.6441188644374771,.03259127616149294,0,7.462829176470591,.0466055556782719,-.0851232987247891,.5241648018700465,0,5.159190588235296,0,0,0,1,0])},kodachrome:()=>{M.colorMatrix([1.1285582396593525,-.3967382283601348,-.03992559172921793,0,63.72958762196502,-.16404339962244616,1.0835251566291304,-.05498805115633132,0,24.732407896706203,-.16786010706155763,-.5603416277695248,1.6014850761964943,0,35.62982807460946,0,0,0,1,0])},technicolor:()=>{M.colorMatrix([1.9125277891456083,-.8545344976951645,-.09155508482755585,0,11.793603434377337,-.3087833385928097,1.7658908555458428,-.10601743074722245,0,-70.35205161461398,-.231103377548616,-.7501899197440212,1.847597816108189,0,30.950940869491138,0,0,0,1,0])},polaroid:()=>{M.colorMatrix([1.438,-.062,-.062,0,0,-.122,1.378,-.122,0,0,-.016,-.016,1.483,0,0,0,0,0,1,0])},shiftToBGR:()=>{M.colorMatrix([0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0])},convolution:u=>{let p=new Float32Array(u),P=1/x.width,R=1/x.height,S=v(Co);!S||(y.uniform1fv(S.uniform.m,p),y.uniform2f(S.uniform.px,P,R),m())},detectEdges:()=>{M.convolution.call(this,[0,1,0,1,-4,1,0,1,0])},sobelX:()=>{M.convolution.call(this,[-1,0,1,-2,0,2,-1,0,1])},sobelY:()=>{M.convolution.call(this,[-1,-2,-1,0,0,0,1,2,1])},sharpen:u=>{let p=u||1;M.convolution.call(this,[0,-1*p,0,-1*p,1+4*p,-1*p,0,-1*p,0])},emboss:u=>{let p=u||1;M.convolution.call(this,[-2*p,-1*p,0,-1*p,1,1*p,0,1*p,2*p])},blur:u=>{let p=u/7/x.width,P=u/7/x.height,R=v(So);!R||(y.uniform2f(R.uniform.px,0,P),m(l.INTERMEDIATE),y.uniform2f(R.uniform.px,p,0),m())},pixelate:u=>{let p=u/x.width,P=u/x.height,R=v(jo);!R||(y.uniform2f(R.uniform.size,p,P),m())}};this.add=function(u){let p=Array.prototype.slice.call(arguments,1),P=M[u];s.push({func:P,args:p})},this.reset=function(){s=[]},this.get=function(){return s},this.apply=function(u){c(u.width,u.height),e=0,t||(t=y.createTexture()),y.bindTexture(y.TEXTURE_2D,t),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,y.NEAREST),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,y.NEAREST),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,u);for(let p=0;pf.data())),a=.99*Math.max(s[0][0],s[1][0],s[2][0]),i=[r.sub(o[0],n[0]),r.sub(o[1],n[1]),r.sub(o[2],n[2])],x=[r.sub(A[0],n[0]),r.sub(A[1],n[1]),r.sub(A[2],n[2])],d=[r.div(a,x[0]),r.div(a,x[1]),r.div(a,x[2])],l=[r.mul(i[0],d[0]),r.mul(i[1],d[1]),r.mul(i[2],d[2])],y=r.stack([l[0],l[1],l[2]],2),c=r.reshape(y,[1,t.shape[0],t.shape[1],3]);return r.dispose([...o,...n,...A,...i,...x,...d,...l,y,t]),c}var et=2048,F=null,_=null,ce=null,D,O0={inputSum:0,cacheDiff:1,sumMethod:0,inputTensor:void 0};function a0(e,t){let o;if(w.browser)if(w.worker){if(typeof OffscreenCanvas=="undefined")throw new Error("canvas error: attempted to run in web worker but OffscreenCanvas is not supported");o=new OffscreenCanvas(e,t)}else{if(typeof document=="undefined")throw new Error("canvas error: attempted to run in browser but DOM is not defined");o=document.createElement("canvas"),o.width=e,o.height=t}else typeof w.Canvas!="undefined"?o=new w.Canvas(e,t):typeof globalThis.Canvas!="undefined"&&(o=new globalThis.Canvas(e,t));return o}function tt(e,t){let o=t||a0(e.width,e.height);return o.getContext("2d").drawImage(e,0,0),o}async function de(e,t,o=!0){if(!e)return t.debug&&b("input error: input is missing"),{tensor:null,canvas:null};if(!(e instanceof xe)&&!(typeof Image!="undefined"&&e instanceof Image)&&!(typeof w.Canvas!="undefined"&&e instanceof w.Canvas)&&!(typeof globalThis.Canvas!="undefined"&&e instanceof globalThis.Canvas)&&!(typeof ImageData!="undefined"&&e instanceof ImageData)&&!(typeof ImageBitmap!="undefined"&&e instanceof ImageBitmap)&&!(typeof HTMLImageElement!="undefined"&&e instanceof HTMLImageElement)&&!(typeof HTMLMediaElement!="undefined"&&e instanceof HTMLMediaElement)&&!(typeof HTMLVideoElement!="undefined"&&e instanceof HTMLVideoElement)&&!(typeof HTMLCanvasElement!="undefined"&&e instanceof HTMLCanvasElement)&&!(typeof OffscreenCanvas!="undefined"&&e instanceof OffscreenCanvas))throw new Error("input error: type is not recognized");if(e instanceof xe){let n=null;if(e.isDisposedInternal)throw new Error("input error: attempted to use tensor but it is disposed");if(!e.shape)throw new Error("input error: attempted to use tensor without a shape");if(e.shape.length===3){if(e.shape[2]===3)n=r.expandDims(e,0);else if(e.shape[2]===4){let A=r.slice3d(e,[0,0,0],[-1,-1,3]);n=r.expandDims(A,0),r.dispose(A)}}else e.shape.length===4&&(e.shape[3]===3?n=r.clone(e):e.shape[3]===4&&(n=r.slice4d(e,[0,0,0,0],[-1,-1,-1,3])));if(n==null||n.shape.length!==4||n.shape[0]!==1||n.shape[3]!==3)throw new Error(`input error: attempted to use tensor with unrecognized shape: ${e.shape}`);if(n.dtype==="int32"){let A=r.cast(n,"float32");r.dispose(n),n=A}return{tensor:n,canvas:t.filter.return?_:null}}else{if(typeof e.readyState!="undefined"&&e.readyState<=2)return t.debug&&b("input stream is not ready"),{tensor:null,canvas:F};let n=e.naturalWidth||e.videoWidth||e.width||e.shape&&e.shape[1]>0,A=e.naturalHeight||e.videoHeight||e.height||e.shape&&e.shape[2]>0;if(!n||!A)return t.debug&&b("cannot determine input dimensions"),{tensor:null,canvas:F};let s=n,a=A;if(s>et&&(s=et,a=Math.trunc(s*A/n)),a>et&&(a=et,s=Math.trunc(a*n/A)),(t.filter.width||0)>0?s=t.filter.width:(t.filter.height||0)>0&&(s=n*((t.filter.height||0)/A)),(t.filter.height||0)>0?a=t.filter.height:(t.filter.width||0)>0&&(a=A*((t.filter.width||0)/n)),!s||!a)throw new Error("input error: cannot determine dimension");(!F||(F==null?void 0:F.width)!==s||(F==null?void 0:F.height)!==a)&&(F=a0(s,a));let i=F.getContext("2d");if(typeof ImageData!="undefined"&&e instanceof ImageData?i.putImageData(e,0,0):t.filter.flip&&typeof i.translate!="undefined"?(i.translate(n,0),i.scale(-1,1),i.drawImage(e,0,0,n,A,0,0,F==null?void 0:F.width,F==null?void 0:F.height),i.setTransform(1,0,0,1,0,0)):i.drawImage(e,0,0,n,A,0,0,F==null?void 0:F.width,F==null?void 0:F.height),(!_||F.width!==_.width||(F==null?void 0:F.height)!==(_==null?void 0:_.height))&&(_=a0(F.width,F.height)),t.filter.enabled&&w.webgl.supported?(D||(D=w.browser?new Wo:null),w.filter=!!D,!D||!D.add?(t.debug&&b("input process error: cannot initialize filters"),w.webgl.supported=!1,t.filter.enabled=!1,tt(F,_)):(D.reset(),t.filter.brightness!==0&&D.add("brightness",t.filter.brightness),t.filter.contrast!==0&&D.add("contrast",t.filter.contrast),t.filter.sharpness!==0&&D.add("sharpen",t.filter.sharpness),t.filter.blur!==0&&D.add("blur",t.filter.blur),t.filter.saturation!==0&&D.add("saturation",t.filter.saturation),t.filter.hue!==0&&D.add("hue",t.filter.hue),t.filter.negative&&D.add("negative"),t.filter.sepia&&D.add("sepia"),t.filter.vintage&&D.add("brownie"),t.filter.sepia&&D.add("sepia"),t.filter.kodachrome&&D.add("kodachrome"),t.filter.technicolor&&D.add("technicolor"),t.filter.polaroid&&D.add("polaroid"),t.filter.pixelate!==0&&D.add("pixelate",t.filter.pixelate),D.get()>0?_=D.apply(F):_=D.draw(F))):(tt(F,_),D&&(D=null),w.filter=!!D),!o)return{tensor:null,canvas:_};if(!_)throw new Error("canvas error: cannot create output");let x,d=3;if(typeof ImageData!="undefined"&&e instanceof ImageData||e.data&&e.width&&e.height)if(w.browser&&r.browser)x=r.browser?r.browser.fromPixels(e):null;else{d=e.data.length/e.height/e.width;let c=new Uint8Array(e.data.buffer);x=r.tensor(c,[e.height,e.width,d],"int32")}else if((!ce||_.width!==ce.width||_.height!==ce.height)&&(ce=a0(_.width,_.height)),r.browser&&w.browser)t.backend==="webgl"||t.backend==="humangl"||t.backend==="webgpu"?x=r.browser.fromPixels(_):(ce=tt(_),x=r.browser.fromPixels(ce));else{let h=tt(_).getContext("2d").getImageData(0,0,s,a);d=h.data.length/s/a;let m=new Uint8Array(h.data.buffer);x=r.tensor(m,[s,a,d])}if(d===4){let c=r.slice3d(x,[0,0,0],[-1,-1,3]);r.dispose(x),x=c}if(!x)throw new Error("input error: cannot create tensor");let l=r.cast(x,"float32"),y=t.filter.equalization?await $e(l):r.expandDims(l,0);return r.dispose([x,l]),{tensor:y,canvas:t.filter.return?_:null}}}async function Oo(e,t){let o=!1;if(e.cacheSensitivity===0||!t.shape||t.shape.length!==4||t.shape[1]>2048||t.shape[2]>2048)return o;if(!O0.inputTensor)O0.inputTensor=r.clone(t);else if(O0.inputTensor.shape[1]!==t.shape[1]||O0.inputTensor.shape[2]!==t.shape[2])r.dispose(O0.inputTensor),O0.inputTensor=r.clone(t);else{let n={};n.diff=r.sub(t,O0.inputTensor),n.squared=r.mul(n.diff,n.diff),n.sum=r.sum(n.squared);let s=(await n.sum.data())[0]/(t.shape[1]||1)/(t.shape[2]||1)/255/3;r.dispose([O0.inputTensor,n.diff,n.squared,n.sum]),O0.inputTensor=r.clone(t),o=s<=(e.cacheSensitivity||0)}return o}async function Io(e,t,o){let n={};if(!t||!o||t.shape.length!==4||t.shape.length!==o.shape.length)return e.debug||b("invalid input tensor or tensor shapes do not match:",t.shape,o.shape),0;if(t.shape[0]!==1||o.shape[0]!==1||t.shape[3]!==3||o.shape[3]!==3)return e.debug||b("input tensors must be of shape [1, height, width, 3]:",t.shape,o.shape),0;n.input1=r.clone(t),n.input2=t.shape[1]!==o.shape[1]||t.shape[2]!==o.shape[2]?r.image.resizeBilinear(o,[t.shape[1],t.shape[2]]):r.clone(o),n.diff=r.sub(n.input1,n.input2),n.squared=r.mul(n.diff,n.diff),n.sum=r.sum(n.squared);let s=(await n.sum.data())[0]/(t.shape[1]||1)/(t.shape[2]||1)/255/3;return r.dispose([n.input1,n.input2,n.diff,n.squared,n.sum]),s}var Dt=class{constructor(){k(this,"browser");k(this,"node");k(this,"worker");k(this,"platform","");k(this,"agent","");k(this,"backends",[]);k(this,"initial");k(this,"filter");k(this,"tfjs");k(this,"offscreen");k(this,"perfadd",!1);k(this,"wasm",{supported:void 0,backend:void 0,simd:void 0,multithread:void 0});k(this,"webgl",{supported:void 0,backend:void 0,version:void 0,renderer:void 0});k(this,"webgpu",{supported:void 0,backend:void 0,adapter:void 0});k(this,"cpu",{model:void 0,flags:[]});k(this,"kernels",[]);k(this,"Canvas");k(this,"Image");k(this,"ImageData");if(this.browser=typeof navigator!="undefined",this.node=typeof process!="undefined"&&typeof process.versions!="undefined"&&typeof process.versions.node!="undefined",this.tfjs={version:Be["tfjs-core"]},this.offscreen=typeof OffscreenCanvas!="undefined",this.initial=!0,this.worker=this.browser&&this.offscreen?typeof WorkerGlobalScope!="undefined":void 0,typeof navigator!="undefined"){let t=navigator.userAgent.match(/\(([^()]+)\)/g);if(t&&t[0]){let o=t[0].match(/\(([^()]+)\)/g);this.platform=o&&o[0]?o[0].replace(/\(|\)/g,""):"",this.agent=navigator.userAgent.replace(t[0],""),this.platform[1]&&(this.agent=this.agent.replace(t[1],"")),this.agent=this.agent.replace(/ /g," ")}}else typeof process!="undefined"&&(this.platform=`${process.platform} ${process.arch}`,this.agent=`NodeJS ${process.version}`)}async updateBackend(){this.backends=Object.keys(r.engine().registryFactory),this.wasm.supported=typeof WebAssembly!="undefined",this.wasm.backend=this.backends.includes("wasm"),this.wasm.supported&&this.wasm.backend&&r.getBackend()==="wasm"&&(this.wasm.simd=await r.env().getAsync("WASM_HAS_SIMD_SUPPORT"),this.wasm.multithread=await r.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT"));let t=a0(100,100),o=t?t.getContext("webgl2"):void 0;if(this.webgl.supported=typeof o!="undefined",this.webgl.backend=this.backends.includes("webgl"),this.webgl.supported&&this.webgl.backend&&(r.getBackend()==="webgl"||r.getBackend()==="humangl")){let n=r.backend().gpgpu!=="undefined"?await r.backend().getGPGPUContext().gl:null;n&&(this.webgl.version=n.getParameter(n.VERSION),this.webgl.renderer=n.getParameter(n.RENDERER))}this.webgpu.supported=this.browser&&typeof navigator.gpu!="undefined",this.webgpu.backend=this.backends.includes("webgpu");try{this.webgpu.supported&&(this.webgpu.adapter=(await navigator.gpu.requestAdapter()).name)}catch(n){this.webgpu.supported=!1}try{this.kernels=r.getKernelsForBackend(r.getBackend()).map(n=>n.kernelName.toLowerCase())}catch(n){}}async updateCPU(){let t={model:"",flags:[]};this.node&&this.platform.startsWith("linux"),this.cpu?this.cpu=t:Object.defineProperty(this,"cpu",{value:t})}},w=new Dt;var I0={cacheModels:!1,verbose:!0,debug:!1,modelBasePath:""};async function kr(e,t){return I0.debug&&b("load model fetch:",e,t),fetch(e,t)}function Lo(e){I0.cacheModels=e.cacheModels,I0.verbose=e.debug,I0.modelBasePath=e.modelBasePath}async function L(e){let t=Ro(I0.modelBasePath,e||""),o=t.split("/"),n="indexeddb://"+o[o.length-1].replace(".json",""),A=await r.io.listModels(),s=I0.cacheModels&&Object.keys(A).includes(n),a=typeof fetch=="undefined"?{}:{fetchFunc:(d,l)=>kr(d,l)},i=new Vt(s?n:t,a),x=!1;try{i.findIOHandler(),I0.debug&&b("model load handler:",i.handler);let d=await i.handler.load();i.loadSync(d),I0.verbose&&b("load model:",i.modelUrl),x=!0}catch(d){b("error loading model:",t,d)}if(x&&I0.cacheModels&&!s)try{let d=await i.save(n);b("model saved:",n,d)}catch(d){b("error saving model:",t,d)}return i}var qt="2.7.0";var ao={};$0(ao,{Models:()=>Ye,load:()=>ro,reset:()=>It,validate:()=>so});var b0,Ut=[],jr=["white","black","asian","indian","other"],Sr=[15,23,28,35.5,45.5,55.5,65],No=0,Go=0,Jt=Number.MAX_SAFE_INTEGER;async function Bo(e){return w.initial&&(b0=null),b0?e.debug&&b("cached model:",b0.modelUrl):b0=await L(e.face.gear),b0}async function Yt(e,t,o,n){var a,i;if(!b0)return{age:0,gender:"unknown",genderScore:0,race:[]};let A=Jt<(((a=t.face.gear)==null?void 0:a.skipFrames)||0),s=(((i=t.face.gear)==null?void 0:i.skipTime)||0)>g()-Go;return t.skipAllowed&&s&&A&&No===n&&Ut[o]?(Jt++,Ut[o]):(Jt=0,new Promise(async x=>{var M,u;if(!(b0!=null&&b0.inputs[0].shape))return;let d={},l=[[0,.1,.9,.9]];d.resize=r.image.cropAndResize(e,l,[0],[b0.inputs[0].shape[2],b0.inputs[0].shape[1]]);let y={age:0,gender:"unknown",genderScore:0,race:[]};(M=t.face.gear)!=null&&M.enabled&&([d.age,d.gender,d.race]=b0.execute(d.resize,["age_output","gender_output","race_output"]));let c=await d.gender.data();y.gender=c[0]>c[1]?"male":"female",y.genderScore=Math.round(100*(c[0]>c[1]?c[0]:c[1]))/100;let f=await d.race.data();for(let p=0;p(((u=t.face.gear)==null?void 0:u.minConfidence)||.2)&&y.race.push({score:Math.round(100*f[p])/100,race:jr[p]});y.race.sort((p,P)=>P.score-p.score);let m=Array.from(await d.age.data()).map((p,P)=>[Sr[P],p]).sort((p,P)=>P[1]-p[1]),v=m[0][0];for(let p=1;pr.dispose(d[p])),Ut[o]=y,No=n,Go=g(),x(y)}))}var N={tf255:255,tf1:1,tf2:2,tf05:.5,tf127:127.5,rgb:[.2989,.587,.114]};function Ho(){N.tf255=r.scalar(255,"float32"),N.tf1=r.scalar(1,"float32"),N.tf2=r.scalar(2,"float32"),N.tf05=r.scalar(.5,"float32"),N.tf127=r.scalar(127.5,"float32"),N.rgb=r.tensor1d([.2989,.587,.114],"float32")}var y0,ot=[],Vo=0,Zo=0,Kt=Number.MAX_SAFE_INTEGER;async function Xo(e){return w.initial&&(y0=null),y0?e.debug&&b("cached model:",y0.modelUrl):y0=await L(e.face.ssrnet.modelPathAge),y0}async function Qt(e,t,o,n){var a,i,x,d;if(!y0)return{age:0};let A=Kt<(((a=t.face.ssrnet)==null?void 0:a.skipFrames)||0),s=(((i=t.face.ssrnet)==null?void 0:i.skipTime)||0)>g()-Zo;return t.skipAllowed&&A&&s&&Vo===n&&((x=ot[o])==null?void 0:x.age)&&((d=ot[o])==null?void 0:d.age)>0?(Kt++,ot[o]):(Kt=0,new Promise(async l=>{if(!(y0!=null&&y0.inputs)||!y0.inputs[0]||!y0.inputs[0].shape)return;let y={};y.resize=r.image.resizeBilinear(e,[y0.inputs[0].shape[2],y0.inputs[0].shape[1]],!1),y.enhance=r.mul(y.resize,N.tf255);let c={age:0};if(t.face.ssrnet.enabled&&(y.age=y0.execute(y.enhance)),y.age){let f=await y.age.data();c.age=Math.trunc(10*f[0])/10}Object.keys(y).forEach(f=>r.dispose(y[f])),ot[o]=c,Vo=n,Zo=g(),l(c)}))}var g0,nt=[],qo=0,Uo=0,_t=Number.MAX_SAFE_INTEGER,$t=[.2989,.587,.114];async function Jo(e){return w.initial&&(g0=null),g0?e.debug&&b("cached model:",g0.modelUrl):g0=await L(e.face.ssrnet.modelPathGender),g0}async function e5(e,t,o,n){var a,i,x,d;if(!g0)return{gender:"unknown",genderScore:0};let A=_t<(((a=t.face.ssrnet)==null?void 0:a.skipFrames)||0),s=(((i=t.face.ssrnet)==null?void 0:i.skipTime)||0)>g()-Uo;return t.skipAllowed&&A&&s&&qo===n&&((x=nt[o])==null?void 0:x.gender)&&((d=nt[o])==null?void 0:d.genderScore)>0?(_t++,nt[o]):(_t=0,new Promise(async l=>{if(!(g0!=null&&g0.inputs[0].shape))return;let y={};y.resize=r.image.resizeBilinear(e,[g0.inputs[0].shape[2],g0.inputs[0].shape[1]],!1),y.enhance=r.tidy(()=>{let[h,m,v]=r.split(y.resize,3,3),M=r.mul(h,$t[0]),u=r.mul(m,$t[1]),p=r.mul(v,$t[2]),P=r.addN([M,u,p]);return r.mul(r.sub(P,N.tf05),2)});let c={gender:"unknown",genderScore:0};t.face.ssrnet.enabled&&(y.gender=g0.execute(y.enhance));let f=await y.gender.data();c.gender=f[0]>f[1]?"female":"male",c.genderScore=f[0]>f[1]?Math.trunc(100*f[0])/100:Math.trunc(100*f[1])/100,Object.keys(y).forEach(h=>r.dispose(y[h])),nt[o]=c,qo=n,Uo=g(),l(c)}))}var A0,At=[],t5=Number.MAX_SAFE_INTEGER,Ko=0,Qo=0;async function _o(e){var t;return w.initial&&(A0=null),A0?e.debug&&b("cached model:",A0.modelUrl):A0=await L((t=e.face.antispoof)==null?void 0:t.modelPath),A0}async function o5(e,t,o,n){var a,i;if(!A0)return 0;let A=(((a=t.face.antispoof)==null?void 0:a.skipTime)||0)>g()-Qo,s=t5<(((i=t.face.antispoof)==null?void 0:i.skipFrames)||0);return t.skipAllowed&&A&&s&&Ko===n&&At[o]?(t5++,At[o]):(t5=0,new Promise(async x=>{let d=r.image.resizeBilinear(e,[A0!=null&&A0.inputs[0].shape?A0.inputs[0].shape[2]:0,A0!=null&&A0.inputs[0].shape?A0.inputs[0].shape[1]:0],!1),l=A0==null?void 0:A0.execute(d),y=(await l.data())[0];At[o]=Math.round(100*y)/100,Ko=n,Qo=g(),r.dispose([d,l]),x(At[o])}))}var M0={silhouette:[10,338,297,332,284,251,389,356,454,323,361,288,397,365,379,378,400,377,152,148,176,149,150,136,172,58,132,93,234,127,162,21,54,103,67,109],lipsUpperOuter:[61,185,40,39,37,0,267,269,270,409,291],lipsLowerOuter:[146,91,181,84,17,314,405,321,375,291],lipsUpperInner:[78,191,80,81,82,13,312,311,310,415,308],lipsLowerInner:[78,95,88,178,87,14,317,402,318,324,308],rightEyeUpper0:[246,161,160,159,158,157,173],rightEyeLower0:[33,7,163,144,145,153,154,155,133],rightEyeUpper1:[247,30,29,27,28,56,190],rightEyeLower1:[130,25,110,24,23,22,26,112,243],rightEyeUpper2:[113,225,224,223,222,221,189],rightEyeLower2:[226,31,228,229,230,231,232,233,244],rightEyeLower3:[143,111,117,118,119,120,121,128,245],rightEyebrowUpper:[156,70,63,105,66,107,55,193],rightEyebrowLower:[35,124,46,53,52,65],rightEyeIris:[473,474,475,476,477],leftEyeUpper0:[466,388,387,386,385,384,398],leftEyeLower0:[263,249,390,373,374,380,381,382,362],leftEyeUpper1:[467,260,259,257,258,286,414],leftEyeLower1:[359,255,339,254,253,252,256,341,463],leftEyeUpper2:[342,445,444,443,442,441,413],leftEyeLower2:[446,261,448,449,450,451,452,453,464],leftEyeLower3:[372,340,346,347,348,349,350,357,465],leftEyebrowUpper:[383,300,293,334,296,336,285,417],leftEyebrowLower:[265,353,276,283,282,295],leftEyeIris:[468,469,470,471,472],midwayBetweenEyes:[168],noseTip:[1],noseBottom:[2],noseRightCorner:[98],noseLeftCorner:[327],rightCheek:[205],leftCheek:[425]},n5={count:468,mouth:13,symmetryLine:[13,M0.midwayBetweenEyes[0]]},He={leftEye:0,rightEye:1,nose:2,mouth:3,leftEar:4,rightEar:5,symmetryLine:[3,2]},A5=[{key:"EyeUpper0",indices:[9,10,11,12,13,14,15]},{key:"EyeUpper1",indices:[25,26,27,28,29,30,31]},{key:"EyeUpper2",indices:[41,42,43,44,45,46,47]},{key:"EyeLower0",indices:[0,1,2,3,4,5,6,7,8]},{key:"EyeLower1",indices:[16,17,18,19,20,21,22,23,24]},{key:"EyeLower2",indices:[32,33,34,35,36,37,38,39,40]},{key:"EyeLower3",indices:[54,55,56,57,58,59,60,61,62]}],Ve=[[.499976992607117,.652534008026123],[.500025987625122,.547487020492554],[.499974012374878,.602371990680695],[.482113003730774,.471979022026062],[.500150978565216,.527155995368958],[.499909996986389,.498252987861633],[.499523013830185,.40106201171875],[.289712011814117,.380764007568359],[.499954998493195,.312398016452789],[.499987006187439,.269918978214264],[.500023007392883,.107050001621246],[.500023007392883,.666234016418457],[.5000159740448,.679224014282227],[.500023007392883,.692348003387451],[.499976992607117,.695277988910675],[.499976992607117,.70593398809433],[.499976992607117,.719385027885437],[.499976992607117,.737019002437592],[.499967992305756,.781370997428894],[.499816000461578,.562981009483337],[.473773002624512,.573909997940063],[.104906998574734,.254140973091125],[.365929991006851,.409575998783112],[.338757991790771,.41302502155304],[.311120003461838,.409460008144379],[.274657994508743,.389131009578705],[.393361985683441,.403706014156342],[.345234006643295,.344011008739471],[.370094001293182,.346076011657715],[.319321990013123,.347265005111694],[.297903001308441,.353591024875641],[.24779200553894,.410809993743896],[.396889001131058,.842755019664764],[.280097991228104,.375599980354309],[.106310002505779,.399955987930298],[.2099249958992,.391353011131287],[.355807989835739,.534406006336212],[.471751004457474,.65040397644043],[.474155008792877,.680191993713379],[.439785003662109,.657229006290436],[.414617002010345,.66654098033905],[.450374007225037,.680860996246338],[.428770989179611,.682690978050232],[.374971002340317,.727805018424988],[.486716985702515,.547628998756409],[.485300987958908,.527395009994507],[.257764995098114,.314490020275116],[.401223003864288,.455172002315521],[.429818987846375,.548614978790283],[.421351999044418,.533740997314453],[.276895999908447,.532056987285614],[.483370006084442,.499586999416351],[.33721199631691,.282882988452911],[.296391993761063,.293242990970612],[.169294998049736,.193813979625702],[.447580009698868,.302609980106354],[.392390012741089,.353887975215912],[.354490011930466,.696784019470215],[.067304998636246,.730105042457581],[.442739009857178,.572826027870178],[.457098007202148,.584792017936707],[.381974011659622,.694710969924927],[.392388999462128,.694203019142151],[.277076005935669,.271932005882263],[.422551989555359,.563233017921448],[.385919004678726,.281364023685455],[.383103013038635,.255840003490448],[.331431001424789,.119714021682739],[.229923993349075,.232002973556519],[.364500999450684,.189113974571228],[.229622006416321,.299540996551514],[.173287004232407,.278747975826263],[.472878992557526,.666198015213013],[.446828007698059,.668527007102966],[.422762006521225,.673889994621277],[.445307999849319,.580065965652466],[.388103008270264,.693961024284363],[.403039008378983,.706539988517761],[.403629004955292,.693953037261963],[.460041999816895,.557139039039612],[.431158006191254,.692366003990173],[.452181994915009,.692366003990173],[.475387006998062,.692366003990173],[.465828001499176,.779190003871918],[.472328990697861,.736225962638855],[.473087012767792,.717857003211975],[.473122000694275,.704625964164734],[.473033010959625,.695277988910675],[.427942007780075,.695277988910675],[.426479011774063,.703539967536926],[.423162013292313,.711845993995667],[.4183090031147,.720062971115112],[.390094995498657,.639572978019714],[.013953999616206,.560034036636353],[.499913990497589,.58014702796936],[.413199990987778,.69539999961853],[.409626007080078,.701822996139526],[.468080013990402,.601534962654114],[.422728985548019,.585985004901886],[.463079988956451,.593783974647522],[.37211999297142,.47341400384903],[.334562003612518,.496073007583618],[.411671012639999,.546965003013611],[.242175996303558,.14767599105835],[.290776997804642,.201445996761322],[.327338010072708,.256527006626129],[.399509996175766,.748921036720276],[.441727995872498,.261676013469696],[.429764986038208,.187834024429321],[.412198007106781,.108901023864746],[.288955003023148,.398952007293701],[.218936994671822,.435410976409912],[.41278201341629,.398970007896423],[.257135003805161,.355440020561218],[.427684992551804,.437960982322693],[.448339998722076,.536936044692993],[.178560003638268,.45755398273468],[.247308000922203,.457193970680237],[.286267012357712,.467674970626831],[.332827985286713,.460712015628815],[.368755996227264,.447206974029541],[.398963987827301,.432654976844788],[.476410001516342,.405806005001068],[.189241006970406,.523923993110657],[.228962004184723,.348950982093811],[.490725994110107,.562400996685028],[.404670000076294,.485132992267609],[.019469000399113,.401564002037048],[.426243007183075,.420431017875671],[.396993011236191,.548797011375427],[.266469985246658,.376977026462555],[.439121007919312,.51895797252655],[.032313998788595,.644356966018677],[.419054001569748,.387154996395111],[.462783008813858,.505746960639954],[.238978996872902,.779744982719421],[.198220998048782,.831938028335571],[.107550002634525,.540755033493042],[.183610007166862,.740257024765015],[.134409993886948,.333683013916016],[.385764002799988,.883153975009918],[.490967005491257,.579378008842468],[.382384985685349,.508572995662689],[.174399003386497,.397670984268188],[.318785011768341,.39623498916626],[.343364000320435,.400596976280212],[.396100014448166,.710216999053955],[.187885001301765,.588537991046906],[.430987000465393,.944064974784851],[.318993002176285,.898285031318665],[.266247987747192,.869701027870178],[.500023007392883,.190576016902924],[.499976992607117,.954452991485596],[.366169989109039,.398822009563446],[.393207013607025,.39553701877594],[.410373002290726,.391080021858215],[.194993004202843,.342101991176605],[.388664990663528,.362284004688263],[.365961998701096,.355970978736877],[.343364000320435,.355356991291046],[.318785011768341,.35834002494812],[.301414996385574,.363156020641327],[.058132998645306,.319076001644135],[.301414996385574,.387449026107788],[.499987989664078,.618434011936188],[.415838003158569,.624195992946625],[.445681989192963,.566076993942261],[.465844005346298,.620640993118286],[.49992299079895,.351523995399475],[.288718998432159,.819945991039276],[.335278987884521,.852819979190826],[.440512001514435,.902418971061707],[.128294005990028,.791940987110138],[.408771991729736,.373893976211548],[.455606997013092,.451801002025604],[.499877005815506,.908990025520325],[.375436991453171,.924192011356354],[.11421000212431,.615022003650665],[.448662012815475,.695277988910675],[.4480200111866,.704632043838501],[.447111994028091,.715808033943176],[.444831997156143,.730794012546539],[.430011987686157,.766808986663818],[.406787008047104,.685672998428345],[.400738000869751,.681069016456604],[.392399996519089,.677703022956848],[.367855995893478,.663918972015381],[.247923001646996,.601333022117615],[.452769994735718,.420849978923798],[.43639200925827,.359887003898621],[.416164010763168,.368713974952698],[.413385987281799,.692366003990173],[.228018000721931,.683571994304657],[.468268007040024,.352671027183533],[.411361992359161,.804327011108398],[.499989002943039,.469825029373169],[.479153990745544,.442654013633728],[.499974012374878,.439637005329132],[.432112008333206,.493588984012604],[.499886006116867,.866917014122009],[.49991300702095,.821729004383087],[.456548988819122,.819200992584229],[.344549000263214,.745438992977142],[.37890899181366,.574010014533997],[.374292999505997,.780184984207153],[.319687992334366,.570737957954407],[.357154995203018,.604269981384277],[.295284003019333,.621580958366394],[.447750002145767,.862477004528046],[.410986006259918,.508723020553589],[.31395098567009,.775308012962341],[.354128003120422,.812552988529205],[.324548006057739,.703992962837219],[.189096003770828,.646299958229065],[.279776990413666,.71465802192688],[.1338230073452,.682700991630554],[.336768001317978,.644733011722565],[.429883986711502,.466521978378296],[.455527991056442,.548622965812683],[.437114000320435,.558896005153656],[.467287987470627,.529924988746643],[.414712011814117,.335219979286194],[.37704598903656,.322777986526489],[.344107985496521,.320150971412659],[.312875986099243,.32233202457428],[.283526003360748,.333190023899078],[.241245999932289,.382785975933075],[.102986000478268,.468762993812561],[.267612010240555,.424560010433197],[.297879010438919,.433175981044769],[.333433985710144,.433878004550934],[.366427004337311,.426115989685059],[.396012008190155,.416696012020111],[.420121014118195,.41022801399231],[.007561000064015,.480777025222778],[.432949006557465,.569517970085144],[.458638995885849,.479089021682739],[.473466008901596,.545744001865387],[.476087987422943,.563830018043518],[.468472003936768,.555056989192963],[.433990985155106,.582361996173859],[.483518004417419,.562983989715576],[.482482999563217,.57784903049469],[.42645001411438,.389798998832703],[.438998997211456,.39649498462677],[.450067013502121,.400434017181396],[.289712011814117,.368252992630005],[.276670008897781,.363372981548309],[.517862021923065,.471948027610779],[.710287988185883,.380764007568359],[.526226997375488,.573909997940063],[.895093023777008,.254140973091125],[.634069979190826,.409575998783112],[.661242008209229,.41302502155304],[.688880026340485,.409460008144379],[.725341975688934,.389131009578705],[.606630027294159,.40370500087738],[.654766023159027,.344011008739471],[.629905998706818,.346076011657715],[.680678009986877,.347265005111694],[.702096998691559,.353591024875641],[.75221198797226,.410804986953735],[.602918028831482,.842862963676453],[.719901978969574,.375599980354309],[.893692970275879,.399959981441498],[.790081977844238,.391354024410248],[.643998026847839,.534487962722778],[.528249025344849,.65040397644043],[.525849997997284,.680191040039062],[.560214996337891,.657229006290436],[.585384011268616,.66654098033905],[.549625992774963,.680860996246338],[.57122802734375,.682691991329193],[.624852001667023,.72809898853302],[.513050019741058,.547281980514526],[.51509702205658,.527251958847046],[.742246985435486,.314507007598877],[.598631024360657,.454979002475739],[.570338010787964,.548575043678284],[.578631997108459,.533622980117798],[.723087012767792,.532054007053375],[.516445994377136,.499638974666595],[.662801027297974,.282917976379395],[.70362401008606,.293271005153656],[.830704987049103,.193813979625702],[.552385985851288,.302568018436432],[.607609987258911,.353887975215912],[.645429015159607,.696707010269165],[.932694971561432,.730105042457581],[.557260990142822,.572826027870178],[.542901992797852,.584792017936707],[.6180260181427,.694710969924927],[.607590973377228,.694203019142151],[.722943007946014,.271963000297546],[.577413976192474,.563166975975037],[.614082992076874,.281386971473694],[.616907000541687,.255886018276215],[.668509006500244,.119913995265961],[.770092010498047,.232020974159241],[.635536015033722,.189248979091644],[.77039098739624,.299556016921997],[.826722025871277,.278755009174347],[.527121007442474,.666198015213013],[.553171992301941,.668527007102966],[.577238023281097,.673889994621277],[.554691970348358,.580065965652466],[.611896991729736,.693961024284363],[.59696102142334,.706539988517761],[.596370995044708,.693953037261963],[.539958000183105,.557139039039612],[.568841993808746,.692366003990173],[.547818005084991,.692366003990173],[.52461302280426,.692366003990173],[.534089982509613,.779141008853912],[.527670979499817,.736225962638855],[.526912987232208,.717857003211975],[.526877999305725,.704625964164734],[.526966989040375,.695277988910675],[.572058022022247,.695277988910675],[.573521018028259,.703539967536926],[.57683801651001,.711845993995667],[.581691026687622,.720062971115112],[.609944999217987,.639909982681274],[.986046016216278,.560034036636353],[.5867999792099,.69539999961853],[.590372025966644,.701822996139526],[.531915009021759,.601536989212036],[.577268004417419,.585934996604919],[.536915004253387,.593786001205444],[.627542972564697,.473352015018463],[.665585994720459,.495950996875763],[.588353991508484,.546862006187439],[.757824003696442,.14767599105835],[.709249973297119,.201507985591888],[.672684013843536,.256581008434296],[.600408971309662,.74900496006012],[.55826598405838,.261672019958496],[.570303976535797,.187870979309082],[.588165998458862,.109044015407562],[.711045026779175,.398952007293701],[.781069993972778,.435405015945435],[.587247014045715,.398931980133057],[.742869973182678,.355445981025696],[.572156012058258,.437651991844177],[.55186802148819,.536570012569427],[.821442008018494,.457556009292603],[.752701997756958,.457181990146637],[.71375697851181,.467626988887787],[.66711300611496,.460672974586487],[.631101012229919,.447153985500336],[.6008620262146,.432473003864288],[.523481011390686,.405627012252808],[.810747981071472,.523926019668579],[.771045982837677,.348959028720856],[.509127020835876,.562718033790588],[.595292985439301,.485023975372314],[.980530977249146,.401564002037048],[.573499977588654,.420000016689301],[.602994978427887,.548687994480133],[.733529984951019,.376977026462555],[.560611009597778,.519016981124878],[.967685997486115,.644356966018677],[.580985009670258,.387160003185272],[.537728011608124,.505385041236877],[.760966002941132,.779752969741821],[.801778972148895,.831938028335571],[.892440974712372,.54076099395752],[.816350996494293,.740260004997253],[.865594983100891,.333687007427216],[.614073991775513,.883246004581451],[.508952975273132,.579437971115112],[.617941975593567,.508316040039062],[.825608015060425,.397674977779388],[.681214988231659,.39623498916626],[.656635999679565,.400596976280212],[.603900015354156,.710216999053955],[.81208598613739,.588539004325867],[.56801301240921,.944564998149872],[.681007981300354,.898285031318665],[.733752012252808,.869701027870178],[.633830010890961,.398822009563446],[.606792986392975,.39553701877594],[.589659988880157,.391062021255493],[.805015981197357,.342108011245728],[.611334979534149,.362284004688263],[.634037971496582,.355970978736877],[.656635999679565,.355356991291046],[.681214988231659,.35834002494812],[.698584973812103,.363156020641327],[.941866993904114,.319076001644135],[.698584973812103,.387449026107788],[.584177017211914,.624107003211975],[.554318010807037,.566076993942261],[.534153997898102,.62064003944397],[.711217999458313,.819975018501282],[.664629995822906,.852871000766754],[.559099972248077,.902631998062134],[.871706008911133,.791940987110138],[.591234028339386,.373893976211548],[.544341027736664,.451583981513977],[.624562978744507,.924192011356354],[.88577002286911,.615028977394104],[.551338016986847,.695277988910675],[.551980018615723,.704632043838501],[.552887976169586,.715808033943176],[.555167973041534,.730794012546539],[.569944024085999,.767035007476807],[.593203008174896,.685675978660583],[.599261999130249,.681069016456604],[.607599973678589,.677703022956848],[.631937980651855,.663500010967255],[.752032995223999,.601315021514893],[.547226011753082,.420395016670227],[.563543975353241,.359827995300293],[.583841025829315,.368713974952698],[.586614012718201,.692366003990173],[.771915018558502,.683578014373779],[.531597018241882,.352482974529266],[.588370978832245,.804440975189209],[.52079701423645,.442565023899078],[.567984998226166,.493479013442993],[.543282985687256,.819254994392395],[.655317008495331,.745514988899231],[.621008992195129,.574018001556396],[.625559985637665,.78031200170517],[.680198013782501,.570719003677368],[.64276397228241,.604337990283966],[.704662978649139,.621529996395111],[.552012026309967,.862591981887817],[.589071989059448,.508637011051178],[.685944974422455,.775357007980347],[.645735025405884,.812640011310577],[.675342977046967,.703978002071381],[.810858011245728,.646304965019226],[.72012197971344,.714666962623596],[.866151988506317,.682704985141754],[.663187026977539,.644596993923187],[.570082008838654,.466325998306274],[.544561982154846,.548375964164734],[.562758982181549,.558784961700439],[.531987011432648,.530140042304993],[.585271000862122,.335177004337311],[.622952997684479,.32277899980545],[.655896008014679,.320163011550903],[.687132000923157,.322345972061157],[.716481983661652,.333200991153717],[.758756995201111,.382786989212036],[.897013008594513,.468769013881683],[.732392013072968,.424547016620636],[.70211398601532,.433162987232208],[.66652500629425,.433866024017334],[.633504986763,.426087975502014],[.603875994682312,.416586995124817],[.579657971858978,.409945011138916],[.992439985275269,.480777025222778],[.567192018032074,.569419980049133],[.54136598110199,.478899002075195],[.526564002037048,.546118021011353],[.523913025856018,.563830018043518],[.531529009342194,.555056989192963],[.566035985946655,.582329034805298],[.51631098985672,.563053965568542],[.5174720287323,.577877044677734],[.573594987392426,.389806985855103],[.560697972774506,.395331978797913],[.549755990505219,.399751007556915],[.710287988185883,.368252992630005],[.723330020904541,.363372981548309]],te=[127,34,139,11,0,37,232,231,120,72,37,39,128,121,47,232,121,128,104,69,67,175,171,148,157,154,155,118,50,101,73,39,40,9,151,108,48,115,131,194,204,211,74,40,185,80,42,183,40,92,186,230,229,118,202,212,214,83,18,17,76,61,146,160,29,30,56,157,173,106,204,194,135,214,192,203,165,98,21,71,68,51,45,4,144,24,23,77,146,91,205,50,187,201,200,18,91,106,182,90,91,181,85,84,17,206,203,36,148,171,140,92,40,39,193,189,244,159,158,28,247,246,161,236,3,196,54,68,104,193,168,8,117,228,31,189,193,55,98,97,99,126,47,100,166,79,218,155,154,26,209,49,131,135,136,150,47,126,217,223,52,53,45,51,134,211,170,140,67,69,108,43,106,91,230,119,120,226,130,247,63,53,52,238,20,242,46,70,156,78,62,96,46,53,63,143,34,227,173,155,133,123,117,111,44,125,19,236,134,51,216,206,205,154,153,22,39,37,167,200,201,208,36,142,100,57,212,202,20,60,99,28,158,157,35,226,113,160,159,27,204,202,210,113,225,46,43,202,204,62,76,77,137,123,116,41,38,72,203,129,142,64,98,240,49,102,64,41,73,74,212,216,207,42,74,184,169,170,211,170,149,176,105,66,69,122,6,168,123,147,187,96,77,90,65,55,107,89,90,180,101,100,120,63,105,104,93,137,227,15,86,85,129,102,49,14,87,86,55,8,9,100,47,121,145,23,22,88,89,179,6,122,196,88,95,96,138,172,136,215,58,172,115,48,219,42,80,81,195,3,51,43,146,61,171,175,199,81,82,38,53,46,225,144,163,110,246,33,7,52,65,66,229,228,117,34,127,234,107,108,69,109,108,151,48,64,235,62,78,191,129,209,126,111,35,143,163,161,246,117,123,50,222,65,52,19,125,141,221,55,65,3,195,197,25,7,33,220,237,44,70,71,139,122,193,245,247,130,33,71,21,162,153,158,159,170,169,150,188,174,196,216,186,92,144,160,161,2,97,167,141,125,241,164,167,37,72,38,12,145,159,160,38,82,13,63,68,71,226,35,111,158,153,154,101,50,205,206,92,165,209,198,217,165,167,97,220,115,218,133,112,243,239,238,241,214,135,169,190,173,133,171,208,32,125,44,237,86,87,178,85,86,179,84,85,180,83,84,181,201,83,182,137,93,132,76,62,183,61,76,184,57,61,185,212,57,186,214,207,187,34,143,156,79,239,237,123,137,177,44,1,4,201,194,32,64,102,129,213,215,138,59,166,219,242,99,97,2,94,141,75,59,235,24,110,228,25,130,226,23,24,229,22,23,230,26,22,231,112,26,232,189,190,243,221,56,190,28,56,221,27,28,222,29,27,223,30,29,224,247,30,225,238,79,20,166,59,75,60,75,240,147,177,215,20,79,166,187,147,213,112,233,244,233,128,245,128,114,188,114,217,174,131,115,220,217,198,236,198,131,134,177,132,58,143,35,124,110,163,7,228,110,25,356,389,368,11,302,267,452,350,349,302,303,269,357,343,277,452,453,357,333,332,297,175,152,377,384,398,382,347,348,330,303,304,270,9,336,337,278,279,360,418,262,431,304,408,409,310,415,407,270,409,410,450,348,347,422,430,434,313,314,17,306,307,375,387,388,260,286,414,398,335,406,418,364,367,416,423,358,327,251,284,298,281,5,4,373,374,253,307,320,321,425,427,411,421,313,18,321,405,406,320,404,405,315,16,17,426,425,266,377,400,369,322,391,269,417,465,464,386,257,258,466,260,388,456,399,419,284,332,333,417,285,8,346,340,261,413,441,285,327,460,328,355,371,329,392,439,438,382,341,256,429,420,360,364,394,379,277,343,437,443,444,283,275,440,363,431,262,369,297,338,337,273,375,321,450,451,349,446,342,467,293,334,282,458,461,462,276,353,383,308,324,325,276,300,293,372,345,447,382,398,362,352,345,340,274,1,19,456,248,281,436,427,425,381,256,252,269,391,393,200,199,428,266,330,329,287,273,422,250,462,328,258,286,384,265,353,342,387,259,257,424,431,430,342,353,276,273,335,424,292,325,307,366,447,345,271,303,302,423,266,371,294,455,460,279,278,294,271,272,304,432,434,427,272,407,408,394,430,431,395,369,400,334,333,299,351,417,168,352,280,411,325,319,320,295,296,336,319,403,404,330,348,349,293,298,333,323,454,447,15,16,315,358,429,279,14,15,316,285,336,9,329,349,350,374,380,252,318,402,403,6,197,419,318,319,325,367,364,365,435,367,397,344,438,439,272,271,311,195,5,281,273,287,291,396,428,199,311,271,268,283,444,445,373,254,339,263,466,249,282,334,296,449,347,346,264,447,454,336,296,299,338,10,151,278,439,455,292,407,415,358,371,355,340,345,372,390,249,466,346,347,280,442,443,282,19,94,370,441,442,295,248,419,197,263,255,359,440,275,274,300,383,368,351,412,465,263,467,466,301,368,389,380,374,386,395,378,379,412,351,419,436,426,322,373,390,388,2,164,393,370,462,461,164,0,267,302,11,12,374,373,387,268,12,13,293,300,301,446,261,340,385,384,381,330,266,425,426,423,391,429,355,437,391,327,326,440,457,438,341,382,362,459,457,461,434,430,394,414,463,362,396,369,262,354,461,457,316,403,402,315,404,403,314,405,404,313,406,405,421,418,406,366,401,361,306,408,407,291,409,408,287,410,409,432,436,410,434,416,411,264,368,383,309,438,457,352,376,401,274,275,4,421,428,262,294,327,358,433,416,367,289,455,439,462,370,326,2,326,370,305,460,455,254,449,448,255,261,446,253,450,449,252,451,450,256,452,451,341,453,452,413,464,463,441,413,414,258,442,441,257,443,442,259,444,443,260,445,444,467,342,445,459,458,250,289,392,290,290,328,460,376,433,435,250,290,392,411,416,433,341,463,464,453,464,465,357,465,412,343,412,399,360,363,440,437,399,456,420,456,363,401,435,288,372,383,353,339,255,249,448,261,255,133,243,190,133,155,112,33,246,247,33,130,25,398,384,286,362,398,414,362,463,341,263,359,467,263,249,255,466,467,260,75,60,166,238,239,79,162,127,139,72,11,37,121,232,120,73,72,39,114,128,47,233,232,128,103,104,67,152,175,148,173,157,155,119,118,101,74,73,40,107,9,108,49,48,131,32,194,211,184,74,185,191,80,183,185,40,186,119,230,118,210,202,214,84,83,17,77,76,146,161,160,30,190,56,173,182,106,194,138,135,192,129,203,98,54,21,68,5,51,4,145,144,23,90,77,91,207,205,187,83,201,18,181,91,182,180,90,181,16,85,17,205,206,36,176,148,140,165,92,39,245,193,244,27,159,28,30,247,161,174,236,196,103,54,104,55,193,8,111,117,31,221,189,55,240,98,99,142,126,100,219,166,218,112,155,26,198,209,131,169,135,150,114,47,217,224,223,53,220,45,134,32,211,140,109,67,108,146,43,91,231,230,120,113,226,247,105,63,52,241,238,242,124,46,156,95,78,96,70,46,63,116,143,227,116,123,111,1,44,19,3,236,51,207,216,205,26,154,22,165,39,167,199,200,208,101,36,100,43,57,202,242,20,99,56,28,157,124,35,113,29,160,27,211,204,210,124,113,46,106,43,204,96,62,77,227,137,116,73,41,72,36,203,142,235,64,240,48,49,64,42,41,74,214,212,207,183,42,184,210,169,211,140,170,176,104,105,69,193,122,168,50,123,187,89,96,90,66,65,107,179,89,180,119,101,120,68,63,104,234,93,227,16,15,85,209,129,49,15,14,86,107,55,9,120,100,121,153,145,22,178,88,179,197,6,196,89,88,96,135,138,136,138,215,172,218,115,219,41,42,81,5,195,51,57,43,61,208,171,199,41,81,38,224,53,225,24,144,110,105,52,66,118,229,117,227,34,234,66,107,69,10,109,151,219,48,235,183,62,191,142,129,126,116,111,143,7,163,246,118,117,50,223,222,52,94,19,141,222,221,65,196,3,197,45,220,44,156,70,139,188,122,245,139,71,162,145,153,159,149,170,150,122,188,196,206,216,92,163,144,161,164,2,167,242,141,241,0,164,37,11,72,12,144,145,160,12,38,13,70,63,71,31,226,111,157,158,154,36,101,205,203,206,165,126,209,217,98,165,97,237,220,218,237,239,241,210,214,169,140,171,32,241,125,237,179,86,178,180,85,179,181,84,180,182,83,181,194,201,182,177,137,132,184,76,183,185,61,184,186,57,185,216,212,186,192,214,187,139,34,156,218,79,237,147,123,177,45,44,4,208,201,32,98,64,129,192,213,138,235,59,219,141,242,97,97,2,141,240,75,235,229,24,228,31,25,226,230,23,229,231,22,230,232,26,231,233,112,232,244,189,243,189,221,190,222,28,221,223,27,222,224,29,223,225,30,224,113,247,225,99,60,240,213,147,215,60,20,166,192,187,213,243,112,244,244,233,245,245,128,188,188,114,174,134,131,220,174,217,236,236,198,134,215,177,58,156,143,124,25,110,7,31,228,25,264,356,368,0,11,267,451,452,349,267,302,269,350,357,277,350,452,357,299,333,297,396,175,377,381,384,382,280,347,330,269,303,270,151,9,337,344,278,360,424,418,431,270,304,409,272,310,407,322,270,410,449,450,347,432,422,434,18,313,17,291,306,375,259,387,260,424,335,418,434,364,416,391,423,327,301,251,298,275,281,4,254,373,253,375,307,321,280,425,411,200,421,18,335,321,406,321,320,405,314,315,17,423,426,266,396,377,369,270,322,269,413,417,464,385,386,258,248,456,419,298,284,333,168,417,8,448,346,261,417,413,285,326,327,328,277,355,329,309,392,438,381,382,256,279,429,360,365,364,379,355,277,437,282,443,283,281,275,363,395,431,369,299,297,337,335,273,321,348,450,349,359,446,467,283,293,282,250,458,462,300,276,383,292,308,325,283,276,293,264,372,447,346,352,340,354,274,19,363,456,281,426,436,425,380,381,252,267,269,393,421,200,428,371,266,329,432,287,422,290,250,328,385,258,384,446,265,342,386,387,257,422,424,430,445,342,276,422,273,424,306,292,307,352,366,345,268,271,302,358,423,371,327,294,460,331,279,294,303,271,304,436,432,427,304,272,408,395,394,431,378,395,400,296,334,299,6,351,168,376,352,411,307,325,320,285,295,336,320,319,404,329,330,349,334,293,333,366,323,447,316,15,315,331,358,279,317,14,316,8,285,9,277,329,350,253,374,252,319,318,403,351,6,419,324,318,325,397,367,365,288,435,397,278,344,439,310,272,311,248,195,281,375,273,291,175,396,199,312,311,268,276,283,445,390,373,339,295,282,296,448,449,346,356,264,454,337,336,299,337,338,151,294,278,455,308,292,415,429,358,355,265,340,372,388,390,466,352,346,280,295,442,282,354,19,370,285,441,295,195,248,197,457,440,274,301,300,368,417,351,465,251,301,389,385,380,386,394,395,379,399,412,419,410,436,322,387,373,388,326,2,393,354,370,461,393,164,267,268,302,12,386,374,387,312,268,13,298,293,301,265,446,340,380,385,381,280,330,425,322,426,391,420,429,437,393,391,326,344,440,438,458,459,461,364,434,394,428,396,262,274,354,457,317,316,402,316,315,403,315,314,404,314,313,405,313,421,406,323,366,361,292,306,407,306,291,408,291,287,409,287,432,410,427,434,411,372,264,383,459,309,457,366,352,401,1,274,4,418,421,262,331,294,358,435,433,367,392,289,439,328,462,326,94,2,370,289,305,455,339,254,448,359,255,446,254,253,449,253,252,450,252,256,451,256,341,452,414,413,463,286,441,414,286,258,441,258,257,442,257,259,443,259,260,444,260,467,445,309,459,250,305,289,290,305,290,460,401,376,435,309,250,392,376,411,433,453,341,464,357,453,465,343,357,412,437,343,399,344,360,440,420,437,456,360,420,363,361,401,288,265,372,353,390,339,249,339,448,255];var Wr=[127,234,132,58,172,150,149,148,152,377,378,379,397,288,361,454,356,70,63,105,66,107,336,296,334,293,300,168,6,195,4,98,97,2,326,327,33,160,158,133,153,144,362,385,387,263,373,380,57,40,37,0,267,270,287,321,314,17,84,91,78,81,13,311,308,402,14,178],Or=[33,133,362,263,1,62,308,159,145,386,374,6,102,331,2,13,14,70,105,107,336,334,300,54,10,284,50,280,234,454,58,288,152],Ir=[33,133,362,263,1,78,308],Es=Wr.map(e=>Ve[e]),zs=Or.map(e=>Ve[e]),js=Ir.map(e=>Ve[e]);var fe=e=>[Math.abs(e.endPoint[0]-e.startPoint[0]),Math.abs(e.endPoint[1]-e.startPoint[1])],rt=e=>[e.startPoint[0]+(e.endPoint[0]-e.startPoint[0])/2,e.startPoint[1]+(e.endPoint[1]-e.startPoint[1])/2,1],i5=(e,t)=>e?[Math.trunc(Math.max(0,e.startPoint[0])),Math.trunc(Math.max(0,e.startPoint[1])),Math.trunc(Math.min(t.shape[2]||0,e.endPoint[0])-Math.max(0,e.startPoint[0])),Math.trunc(Math.min(t.shape[1]||0,e.endPoint[1])-Math.max(0,e.startPoint[1]))]:[0,0,0,0],l5=(e,t)=>e?[e.startPoint[0]/(t.shape[2]||0),e.startPoint[1]/(t.shape[1]||0),(e.endPoint[0]-e.startPoint[0])/(t.shape[2]||0),(e.endPoint[1]-e.startPoint[1])/(t.shape[1]||0)]:[0,0,0,0],on=(e,t)=>{let o=[e.startPoint[0]*t[0],e.startPoint[1]*t[1]],n=[e.endPoint[0]*t[0],e.endPoint[1]*t[1]];return{startPoint:o,endPoint:n,landmarks:e.landmarks,confidence:e.confidence}},s5=(e,t,o)=>{let n=t.shape[1],A=t.shape[2],s=[e.startPoint[1]/n,e.startPoint[0]/A,e.endPoint[1]/n,e.endPoint[0]/A],a=r.image.cropAndResize(t,[s],[0],o),i=r.div(a,N.tf255);return r.dispose(a),i},st=(e,t)=>{let o=rt(e),n=fe(e),A=[t*n[0]/2,t*n[1]/2];return{startPoint:[o[0]-A[0],o[1]-A[1]],endPoint:[o[0]+A[0],o[1]+A[1]],landmarks:e.landmarks,confidence:e.confidence}},at=e=>{let t=rt(e),o=fe(e),n=Math.max(...o)/2;return{startPoint:[Math.round(t[0]-n),Math.round(t[1]-n)],endPoint:[Math.round(t[0]+n),Math.round(t[1]+n)],landmarks:e.landmarks,confidence:e.confidence}},nn=e=>{let t=e.map(n=>n[0]),o=e.map(n=>n[1]);return{startPoint:[Math.min(...t),Math.min(...o)],endPoint:[Math.max(...t),Math.max(...o)],landmarks:e}},a5=[[1,0,0],[0,1,0],[0,0,1]],Lr=e=>e-2*Math.PI*Math.floor((e+Math.PI)/(2*Math.PI)),Nr=(e,t)=>Lr(Math.PI/2-Math.atan2(-(t[1]-e[1]),t[0]-e[0]));var en=(e,t)=>[[1,0,e],[0,1,t],[0,0,1]],oe=(e,t)=>{let o=0;for(let n=0;n{let o=[];for(let n=0;n{let o=[],n=e.length;for(let A=0;A{let o=Math.cos(e),n=Math.sin(e),A=[[o,-n,0],[n,o,0],[0,0,1]],s=en(t[0],t[1]),a=tn(s,A),i=en(-t[0],-t[1]);return tn(a,i)},Br=e=>{let t=[[e[0][0],e[1][0]],[e[0][1],e[1][1]]],o=[e[0][2],e[1][2]],n=[-oe(t[0],o),-oe(t[1],o)];return[t[0].concat(n[0]),t[1].concat(n[1]),[0,0,1]]},Fr=(e,t)=>[oe(e,t[0]),oe(e,t[1])];function rn(e){let t={strides:[e/16,e/8],anchors:[2,6]},o=[];for(let n=0;n[s[0]/A*(f[0]-A/2),s[1]/A*(f[1]-A/2),f[2]||0]),i=o&&o!==0&&Math.abs(o)>.2,x=i?An(o,[0,0]):a5,d=i?a.map(f=>[...Fr(f,x),f[2]]):a,l=i?Br(n):a5,y=rt(t),c=[oe(y,l[0]),oe(y,l[1])];return d.map(f=>[Math.trunc(f[0]+c[0]),Math.trunc(f[1]+c[1]),Math.trunc(f[2]||0)])}function an(e,t,o,n){let A=t.landmarks.length>=n5.count?n5.symmetryLine:He.symmetryLine,s=0,a=a5,i;if(e&&w.kernels.includes("rotatewithoffset"))if(s=Nr(t.landmarks[A[0]],t.landmarks[A[1]]),s&&s!==0&&Math.abs(s)>.2){let d=rt(t),l=[d[0]/o.shape[2],d[1]/o.shape[1]],y=r.image.rotateWithOffset(o,s,0,l);a=An(-s,d),i=s5(t,y,[n,n]),r.dispose(y)}else i=s5(t,o,[n,n]);else i=s5(t,o,[n,n]);return[s,a,i]}var Hr=e=>{let t=e.map(n=>n[0]),o=e.map(n=>n[1]);return[Math.min(...t)+(Math.max(...t)-Math.min(...t))/2,Math.min(...o)+(Math.max(...o)-Math.min(...o))/2]},ln=(e,t)=>{let o=Hr(e),n=fe(t);return{startPoint:[o[0]-n[0]/2,o[1]-n[1]/2],endPoint:[o[0]+n[0]/2,o[1]+n[1]/2]}};var yn=6,Vr=1.4,R0,xn=null,Z0=0,Ze=null,it=()=>Z0;async function cn(e){var t;return w.initial&&(R0=null),R0?e.debug&&b("cached model:",R0.modelUrl):R0=await L((t=e.face.detector)==null?void 0:t.modelPath),Z0=R0.inputs[0].shape?R0.inputs[0].shape[2]:0,Ze=r.scalar(Z0,"int32"),xn=r.tensor2d(rn(Z0)),R0}function Zr(e){let t={};t.boxStarts=r.slice(e,[0,1],[-1,2]),t.centers=r.add(t.boxStarts,xn),t.boxSizes=r.slice(e,[0,3],[-1,2]),t.boxSizesNormalized=r.div(t.boxSizes,Ze),t.centersNormalized=r.div(t.centers,Ze),t.halfBoxSize=r.div(t.boxSizesNormalized,N.tf2),t.starts=r.sub(t.centersNormalized,t.halfBoxSize),t.ends=r.add(t.centersNormalized,t.halfBoxSize),t.startNormalized=r.mul(t.starts,Ze),t.endNormalized=r.mul(t.ends,Ze);let o=r.concat2d([t.startNormalized,t.endNormalized],1);return Object.keys(t).forEach(n=>r.dispose(t[n])),o}async function dn(e,t){var i,x,d,l;if(!e||e.isDisposedInternal||e.shape.length!==4||e.shape[1]<1||e.shape[2]<1)return[];let o={};o.resized=r.image.resizeBilinear(e,[Z0,Z0]),o.div=r.div(o.resized,N.tf127),o.normalized=r.sub(o.div,N.tf05);let n=R0==null?void 0:R0.execute(o.normalized);if(Array.isArray(n)){let y=n.sort((c,f)=>c.size-f.size);o.concat384=r.concat([y[0],y[2]],2),o.concat512=r.concat([y[1],y[3]],2),o.concat=r.concat([o.concat512,o.concat384],1),o.batch=r.squeeze(o.concat,0)}else o.batch=r.squeeze(n);r.dispose(n),o.boxes=Zr(o.batch),o.logits=r.slice(o.batch,[0,0],[-1,1]),o.sigmoid=r.sigmoid(o.logits),o.scores=r.squeeze(o.sigmoid),o.nms=await r.image.nonMaxSuppressionAsync(o.boxes,o.scores,((i=t.face.detector)==null?void 0:i.maxDetected)||0,((x=t.face.detector)==null?void 0:x.iouThreshold)||0,((d=t.face.detector)==null?void 0:d.minConfidence)||0);let A=await o.nms.array(),s=[],a=await o.scores.data();for(let y=0;y(((l=t.face.detector)==null?void 0:l.minConfidence)||0)){let f={};f.bbox=r.slice(o.boxes,[A[y],0],[1,-1]),f.slice=r.slice(o.batch,[A[y],yn-1],[1,-1]),f.squeeze=r.squeeze(f.slice),f.landmarks=r.reshape(f.squeeze,[yn,-1]);let h=await f.bbox.data(),m={startPoint:[h[0],h[1]],endPoint:[h[2],h[3]],landmarks:await f.landmarks.array(),confidence:c},v=on(m,[(e.shape[2]||0)/Z0,(e.shape[1]||0)/Z0]),M=st(v,t.face.scale||Vr),u=at(M);s.push(u),Object.keys(f).forEach(p=>r.dispose(f[p]))}}return Object.keys(o).forEach(y=>r.dispose(o[y])),s}var lt={};$0(lt,{connected:()=>c5,kpt:()=>x5});var x5=["nose","leftEyeInside","leftEye","leftEyeOutside","rightEyeInside","rightEye","rightEyeOutside","leftEar","rightEar","leftMouth","rightMouth","leftShoulder","rightShoulder","leftElbow","rightElbow","leftWrist","rightWrist","leftPinky","rightPinky","leftIndex","rightIndex","leftThumb","rightThumb","leftHip","rightHip","leftKnee","rightKnee","leftAnkle","rightAnkle","leftHeel","rightHeel","leftFoot","rightFoot","bodyCenter","bodyTop","leftPalm","leftHand","rightPalm","rightHand"],c5={shoulders:["leftShoulder","rightShoulder"],hips:["rightHip","leftHip"],mouth:["leftMouth","rightMouth"],leftLegUpper:["leftHip","leftKnee"],leftLegLower:["leftKnee","leftAnkle"],leftFoot:["leftAnkle","leftHeel","leftFoot"],leftTorso:["leftShoulder","leftHip"],leftArmUpper:["leftShoulder","leftElbow"],leftArmLower:["leftElbow","leftWrist"],leftHand:["leftWrist","leftPalm"],leftHandPinky:["leftPalm","leftPinky"],leftHandIndex:["leftPalm","leftIndex"],leftHandThumb:["leftPalm","leftThumb"],leftEyeOutline:["leftEyeInside","leftEyeOutside"],rightLegUpper:["rightHip","rightKnee"],rightLegLower:["rightKnee","rightAnkle"],rightFoot:["rightAnkle","rightHeel","rightFoot"],rightTorso:["rightShoulder","rightHip"],rightArmUpper:["rightShoulder","rightElbow"],rightArmLower:["rightElbow","rightWrist"],rightHand:["rightWrist","rightPalm"],rightHandPinky:["rightPalm","rightPinky"],rightHandIndex:["rightPalm","rightIndex"],rightHandThumb:["rightPalm","rightThumb"],rightEyeOutline:["rightEyeInside","rightEyeOutside"]};var mn=224,Xr,Dr=5,yt=[8,16,32,32,32];async function pn(){let e=[],t=0;for(;to.x)),y:r.tensor1d(e.map(o=>o.y))}}function L0(e,t=[1,1]){let o=[e.map(i=>i[0]),e.map(i=>i[1])],n=[Math.min(...o[0]),Math.min(...o[1])],A=[Math.max(...o[0]),Math.max(...o[1])],s=[n[0],n[1],A[0]-n[0],A[1]-n[1]],a=[s[0]/t[0],s[1]/t[1],s[2]/t[0],s[3]/t[1]];return{box:s,boxRaw:a}}function un(e,t=[1,1]){let o=[e.map(d=>d[0]),e.map(d=>d[1])],n=[Math.min(...o[0]),Math.min(...o[1])],A=[Math.max(...o[0]),Math.max(...o[1])],s=[(n[0]+A[0])/2,(n[1]+A[1])/2],a=Math.max(s[0]-n[0],s[1]-n[1],-s[0]+A[0],-s[1]+A[1]),i=[Math.trunc(s[0]-a),Math.trunc(s[1]-a),Math.trunc(2*a),Math.trunc(2*a)],x=[i[0]/t[0],i[1]/t[1],i[2]/t[0],i[3]/t[1]];return{box:i,boxRaw:x}}function xt(e,t){let o=[e[2]*t,e[3]*t];return[e[0]-(o[0]-e[2])/2,e[1]-(o[1]-e[3])/2,o[0],o[1]]}var gn={initial:!0},x0={detector:null,landmarks:null},me={detector:[224,224],landmarks:[256,256]},d5=Number.MAX_SAFE_INTEGER,Ur={landmarks:["ld_3d","activation_segmentation","activation_heatmap","world_3d","output_poseflag"],detector:[]},dt=null,Xe,X0=[[0,0],[0,0],[0,0],[0,0]],hn=0,bn=e=>1-1/(1+Math.exp(e));async function Mn(e){if(gn.initial&&(x0.detector=null),!x0.detector&&e.body.detector&&e.body.detector.modelPath){x0.detector=await L(e.body.detector.modelPath);let t=Object.values(x0.detector.modelSignature.inputs);me.detector[0]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[1].size):0,me.detector[1]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}else e.debug&&x0.detector&&b("cached model:",x0.detector.modelUrl);return await pn(),x0.detector}async function Pn(e){if(gn.initial&&(x0.landmarks=null),x0.landmarks)e.debug&&b("cached model:",x0.landmarks.modelUrl);else{x0.landmarks=await L(e.body.modelPath);let t=Object.values(x0.landmarks.modelSignature.inputs);me.landmarks[0]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[1].size):0,me.landmarks[1]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}return x0.landmarks}async function Jr(e,t){let o={};if(!e.shape||!e.shape[1]||!e.shape[2])return e;let n;if(Xe&&(o.cropped=r.image.cropAndResize(e,[Xe],[0],[e.shape[1],e.shape[2]])),e.shape[1]!==e.shape[2]){let A=[e.shape[2]>e.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0,e.shape[2]>e.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0],s=[e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0,e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0];X0=[[0,0],A,s,[0,0]],o.pad=r.pad(o.cropped||e,X0),o.resize=r.image.resizeBilinear(o.pad,[t,t]),n=r.div(o.resize,N.tf255)}else e.shape[1]!==t?(o.resize=r.image.resizeBilinear(o.cropped||e,[t,t]),n=r.div(o.resize,N.tf255)):n=r.div(o.cropped||e,N.tf255);return Object.keys(o).forEach(A=>r.dispose(o[A])),n}function Yr(e,t){for(let o of e)o.position=[Math.trunc(o.position[0]*(t[0]+X0[2][0]+X0[2][1])/t[0]-X0[2][0]),Math.trunc(o.position[1]*(t[1]+X0[1][0]+X0[1][1])/t[1]-X0[1][0]),o.position[2]],o.positionRaw=[o.position[0]/t[0],o.position[1]/t[1],2*o.position[2]/(t[0]+t[1])];if(Xe)for(let o of e)o.positionRaw=[o.positionRaw[0]+Xe[1],o.positionRaw[1]+Xe[0],o.positionRaw[2]],o.position=[Math.trunc(o.positionRaw[0]*t[0]),Math.trunc(o.positionRaw[1]*t[1]),o.positionRaw[2]];return e}async function Kr(e){let t=e.find(i=>i.part==="leftPalm"),o=e.find(i=>i.part==="leftWrist"),n=e.find(i=>i.part==="leftIndex");t.position[2]=((o.position[2]||0)+(n.position[2]||0))/2;let A=e.find(i=>i.part==="rightPalm"),s=e.find(i=>i.part==="rightWrist"),a=e.find(i=>i.part==="rightIndex");A.position[2]=((s.position[2]||0)+(a.position[2]||0))/2}async function Qr(e,t,o){var h;let n={};[n.ld,n.segmentation,n.heatmap,n.world,n.poseflag]=(h=x0.landmarks)==null?void 0:h.execute(e,Ur.landmarks);let A=(await n.poseflag.data())[0],s=await n.ld.data(),a=await n.world.data();Object.keys(n).forEach(m=>r.dispose(n[m]));let i=[],x=5;for(let m=0;mm.position),y=L0(l,[o[0],o[1]]),c={};for(let[m,v]of Object.entries(c5)){let M=[];for(let u=0;uR.part===v[u]),P=d.find(R=>R.part===v[u+1]);p&&P&&M.push([p.position,P.position])}c[m]=M}return{id:0,score:Math.trunc(100*A)/100,box:y.box,boxRaw:y.boxRaw,keypoints:d,annotations:c}}async function f5(e,t){let o=[e.shape[2]||0,e.shape[1]||0],n=(t.body.skipTime||0)>g()-hn,A=d5<(t.body.skipFrames||0);if(t.skipAllowed&&n&&A&&dt!==null)d5++;else{let s={};s.landmarks=await Jr(e,256),dt=await Qr(s.landmarks,t,o),Object.keys(s).forEach(a=>r.dispose(s[a])),hn=g(),d5=0}return dt?[dt]:[]}var pe=[{class:1,label:"person"},{class:2,label:"bicycle"},{class:3,label:"car"},{class:4,label:"motorcycle"},{class:5,label:"airplane"},{class:6,label:"bus"},{class:7,label:"train"},{class:8,label:"truck"},{class:9,label:"boat"},{class:10,label:"traffic light"},{class:11,label:"fire hydrant"},{class:12,label:"stop sign"},{class:13,label:"parking meter"},{class:14,label:"bench"},{class:15,label:"bird"},{class:16,label:"cat"},{class:17,label:"dog"},{class:18,label:"horse"},{class:19,label:"sheep"},{class:20,label:"cow"},{class:21,label:"elephant"},{class:22,label:"bear"},{class:23,label:"zebra"},{class:24,label:"giraffe"},{class:25,label:"backpack"},{class:26,label:"umbrella"},{class:27,label:"handbag"},{class:28,label:"tie"},{class:29,label:"suitcase"},{class:30,label:"frisbee"},{class:31,label:"skis"},{class:32,label:"snowboard"},{class:33,label:"sports ball"},{class:34,label:"kite"},{class:35,label:"baseball bat"},{class:36,label:"baseball glove"},{class:37,label:"skateboard"},{class:38,label:"surfboard"},{class:39,label:"tennis racket"},{class:40,label:"bottle"},{class:41,label:"wine glass"},{class:42,label:"cup"},{class:43,label:"fork"},{class:44,label:"knife"},{class:45,label:"spoon"},{class:46,label:"bowl"},{class:47,label:"banana"},{class:48,label:"apple"},{class:49,label:"sandwich"},{class:50,label:"orange"},{class:51,label:"broccoli"},{class:52,label:"carrot"},{class:53,label:"hot dog"},{class:54,label:"pizza"},{class:55,label:"donut"},{class:56,label:"cake"},{class:57,label:"chair"},{class:58,label:"couch"},{class:59,label:"potted plant"},{class:60,label:"bed"},{class:61,label:"dining table"},{class:62,label:"toilet"},{class:63,label:"tv"},{class:64,label:"laptop"},{class:65,label:"mouse"},{class:66,label:"remote"},{class:67,label:"keyboard"},{class:68,label:"cell phone"},{class:69,label:"microwave"},{class:70,label:"oven"},{class:71,label:"toaster"},{class:72,label:"sink"},{class:73,label:"refrigerator"},{class:74,label:"book"},{class:75,label:"clock"},{class:76,label:"vase"},{class:77,label:"scissors"},{class:78,label:"teddy bear"},{class:79,label:"hair drier"},{class:80,label:"toothbrush"}];var N0,ne=0,m5=[],Tn=0,p5=Number.MAX_SAFE_INTEGER;async function wn(e){if(w.initial&&(N0=null),N0)e.debug&&b("cached model:",N0.modelUrl);else{N0=await L(e.object.modelPath);let t=Object.values(N0.modelSignature.inputs);ne=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}return N0}async function _r(e,t,o){if(!e)return[];let n={},A=[],s=await e.array();n.squeeze=r.squeeze(e);let a=r.split(n.squeeze,6,1);n.stack=r.stack([a[1],a[0],a[3],a[2]],1),n.boxes=r.squeeze(n.stack),n.scores=r.squeeze(a[4]),n.classes=r.squeeze(a[5]),r.dispose([e,...a]),n.nms=await r.image.nonMaxSuppressionAsync(n.boxes,n.scores,o.object.maxDetected,o.object.iouThreshold,o.object.minConfidence||0);let i=await n.nms.data(),x=0;for(let d of Array.from(i)){let l=Math.trunc(100*s[0][d][4])/100,y=s[0][d][5],c=pe[y].label,[f,h]=[s[0][d][0]/ne,s[0][d][1]/ne],m=[f,h,s[0][d][2]/ne-f,s[0][d][3]/ne-h],v=[Math.trunc(m[0]*t[0]),Math.trunc(m[1]*t[1]),Math.trunc(m[2]*t[0]),Math.trunc(m[3]*t[1])];A.push({id:x++,score:l,class:y,label:c,box:v,boxRaw:m})}return Object.keys(n).forEach(d=>r.dispose(n[d])),A}async function u5(e,t){let o=(t.object.skipTime||0)>g()-Tn,n=p5<(t.object.skipFrames||0);return t.skipAllowed&&o&&n&&m5.length>0?(p5++,m5):(p5=0,new Promise(async A=>{let s=[e.shape[2]||0,e.shape[1]||0],a=r.image.resizeBilinear(e,[ne,ne]),i=t.object.enabled?N0==null?void 0:N0.execute(a,["tower_0/detections"]):null;Tn=g(),r.dispose(a);let x=await _r(i,s,t);m5=x,A(x)}))}var ft={};$0(ft,{connected:()=>b5,kpt:()=>h5});var h5=["head","neck","rightShoulder","rightElbow","rightWrist","chest","leftShoulder","leftElbow","leftWrist","bodyCenter","rightHip","rightKnee","rightAnkle","leftHip","leftKnee","leftAnkle"],b5={leftLeg:["leftHip","leftKnee","leftAnkle"],rightLeg:["rightHip","rightKnee","rightAnkle"],torso:["leftShoulder","rightShoulder","rightHip","leftHip","leftShoulder"],leftArm:["leftShoulder","leftElbow","leftWrist"],rightArm:["rightShoulder","rightElbow","rightWrist"],head:[]};var r0,kn=0,i0={id:0,keypoints:[],box:[0,0,0,0],boxRaw:[0,0,0,0],score:0,annotations:{}},g5=Number.MAX_SAFE_INTEGER;async function En(e){return w.initial&&(r0=null),r0?e.debug&&b("cached model:",r0.modelUrl):r0=await L(e.body.modelPath),r0}async function $r(e,t){let[o,n]=e.shape,A=r.reshape(e,[n*o]),s=r.max(A,0),a=(await s.data())[0];if(r.dispose([A,s]),a>t){let i=r.argMax(A,0),x=r.mod(i,o),d=(await x.data())[0],l=r.div(i,r.scalar(o,"int32")),y=(await l.data())[0];return r.dispose([x,l]),[d,y,a]}return[0,0,a]}async function M5(e,t){let o=(t.body.skipTime||0)>g()-kn,n=g5<(t.body.skipFrames||0);return t.skipAllowed&&o&&n&&Object.keys(i0.keypoints).length>0?(g5++,[i0]):(g5=0,new Promise(async A=>{var y;let s=r.tidy(()=>{if(!(r0!=null&&r0.inputs[0].shape))return null;let c=r.image.resizeBilinear(e,[r0.inputs[0].shape[2],r0.inputs[0].shape[1]],!1),f=r.mul(c,N.tf2);return r.sub(f,N.tf1)}),a;if(t.body.enabled&&(a=r0==null?void 0:r0.execute(s)),kn=g(),r.dispose(s),a){i0.keypoints.length=0;let c=a.squeeze();r.dispose(a);let f=c.unstack(2);r.dispose(c);for(let h=0;h(((y=t.body)==null?void 0:y.minConfidence)||0)&&i0.keypoints.push({score:Math.round(100*M)/100,part:h5[h],positionRaw:[m/r0.inputs[0].shape[2],v/r0.inputs[0].shape[1]],position:[Math.round(e.shape[2]*m/r0.inputs[0].shape[2]),Math.round(e.shape[1]*v/r0.inputs[0].shape[1])]})}f.forEach(h=>r.dispose(h))}i0.score=i0.keypoints.reduce((c,f)=>f.score>c?f.score:c,0);let i=i0.keypoints.map(c=>c.position[0]),x=i0.keypoints.map(c=>c.position[1]);i0.box=[Math.min(...i),Math.min(...x),Math.max(...i)-Math.min(...i),Math.max(...x)-Math.min(...x)];let d=i0.keypoints.map(c=>c.positionRaw[0]),l=i0.keypoints.map(c=>c.positionRaw[1]);i0.boxRaw=[Math.min(...d),Math.min(...l),Math.max(...d)-Math.min(...d),Math.max(...l)-Math.min(...l)];for(let[c,f]of Object.entries(b5)){let h=[];for(let m=0;mu.part===f[m]),M=i0.keypoints.find(u=>u.part===f[m+1]);v&&M&&v.score>(t.body.minConfidence||0)&&M.score>(t.body.minConfidence||0)&&h.push([v.position,M.position])}i0.annotations[c]=h}A([i0])}))}var e2=["angry","disgust","fear","happy","sad","surprise","neutral"],u0,mt=[],jn=0,Sn=0,P5=Number.MAX_SAFE_INTEGER;async function Cn(e){var t;return w.initial&&(u0=null),u0?e.debug&&b("cached model:",u0.modelUrl):u0=await L((t=e.face.emotion)==null?void 0:t.modelPath),u0}async function v5(e,t,o,n){var a,i;if(!u0)return[];let A=P5<(((a=t.face.emotion)==null?void 0:a.skipFrames)||0),s=(((i=t.face.emotion)==null?void 0:i.skipTime)||0)>g()-Sn;return t.skipAllowed&&s&&A&&jn===n&&mt[o]&&mt[o].length>0?(P5++,mt[o]):(P5=0,new Promise(async x=>{var l,y;let d=[];if((l=t.face.emotion)!=null&&l.enabled){let c={},f=u0!=null&&u0.inputs[0].shape?u0.inputs[0].shape[2]:0;c.resize=r.image.resizeBilinear(e,[f,f],!1),c.channels=r.mul(c.resize,N.rgb),c.grayscale=r.sum(c.channels,3,!0),c.grayscaleSub=r.sub(c.grayscale,N.tf05),c.grayscaleMul=r.mul(c.grayscaleSub,N.tf2),c.emotion=u0==null?void 0:u0.execute(c.grayscaleMul),Sn=g();let h=await c.emotion.data();for(let m=0;m(((y=t.face.emotion)==null?void 0:y.minConfidence)||0)&&d.push({score:Math.min(.99,Math.trunc(100*h[m])/100),emotion:e2[m]});d.sort((m,v)=>v.score-m.score),Object.keys(c).forEach(m=>r.dispose(c[m]))}mt[o]=d,jn=n,x(d)}))}var c0,T5=[],On=0,In=0,Ln=Number.MAX_SAFE_INTEGER;async function Nn(e){return w.initial&&(c0=null),c0?e.debug&&b("cached model:",c0.modelUrl):c0=await L(e.face.mobilefacenet.modelPath),c0}async function w5(e,t,o,n){var a,i;if(!c0)return[];let A=Ln<(((a=t.face.embedding)==null?void 0:a.skipFrames)||0),s=(((i=t.face.embedding)==null?void 0:i.skipTime)||0)>g()-In;return t.skipAllowed&&s&&A&&On===n&&T5[o]?(Ln++,T5[o]):new Promise(async x=>{var l;let d=[];if(((l=t.face.embedding)==null?void 0:l.enabled)&&(c0==null?void 0:c0.inputs[0].shape)){let y={};y.crop=r.image.resizeBilinear(e,[c0.inputs[0].shape[2],c0.inputs[0].shape[1]],!1),y.data=c0==null?void 0:c0.execute(y.crop);let c=await y.data.data();d=Array.from(c)}T5[o]=d,On=n,In=g(),x(d)})}var G0,D0=0,t2=2.3,R5=M0.leftEyeLower0,k5=M0.rightEyeLower0,ue={leftBounds:[R5[0],R5[R5.length-1]],rightBounds:[k5[0],k5[k5.length-1]]},he={upperCenter:3,lowerCenter:4,index:71,numCoordinates:76};async function Vn(e){var t;return w.initial&&(G0=null),G0?e.debug&&b("cached model:",G0.modelUrl):G0=await L((t=e.face.iris)==null?void 0:t.modelPath),D0=G0.inputs[0].shape?G0.inputs[0].shape[2]:0,D0===-1&&(D0=64),G0}function pt(e,t,o,n){for(let A=0;A{let t=e[ue.leftBounds[0]][2],o=e[ue.rightBounds[0]][2];return t-o},Bn=(e,t,o,n,A,s=!1)=>{let a=at(st(nn([e[o],e[n]]),t2)),i=fe(a),x=r.image.cropAndResize(t,[[a.startPoint[1]/A,a.startPoint[0]/A,a.endPoint[1]/A,a.endPoint[0]/A]],[0],[D0,D0]);if(s&&w.kernels.includes("flipleftright")){let d=r.image.flipLeftRight(x);r.dispose(x),x=d}return{box:a,boxSize:i,crop:x}},Fn=(e,t,o,n=!1)=>{let A=[];for(let s=0;s{let n=e[M0[`${o}EyeUpper0`][he.upperCenter]][2],A=e[M0[`${o}EyeLower0`][he.lowerCenter]][2],s=(n+A)/2;return t.map((a,i)=>{let x=s;return i===2?x=n:i===4&&(x=A),[a[0],a[1],x]})};async function Zn(e,t,o,n){if(!G0)return o.debug&&b("face mesh iris detection requested, but model is not loaded"),e;let{box:A,boxSize:s,crop:a}=Bn(e,t,ue.leftBounds[0],ue.leftBounds[1],n,!0),{box:i,boxSize:x,crop:d}=Bn(e,t,ue.rightBounds[0],ue.rightBounds[1],n,!0),l=r.concat([a,d]);r.dispose(a),r.dispose(d);let y=G0.execute(l);r.dispose(l);let c=await y.data();r.dispose(y);let f=c.slice(0,he.numCoordinates*3),{rawCoords:h,iris:m}=Fn(f,A,s,!0),v=c.slice(he.numCoordinates*3),{rawCoords:M,iris:u}=Fn(v,i,x,!1),p=o2(e);Math.abs(p)<30?(pt(e,h,"left",null),pt(e,M,"right",null)):p<1?pt(e,h,"left",["EyeUpper0","EyeLower0"]):pt(e,M,"right",["EyeUpper0","EyeLower0"]);let P=Hn(e,m,"left"),R=Hn(e,u,"right");return e.concat(P).concat(R)}async function Dn(e,t){let o={eyeL:t[0].dataSync(),eyeR:t[6].dataSync(),irisL:t[3].dataSync(),irisR:t[1].dataSync(),lips:t[5].dataSync()};for(let n=0;ng()-k0.timestamp,n=k0.skipped<(((x=t.face.detector)==null?void 0:x.skipFrames)||0);!t.skipAllowed||!o||!n||k0.boxes.length===0?(k0.boxes=await dn(e,t),k0.timestamp=g(),k0.skipped=0):k0.skipped++;let A=[],s=[],a=0;for(let M=0;MB.shape[B.shape.length-1]===1),C=S.find(B=>B.shape[B.shape.length-1]===1404),I=await O.data();R.faceScore=Math.round(100*I[0])/100;let V=r.reshape(C,[-1,3]),G=await V.array();if(R.faceScore<(((f=t.face.detector)==null?void 0:f.minConfidence)||1))u.confidence=R.faceScore;else{(h=t.face.attention)!=null&&h.enabled?G=await Dn(G,S):(m=t.face.iris)!=null&&m.enabled&&(G=await Zn(G,R.tensor,t,be)),R.mesh=sn(G,u,p,P,be),R.meshRaw=R.mesh.map(J=>[J[0]/(e.shape[2]||0),J[1]/(e.shape[1]||0),(J[2]||0)/be]);for(let J of Object.keys(M0))R.annotations[J]=M0[J].map(z=>R.mesh[z]);R.score=R.faceScore;let B={...ln(R.mesh,u),confidence:u.confidence,landmarks:u.landmarks};R.box=i5(B,e),R.boxRaw=l5(B,e),s.push(B)}r.dispose([...S,V])}else{R.box=i5(u,e),R.boxRaw=l5(u,e),R.score=R.boxScore,R.mesh=u.landmarks.map(S=>[(u.startPoint[0]+u.endPoint[0])/2+(u.endPoint[0]+u.startPoint[0])*S[0]/it(),(u.startPoint[1]+u.endPoint[1])/2+(u.endPoint[1]+u.startPoint[1])*S[1]/it()]),R.meshRaw=R.mesh.map(S=>[S[0]/(e.shape[2]||0),S[1]/(e.shape[1]||0),(S[2]||0)/be]);for(let S of Object.keys(He))R.annotations[S]=[R.mesh[He[S]]]}R.score>(((v=t.face.detector)==null?void 0:v.minConfidence)||1)?A.push(R):r.dispose(R.tensor)}return k0.boxes=s,A}async function Un(e){var t,o,n;return w.initial&&(E0=null),E0?e.debug&&b("cached model:",E0.modelUrl):(t=e.face.attention)!=null&&t.enabled?E0=await L((o=e.face.attention)==null?void 0:o.modelPath):E0=await L((n=e.face.mesh)==null?void 0:n.modelPath),be=E0.inputs[0].shape?E0.inputs[0].shape[2]:0,E0}var Jn=te,Yn=Ve;var d0,ut=[],Kn=0,Qn=0,z5=Number.MAX_SAFE_INTEGER;async function _n(e){var t;return w.initial&&(d0=null),d0?e.debug&&b("cached model:",d0.modelUrl):d0=await L((t=e.face.description)==null?void 0:t.modelPath),d0}function j5(e){let t=e.image||e.tensor||e;if(!(d0!=null&&d0.inputs[0].shape))return t;let o=r.image.resizeBilinear(t,[d0.inputs[0].shape[2],d0.inputs[0].shape[1]],!1),n=r.mul(o,N.tf255);return r.dispose(o),n}async function S5(e,t,o,n){var a,i,x,d;if(!d0)return{age:0,gender:"unknown",genderScore:0,descriptor:[]};let A=z5<(((a=t.face.description)==null?void 0:a.skipFrames)||0),s=(((i=t.face.description)==null?void 0:i.skipTime)||0)>g()-Kn;return t.skipAllowed&&A&&s&&Qn===n&&((x=ut[o])==null?void 0:x.age)&&((d=ut[o])==null?void 0:d.age)>0?(z5++,ut[o]):(z5=0,new Promise(async l=>{var c,f;let y={age:0,gender:"unknown",genderScore:0,descriptor:[]};if((c=t.face.description)!=null&&c.enabled){let h=j5(e),m=d0==null?void 0:d0.execute(h);Kn=g(),r.dispose(h);let M=await(await m.find(I=>I.shape[1]===1)).data(),u=Math.trunc(200*Math.abs(M[0]-.5))/100;u>(((f=t.face.description)==null?void 0:f.minConfidence)||0)&&(y.gender=M[0]<=.5?"female":"male",y.genderScore=Math.min(.99,u));let p=r.argMax(m.find(I=>I.shape[1]===100),1),P=(await p.data())[0];r.dispose(p);let S=await m.find(I=>I.shape[1]===100).data();y.age=Math.round(S[P-1]>S[P+1]?10*P-100*S[P-1]:10*P+100*S[P+1])/10;let O=m.find(I=>I.shape[1]===1024),C=O?await O.data():[];y.descriptor=Array.from(C),m.forEach(I=>r.dispose(I))}ut[o]=y,Qn=n,l(y)}))}function ht(e){return[Math.abs(e.endPoint[0]-e.startPoint[0]),Math.abs(e.endPoint[1]-e.startPoint[1])]}function De(e){return[e.startPoint[0]+(e.endPoint[0]-e.startPoint[0])/2,e.startPoint[1]+(e.endPoint[1]-e.startPoint[1])/2]}function tA(e,t,o){let n=t.shape[1],A=t.shape[2],s=[[e.startPoint[1]/n,e.startPoint[0]/A,e.endPoint[1]/n,e.endPoint[0]/A]];return r.image.cropAndResize(t,s,[0],o)}function oA(e,t){let o=[e.startPoint[0]*t[0],e.startPoint[1]*t[1]],n=[e.endPoint[0]*t[0],e.endPoint[1]*t[1]],A=e.palmLandmarks.map(s=>[s[0]*t[0],s[1]*t[1]]);return{startPoint:o,endPoint:n,palmLandmarks:A,confidence:e.confidence}}function bt(e,t=1.5){let o=De(e),n=ht(e),A=[t*n[0]/2,t*n[1]/2],s=[o[0]-A[0],o[1]-A[1]],a=[o[0]+A[0],o[1]+A[1]];return{startPoint:s,endPoint:a,palmLandmarks:e.palmLandmarks}}function gt(e){let t=De(e),o=ht(e),A=Math.max(...o)/2,s=[t[0]-A,t[1]-A],a=[t[0]+A,t[1]+A];return{startPoint:s,endPoint:a,palmLandmarks:e.palmLandmarks}}function A2(e){return e-2*Math.PI*Math.floor((e+Math.PI)/(2*Math.PI))}function nA(e,t){let o=Math.PI/2-Math.atan2(-(t[1]-e[1]),t[0]-e[0]);return A2(o)}var $n=(e,t)=>[[1,0,e],[0,1,t],[0,0,1]];function q0(e,t){let o=0;for(let n=0;n[o.x,o.y]),this.anchorsTensor=r.tensor2d(this.anchors),this.inputSize=this.model&&this.model.inputs&&this.model.inputs[0].shape?this.model.inputs[0].shape[2]:0,this.inputSizeTensor=r.tensor1d([this.inputSize,this.inputSize]),this.doubleInputSizeTensor=r.tensor1d([this.inputSize*2,this.inputSize*2])}normalizeBoxes(t){let o={};o.boxOffsets=r.slice(t,[0,0],[-1,2]),o.boxSizes=r.slice(t,[0,2],[-1,2]),o.div=r.div(o.boxOffsets,this.inputSizeTensor),o.boxCenterPoints=r.add(o.div,this.anchorsTensor),o.halfBoxSizes=r.div(o.boxSizes,this.doubleInputSizeTensor),o.sub=r.sub(o.boxCenterPoints,o.halfBoxSizes),o.startPoints=r.mul(o.sub,this.inputSizeTensor),o.add=r.add(o.boxCenterPoints,o.halfBoxSizes),o.endPoints=r.mul(o.add,this.inputSizeTensor);let n=r.concat2d([o.startPoints,o.endPoints],1);return Object.keys(o).forEach(A=>r.dispose(o[A])),n}normalizeLandmarks(t,o){let n={};n.reshape=r.reshape(t,[-1,7,2]),n.div=r.div(n.reshape,this.inputSizeTensor),n.landmarks=r.add(n.div,this.anchors[o]);let A=r.mul(n.landmarks,this.inputSizeTensor);return Object.keys(n).forEach(s=>r.dispose(n[s])),A}async predict(t,o){let n={};n.resize=r.image.resizeBilinear(t,[this.inputSize,this.inputSize]),n.div=r.div(n.resize,N.tf127),n.image=r.sub(n.div,N.tf1),n.batched=this.model.execute(n.image),n.predictions=r.squeeze(n.batched),n.slice=r.slice(n.predictions,[0,0],[-1,1]),n.sigmoid=r.sigmoid(n.slice),n.scores=r.squeeze(n.sigmoid);let A=await n.scores.data();n.boxes=r.slice(n.predictions,[0,1],[-1,4]),n.norm=this.normalizeBoxes(n.boxes),n.nms=await r.image.nonMaxSuppressionAsync(n.norm,n.scores,3*o.hand.maxDetected,o.hand.iouThreshold,o.hand.minConfidence);let s=await n.nms.array(),a=[];for(let i of s){let x={};x.box=r.slice(n.norm,[i,0],[1,-1]),x.slice=r.slice(n.predictions,[i,5],[1,14]),x.norm=this.normalizeLandmarks(x.slice,i),x.palmLandmarks=r.reshape(x.norm,[-1,2]);let d=await x.box.data(),l=d.slice(0,2),y=d.slice(2,4),c=await x.palmLandmarks.array(),f={startPoint:l,endPoint:y,palmLandmarks:c,confidence:A[i]},h=oA(f,[t.shape[2]/this.inputSize,t.shape[1]/this.inputSize]);a.push(h),Object.keys(x).forEach(m=>r.dispose(x[m]))}return Object.keys(n).forEach(i=>r.dispose(n[i])),a}};var i2=5,aA=1.65,iA=[0,5,9,13,17,1,2],l2=0,y2=2,lA=0,Pt=class{constructor(t,o){k(this,"handDetector");k(this,"handPoseModel");k(this,"inputSize");k(this,"storedBoxes");k(this,"skipped");k(this,"detectedHands");this.handDetector=t,this.handPoseModel=o,this.inputSize=this.handPoseModel&&this.handPoseModel.inputs[0].shape?this.handPoseModel.inputs[0].shape[2]:0,this.storedBoxes=[],this.skipped=Number.MAX_SAFE_INTEGER,this.detectedHands=0}calculateLandmarksBoundingBox(t){let o=t.map(a=>a[0]),n=t.map(a=>a[1]),A=[Math.min(...o),Math.min(...n)],s=[Math.max(...o),Math.max(...n)];return{startPoint:A,endPoint:s}}getBoxForPalmLandmarks(t,o){let n=t.map(s=>O5([...s,1],o)),A=this.calculateLandmarksBoundingBox(n);return bt(gt(A),i2)}getBoxForHandLandmarks(t){let o=this.calculateLandmarksBoundingBox(t),n=bt(gt(o),aA);n.palmLandmarks=[];for(let A=0;A[a[0]*(f[0]-this.inputSize/2),a[1]*(f[1]-this.inputSize/2),a[2]*f[2]]),x=W5(n,[0,0]),d=i.map(f=>[...O5(f,x),f[2]]),l=AA(A),y=[...De(o),1],c=[q0(y,l[0]),q0(y,l[1])];return d.map(f=>[Math.trunc(f[0]+c[0]),Math.trunc(f[1]+c[1]),Math.trunc(f[2])])}async estimateHands(t,o){let n=!1,A,s=(o.hand.skipTime||0)>g()-lA,a=this.skipped<(o.hand.skipFrames||0);o.skipAllowed&&s&&a&&(A=await this.handDetector.predict(t,o),this.skipped=0),o.skipAllowed&&this.skipped++,A&&A.length>0&&(A.length!==this.detectedHands&&this.detectedHands!==o.hand.maxDetected||!o.hand.landmarks)&&(this.detectedHands=0,this.storedBoxes=[...A],this.storedBoxes.length>0&&(n=!0));let i=[];for(let x=0;x=o.hand.minConfidence/4){let R=r.reshape(p,[-1,3]),S=await R.array();r.dispose(p),r.dispose(R);let O=this.transformRawCoords(S,m,l,h),C=this.getBoxForHandLandmarks(O);this.storedBoxes[x]={...C,confidence:P};let I={landmarks:O,confidence:P,boxConfidence:d.confidence,fingerConfidence:P,box:{topLeft:C.startPoint,bottomRight:C.endPoint}};i.push(I)}else this.storedBoxes[x]=null;r.dispose(p)}else{let l=bt(gt(d),aA),y={confidence:d.confidence,boxConfidence:d.confidence,fingerConfidence:0,box:{topLeft:l.startPoint,bottomRight:l.endPoint},landmarks:[]};i.push(y)}}return this.storedBoxes=this.storedBoxes.filter(x=>x!==null),this.detectedHands=i.length,i.length>o.hand.maxDetected&&(i.length=o.hand.maxDetected),i}};var l0={thumb:0,index:1,middle:2,ring:3,pinky:4,all:[0,1,2,3,4],nameMapping:{0:"thumb",1:"index",2:"middle",3:"ring",4:"pinky"},pointsMapping:{0:[[0,1],[1,2],[2,3],[3,4]],1:[[0,5],[5,6],[6,7],[7,8]],2:[[0,9],[9,10],[10,11],[11,12]],3:[[0,13],[13,14],[14,15],[15,16]],4:[[0,17],[17,18],[18,19],[19,20]]},getName:e=>l0.nameMapping[e],getPoints:e=>l0.pointsMapping[e]},J0={none:0,half:1,full:2,nameMapping:{0:"none",1:"half",2:"full"},getName:e=>J0.nameMapping[e]},U={verticalUp:0,verticalDown:1,horizontalLeft:2,horizontalRight:3,diagonalUpRight:4,diagonalUpLeft:5,diagonalDownRight:6,diagonalDownLeft:7,nameMapping:{0:"verticalUp",1:"verticalDown",2:"horizontalLeft",3:"horizontalRight",4:"diagonalUpRight",5:"diagonalUpLeft",6:"diagonalDownRight",7:"diagonalDownLeft"},getName:e=>U.nameMapping[e]},U0=class{constructor(t){k(this,"name");k(this,"curls");k(this,"directions");k(this,"weights");k(this,"weightsRelative");this.name=t,this.curls={},this.directions={},this.weights=[1,1,1,1,1],this.weightsRelative=[1,1,1,1,1]}curl(t,o,n){typeof this.curls[t]=="undefined"&&(this.curls[t]=[]),this.curls[t].push([o,n])}direction(t,o,n){this.directions[t]||(this.directions[t]=[]),this.directions[t].push([o,n])}weight(t,o){this.weights[t]=o;let n=this.weights.reduce((A,s)=>A+s,0);this.weightsRelative=this.weights.map(A=>A*5/n)}matchAgainst(t,o){let n=0;for(let A in t){let s=t[A],a=this.curls[A];if(typeof a=="undefined"){n+=this.weightsRelative[A];continue}for(let[i,x]of a)if(s===i){n+=x*this.weightsRelative[A];break}}for(let A in o){let s=o[A],a=this.directions[A];if(typeof a=="undefined"){n+=this.weightsRelative[A];continue}for(let[i,x]of a)if(s===i){n+=x*this.weightsRelative[A];break}}return n/10}};var{thumb:P0,index:B0,middle:F0,ring:Ae,pinky:re}=l0,{none:v0,half:c2,full:T0}=J0,{verticalUp:ge,verticalDown:ba,horizontalLeft:I5,horizontalRight:d2,diagonalUpRight:f2,diagonalUpLeft:Me,diagonalDownRight:ga,diagonalDownLeft:Ma}=U,Y0=new U0("thumbs up");Y0.curl(P0,v0,1);Y0.direction(P0,ge,1);Y0.direction(P0,Me,.25);Y0.direction(P0,f2,.25);for(let e of[l0.index,l0.middle,l0.ring,l0.pinky])Y0.curl(e,T0,1),Y0.direction(e,I5,1),Y0.direction(e,d2,1);var $=new U0("victory");$.curl(P0,c2,.5);$.curl(P0,v0,.5);$.direction(P0,ge,1);$.direction(P0,Me,1);$.curl(B0,v0,1);$.direction(B0,ge,.75);$.direction(B0,Me,1);$.curl(F0,v0,1);$.direction(F0,ge,1);$.direction(F0,Me,.75);$.curl(Ae,T0,1);$.direction(Ae,ge,.2);$.direction(Ae,Me,1);$.direction(Ae,I5,.2);$.curl(re,T0,1);$.direction(re,ge,.2);$.direction(re,Me,1);$.direction(re,I5,.2);$.weight(B0,2);$.weight(F0,2);var K0=new U0("point");K0.curl(P0,T0,1);K0.curl(B0,v0,.5);K0.curl(F0,T0,.5);K0.curl(Ae,T0,.5);K0.curl(re,T0,.5);K0.weight(B0,2);K0.weight(F0,2);var Q0=new U0("middle finger");Q0.curl(P0,v0,1);Q0.curl(B0,T0,.5);Q0.curl(F0,T0,.5);Q0.curl(Ae,T0,.5);Q0.curl(re,T0,.5);Q0.weight(B0,2);Q0.weight(F0,2);var Pe=new U0("open palm");Pe.curl(P0,v0,.75);Pe.curl(B0,v0,.75);Pe.curl(F0,v0,.75);Pe.curl(Ae,v0,.75);Pe.curl(re,v0,.75);var yA=[Y0,$,K0,Q0,Pe];var m2=.7,se={HALF_CURL_START_LIMIT:60,NO_CURL_START_LIMIT:130,DISTANCE_VOTE_POWER:1.1,SINGLE_ANGLE_VOTE_POWER:.9,TOTAL_ANGLE_VOTE_POWER:1.6};function xA(e,t,o,n){let A=(t-n)/(e-o),s=Math.atan(A)*180/Math.PI;return s<=0?s=-s:s>0&&(s=180-s),s}function dA(e,t){if(!e||!t)return[0,0];let o=xA(e[0],e[1],t[0],t[1]);if(e.length===2)return o;let n=xA(e[1],e[2],t[1],t[2]);return[o,n]}function cA(e,t=1){let o=0,n=0,A=0;return e>=75&&e<=105?o=1*t:e>=25&&e<=155?n=1*t:A=1*t,[o,n,A]}function p2(e,t,o){let n=e[0]-t[0],A=e[0]-o[0],s=t[0]-o[0],a=e[1]-t[1],i=e[1]-o[1],x=t[1]-o[1],d=e[2]-t[2],l=e[2]-o[2],y=t[2]-o[2],c=Math.sqrt(n*n+a*a+d*d),f=Math.sqrt(A*A+i*i+l*l),h=Math.sqrt(s*s+x*x+y*y),m=(h*h+c*c-f*f)/(2*h*c);m>1?m=1:m<-1&&(m=-1);let v=Math.acos(m);v=57.2958*v%180;let M;return v>se.NO_CURL_START_LIMIT?M=J0.none:v>se.HALF_CURL_START_LIMIT?M=J0.half:M=J0.full,M}function fA(e,t,o,n){let A;return n===Math.abs(e)?e>0?A=U.horizontalLeft:A=U.horizontalRight:n===Math.abs(t)?t>0?A=U.horizontalLeft:A=U.horizontalRight:o>0?A=U.horizontalLeft:A=U.horizontalRight,A}function mA(e,t,o,n){let A;return n===Math.abs(e)?e<0?A=U.verticalDown:A=U.verticalUp:n===Math.abs(t)?t<0?A=U.verticalDown:A=U.verticalUp:o<0?A=U.verticalDown:A=U.verticalUp,A}function u2(e,t,o,n,A,s,a,i){let x,d=mA(e,t,o,n),l=fA(A,s,a,i);return d===U.verticalUp?l===U.horizontalLeft?x=U.diagonalUpLeft:x=U.diagonalUpRight:l===U.horizontalLeft?x=U.diagonalDownLeft:x=U.diagonalDownRight,x}function h2(e,t,o,n){let A=e[0]-t[0],s=e[0]-o[0],a=t[0]-o[0],i=e[1]-t[1],x=e[1]-o[1],d=t[1]-o[1],l=Math.max(Math.abs(A),Math.abs(s),Math.abs(a)),y=Math.max(Math.abs(i),Math.abs(x),Math.abs(d)),c=0,f=0,h=0,m=y/(l+1e-5);m>1.5?c+=se.DISTANCE_VOTE_POWER:m>.66?f+=se.DISTANCE_VOTE_POWER:h+=se.DISTANCE_VOTE_POWER;let v=Math.sqrt(A*A+i*i),M=Math.sqrt(s*s+x*x),u=Math.sqrt(a*a+d*d),p=Math.max(v,M,u),P=e[0],R=e[1],S=o[0],O=o[1];p===v?(S=o[0],O=o[1]):p===u&&(P=t[0],R=t[1]);let V=dA([P,R],[S,O]),G=cA(V,se.TOTAL_ANGLE_VOTE_POWER);c+=G[0],f+=G[1],h+=G[2];for(let J of n){let z=cA(J,se.SINGLE_ANGLE_VOTE_POWER);c+=z[0],f+=z[1],h+=z[2]}let B;return c===Math.max(c,f,h)?B=mA(x,i,d,y):h===Math.max(f,h)?B=fA(s,A,a,l):B=u2(x,i,d,y,s,A,a,l),B}function pA(e){let t=[],o=[],n=[],A=[];if(!e)return{curls:n,directions:A};for(let s of l0.all){let a=l0.getPoints(s),i=[],x=[];for(let d of a){let l=e[d[0]],y=e[d[1]],c=dA(l,y),f=c[0],h=c[1];i.push(f),x.push(h)}t.push(i),o.push(x)}for(let s of l0.all){let a=s===l0.thumb?1:0,i=l0.getPoints(s),x=e[i[a][0]],d=e[i[a+1][1]],l=e[i[3][1]],y=p2(x,d,l),c=h2(x,d,l,t[s].slice(a));n[s]=y,A[s]=c}return{curls:n,directions:A}}function vt(e){if(!e||e.length===0)return null;let t=pA(e),o={};for(let n of l0.all)o[l0.getName(n)]={curl:J0.getName(t.curls[n]),direction:U.getName(t.directions[n])};return o}function uA(e){let t=[];if(!e||e.length===0)return t;let o=pA(e);for(let n of yA){let A=n.matchAgainst(o.curls,o.directions);A>=m2&&t.push({name:n.name,confidence:A})}return t}var hA={thumb:[1,2,3,4],index:[5,6,7,8],middle:[9,10,11,12],ring:[13,14,15,16],pinky:[17,18,19,20],palm:[0]},ve,Te,bA;async function N5(e,t){let o=await bA.estimateHands(e,t);if(!o)return[];let n=[];for(let A=0;Ao[A].landmarks[y]);let a=o[A].landmarks,i=[Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,0,0],x=[0,0,0,0];if(a&&a.length>0){for(let l of a)l[0]i[2]&&(i[2]=l[0]),l[1]>i[3]&&(i[3]=l[1]);i[2]-=i[0],i[3]-=i[1],x=[i[0]/(e.shape[2]||0),i[1]/(e.shape[1]||0),i[2]/(e.shape[2]||0),i[3]/(e.shape[1]||0)]}else i=o[A].box?[Math.trunc(Math.max(0,o[A].box.topLeft[0])),Math.trunc(Math.max(0,o[A].box.topLeft[1])),Math.trunc(Math.min(e.shape[2]||0,o[A].box.bottomRight[0])-Math.max(0,o[A].box.topLeft[0])),Math.trunc(Math.min(e.shape[1]||0,o[A].box.bottomRight[1])-Math.max(0,o[A].box.topLeft[1]))]:[0,0,0,0],x=[o[A].box.topLeft[0]/(e.shape[2]||0),o[A].box.topLeft[1]/(e.shape[1]||0),(o[A].box.bottomRight[0]-o[A].box.topLeft[0])/(e.shape[2]||0),(o[A].box.bottomRight[1]-o[A].box.topLeft[1])/(e.shape[1]||0)];let d=vt(a);n.push({id:A,score:Math.round(100*o[A].confidence)/100,boxScore:Math.round(100*o[A].boxConfidence)/100,fingerScore:Math.round(100*o[A].fingerConfidence)/100,label:"hand",box:i,boxRaw:x,keypoints:a,annotations:s,landmarks:d})}return n}async function G5(e){var o,n;w.initial&&(ve=null,Te=null),!ve||!Te?[ve,Te]=await Promise.all([e.hand.enabled?L((o=e.hand.detector)==null?void 0:o.modelPath):null,e.hand.landmarks?L((n=e.hand.skeleton)==null?void 0:n.modelPath):null]):(e.debug&&b("cached model:",ve.modelUrl),e.debug&&b("cached model:",Te.modelUrl));let t=new Mt(ve);return bA=new Pt(t,Te),[ve,Te]}var t0=[null,null],b2=["StatefulPartitionedCall/Postprocessor/Slice","StatefulPartitionedCall/Postprocessor/ExpandDims_1"],_0=[[0,0],[0,0]],g2=["hand","fist","pinch","point","face","tip","pinchtip"],MA=4,PA=1.6,M2=512,P2=1.4,Tt=Number.MAX_SAFE_INTEGER,B5=0,H0=[0,0],K={boxes:[],hands:[]},vA={thumb:[1,2,3,4],index:[5,6,7,8],middle:[9,10,11,12],ring:[13,14,15,16],pinky:[17,18,19,20],base:[0],palm:[0,17,13,9,5,1,0]};async function TA(e){var t;if(w.initial&&(t0[0]=null),t0[0])e.debug&&b("cached model:",t0[0].modelUrl);else{wt(["tensorlistreserve","enter","tensorlistfromtensor","merge","loopcond","switch","exit","tensorliststack","nextiteration","tensorlistsetitem","tensorlistgetitem","reciprocal","shape","split","where"],e),t0[0]=await L((t=e.hand.detector)==null?void 0:t.modelPath);let o=Object.values(t0[0].modelSignature.inputs);_0[0][0]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[1].size):0,_0[0][1]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[2].size):0}return t0[0]}async function wA(e){var t;if(w.initial&&(t0[1]=null),t0[1])e.debug&&b("cached model:",t0[1].modelUrl);else{t0[1]=await L((t=e.hand.skeleton)==null?void 0:t.modelPath);let o=Object.values(t0[1].modelSignature.inputs);_0[1][0]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[1].size):0,_0[1][1]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[2].size):0}return t0[1]}async function v2(e,t){let o=[];if(!e||!t0[0])return o;let n={},A=(e.shape[2]||1)/(e.shape[1]||1),s=Math.min(Math.round((e.shape[1]||0)/8)*8,M2),a=Math.round(s*A/8)*8;n.resize=r.image.resizeBilinear(e,[s,a]),n.cast=r.cast(n.resize,"int32"),[n.rawScores,n.rawBoxes]=await t0[0].executeAsync(n.cast,b2),n.boxes=r.squeeze(n.rawBoxes,[0,2]),n.scores=r.squeeze(n.rawScores,[0]);let i=r.unstack(n.scores,1);r.dispose(i[MA]),i.splice(MA,1),n.filtered=r.stack(i,1),r.dispose(i),n.max=r.max(n.filtered,1),n.argmax=r.argMax(n.filtered,1);let x=0;n.nms=await r.image.nonMaxSuppressionAsync(n.boxes,n.max,(t.hand.maxDetected||0)+1,t.hand.iouThreshold||0,t.hand.minConfidence||1);let d=await n.nms.data(),l=await n.max.data(),y=await n.argmax.data();for(let c of Array.from(d)){let f=r.slice(n.boxes,c,1),h=await f.data();r.dispose(f);let m=[h[1],h[0],h[3]-h[1],h[2]-h[0]],v=xt(m,P2),M=[Math.trunc(m[0]*H0[0]),Math.trunc(m[1]*H0[1]),Math.trunc(m[2]*H0[0]),Math.trunc(m[3]*H0[1])],u=l[c],p=g2[y[c]],P={id:x++,score:u,box:M,boxRaw:v,label:p};o.push(P)}return Object.keys(n).forEach(c=>r.dispose(n[c])),o.sort((c,f)=>f.score-c.score),o.length>(t.hand.maxDetected||1)&&(o.length=t.hand.maxDetected||1),o}async function F5(e,t,o){let n={id:t.id,score:Math.round(100*t.score)/100,boxScore:Math.round(100*t.score)/100,fingerScore:0,box:t.box,boxRaw:t.boxRaw,label:t.label,keypoints:[],landmarks:{},annotations:{}};if(e&&t0[1]&&o.hand.landmarks&&t.score>(o.hand.minConfidence||0)){let A={},s=[t.boxRaw[1],t.boxRaw[0],t.boxRaw[3]+t.boxRaw[1],t.boxRaw[2]+t.boxRaw[0]];A.crop=r.image.cropAndResize(e,[s],[0],[_0[1][0],_0[1][1]],"bilinear"),A.div=r.div(A.crop,N.tf255),[A.score,A.keypoints]=t0[1].execute(A.div,["Identity_1","Identity"]);let a=(await A.score.data())[0],i=(100-Math.trunc(100/(1+Math.exp(a))))/100;if(i>=(o.hand.minConfidence||0)){n.fingerScore=i,A.reshaped=r.reshape(A.keypoints,[-1,3]);let l=(await A.reshaped.array()).map(y=>[y[0]/_0[1][1],y[1]/_0[1][0],y[2]||0]).map(y=>[y[0]*t.boxRaw[2],y[1]*t.boxRaw[3],y[2]||0]);n.keypoints=l.map(y=>[H0[0]*(y[0]+t.boxRaw[0]),H0[1]*(y[1]+t.boxRaw[1]),y[2]||0]),n.landmarks=vt(n.keypoints);for(let y of Object.keys(vA))n.annotations[y]=vA[y].map(c=>n.landmarks&&n.keypoints[c]?n.keypoints[c]:null)}Object.keys(A).forEach(x=>r.dispose(A[x]))}return n}async function H5(e,t){var A,s;if(!t0[0]||!t0[1]||!((A=t0[0])!=null&&A.inputs[0].shape)||!((s=t0[1])!=null&&s.inputs[0].shape))return[];H0=[e.shape[2]||0,e.shape[1]||0],Tt++;let o=(t.hand.skipTime||0)>g()-B5,n=Tt<(t.hand.skipFrames||0);return t.skipAllowed&&o&&n?K.hands:new Promise(async a=>{let i=3*(t.hand.skipTime||0)>g()-B5,x=Tt<3*(t.hand.skipFrames||0);t.skipAllowed&&K.hands.length===t.hand.maxDetected?K.hands=await Promise.all(K.boxes.map(l=>F5(e,l,t))):t.skipAllowed&&i&&x&&K.hands.length>0?K.hands=await Promise.all(K.boxes.map(l=>F5(e,l,t))):(K.boxes=await v2(e,t),B5=g(),K.hands=await Promise.all(K.boxes.map(l=>F5(e,l,t))),Tt=0);let d=[...K.boxes];if(K.boxes.length=0,t.cacheSensitivity>0)for(let l=0;l.05&&y.box[3]/(e.shape[1]||1)>.05&&K.hands[l].fingerScore&&K.hands[l].fingerScore>(t.hand.minConfidence||0)){let c=xt(y.box,PA),f=xt(y.boxRaw,PA);K.boxes.push({...d[l],box:c,boxRaw:f})}}for(let l=0;lg()-EA,s=V5<(((i=t.face.liveness)==null?void 0:i.skipFrames)||0);return t.skipAllowed&&A&&s&&kA===n&&Rt[o]?(V5++,Rt[o]):(V5=0,new Promise(async x=>{let d=r.image.resizeBilinear(e,[s0!=null&&s0.inputs[0].shape?s0.inputs[0].shape[2]:0,s0!=null&&s0.inputs[0].shape?s0.inputs[0].shape[1]:0],!1),l=s0==null?void 0:s0.execute(d),y=(await l.data())[0];Rt[o]=Math.round(100*y)/100,kA=n,EA=g(),r.dispose([d,l]),x(Rt[o])}))}var qe={};$0(qe,{connected:()=>Et,horizontal:()=>X5,kpt:()=>kt,relative:()=>q5,vertical:()=>D5});var kt=["nose","leftEye","rightEye","leftEar","rightEar","leftShoulder","rightShoulder","leftElbow","rightElbow","leftWrist","rightWrist","leftHip","rightHip","leftKnee","rightKnee","leftAnkle","rightAnkle"],X5=[["leftEye","rightEye"],["leftEar","rightEar"],["leftShoulder","rightShoulder"],["leftElbow","rightElbow"],["leftWrist","rightWrist"],["leftHip","rightHip"],["leftKnee","rightKnee"],["leftAnkle","rightAnkle"]],D5=[["leftKnee","leftShoulder"],["rightKnee","rightShoulder"],["leftAnkle","leftKnee"],["rightAnkle","rightKnee"]],q5=[[["leftHip","rightHip"],["leftShoulder","rightShoulder"]],[["leftElbow","rightElbow"],["leftShoulder","rightShoulder"]]],Et={leftLeg:["leftHip","leftKnee","leftAnkle"],rightLeg:["rightHip","rightKnee","rightAnkle"],torso:["leftShoulder","rightShoulder","rightHip","leftHip","leftShoulder"],leftArm:["leftShoulder","leftElbow","leftWrist"],rightArm:["rightShoulder","rightElbow","rightWrist"],head:[]};var SA=.005,f0={keypoints:[],padding:[[0,0],[0,0],[0,0],[0,0]]};function U5(e){for(let t of X5){let o=e.keypoints.findIndex(A=>A.part===t[0]),n=e.keypoints.findIndex(A=>A.part===t[1]);if(e.keypoints[o]&&e.keypoints[n]&&e.keypoints[o].position[0]A&&A.part===t[0]),n=e.keypoints.findIndex(A=>A&&A.part===t[1]);e.keypoints[o]&&e.keypoints[n]&&e.keypoints[o].position[1]d&&d.part===t[0]),A=e.keypoints.findIndex(d=>d&&d.part===t[1]),s=e.keypoints.findIndex(d=>d&&d.part===o[0]),a=e.keypoints.findIndex(d=>d&&d.part===o[1]);if(!e.keypoints[s]||!e.keypoints[a])continue;let i=e.keypoints[n]?[Math.abs(e.keypoints[s].position[0]-e.keypoints[n].position[0]),Math.abs(e.keypoints[a].position[0]-e.keypoints[n].position[0])]:[0,0],x=e.keypoints[A]?[Math.abs(e.keypoints[a].position[0]-e.keypoints[A].position[0]),Math.abs(e.keypoints[s].position[0]-e.keypoints[A].position[0])]:[0,0];if(i[0]>i[1]||x[0]>x[1]){let d=e.keypoints[n];e.keypoints[n]=e.keypoints[A],e.keypoints[A]=d}}}function CA(e){for(let t=0;te.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0,e.shape[2]>e.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0],[e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0,e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0],[0,0]],o.pad=r.pad(e,f0.padding),o.resize=r.image.resizeBilinear(o.pad,[t,t]);let n=r.cast(o.resize,"int32");return Object.keys(o).forEach(A=>r.dispose(o[A])),n}function OA(e,t){e.keypoints=e.keypoints.filter(n=>n&&n.position);for(let n of e.keypoints)n.position=[n.position[0]*(t[0]+f0.padding[2][0]+f0.padding[2][1])/t[0]-f0.padding[2][0],n.position[1]*(t[1]+f0.padding[1][0]+f0.padding[1][1])/t[1]-f0.padding[1][0]],n.positionRaw=[n.position[0]/t[0],n.position[1]/t[1]];let o=L0(e.keypoints.map(n=>n.position),t);return e.box=o.box,e.boxRaw=o.boxRaw,e}var m0,zt=0,J5=Number.MAX_SAFE_INTEGER,ae={boxes:[],bodies:[],last:0};async function IA(e){return w.initial&&(m0=null),m0?e.debug&&b("cached model:",m0.modelUrl):(wt(["size"],e),m0=await L(e.body.modelPath)),zt=m0.inputs[0].shape?m0.inputs[0].shape[2]:0,zt<64&&(zt=256),m0}async function w2(e,t,o){let n=e[0][0],A=[],s=0;for(let l=0;lt.body.minConfidence){let y=[n[l][1],n[l][0]];A.push({score:Math.round(100*s)/100,part:kt[l],positionRaw:y,position:[Math.round((o.shape[2]||0)*y[0]),Math.round((o.shape[1]||0)*y[1])]})}s=A.reduce((l,y)=>y.score>l?y.score:l,0);let a=[],i=L0(A.map(l=>l.position),[o.shape[2],o.shape[1]]),x={};for(let[l,y]of Object.entries(Et)){let c=[];for(let f=0;fv.part===y[f]),m=A.find(v=>v.part===y[f+1]);h&&m&&h.score>(t.body.minConfidence||0)&&m.score>(t.body.minConfidence||0)&&c.push([h.position,m.position])}x[l]=c}let d={id:0,score:s,box:i.box,boxRaw:i.boxRaw,keypoints:A,annotations:x};return U5(d),a.push(d),a}async function R2(e,t,o){let n=[];for(let A=0;At.body.minConfidence){let i=[];for(let y=0;y<17;y++){let c=s[3*y+2];if(c>t.body.minConfidence){let f=[s[3*y+1],s[3*y+0]];i.push({part:kt[y],score:Math.round(100*c)/100,positionRaw:f,position:[Math.round((o.shape[2]||0)*f[0]),Math.round((o.shape[1]||0)*f[1])]})}}let x=L0(i.map(y=>y.position),[o.shape[2],o.shape[1]]),d={};for(let[y,c]of Object.entries(Et)){let f=[];for(let h=0;hM.part===c[h]),v=i.find(M=>M.part===c[h+1]);m&&v&&m.score>(t.body.minConfidence||0)&&v.score>(t.body.minConfidence||0)&&f.push([m.position,v.position])}d[y]=f}let l={id:A,score:a,box:x.box,boxRaw:x.boxRaw,keypoints:[...i],annotations:d};U5(l),n.push(l)}}return n.sort((A,s)=>s.score-A.score),n.length>t.body.maxDetected&&(n.length=t.body.maxDetected),n}async function Y5(e,t){if(!m0||!(m0!=null&&m0.inputs[0].shape))return[];t.skipAllowed||(ae.boxes.length=0),J5++;let o=(t.body.skipTime||0)>g()-ae.last,n=J5<(t.body.skipFrames||0);return t.skipAllowed&&o&&n?ae.bodies:new Promise(async A=>{let s={};J5=0,s.input=WA(e,zt),s.res=m0==null?void 0:m0.execute(s.input),ae.last=g();let a=await s.res.array();ae.bodies=s.res.shape[2]===17?await w2(a,t,e):await R2(a,t,e);for(let i of ae.bodies)OA(i,[e.shape[2]||1,e.shape[1]||1]),CA(i.keypoints);Object.keys(s).forEach(i=>r.dispose(s[i])),A(ae.bodies)})}var we,jt=[],NA=0,K5=Number.MAX_SAFE_INTEGER,Ct=0,St=2.5;async function GA(e){if(!we||w.initial){we=await L(e.object.modelPath);let t=Object.values(we.modelSignature.inputs);Ct=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}else e.debug&&b("cached model:",we.modelUrl);return we}async function k2(e,t,o){let n=0,A=[];for(let x of[1,2,4])r.tidy(async()=>{let d=x*13,l=r.squeeze(e.find(m=>m.shape[1]===d**2&&(m.shape[2]||0)===pe.length)),y=r.squeeze(e.find(m=>m.shape[1]===d**2&&(m.shape[2]||0)(o.object.minConfidence||0)&&v!==61){let u=(.5+Math.trunc(m%d))/d,p=(.5+Math.trunc(m/d))/d,P=f[m].map(B=>B*(d/x/Ct)),[R,S]=[u-St/x*P[0],p-St/x*P[1]],[O,C]=[u+St/x*P[2]-R,p+St/x*P[3]-S],I=[R,S,O,C];I=I.map(B=>Math.max(0,Math.min(B,1)));let V=[I[0]*t[0],I[1]*t[1],I[2]*t[0],I[3]*t[1]],G={id:n++,score:Math.round(100*M)/100,class:v+1,label:pe[v].label,box:V.map(B=>Math.trunc(B)),boxRaw:I};A.push(G)}}});e.forEach(x=>r.dispose(x));let s=A.map(x=>[x.boxRaw[1],x.boxRaw[0],x.boxRaw[3],x.boxRaw[2]]),a=A.map(x=>x.score),i=[];if(s&&s.length>0){let x=await r.image.nonMaxSuppressionAsync(s,a,o.object.maxDetected,o.object.iouThreshold,o.object.minConfidence);i=await x.data(),r.dispose(x)}return A=A.filter((x,d)=>i.includes(d)).sort((x,d)=>d.score-x.score),A}async function Q5(e,t){let o=(t.object.skipTime||0)>g()-NA,n=K5<(t.object.skipFrames||0);return t.skipAllowed&&o&&n&&jt.length>0?(K5++,jt):(K5=0,!w.kernels.includes("mod")||!w.kernels.includes("sparsetodense")?jt:new Promise(async A=>{let s=[e.shape[2]||0,e.shape[1]||0],a=r.image.resizeBilinear(e,[Ct,Ct],!1),i=r.div(a,N.tf255),x=i.transpose([0,3,1,2]);r.dispose(i),r.dispose(a);let d;t.object.enabled&&(d=we.execute(x)),NA=g(),r.dispose(x);let l=await k2(d,s,t);jt=l,A(l)}))}var Je=["nose","leftEye","rightEye","leftEar","rightEar","leftShoulder","rightShoulder","leftElbow","rightElbow","leftWrist","rightWrist","leftHip","rightHip","leftKnee","rightKnee","leftAnkle","rightAnkle"],E2=Je.length,Ue=Je.reduce((e,t,o)=>(e[t]=o,e),{}),z2=[["leftHip","leftShoulder"],["leftElbow","leftShoulder"],["leftElbow","leftWrist"],["leftHip","leftKnee"],["leftKnee","leftAnkle"],["rightHip","rightShoulder"],["rightElbow","rightShoulder"],["rightElbow","rightWrist"],["rightHip","rightKnee"],["rightKnee","rightAnkle"],["leftShoulder","rightShoulder"],["leftHip","rightHip"]],Da=z2.map(([e,t])=>[Ue[e],Ue[t]]),FA=[["nose","leftEye"],["leftEye","leftEar"],["nose","rightEye"],["rightEye","rightEar"],["nose","leftShoulder"],["leftShoulder","leftElbow"],["leftElbow","leftWrist"],["leftShoulder","leftHip"],["leftHip","leftKnee"],["leftKnee","leftAnkle"],["nose","rightShoulder"],["rightShoulder","rightElbow"],["rightElbow","rightWrist"],["rightShoulder","rightHip"],["rightHip","rightKnee"],["rightKnee","rightAnkle"]];function HA(e){let t=e.reduce(({maxX:o,maxY:n,minX:A,minY:s},{position:{x:a,y:i}})=>({maxX:Math.max(o,a),maxY:Math.max(n,i),minX:Math.min(A,a),minY:Math.min(s,i)}),{maxX:Number.NEGATIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY,minX:Number.POSITIVE_INFINITY,minY:Number.POSITIVE_INFINITY});return[t.minX,t.minY,t.maxX-t.minX,t.maxY-t.minY]}function VA(e,[t,o],[n,A]){let s=t/n,a=o/A,i=(d,l)=>({id:l,score:d.score,boxRaw:[d.box[0]/A,d.box[1]/n,d.box[2]/A,d.box[3]/n],box:[Math.trunc(d.box[0]*a),Math.trunc(d.box[1]*s),Math.trunc(d.box[2]*a),Math.trunc(d.box[3]*s)],keypoints:d.keypoints.map(({score:y,part:c,position:f})=>({score:y,part:c,position:[Math.trunc(f.x*a),Math.trunc(f.y*s)],positionRaw:[f.x/n,f.y/n]})),annotations:{}});return e.map((d,l)=>i(d,l))}var Wt=class{constructor(t,o){k(this,"priorityQueue");k(this,"numberOfElements");k(this,"getElementValue");this.priorityQueue=new Array(t),this.numberOfElements=-1,this.getElementValue=o}enqueue(t){this.priorityQueue[++this.numberOfElements]=t,this.swim(this.numberOfElements)}dequeue(){let t=this.priorityQueue[0];return this.exchange(0,this.numberOfElements--),this.sink(0),this.priorityQueue[this.numberOfElements+1]=null,t}empty(){return this.numberOfElements===-1}size(){return this.numberOfElements+1}all(){return this.priorityQueue.slice(0,this.numberOfElements+1)}max(){return this.priorityQueue[0]}swim(t){for(;t>0&&this.less(Math.floor(t/2),t);)this.exchange(t,Math.floor(t/2)),t=Math.floor(t/2)}sink(t){for(;2*t<=this.numberOfElements;){let o=2*t;if(oo?o:e}function ZA(e,t,o,n){let A=o-e,s=n-t;return A*A+s*s}function to(e,t){return{x:e.x+t.x,y:e.y+t.y}}var w0,S2=["MobilenetV1/offset_2/BiasAdd","MobilenetV1/heatmap_2/BiasAdd","MobilenetV1/displacement_fwd_2/BiasAdd","MobilenetV1/displacement_bwd_2/BiasAdd"],Ot=1,Re=16,C2=50**2;function XA(e,t,o,n,A,s,a=2){let i=M=>({y:s.get(M.y,M.x,e),x:s.get(M.y,M.x,s.shape[2]/2+e)}),x=(M,u,p)=>({y:eo(Math.round(M.y/Re),0,u-1),x:eo(Math.round(M.x/Re),0,p-1)}),[d,l]=n.shape,y=x(t.position,d,l),c=i(y),h=to(t.position,c);for(let M=0;M[Ue[c],Ue[f]]),a=s.map(([,c])=>c),i=s.map(([c])=>c),x=t.shape[2],d=a.length,l=new Array(x),y=$5(e.part,Re,o);l[e.part.id]={score:e.score,part:Je[e.part.id],position:y};for(let c=d-1;c>=0;--c){let f=a[c],h=i[c];l[f]&&!l[h]&&(l[h]=XA(c,l[f],h,t,o,A))}for(let c=0;ct){i=!1;break}if(!i)break}return i}function I2(e,t){let[o,n,A]=t.shape,s=new Wt(o*n*A,({score:a})=>a);for(let a=0;a{var a;let s=(a=A[n])==null?void 0:a.position;return s?ZA(o,t,s.y,s.x)<=C2:!1})}function L2(e,t){return t.reduce((n,{position:A,score:s},a)=>(DA(e,A,a)||(n+=s),n),0)/t.length}function N2(e,t,o,n,A,s){let a=[],i=I2(s,t);for(;a.lengthf.score>s);let y=L2(a,l),c=HA(l);y>s&&a.push({keypoints:l,box:c,score:Math.round(100*y)/100})}return a}async function oo(e,t){let o=r.tidy(()=>{if(!w0.inputs[0].shape)return[];let a=r.image.resizeBilinear(e,[w0.inputs[0].shape[2],w0.inputs[0].shape[1]]),i=r.sub(r.div(r.cast(a,"float32"),127.5),1),d=w0.execute(i,S2).map(l=>r.squeeze(l,[0]));return d[1]=r.sigmoid(d[1]),d}),n=await Promise.all(o.map(a=>a.buffer()));for(let a of o)r.dispose(a);let A=await N2(n[0],n[1],n[2],n[3],t.body.maxDetected,t.body.minConfidence);return w0.inputs[0].shape?VA(A,[e.shape[1],e.shape[2]],[w0.inputs[0].shape[2],w0.inputs[0].shape[1]]):[]}async function qA(e){return!w0||w.initial?w0=await L(e.body.modelPath):e.debug&&b("cached model:",w0.modelUrl),w0}var z0,no=!1;async function Ao(e){return!z0||w.initial?z0=await L(e.segmentation.modelPath):e.debug&&b("cached model:",z0.modelUrl),z0}async function JA(e,t,o){var m,v;if(no)return{data:[],canvas:null,alpha:null};no=!0,z0||await Ao(o);let n=await de(e,o),A=((m=n.tensor)==null?void 0:m.shape[2])||0,s=((v=n.tensor)==null?void 0:v.shape[1])||0;if(!n.tensor)return{data:[],canvas:null,alpha:null};let a={};a.resize=r.image.resizeBilinear(n.tensor,[z0.inputs[0].shape?z0.inputs[0].shape[1]:0,z0.inputs[0].shape?z0.inputs[0].shape[2]:0],!1),r.dispose(n.tensor),a.norm=r.div(a.resize,N.tf255),a.res=z0.execute(a.norm),a.squeeze=r.squeeze(a.res,0),a.squeeze.shape[2]===2?(a.softmax=r.softmax(a.squeeze),[a.bg,a.fg]=r.unstack(a.softmax,2),a.expand=r.expandDims(a.fg,2),a.pad=r.expandDims(a.expand,0),a.crop=r.image.cropAndResize(a.pad,[[0,0,.5,.5]],[0],[A,s]),a.data=r.squeeze(a.crop,0)):a.data=r.image.resizeBilinear(a.squeeze,[s,A]);let i=Array.from(await a.data.data());if(w.node&&!w.Canvas&&typeof ImageData=="undefined")return o.debug&&b("canvas support missing"),Object.keys(a).forEach(M=>r.dispose(a[M])),{data:i,canvas:null,alpha:null};let x=a0(A,s);r.browser&&await r.browser.toPixels(a.data,x);let d=x.getContext("2d");o.segmentation.blur&&o.segmentation.blur>0&&(d.filter=`blur(${o.segmentation.blur}px)`);let l=d.getImageData(0,0,A,s),y=a0(A,s),c=y.getContext("2d");n.canvas&&c.drawImage(n.canvas,0,0),c.globalCompositeOperation="darken",o.segmentation.blur&&o.segmentation.blur>0&&(c.filter=`blur(${o.segmentation.blur}px)`),c.drawImage(x,0,0),c.globalCompositeOperation="source-over",c.filter="none";let f=c.getImageData(0,0,A,s);for(let M=0;Mr.dispose(a[M])),no=!1,{data:i,canvas:y,alpha:x}}var Ye=class{constructor(){k(this,"ssrnetage",null);k(this,"gear",null);k(this,"blazeposedetect",null);k(this,"blazepose",null);k(this,"centernet",null);k(this,"efficientpose",null);k(this,"mobilefacenet",null);k(this,"emotion",null);k(this,"facedetect",null);k(this,"faceiris",null);k(this,"facemesh",null);k(this,"faceres",null);k(this,"ssrnetgender",null);k(this,"handpose",null);k(this,"handskeleton",null);k(this,"handtrack",null);k(this,"liveness",null);k(this,"movenet",null);k(this,"nanodet",null);k(this,"posenet",null);k(this,"segmentation",null);k(this,"antispoof",null)}};function It(e){for(let t of Object.keys(e.models))e.models[t]=null}async function ro(e){var t,o,n,A,s,a,i,x,d,l,y,c,f,h,m,v,M,u,p,P,R,S,O,C,I,V,G,B,J,z;w.initial&&It(e),e.config.hand.enabled&&(!e.models.handpose&&((o=(t=e.config.hand.detector)==null?void 0:t.modelPath)==null?void 0:o.includes("handdetect"))&&([e.models.handpose,e.models.handskeleton]=await G5(e.config)),!e.models.handskeleton&&e.config.hand.landmarks&&((A=(n=e.config.hand.detector)==null?void 0:n.modelPath)==null?void 0:A.includes("handdetect"))&&([e.models.handpose,e.models.handskeleton]=await G5(e.config))),e.config.body.enabled&&!e.models.blazepose&&((a=(s=e.config.body)==null?void 0:s.modelPath)==null?void 0:a.includes("blazepose"))&&(e.models.blazepose=Pn(e.config)),e.config.body.enabled&&!e.models.blazeposedetect&&e.config.body.detector&&e.config.body.detector.modelPath&&(e.models.blazeposedetect=Mn(e.config)),e.config.body.enabled&&!e.models.efficientpose&&((x=(i=e.config.body)==null?void 0:i.modelPath)==null?void 0:x.includes("efficientpose"))&&(e.models.efficientpose=En(e.config)),e.config.body.enabled&&!e.models.movenet&&((l=(d=e.config.body)==null?void 0:d.modelPath)==null?void 0:l.includes("movenet"))&&(e.models.movenet=IA(e.config)),e.config.body.enabled&&!e.models.posenet&&((c=(y=e.config.body)==null?void 0:y.modelPath)==null?void 0:c.includes("posenet"))&&(e.models.posenet=qA(e.config)),e.config.face.enabled&&!e.models.facedetect&&(e.models.facedetect=cn(e.config)),e.config.face.enabled&&((f=e.config.face.antispoof)==null?void 0:f.enabled)&&!e.models.antispoof&&(e.models.antispoof=_o(e.config)),e.config.face.enabled&&((h=e.config.face.liveness)==null?void 0:h.enabled)&&!e.models.liveness&&(e.models.liveness=zA(e.config)),e.config.face.enabled&&((m=e.config.face.description)==null?void 0:m.enabled)&&!e.models.faceres&&(e.models.faceres=_n(e.config)),e.config.face.enabled&&((v=e.config.face.emotion)==null?void 0:v.enabled)&&!e.models.emotion&&(e.models.emotion=Cn(e.config)),e.config.face.enabled&&((M=e.config.face.iris)==null?void 0:M.enabled)&&!e.models.faceiris&&(e.models.faceiris=Vn(e.config)),e.config.face.enabled&&((u=e.config.face.mesh)==null?void 0:u.enabled)&&!e.models.facemesh&&(e.models.facemesh=Un(e.config)),e.config.face.enabled&&((p=e.config.face.gear)==null?void 0:p.enabled)&&!e.models.gear&&(e.models.gear=Bo(e.config)),e.config.face.enabled&&((P=e.config.face.ssrnet)==null?void 0:P.enabled)&&!e.models.ssrnetage&&(e.models.ssrnetage=Xo(e.config)),e.config.face.enabled&&((R=e.config.face.ssrnet)==null?void 0:R.enabled)&&!e.models.ssrnetgender&&(e.models.ssrnetgender=Jo(e.config)),e.config.face.enabled&&((S=e.config.face.mobilefacenet)==null?void 0:S.enabled)&&!e.models.mobilefacenet&&(e.models.mobilefacenet=Nn(e.config)),e.config.hand.enabled&&!e.models.handtrack&&((C=(O=e.config.hand.detector)==null?void 0:O.modelPath)==null?void 0:C.includes("handtrack"))&&(e.models.handtrack=TA(e.config)),e.config.hand.enabled&&e.config.hand.landmarks&&!e.models.handskeleton&&((V=(I=e.config.hand.detector)==null?void 0:I.modelPath)==null?void 0:V.includes("handtrack"))&&(e.models.handskeleton=wA(e.config)),e.config.object.enabled&&!e.models.centernet&&((B=(G=e.config.object)==null?void 0:G.modelPath)==null?void 0:B.includes("centernet"))&&(e.models.centernet=wn(e.config)),e.config.object.enabled&&!e.models.nanodet&&((z=(J=e.config.object)==null?void 0:J.modelPath)==null?void 0:z.includes("nanodet"))&&(e.models.nanodet=GA(e.config)),e.config.segmentation.enabled&&!e.models.segmentation&&(e.models.segmentation=Ao(e.config));for await(let p0 of Object.keys(e.models))e.models[p0]&&typeof e.models[p0]!="undefined"&&(e.models[p0]=await e.models[p0])}async function so(e){let t=["const","placeholder","noop","pad","squeeze","add","sub","mul","div"];for(let o of Object.keys(e.models)){let n=e.models[o];if(!n)continue;let A=[],s=n==null?void 0:n.executor;if(s&&s.graph.nodes)for(let i of Object.values(s.graph.nodes)){let x=i.op.toLowerCase();A.includes(x)||A.push(x)}else!s&&e.config.debug&&b("model signature not determined:",o);let a=[];for(let i of A)!t.includes(i)&&!e.env.kernels.includes(i)&&!e.env.kernels.includes(i.replace("_",""))&&!e.env.kernels.includes(i.replace("native",""))&&!e.env.kernels.includes(i.replace("v2",""))&&a.push(i);e.config.debug&&a.length>0&&b("model validation failed:",o,a)}}var q={name:"humangl",priority:999,canvas:null,gl:null,extensions:[],webGLattr:{alpha:!1,antialias:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,depth:!1,stencil:!1,failIfMajorPerformanceCaveat:!1,desynchronized:!0}};function G2(){let e=q.gl;!e||(q.extensions=e.getSupportedExtensions())}async function KA(e){var t;if(e.config.backend==="humangl"&&(q.name in r.engine().registry&&(!q.gl||!q.gl.getParameter(q.gl.VERSION))&&(b("error: humangl backend invalid context"),It(e)),!r.findBackend(q.name))){try{q.canvas=await a0(100,100)}catch(n){b("error: cannot create canvas:",n);return}try{if(q.gl=(t=q.canvas)==null?void 0:t.getContext("webgl2",q.webGLattr),!q.gl.getParameter(q.gl.VERSION).includes("2.0")){b("override: using fallback webgl backend as webgl 2.0 is not detected"),e.config.backend="webgl";return}q.canvas&&(q.canvas.addEventListener("webglcontextlost",async A=>{throw b("error: humangl:",A.type),b("possible browser memory leak using webgl or conflict with multiple backend registrations"),e.emit("error"),new Error("backend error: webgl context lost")}),q.canvas.addEventListener("webglcontextrestored",A=>{b("error: humangl context restored:",A)}),q.canvas.addEventListener("webglcontextcreationerror",A=>{b("error: humangl context create:",A)}))}catch(n){b("error: cannot get WebGL context:",n);return}try{r.setWebGLContext(2,q.gl)}catch(n){b("error: cannot set WebGL context:",n);return}try{let n=new r.GPGPUContext(q.gl);r.registerBackend(q.name,()=>new r.MathBackendWebGL(n),q.priority)}catch(n){b("error: cannot register WebGL backend:",n);return}try{r.getKernelsForBackend("webgl").forEach(A=>{let s={...A,backendName:q.name};r.registerKernel(s)})}catch(n){b("error: cannot update WebGL backend registration:",n);return}let o=r.backend().getGPGPUContext?r.backend().getGPGPUContext().gl:null;if(o)b(`humangl webgl version:${o.getParameter(o.VERSION)} renderer:${o.getParameter(o.RENDERER)}`);else{b("error: no current gl context:",o,q.gl);return}try{r.ENV.set("WEBGL_VERSION",2)}catch(n){b("error: cannot set WebGL backend flags:",n);return}G2(),b("backend registered:",q.name)}}function B2(){if(!w.kernels.includes("mod")){let e={kernelName:"Mod",backendName:r.getBackend(),kernelFunc:t=>r.tidy(()=>r.sub(t.inputs.a,r.mul(r.div(t.inputs.a,t.inputs.b),t.inputs.b)))};r.registerKernel(e),w.kernels.push("mod")}if(!w.kernels.includes("floormod")){let e={kernelName:"FloorMod",backendName:r.getBackend(),kernelFunc:t=>r.tidy(()=>r.floorDiv(t.inputs.a/t.inputs.b)*t.inputs.b+r.mod(t.inputs.a,t.inputs.b))};r.registerKernel(e),w.kernels.push("floormod")}}async function Lt(e,t=!1){if(e.state="backend",t||w.initial||e.config.backend&&e.config.backend.length>0&&r.getBackend()!==e.config.backend){let o=g();if(e.config.backend&&e.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&e.config.debug&&e.config.debug&&b("running inside web worker"),w.browser&&e.config.backend==="tensorflow"&&(e.config.debug&&b("override: backend set to tensorflow while running in browser"),e.config.backend="humangl"),w.node&&(e.config.backend==="webgl"||e.config.backend==="humangl")&&(e.config.debug&&b(`override: backend set to ${e.config.backend} while running in nodejs`),e.config.backend="tensorflow"),w.browser&&e.config.backend==="webgpu")if(typeof navigator=="undefined"||typeof navigator.gpu=="undefined")b("override: backend set to webgpu but browser does not support webgpu"),e.config.backend="humangl";else{let A=await navigator.gpu.requestAdapter();e.config.debug&&b("enumerated webgpu adapter:",A)}e.config.backend==="humangl"&&await KA(e);let n=Object.keys(r.engine().registryFactory);if(e.config.debug&&b("available backends:",n),n.includes(e.config.backend)||(b(`error: backend ${e.config.backend} not found in registry`),e.config.backend=w.node?"tensorflow":"webgl",e.config.debug&&b(`override: setting backend ${e.config.backend}`)),e.config.debug&&b("setting backend:",e.config.backend),e.config.backend==="wasm"){if(e.config.debug&&b("wasm path:",e.config.wasmPath),typeof(r==null?void 0:r.setWasmPaths)!="undefined")await r.setWasmPaths(e.config.wasmPath,e.config.wasmPlatformFetch);else throw new Error("backend error: attempting to use wasm backend but wasm path is not set");let A=await r.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await r.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");e.config.debug&&b(`wasm execution: ${A?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),e.config.debug&&!A&&b("warning: wasm simd support is not enabled")}try{await r.setBackend(e.config.backend),await r.ready(),Ho()}catch(A){return b("error: cannot set backend:",e.config.backend,A),!1}}if(r.getBackend()==="humangl"&&(r.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),r.ENV.set("WEBGL_CPU_FORWARD",!0),r.ENV.set("WEBGL_USE_SHAPES_UNIFORMS",!0),r.ENV.set("CPU_HANDOFF_SIZE_THRESHOLD",256),typeof e.config.deallocate!="undefined"&&e.config.deallocate&&(b("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),r.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0)),r.backend().getGPGPUContext)){let n=await r.backend().getGPGPUContext().gl;e.config.debug&&b(`gl version:${n.getParameter(n.VERSION)} renderer:${n.getParameter(n.RENDERER)}`)}r.getBackend(),r.enableProdMode(),await r.ready(),e.performance.initBackend=Math.trunc(g()-o),e.config.backend=r.getBackend(),await w.updateBackend(),B2()}return!0}function wt(e,t){for(let o of e){let n={kernelName:o,backendName:t.backend,kernelFunc:()=>{t.debug&&b("kernelFunc",o,t.backend)}};r.registerKernel(n)}w.kernels=r.getKernelsForBackend(r.getBackend()).map(o=>o.kernelName.toLowerCase())}var $A={};$0($A,{all:()=>fo,body:()=>Ee,canvas:()=>co,face:()=>ke,gesture:()=>Se,hand:()=>ze,object:()=>je,options:()=>n0,person:()=>xo});var n0={color:"rgba(173, 216, 230, 0.6)",labelColor:"rgba(173, 216, 230, 1)",shadowColor:"black",alpha:.5,font:'small-caps 16px "Segoe UI"',lineHeight:18,lineWidth:4,pointSize:2,roundRect:8,drawPoints:!1,drawLabels:!0,drawBoxes:!0,drawAttention:!0,drawGestures:!0,drawPolygons:!0,drawGaze:!0,fillPolygons:!1,useDepth:!0,useCurves:!1};var h0=e=>{if(!e)b("draw error: invalid canvas");else if(!e.getContext)b("draw error: canvas context not defined");else{let t=e.getContext("2d");if(!t)b("draw error: cannot get canvas context");else return t}return null},ie=e=>Math.round(e*180/Math.PI),j0=(e,t=[!0,!0,!1])=>{let o=t[0]?127+Math.trunc(3*e):255,n=t[1]?127-Math.trunc(3*e):255,A=t[2]?127-Math.trunc(3*e):255;return`rgba(${o}, ${n}, ${A}, ${n0.alpha})`};function le(e,t,o,n,A){n=n||0,e.fillStyle=A.useDepth&&n?j0(n,n===-255?[!0,!1,!0]:[!0,!1,!1]):A.color,e.beginPath(),e.arc(t,o,A.pointSize,0,2*Math.PI),e.fill()}function S0(e,t,o,n,A,s){if(e.beginPath(),e.lineWidth=s.lineWidth,s.useCurves){let a=(t+t+n)/2,i=(o+o+A)/2;e.ellipse(a,i,n/2,A/2,0,0,2*Math.PI)}else e.moveTo(t+s.roundRect,o),e.lineTo(t+n-s.roundRect,o),e.quadraticCurveTo(t+n,o,t+n,o+s.roundRect),e.lineTo(t+n,o+A-s.roundRect),e.quadraticCurveTo(t+n,o+A,t+n-s.roundRect,o+A),e.lineTo(t+s.roundRect,o+A),e.quadraticCurveTo(t,o+A,t,o+A-s.roundRect),e.lineTo(t,o+s.roundRect),e.quadraticCurveTo(t,o,t+s.roundRect,o),e.closePath();e.stroke()}function io(e,t,o){if(!(t.length<2)){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n of t){let A=n[2]||0;e.strokeStyle=o.useDepth&&A!==0?j0(A):o.color,e.fillStyle=o.useDepth&&A!==0?j0(A):o.color,e.lineTo(n[0],Math.round(n[1]))}e.stroke(),o.fillPolygons&&(e.closePath(),e.fill())}}function _A(e,t,o){if(!(t.length<2)){if(e.lineWidth=o.lineWidth,!o.useCurves||t.length<=2){io(e,t,o);return}e.moveTo(t[0][0],t[0][1]);for(let n=0;n0){let c=l.emotion.map(f=>`${Math.trunc(100*f.score)}% ${f.emotion}`);c.length>3&&(c.length=3),y.push(c.join(" "))}l.rotation&&l.rotation.angle&&l.rotation.gaze&&(l.rotation.angle.roll&&y.push(`roll: ${ie(l.rotation.angle.roll)}\xB0 yaw:${ie(l.rotation.angle.yaw)}\xB0 pitch:${ie(l.rotation.angle.pitch)}\xB0`),l.rotation.gaze.bearing&&y.push(`gaze: ${ie(l.rotation.gaze.bearing)}\xB0`)),y.length===0&&y.push("face"),A.fillStyle=n.color;for(let c=y.length-1;c>=0;c--){let f=Math.max(l.box[0],0),h=c*n.lineHeight+l.box[1];n.shadowColor&&n.shadowColor!==""&&(A.fillStyle=n.shadowColor,A.fillText(y[c],f+5,h+16)),A.fillStyle=n.labelColor,A.fillText(y[c],f+4,h+15)}}if(A.lineWidth=2,l.mesh&&l.mesh.length>0){if(n.drawPoints){let y=Math.max(468,l.mesh.length);for(let c=0;c468)for(let y=468;y450)for(let y=0;yl.mesh[f]);io(A,c,n)}if(l.annotations&&l.annotations.leftEyeIris&&l.annotations.leftEyeIris[0]){A.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.color,A.beginPath();let y=Math.abs(l.annotations.leftEyeIris[3][0]-l.annotations.leftEyeIris[1][0])/2,c=Math.abs(l.annotations.leftEyeIris[4][1]-l.annotations.leftEyeIris[2][1])/2;A.ellipse(l.annotations.leftEyeIris[0][0],l.annotations.leftEyeIris[0][1],y,c,0,0,2*Math.PI),A.stroke(),n.fillPolygons&&(A.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.color,A.fill())}if(l.annotations&&l.annotations.rightEyeIris&&l.annotations.rightEyeIris[0]){A.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.color,A.beginPath();let y=Math.abs(l.annotations.rightEyeIris[3][0]-l.annotations.rightEyeIris[1][0])/2,c=Math.abs(l.annotations.rightEyeIris[4][1]-l.annotations.rightEyeIris[2][1])/2;A.ellipse(l.annotations.rightEyeIris[0][0],l.annotations.rightEyeIris[0][1],y,c,0,0,2*Math.PI),A.stroke(),n.fillPolygons&&(A.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.color,A.fill())}if(n.drawGaze&&((s=l.rotation)==null?void 0:s.angle)&&typeof Path2D!="undefined"){A.strokeStyle="pink";let y=l.box[0]+l.box[2]/2-l.box[3]*ie(l.rotation.angle.yaw)/90,c=l.box[1]+l.box[3]/2+l.box[2]*ie(l.rotation.angle.pitch)/90,f=new Path2D(`
+`;var Dt=(e,t,o)=>{let n=new RegExp("\\b"+t+" \\w+ (\\w+)","ig");e.replace(n,(A,s)=>(o[s]=0,A))},Xt=class{constructor(t,o,n){k(this,"uniform",{});k(this,"attribute",{});k(this,"gl");k(this,"id");k(this,"compile",(t,o)=>{let n=this.gl.createShader(o);return n?(this.gl.shaderSource(n,t),this.gl.compileShader(n),this.gl.getShaderParameter(n,this.gl.COMPILE_STATUS)?n:(b(`filter: gl compile failed: ${this.gl.getShaderInfoLog(n)}`),null)):(b("filter: could not create shader"),null)});this.gl=t;let A=this.compile(o,this.gl.VERTEX_SHADER),s=this.compile(n,this.gl.FRAGMENT_SHADER);if(this.id=this.gl.createProgram(),!(!A||!s)){if(!this.id){b("filter: could not create webgl program");return}if(this.gl.attachShader(this.id,A),this.gl.attachShader(this.id,s),this.gl.linkProgram(this.id),!this.gl.getProgramParameter(this.id,this.gl.LINK_STATUS)){b(`filter: gl link failed: ${this.gl.getProgramInfoLog(this.id)}`);return}this.gl.useProgram(this.id),Dt(o,"attribute",this.attribute);for(let a in this.attribute)this.attribute[a]=this.gl.getAttribLocation(this.id,a);Dt(o,"uniform",this.uniform),Dt(n,"uniform",this.uniform);for(let a in this.uniform)this.uniform[a]=this.gl.getUniformLocation(this.id,a)}}};function Oo(){let e=0,t=null,o=!1,n=-1,A=[null,null],s=[],a=null,i=null,x=a0(100,100),d={},l={INTERMEDIATE:1},y=x.getContext("webgl");if(!y){b("filter: cannot get webgl context");return}this.gl=y;function c(u,p){if(!(u===x.width&&p===x.height)){if(x.width=u,x.height=p,!a){let P=new Float32Array([-1,-1,0,1,1,-1,1,1,-1,1,0,0,-1,1,0,0,1,-1,1,1,1,1,1,0]);a=y.createBuffer(),y.bindBuffer(y.ARRAY_BUFFER,a),y.bufferData(y.ARRAY_BUFFER,P,y.STATIC_DRAW),y.pixelStorei(y.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0)}y.viewport(0,0,x.width,x.height),A=[null,null]}}function f(u,p){let P=y.createFramebuffer();y.bindFramebuffer(y.FRAMEBUFFER,P);let w=y.createRenderbuffer();y.bindRenderbuffer(y.RENDERBUFFER,w);let S=y.createTexture();return y.bindTexture(y.TEXTURE_2D,S),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,u,p,0,y.RGBA,y.UNSIGNED_BYTE,null),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,y.LINEAR),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,y.CLAMP_TO_EDGE),y.framebufferTexture2D(y.FRAMEBUFFER,y.COLOR_ATTACHMENT0,y.TEXTURE_2D,S,0),y.bindTexture(y.TEXTURE_2D,null),y.bindFramebuffer(y.FRAMEBUFFER,null),{fbo:P,texture:S}}function h(u){return A[u]=A[u]||f(x.width,x.height),A[u]}function m(u=0){if(!i)return;let p=null,P=null,w=!1;e===0?p=t:p=h(n).texture||null,e++,o&&!(u&l.INTERMEDIATE)?(P=null,w=e%2===0):(n=(n+1)%2,P=h(n).fbo||null),y.bindTexture(y.TEXTURE_2D,p),y.bindFramebuffer(y.FRAMEBUFFER,P),y.uniform1f(i.uniform.flipY,w?-1:1),y.drawArrays(y.TRIANGLES,0,6)}function v(u){if(d[u])return i=d[u],y.useProgram((i?i.id:null)||null),i;if(i=new Xt(y,Eo,u),!i)return b("filter: could not get webgl program"),null;let p=Float32Array.BYTES_PER_ELEMENT,P=4*p;return y.enableVertexAttribArray(i.attribute.pos),y.vertexAttribPointer(i.attribute.pos,2,y.FLOAT,!1,P,0*p),y.enableVertexAttribArray(i.attribute.uv),y.vertexAttribPointer(i.attribute.uv,2,y.FLOAT,!1,P,2*p),d[u]=i,i}let M={colorMatrix:u=>{let p=new Float32Array(u);p[4]/=255,p[9]/=255,p[14]/=255,p[19]/=255;let P=p[18]===1&&p[3]===0&&p[8]===0&&p[13]===0&&p[15]===0&&p[16]===0&&p[17]===0&&p[19]===0?jo:zo,w=v(P);!w||(y.uniform1fv(w.uniform.m,p),m())},brightness:u=>{let p=(u||0)+1;M.colorMatrix([p,0,0,0,0,0,p,0,0,0,0,0,p,0,0,0,0,0,1,0])},saturation:u=>{let p=(u||0)*2/3+1,P=(p-1)*-.5;M.colorMatrix([p,P,P,0,0,P,p,P,0,0,P,P,p,0,0,0,0,0,1,0])},desaturate:()=>{M.saturation(-1)},contrast:u=>{let p=(u||0)+1,P=-128*(p-1);M.colorMatrix([p,0,0,0,P,0,p,0,0,P,0,0,p,0,P,0,0,0,1,0])},negative:()=>{M.contrast(-2)},hue:u=>{u=(u||0)/180*Math.PI;let p=Math.cos(u),P=Math.sin(u),w=.213,S=.715,O=.072;M.colorMatrix([w+p*(1-w)+P*-w,S+p*-S+P*-S,O+p*-O+P*(1-O),0,0,w+p*-w+P*.143,S+p*(1-S)+P*.14,O+p*-O+P*-.283,0,0,w+p*-w+P*-(1-w),S+p*-S+P*S,O+p*(1-O)+P*O,0,0,0,0,0,1,0])},desaturateLuminance:()=>{M.colorMatrix([.2764723,.929708,.0938197,0,-37.1,.2764723,.929708,.0938197,0,-37.1,.2764723,.929708,.0938197,0,-37.1,0,0,0,1,0])},sepia:()=>{M.colorMatrix([.393,.7689999,.18899999,0,0,.349,.6859999,.16799999,0,0,.272,.5339999,.13099999,0,0,0,0,0,1,0])},brownie:()=>{M.colorMatrix([.5997023498159715,.34553243048391263,-.2708298674538042,0,47.43192855600873,-.037703249837783157,.8609577587992641,.15059552388459913,0,-36.96841498319127,.24113635128153335,-.07441037908422492,.44972182064877153,0,-7.562075277591283,0,0,0,1,0])},vintagePinhole:()=>{M.colorMatrix([.6279345635605994,.3202183420819367,-.03965408211312453,0,9.651285835294123,.02578397704808868,.6441188644374771,.03259127616149294,0,7.462829176470591,.0466055556782719,-.0851232987247891,.5241648018700465,0,5.159190588235296,0,0,0,1,0])},kodachrome:()=>{M.colorMatrix([1.1285582396593525,-.3967382283601348,-.03992559172921793,0,63.72958762196502,-.16404339962244616,1.0835251566291304,-.05498805115633132,0,24.732407896706203,-.16786010706155763,-.5603416277695248,1.6014850761964943,0,35.62982807460946,0,0,0,1,0])},technicolor:()=>{M.colorMatrix([1.9125277891456083,-.8545344976951645,-.09155508482755585,0,11.793603434377337,-.3087833385928097,1.7658908555458428,-.10601743074722245,0,-70.35205161461398,-.231103377548616,-.7501899197440212,1.847597816108189,0,30.950940869491138,0,0,0,1,0])},polaroid:()=>{M.colorMatrix([1.438,-.062,-.062,0,0,-.122,1.378,-.122,0,0,-.016,-.016,1.483,0,0,0,0,0,1,0])},shiftToBGR:()=>{M.colorMatrix([0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0])},convolution:u=>{let p=new Float32Array(u),P=1/x.width,w=1/x.height,S=v(Co);!S||(y.uniform1fv(S.uniform.m,p),y.uniform2f(S.uniform.px,P,w),m())},detectEdges:()=>{M.convolution.call(this,[0,1,0,1,-4,1,0,1,0])},sobelX:()=>{M.convolution.call(this,[-1,0,1,-2,0,2,-1,0,1])},sobelY:()=>{M.convolution.call(this,[-1,-2,-1,0,0,0,1,2,1])},sharpen:u=>{let p=u||1;M.convolution.call(this,[0,-1*p,0,-1*p,1+4*p,-1*p,0,-1*p,0])},emboss:u=>{let p=u||1;M.convolution.call(this,[-2*p,-1*p,0,-1*p,1,1*p,0,1*p,2*p])},blur:u=>{let p=u/7/x.width,P=u/7/x.height,w=v(Wo);!w||(y.uniform2f(w.uniform.px,0,P),m(l.INTERMEDIATE),y.uniform2f(w.uniform.px,p,0),m())},pixelate:u=>{let p=u/x.width,P=u/x.height,w=v(So);!w||(y.uniform2f(w.uniform.size,p,P),m())}};this.add=function(u){let p=Array.prototype.slice.call(arguments,1),P=M[u];s.push({func:P,args:p})},this.reset=function(){s=[]},this.get=function(){return s},this.apply=function(u){c(u.width,u.height),e=0,t||(t=y.createTexture()),y.bindTexture(y.TEXTURE_2D,t),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_S,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_WRAP_T,y.CLAMP_TO_EDGE),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MIN_FILTER,y.NEAREST),y.texParameteri(y.TEXTURE_2D,y.TEXTURE_MAG_FILTER,y.NEAREST),y.texImage2D(y.TEXTURE_2D,0,y.RGBA,y.RGBA,y.UNSIGNED_BYTE,u);for(let p=0;pf.data())),a=.99*Math.max(s[0][0],s[1][0],s[2][0]),i=[r.sub(o[0],n[0]),r.sub(o[1],n[1]),r.sub(o[2],n[2])],x=[r.sub(A[0],n[0]),r.sub(A[1],n[1]),r.sub(A[2],n[2])],d=[r.div(a,x[0]),r.div(a,x[1]),r.div(a,x[2])],l=[r.mul(i[0],d[0]),r.mul(i[1],d[1]),r.mul(i[2],d[2])],y=r.stack([l[0],l[1],l[2]],2),c=r.reshape(y,[1,t.shape[0],t.shape[1],3]);return r.dispose([...o,...n,...A,...i,...x,...d,...l,y,t]),c}var tt=2048,F=null,_=null,de=null,X,I0={inputSum:0,cacheDiff:1,sumMethod:0,inputTensor:void 0};function a0(e,t){let o;if(R.browser)if(R.worker){if(typeof OffscreenCanvas=="undefined")throw new Error("canvas error: attempted to run in web worker but OffscreenCanvas is not supported");o=new OffscreenCanvas(e,t)}else{if(typeof document=="undefined")throw new Error("canvas error: attempted to run in browser but DOM is not defined");o=document.createElement("canvas"),o.width=e,o.height=t}else typeof R.Canvas!="undefined"?o=new R.Canvas(e,t):typeof globalThis.Canvas!="undefined"&&(o=new globalThis.Canvas(e,t));return o}function ot(e,t){let o=t||a0(e.width,e.height);return o.getContext("2d").drawImage(e,0,0),o}async function fe(e,t,o=!0){if(!e)return t.debug&&b("input error: input is missing"),{tensor:null,canvas:null};if(!(e instanceof ce)&&!(typeof Image!="undefined"&&e instanceof Image)&&!(typeof R.Canvas!="undefined"&&e instanceof R.Canvas)&&!(typeof globalThis.Canvas!="undefined"&&e instanceof globalThis.Canvas)&&!(typeof ImageData!="undefined"&&e instanceof ImageData)&&!(typeof ImageBitmap!="undefined"&&e instanceof ImageBitmap)&&!(typeof HTMLImageElement!="undefined"&&e instanceof HTMLImageElement)&&!(typeof HTMLMediaElement!="undefined"&&e instanceof HTMLMediaElement)&&!(typeof HTMLVideoElement!="undefined"&&e instanceof HTMLVideoElement)&&!(typeof HTMLCanvasElement!="undefined"&&e instanceof HTMLCanvasElement)&&!(typeof OffscreenCanvas!="undefined"&&e instanceof OffscreenCanvas))throw new Error("input error: type is not recognized");if(e instanceof ce){let n=null;if(e.isDisposedInternal)throw new Error("input error: attempted to use tensor but it is disposed");if(!e.shape)throw new Error("input error: attempted to use tensor without a shape");if(e.shape.length===3){if(e.shape[2]===3)n=r.expandDims(e,0);else if(e.shape[2]===4){let A=r.slice3d(e,[0,0,0],[-1,-1,3]);n=r.expandDims(A,0),r.dispose(A)}}else e.shape.length===4&&(e.shape[3]===3?n=r.clone(e):e.shape[3]===4&&(n=r.slice4d(e,[0,0,0,0],[-1,-1,-1,3])));if(n==null||n.shape.length!==4||n.shape[0]!==1||n.shape[3]!==3)throw new Error(`input error: attempted to use tensor with unrecognized shape: ${e.shape}`);if(n.dtype==="int32"){let A=r.cast(n,"float32");r.dispose(n),n=A}return{tensor:n,canvas:t.filter.return?_:null}}else{if(typeof e.readyState!="undefined"&&e.readyState<=2)return t.debug&&b("input stream is not ready"),{tensor:null,canvas:F};let n=e.naturalWidth||e.videoWidth||e.width||e.shape&&e.shape[1]>0,A=e.naturalHeight||e.videoHeight||e.height||e.shape&&e.shape[2]>0;if(!n||!A)return t.debug&&b("cannot determine input dimensions"),{tensor:null,canvas:F};let s=n,a=A;if(s>tt&&(s=tt,a=Math.trunc(s*A/n)),a>tt&&(a=tt,s=Math.trunc(a*n/A)),(t.filter.width||0)>0?s=t.filter.width:(t.filter.height||0)>0&&(s=n*((t.filter.height||0)/A)),(t.filter.height||0)>0?a=t.filter.height:(t.filter.width||0)>0&&(a=A*((t.filter.width||0)/n)),!s||!a)throw new Error("input error: cannot determine dimension");(!F||(F==null?void 0:F.width)!==s||(F==null?void 0:F.height)!==a)&&(F=a0(s,a));let i=F.getContext("2d");if(typeof ImageData!="undefined"&&e instanceof ImageData?i.putImageData(e,0,0):t.filter.flip&&typeof i.translate!="undefined"?(i.translate(n,0),i.scale(-1,1),i.drawImage(e,0,0,n,A,0,0,F==null?void 0:F.width,F==null?void 0:F.height),i.setTransform(1,0,0,1,0,0)):i.drawImage(e,0,0,n,A,0,0,F==null?void 0:F.width,F==null?void 0:F.height),(!_||F.width!==_.width||(F==null?void 0:F.height)!==(_==null?void 0:_.height))&&(_=a0(F.width,F.height)),t.filter.enabled&&R.webgl.supported?(X||(X=R.browser?new Oo:null),R.filter=!!X,!X||!X.add?(t.debug&&b("input process error: cannot initialize filters"),R.webgl.supported=!1,t.filter.enabled=!1,ot(F,_)):(X.reset(),t.filter.brightness!==0&&X.add("brightness",t.filter.brightness),t.filter.contrast!==0&&X.add("contrast",t.filter.contrast),t.filter.sharpness!==0&&X.add("sharpen",t.filter.sharpness),t.filter.blur!==0&&X.add("blur",t.filter.blur),t.filter.saturation!==0&&X.add("saturation",t.filter.saturation),t.filter.hue!==0&&X.add("hue",t.filter.hue),t.filter.negative&&X.add("negative"),t.filter.sepia&&X.add("sepia"),t.filter.vintage&&X.add("brownie"),t.filter.sepia&&X.add("sepia"),t.filter.kodachrome&&X.add("kodachrome"),t.filter.technicolor&&X.add("technicolor"),t.filter.polaroid&&X.add("polaroid"),t.filter.pixelate!==0&&X.add("pixelate",t.filter.pixelate),X.get()>0?_=X.apply(F):_=X.draw(F))):(ot(F,_),X&&(X=null),R.filter=!!X),!o)return{tensor:null,canvas:_};if(!_)throw new Error("canvas error: cannot create output");let x,d=3;if(typeof ImageData!="undefined"&&e instanceof ImageData||e.data&&e.width&&e.height)if(R.browser&&r.browser)x=r.browser?r.browser.fromPixels(e):null;else{d=e.data.length/e.height/e.width;let c=new Uint8Array(e.data.buffer);x=r.tensor(c,[e.height,e.width,d],"int32")}else if((!de||_.width!==de.width||_.height!==de.height)&&(de=a0(_.width,_.height)),r.browser&&R.browser)t.backend==="webgl"||t.backend==="humangl"||t.backend==="webgpu"?x=r.browser.fromPixels(_):(de=ot(_),x=r.browser.fromPixels(de));else{let h=ot(_).getContext("2d").getImageData(0,0,s,a);d=h.data.length/s/a;let m=new Uint8Array(h.data.buffer);x=r.tensor(m,[s,a,d])}if(d===4){let c=r.slice3d(x,[0,0,0],[-1,-1,3]);r.dispose(x),x=c}if(!x)throw new Error("input error: cannot create tensor");let l=r.cast(x,"float32"),y=t.filter.equalization?await et(l):r.expandDims(l,0);return r.dispose([x,l]),{tensor:y,canvas:t.filter.return?_:null}}}async function Io(e,t){let o=!1;if(e.cacheSensitivity===0||!t.shape||t.shape.length!==4||t.shape[1]>2048||t.shape[2]>2048)return o;if(!I0.inputTensor)I0.inputTensor=r.clone(t);else if(I0.inputTensor.shape[1]!==t.shape[1]||I0.inputTensor.shape[2]!==t.shape[2])r.dispose(I0.inputTensor),I0.inputTensor=r.clone(t);else{let n={};n.diff=r.sub(t,I0.inputTensor),n.squared=r.mul(n.diff,n.diff),n.sum=r.sum(n.squared);let s=(await n.sum.data())[0]/(t.shape[1]||1)/(t.shape[2]||1)/255/3;r.dispose([I0.inputTensor,n.diff,n.squared,n.sum]),I0.inputTensor=r.clone(t),o=s<=(e.cacheSensitivity||0)}return o}async function Lo(e,t,o){let n={};if(!t||!o||t.shape.length!==4||t.shape.length!==o.shape.length)return e.debug||b("invalid input tensor or tensor shapes do not match:",t.shape,o.shape),0;if(t.shape[0]!==1||o.shape[0]!==1||t.shape[3]!==3||o.shape[3]!==3)return e.debug||b("input tensors must be of shape [1, height, width, 3]:",t.shape,o.shape),0;n.input1=r.clone(t),n.input2=t.shape[1]!==o.shape[1]||t.shape[2]!==o.shape[2]?r.image.resizeBilinear(o,[t.shape[1],t.shape[2]]):r.clone(o),n.diff=r.sub(n.input1,n.input2),n.squared=r.mul(n.diff,n.diff),n.sum=r.sum(n.squared);let s=(await n.sum.data())[0]/(t.shape[1]||1)/(t.shape[2]||1)/255/3;return r.dispose([n.input1,n.input2,n.diff,n.squared,n.sum]),s}var qt=class{constructor(){k(this,"browser");k(this,"node");k(this,"worker");k(this,"platform","");k(this,"agent","");k(this,"backends",[]);k(this,"initial");k(this,"filter");k(this,"tfjs");k(this,"offscreen");k(this,"perfadd",!1);k(this,"wasm",{supported:void 0,backend:void 0,simd:void 0,multithread:void 0});k(this,"webgl",{supported:void 0,backend:void 0,version:void 0,renderer:void 0});k(this,"webgpu",{supported:void 0,backend:void 0,adapter:void 0});k(this,"cpu",{model:void 0,flags:[]});k(this,"kernels",[]);k(this,"Canvas");k(this,"Image");k(this,"ImageData");if(this.browser=typeof navigator!="undefined",this.node=typeof process!="undefined"&&typeof process.versions!="undefined"&&typeof process.versions.node!="undefined",this.tfjs={version:Fe["tfjs-core"]},this.offscreen=typeof OffscreenCanvas!="undefined",this.initial=!0,this.worker=this.browser&&this.offscreen?typeof WorkerGlobalScope!="undefined":void 0,typeof navigator!="undefined"){let t=navigator.userAgent.match(/\(([^()]+)\)/g);if(t&&t[0]){let o=t[0].match(/\(([^()]+)\)/g);this.platform=o&&o[0]?o[0].replace(/\(|\)/g,""):"",this.agent=navigator.userAgent.replace(t[0],""),this.platform[1]&&(this.agent=this.agent.replace(t[1],"")),this.agent=this.agent.replace(/ /g," ")}}else typeof process!="undefined"&&(this.platform=`${process.platform} ${process.arch}`,this.agent=`NodeJS ${process.version}`)}async updateBackend(){this.backends=Object.keys(r.engine().registryFactory),this.wasm.supported=typeof WebAssembly!="undefined",this.wasm.backend=this.backends.includes("wasm"),this.wasm.supported&&this.wasm.backend&&r.getBackend()==="wasm"&&(this.wasm.simd=await r.env().getAsync("WASM_HAS_SIMD_SUPPORT"),this.wasm.multithread=await r.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT"));let t=a0(100,100),o=t?t.getContext("webgl2"):void 0;if(this.webgl.supported=typeof o!="undefined",this.webgl.backend=this.backends.includes("webgl"),this.webgl.supported&&this.webgl.backend&&(r.getBackend()==="webgl"||r.getBackend()==="humangl")){let n=r.backend().gpgpu!=="undefined"?await r.backend().getGPGPUContext().gl:null;n&&(this.webgl.version=n.getParameter(n.VERSION),this.webgl.renderer=n.getParameter(n.RENDERER))}this.webgpu.supported=this.browser&&typeof navigator.gpu!="undefined",this.webgpu.backend=this.backends.includes("webgpu");try{this.webgpu.supported&&(this.webgpu.adapter=(await navigator.gpu.requestAdapter()).name)}catch(n){this.webgpu.supported=!1}try{this.kernels=r.getKernelsForBackend(r.getBackend()).map(n=>n.kernelName.toLowerCase())}catch(n){}}async updateCPU(){let t={model:"",flags:[]};this.node&&this.platform.startsWith("linux"),this.cpu?this.cpu=t:Object.defineProperty(this,"cpu",{value:t})}},R=new qt;var L0={cacheModels:!1,verbose:!0,debug:!1,modelBasePath:""};async function Er(e,t){return L0.debug&&b("load model fetch:",e,t),fetch(e,t)}function No(e){L0.cacheModels=e.cacheModels,L0.verbose=e.debug,L0.modelBasePath=e.modelBasePath}async function L(e){let t=ko(L0.modelBasePath,e||""),o=t.split("/"),n="indexeddb://"+o[o.length-1].replace(".json",""),A=await r.io.listModels(),s=L0.cacheModels&&Object.keys(A).includes(n),a=typeof fetch=="undefined"?{}:{fetchFunc:(d,l)=>Er(d,l)},i=new Zt(s?n:t,a),x=!1;try{i.findIOHandler(),L0.debug&&b("model load handler:",i.handler);let d=await i.handler.load();i.loadSync(d),L0.verbose&&b("load model:",i.modelUrl),x=!0}catch(d){b("error loading model:",t,d)}if(x&&L0.cacheModels&&!s)try{let d=await i.save(n);b("model saved:",n,d)}catch(d){b("error saving model:",t,d)}return i}var Ut="2.7.0";var io={};ee(io,{Models:()=>Ke,load:()=>so,reset:()=>Lt,validate:()=>ao});var b0,Jt=[],Sr=["white","black","asian","indian","other"],Wr=[15,23,28,35.5,45.5,55.5,65],Go=0,Bo=0,Yt=Number.MAX_SAFE_INTEGER;async function Fo(e){return R.initial&&(b0=null),b0?e.debug&&b("cached model:",b0.modelUrl):b0=await L(e.face.gear),b0}async function Kt(e,t,o,n){var a,i;if(!b0)return{age:0,gender:"unknown",genderScore:0,race:[]};let A=Yt<(((a=t.face.gear)==null?void 0:a.skipFrames)||0),s=(((i=t.face.gear)==null?void 0:i.skipTime)||0)>g()-Bo;return t.skipAllowed&&s&&A&&Go===n&&Jt[o]?(Yt++,Jt[o]):(Yt=0,new Promise(async x=>{var M,u;if(!(b0!=null&&b0.inputs[0].shape))return;let d={},l=[[0,.1,.9,.9]];d.resize=r.image.cropAndResize(e,l,[0],[b0.inputs[0].shape[2],b0.inputs[0].shape[1]]);let y={age:0,gender:"unknown",genderScore:0,race:[]};(M=t.face.gear)!=null&&M.enabled&&([d.age,d.gender,d.race]=b0.execute(d.resize,["age_output","gender_output","race_output"]));let c=await d.gender.data();y.gender=c[0]>c[1]?"male":"female",y.genderScore=Math.round(100*(c[0]>c[1]?c[0]:c[1]))/100;let f=await d.race.data();for(let p=0;p(((u=t.face.gear)==null?void 0:u.minConfidence)||.2)&&y.race.push({score:Math.round(100*f[p])/100,race:Sr[p]});y.race.sort((p,P)=>P.score-p.score);let m=Array.from(await d.age.data()).map((p,P)=>[Wr[P],p]).sort((p,P)=>P[1]-p[1]),v=m[0][0];for(let p=1;pr.dispose(d[p])),Jt[o]=y,Go=n,Bo=g(),x(y)}))}var N={tf255:255,tf1:1,tf2:2,tf05:.5,tf127:127.5,rgb:[.2989,.587,.114]};function Vo(){N.tf255=r.scalar(255,"float32"),N.tf1=r.scalar(1,"float32"),N.tf2=r.scalar(2,"float32"),N.tf05=r.scalar(.5,"float32"),N.tf127=r.scalar(127.5,"float32"),N.rgb=r.tensor1d([.2989,.587,.114],"float32")}var y0,nt=[],Zo=0,Do=0,Qt=Number.MAX_SAFE_INTEGER;async function Xo(e){return R.initial&&(y0=null),y0?e.debug&&b("cached model:",y0.modelUrl):y0=await L(e.face.ssrnet.modelPathAge),y0}async function _t(e,t,o,n){var a,i,x,d;if(!y0)return{age:0};let A=Qt<(((a=t.face.ssrnet)==null?void 0:a.skipFrames)||0),s=(((i=t.face.ssrnet)==null?void 0:i.skipTime)||0)>g()-Do;return t.skipAllowed&&A&&s&&Zo===n&&((x=nt[o])==null?void 0:x.age)&&((d=nt[o])==null?void 0:d.age)>0?(Qt++,nt[o]):(Qt=0,new Promise(async l=>{if(!(y0!=null&&y0.inputs)||!y0.inputs[0]||!y0.inputs[0].shape)return;let y={};y.resize=r.image.resizeBilinear(e,[y0.inputs[0].shape[2],y0.inputs[0].shape[1]],!1),y.enhance=r.mul(y.resize,N.tf255);let c={age:0};if(t.face.ssrnet.enabled&&(y.age=y0.execute(y.enhance)),y.age){let f=await y.age.data();c.age=Math.trunc(10*f[0])/10}Object.keys(y).forEach(f=>r.dispose(y[f])),nt[o]=c,Zo=n,Do=g(),l(c)}))}var g0,At=[],Uo=0,Jo=0,$t=Number.MAX_SAFE_INTEGER,e5=[.2989,.587,.114];async function Yo(e){return R.initial&&(g0=null),g0?e.debug&&b("cached model:",g0.modelUrl):g0=await L(e.face.ssrnet.modelPathGender),g0}async function t5(e,t,o,n){var a,i,x,d;if(!g0)return{gender:"unknown",genderScore:0};let A=$t<(((a=t.face.ssrnet)==null?void 0:a.skipFrames)||0),s=(((i=t.face.ssrnet)==null?void 0:i.skipTime)||0)>g()-Jo;return t.skipAllowed&&A&&s&&Uo===n&&((x=At[o])==null?void 0:x.gender)&&((d=At[o])==null?void 0:d.genderScore)>0?($t++,At[o]):($t=0,new Promise(async l=>{if(!(g0!=null&&g0.inputs[0].shape))return;let y={};y.resize=r.image.resizeBilinear(e,[g0.inputs[0].shape[2],g0.inputs[0].shape[1]],!1),y.enhance=r.tidy(()=>{let[h,m,v]=r.split(y.resize,3,3),M=r.mul(h,e5[0]),u=r.mul(m,e5[1]),p=r.mul(v,e5[2]),P=r.addN([M,u,p]);return r.mul(r.sub(P,N.tf05),2)});let c={gender:"unknown",genderScore:0};t.face.ssrnet.enabled&&(y.gender=g0.execute(y.enhance));let f=await y.gender.data();c.gender=f[0]>f[1]?"female":"male",c.genderScore=f[0]>f[1]?Math.trunc(100*f[0])/100:Math.trunc(100*f[1])/100,Object.keys(y).forEach(h=>r.dispose(y[h])),At[o]=c,Uo=n,Jo=g(),l(c)}))}var A0,rt=[],o5=Number.MAX_SAFE_INTEGER,Qo=0,_o=0;async function $o(e){var t;return R.initial&&(A0=null),A0?e.debug&&b("cached model:",A0.modelUrl):A0=await L((t=e.face.antispoof)==null?void 0:t.modelPath),A0}async function n5(e,t,o,n){var a,i;if(!A0)return 0;let A=(((a=t.face.antispoof)==null?void 0:a.skipTime)||0)>g()-_o,s=o5<(((i=t.face.antispoof)==null?void 0:i.skipFrames)||0);return t.skipAllowed&&A&&s&&Qo===n&&rt[o]?(o5++,rt[o]):(o5=0,new Promise(async x=>{let d=r.image.resizeBilinear(e,[A0!=null&&A0.inputs[0].shape?A0.inputs[0].shape[2]:0,A0!=null&&A0.inputs[0].shape?A0.inputs[0].shape[1]:0],!1),l=A0==null?void 0:A0.execute(d),y=(await l.data())[0];rt[o]=Math.round(100*y)/100,Qo=n,_o=g(),r.dispose([d,l]),x(rt[o])}))}var M0={silhouette:[10,338,297,332,284,251,389,356,454,323,361,288,397,365,379,378,400,377,152,148,176,149,150,136,172,58,132,93,234,127,162,21,54,103,67,109],lipsUpperOuter:[61,185,40,39,37,0,267,269,270,409,291],lipsLowerOuter:[146,91,181,84,17,314,405,321,375,291],lipsUpperInner:[78,191,80,81,82,13,312,311,310,415,308],lipsLowerInner:[78,95,88,178,87,14,317,402,318,324,308],rightEyeUpper0:[246,161,160,159,158,157,173],rightEyeLower0:[33,7,163,144,145,153,154,155,133],rightEyeUpper1:[247,30,29,27,28,56,190],rightEyeLower1:[130,25,110,24,23,22,26,112,243],rightEyeUpper2:[113,225,224,223,222,221,189],rightEyeLower2:[226,31,228,229,230,231,232,233,244],rightEyeLower3:[143,111,117,118,119,120,121,128,245],rightEyebrowUpper:[156,70,63,105,66,107,55,193],rightEyebrowLower:[35,124,46,53,52,65],rightEyeIris:[473,474,475,476,477],leftEyeUpper0:[466,388,387,386,385,384,398],leftEyeLower0:[263,249,390,373,374,380,381,382,362],leftEyeUpper1:[467,260,259,257,258,286,414],leftEyeLower1:[359,255,339,254,253,252,256,341,463],leftEyeUpper2:[342,445,444,443,442,441,413],leftEyeLower2:[446,261,448,449,450,451,452,453,464],leftEyeLower3:[372,340,346,347,348,349,350,357,465],leftEyebrowUpper:[383,300,293,334,296,336,285,417],leftEyebrowLower:[265,353,276,283,282,295],leftEyeIris:[468,469,470,471,472],midwayBetweenEyes:[168],noseTip:[1],noseBottom:[2],noseRightCorner:[98],noseLeftCorner:[327],rightCheek:[205],leftCheek:[425]},A5={count:468,mouth:13,symmetryLine:[13,M0.midwayBetweenEyes[0]]},Ve={leftEye:0,rightEye:1,nose:2,mouth:3,leftEar:4,rightEar:5,symmetryLine:[3,2]},r5=[{key:"EyeUpper0",indices:[9,10,11,12,13,14,15]},{key:"EyeUpper1",indices:[25,26,27,28,29,30,31]},{key:"EyeUpper2",indices:[41,42,43,44,45,46,47]},{key:"EyeLower0",indices:[0,1,2,3,4,5,6,7,8]},{key:"EyeLower1",indices:[16,17,18,19,20,21,22,23,24]},{key:"EyeLower2",indices:[32,33,34,35,36,37,38,39,40]},{key:"EyeLower3",indices:[54,55,56,57,58,59,60,61,62]},{key:"EyebrowUpper",indices:[63,64,65,66,67,68,69,70]},{key:"EyebrowLower",indices:[48,49,50,51,52,53]}],Ze=[[.499976992607117,.652534008026123],[.500025987625122,.547487020492554],[.499974012374878,.602371990680695],[.482113003730774,.471979022026062],[.500150978565216,.527155995368958],[.499909996986389,.498252987861633],[.499523013830185,.40106201171875],[.289712011814117,.380764007568359],[.499954998493195,.312398016452789],[.499987006187439,.269918978214264],[.500023007392883,.107050001621246],[.500023007392883,.666234016418457],[.5000159740448,.679224014282227],[.500023007392883,.692348003387451],[.499976992607117,.695277988910675],[.499976992607117,.70593398809433],[.499976992607117,.719385027885437],[.499976992607117,.737019002437592],[.499967992305756,.781370997428894],[.499816000461578,.562981009483337],[.473773002624512,.573909997940063],[.104906998574734,.254140973091125],[.365929991006851,.409575998783112],[.338757991790771,.41302502155304],[.311120003461838,.409460008144379],[.274657994508743,.389131009578705],[.393361985683441,.403706014156342],[.345234006643295,.344011008739471],[.370094001293182,.346076011657715],[.319321990013123,.347265005111694],[.297903001308441,.353591024875641],[.24779200553894,.410809993743896],[.396889001131058,.842755019664764],[.280097991228104,.375599980354309],[.106310002505779,.399955987930298],[.2099249958992,.391353011131287],[.355807989835739,.534406006336212],[.471751004457474,.65040397644043],[.474155008792877,.680191993713379],[.439785003662109,.657229006290436],[.414617002010345,.66654098033905],[.450374007225037,.680860996246338],[.428770989179611,.682690978050232],[.374971002340317,.727805018424988],[.486716985702515,.547628998756409],[.485300987958908,.527395009994507],[.257764995098114,.314490020275116],[.401223003864288,.455172002315521],[.429818987846375,.548614978790283],[.421351999044418,.533740997314453],[.276895999908447,.532056987285614],[.483370006084442,.499586999416351],[.33721199631691,.282882988452911],[.296391993761063,.293242990970612],[.169294998049736,.193813979625702],[.447580009698868,.302609980106354],[.392390012741089,.353887975215912],[.354490011930466,.696784019470215],[.067304998636246,.730105042457581],[.442739009857178,.572826027870178],[.457098007202148,.584792017936707],[.381974011659622,.694710969924927],[.392388999462128,.694203019142151],[.277076005935669,.271932005882263],[.422551989555359,.563233017921448],[.385919004678726,.281364023685455],[.383103013038635,.255840003490448],[.331431001424789,.119714021682739],[.229923993349075,.232002973556519],[.364500999450684,.189113974571228],[.229622006416321,.299540996551514],[.173287004232407,.278747975826263],[.472878992557526,.666198015213013],[.446828007698059,.668527007102966],[.422762006521225,.673889994621277],[.445307999849319,.580065965652466],[.388103008270264,.693961024284363],[.403039008378983,.706539988517761],[.403629004955292,.693953037261963],[.460041999816895,.557139039039612],[.431158006191254,.692366003990173],[.452181994915009,.692366003990173],[.475387006998062,.692366003990173],[.465828001499176,.779190003871918],[.472328990697861,.736225962638855],[.473087012767792,.717857003211975],[.473122000694275,.704625964164734],[.473033010959625,.695277988910675],[.427942007780075,.695277988910675],[.426479011774063,.703539967536926],[.423162013292313,.711845993995667],[.4183090031147,.720062971115112],[.390094995498657,.639572978019714],[.013953999616206,.560034036636353],[.499913990497589,.58014702796936],[.413199990987778,.69539999961853],[.409626007080078,.701822996139526],[.468080013990402,.601534962654114],[.422728985548019,.585985004901886],[.463079988956451,.593783974647522],[.37211999297142,.47341400384903],[.334562003612518,.496073007583618],[.411671012639999,.546965003013611],[.242175996303558,.14767599105835],[.290776997804642,.201445996761322],[.327338010072708,.256527006626129],[.399509996175766,.748921036720276],[.441727995872498,.261676013469696],[.429764986038208,.187834024429321],[.412198007106781,.108901023864746],[.288955003023148,.398952007293701],[.218936994671822,.435410976409912],[.41278201341629,.398970007896423],[.257135003805161,.355440020561218],[.427684992551804,.437960982322693],[.448339998722076,.536936044692993],[.178560003638268,.45755398273468],[.247308000922203,.457193970680237],[.286267012357712,.467674970626831],[.332827985286713,.460712015628815],[.368755996227264,.447206974029541],[.398963987827301,.432654976844788],[.476410001516342,.405806005001068],[.189241006970406,.523923993110657],[.228962004184723,.348950982093811],[.490725994110107,.562400996685028],[.404670000076294,.485132992267609],[.019469000399113,.401564002037048],[.426243007183075,.420431017875671],[.396993011236191,.548797011375427],[.266469985246658,.376977026462555],[.439121007919312,.51895797252655],[.032313998788595,.644356966018677],[.419054001569748,.387154996395111],[.462783008813858,.505746960639954],[.238978996872902,.779744982719421],[.198220998048782,.831938028335571],[.107550002634525,.540755033493042],[.183610007166862,.740257024765015],[.134409993886948,.333683013916016],[.385764002799988,.883153975009918],[.490967005491257,.579378008842468],[.382384985685349,.508572995662689],[.174399003386497,.397670984268188],[.318785011768341,.39623498916626],[.343364000320435,.400596976280212],[.396100014448166,.710216999053955],[.187885001301765,.588537991046906],[.430987000465393,.944064974784851],[.318993002176285,.898285031318665],[.266247987747192,.869701027870178],[.500023007392883,.190576016902924],[.499976992607117,.954452991485596],[.366169989109039,.398822009563446],[.393207013607025,.39553701877594],[.410373002290726,.391080021858215],[.194993004202843,.342101991176605],[.388664990663528,.362284004688263],[.365961998701096,.355970978736877],[.343364000320435,.355356991291046],[.318785011768341,.35834002494812],[.301414996385574,.363156020641327],[.058132998645306,.319076001644135],[.301414996385574,.387449026107788],[.499987989664078,.618434011936188],[.415838003158569,.624195992946625],[.445681989192963,.566076993942261],[.465844005346298,.620640993118286],[.49992299079895,.351523995399475],[.288718998432159,.819945991039276],[.335278987884521,.852819979190826],[.440512001514435,.902418971061707],[.128294005990028,.791940987110138],[.408771991729736,.373893976211548],[.455606997013092,.451801002025604],[.499877005815506,.908990025520325],[.375436991453171,.924192011356354],[.11421000212431,.615022003650665],[.448662012815475,.695277988910675],[.4480200111866,.704632043838501],[.447111994028091,.715808033943176],[.444831997156143,.730794012546539],[.430011987686157,.766808986663818],[.406787008047104,.685672998428345],[.400738000869751,.681069016456604],[.392399996519089,.677703022956848],[.367855995893478,.663918972015381],[.247923001646996,.601333022117615],[.452769994735718,.420849978923798],[.43639200925827,.359887003898621],[.416164010763168,.368713974952698],[.413385987281799,.692366003990173],[.228018000721931,.683571994304657],[.468268007040024,.352671027183533],[.411361992359161,.804327011108398],[.499989002943039,.469825029373169],[.479153990745544,.442654013633728],[.499974012374878,.439637005329132],[.432112008333206,.493588984012604],[.499886006116867,.866917014122009],[.49991300702095,.821729004383087],[.456548988819122,.819200992584229],[.344549000263214,.745438992977142],[.37890899181366,.574010014533997],[.374292999505997,.780184984207153],[.319687992334366,.570737957954407],[.357154995203018,.604269981384277],[.295284003019333,.621580958366394],[.447750002145767,.862477004528046],[.410986006259918,.508723020553589],[.31395098567009,.775308012962341],[.354128003120422,.812552988529205],[.324548006057739,.703992962837219],[.189096003770828,.646299958229065],[.279776990413666,.71465802192688],[.1338230073452,.682700991630554],[.336768001317978,.644733011722565],[.429883986711502,.466521978378296],[.455527991056442,.548622965812683],[.437114000320435,.558896005153656],[.467287987470627,.529924988746643],[.414712011814117,.335219979286194],[.37704598903656,.322777986526489],[.344107985496521,.320150971412659],[.312875986099243,.32233202457428],[.283526003360748,.333190023899078],[.241245999932289,.382785975933075],[.102986000478268,.468762993812561],[.267612010240555,.424560010433197],[.297879010438919,.433175981044769],[.333433985710144,.433878004550934],[.366427004337311,.426115989685059],[.396012008190155,.416696012020111],[.420121014118195,.41022801399231],[.007561000064015,.480777025222778],[.432949006557465,.569517970085144],[.458638995885849,.479089021682739],[.473466008901596,.545744001865387],[.476087987422943,.563830018043518],[.468472003936768,.555056989192963],[.433990985155106,.582361996173859],[.483518004417419,.562983989715576],[.482482999563217,.57784903049469],[.42645001411438,.389798998832703],[.438998997211456,.39649498462677],[.450067013502121,.400434017181396],[.289712011814117,.368252992630005],[.276670008897781,.363372981548309],[.517862021923065,.471948027610779],[.710287988185883,.380764007568359],[.526226997375488,.573909997940063],[.895093023777008,.254140973091125],[.634069979190826,.409575998783112],[.661242008209229,.41302502155304],[.688880026340485,.409460008144379],[.725341975688934,.389131009578705],[.606630027294159,.40370500087738],[.654766023159027,.344011008739471],[.629905998706818,.346076011657715],[.680678009986877,.347265005111694],[.702096998691559,.353591024875641],[.75221198797226,.410804986953735],[.602918028831482,.842862963676453],[.719901978969574,.375599980354309],[.893692970275879,.399959981441498],[.790081977844238,.391354024410248],[.643998026847839,.534487962722778],[.528249025344849,.65040397644043],[.525849997997284,.680191040039062],[.560214996337891,.657229006290436],[.585384011268616,.66654098033905],[.549625992774963,.680860996246338],[.57122802734375,.682691991329193],[.624852001667023,.72809898853302],[.513050019741058,.547281980514526],[.51509702205658,.527251958847046],[.742246985435486,.314507007598877],[.598631024360657,.454979002475739],[.570338010787964,.548575043678284],[.578631997108459,.533622980117798],[.723087012767792,.532054007053375],[.516445994377136,.499638974666595],[.662801027297974,.282917976379395],[.70362401008606,.293271005153656],[.830704987049103,.193813979625702],[.552385985851288,.302568018436432],[.607609987258911,.353887975215912],[.645429015159607,.696707010269165],[.932694971561432,.730105042457581],[.557260990142822,.572826027870178],[.542901992797852,.584792017936707],[.6180260181427,.694710969924927],[.607590973377228,.694203019142151],[.722943007946014,.271963000297546],[.577413976192474,.563166975975037],[.614082992076874,.281386971473694],[.616907000541687,.255886018276215],[.668509006500244,.119913995265961],[.770092010498047,.232020974159241],[.635536015033722,.189248979091644],[.77039098739624,.299556016921997],[.826722025871277,.278755009174347],[.527121007442474,.666198015213013],[.553171992301941,.668527007102966],[.577238023281097,.673889994621277],[.554691970348358,.580065965652466],[.611896991729736,.693961024284363],[.59696102142334,.706539988517761],[.596370995044708,.693953037261963],[.539958000183105,.557139039039612],[.568841993808746,.692366003990173],[.547818005084991,.692366003990173],[.52461302280426,.692366003990173],[.534089982509613,.779141008853912],[.527670979499817,.736225962638855],[.526912987232208,.717857003211975],[.526877999305725,.704625964164734],[.526966989040375,.695277988910675],[.572058022022247,.695277988910675],[.573521018028259,.703539967536926],[.57683801651001,.711845993995667],[.581691026687622,.720062971115112],[.609944999217987,.639909982681274],[.986046016216278,.560034036636353],[.5867999792099,.69539999961853],[.590372025966644,.701822996139526],[.531915009021759,.601536989212036],[.577268004417419,.585934996604919],[.536915004253387,.593786001205444],[.627542972564697,.473352015018463],[.665585994720459,.495950996875763],[.588353991508484,.546862006187439],[.757824003696442,.14767599105835],[.709249973297119,.201507985591888],[.672684013843536,.256581008434296],[.600408971309662,.74900496006012],[.55826598405838,.261672019958496],[.570303976535797,.187870979309082],[.588165998458862,.109044015407562],[.711045026779175,.398952007293701],[.781069993972778,.435405015945435],[.587247014045715,.398931980133057],[.742869973182678,.355445981025696],[.572156012058258,.437651991844177],[.55186802148819,.536570012569427],[.821442008018494,.457556009292603],[.752701997756958,.457181990146637],[.71375697851181,.467626988887787],[.66711300611496,.460672974586487],[.631101012229919,.447153985500336],[.6008620262146,.432473003864288],[.523481011390686,.405627012252808],[.810747981071472,.523926019668579],[.771045982837677,.348959028720856],[.509127020835876,.562718033790588],[.595292985439301,.485023975372314],[.980530977249146,.401564002037048],[.573499977588654,.420000016689301],[.602994978427887,.548687994480133],[.733529984951019,.376977026462555],[.560611009597778,.519016981124878],[.967685997486115,.644356966018677],[.580985009670258,.387160003185272],[.537728011608124,.505385041236877],[.760966002941132,.779752969741821],[.801778972148895,.831938028335571],[.892440974712372,.54076099395752],[.816350996494293,.740260004997253],[.865594983100891,.333687007427216],[.614073991775513,.883246004581451],[.508952975273132,.579437971115112],[.617941975593567,.508316040039062],[.825608015060425,.397674977779388],[.681214988231659,.39623498916626],[.656635999679565,.400596976280212],[.603900015354156,.710216999053955],[.81208598613739,.588539004325867],[.56801301240921,.944564998149872],[.681007981300354,.898285031318665],[.733752012252808,.869701027870178],[.633830010890961,.398822009563446],[.606792986392975,.39553701877594],[.589659988880157,.391062021255493],[.805015981197357,.342108011245728],[.611334979534149,.362284004688263],[.634037971496582,.355970978736877],[.656635999679565,.355356991291046],[.681214988231659,.35834002494812],[.698584973812103,.363156020641327],[.941866993904114,.319076001644135],[.698584973812103,.387449026107788],[.584177017211914,.624107003211975],[.554318010807037,.566076993942261],[.534153997898102,.62064003944397],[.711217999458313,.819975018501282],[.664629995822906,.852871000766754],[.559099972248077,.902631998062134],[.871706008911133,.791940987110138],[.591234028339386,.373893976211548],[.544341027736664,.451583981513977],[.624562978744507,.924192011356354],[.88577002286911,.615028977394104],[.551338016986847,.695277988910675],[.551980018615723,.704632043838501],[.552887976169586,.715808033943176],[.555167973041534,.730794012546539],[.569944024085999,.767035007476807],[.593203008174896,.685675978660583],[.599261999130249,.681069016456604],[.607599973678589,.677703022956848],[.631937980651855,.663500010967255],[.752032995223999,.601315021514893],[.547226011753082,.420395016670227],[.563543975353241,.359827995300293],[.583841025829315,.368713974952698],[.586614012718201,.692366003990173],[.771915018558502,.683578014373779],[.531597018241882,.352482974529266],[.588370978832245,.804440975189209],[.52079701423645,.442565023899078],[.567984998226166,.493479013442993],[.543282985687256,.819254994392395],[.655317008495331,.745514988899231],[.621008992195129,.574018001556396],[.625559985637665,.78031200170517],[.680198013782501,.570719003677368],[.64276397228241,.604337990283966],[.704662978649139,.621529996395111],[.552012026309967,.862591981887817],[.589071989059448,.508637011051178],[.685944974422455,.775357007980347],[.645735025405884,.812640011310577],[.675342977046967,.703978002071381],[.810858011245728,.646304965019226],[.72012197971344,.714666962623596],[.866151988506317,.682704985141754],[.663187026977539,.644596993923187],[.570082008838654,.466325998306274],[.544561982154846,.548375964164734],[.562758982181549,.558784961700439],[.531987011432648,.530140042304993],[.585271000862122,.335177004337311],[.622952997684479,.32277899980545],[.655896008014679,.320163011550903],[.687132000923157,.322345972061157],[.716481983661652,.333200991153717],[.758756995201111,.382786989212036],[.897013008594513,.468769013881683],[.732392013072968,.424547016620636],[.70211398601532,.433162987232208],[.66652500629425,.433866024017334],[.633504986763,.426087975502014],[.603875994682312,.416586995124817],[.579657971858978,.409945011138916],[.992439985275269,.480777025222778],[.567192018032074,.569419980049133],[.54136598110199,.478899002075195],[.526564002037048,.546118021011353],[.523913025856018,.563830018043518],[.531529009342194,.555056989192963],[.566035985946655,.582329034805298],[.51631098985672,.563053965568542],[.5174720287323,.577877044677734],[.573594987392426,.389806985855103],[.560697972774506,.395331978797913],[.549755990505219,.399751007556915],[.710287988185883,.368252992630005],[.723330020904541,.363372981548309]],oe=[127,34,139,11,0,37,232,231,120,72,37,39,128,121,47,232,121,128,104,69,67,175,171,148,157,154,155,118,50,101,73,39,40,9,151,108,48,115,131,194,204,211,74,40,185,80,42,183,40,92,186,230,229,118,202,212,214,83,18,17,76,61,146,160,29,30,56,157,173,106,204,194,135,214,192,203,165,98,21,71,68,51,45,4,144,24,23,77,146,91,205,50,187,201,200,18,91,106,182,90,91,181,85,84,17,206,203,36,148,171,140,92,40,39,193,189,244,159,158,28,247,246,161,236,3,196,54,68,104,193,168,8,117,228,31,189,193,55,98,97,99,126,47,100,166,79,218,155,154,26,209,49,131,135,136,150,47,126,217,223,52,53,45,51,134,211,170,140,67,69,108,43,106,91,230,119,120,226,130,247,63,53,52,238,20,242,46,70,156,78,62,96,46,53,63,143,34,227,173,155,133,123,117,111,44,125,19,236,134,51,216,206,205,154,153,22,39,37,167,200,201,208,36,142,100,57,212,202,20,60,99,28,158,157,35,226,113,160,159,27,204,202,210,113,225,46,43,202,204,62,76,77,137,123,116,41,38,72,203,129,142,64,98,240,49,102,64,41,73,74,212,216,207,42,74,184,169,170,211,170,149,176,105,66,69,122,6,168,123,147,187,96,77,90,65,55,107,89,90,180,101,100,120,63,105,104,93,137,227,15,86,85,129,102,49,14,87,86,55,8,9,100,47,121,145,23,22,88,89,179,6,122,196,88,95,96,138,172,136,215,58,172,115,48,219,42,80,81,195,3,51,43,146,61,171,175,199,81,82,38,53,46,225,144,163,110,246,33,7,52,65,66,229,228,117,34,127,234,107,108,69,109,108,151,48,64,235,62,78,191,129,209,126,111,35,143,163,161,246,117,123,50,222,65,52,19,125,141,221,55,65,3,195,197,25,7,33,220,237,44,70,71,139,122,193,245,247,130,33,71,21,162,153,158,159,170,169,150,188,174,196,216,186,92,144,160,161,2,97,167,141,125,241,164,167,37,72,38,12,145,159,160,38,82,13,63,68,71,226,35,111,158,153,154,101,50,205,206,92,165,209,198,217,165,167,97,220,115,218,133,112,243,239,238,241,214,135,169,190,173,133,171,208,32,125,44,237,86,87,178,85,86,179,84,85,180,83,84,181,201,83,182,137,93,132,76,62,183,61,76,184,57,61,185,212,57,186,214,207,187,34,143,156,79,239,237,123,137,177,44,1,4,201,194,32,64,102,129,213,215,138,59,166,219,242,99,97,2,94,141,75,59,235,24,110,228,25,130,226,23,24,229,22,23,230,26,22,231,112,26,232,189,190,243,221,56,190,28,56,221,27,28,222,29,27,223,30,29,224,247,30,225,238,79,20,166,59,75,60,75,240,147,177,215,20,79,166,187,147,213,112,233,244,233,128,245,128,114,188,114,217,174,131,115,220,217,198,236,198,131,134,177,132,58,143,35,124,110,163,7,228,110,25,356,389,368,11,302,267,452,350,349,302,303,269,357,343,277,452,453,357,333,332,297,175,152,377,384,398,382,347,348,330,303,304,270,9,336,337,278,279,360,418,262,431,304,408,409,310,415,407,270,409,410,450,348,347,422,430,434,313,314,17,306,307,375,387,388,260,286,414,398,335,406,418,364,367,416,423,358,327,251,284,298,281,5,4,373,374,253,307,320,321,425,427,411,421,313,18,321,405,406,320,404,405,315,16,17,426,425,266,377,400,369,322,391,269,417,465,464,386,257,258,466,260,388,456,399,419,284,332,333,417,285,8,346,340,261,413,441,285,327,460,328,355,371,329,392,439,438,382,341,256,429,420,360,364,394,379,277,343,437,443,444,283,275,440,363,431,262,369,297,338,337,273,375,321,450,451,349,446,342,467,293,334,282,458,461,462,276,353,383,308,324,325,276,300,293,372,345,447,382,398,362,352,345,340,274,1,19,456,248,281,436,427,425,381,256,252,269,391,393,200,199,428,266,330,329,287,273,422,250,462,328,258,286,384,265,353,342,387,259,257,424,431,430,342,353,276,273,335,424,292,325,307,366,447,345,271,303,302,423,266,371,294,455,460,279,278,294,271,272,304,432,434,427,272,407,408,394,430,431,395,369,400,334,333,299,351,417,168,352,280,411,325,319,320,295,296,336,319,403,404,330,348,349,293,298,333,323,454,447,15,16,315,358,429,279,14,15,316,285,336,9,329,349,350,374,380,252,318,402,403,6,197,419,318,319,325,367,364,365,435,367,397,344,438,439,272,271,311,195,5,281,273,287,291,396,428,199,311,271,268,283,444,445,373,254,339,263,466,249,282,334,296,449,347,346,264,447,454,336,296,299,338,10,151,278,439,455,292,407,415,358,371,355,340,345,372,390,249,466,346,347,280,442,443,282,19,94,370,441,442,295,248,419,197,263,255,359,440,275,274,300,383,368,351,412,465,263,467,466,301,368,389,380,374,386,395,378,379,412,351,419,436,426,322,373,390,388,2,164,393,370,462,461,164,0,267,302,11,12,374,373,387,268,12,13,293,300,301,446,261,340,385,384,381,330,266,425,426,423,391,429,355,437,391,327,326,440,457,438,341,382,362,459,457,461,434,430,394,414,463,362,396,369,262,354,461,457,316,403,402,315,404,403,314,405,404,313,406,405,421,418,406,366,401,361,306,408,407,291,409,408,287,410,409,432,436,410,434,416,411,264,368,383,309,438,457,352,376,401,274,275,4,421,428,262,294,327,358,433,416,367,289,455,439,462,370,326,2,326,370,305,460,455,254,449,448,255,261,446,253,450,449,252,451,450,256,452,451,341,453,452,413,464,463,441,413,414,258,442,441,257,443,442,259,444,443,260,445,444,467,342,445,459,458,250,289,392,290,290,328,460,376,433,435,250,290,392,411,416,433,341,463,464,453,464,465,357,465,412,343,412,399,360,363,440,437,399,456,420,456,363,401,435,288,372,383,353,339,255,249,448,261,255,133,243,190,133,155,112,33,246,247,33,130,25,398,384,286,362,398,414,362,463,341,263,359,467,263,249,255,466,467,260,75,60,166,238,239,79,162,127,139,72,11,37,121,232,120,73,72,39,114,128,47,233,232,128,103,104,67,152,175,148,173,157,155,119,118,101,74,73,40,107,9,108,49,48,131,32,194,211,184,74,185,191,80,183,185,40,186,119,230,118,210,202,214,84,83,17,77,76,146,161,160,30,190,56,173,182,106,194,138,135,192,129,203,98,54,21,68,5,51,4,145,144,23,90,77,91,207,205,187,83,201,18,181,91,182,180,90,181,16,85,17,205,206,36,176,148,140,165,92,39,245,193,244,27,159,28,30,247,161,174,236,196,103,54,104,55,193,8,111,117,31,221,189,55,240,98,99,142,126,100,219,166,218,112,155,26,198,209,131,169,135,150,114,47,217,224,223,53,220,45,134,32,211,140,109,67,108,146,43,91,231,230,120,113,226,247,105,63,52,241,238,242,124,46,156,95,78,96,70,46,63,116,143,227,116,123,111,1,44,19,3,236,51,207,216,205,26,154,22,165,39,167,199,200,208,101,36,100,43,57,202,242,20,99,56,28,157,124,35,113,29,160,27,211,204,210,124,113,46,106,43,204,96,62,77,227,137,116,73,41,72,36,203,142,235,64,240,48,49,64,42,41,74,214,212,207,183,42,184,210,169,211,140,170,176,104,105,69,193,122,168,50,123,187,89,96,90,66,65,107,179,89,180,119,101,120,68,63,104,234,93,227,16,15,85,209,129,49,15,14,86,107,55,9,120,100,121,153,145,22,178,88,179,197,6,196,89,88,96,135,138,136,138,215,172,218,115,219,41,42,81,5,195,51,57,43,61,208,171,199,41,81,38,224,53,225,24,144,110,105,52,66,118,229,117,227,34,234,66,107,69,10,109,151,219,48,235,183,62,191,142,129,126,116,111,143,7,163,246,118,117,50,223,222,52,94,19,141,222,221,65,196,3,197,45,220,44,156,70,139,188,122,245,139,71,162,145,153,159,149,170,150,122,188,196,206,216,92,163,144,161,164,2,167,242,141,241,0,164,37,11,72,12,144,145,160,12,38,13,70,63,71,31,226,111,157,158,154,36,101,205,203,206,165,126,209,217,98,165,97,237,220,218,237,239,241,210,214,169,140,171,32,241,125,237,179,86,178,180,85,179,181,84,180,182,83,181,194,201,182,177,137,132,184,76,183,185,61,184,186,57,185,216,212,186,192,214,187,139,34,156,218,79,237,147,123,177,45,44,4,208,201,32,98,64,129,192,213,138,235,59,219,141,242,97,97,2,141,240,75,235,229,24,228,31,25,226,230,23,229,231,22,230,232,26,231,233,112,232,244,189,243,189,221,190,222,28,221,223,27,222,224,29,223,225,30,224,113,247,225,99,60,240,213,147,215,60,20,166,192,187,213,243,112,244,244,233,245,245,128,188,188,114,174,134,131,220,174,217,236,236,198,134,215,177,58,156,143,124,25,110,7,31,228,25,264,356,368,0,11,267,451,452,349,267,302,269,350,357,277,350,452,357,299,333,297,396,175,377,381,384,382,280,347,330,269,303,270,151,9,337,344,278,360,424,418,431,270,304,409,272,310,407,322,270,410,449,450,347,432,422,434,18,313,17,291,306,375,259,387,260,424,335,418,434,364,416,391,423,327,301,251,298,275,281,4,254,373,253,375,307,321,280,425,411,200,421,18,335,321,406,321,320,405,314,315,17,423,426,266,396,377,369,270,322,269,413,417,464,385,386,258,248,456,419,298,284,333,168,417,8,448,346,261,417,413,285,326,327,328,277,355,329,309,392,438,381,382,256,279,429,360,365,364,379,355,277,437,282,443,283,281,275,363,395,431,369,299,297,337,335,273,321,348,450,349,359,446,467,283,293,282,250,458,462,300,276,383,292,308,325,283,276,293,264,372,447,346,352,340,354,274,19,363,456,281,426,436,425,380,381,252,267,269,393,421,200,428,371,266,329,432,287,422,290,250,328,385,258,384,446,265,342,386,387,257,422,424,430,445,342,276,422,273,424,306,292,307,352,366,345,268,271,302,358,423,371,327,294,460,331,279,294,303,271,304,436,432,427,304,272,408,395,394,431,378,395,400,296,334,299,6,351,168,376,352,411,307,325,320,285,295,336,320,319,404,329,330,349,334,293,333,366,323,447,316,15,315,331,358,279,317,14,316,8,285,9,277,329,350,253,374,252,319,318,403,351,6,419,324,318,325,397,367,365,288,435,397,278,344,439,310,272,311,248,195,281,375,273,291,175,396,199,312,311,268,276,283,445,390,373,339,295,282,296,448,449,346,356,264,454,337,336,299,337,338,151,294,278,455,308,292,415,429,358,355,265,340,372,388,390,466,352,346,280,295,442,282,354,19,370,285,441,295,195,248,197,457,440,274,301,300,368,417,351,465,251,301,389,385,380,386,394,395,379,399,412,419,410,436,322,387,373,388,326,2,393,354,370,461,393,164,267,268,302,12,386,374,387,312,268,13,298,293,301,265,446,340,380,385,381,280,330,425,322,426,391,420,429,437,393,391,326,344,440,438,458,459,461,364,434,394,428,396,262,274,354,457,317,316,402,316,315,403,315,314,404,314,313,405,313,421,406,323,366,361,292,306,407,306,291,408,291,287,409,287,432,410,427,434,411,372,264,383,459,309,457,366,352,401,1,274,4,418,421,262,331,294,358,435,433,367,392,289,439,328,462,326,94,2,370,289,305,455,339,254,448,359,255,446,254,253,449,253,252,450,252,256,451,256,341,452,414,413,463,286,441,414,286,258,441,258,257,442,257,259,443,259,260,444,260,467,445,309,459,250,305,289,290,305,290,460,401,376,435,309,250,392,376,411,433,453,341,464,357,453,465,343,357,412,437,343,399,344,360,440,420,437,456,360,420,363,361,401,288,265,372,353,390,339,249,339,448,255];var Or=[127,234,132,58,172,150,149,148,152,377,378,379,397,288,361,454,356,70,63,105,66,107,336,296,334,293,300,168,6,195,4,98,97,2,326,327,33,160,158,133,153,144,362,385,387,263,373,380,57,40,37,0,267,270,287,321,314,17,84,91,78,81,13,311,308,402,14,178],Ir=[33,133,362,263,1,62,308,159,145,386,374,6,102,331,2,13,14,70,105,107,336,334,300,54,10,284,50,280,234,454,58,288,152],Lr=[33,133,362,263,1,78,308],zs=Or.map(e=>Ze[e]),js=Ir.map(e=>Ze[e]),Ss=Lr.map(e=>Ze[e]);var me=e=>[Math.abs(e.endPoint[0]-e.startPoint[0]),Math.abs(e.endPoint[1]-e.startPoint[1])],st=e=>[e.startPoint[0]+(e.endPoint[0]-e.startPoint[0])/2,e.startPoint[1]+(e.endPoint[1]-e.startPoint[1])/2,1],l5=(e,t)=>e?[Math.trunc(Math.max(0,e.startPoint[0])),Math.trunc(Math.max(0,e.startPoint[1])),Math.trunc(Math.min(t.shape[2]||0,e.endPoint[0])-Math.max(0,e.startPoint[0])),Math.trunc(Math.min(t.shape[1]||0,e.endPoint[1])-Math.max(0,e.startPoint[1]))]:[0,0,0,0],y5=(e,t)=>e?[e.startPoint[0]/(t.shape[2]||0),e.startPoint[1]/(t.shape[1]||0),(e.endPoint[0]-e.startPoint[0])/(t.shape[2]||0),(e.endPoint[1]-e.startPoint[1])/(t.shape[1]||0)]:[0,0,0,0],nn=(e,t)=>{let o=[e.startPoint[0]*t[0],e.startPoint[1]*t[1]],n=[e.endPoint[0]*t[0],e.endPoint[1]*t[1]];return{startPoint:o,endPoint:n,landmarks:e.landmarks,confidence:e.confidence}},a5=(e,t,o)=>{let n=t.shape[1],A=t.shape[2],s=[e.startPoint[1]/n,e.startPoint[0]/A,e.endPoint[1]/n,e.endPoint[0]/A],a=r.image.cropAndResize(t,[s],[0],o),i=r.div(a,N.tf255);return r.dispose(a),i},at=(e,t)=>{let o=st(e),n=me(e),A=[t*n[0]/2,t*n[1]/2];return{startPoint:[o[0]-A[0],o[1]-A[1]],endPoint:[o[0]+A[0],o[1]+A[1]],landmarks:e.landmarks,confidence:e.confidence}},it=e=>{let t=st(e),o=me(e),n=Math.max(...o)/2;return{startPoint:[Math.round(t[0]-n),Math.round(t[1]-n)],endPoint:[Math.round(t[0]+n),Math.round(t[1]+n)],landmarks:e.landmarks,confidence:e.confidence}},An=e=>{let t=e.map(n=>n[0]),o=e.map(n=>n[1]);return{startPoint:[Math.min(...t),Math.min(...o)],endPoint:[Math.max(...t),Math.max(...o)],landmarks:e}},i5=[[1,0,0],[0,1,0],[0,0,1]],Nr=e=>e-2*Math.PI*Math.floor((e+Math.PI)/(2*Math.PI)),Gr=(e,t)=>Nr(Math.PI/2-Math.atan2(-(t[1]-e[1]),t[0]-e[0]));var tn=(e,t)=>[[1,0,e],[0,1,t],[0,0,1]],ne=(e,t)=>{let o=0;for(let n=0;n{let o=[];for(let n=0;n{let o=[],n=e.length;for(let A=0;A{let o=Math.cos(e),n=Math.sin(e),A=[[o,-n,0],[n,o,0],[0,0,1]],s=tn(t[0],t[1]),a=on(s,A),i=tn(-t[0],-t[1]);return on(a,i)},Fr=e=>{let t=[[e[0][0],e[1][0]],[e[0][1],e[1][1]]],o=[e[0][2],e[1][2]],n=[-ne(t[0],o),-ne(t[1],o)];return[t[0].concat(n[0]),t[1].concat(n[1]),[0,0,1]]},Hr=(e,t)=>[ne(e,t[0]),ne(e,t[1])];function sn(e){let t={strides:[e/16,e/8],anchors:[2,6]},o=[];for(let n=0;n[s[0]/A*(f[0]-A/2),s[1]/A*(f[1]-A/2),f[2]||0]),i=o&&o!==0&&Math.abs(o)>.2,x=i?rn(o,[0,0]):i5,d=i?a.map(f=>[...Hr(f,x),f[2]]):a,l=i?Fr(n):i5,y=st(t),c=[ne(y,l[0]),ne(y,l[1])];return d.map(f=>[Math.trunc(f[0]+c[0]),Math.trunc(f[1]+c[1]),Math.trunc(f[2]||0)])}function ln(e,t,o,n){let A=t.landmarks.length>=A5.count?A5.symmetryLine:Ve.symmetryLine,s=0,a=i5,i;if(e&&R.kernels.includes("rotatewithoffset"))if(s=Gr(t.landmarks[A[0]],t.landmarks[A[1]]),s&&s!==0&&Math.abs(s)>.2){let d=st(t),l=[d[0]/o.shape[2],d[1]/o.shape[1]],y=r.image.rotateWithOffset(o,s,0,l);a=rn(-s,d),i=a5(t,y,[n,n]),r.dispose(y)}else i=a5(t,o,[n,n]);else i=a5(t,o,[n,n]);return[s,a,i]}var Vr=e=>{let t=e.map(n=>n[0]),o=e.map(n=>n[1]);return[Math.min(...t)+(Math.max(...t)-Math.min(...t))/2,Math.min(...o)+(Math.max(...o)-Math.min(...o))/2]},yn=(e,t)=>{let o=Vr(e),n=me(t);return{startPoint:[o[0]-n[0]/2,o[1]-n[1]/2],endPoint:[o[0]+n[0]/2,o[1]+n[1]/2]}};var xn=6,Zr=1.4,k0,cn=null,Z0=0,De=null,lt=()=>Z0;async function dn(e){var t;return R.initial&&(k0=null),k0?e.debug&&b("cached model:",k0.modelUrl):k0=await L((t=e.face.detector)==null?void 0:t.modelPath),Z0=k0.inputs[0].shape?k0.inputs[0].shape[2]:0,De=r.scalar(Z0,"int32"),cn=r.tensor2d(sn(Z0)),k0}function Dr(e){let t={};t.boxStarts=r.slice(e,[0,1],[-1,2]),t.centers=r.add(t.boxStarts,cn),t.boxSizes=r.slice(e,[0,3],[-1,2]),t.boxSizesNormalized=r.div(t.boxSizes,De),t.centersNormalized=r.div(t.centers,De),t.halfBoxSize=r.div(t.boxSizesNormalized,N.tf2),t.starts=r.sub(t.centersNormalized,t.halfBoxSize),t.ends=r.add(t.centersNormalized,t.halfBoxSize),t.startNormalized=r.mul(t.starts,De),t.endNormalized=r.mul(t.ends,De);let o=r.concat2d([t.startNormalized,t.endNormalized],1);return Object.keys(t).forEach(n=>r.dispose(t[n])),o}async function fn(e,t){var i,x,d,l;if(!e||e.isDisposedInternal||e.shape.length!==4||e.shape[1]<1||e.shape[2]<1)return[];let o={};o.resized=r.image.resizeBilinear(e,[Z0,Z0]),o.div=r.div(o.resized,N.tf127),o.normalized=r.sub(o.div,N.tf05);let n=k0==null?void 0:k0.execute(o.normalized);if(Array.isArray(n)){let y=n.sort((c,f)=>c.size-f.size);o.concat384=r.concat([y[0],y[2]],2),o.concat512=r.concat([y[1],y[3]],2),o.concat=r.concat([o.concat512,o.concat384],1),o.batch=r.squeeze(o.concat,0)}else o.batch=r.squeeze(n);r.dispose(n),o.boxes=Dr(o.batch),o.logits=r.slice(o.batch,[0,0],[-1,1]),o.sigmoid=r.sigmoid(o.logits),o.scores=r.squeeze(o.sigmoid),o.nms=await r.image.nonMaxSuppressionAsync(o.boxes,o.scores,((i=t.face.detector)==null?void 0:i.maxDetected)||0,((x=t.face.detector)==null?void 0:x.iouThreshold)||0,((d=t.face.detector)==null?void 0:d.minConfidence)||0);let A=await o.nms.array(),s=[],a=await o.scores.data();for(let y=0;y(((l=t.face.detector)==null?void 0:l.minConfidence)||0)){let f={};f.bbox=r.slice(o.boxes,[A[y],0],[1,-1]),f.slice=r.slice(o.batch,[A[y],xn-1],[1,-1]),f.squeeze=r.squeeze(f.slice),f.landmarks=r.reshape(f.squeeze,[xn,-1]);let h=await f.bbox.data(),m={startPoint:[h[0],h[1]],endPoint:[h[2],h[3]],landmarks:await f.landmarks.array(),confidence:c},v=nn(m,[(e.shape[2]||0)/Z0,(e.shape[1]||0)/Z0]),M=at(v,t.face.scale||Zr),u=it(M);s.push(u),Object.keys(f).forEach(p=>r.dispose(f[p]))}}return Object.keys(o).forEach(y=>r.dispose(o[y])),s}var yt={};ee(yt,{connected:()=>d5,kpt:()=>c5});var c5=["nose","leftEyeInside","leftEye","leftEyeOutside","rightEyeInside","rightEye","rightEyeOutside","leftEar","rightEar","leftMouth","rightMouth","leftShoulder","rightShoulder","leftElbow","rightElbow","leftWrist","rightWrist","leftPinky","rightPinky","leftIndex","rightIndex","leftThumb","rightThumb","leftHip","rightHip","leftKnee","rightKnee","leftAnkle","rightAnkle","leftHeel","rightHeel","leftFoot","rightFoot","bodyCenter","bodyTop","leftPalm","leftHand","rightPalm","rightHand"],d5={shoulders:["leftShoulder","rightShoulder"],hips:["rightHip","leftHip"],mouth:["leftMouth","rightMouth"],leftLegUpper:["leftHip","leftKnee"],leftLegLower:["leftKnee","leftAnkle"],leftFoot:["leftAnkle","leftHeel","leftFoot"],leftTorso:["leftShoulder","leftHip"],leftArmUpper:["leftShoulder","leftElbow"],leftArmLower:["leftElbow","leftWrist"],leftHand:["leftWrist","leftPalm"],leftHandPinky:["leftPalm","leftPinky"],leftHandIndex:["leftPalm","leftIndex"],leftHandThumb:["leftPalm","leftThumb"],leftEyeOutline:["leftEyeInside","leftEyeOutside"],rightLegUpper:["rightHip","rightKnee"],rightLegLower:["rightKnee","rightAnkle"],rightFoot:["rightAnkle","rightHeel","rightFoot"],rightTorso:["rightShoulder","rightHip"],rightArmUpper:["rightShoulder","rightElbow"],rightArmLower:["rightElbow","rightWrist"],rightHand:["rightWrist","rightPalm"],rightHandPinky:["rightPalm","rightPinky"],rightHandIndex:["rightPalm","rightIndex"],rightHandThumb:["rightPalm","rightThumb"],rightEyeOutline:["rightEyeInside","rightEyeOutside"]};var pn=224,Xr,qr=5,xt=[8,16,32,32,32];async function un(){let e=[],t=0;for(;to.x)),y:r.tensor1d(e.map(o=>o.y))}}function N0(e,t=[1,1]){let o=[e.map(i=>i[0]),e.map(i=>i[1])],n=[Math.min(...o[0]),Math.min(...o[1])],A=[Math.max(...o[0]),Math.max(...o[1])],s=[n[0],n[1],A[0]-n[0],A[1]-n[1]],a=[s[0]/t[0],s[1]/t[1],s[2]/t[0],s[3]/t[1]];return{box:s,boxRaw:a}}function hn(e,t=[1,1]){let o=[e.map(d=>d[0]),e.map(d=>d[1])],n=[Math.min(...o[0]),Math.min(...o[1])],A=[Math.max(...o[0]),Math.max(...o[1])],s=[(n[0]+A[0])/2,(n[1]+A[1])/2],a=Math.max(s[0]-n[0],s[1]-n[1],-s[0]+A[0],-s[1]+A[1]),i=[Math.trunc(s[0]-a),Math.trunc(s[1]-a),Math.trunc(2*a),Math.trunc(2*a)],x=[i[0]/t[0],i[1]/t[1],i[2]/t[0],i[3]/t[1]];return{box:i,boxRaw:x}}function ct(e,t){let o=[e[2]*t,e[3]*t];return[e[0]-(o[0]-e[2])/2,e[1]-(o[1]-e[3])/2,o[0],o[1]]}var Mn={initial:!0},x0={detector:null,landmarks:null},pe={detector:[224,224],landmarks:[256,256]},f5=Number.MAX_SAFE_INTEGER,Jr={landmarks:["ld_3d","activation_segmentation","activation_heatmap","world_3d","output_poseflag"],detector:[]},ft=null,Xe,D0=[[0,0],[0,0],[0,0],[0,0]],bn=0,gn=e=>1-1/(1+Math.exp(e));async function Pn(e){if(Mn.initial&&(x0.detector=null),!x0.detector&&e.body.detector&&e.body.detector.modelPath){x0.detector=await L(e.body.detector.modelPath);let t=Object.values(x0.detector.modelSignature.inputs);pe.detector[0]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[1].size):0,pe.detector[1]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}else e.debug&&x0.detector&&b("cached model:",x0.detector.modelUrl);return await un(),x0.detector}async function vn(e){if(Mn.initial&&(x0.landmarks=null),x0.landmarks)e.debug&&b("cached model:",x0.landmarks.modelUrl);else{x0.landmarks=await L(e.body.modelPath);let t=Object.values(x0.landmarks.modelSignature.inputs);pe.landmarks[0]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[1].size):0,pe.landmarks[1]=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}return x0.landmarks}async function Yr(e,t){let o={};if(!e.shape||!e.shape[1]||!e.shape[2])return e;let n;if(Xe&&(o.cropped=r.image.cropAndResize(e,[Xe],[0],[e.shape[1],e.shape[2]])),e.shape[1]!==e.shape[2]){let A=[e.shape[2]>e.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0,e.shape[2]>e.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0],s=[e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0,e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0];D0=[[0,0],A,s,[0,0]],o.pad=r.pad(o.cropped||e,D0),o.resize=r.image.resizeBilinear(o.pad,[t,t]),n=r.div(o.resize,N.tf255)}else e.shape[1]!==t?(o.resize=r.image.resizeBilinear(o.cropped||e,[t,t]),n=r.div(o.resize,N.tf255)):n=r.div(o.cropped||e,N.tf255);return Object.keys(o).forEach(A=>r.dispose(o[A])),n}function Kr(e,t){for(let o of e)o.position=[Math.trunc(o.position[0]*(t[0]+D0[2][0]+D0[2][1])/t[0]-D0[2][0]),Math.trunc(o.position[1]*(t[1]+D0[1][0]+D0[1][1])/t[1]-D0[1][0]),o.position[2]],o.positionRaw=[o.position[0]/t[0],o.position[1]/t[1],2*o.position[2]/(t[0]+t[1])];if(Xe)for(let o of e)o.positionRaw=[o.positionRaw[0]+Xe[1],o.positionRaw[1]+Xe[0],o.positionRaw[2]],o.position=[Math.trunc(o.positionRaw[0]*t[0]),Math.trunc(o.positionRaw[1]*t[1]),o.positionRaw[2]];return e}async function Qr(e){let t=e.find(i=>i.part==="leftPalm"),o=e.find(i=>i.part==="leftWrist"),n=e.find(i=>i.part==="leftIndex");t.position[2]=((o.position[2]||0)+(n.position[2]||0))/2;let A=e.find(i=>i.part==="rightPalm"),s=e.find(i=>i.part==="rightWrist"),a=e.find(i=>i.part==="rightIndex");A.position[2]=((s.position[2]||0)+(a.position[2]||0))/2}async function _r(e,t,o){var h;let n={};[n.ld,n.segmentation,n.heatmap,n.world,n.poseflag]=(h=x0.landmarks)==null?void 0:h.execute(e,Jr.landmarks);let A=(await n.poseflag.data())[0],s=await n.ld.data(),a=await n.world.data();Object.keys(n).forEach(m=>r.dispose(n[m]));let i=[],x=5;for(let m=0;mm.position),y=N0(l,[o[0],o[1]]),c={};for(let[m,v]of Object.entries(d5)){let M=[];for(let u=0;uw.part===v[u]),P=d.find(w=>w.part===v[u+1]);p&&P&&M.push([p.position,P.position])}c[m]=M}return{id:0,score:Math.trunc(100*A)/100,box:y.box,boxRaw:y.boxRaw,keypoints:d,annotations:c}}async function m5(e,t){let o=[e.shape[2]||0,e.shape[1]||0],n=(t.body.skipTime||0)>g()-bn,A=f5<(t.body.skipFrames||0);if(t.skipAllowed&&n&&A&&ft!==null)f5++;else{let s={};s.landmarks=await Yr(e,256),ft=await _r(s.landmarks,t,o),Object.keys(s).forEach(a=>r.dispose(s[a])),bn=g(),f5=0}return ft?[ft]:[]}var ue=[{class:1,label:"person"},{class:2,label:"bicycle"},{class:3,label:"car"},{class:4,label:"motorcycle"},{class:5,label:"airplane"},{class:6,label:"bus"},{class:7,label:"train"},{class:8,label:"truck"},{class:9,label:"boat"},{class:10,label:"traffic light"},{class:11,label:"fire hydrant"},{class:12,label:"stop sign"},{class:13,label:"parking meter"},{class:14,label:"bench"},{class:15,label:"bird"},{class:16,label:"cat"},{class:17,label:"dog"},{class:18,label:"horse"},{class:19,label:"sheep"},{class:20,label:"cow"},{class:21,label:"elephant"},{class:22,label:"bear"},{class:23,label:"zebra"},{class:24,label:"giraffe"},{class:25,label:"backpack"},{class:26,label:"umbrella"},{class:27,label:"handbag"},{class:28,label:"tie"},{class:29,label:"suitcase"},{class:30,label:"frisbee"},{class:31,label:"skis"},{class:32,label:"snowboard"},{class:33,label:"sports ball"},{class:34,label:"kite"},{class:35,label:"baseball bat"},{class:36,label:"baseball glove"},{class:37,label:"skateboard"},{class:38,label:"surfboard"},{class:39,label:"tennis racket"},{class:40,label:"bottle"},{class:41,label:"wine glass"},{class:42,label:"cup"},{class:43,label:"fork"},{class:44,label:"knife"},{class:45,label:"spoon"},{class:46,label:"bowl"},{class:47,label:"banana"},{class:48,label:"apple"},{class:49,label:"sandwich"},{class:50,label:"orange"},{class:51,label:"broccoli"},{class:52,label:"carrot"},{class:53,label:"hot dog"},{class:54,label:"pizza"},{class:55,label:"donut"},{class:56,label:"cake"},{class:57,label:"chair"},{class:58,label:"couch"},{class:59,label:"potted plant"},{class:60,label:"bed"},{class:61,label:"dining table"},{class:62,label:"toilet"},{class:63,label:"tv"},{class:64,label:"laptop"},{class:65,label:"mouse"},{class:66,label:"remote"},{class:67,label:"keyboard"},{class:68,label:"cell phone"},{class:69,label:"microwave"},{class:70,label:"oven"},{class:71,label:"toaster"},{class:72,label:"sink"},{class:73,label:"refrigerator"},{class:74,label:"book"},{class:75,label:"clock"},{class:76,label:"vase"},{class:77,label:"scissors"},{class:78,label:"teddy bear"},{class:79,label:"hair drier"},{class:80,label:"toothbrush"}];var G0,Ae=0,p5=[],Rn=0,u5=Number.MAX_SAFE_INTEGER;async function wn(e){if(R.initial&&(G0=null),G0)e.debug&&b("cached model:",G0.modelUrl);else{G0=await L(e.object.modelPath);let t=Object.values(G0.modelSignature.inputs);Ae=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}return G0}async function $r(e,t,o){if(!e)return[];let n={},A=[],s=await e.array();n.squeeze=r.squeeze(e);let a=r.split(n.squeeze,6,1);n.stack=r.stack([a[1],a[0],a[3],a[2]],1),n.boxes=r.squeeze(n.stack),n.scores=r.squeeze(a[4]),n.classes=r.squeeze(a[5]),r.dispose([e,...a]),n.nms=await r.image.nonMaxSuppressionAsync(n.boxes,n.scores,o.object.maxDetected,o.object.iouThreshold,o.object.minConfidence||0);let i=await n.nms.data(),x=0;for(let d of Array.from(i)){let l=Math.trunc(100*s[0][d][4])/100,y=s[0][d][5],c=ue[y].label,[f,h]=[s[0][d][0]/Ae,s[0][d][1]/Ae],m=[f,h,s[0][d][2]/Ae-f,s[0][d][3]/Ae-h],v=[Math.trunc(m[0]*t[0]),Math.trunc(m[1]*t[1]),Math.trunc(m[2]*t[0]),Math.trunc(m[3]*t[1])];A.push({id:x++,score:l,class:y,label:c,box:v,boxRaw:m})}return Object.keys(n).forEach(d=>r.dispose(n[d])),A}async function h5(e,t){let o=(t.object.skipTime||0)>g()-Rn,n=u5<(t.object.skipFrames||0);return t.skipAllowed&&o&&n&&p5.length>0?(u5++,p5):(u5=0,new Promise(async A=>{let s=[e.shape[2]||0,e.shape[1]||0],a=r.image.resizeBilinear(e,[Ae,Ae]),i=t.object.enabled?G0==null?void 0:G0.execute(a,["tower_0/detections"]):null;Rn=g(),r.dispose(a);let x=await $r(i,s,t);p5=x,A(x)}))}var mt={};ee(mt,{connected:()=>g5,kpt:()=>b5});var b5=["head","neck","rightShoulder","rightElbow","rightWrist","chest","leftShoulder","leftElbow","leftWrist","bodyCenter","rightHip","rightKnee","rightAnkle","leftHip","leftKnee","leftAnkle"],g5={leftLeg:["leftHip","leftKnee","leftAnkle"],rightLeg:["rightHip","rightKnee","rightAnkle"],torso:["leftShoulder","rightShoulder","rightHip","leftHip","leftShoulder"],leftArm:["leftShoulder","leftElbow","leftWrist"],rightArm:["rightShoulder","rightElbow","rightWrist"],head:[]};var r0,En=0,i0={id:0,keypoints:[],box:[0,0,0,0],boxRaw:[0,0,0,0],score:0,annotations:{}},M5=Number.MAX_SAFE_INTEGER;async function zn(e){return R.initial&&(r0=null),r0?e.debug&&b("cached model:",r0.modelUrl):r0=await L(e.body.modelPath),r0}async function e2(e,t){let[o,n]=e.shape,A=r.reshape(e,[n*o]),s=r.max(A,0),a=(await s.data())[0];if(r.dispose([A,s]),a>t){let i=r.argMax(A,0),x=r.mod(i,o),d=(await x.data())[0],l=r.div(i,r.scalar(o,"int32")),y=(await l.data())[0];return r.dispose([x,l]),[d,y,a]}return[0,0,a]}async function P5(e,t){let o=(t.body.skipTime||0)>g()-En,n=M5<(t.body.skipFrames||0);return t.skipAllowed&&o&&n&&Object.keys(i0.keypoints).length>0?(M5++,[i0]):(M5=0,new Promise(async A=>{var y;let s=r.tidy(()=>{if(!(r0!=null&&r0.inputs[0].shape))return null;let c=r.image.resizeBilinear(e,[r0.inputs[0].shape[2],r0.inputs[0].shape[1]],!1),f=r.mul(c,N.tf2);return r.sub(f,N.tf1)}),a;if(t.body.enabled&&(a=r0==null?void 0:r0.execute(s)),En=g(),r.dispose(s),a){i0.keypoints.length=0;let c=a.squeeze();r.dispose(a);let f=c.unstack(2);r.dispose(c);for(let h=0;h(((y=t.body)==null?void 0:y.minConfidence)||0)&&i0.keypoints.push({score:Math.round(100*M)/100,part:b5[h],positionRaw:[m/r0.inputs[0].shape[2],v/r0.inputs[0].shape[1]],position:[Math.round(e.shape[2]*m/r0.inputs[0].shape[2]),Math.round(e.shape[1]*v/r0.inputs[0].shape[1])]})}f.forEach(h=>r.dispose(h))}i0.score=i0.keypoints.reduce((c,f)=>f.score>c?f.score:c,0);let i=i0.keypoints.map(c=>c.position[0]),x=i0.keypoints.map(c=>c.position[1]);i0.box=[Math.min(...i),Math.min(...x),Math.max(...i)-Math.min(...i),Math.max(...x)-Math.min(...x)];let d=i0.keypoints.map(c=>c.positionRaw[0]),l=i0.keypoints.map(c=>c.positionRaw[1]);i0.boxRaw=[Math.min(...d),Math.min(...l),Math.max(...d)-Math.min(...d),Math.max(...l)-Math.min(...l)];for(let[c,f]of Object.entries(g5)){let h=[];for(let m=0;mu.part===f[m]),M=i0.keypoints.find(u=>u.part===f[m+1]);v&&M&&v.score>(t.body.minConfidence||0)&&M.score>(t.body.minConfidence||0)&&h.push([v.position,M.position])}i0.annotations[c]=h}A([i0])}))}var t2=["angry","disgust","fear","happy","sad","surprise","neutral"],u0,pt=[],Sn=0,Wn=0,v5=Number.MAX_SAFE_INTEGER;async function Cn(e){var t;return R.initial&&(u0=null),u0?e.debug&&b("cached model:",u0.modelUrl):u0=await L((t=e.face.emotion)==null?void 0:t.modelPath),u0}async function T5(e,t,o,n){var a,i;if(!u0)return[];let A=v5<(((a=t.face.emotion)==null?void 0:a.skipFrames)||0),s=(((i=t.face.emotion)==null?void 0:i.skipTime)||0)>g()-Wn;return t.skipAllowed&&s&&A&&Sn===n&&pt[o]&&pt[o].length>0?(v5++,pt[o]):(v5=0,new Promise(async x=>{var l,y;let d=[];if((l=t.face.emotion)!=null&&l.enabled){let c={},f=u0!=null&&u0.inputs[0].shape?u0.inputs[0].shape[2]:0;c.resize=r.image.resizeBilinear(e,[f,f],!1),c.channels=r.mul(c.resize,N.rgb),c.grayscale=r.sum(c.channels,3,!0),c.grayscaleSub=r.sub(c.grayscale,N.tf05),c.grayscaleMul=r.mul(c.grayscaleSub,N.tf2),c.emotion=u0==null?void 0:u0.execute(c.grayscaleMul),Wn=g();let h=await c.emotion.data();for(let m=0;m(((y=t.face.emotion)==null?void 0:y.minConfidence)||0)&&d.push({score:Math.min(.99,Math.trunc(100*h[m])/100),emotion:t2[m]});d.sort((m,v)=>v.score-m.score),Object.keys(c).forEach(m=>r.dispose(c[m]))}pt[o]=d,Sn=n,x(d)}))}var c0,R5=[],In=0,Ln=0,Nn=Number.MAX_SAFE_INTEGER;async function Gn(e){return R.initial&&(c0=null),c0?e.debug&&b("cached model:",c0.modelUrl):c0=await L(e.face.mobilefacenet.modelPath),c0}async function w5(e,t,o,n){var a,i;if(!c0)return[];let A=Nn<(((a=t.face.embedding)==null?void 0:a.skipFrames)||0),s=(((i=t.face.embedding)==null?void 0:i.skipTime)||0)>g()-Ln;return t.skipAllowed&&s&&A&&In===n&&R5[o]?(Nn++,R5[o]):new Promise(async x=>{var l;let d=[];if(((l=t.face.embedding)==null?void 0:l.enabled)&&(c0==null?void 0:c0.inputs[0].shape)){let y={};y.crop=r.image.resizeBilinear(e,[c0.inputs[0].shape[2],c0.inputs[0].shape[1]],!1),y.data=c0==null?void 0:c0.execute(y.crop);let c=await y.data.data();d=Array.from(c)}R5[o]=d,In=n,Ln=g(),x(d)})}var B0,X0=0,o2=2.3,k5=M0.leftEyeLower0,E5=M0.rightEyeLower0,he={leftBounds:[k5[0],k5[k5.length-1]],rightBounds:[E5[0],E5[E5.length-1]]},be={upperCenter:3,lowerCenter:4,index:71,numCoordinates:76};async function Zn(e){var t;return R.initial&&(B0=null),B0?e.debug&&b("cached model:",B0.modelUrl):B0=await L((t=e.face.iris)==null?void 0:t.modelPath),X0=B0.inputs[0].shape?B0.inputs[0].shape[2]:0,X0===-1&&(X0=64),B0}function ut(e,t,o,n){for(let A=0;A{let t=e[he.leftBounds[0]][2],o=e[he.rightBounds[0]][2];return t-o},Fn=(e,t,o,n,A,s=!1)=>{let a=it(at(An([e[o],e[n]]),o2)),i=me(a),x=r.image.cropAndResize(t,[[a.startPoint[1]/A,a.startPoint[0]/A,a.endPoint[1]/A,a.endPoint[0]/A]],[0],[X0,X0]);if(s&&R.kernels.includes("flipleftright")){let d=r.image.flipLeftRight(x);r.dispose(x),x=d}return{box:a,boxSize:i,crop:x}},Hn=(e,t,o,n=!1)=>{let A=[];for(let s=0;s{let n=e[M0[`${o}EyeUpper0`][be.upperCenter]][2],A=e[M0[`${o}EyeLower0`][be.lowerCenter]][2],s=(n+A)/2;return t.map((a,i)=>{let x=s;return i===2?x=n:i===4&&(x=A),[a[0],a[1],x]})};async function Dn(e,t,o,n){if(!B0)return o.debug&&b("face mesh iris detection requested, but model is not loaded"),e;let{box:A,boxSize:s,crop:a}=Fn(e,t,he.leftBounds[0],he.leftBounds[1],n,!0),{box:i,boxSize:x,crop:d}=Fn(e,t,he.rightBounds[0],he.rightBounds[1],n,!0),l=r.concat([a,d]);r.dispose(a),r.dispose(d);let y=B0.execute(l);r.dispose(l);let c=await y.data();r.dispose(y);let f=c.slice(0,be.numCoordinates*3),{rawCoords:h,iris:m}=Hn(f,A,s,!0),v=c.slice(be.numCoordinates*3),{rawCoords:M,iris:u}=Hn(v,i,x,!1),p=n2(e);Math.abs(p)<30?(ut(e,h,"left",null),ut(e,M,"right",null)):p<1?ut(e,h,"left",["EyeUpper0","EyeLower0"]):ut(e,M,"right",["EyeUpper0","EyeLower0"]);let P=Vn(e,m,"left"),w=Vn(e,u,"right");return e.concat(P).concat(w)}var q0={eyeLLower:[33,7,163,144,145,153,154,155,133],eyeRLower:[263,249,390,373,374,380,381,382,362],lips:[61,76,91,181,84,17,314,405,321,291,291,185,40,39,37,0,267,269,270,291,62,183,88,178,87,14,268,303,304,408,291,184,42,178,87,14,268,303,304,408,61,62,90,180,85,16,315,404,307,308,291,185,40,73,72,0,302,269,270,409,61,184,95,179,86,15,316,403,324,408,291,184,74,41,38,11,268,303,304,408],eyeL:[33,7,163,144,145,153,154,155,133,246,161,160,159,158,157,173,130,25,110,24,23,22,26,112,243,247,30,29,27,28,56,190,226,31,228,229,230,231,232,233,244,113,225,224,223,222,221,189,35,124,46,53,52,65,143,111,117,118,119,120,121,128,245,156,70,63,105,66,107,55,193],eyeR:[263,249,390,373,374,380,381,382,362,466,388,387,386,385,384,398,359,255,339,254,253,252,256,341,463,467,260,259,257,258,286,414,446,261,448,449,450,451,452,453,464,342,445,444,443,442,441,413,265,353,276,283,282,295,372,340,346,347,348,349,350,357,465,383,300,293,334,296,336,285,417]};async function qn(e,t){let o={irisL:t[3].dataSync(),irisR:t[1].dataSync(),eyeL:t[0].dataSync(),eyeR:t[6].dataSync(),lips:t[5].dataSync()},n=q0.eyeRLower.reduce((s,a)=>s+=e[a][2],0)/q0.eyeRLower.length;for(let s=0;ss+=e[a][2],0)/q0.eyeLLower.length;for(let s=0;sg()-E0.timestamp,n=E0.skipped<(((x=t.face.detector)==null?void 0:x.skipFrames)||0);!t.skipAllowed||!o||!n||E0.boxes.length===0?(E0.boxes=await fn(e,t),E0.timestamp=g(),E0.skipped=0):E0.skipped++;let A=[],s=[],a=0;for(let M=0;MB.shape[B.shape.length-1]===1),W=S.find(B=>B.shape[B.shape.length-1]===1404),I=await O.data();w.faceScore=Math.round(100*I[0])/100;let V=r.reshape(W,[-1,3]),G=await V.array();if(w.faceScore<(((f=t.face.detector)==null?void 0:f.minConfidence)||1))u.confidence=w.faceScore;else{(h=t.face.attention)!=null&&h.enabled?G=await qn(G,S):(m=t.face.iris)!=null&&m.enabled&&(G=await Dn(G,w.tensor,t,ge)),w.mesh=an(G,u,p,P,ge),w.meshRaw=w.mesh.map(J=>[J[0]/(e.shape[2]||0),J[1]/(e.shape[1]||0),(J[2]||0)/ge]);for(let J of Object.keys(M0))w.annotations[J]=M0[J].map(z=>w.mesh[z]);w.score=w.faceScore;let B={...yn(w.mesh,u),confidence:u.confidence,landmarks:u.landmarks};w.box=l5(B,e),w.boxRaw=y5(B,e),s.push(B)}r.dispose([...S,V])}else{w.box=l5(u,e),w.boxRaw=y5(u,e),w.score=w.boxScore,w.mesh=u.landmarks.map(S=>[(u.startPoint[0]+u.endPoint[0])/2+(u.endPoint[0]+u.startPoint[0])*S[0]/lt(),(u.startPoint[1]+u.endPoint[1])/2+(u.endPoint[1]+u.startPoint[1])*S[1]/lt()]),w.meshRaw=w.mesh.map(S=>[S[0]/(e.shape[2]||0),S[1]/(e.shape[1]||0),(S[2]||0)/ge]);for(let S of Object.keys(Ve))w.annotations[S]=[w.mesh[Ve[S]]]}w.score>(((v=t.face.detector)==null?void 0:v.minConfidence)||1)?A.push(w):r.dispose(w.tensor)}return E0.boxes=s,A}async function Jn(e){var t,o,n;return R.initial&&(z0=null),z0?e.debug&&b("cached model:",z0.modelUrl):(t=e.face.attention)!=null&&t.enabled?z0=await L((o=e.face.attention)==null?void 0:o.modelPath):z0=await L((n=e.face.mesh)==null?void 0:n.modelPath),ge=z0.inputs[0].shape?z0.inputs[0].shape[2]:0,z0}var Yn=oe,Kn=Ze;var d0,ht=[],Qn=0,_n=0,j5=Number.MAX_SAFE_INTEGER;async function $n(e){var t;return R.initial&&(d0=null),d0?e.debug&&b("cached model:",d0.modelUrl):d0=await L((t=e.face.description)==null?void 0:t.modelPath),d0}function S5(e){let t=e.image||e.tensor||e;if(!(d0!=null&&d0.inputs[0].shape))return t;let o=r.image.resizeBilinear(t,[d0.inputs[0].shape[2],d0.inputs[0].shape[1]],!1),n=r.mul(o,N.tf255);return r.dispose(o),n}async function W5(e,t,o,n){var a,i,x,d;if(!d0)return{age:0,gender:"unknown",genderScore:0,descriptor:[]};let A=j5<(((a=t.face.description)==null?void 0:a.skipFrames)||0),s=(((i=t.face.description)==null?void 0:i.skipTime)||0)>g()-Qn;return t.skipAllowed&&A&&s&&_n===n&&((x=ht[o])==null?void 0:x.age)&&((d=ht[o])==null?void 0:d.age)>0?(j5++,ht[o]):(j5=0,new Promise(async l=>{var c,f;let y={age:0,gender:"unknown",genderScore:0,descriptor:[]};if((c=t.face.description)!=null&&c.enabled){let h=S5(e),m=d0==null?void 0:d0.execute(h);Qn=g(),r.dispose(h);let M=await(await m.find(I=>I.shape[1]===1)).data(),u=Math.trunc(200*Math.abs(M[0]-.5))/100;u>(((f=t.face.description)==null?void 0:f.minConfidence)||0)&&(y.gender=M[0]<=.5?"female":"male",y.genderScore=Math.min(.99,u));let p=r.argMax(m.find(I=>I.shape[1]===100),1),P=(await p.data())[0];r.dispose(p);let S=await m.find(I=>I.shape[1]===100).data();y.age=Math.round(S[P-1]>S[P+1]?10*P-100*S[P-1]:10*P+100*S[P+1])/10;let O=m.find(I=>I.shape[1]===1024),W=O?await O.data():[];y.descriptor=Array.from(W),m.forEach(I=>r.dispose(I))}ht[o]=y,_n=n,l(y)}))}function bt(e){return[Math.abs(e.endPoint[0]-e.startPoint[0]),Math.abs(e.endPoint[1]-e.startPoint[1])]}function qe(e){return[e.startPoint[0]+(e.endPoint[0]-e.startPoint[0])/2,e.startPoint[1]+(e.endPoint[1]-e.startPoint[1])/2]}function oA(e,t,o){let n=t.shape[1],A=t.shape[2],s=[[e.startPoint[1]/n,e.startPoint[0]/A,e.endPoint[1]/n,e.endPoint[0]/A]];return r.image.cropAndResize(t,s,[0],o)}function nA(e,t){let o=[e.startPoint[0]*t[0],e.startPoint[1]*t[1]],n=[e.endPoint[0]*t[0],e.endPoint[1]*t[1]],A=e.palmLandmarks.map(s=>[s[0]*t[0],s[1]*t[1]]);return{startPoint:o,endPoint:n,palmLandmarks:A,confidence:e.confidence}}function gt(e,t=1.5){let o=qe(e),n=bt(e),A=[t*n[0]/2,t*n[1]/2],s=[o[0]-A[0],o[1]-A[1]],a=[o[0]+A[0],o[1]+A[1]];return{startPoint:s,endPoint:a,palmLandmarks:e.palmLandmarks}}function Mt(e){let t=qe(e),o=bt(e),A=Math.max(...o)/2,s=[t[0]-A,t[1]-A],a=[t[0]+A,t[1]+A];return{startPoint:s,endPoint:a,palmLandmarks:e.palmLandmarks}}function r2(e){return e-2*Math.PI*Math.floor((e+Math.PI)/(2*Math.PI))}function AA(e,t){let o=Math.PI/2-Math.atan2(-(t[1]-e[1]),t[0]-e[0]);return r2(o)}var eA=(e,t)=>[[1,0,e],[0,1,t],[0,0,1]];function U0(e,t){let o=0;for(let n=0;n[o.x,o.y]),this.anchorsTensor=r.tensor2d(this.anchors),this.inputSize=this.model&&this.model.inputs&&this.model.inputs[0].shape?this.model.inputs[0].shape[2]:0,this.inputSizeTensor=r.tensor1d([this.inputSize,this.inputSize]),this.doubleInputSizeTensor=r.tensor1d([this.inputSize*2,this.inputSize*2])}normalizeBoxes(t){let o={};o.boxOffsets=r.slice(t,[0,0],[-1,2]),o.boxSizes=r.slice(t,[0,2],[-1,2]),o.div=r.div(o.boxOffsets,this.inputSizeTensor),o.boxCenterPoints=r.add(o.div,this.anchorsTensor),o.halfBoxSizes=r.div(o.boxSizes,this.doubleInputSizeTensor),o.sub=r.sub(o.boxCenterPoints,o.halfBoxSizes),o.startPoints=r.mul(o.sub,this.inputSizeTensor),o.add=r.add(o.boxCenterPoints,o.halfBoxSizes),o.endPoints=r.mul(o.add,this.inputSizeTensor);let n=r.concat2d([o.startPoints,o.endPoints],1);return Object.keys(o).forEach(A=>r.dispose(o[A])),n}normalizeLandmarks(t,o){let n={};n.reshape=r.reshape(t,[-1,7,2]),n.div=r.div(n.reshape,this.inputSizeTensor),n.landmarks=r.add(n.div,this.anchors[o]);let A=r.mul(n.landmarks,this.inputSizeTensor);return Object.keys(n).forEach(s=>r.dispose(n[s])),A}async predict(t,o){let n={};n.resize=r.image.resizeBilinear(t,[this.inputSize,this.inputSize]),n.div=r.div(n.resize,N.tf127),n.image=r.sub(n.div,N.tf1),n.batched=this.model.execute(n.image),n.predictions=r.squeeze(n.batched),n.slice=r.slice(n.predictions,[0,0],[-1,1]),n.sigmoid=r.sigmoid(n.slice),n.scores=r.squeeze(n.sigmoid);let A=await n.scores.data();n.boxes=r.slice(n.predictions,[0,1],[-1,4]),n.norm=this.normalizeBoxes(n.boxes),n.nms=await r.image.nonMaxSuppressionAsync(n.norm,n.scores,3*o.hand.maxDetected,o.hand.iouThreshold,o.hand.minConfidence);let s=await n.nms.array(),a=[];for(let i of s){let x={};x.box=r.slice(n.norm,[i,0],[1,-1]),x.slice=r.slice(n.predictions,[i,5],[1,14]),x.norm=this.normalizeLandmarks(x.slice,i),x.palmLandmarks=r.reshape(x.norm,[-1,2]);let d=await x.box.data(),l=d.slice(0,2),y=d.slice(2,4),c=await x.palmLandmarks.array(),f={startPoint:l,endPoint:y,palmLandmarks:c,confidence:A[i]},h=nA(f,[t.shape[2]/this.inputSize,t.shape[1]/this.inputSize]);a.push(h),Object.keys(x).forEach(m=>r.dispose(x[m]))}return Object.keys(n).forEach(i=>r.dispose(n[i])),a}};var l2=5,iA=1.65,lA=[0,5,9,13,17,1,2],y2=0,x2=2,yA=0,vt=class{constructor(t,o){k(this,"handDetector");k(this,"handPoseModel");k(this,"inputSize");k(this,"storedBoxes");k(this,"skipped");k(this,"detectedHands");this.handDetector=t,this.handPoseModel=o,this.inputSize=this.handPoseModel&&this.handPoseModel.inputs[0].shape?this.handPoseModel.inputs[0].shape[2]:0,this.storedBoxes=[],this.skipped=Number.MAX_SAFE_INTEGER,this.detectedHands=0}calculateLandmarksBoundingBox(t){let o=t.map(a=>a[0]),n=t.map(a=>a[1]),A=[Math.min(...o),Math.min(...n)],s=[Math.max(...o),Math.max(...n)];return{startPoint:A,endPoint:s}}getBoxForPalmLandmarks(t,o){let n=t.map(s=>I5([...s,1],o)),A=this.calculateLandmarksBoundingBox(n);return gt(Mt(A),l2)}getBoxForHandLandmarks(t){let o=this.calculateLandmarksBoundingBox(t),n=gt(Mt(o),iA);n.palmLandmarks=[];for(let A=0;A[a[0]*(f[0]-this.inputSize/2),a[1]*(f[1]-this.inputSize/2),a[2]*f[2]]),x=O5(n,[0,0]),d=i.map(f=>[...I5(f,x),f[2]]),l=rA(A),y=[...qe(o),1],c=[U0(y,l[0]),U0(y,l[1])];return d.map(f=>[Math.trunc(f[0]+c[0]),Math.trunc(f[1]+c[1]),Math.trunc(f[2])])}async estimateHands(t,o){let n=!1,A,s=(o.hand.skipTime||0)>g()-yA,a=this.skipped<(o.hand.skipFrames||0);o.skipAllowed&&s&&a&&(A=await this.handDetector.predict(t,o),this.skipped=0),o.skipAllowed&&this.skipped++,A&&A.length>0&&(A.length!==this.detectedHands&&this.detectedHands!==o.hand.maxDetected||!o.hand.landmarks)&&(this.detectedHands=0,this.storedBoxes=[...A],this.storedBoxes.length>0&&(n=!0));let i=[];for(let x=0;x=o.hand.minConfidence/4){let w=r.reshape(p,[-1,3]),S=await w.array();r.dispose(p),r.dispose(w);let O=this.transformRawCoords(S,m,l,h),W=this.getBoxForHandLandmarks(O);this.storedBoxes[x]={...W,confidence:P};let I={landmarks:O,confidence:P,boxConfidence:d.confidence,fingerConfidence:P,box:{topLeft:W.startPoint,bottomRight:W.endPoint}};i.push(I)}else this.storedBoxes[x]=null;r.dispose(p)}else{let l=gt(Mt(d),iA),y={confidence:d.confidence,boxConfidence:d.confidence,fingerConfidence:0,box:{topLeft:l.startPoint,bottomRight:l.endPoint},landmarks:[]};i.push(y)}}return this.storedBoxes=this.storedBoxes.filter(x=>x!==null),this.detectedHands=i.length,i.length>o.hand.maxDetected&&(i.length=o.hand.maxDetected),i}};var l0={thumb:0,index:1,middle:2,ring:3,pinky:4,all:[0,1,2,3,4],nameMapping:{0:"thumb",1:"index",2:"middle",3:"ring",4:"pinky"},pointsMapping:{0:[[0,1],[1,2],[2,3],[3,4]],1:[[0,5],[5,6],[6,7],[7,8]],2:[[0,9],[9,10],[10,11],[11,12]],3:[[0,13],[13,14],[14,15],[15,16]],4:[[0,17],[17,18],[18,19],[19,20]]},getName:e=>l0.nameMapping[e],getPoints:e=>l0.pointsMapping[e]},Y0={none:0,half:1,full:2,nameMapping:{0:"none",1:"half",2:"full"},getName:e=>Y0.nameMapping[e]},U={verticalUp:0,verticalDown:1,horizontalLeft:2,horizontalRight:3,diagonalUpRight:4,diagonalUpLeft:5,diagonalDownRight:6,diagonalDownLeft:7,nameMapping:{0:"verticalUp",1:"verticalDown",2:"horizontalLeft",3:"horizontalRight",4:"diagonalUpRight",5:"diagonalUpLeft",6:"diagonalDownRight",7:"diagonalDownLeft"},getName:e=>U.nameMapping[e]},J0=class{constructor(t){k(this,"name");k(this,"curls");k(this,"directions");k(this,"weights");k(this,"weightsRelative");this.name=t,this.curls={},this.directions={},this.weights=[1,1,1,1,1],this.weightsRelative=[1,1,1,1,1]}curl(t,o,n){typeof this.curls[t]=="undefined"&&(this.curls[t]=[]),this.curls[t].push([o,n])}direction(t,o,n){this.directions[t]||(this.directions[t]=[]),this.directions[t].push([o,n])}weight(t,o){this.weights[t]=o;let n=this.weights.reduce((A,s)=>A+s,0);this.weightsRelative=this.weights.map(A=>A*5/n)}matchAgainst(t,o){let n=0;for(let A in t){let s=t[A],a=this.curls[A];if(typeof a=="undefined"){n+=this.weightsRelative[A];continue}for(let[i,x]of a)if(s===i){n+=x*this.weightsRelative[A];break}}for(let A in o){let s=o[A],a=this.directions[A];if(typeof a=="undefined"){n+=this.weightsRelative[A];continue}for(let[i,x]of a)if(s===i){n+=x*this.weightsRelative[A];break}}return n/10}};var{thumb:v0,index:F0,middle:H0,ring:re,pinky:se}=l0,{none:T0,half:d2,full:R0}=Y0,{verticalUp:Me,verticalDown:ga,horizontalLeft:L5,horizontalRight:f2,diagonalUpRight:m2,diagonalUpLeft:Pe,diagonalDownRight:Ma,diagonalDownLeft:Pa}=U,K0=new J0("thumbs up");K0.curl(v0,T0,1);K0.direction(v0,Me,1);K0.direction(v0,Pe,.25);K0.direction(v0,m2,.25);for(let e of[l0.index,l0.middle,l0.ring,l0.pinky])K0.curl(e,R0,1),K0.direction(e,L5,1),K0.direction(e,f2,1);var $=new J0("victory");$.curl(v0,d2,.5);$.curl(v0,T0,.5);$.direction(v0,Me,1);$.direction(v0,Pe,1);$.curl(F0,T0,1);$.direction(F0,Me,.75);$.direction(F0,Pe,1);$.curl(H0,T0,1);$.direction(H0,Me,1);$.direction(H0,Pe,.75);$.curl(re,R0,1);$.direction(re,Me,.2);$.direction(re,Pe,1);$.direction(re,L5,.2);$.curl(se,R0,1);$.direction(se,Me,.2);$.direction(se,Pe,1);$.direction(se,L5,.2);$.weight(F0,2);$.weight(H0,2);var Q0=new J0("point");Q0.curl(v0,R0,1);Q0.curl(F0,T0,.5);Q0.curl(H0,R0,.5);Q0.curl(re,R0,.5);Q0.curl(se,R0,.5);Q0.weight(F0,2);Q0.weight(H0,2);var _0=new J0("middle finger");_0.curl(v0,T0,1);_0.curl(F0,R0,.5);_0.curl(H0,R0,.5);_0.curl(re,R0,.5);_0.curl(se,R0,.5);_0.weight(F0,2);_0.weight(H0,2);var ve=new J0("open palm");ve.curl(v0,T0,.75);ve.curl(F0,T0,.75);ve.curl(H0,T0,.75);ve.curl(re,T0,.75);ve.curl(se,T0,.75);var xA=[K0,$,Q0,_0,ve];var p2=.7,ae={HALF_CURL_START_LIMIT:60,NO_CURL_START_LIMIT:130,DISTANCE_VOTE_POWER:1.1,SINGLE_ANGLE_VOTE_POWER:.9,TOTAL_ANGLE_VOTE_POWER:1.6};function cA(e,t,o,n){let A=(t-n)/(e-o),s=Math.atan(A)*180/Math.PI;return s<=0?s=-s:s>0&&(s=180-s),s}function fA(e,t){if(!e||!t)return[0,0];let o=cA(e[0],e[1],t[0],t[1]);if(e.length===2)return o;let n=cA(e[1],e[2],t[1],t[2]);return[o,n]}function dA(e,t=1){let o=0,n=0,A=0;return e>=75&&e<=105?o=1*t:e>=25&&e<=155?n=1*t:A=1*t,[o,n,A]}function u2(e,t,o){let n=e[0]-t[0],A=e[0]-o[0],s=t[0]-o[0],a=e[1]-t[1],i=e[1]-o[1],x=t[1]-o[1],d=e[2]-t[2],l=e[2]-o[2],y=t[2]-o[2],c=Math.sqrt(n*n+a*a+d*d),f=Math.sqrt(A*A+i*i+l*l),h=Math.sqrt(s*s+x*x+y*y),m=(h*h+c*c-f*f)/(2*h*c);m>1?m=1:m<-1&&(m=-1);let v=Math.acos(m);v=57.2958*v%180;let M;return v>ae.NO_CURL_START_LIMIT?M=Y0.none:v>ae.HALF_CURL_START_LIMIT?M=Y0.half:M=Y0.full,M}function mA(e,t,o,n){let A;return n===Math.abs(e)?e>0?A=U.horizontalLeft:A=U.horizontalRight:n===Math.abs(t)?t>0?A=U.horizontalLeft:A=U.horizontalRight:o>0?A=U.horizontalLeft:A=U.horizontalRight,A}function pA(e,t,o,n){let A;return n===Math.abs(e)?e<0?A=U.verticalDown:A=U.verticalUp:n===Math.abs(t)?t<0?A=U.verticalDown:A=U.verticalUp:o<0?A=U.verticalDown:A=U.verticalUp,A}function h2(e,t,o,n,A,s,a,i){let x,d=pA(e,t,o,n),l=mA(A,s,a,i);return d===U.verticalUp?l===U.horizontalLeft?x=U.diagonalUpLeft:x=U.diagonalUpRight:l===U.horizontalLeft?x=U.diagonalDownLeft:x=U.diagonalDownRight,x}function b2(e,t,o,n){let A=e[0]-t[0],s=e[0]-o[0],a=t[0]-o[0],i=e[1]-t[1],x=e[1]-o[1],d=t[1]-o[1],l=Math.max(Math.abs(A),Math.abs(s),Math.abs(a)),y=Math.max(Math.abs(i),Math.abs(x),Math.abs(d)),c=0,f=0,h=0,m=y/(l+1e-5);m>1.5?c+=ae.DISTANCE_VOTE_POWER:m>.66?f+=ae.DISTANCE_VOTE_POWER:h+=ae.DISTANCE_VOTE_POWER;let v=Math.sqrt(A*A+i*i),M=Math.sqrt(s*s+x*x),u=Math.sqrt(a*a+d*d),p=Math.max(v,M,u),P=e[0],w=e[1],S=o[0],O=o[1];p===v?(S=o[0],O=o[1]):p===u&&(P=t[0],w=t[1]);let V=fA([P,w],[S,O]),G=dA(V,ae.TOTAL_ANGLE_VOTE_POWER);c+=G[0],f+=G[1],h+=G[2];for(let J of n){let z=dA(J,ae.SINGLE_ANGLE_VOTE_POWER);c+=z[0],f+=z[1],h+=z[2]}let B;return c===Math.max(c,f,h)?B=pA(x,i,d,y):h===Math.max(f,h)?B=mA(s,A,a,l):B=h2(x,i,d,y,s,A,a,l),B}function uA(e){let t=[],o=[],n=[],A=[];if(!e)return{curls:n,directions:A};for(let s of l0.all){let a=l0.getPoints(s),i=[],x=[];for(let d of a){let l=e[d[0]],y=e[d[1]],c=fA(l,y),f=c[0],h=c[1];i.push(f),x.push(h)}t.push(i),o.push(x)}for(let s of l0.all){let a=s===l0.thumb?1:0,i=l0.getPoints(s),x=e[i[a][0]],d=e[i[a+1][1]],l=e[i[3][1]],y=u2(x,d,l),c=b2(x,d,l,t[s].slice(a));n[s]=y,A[s]=c}return{curls:n,directions:A}}function Tt(e){if(!e||e.length===0)return null;let t=uA(e),o={};for(let n of l0.all)o[l0.getName(n)]={curl:Y0.getName(t.curls[n]),direction:U.getName(t.directions[n])};return o}function hA(e){let t=[];if(!e||e.length===0)return t;let o=uA(e);for(let n of xA){let A=n.matchAgainst(o.curls,o.directions);A>=p2&&t.push({name:n.name,confidence:A})}return t}var bA={thumb:[1,2,3,4],index:[5,6,7,8],middle:[9,10,11,12],ring:[13,14,15,16],pinky:[17,18,19,20],palm:[0]},Te,Re,gA;async function G5(e,t){let o=await gA.estimateHands(e,t);if(!o)return[];let n=[];for(let A=0;Ao[A].landmarks[y]);let a=o[A].landmarks,i=[Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER,0,0],x=[0,0,0,0];if(a&&a.length>0){for(let l of a)l[0]i[2]&&(i[2]=l[0]),l[1]>i[3]&&(i[3]=l[1]);i[2]-=i[0],i[3]-=i[1],x=[i[0]/(e.shape[2]||0),i[1]/(e.shape[1]||0),i[2]/(e.shape[2]||0),i[3]/(e.shape[1]||0)]}else i=o[A].box?[Math.trunc(Math.max(0,o[A].box.topLeft[0])),Math.trunc(Math.max(0,o[A].box.topLeft[1])),Math.trunc(Math.min(e.shape[2]||0,o[A].box.bottomRight[0])-Math.max(0,o[A].box.topLeft[0])),Math.trunc(Math.min(e.shape[1]||0,o[A].box.bottomRight[1])-Math.max(0,o[A].box.topLeft[1]))]:[0,0,0,0],x=[o[A].box.topLeft[0]/(e.shape[2]||0),o[A].box.topLeft[1]/(e.shape[1]||0),(o[A].box.bottomRight[0]-o[A].box.topLeft[0])/(e.shape[2]||0),(o[A].box.bottomRight[1]-o[A].box.topLeft[1])/(e.shape[1]||0)];let d=Tt(a);n.push({id:A,score:Math.round(100*o[A].confidence)/100,boxScore:Math.round(100*o[A].boxConfidence)/100,fingerScore:Math.round(100*o[A].fingerConfidence)/100,label:"hand",box:i,boxRaw:x,keypoints:a,annotations:s,landmarks:d})}return n}async function B5(e){var o,n;R.initial&&(Te=null,Re=null),!Te||!Re?[Te,Re]=await Promise.all([e.hand.enabled?L((o=e.hand.detector)==null?void 0:o.modelPath):null,e.hand.landmarks?L((n=e.hand.skeleton)==null?void 0:n.modelPath):null]):(e.debug&&b("cached model:",Te.modelUrl),e.debug&&b("cached model:",Re.modelUrl));let t=new Pt(Te);return gA=new vt(t,Re),[Te,Re]}var t0=[null,null],g2=["StatefulPartitionedCall/Postprocessor/Slice","StatefulPartitionedCall/Postprocessor/ExpandDims_1"],$0=[[0,0],[0,0]],M2=["hand","fist","pinch","point","face","tip","pinchtip"],PA=4,vA=1.6,P2=512,v2=1.4,Rt=Number.MAX_SAFE_INTEGER,F5=0,V0=[0,0],K={boxes:[],hands:[]},TA={thumb:[1,2,3,4],index:[5,6,7,8],middle:[9,10,11,12],ring:[13,14,15,16],pinky:[17,18,19,20],base:[0],palm:[0,17,13,9,5,1,0]};async function RA(e){var t;if(R.initial&&(t0[0]=null),t0[0])e.debug&&b("cached model:",t0[0].modelUrl);else{wt(["tensorlistreserve","enter","tensorlistfromtensor","merge","loopcond","switch","exit","tensorliststack","nextiteration","tensorlistsetitem","tensorlistgetitem","reciprocal","shape","split","where"],e),t0[0]=await L((t=e.hand.detector)==null?void 0:t.modelPath);let o=Object.values(t0[0].modelSignature.inputs);$0[0][0]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[1].size):0,$0[0][1]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[2].size):0}return t0[0]}async function wA(e){var t;if(R.initial&&(t0[1]=null),t0[1])e.debug&&b("cached model:",t0[1].modelUrl);else{t0[1]=await L((t=e.hand.skeleton)==null?void 0:t.modelPath);let o=Object.values(t0[1].modelSignature.inputs);$0[1][0]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[1].size):0,$0[1][1]=Array.isArray(o)?parseInt(o[0].tensorShape.dim[2].size):0}return t0[1]}async function T2(e,t){let o=[];if(!e||!t0[0])return o;let n={},A=(e.shape[2]||1)/(e.shape[1]||1),s=Math.min(Math.round((e.shape[1]||0)/8)*8,P2),a=Math.round(s*A/8)*8;n.resize=r.image.resizeBilinear(e,[s,a]),n.cast=r.cast(n.resize,"int32"),[n.rawScores,n.rawBoxes]=await t0[0].executeAsync(n.cast,g2),n.boxes=r.squeeze(n.rawBoxes,[0,2]),n.scores=r.squeeze(n.rawScores,[0]);let i=r.unstack(n.scores,1);r.dispose(i[PA]),i.splice(PA,1),n.filtered=r.stack(i,1),r.dispose(i),n.max=r.max(n.filtered,1),n.argmax=r.argMax(n.filtered,1);let x=0;n.nms=await r.image.nonMaxSuppressionAsync(n.boxes,n.max,(t.hand.maxDetected||0)+1,t.hand.iouThreshold||0,t.hand.minConfidence||1);let d=await n.nms.data(),l=await n.max.data(),y=await n.argmax.data();for(let c of Array.from(d)){let f=r.slice(n.boxes,c,1),h=await f.data();r.dispose(f);let m=[h[1],h[0],h[3]-h[1],h[2]-h[0]],v=ct(m,v2),M=[Math.trunc(m[0]*V0[0]),Math.trunc(m[1]*V0[1]),Math.trunc(m[2]*V0[0]),Math.trunc(m[3]*V0[1])],u=l[c],p=M2[y[c]],P={id:x++,score:u,box:M,boxRaw:v,label:p};o.push(P)}return Object.keys(n).forEach(c=>r.dispose(n[c])),o.sort((c,f)=>f.score-c.score),o.length>(t.hand.maxDetected||1)&&(o.length=t.hand.maxDetected||1),o}async function H5(e,t,o){let n={id:t.id,score:Math.round(100*t.score)/100,boxScore:Math.round(100*t.score)/100,fingerScore:0,box:t.box,boxRaw:t.boxRaw,label:t.label,keypoints:[],landmarks:{},annotations:{}};if(e&&t0[1]&&o.hand.landmarks&&t.score>(o.hand.minConfidence||0)){let A={},s=[t.boxRaw[1],t.boxRaw[0],t.boxRaw[3]+t.boxRaw[1],t.boxRaw[2]+t.boxRaw[0]];A.crop=r.image.cropAndResize(e,[s],[0],[$0[1][0],$0[1][1]],"bilinear"),A.div=r.div(A.crop,N.tf255),[A.score,A.keypoints]=t0[1].execute(A.div,["Identity_1","Identity"]);let a=(await A.score.data())[0],i=(100-Math.trunc(100/(1+Math.exp(a))))/100;if(i>=(o.hand.minConfidence||0)){n.fingerScore=i,A.reshaped=r.reshape(A.keypoints,[-1,3]);let l=(await A.reshaped.array()).map(y=>[y[0]/$0[1][1],y[1]/$0[1][0],y[2]||0]).map(y=>[y[0]*t.boxRaw[2],y[1]*t.boxRaw[3],y[2]||0]);n.keypoints=l.map(y=>[V0[0]*(y[0]+t.boxRaw[0]),V0[1]*(y[1]+t.boxRaw[1]),y[2]||0]),n.landmarks=Tt(n.keypoints);for(let y of Object.keys(TA))n.annotations[y]=TA[y].map(c=>n.landmarks&&n.keypoints[c]?n.keypoints[c]:null)}Object.keys(A).forEach(x=>r.dispose(A[x]))}return n}async function V5(e,t){var A,s;if(!t0[0]||!t0[1]||!((A=t0[0])!=null&&A.inputs[0].shape)||!((s=t0[1])!=null&&s.inputs[0].shape))return[];V0=[e.shape[2]||0,e.shape[1]||0],Rt++;let o=(t.hand.skipTime||0)>g()-F5,n=Rt<(t.hand.skipFrames||0);return t.skipAllowed&&o&&n?K.hands:new Promise(async a=>{let i=3*(t.hand.skipTime||0)>g()-F5,x=Rt<3*(t.hand.skipFrames||0);t.skipAllowed&&K.hands.length===t.hand.maxDetected?K.hands=await Promise.all(K.boxes.map(l=>H5(e,l,t))):t.skipAllowed&&i&&x&&K.hands.length>0?K.hands=await Promise.all(K.boxes.map(l=>H5(e,l,t))):(K.boxes=await T2(e,t),F5=g(),K.hands=await Promise.all(K.boxes.map(l=>H5(e,l,t))),Rt=0);let d=[...K.boxes];if(K.boxes.length=0,t.cacheSensitivity>0)for(let l=0;l.05&&y.box[3]/(e.shape[1]||1)>.05&&K.hands[l].fingerScore&&K.hands[l].fingerScore>(t.hand.minConfidence||0)){let c=ct(y.box,vA),f=ct(y.boxRaw,vA);K.boxes.push({...d[l],box:c,boxRaw:f})}}for(let l=0;lg()-zA,s=Z5<(((i=t.face.liveness)==null?void 0:i.skipFrames)||0);return t.skipAllowed&&A&&s&&EA===n&&kt[o]?(Z5++,kt[o]):(Z5=0,new Promise(async x=>{let d=r.image.resizeBilinear(e,[s0!=null&&s0.inputs[0].shape?s0.inputs[0].shape[2]:0,s0!=null&&s0.inputs[0].shape?s0.inputs[0].shape[1]:0],!1),l=s0==null?void 0:s0.execute(d),y=(await l.data())[0];kt[o]=Math.round(100*y)/100,EA=n,zA=g(),r.dispose([d,l]),x(kt[o])}))}var Ue={};ee(Ue,{connected:()=>zt,horizontal:()=>X5,kpt:()=>Et,relative:()=>U5,vertical:()=>q5});var Et=["nose","leftEye","rightEye","leftEar","rightEar","leftShoulder","rightShoulder","leftElbow","rightElbow","leftWrist","rightWrist","leftHip","rightHip","leftKnee","rightKnee","leftAnkle","rightAnkle"],X5=[["leftEye","rightEye"],["leftEar","rightEar"],["leftShoulder","rightShoulder"],["leftElbow","rightElbow"],["leftWrist","rightWrist"],["leftHip","rightHip"],["leftKnee","rightKnee"],["leftAnkle","rightAnkle"]],q5=[["leftKnee","leftShoulder"],["rightKnee","rightShoulder"],["leftAnkle","leftKnee"],["rightAnkle","rightKnee"]],U5=[[["leftHip","rightHip"],["leftShoulder","rightShoulder"]],[["leftElbow","rightElbow"],["leftShoulder","rightShoulder"]]],zt={leftLeg:["leftHip","leftKnee","leftAnkle"],rightLeg:["rightHip","rightKnee","rightAnkle"],torso:["leftShoulder","rightShoulder","rightHip","leftHip","leftShoulder"],leftArm:["leftShoulder","leftElbow","leftWrist"],rightArm:["rightShoulder","rightElbow","rightWrist"],head:[]};var WA=.005,f0={keypoints:[],padding:[[0,0],[0,0],[0,0],[0,0]]};function J5(e){for(let t of X5){let o=e.keypoints.findIndex(A=>A.part===t[0]),n=e.keypoints.findIndex(A=>A.part===t[1]);if(e.keypoints[o]&&e.keypoints[n]&&e.keypoints[o].position[0]A&&A.part===t[0]),n=e.keypoints.findIndex(A=>A&&A.part===t[1]);e.keypoints[o]&&e.keypoints[n]&&e.keypoints[o].position[1]d&&d.part===t[0]),A=e.keypoints.findIndex(d=>d&&d.part===t[1]),s=e.keypoints.findIndex(d=>d&&d.part===o[0]),a=e.keypoints.findIndex(d=>d&&d.part===o[1]);if(!e.keypoints[s]||!e.keypoints[a])continue;let i=e.keypoints[n]?[Math.abs(e.keypoints[s].position[0]-e.keypoints[n].position[0]),Math.abs(e.keypoints[a].position[0]-e.keypoints[n].position[0])]:[0,0],x=e.keypoints[A]?[Math.abs(e.keypoints[a].position[0]-e.keypoints[A].position[0]),Math.abs(e.keypoints[s].position[0]-e.keypoints[A].position[0])]:[0,0];if(i[0]>i[1]||x[0]>x[1]){let d=e.keypoints[n];e.keypoints[n]=e.keypoints[A],e.keypoints[A]=d}}}function CA(e){for(let t=0;te.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0,e.shape[2]>e.shape[1]?Math.trunc((e.shape[2]-e.shape[1])/2):0],[e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0,e.shape[1]>e.shape[2]?Math.trunc((e.shape[1]-e.shape[2])/2):0],[0,0]],o.pad=r.pad(e,f0.padding),o.resize=r.image.resizeBilinear(o.pad,[t,t]);let n=r.cast(o.resize,"int32");return Object.keys(o).forEach(A=>r.dispose(o[A])),n}function IA(e,t){e.keypoints=e.keypoints.filter(n=>n&&n.position);for(let n of e.keypoints)n.position=[n.position[0]*(t[0]+f0.padding[2][0]+f0.padding[2][1])/t[0]-f0.padding[2][0],n.position[1]*(t[1]+f0.padding[1][0]+f0.padding[1][1])/t[1]-f0.padding[1][0]],n.positionRaw=[n.position[0]/t[0],n.position[1]/t[1]];let o=N0(e.keypoints.map(n=>n.position),t);return e.box=o.box,e.boxRaw=o.boxRaw,e}var m0,jt=0,Y5=Number.MAX_SAFE_INTEGER,ie={boxes:[],bodies:[],last:0};async function LA(e){return R.initial&&(m0=null),m0?e.debug&&b("cached model:",m0.modelUrl):(wt(["size"],e),m0=await L(e.body.modelPath)),jt=m0.inputs[0].shape?m0.inputs[0].shape[2]:0,jt<64&&(jt=256),m0}async function w2(e,t,o){let n=e[0][0],A=[],s=0;for(let l=0;lt.body.minConfidence){let y=[n[l][1],n[l][0]];A.push({score:Math.round(100*s)/100,part:Et[l],positionRaw:y,position:[Math.round((o.shape[2]||0)*y[0]),Math.round((o.shape[1]||0)*y[1])]})}s=A.reduce((l,y)=>y.score>l?y.score:l,0);let a=[],i=N0(A.map(l=>l.position),[o.shape[2],o.shape[1]]),x={};for(let[l,y]of Object.entries(zt)){let c=[];for(let f=0;fv.part===y[f]),m=A.find(v=>v.part===y[f+1]);h&&m&&h.score>(t.body.minConfidence||0)&&m.score>(t.body.minConfidence||0)&&c.push([h.position,m.position])}x[l]=c}let d={id:0,score:s,box:i.box,boxRaw:i.boxRaw,keypoints:A,annotations:x};return J5(d),a.push(d),a}async function k2(e,t,o){let n=[];for(let A=0;At.body.minConfidence){let i=[];for(let y=0;y<17;y++){let c=s[3*y+2];if(c>t.body.minConfidence){let f=[s[3*y+1],s[3*y+0]];i.push({part:Et[y],score:Math.round(100*c)/100,positionRaw:f,position:[Math.round((o.shape[2]||0)*f[0]),Math.round((o.shape[1]||0)*f[1])]})}}let x=N0(i.map(y=>y.position),[o.shape[2],o.shape[1]]),d={};for(let[y,c]of Object.entries(zt)){let f=[];for(let h=0;hM.part===c[h]),v=i.find(M=>M.part===c[h+1]);m&&v&&m.score>(t.body.minConfidence||0)&&v.score>(t.body.minConfidence||0)&&f.push([m.position,v.position])}d[y]=f}let l={id:A,score:a,box:x.box,boxRaw:x.boxRaw,keypoints:[...i],annotations:d};J5(l),n.push(l)}}return n.sort((A,s)=>s.score-A.score),n.length>t.body.maxDetected&&(n.length=t.body.maxDetected),n}async function K5(e,t){if(!m0||!(m0!=null&&m0.inputs[0].shape))return[];t.skipAllowed||(ie.boxes.length=0),Y5++;let o=(t.body.skipTime||0)>g()-ie.last,n=Y5<(t.body.skipFrames||0);return t.skipAllowed&&o&&n?ie.bodies:new Promise(async A=>{let s={};Y5=0,s.input=OA(e,jt),s.res=m0==null?void 0:m0.execute(s.input),ie.last=g();let a=await s.res.array();ie.bodies=s.res.shape[2]===17?await w2(a,t,e):await k2(a,t,e);for(let i of ie.bodies)IA(i,[e.shape[2]||1,e.shape[1]||1]),CA(i.keypoints);Object.keys(s).forEach(i=>r.dispose(s[i])),A(ie.bodies)})}var we,St=[],GA=0,Q5=Number.MAX_SAFE_INTEGER,Ct=0,Wt=2.5;async function BA(e){if(!we||R.initial){we=await L(e.object.modelPath);let t=Object.values(we.modelSignature.inputs);Ct=Array.isArray(t)?parseInt(t[0].tensorShape.dim[2].size):0}else e.debug&&b("cached model:",we.modelUrl);return we}async function E2(e,t,o){let n=0,A=[];for(let x of[1,2,4])r.tidy(async()=>{let d=x*13,l=r.squeeze(e.find(m=>m.shape[1]===d**2&&(m.shape[2]||0)===ue.length)),y=r.squeeze(e.find(m=>m.shape[1]===d**2&&(m.shape[2]||0)(o.object.minConfidence||0)&&v!==61){let u=(.5+Math.trunc(m%d))/d,p=(.5+Math.trunc(m/d))/d,P=f[m].map(B=>B*(d/x/Ct)),[w,S]=[u-Wt/x*P[0],p-Wt/x*P[1]],[O,W]=[u+Wt/x*P[2]-w,p+Wt/x*P[3]-S],I=[w,S,O,W];I=I.map(B=>Math.max(0,Math.min(B,1)));let V=[I[0]*t[0],I[1]*t[1],I[2]*t[0],I[3]*t[1]],G={id:n++,score:Math.round(100*M)/100,class:v+1,label:ue[v].label,box:V.map(B=>Math.trunc(B)),boxRaw:I};A.push(G)}}});e.forEach(x=>r.dispose(x));let s=A.map(x=>[x.boxRaw[1],x.boxRaw[0],x.boxRaw[3],x.boxRaw[2]]),a=A.map(x=>x.score),i=[];if(s&&s.length>0){let x=await r.image.nonMaxSuppressionAsync(s,a,o.object.maxDetected,o.object.iouThreshold,o.object.minConfidence);i=await x.data(),r.dispose(x)}return A=A.filter((x,d)=>i.includes(d)).sort((x,d)=>d.score-x.score),A}async function _5(e,t){let o=(t.object.skipTime||0)>g()-GA,n=Q5<(t.object.skipFrames||0);return t.skipAllowed&&o&&n&&St.length>0?(Q5++,St):(Q5=0,!R.kernels.includes("mod")||!R.kernels.includes("sparsetodense")?St:new Promise(async A=>{let s=[e.shape[2]||0,e.shape[1]||0],a=r.image.resizeBilinear(e,[Ct,Ct],!1),i=r.div(a,N.tf255),x=i.transpose([0,3,1,2]);r.dispose(i),r.dispose(a);let d;t.object.enabled&&(d=we.execute(x)),GA=g(),r.dispose(x);let l=await E2(d,s,t);St=l,A(l)}))}var Ye=["nose","leftEye","rightEye","leftEar","rightEar","leftShoulder","rightShoulder","leftElbow","rightElbow","leftWrist","rightWrist","leftHip","rightHip","leftKnee","rightKnee","leftAnkle","rightAnkle"],z2=Ye.length,Je=Ye.reduce((e,t,o)=>(e[t]=o,e),{}),j2=[["leftHip","leftShoulder"],["leftElbow","leftShoulder"],["leftElbow","leftWrist"],["leftHip","leftKnee"],["leftKnee","leftAnkle"],["rightHip","rightShoulder"],["rightElbow","rightShoulder"],["rightElbow","rightWrist"],["rightHip","rightKnee"],["rightKnee","rightAnkle"],["leftShoulder","rightShoulder"],["leftHip","rightHip"]],qa=j2.map(([e,t])=>[Je[e],Je[t]]),HA=[["nose","leftEye"],["leftEye","leftEar"],["nose","rightEye"],["rightEye","rightEar"],["nose","leftShoulder"],["leftShoulder","leftElbow"],["leftElbow","leftWrist"],["leftShoulder","leftHip"],["leftHip","leftKnee"],["leftKnee","leftAnkle"],["nose","rightShoulder"],["rightShoulder","rightElbow"],["rightElbow","rightWrist"],["rightShoulder","rightHip"],["rightHip","rightKnee"],["rightKnee","rightAnkle"]];function VA(e){let t=e.reduce(({maxX:o,maxY:n,minX:A,minY:s},{position:{x:a,y:i}})=>({maxX:Math.max(o,a),maxY:Math.max(n,i),minX:Math.min(A,a),minY:Math.min(s,i)}),{maxX:Number.NEGATIVE_INFINITY,maxY:Number.NEGATIVE_INFINITY,minX:Number.POSITIVE_INFINITY,minY:Number.POSITIVE_INFINITY});return[t.minX,t.minY,t.maxX-t.minX,t.maxY-t.minY]}function ZA(e,[t,o],[n,A]){let s=t/n,a=o/A,i=(d,l)=>({id:l,score:d.score,boxRaw:[d.box[0]/A,d.box[1]/n,d.box[2]/A,d.box[3]/n],box:[Math.trunc(d.box[0]*a),Math.trunc(d.box[1]*s),Math.trunc(d.box[2]*a),Math.trunc(d.box[3]*s)],keypoints:d.keypoints.map(({score:y,part:c,position:f})=>({score:y,part:c,position:[Math.trunc(f.x*a),Math.trunc(f.y*s)],positionRaw:[f.x/n,f.y/n]})),annotations:{}});return e.map((d,l)=>i(d,l))}var Ot=class{constructor(t,o){k(this,"priorityQueue");k(this,"numberOfElements");k(this,"getElementValue");this.priorityQueue=new Array(t),this.numberOfElements=-1,this.getElementValue=o}enqueue(t){this.priorityQueue[++this.numberOfElements]=t,this.swim(this.numberOfElements)}dequeue(){let t=this.priorityQueue[0];return this.exchange(0,this.numberOfElements--),this.sink(0),this.priorityQueue[this.numberOfElements+1]=null,t}empty(){return this.numberOfElements===-1}size(){return this.numberOfElements+1}all(){return this.priorityQueue.slice(0,this.numberOfElements+1)}max(){return this.priorityQueue[0]}swim(t){for(;t>0&&this.less(Math.floor(t/2),t);)this.exchange(t,Math.floor(t/2)),t=Math.floor(t/2)}sink(t){for(;2*t<=this.numberOfElements;){let o=2*t;if(oo?o:e}function DA(e,t,o,n){let A=o-e,s=n-t;return A*A+s*s}function oo(e,t){return{x:e.x+t.x,y:e.y+t.y}}var w0,W2=["MobilenetV1/offset_2/BiasAdd","MobilenetV1/heatmap_2/BiasAdd","MobilenetV1/displacement_fwd_2/BiasAdd","MobilenetV1/displacement_bwd_2/BiasAdd"],It=1,ke=16,C2=50**2;function XA(e,t,o,n,A,s,a=2){let i=M=>({y:s.get(M.y,M.x,e),x:s.get(M.y,M.x,s.shape[2]/2+e)}),x=(M,u,p)=>({y:to(Math.round(M.y/ke),0,u-1),x:to(Math.round(M.x/ke),0,p-1)}),[d,l]=n.shape,y=x(t.position,d,l),c=i(y),h=oo(t.position,c);for(let M=0;M[Je[c],Je[f]]),a=s.map(([,c])=>c),i=s.map(([c])=>c),x=t.shape[2],d=a.length,l=new Array(x),y=eo(e.part,ke,o);l[e.part.id]={score:e.score,part:Ye[e.part.id],position:y};for(let c=d-1;c>=0;--c){let f=a[c],h=i[c];l[f]&&!l[h]&&(l[h]=XA(c,l[f],h,t,o,A))}for(let c=0;ct){i=!1;break}if(!i)break}return i}function L2(e,t){let[o,n,A]=t.shape,s=new Ot(o*n*A,({score:a})=>a);for(let a=0;a{var a;let s=(a=A[n])==null?void 0:a.position;return s?DA(o,t,s.y,s.x)<=C2:!1})}function N2(e,t){return t.reduce((n,{position:A,score:s},a)=>(qA(e,A,a)||(n+=s),n),0)/t.length}function G2(e,t,o,n,A,s){let a=[],i=L2(s,t);for(;a.lengthf.score>s);let y=N2(a,l),c=VA(l);y>s&&a.push({keypoints:l,box:c,score:Math.round(100*y)/100})}return a}async function no(e,t){let o=r.tidy(()=>{if(!w0.inputs[0].shape)return[];let a=r.image.resizeBilinear(e,[w0.inputs[0].shape[2],w0.inputs[0].shape[1]]),i=r.sub(r.div(r.cast(a,"float32"),127.5),1),d=w0.execute(i,W2).map(l=>r.squeeze(l,[0]));return d[1]=r.sigmoid(d[1]),d}),n=await Promise.all(o.map(a=>a.buffer()));for(let a of o)r.dispose(a);let A=await G2(n[0],n[1],n[2],n[3],t.body.maxDetected,t.body.minConfidence);return w0.inputs[0].shape?ZA(A,[e.shape[1],e.shape[2]],[w0.inputs[0].shape[2],w0.inputs[0].shape[1]]):[]}async function UA(e){return!w0||R.initial?w0=await L(e.body.modelPath):e.debug&&b("cached model:",w0.modelUrl),w0}var j0,Ao=!1;async function ro(e){return!j0||R.initial?j0=await L(e.segmentation.modelPath):e.debug&&b("cached model:",j0.modelUrl),j0}async function YA(e,t,o){var m,v;if(Ao)return{data:[],canvas:null,alpha:null};Ao=!0,j0||await ro(o);let n=await fe(e,o),A=((m=n.tensor)==null?void 0:m.shape[2])||0,s=((v=n.tensor)==null?void 0:v.shape[1])||0;if(!n.tensor)return{data:[],canvas:null,alpha:null};let a={};a.resize=r.image.resizeBilinear(n.tensor,[j0.inputs[0].shape?j0.inputs[0].shape[1]:0,j0.inputs[0].shape?j0.inputs[0].shape[2]:0],!1),r.dispose(n.tensor),a.norm=r.div(a.resize,N.tf255),a.res=j0.execute(a.norm),a.squeeze=r.squeeze(a.res,0),a.squeeze.shape[2]===2?(a.softmax=r.softmax(a.squeeze),[a.bg,a.fg]=r.unstack(a.softmax,2),a.expand=r.expandDims(a.fg,2),a.pad=r.expandDims(a.expand,0),a.crop=r.image.cropAndResize(a.pad,[[0,0,.5,.5]],[0],[A,s]),a.data=r.squeeze(a.crop,0)):a.data=r.image.resizeBilinear(a.squeeze,[s,A]);let i=Array.from(await a.data.data());if(R.node&&!R.Canvas&&typeof ImageData=="undefined")return o.debug&&b("canvas support missing"),Object.keys(a).forEach(M=>r.dispose(a[M])),{data:i,canvas:null,alpha:null};let x=a0(A,s);r.browser&&await r.browser.toPixels(a.data,x);let d=x.getContext("2d");o.segmentation.blur&&o.segmentation.blur>0&&(d.filter=`blur(${o.segmentation.blur}px)`);let l=d.getImageData(0,0,A,s),y=a0(A,s),c=y.getContext("2d");n.canvas&&c.drawImage(n.canvas,0,0),c.globalCompositeOperation="darken",o.segmentation.blur&&o.segmentation.blur>0&&(c.filter=`blur(${o.segmentation.blur}px)`),c.drawImage(x,0,0),c.globalCompositeOperation="source-over",c.filter="none";let f=c.getImageData(0,0,A,s);for(let M=0;Mr.dispose(a[M])),Ao=!1,{data:i,canvas:y,alpha:x}}var Ke=class{constructor(){k(this,"ssrnetage",null);k(this,"gear",null);k(this,"blazeposedetect",null);k(this,"blazepose",null);k(this,"centernet",null);k(this,"efficientpose",null);k(this,"mobilefacenet",null);k(this,"emotion",null);k(this,"facedetect",null);k(this,"faceiris",null);k(this,"facemesh",null);k(this,"faceres",null);k(this,"ssrnetgender",null);k(this,"handpose",null);k(this,"handskeleton",null);k(this,"handtrack",null);k(this,"liveness",null);k(this,"movenet",null);k(this,"nanodet",null);k(this,"posenet",null);k(this,"segmentation",null);k(this,"antispoof",null)}};function Lt(e){for(let t of Object.keys(e.models))e.models[t]=null}async function so(e){var t,o,n,A,s,a,i,x,d,l,y,c,f,h,m,v,M,u,p,P,w,S,O,W,I,V,G,B,J,z,P0;R.initial&&Lt(e),e.config.hand.enabled&&(!e.models.handpose&&((o=(t=e.config.hand.detector)==null?void 0:t.modelPath)==null?void 0:o.includes("handdetect"))&&([e.models.handpose,e.models.handskeleton]=await B5(e.config)),!e.models.handskeleton&&e.config.hand.landmarks&&((A=(n=e.config.hand.detector)==null?void 0:n.modelPath)==null?void 0:A.includes("handdetect"))&&([e.models.handpose,e.models.handskeleton]=await B5(e.config))),e.config.body.enabled&&!e.models.blazepose&&((a=(s=e.config.body)==null?void 0:s.modelPath)==null?void 0:a.includes("blazepose"))&&(e.models.blazepose=vn(e.config)),e.config.body.enabled&&!e.models.blazeposedetect&&e.config.body.detector&&e.config.body.detector.modelPath&&(e.models.blazeposedetect=Pn(e.config)),e.config.body.enabled&&!e.models.efficientpose&&((x=(i=e.config.body)==null?void 0:i.modelPath)==null?void 0:x.includes("efficientpose"))&&(e.models.efficientpose=zn(e.config)),e.config.body.enabled&&!e.models.movenet&&((l=(d=e.config.body)==null?void 0:d.modelPath)==null?void 0:l.includes("movenet"))&&(e.models.movenet=LA(e.config)),e.config.body.enabled&&!e.models.posenet&&((c=(y=e.config.body)==null?void 0:y.modelPath)==null?void 0:c.includes("posenet"))&&(e.models.posenet=UA(e.config)),e.config.face.enabled&&!e.models.facedetect&&(e.models.facedetect=dn(e.config)),e.config.face.enabled&&((f=e.config.face.antispoof)==null?void 0:f.enabled)&&!e.models.antispoof&&(e.models.antispoof=$o(e.config)),e.config.face.enabled&&((h=e.config.face.liveness)==null?void 0:h.enabled)&&!e.models.liveness&&(e.models.liveness=jA(e.config)),e.config.face.enabled&&((m=e.config.face.description)==null?void 0:m.enabled)&&!e.models.faceres&&(e.models.faceres=$n(e.config)),e.config.face.enabled&&((v=e.config.face.emotion)==null?void 0:v.enabled)&&!e.models.emotion&&(e.models.emotion=Cn(e.config)),e.config.face.enabled&&((M=e.config.face.iris)==null?void 0:M.enabled)&&!((u=e.config.face.attention)!=null&&u.enabled)&&!e.models.faceiris&&(e.models.faceiris=Zn(e.config)),e.config.face.enabled&&((p=e.config.face.mesh)==null?void 0:p.enabled)&&!e.models.facemesh&&(e.models.facemesh=Jn(e.config)),e.config.face.enabled&&((P=e.config.face.gear)==null?void 0:P.enabled)&&!e.models.gear&&(e.models.gear=Fo(e.config)),e.config.face.enabled&&((w=e.config.face.ssrnet)==null?void 0:w.enabled)&&!e.models.ssrnetage&&(e.models.ssrnetage=Xo(e.config)),e.config.face.enabled&&((S=e.config.face.ssrnet)==null?void 0:S.enabled)&&!e.models.ssrnetgender&&(e.models.ssrnetgender=Yo(e.config)),e.config.face.enabled&&((O=e.config.face.mobilefacenet)==null?void 0:O.enabled)&&!e.models.mobilefacenet&&(e.models.mobilefacenet=Gn(e.config)),e.config.hand.enabled&&!e.models.handtrack&&((I=(W=e.config.hand.detector)==null?void 0:W.modelPath)==null?void 0:I.includes("handtrack"))&&(e.models.handtrack=RA(e.config)),e.config.hand.enabled&&e.config.hand.landmarks&&!e.models.handskeleton&&((G=(V=e.config.hand.detector)==null?void 0:V.modelPath)==null?void 0:G.includes("handtrack"))&&(e.models.handskeleton=wA(e.config)),e.config.object.enabled&&!e.models.centernet&&((J=(B=e.config.object)==null?void 0:B.modelPath)==null?void 0:J.includes("centernet"))&&(e.models.centernet=wn(e.config)),e.config.object.enabled&&!e.models.nanodet&&((P0=(z=e.config.object)==null?void 0:z.modelPath)==null?void 0:P0.includes("nanodet"))&&(e.models.nanodet=BA(e.config)),e.config.segmentation.enabled&&!e.models.segmentation&&(e.models.segmentation=ro(e.config));for await(let p0 of Object.keys(e.models))e.models[p0]&&typeof e.models[p0]!="undefined"&&(e.models[p0]=await e.models[p0])}async function ao(e){let t=["const","placeholder","noop","pad","squeeze","add","sub","mul","div"];for(let o of Object.keys(e.models)){let n=e.models[o];if(!n)continue;let A=[],s=n==null?void 0:n.executor;if(s&&s.graph.nodes)for(let i of Object.values(s.graph.nodes)){let x=i.op.toLowerCase();A.includes(x)||A.push(x)}else!s&&e.config.debug&&b("model signature not determined:",o);let a=[];for(let i of A)!t.includes(i)&&!e.env.kernels.includes(i)&&!e.env.kernels.includes(i.replace("_",""))&&!e.env.kernels.includes(i.replace("native",""))&&!e.env.kernels.includes(i.replace("v2",""))&&a.push(i);e.config.debug&&a.length>0&&b("model validation failed:",o,a)}}var q={name:"humangl",priority:999,canvas:null,gl:null,extensions:[],webGLattr:{alpha:!1,antialias:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,depth:!1,stencil:!1,failIfMajorPerformanceCaveat:!1,desynchronized:!0}};function B2(){let e=q.gl;!e||(q.extensions=e.getSupportedExtensions())}async function QA(e){var t;if(e.config.backend==="humangl"&&(q.name in r.engine().registry&&(!q.gl||!q.gl.getParameter(q.gl.VERSION))&&(b("error: humangl backend invalid context"),Lt(e)),!r.findBackend(q.name))){try{q.canvas=await a0(100,100)}catch(n){b("error: cannot create canvas:",n);return}try{if(q.gl=(t=q.canvas)==null?void 0:t.getContext("webgl2",q.webGLattr),!q.gl.getParameter(q.gl.VERSION).includes("2.0")){b("override: using fallback webgl backend as webgl 2.0 is not detected"),e.config.backend="webgl";return}q.canvas&&(q.canvas.addEventListener("webglcontextlost",async A=>{throw b("error: humangl:",A.type),b("possible browser memory leak using webgl or conflict with multiple backend registrations"),e.emit("error"),new Error("backend error: webgl context lost")}),q.canvas.addEventListener("webglcontextrestored",A=>{b("error: humangl context restored:",A)}),q.canvas.addEventListener("webglcontextcreationerror",A=>{b("error: humangl context create:",A)}))}catch(n){b("error: cannot get WebGL context:",n);return}try{r.setWebGLContext(2,q.gl)}catch(n){b("error: cannot set WebGL context:",n);return}try{let n=new r.GPGPUContext(q.gl);r.registerBackend(q.name,()=>new r.MathBackendWebGL(n),q.priority)}catch(n){b("error: cannot register WebGL backend:",n);return}try{r.getKernelsForBackend("webgl").forEach(A=>{let s={...A,backendName:q.name};r.registerKernel(s)})}catch(n){b("error: cannot update WebGL backend registration:",n);return}let o=r.backend().getGPGPUContext?r.backend().getGPGPUContext().gl:null;if(o)b(`humangl webgl version:${o.getParameter(o.VERSION)} renderer:${o.getParameter(o.RENDERER)}`);else{b("error: no current gl context:",o,q.gl);return}try{r.ENV.set("WEBGL_VERSION",2)}catch(n){b("error: cannot set WebGL backend flags:",n);return}B2(),b("backend registered:",q.name)}}function F2(){if(!R.kernels.includes("mod")){let e={kernelName:"Mod",backendName:r.getBackend(),kernelFunc:t=>r.tidy(()=>r.sub(t.inputs.a,r.mul(r.div(t.inputs.a,t.inputs.b),t.inputs.b)))};r.registerKernel(e),R.kernels.push("mod")}if(!R.kernels.includes("floormod")){let e={kernelName:"FloorMod",backendName:r.getBackend(),kernelFunc:t=>r.tidy(()=>r.floorDiv(t.inputs.a/t.inputs.b)*t.inputs.b+r.mod(t.inputs.a,t.inputs.b))};r.registerKernel(e),R.kernels.push("floormod")}}async function Nt(e,t=!1){if(e.state="backend",t||R.initial||e.config.backend&&e.config.backend.length>0&&r.getBackend()!==e.config.backend){let o=g();if(e.config.backend&&e.config.backend.length>0){if(typeof window=="undefined"&&typeof WorkerGlobalScope!="undefined"&&e.config.debug&&e.config.debug&&b("running inside web worker"),R.browser&&e.config.backend==="tensorflow"&&(e.config.debug&&b("override: backend set to tensorflow while running in browser"),e.config.backend="humangl"),R.node&&(e.config.backend==="webgl"||e.config.backend==="humangl")&&(e.config.debug&&b(`override: backend set to ${e.config.backend} while running in nodejs`),e.config.backend="tensorflow"),R.browser&&e.config.backend==="webgpu")if(typeof navigator=="undefined"||typeof navigator.gpu=="undefined")b("override: backend set to webgpu but browser does not support webgpu"),e.config.backend="humangl";else{let A=await navigator.gpu.requestAdapter();e.config.debug&&b("enumerated webgpu adapter:",A)}e.config.backend==="humangl"&&await QA(e);let n=Object.keys(r.engine().registryFactory);if(e.config.debug&&b("available backends:",n),n.includes(e.config.backend)||(b(`error: backend ${e.config.backend} not found in registry`),e.config.backend=R.node?"tensorflow":"webgl",e.config.debug&&b(`override: setting backend ${e.config.backend}`)),e.config.debug&&b("setting backend:",e.config.backend),e.config.backend==="wasm"){if(e.config.debug&&b("wasm path:",e.config.wasmPath),typeof(r==null?void 0:r.setWasmPaths)!="undefined")await r.setWasmPaths(e.config.wasmPath,e.config.wasmPlatformFetch);else throw new Error("backend error: attempting to use wasm backend but wasm path is not set");let A=await r.env().getAsync("WASM_HAS_SIMD_SUPPORT"),s=await r.env().getAsync("WASM_HAS_MULTITHREAD_SUPPORT");e.config.debug&&b(`wasm execution: ${A?"SIMD":"no SIMD"} ${s?"multithreaded":"singlethreaded"}`),e.config.debug&&!A&&b("warning: wasm simd support is not enabled")}try{await r.setBackend(e.config.backend),await r.ready(),Vo()}catch(A){return b("error: cannot set backend:",e.config.backend,A),!1}}if(r.getBackend()==="humangl"&&(r.ENV.set("CHECK_COMPUTATION_FOR_ERRORS",!1),r.ENV.set("WEBGL_CPU_FORWARD",!0),r.ENV.set("WEBGL_USE_SHAPES_UNIFORMS",!0),r.ENV.set("CPU_HANDOFF_SIZE_THRESHOLD",256),typeof e.config.deallocate!="undefined"&&e.config.deallocate&&(b("changing webgl: WEBGL_DELETE_TEXTURE_THRESHOLD:",!0),r.ENV.set("WEBGL_DELETE_TEXTURE_THRESHOLD",0)),r.backend().getGPGPUContext)){let n=await r.backend().getGPGPUContext().gl;e.config.debug&&b(`gl version:${n.getParameter(n.VERSION)} renderer:${n.getParameter(n.RENDERER)}`)}r.getBackend(),r.enableProdMode(),await r.ready(),e.performance.initBackend=Math.trunc(g()-o),e.config.backend=r.getBackend(),await R.updateBackend(),F2()}return!0}function wt(e,t){for(let o of e){let n={kernelName:o,backendName:t.backend,kernelFunc:()=>{t.debug&&b("kernelFunc",o,t.backend)}};r.registerKernel(n)}R.kernels=r.getKernelsForBackend(r.getBackend()).map(o=>o.kernelName.toLowerCase())}var er={};ee(er,{all:()=>mo,body:()=>ze,canvas:()=>fo,face:()=>Ee,gesture:()=>We,hand:()=>je,object:()=>Se,options:()=>n0,person:()=>co});var n0={color:"rgba(173, 216, 230, 0.6)",labelColor:"rgba(173, 216, 230, 1)",shadowColor:"black",alpha:.5,font:'small-caps 16px "Segoe UI"',lineHeight:18,lineWidth:4,pointSize:2,roundRect:8,drawPoints:!1,drawLabels:!0,drawBoxes:!0,drawAttention:!0,drawGestures:!0,drawPolygons:!0,drawGaze:!0,fillPolygons:!1,useDepth:!0,useCurves:!1};var h0=e=>{if(!e)b("draw error: invalid canvas");else if(!e.getContext)b("draw error: canvas context not defined");else{let t=e.getContext("2d");if(!t)b("draw error: cannot get canvas context");else return t}return null},le=e=>Math.round(e*180/Math.PI),S0=(e,t=[!0,!0,!1])=>{let o=t[0]?127+Math.trunc(3*e):255,n=t[1]?127-Math.trunc(3*e):255,A=t[2]?127-Math.trunc(3*e):255;return`rgba(${o}, ${n}, ${A}, ${n0.alpha})`};function ye(e,t,o,n,A){n=n||0,e.fillStyle=A.useDepth&&n?S0(n,n===-255?[!0,!1,!0]:[!0,!1,!1]):A.color,e.beginPath(),e.arc(t,o,A.pointSize,0,2*Math.PI),e.fill()}function W0(e,t,o,n,A,s){if(e.beginPath(),e.lineWidth=s.lineWidth,s.useCurves){let a=(t+t+n)/2,i=(o+o+A)/2;e.ellipse(a,i,n/2,A/2,0,0,2*Math.PI)}else e.moveTo(t+s.roundRect,o),e.lineTo(t+n-s.roundRect,o),e.quadraticCurveTo(t+n,o,t+n,o+s.roundRect),e.lineTo(t+n,o+A-s.roundRect),e.quadraticCurveTo(t+n,o+A,t+n-s.roundRect,o+A),e.lineTo(t+s.roundRect,o+A),e.quadraticCurveTo(t,o+A,t,o+A-s.roundRect),e.lineTo(t,o+s.roundRect),e.quadraticCurveTo(t,o,t+s.roundRect,o),e.closePath();e.stroke()}function lo(e,t,o){if(!(t.length<2)){e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n of t){let A=n[2]||0;e.strokeStyle=o.useDepth&&A!==0?S0(A):o.color,e.fillStyle=o.useDepth&&A!==0?S0(A):o.color,e.lineTo(n[0],Math.round(n[1]))}e.stroke(),o.fillPolygons&&(e.closePath(),e.fill())}}function $A(e,t,o){if(!(t.length<2)){if(e.lineWidth=o.lineWidth,!o.useCurves||t.length<=2){lo(e,t,o);return}e.moveTo(t[0][0],t[0][1]);for(let n=0;n0){let c=l.emotion.map(f=>`${Math.trunc(100*f.score)}% ${f.emotion}`);c.length>3&&(c.length=3),y.push(c.join(" "))}l.rotation&&l.rotation.angle&&l.rotation.gaze&&(l.rotation.angle.roll&&y.push(`roll: ${le(l.rotation.angle.roll)}\xB0 yaw:${le(l.rotation.angle.yaw)}\xB0 pitch:${le(l.rotation.angle.pitch)}\xB0`),l.rotation.gaze.bearing&&y.push(`gaze: ${le(l.rotation.gaze.bearing)}\xB0`)),y.length===0&&y.push("face"),A.fillStyle=n.color;for(let c=y.length-1;c>=0;c--){let f=Math.max(l.box[0],0),h=c*n.lineHeight+l.box[1];n.shadowColor&&n.shadowColor!==""&&(A.fillStyle=n.shadowColor,A.fillText(y[c],f+5,h+16)),A.fillStyle=n.labelColor,A.fillText(y[c],f+4,h+15)}}if(A.lineWidth=2,l.mesh&&l.mesh.length>0){if(n.drawPoints){let y=Math.max(468,l.mesh.length);for(let c=0;c468)for(let y=468;y450)for(let y=0;yl.mesh[f]);lo(A,c,n)}if(l.annotations&&l.annotations.leftEyeIris&&l.annotations.leftEyeIris[0]){A.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.color,A.beginPath();let y=Math.abs(l.annotations.leftEyeIris[3][0]-l.annotations.leftEyeIris[1][0])/2,c=Math.abs(l.annotations.leftEyeIris[4][1]-l.annotations.leftEyeIris[2][1])/2;A.ellipse(l.annotations.leftEyeIris[0][0],l.annotations.leftEyeIris[0][1],y,c,0,0,2*Math.PI),A.stroke(),n.fillPolygons&&(A.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.color,A.fill())}if(l.annotations&&l.annotations.rightEyeIris&&l.annotations.rightEyeIris[0]){A.strokeStyle=n.useDepth?"rgba(255, 200, 255, 0.3)":n.color,A.beginPath();let y=Math.abs(l.annotations.rightEyeIris[3][0]-l.annotations.rightEyeIris[1][0])/2,c=Math.abs(l.annotations.rightEyeIris[4][1]-l.annotations.rightEyeIris[2][1])/2;A.ellipse(l.annotations.rightEyeIris[0][0],l.annotations.rightEyeIris[0][1],y,c,0,0,2*Math.PI),A.stroke(),n.fillPolygons&&(A.fillStyle=n.useDepth?"rgba(255, 255, 200, 0.3)":n.color,A.fill())}if(n.drawGaze&&((s=l.rotation)==null?void 0:s.angle)&&typeof Path2D!="undefined"){A.strokeStyle="pink";let y=l.box[0]+l.box[2]/2-l.box[3]*le(l.rotation.angle.yaw)/90,c=l.box[1]+l.box[3]/2+l.box[2]*le(l.rotation.angle.pitch)/90,f=new Path2D(`
M ${l.box[0]+l.box[2]/2} ${l.box[1]}
C
${y} ${l.box[1]},
@@ -108,7 +108,7 @@ var Ft=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var dr=Objec
${l.box[0]} ${c},
${l.box[0]+l.box[2]} ${c},
${l.box[0]+l.box[2]} ${l.box[1]+l.box[3]/2}
- `);A.stroke(h),A.stroke(f)}if(n.drawGaze&&((i=(a=l.rotation)==null?void 0:a.gaze)==null?void 0:i.strength)&&((d=(x=l.rotation)==null?void 0:x.gaze)==null?void 0:d.bearing)&&l.annotations.leftEyeIris&&l.annotations.rightEyeIris&&l.annotations.leftEyeIris[0]&&l.annotations.rightEyeIris[0]){A.strokeStyle="pink",A.fillStyle="pink";let y=[l.annotations.leftEyeIris[0][0]+Math.sin(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[3],l.annotations.leftEyeIris[0][1]+Math.cos(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[2]];lo(A,[l.annotations.leftEyeIris[0][0],l.annotations.leftEyeIris[0][1]],[y[0],y[1]],4);let c=[l.annotations.rightEyeIris[0][0]+Math.sin(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[3],l.annotations.rightEyeIris[0][1]+Math.cos(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[2]];lo(A,[l.annotations.rightEyeIris[0][0],l.annotations.rightEyeIris[0][1]],[c[0],c[1]],4)}}}}}async function Ee(e,t,o){var s;let n=Y(n0,o);if(!t||!e)return;let A=h0(e);if(!!A){A.lineJoin="round";for(let a=0;a0)for(let a of s.keypoints)A.fillStyle=n.useDepth?j0(a[2]||0):n.color,le(A,a[0],a[1],0,n);if(n.drawLabels&&s.annotations){let a=(i,x)=>{if(!i||i.length===0||!i[0])return;let d=i[i.length-1][2]||0;A.fillStyle=n.useDepth?j0(d):n.color,A.fillText(x,i[i.length-1][0]+4,i[i.length-1][1]+4)};A.font=n.font,a(s.annotations.index,"index"),a(s.annotations.middle,"middle"),a(s.annotations.ring,"ring"),a(s.annotations.pinky,"pinky"),a(s.annotations.thumb,"thumb"),a(s.annotations.palm,"palm")}if(n.drawPolygons&&s.annotations){let a=i=>{if(!(!i||i.length===0||!i[0]))for(let x=0;x0?x-1:0][0],i[x>0?x-1:0][1]),A.lineTo(i[x][0],i[x][1]),A.stroke()}};A.lineWidth=n.lineWidth,a(s.annotations.index),a(s.annotations.middle),a(s.annotations.ring),a(s.annotations.pinky),a(s.annotations.thumb)}}}}async function je(e,t,o){let n=Y(n0,o);if(!t||!e)return;let A=h0(e);if(!!A){A.lineJoin="round",A.font=n.font;for(let s of t)if(n.drawBoxes){if(A.strokeStyle=n.color,A.fillStyle=n.color,S0(A,s.box[0],s.box[1],s.box[2],s.box[3],n),n.drawLabels){let a=`${s.label} ${Math.round(100*s.score)}%`;n.shadowColor&&n.shadowColor!==""&&(A.fillStyle=n.shadowColor,A.fillText(a,s.box[0]+3,1+s.box[1]+n.lineHeight,s.box[2])),A.fillStyle=n.labelColor,A.fillText(a,s.box[0]+2,0+s.box[1]+n.lineHeight,s.box[2])}A.stroke()}}}async function Se(e,t,o){let n=Y(n0,o);if(!(!t||!e)&&n.drawGestures){let A=h0(e);if(!A)return;A.font=n.font,A.fillStyle=n.color;let s=1;for(let a=0;a1&&x[1].length>0){let d=i[1]>0?`#${i[1]}`:"",l=`${i[0]} ${d}: ${x[1]}`;n.shadowColor&&n.shadowColor!==""&&(A.fillStyle=n.shadowColor,A.fillText(l,8,2+s*n.lineHeight)),A.fillStyle=n.labelColor,A.fillText(l,6,0+s*n.lineHeight),s+=1}}}}var yo=0;async function xo(e,t,o){let n=Y(n0,o);if(!t||!e)return;let A=h0(e);if(!!A){A.lineJoin="round",A.font=n.font;for(let s=0;st!=o[A].y>t&&e<(o[A].x-o[s].x)*(t-o[s].y)/(o[A].y-o[s].y)+o[s].x&&(n=!n);return n}async function er(e){if(!e.tensor||!e.mesh||e.mesh.length<100)return e.tensor;let t=e.tensor.shape[2]||0,o=e.tensor.shape[1]||0,n=await e.tensor.buffer(),A=[];for(let a of M0.silhouette)A.push({x:(e.mesh[a][0]-e.box[0])/e.box[2],y:(e.mesh[a][1]-e.box[1])/e.box[3]});Ce&&Ce>0&&(A=A.map(a=>({x:a.x>.5?a.x+Ce:a.x-Ce,y:a.y>.5?a.y+Ce:a.y-Ce})));for(let a=0;a{let t=(y,c)=>Math.atan2(y[1]-c[1],y[0]-c[0]);if(!e.annotations.rightEyeIris||!e.annotations.leftEyeIris)return{bearing:0,strength:0};let o=[0,-.1],n=1,A=(e.mesh[33][2]||0)>(e.mesh[263][2]||0),s=A?e.mesh[473]:e.mesh[468],a=A?[(e.mesh[133][0]+e.mesh[33][0])/2,(e.mesh[133][1]+e.mesh[33][1])/2]:[(e.mesh[263][0]+e.mesh[362][0])/2,(e.mesh[263][1]+e.mesh[362][1])/2],i=A?[e.mesh[133][0]-e.mesh[33][0],e.mesh[23][1]-e.mesh[27][1]]:[e.mesh[263][0]-e.mesh[362][0],e.mesh[253][1]-e.mesh[257][1]],x=[(a[0]-s[0])/i[0]-o[0],n*(s[1]-a[1])/i[1]-o[1]],d=Math.sqrt(x[0]*x[0]+x[1]*x[1]);return d=Math.min(d,e.boxRaw[2]/2,e.boxRaw[3]/2),{bearing:(t([0,0],x)+Math.PI/2)%Math.PI,strength:d}},tr=(e,t)=>{let o=m=>{let v=Math.sqrt(m[0]*m[0]+m[1]*m[1]+m[2]*m[2]);return m[0]/=v,m[1]/=v,m[2]/=v,m},n=(m,v)=>{let M=m[0]-v[0],u=m[1]-v[1],p=m[2]-v[2];return[M,u,p]},A=(m,v)=>{let M=m[1]*v[2]-m[2]*v[1],u=m[2]*v[0]-m[0]*v[2],p=m[0]*v[1]-m[1]*v[0];return[M,u,p]},s=m=>{let[v,M,u,p,P,R,S,O,C]=m,I,V,G;return p<1?p>-1?(G=Math.asin(p),V=Math.atan2(-S,v),I=Math.atan2(-R,P)):(G=-Math.PI/2,V=-Math.atan2(O,C),I=0):(G=Math.PI/2,V=Math.atan2(O,C),I=0),isNaN(I)&&(I=0),isNaN(V)&&(V=0),isNaN(G)&&(G=0),{pitch:2*-I,yaw:2*-V,roll:2*-G}},a=e.meshRaw;if(!a||a.length<300)return{angle:{pitch:0,yaw:0,roll:0},matrix:[1,0,0,0,1,0,0,0,1],gaze:{bearing:0,strength:0}};let i=Math.max(e.boxRaw[2]*t[0],e.boxRaw[3]*t[1])/1.5,x=[a[10],a[152],a[234],a[454]].map(m=>[m[0]*t[0]/i,m[1]*t[1]/i,m[2]]),d=o(n(x[1],x[0])),l=o(n(x[3],x[2])),y=o(A(l,d));l=A(d,y);let c=[l[0],l[1],l[2],d[0],d[1],d[2],y[0],y[1],y[2]],f=s(c),h=a.length===478?Z2(e):{bearing:0,strength:0};return{angle:f,matrix:c,gaze:h}};var po=async(e,t)=>{var f,h,m,v,M,u,p,P,R,S,O,C,I,V,G,B,J,z,p0,V0,T,e0;let o=g(),n,A,s,a,i,x,d,l,y=[];e.state="run:face";let c=await qn(t,e.config);if(e.performance.face=w.perfadd?(e.performance.face||0)+Math.trunc(g()-o):Math.trunc(g()-o),!t.shape||t.shape.length!==4)return[];if(!c)return[];for(let E=0;E200?tr(c[E],[t.shape[2],t.shape[1]]):null;e.analyze("Start Emotion:"),e.config.async?a=(h=e.config.face.emotion)!=null&&h.enabled?v5(c[E].tensor||r.tensor([]),e.config,E,c.length):[]:(e.state="run:emotion",o=g(),a=(m=e.config.face.emotion)!=null&&m.enabled?await v5(c[E].tensor||r.tensor([]),e.config,E,c.length):[],e.performance.emotion=w.perfadd?(e.performance.emotion||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End Emotion:"),e.analyze("Start AntiSpoof:"),e.config.async?x=(v=e.config.face.antispoof)!=null&&v.enabled?o5(c[E].tensor||r.tensor([]),e.config,E,c.length):0:(e.state="run:antispoof",o=g(),x=(M=e.config.face.antispoof)!=null&&M.enabled?await o5(c[E].tensor||r.tensor([]),e.config,E,c.length):0,e.performance.antispoof=w.perfadd?(e.performance.antispoof||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End AntiSpoof:"),e.analyze("Start Liveness:"),e.config.async?d=(u=e.config.face.liveness)!=null&&u.enabled?Z5(c[E].tensor||r.tensor([]),e.config,E,c.length):0:(e.state="run:liveness",o=g(),d=(p=e.config.face.liveness)!=null&&p.enabled?await Z5(c[E].tensor||r.tensor([]),e.config,E,c.length):0,e.performance.liveness=w.perfadd?(e.performance.antispoof||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End Liveness:"),e.analyze("Start GEAR:"),e.config.async?A=(P=e.config.face.gear)!=null&&P.enabled?Yt(c[E].tensor||r.tensor([]),e.config,E,c.length):null:(e.state="run:gear",o=g(),A=(R=e.config.face.gear)!=null&&R.enabled?await Yt(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.gear=Math.trunc(g()-o)),e.analyze("End GEAR:"),e.analyze("Start SSRNet:"),e.config.async?(n=(S=e.config.face.ssrnet)!=null&&S.enabled?Qt(c[E].tensor||r.tensor([]),e.config,E,c.length):null,s=(O=e.config.face.ssrnet)!=null&&O.enabled?e5(c[E].tensor||r.tensor([]),e.config,E,c.length):null):(e.state="run:ssrnet",o=g(),n=(C=e.config.face.ssrnet)!=null&&C.enabled?await Qt(c[E].tensor||r.tensor([]),e.config,E,c.length):null,s=(I=e.config.face.ssrnet)!=null&&I.enabled?await e5(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.ssrnet=Math.trunc(g()-o)),e.analyze("End SSRNet:"),e.analyze("Start MobileFaceNet:"),e.config.async?i=(V=e.config.face.mobilefacenet)!=null&&V.enabled?w5(c[E].tensor||r.tensor([]),e.config,E,c.length):null:(e.state="run:mobilefacenet",o=g(),i=(G=e.config.face.mobilefacenet)!=null&&G.enabled?await w5(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.mobilefacenet=Math.trunc(g()-o)),e.analyze("End MobileFaceNet:"),e.analyze("Start Description:"),e.config.async?l=(B=e.config.face.description)!=null&&B.enabled?S5(c[E].tensor||r.tensor([]),e.config,E,c.length):null:(e.state="run:description",o=g(),l=(J=e.config.face.description)!=null&&J.enabled?await S5(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.description=w.perfadd?(e.performance.description||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End Description:"),e.config.async&&([n,s,a,i,l,A,x,d]=await Promise.all([n,s,a,i,l,A,x,d])),e.analyze("Finish Face:"),((z=e.config.face.ssrnet)==null?void 0:z.enabled)&&n&&s&&(l={...l,age:n.age,gender:s.gender,genderScore:s.genderScore}),((p0=e.config.face.gear)==null?void 0:p0.enabled)&&A&&(l={...l,age:A.age,gender:A.gender,genderScore:A.genderScore,race:A.race}),((V0=e.config.face.mobilefacenet)==null?void 0:V0.enabled)&&i&&(l.descriptor=i),(T=e.config.face.iris)!=null&&T.enabled;let Q=c[E].annotations&&c[E].annotations.leftEyeIris&&c[E].annotations.leftEyeIris[0]&&c[E].annotations.rightEyeIris&&c[E].annotations.rightEyeIris[0]&&c[E].annotations.leftEyeIris.length>0&&c[E].annotations.rightEyeIris.length>0&&c[E].annotations.leftEyeIris[0]!==null&&c[E].annotations.rightEyeIris[0]!==null?Math.max(Math.abs(c[E].annotations.leftEyeIris[3][0]-c[E].annotations.leftEyeIris[1][0]),Math.abs(c[E].annotations.rightEyeIris[4][1]-c[E].annotations.rightEyeIris[2][1]))/t.shape[2]:0,o0=(e0=e.config.face.detector)!=null&&e0.return?r.squeeze(c[E].tensor):null;r.dispose(c[E].tensor),c[E].tensor&&delete c[E].tensor;let W={...c[E],id:E};l!=null&&l.age&&(W.age=l.age),l!=null&&l.gender&&(W.gender=l.gender),l!=null&&l.genderScore&&(W.genderScore=l==null?void 0:l.genderScore),l!=null&&l.descriptor&&(W.embedding=l==null?void 0:l.descriptor),l!=null&&l.race&&(W.race=l==null?void 0:l.race),a&&(W.emotion=a),x&&(W.real=x),d&&(W.live=d),Q&&Q!==0&&(W.iris=Math.trunc(500/Q/11.7)/100),X&&(W.rotation=X),o0&&(W.tensor=o0),y.push(W),e.analyze("End Face")}return e.analyze("End FaceMesh:"),e.config.async&&(e.performance.face&&delete e.performance.face,e.performance.age&&delete e.performance.age,e.performance.gender&&delete e.performance.gender,e.performance.emotion&&delete e.performance.emotion),y};var or=e=>{if(!e)return[];let t=[];for(let o=0;ox.part==="leftWrist"),A=e[o].keypoints.find(x=>x.part==="rightWrist"),s=e[o].keypoints.find(x=>x.part==="nose");s&&n&&A&&n.position[1]x.part==="leftShoulder"),i=e[o].keypoints.find(x=>x.part==="rightShoulder");a&&i&&Math.abs(a.positionRaw[1]-i.positionRaw[1])>.1&&t.push({body:o,gesture:`leaning ${a.position[1]>i.position[1]?"left":"right"}`})}return t},nr=e=>{if(!e)return[];let t=[];for(let o=0;o450){let n=(e[o].mesh[33][2]||0)-(e[o].mesh[263][2]||0),A=e[o].mesh[33][0]-e[o].mesh[263][0];Math.abs(n/A)<=.15?t.push({face:o,gesture:"facing center"}):t.push({face:o,gesture:`facing ${n<0?"left":"right"}`}),Math.abs(e[o].mesh[374][1]-e[o].mesh[386][1])/Math.abs(e[o].mesh[443][1]-e[o].mesh[450][1])<.2&&t.push({face:o,gesture:"blink left eye"}),Math.abs(e[o].mesh[145][1]-e[o].mesh[159][1])/Math.abs(e[o].mesh[223][1]-e[o].mesh[230][1])<.2&&t.push({face:o,gesture:"blink right eye"});let i=Math.min(100,500*Math.abs(e[o].mesh[13][1]-e[o].mesh[14][1])/Math.abs(e[o].mesh[10][1]-e[o].mesh[152][1]));i>10&&t.push({face:o,gesture:`mouth ${Math.trunc(i)}% open`});let x=e[o].mesh[152][2]||0;Math.abs(x)>10&&t.push({face:o,gesture:`head ${x<0?"up":"down"}`})}return t},Ar=e=>{if(!e)return[];let t=[];for(let o=0;o.06||c>.06)&&(d=!1),y>c?y>.05&&t.push({iris:o,gesture:"looking right"}):c>.05&&t.push({iris:o,gesture:"looking left"});let f=Math.abs(e[o].mesh[145][1]-e[o].annotations.rightEyeIris[0][1])/e[o].box[3],h=Math.abs(e[o].mesh[374][1]-e[o].annotations.leftEyeIris[0][1])/e[o].box[3];(h<.01||f<.01||h>.022||f>.022)&&(d=!1),(h<.01||f<.01)&&t.push({iris:o,gesture:"looking down"}),(h>.022||f>.022)&&t.push({iris:o,gesture:"looking up"}),d&&t.push({iris:o,gesture:"looking center"})}return t},rr=e=>{if(!e)return[];let t=[];for(let o=0;o0){let A=n.reduce((a,i)=>(a.position[2]||0)<(i.position[2]||0)?a:i);t.push({hand:o,gesture:`${A.name} forward`});let s=n.reduce((a,i)=>a.position[1]((A-1)*j.body[T].box[H]+W)/A),E=e.body[T].boxRaw.map((W,H)=>((A-1)*j.body[T].boxRaw[H]+W)/A),X=e.body[T].keypoints.map((W,H)=>{var C0,W0,Oe,Ie,ye,go,Mo,Po,vo;return{score:W.score,part:W.part,position:[j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].position[0]||0)+(W.position[0]||0))/A:W.position[0],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].position[1]||0)+(W.position[1]||0))/A:W.position[1],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].position[2]||0)+(W.position[2]||0))/A:W.position[2]],positionRaw:[j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].positionRaw[0]||0)+(W.positionRaw[0]||0))/A:W.positionRaw[0],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].positionRaw[1]||0)+(W.positionRaw[1]||0))/A:W.positionRaw[1],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].positionRaw[2]||0)+(W.positionRaw[2]||0))/A:W.positionRaw[2]],distance:[j.body[T].keypoints[H]?((A-1)*(((C0=j.body[T].keypoints[H].distance)==null?void 0:C0[0])||0)+(((W0=W.distance)==null?void 0:W0[0])||0))/A:(Oe=W.distance)==null?void 0:Oe[0],j.body[T].keypoints[H]?((A-1)*(((Ie=j.body[T].keypoints[H].distance)==null?void 0:Ie[1])||0)+(((ye=W.distance)==null?void 0:ye[1])||0))/A:(go=W.distance)==null?void 0:go[1],j.body[T].keypoints[H]?((A-1)*(((Mo=j.body[T].keypoints[H].distance)==null?void 0:Mo[2])||0)+(((Po=W.distance)==null?void 0:Po[2])||0))/A:(vo=W.distance)==null?void 0:vo[2]]}}),Q={},o0={connected:{}};(i=(a=t.body)==null?void 0:a.modelPath)!=null&&i.includes("efficientpose")?o0=ft:(d=(x=t.body)==null?void 0:x.modelPath)!=null&&d.includes("blazepose")?o0=lt:(y=(l=t.body)==null?void 0:l.modelPath)!=null&&y.includes("movenet")&&(o0=qe);for(let[W,H]of Object.entries(o0.connected)){let C0=[];for(let W0=0;W0ye.part===H[W0]),Ie=X.find(ye=>ye.part===H[W0+1]);Oe&&Ie&&C0.push([Oe.position,Ie.position])}Q[W]=C0}j.body[T]={...e.body[T],box:e0,boxRaw:E,keypoints:X,annotations:Q}}if(!j.hand||e.hand.length!==j.hand.length)j.hand=JSON.parse(JSON.stringify(e.hand));else for(let T=0;T((A-1)*j.hand[T].box[W]+o0)/A),E=e.hand[T].boxRaw.map((o0,W)=>((A-1)*j.hand[T].boxRaw[W]+o0)/A);j.hand[T].keypoints.length!==e.hand[T].keypoints.length&&(j.hand[T].keypoints=e.hand[T].keypoints);let X=e.hand[T].keypoints&&e.hand[T].keypoints.length>0?e.hand[T].keypoints.map((o0,W)=>o0.map((H,C0)=>((A-1)*(j.hand[T].keypoints[W][C0]||1)+(H||0))/A)):[],Q={};if(Object.keys(j.hand[T].annotations).length!==Object.keys(e.hand[T].annotations).length)j.hand[T].annotations=e.hand[T].annotations,Q=j.hand[T].annotations;else if(e.hand[T].annotations)for(let o0 of Object.keys(e.hand[T].annotations))Q[o0]=e.hand[T].annotations[o0]&&e.hand[T].annotations[o0][0]?e.hand[T].annotations[o0].map((W,H)=>W.map((C0,W0)=>((A-1)*j.hand[T].annotations[o0][H][W0]+C0)/A)):null;j.hand[T]={...e.hand[T],box:e0,boxRaw:E,keypoints:X,annotations:Q}}if(!j.face||e.face.length!==j.face.length)j.face=JSON.parse(JSON.stringify(e.face));else for(let T=0;T((A-1)*j.face[T].box[Q]+X)/A),E=e.face[T].boxRaw.map((X,Q)=>((A-1)*j.face[T].boxRaw[Q]+X)/A);if(e.face[T].rotation){let X={matrix:[0,0,0,0,0,0,0,0,0],angle:{roll:0,yaw:0,pitch:0},gaze:{bearing:0,strength:0}};X.matrix=(c=e.face[T].rotation)==null?void 0:c.matrix,X.angle={roll:((A-1)*(((h=(f=j.face[T].rotation)==null?void 0:f.angle)==null?void 0:h.roll)||0)+(((v=(m=e.face[T].rotation)==null?void 0:m.angle)==null?void 0:v.roll)||0))/A,yaw:((A-1)*(((u=(M=j.face[T].rotation)==null?void 0:M.angle)==null?void 0:u.yaw)||0)+(((P=(p=e.face[T].rotation)==null?void 0:p.angle)==null?void 0:P.yaw)||0))/A,pitch:((A-1)*(((S=(R=j.face[T].rotation)==null?void 0:R.angle)==null?void 0:S.pitch)||0)+(((C=(O=e.face[T].rotation)==null?void 0:O.angle)==null?void 0:C.pitch)||0))/A},X.gaze={bearing:((A-1)*(((V=(I=j.face[T].rotation)==null?void 0:I.gaze)==null?void 0:V.bearing)||0)+(((B=(G=e.face[T].rotation)==null?void 0:G.gaze)==null?void 0:B.bearing)||0))/A,strength:((A-1)*(((z=(J=j.face[T].rotation)==null?void 0:J.gaze)==null?void 0:z.strength)||0)+(((V0=(p0=e.face[T].rotation)==null?void 0:p0.gaze)==null?void 0:V0.strength)||0))/A},j.face[T]={...e.face[T],rotation:X,box:e0,boxRaw:E}}j.face[T]={...e.face[T],box:e0,boxRaw:E}}if(!j.object||e.object.length!==j.object.length)j.object=JSON.parse(JSON.stringify(e.object));else for(let T=0;T((A-1)*j.object[T].box[Q]+X)/A),E=e.object[T].boxRaw.map((X,Q)=>((A-1)*j.object[T].boxRaw[Q]+X)/A);j.object[T]={...e.object[T],box:e0,boxRaw:E}}if(e.persons){let T=e.persons;if(!j.persons||T.length!==j.persons.length)j.persons=JSON.parse(JSON.stringify(T));else for(let e0=0;e0((A-1)*j.persons[e0].box[X]+E)/A)}e.gesture&&(j.gesture=e.gesture);let s=g();return uo=w.perfadd?uo+Math.round(s-o):Math.round(s-o),e.performance&&(j.performance={...e.performance,interpolate:uo}),j}var ir={};$0(ir,{distance:()=>Ke,match:()=>bo,similarity:()=>ho});function Ke(e,t,o={order:2,multiplier:25}){let n=0;for(let A=0;A{if(e===0)return 1;let A=t===2?Math.sqrt(e):e**(1/t),s=(1-A/100-o)/(n-o);return Math.max(Math.min(s,1),0)};function ho(e,t,o={order:2,multiplier:25,min:.2,max:.8}){let n=Ke(e,t,o);return ar(n,o.order||2,o.min||0,o.max||1)}function bo(e,t,o={order:2,multiplier:25,threshold:0,min:.2,max:.8}){if(!Array.isArray(e)||!Array.isArray(t)||e.length<64||t.length===0||e.length!==t[0].length)return{index:-1,distance:Number.POSITIVE_INFINITY,similarity:0};let n=Number.MAX_SAFE_INTEGER,A=-1;for(let a=0;az.box[0]&&O.box[0]z.box[1]&&O.box[1]+O.box[3]C.body.box[0]&&z.box[0]+z.box[2]C.body.box[1]&&z.box[1]+z.box[3]C.body.box[0]&&z.box[1]+z.box[3]>C.body.box[1]&&z.box[1]+z.box[3]{z&&z.length===4&&(I.push(z[0],z[0]+z[2]),V.push(z[1],z[1]+z[3]))};G((M=C.face)==null?void 0:M.box),G((u=C.body)==null?void 0:u.box),G((P=(p=C.hands)==null?void 0:p.left)==null?void 0:P.box),G((S=(R=C.hands)==null?void 0:R.right)==null?void 0:S.box);let B=Math.min(...I),J=Math.min(...V);C.box=[B,J,Math.max(...I)-B,Math.max(...V)-J],A&&A[1]&&A[2]&&(C.boxRaw=[C.box[0]/A[2],C.box[1]/A[1],C.box[2]/A[2],C.box[3]/A[1]]),a.push(C)}return a}var Nt=`
+ `);A.stroke(h),A.stroke(f)}if(n.drawGaze&&((i=(a=l.rotation)==null?void 0:a.gaze)==null?void 0:i.strength)&&((d=(x=l.rotation)==null?void 0:x.gaze)==null?void 0:d.bearing)&&l.annotations.leftEyeIris&&l.annotations.rightEyeIris&&l.annotations.leftEyeIris[0]&&l.annotations.rightEyeIris[0]){A.strokeStyle="pink",A.fillStyle="pink";let y=[l.annotations.leftEyeIris[0][0]+Math.sin(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[3],l.annotations.leftEyeIris[0][1]+Math.cos(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[2]];yo(A,[l.annotations.leftEyeIris[0][0],l.annotations.leftEyeIris[0][1]],[y[0],y[1]],4);let c=[l.annotations.rightEyeIris[0][0]+Math.sin(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[3],l.annotations.rightEyeIris[0][1]+Math.cos(l.rotation.gaze.bearing)*l.rotation.gaze.strength*l.box[2]];yo(A,[l.annotations.rightEyeIris[0][0],l.annotations.rightEyeIris[0][1]],[c[0],c[1]],4)}}}}}async function ze(e,t,o){var s;let n=Y(n0,o);if(!t||!e)return;let A=h0(e);if(!!A){A.lineJoin="round";for(let a=0;a0)for(let a of s.keypoints)A.fillStyle=n.useDepth?S0(a[2]||0):n.color,ye(A,a[0],a[1],0,n);if(n.drawLabels&&s.annotations){let a=(i,x)=>{if(!i||i.length===0||!i[0])return;let d=i[i.length-1][2]||0;A.fillStyle=n.useDepth?S0(d):n.color,A.fillText(x,i[i.length-1][0]+4,i[i.length-1][1]+4)};A.font=n.font,a(s.annotations.index,"index"),a(s.annotations.middle,"middle"),a(s.annotations.ring,"ring"),a(s.annotations.pinky,"pinky"),a(s.annotations.thumb,"thumb"),a(s.annotations.palm,"palm")}if(n.drawPolygons&&s.annotations){let a=i=>{if(!(!i||i.length===0||!i[0]))for(let x=0;x0?x-1:0][0],i[x>0?x-1:0][1]),A.lineTo(i[x][0],i[x][1]),A.stroke()}};A.lineWidth=n.lineWidth,a(s.annotations.index),a(s.annotations.middle),a(s.annotations.ring),a(s.annotations.pinky),a(s.annotations.thumb)}}}}async function Se(e,t,o){let n=Y(n0,o);if(!t||!e)return;let A=h0(e);if(!!A){A.lineJoin="round",A.font=n.font;for(let s of t)if(n.drawBoxes){if(A.strokeStyle=n.color,A.fillStyle=n.color,W0(A,s.box[0],s.box[1],s.box[2],s.box[3],n),n.drawLabels){let a=`${s.label} ${Math.round(100*s.score)}%`;n.shadowColor&&n.shadowColor!==""&&(A.fillStyle=n.shadowColor,A.fillText(a,s.box[0]+3,1+s.box[1]+n.lineHeight,s.box[2])),A.fillStyle=n.labelColor,A.fillText(a,s.box[0]+2,0+s.box[1]+n.lineHeight,s.box[2])}A.stroke()}}}async function We(e,t,o){let n=Y(n0,o);if(!(!t||!e)&&n.drawGestures){let A=h0(e);if(!A)return;A.font=n.font,A.fillStyle=n.color;let s=1;for(let a=0;a1&&x[1].length>0){let d=i[1]>0?`#${i[1]}`:"",l=`${i[0]} ${d}: ${x[1]}`;n.shadowColor&&n.shadowColor!==""&&(A.fillStyle=n.shadowColor,A.fillText(l,8,2+s*n.lineHeight)),A.fillStyle=n.labelColor,A.fillText(l,6,0+s*n.lineHeight),s+=1}}}}var xo=0;async function co(e,t,o){let n=Y(n0,o);if(!t||!e)return;let A=h0(e);if(!!A){A.lineJoin="round",A.font=n.font;for(let s=0;st!=o[A].y>t&&e<(o[A].x-o[s].x)*(t-o[s].y)/(o[A].y-o[s].y)+o[s].x&&(n=!n);return n}async function tr(e){if(!e.tensor||!e.mesh||e.mesh.length<100)return e.tensor;let t=e.tensor.shape[2]||0,o=e.tensor.shape[1]||0,n=await e.tensor.buffer(),A=[];for(let a of M0.silhouette)A.push({x:(e.mesh[a][0]-e.box[0])/e.box[2],y:(e.mesh[a][1]-e.box[1])/e.box[3]});Ce&&Ce>0&&(A=A.map(a=>({x:a.x>.5?a.x+Ce:a.x-Ce,y:a.y>.5?a.y+Ce:a.y-Ce})));for(let a=0;a{let t=(y,c)=>Math.atan2(y[1]-c[1],y[0]-c[0]);if(!e.annotations.rightEyeIris||!e.annotations.leftEyeIris)return{bearing:0,strength:0};let o=[0,-.1],n=1,A=(e.mesh[33][2]||0)>(e.mesh[263][2]||0),s=A?e.mesh[473]:e.mesh[468],a=A?[(e.mesh[133][0]+e.mesh[33][0])/2,(e.mesh[133][1]+e.mesh[33][1])/2]:[(e.mesh[263][0]+e.mesh[362][0])/2,(e.mesh[263][1]+e.mesh[362][1])/2],i=A?[e.mesh[133][0]-e.mesh[33][0],e.mesh[23][1]-e.mesh[27][1]]:[e.mesh[263][0]-e.mesh[362][0],e.mesh[253][1]-e.mesh[257][1]],x=[(a[0]-s[0])/i[0]-o[0],n*(s[1]-a[1])/i[1]-o[1]],d=Math.sqrt(x[0]*x[0]+x[1]*x[1]);return d=Math.min(d,e.boxRaw[2]/2,e.boxRaw[3]/2),{bearing:(t([0,0],x)+Math.PI/2)%Math.PI,strength:d}},or=(e,t)=>{let o=m=>{let v=Math.sqrt(m[0]*m[0]+m[1]*m[1]+m[2]*m[2]);return m[0]/=v,m[1]/=v,m[2]/=v,m},n=(m,v)=>{let M=m[0]-v[0],u=m[1]-v[1],p=m[2]-v[2];return[M,u,p]},A=(m,v)=>{let M=m[1]*v[2]-m[2]*v[1],u=m[2]*v[0]-m[0]*v[2],p=m[0]*v[1]-m[1]*v[0];return[M,u,p]},s=m=>{let[v,M,u,p,P,w,S,O,W]=m,I,V,G;return p<1?p>-1?(G=Math.asin(p),V=Math.atan2(-S,v),I=Math.atan2(-w,P)):(G=-Math.PI/2,V=-Math.atan2(O,W),I=0):(G=Math.PI/2,V=Math.atan2(O,W),I=0),isNaN(I)&&(I=0),isNaN(V)&&(V=0),isNaN(G)&&(G=0),{pitch:2*-I,yaw:2*-V,roll:2*-G}},a=e.meshRaw;if(!a||a.length<300)return{angle:{pitch:0,yaw:0,roll:0},matrix:[1,0,0,0,1,0,0,0,1],gaze:{bearing:0,strength:0}};let i=Math.max(e.boxRaw[2]*t[0],e.boxRaw[3]*t[1])/1.5,x=[a[10],a[152],a[234],a[454]].map(m=>[m[0]*t[0]/i,m[1]*t[1]/i,m[2]]),d=o(n(x[1],x[0])),l=o(n(x[3],x[2])),y=o(A(l,d));l=A(d,y);let c=[l[0],l[1],l[2],d[0],d[1],d[2],y[0],y[1],y[2]],f=s(c),h=a.length===478?D2(e):{bearing:0,strength:0};return{angle:f,matrix:c,gaze:h}};var uo=async(e,t)=>{var f,h,m,v,M,u,p,P,w,S,O,W,I,V,G,B,J,z,P0,p0,T,e0;let o=g(),n,A,s,a,i,x,d,l,y=[];e.state="run:face";let c=await Un(t,e.config);if(e.performance.face=R.perfadd?(e.performance.face||0)+Math.trunc(g()-o):Math.trunc(g()-o),!t.shape||t.shape.length!==4)return[];if(!c)return[];for(let E=0;E200?or(c[E],[t.shape[2],t.shape[1]]):null;e.analyze("Start Emotion:"),e.config.async?a=(h=e.config.face.emotion)!=null&&h.enabled?T5(c[E].tensor||r.tensor([]),e.config,E,c.length):[]:(e.state="run:emotion",o=g(),a=(m=e.config.face.emotion)!=null&&m.enabled?await T5(c[E].tensor||r.tensor([]),e.config,E,c.length):[],e.performance.emotion=R.perfadd?(e.performance.emotion||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End Emotion:"),e.analyze("Start AntiSpoof:"),e.config.async?x=(v=e.config.face.antispoof)!=null&&v.enabled?n5(c[E].tensor||r.tensor([]),e.config,E,c.length):0:(e.state="run:antispoof",o=g(),x=(M=e.config.face.antispoof)!=null&&M.enabled?await n5(c[E].tensor||r.tensor([]),e.config,E,c.length):0,e.performance.antispoof=R.perfadd?(e.performance.antispoof||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End AntiSpoof:"),e.analyze("Start Liveness:"),e.config.async?d=(u=e.config.face.liveness)!=null&&u.enabled?D5(c[E].tensor||r.tensor([]),e.config,E,c.length):0:(e.state="run:liveness",o=g(),d=(p=e.config.face.liveness)!=null&&p.enabled?await D5(c[E].tensor||r.tensor([]),e.config,E,c.length):0,e.performance.liveness=R.perfadd?(e.performance.antispoof||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End Liveness:"),e.analyze("Start GEAR:"),e.config.async?A=(P=e.config.face.gear)!=null&&P.enabled?Kt(c[E].tensor||r.tensor([]),e.config,E,c.length):null:(e.state="run:gear",o=g(),A=(w=e.config.face.gear)!=null&&w.enabled?await Kt(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.gear=Math.trunc(g()-o)),e.analyze("End GEAR:"),e.analyze("Start SSRNet:"),e.config.async?(n=(S=e.config.face.ssrnet)!=null&&S.enabled?_t(c[E].tensor||r.tensor([]),e.config,E,c.length):null,s=(O=e.config.face.ssrnet)!=null&&O.enabled?t5(c[E].tensor||r.tensor([]),e.config,E,c.length):null):(e.state="run:ssrnet",o=g(),n=(W=e.config.face.ssrnet)!=null&&W.enabled?await _t(c[E].tensor||r.tensor([]),e.config,E,c.length):null,s=(I=e.config.face.ssrnet)!=null&&I.enabled?await t5(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.ssrnet=Math.trunc(g()-o)),e.analyze("End SSRNet:"),e.analyze("Start MobileFaceNet:"),e.config.async?i=(V=e.config.face.mobilefacenet)!=null&&V.enabled?w5(c[E].tensor||r.tensor([]),e.config,E,c.length):null:(e.state="run:mobilefacenet",o=g(),i=(G=e.config.face.mobilefacenet)!=null&&G.enabled?await w5(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.mobilefacenet=Math.trunc(g()-o)),e.analyze("End MobileFaceNet:"),e.analyze("Start Description:"),e.config.async?l=(B=e.config.face.description)!=null&&B.enabled?W5(c[E].tensor||r.tensor([]),e.config,E,c.length):null:(e.state="run:description",o=g(),l=(J=e.config.face.description)!=null&&J.enabled?await W5(c[E].tensor||r.tensor([]),e.config,E,c.length):null,e.performance.description=R.perfadd?(e.performance.description||0)+Math.trunc(g()-o):Math.trunc(g()-o)),e.analyze("End Description:"),e.config.async&&([n,s,a,i,l,A,x,d]=await Promise.all([n,s,a,i,l,A,x,d])),e.analyze("Finish Face:"),((z=e.config.face.ssrnet)==null?void 0:z.enabled)&&n&&s&&(l={...l,age:n.age,gender:s.gender,genderScore:s.genderScore}),((P0=e.config.face.gear)==null?void 0:P0.enabled)&&A&&(l={...l,age:A.age,gender:A.gender,genderScore:A.genderScore,race:A.race}),((p0=e.config.face.mobilefacenet)==null?void 0:p0.enabled)&&i&&(l.descriptor=i),(T=e.config.face.iris)!=null&&T.enabled;let Q=c[E].annotations&&c[E].annotations.leftEyeIris&&c[E].annotations.leftEyeIris[0]&&c[E].annotations.rightEyeIris&&c[E].annotations.rightEyeIris[0]&&c[E].annotations.leftEyeIris.length>0&&c[E].annotations.rightEyeIris.length>0&&c[E].annotations.leftEyeIris[0]!==null&&c[E].annotations.rightEyeIris[0]!==null?Math.max(Math.abs(c[E].annotations.leftEyeIris[3][0]-c[E].annotations.leftEyeIris[1][0]),Math.abs(c[E].annotations.rightEyeIris[4][1]-c[E].annotations.rightEyeIris[2][1]))/t.shape[2]:0,o0=(e0=e.config.face.detector)!=null&&e0.return?r.squeeze(c[E].tensor):null;r.dispose(c[E].tensor),c[E].tensor&&delete c[E].tensor;let C={...c[E],id:E};l!=null&&l.age&&(C.age=l.age),l!=null&&l.gender&&(C.gender=l.gender),l!=null&&l.genderScore&&(C.genderScore=l==null?void 0:l.genderScore),l!=null&&l.descriptor&&(C.embedding=l==null?void 0:l.descriptor),l!=null&&l.race&&(C.race=l==null?void 0:l.race),a&&(C.emotion=a),x&&(C.real=x),d&&(C.live=d),Q&&Q!==0&&(C.iris=Math.trunc(500/Q/11.7)/100),D&&(C.rotation=D),o0&&(C.tensor=o0),y.push(C),e.analyze("End Face")}return e.analyze("End FaceMesh:"),e.config.async&&(e.performance.face&&delete e.performance.face,e.performance.age&&delete e.performance.age,e.performance.gender&&delete e.performance.gender,e.performance.emotion&&delete e.performance.emotion),y};var nr=e=>{if(!e)return[];let t=[];for(let o=0;ox.part==="leftWrist"),A=e[o].keypoints.find(x=>x.part==="rightWrist"),s=e[o].keypoints.find(x=>x.part==="nose");s&&n&&A&&n.position[1]x.part==="leftShoulder"),i=e[o].keypoints.find(x=>x.part==="rightShoulder");a&&i&&Math.abs(a.positionRaw[1]-i.positionRaw[1])>.1&&t.push({body:o,gesture:`leaning ${a.position[1]>i.position[1]?"left":"right"}`})}return t},Ar=e=>{if(!e)return[];let t=[];for(let o=0;o450){let n=(e[o].mesh[33][2]||0)-(e[o].mesh[263][2]||0),A=e[o].mesh[33][0]-e[o].mesh[263][0];Math.abs(n/A)<=.15?t.push({face:o,gesture:"facing center"}):t.push({face:o,gesture:`facing ${n<0?"left":"right"}`}),Math.abs(e[o].mesh[374][1]-e[o].mesh[386][1])/Math.abs(e[o].mesh[443][1]-e[o].mesh[450][1])<.2&&t.push({face:o,gesture:"blink left eye"}),Math.abs(e[o].mesh[145][1]-e[o].mesh[159][1])/Math.abs(e[o].mesh[223][1]-e[o].mesh[230][1])<.2&&t.push({face:o,gesture:"blink right eye"});let i=Math.min(100,500*Math.abs(e[o].mesh[13][1]-e[o].mesh[14][1])/Math.abs(e[o].mesh[10][1]-e[o].mesh[152][1]));i>10&&t.push({face:o,gesture:`mouth ${Math.trunc(i)}% open`});let x=e[o].mesh[152][2]||0;Math.abs(x)>10&&t.push({face:o,gesture:`head ${x<0?"up":"down"}`})}return t},rr=e=>{if(!e)return[];let t=[];for(let o=0;o.06||c>.06)&&(d=!1),y>c?y>.05&&t.push({iris:o,gesture:"looking right"}):c>.05&&t.push({iris:o,gesture:"looking left"});let f=Math.abs(e[o].mesh[145][1]-e[o].annotations.rightEyeIris[0][1])/e[o].box[3],h=Math.abs(e[o].mesh[374][1]-e[o].annotations.leftEyeIris[0][1])/e[o].box[3];(h<.01||f<.01||h>.022||f>.022)&&(d=!1),(h<.01||f<.01)&&t.push({iris:o,gesture:"looking down"}),(h>.022||f>.022)&&t.push({iris:o,gesture:"looking up"}),d&&t.push({iris:o,gesture:"looking center"})}return t},sr=e=>{if(!e)return[];let t=[];for(let o=0;o0){let A=n.reduce((a,i)=>(a.position[2]||0)<(i.position[2]||0)?a:i);t.push({hand:o,gesture:`${A.name} forward`});let s=n.reduce((a,i)=>a.position[1]((A-1)*j.body[T].box[H]+C)/A),E=e.body[T].boxRaw.map((C,H)=>((A-1)*j.body[T].boxRaw[H]+C)/A),D=e.body[T].keypoints.map((C,H)=>{var C0,O0,Ie,Le,xe,Mo,Po,vo,To;return{score:C.score,part:C.part,position:[j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].position[0]||0)+(C.position[0]||0))/A:C.position[0],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].position[1]||0)+(C.position[1]||0))/A:C.position[1],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].position[2]||0)+(C.position[2]||0))/A:C.position[2]],positionRaw:[j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].positionRaw[0]||0)+(C.positionRaw[0]||0))/A:C.positionRaw[0],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].positionRaw[1]||0)+(C.positionRaw[1]||0))/A:C.positionRaw[1],j.body[T].keypoints[H]?((A-1)*(j.body[T].keypoints[H].positionRaw[2]||0)+(C.positionRaw[2]||0))/A:C.positionRaw[2]],distance:[j.body[T].keypoints[H]?((A-1)*(((C0=j.body[T].keypoints[H].distance)==null?void 0:C0[0])||0)+(((O0=C.distance)==null?void 0:O0[0])||0))/A:(Ie=C.distance)==null?void 0:Ie[0],j.body[T].keypoints[H]?((A-1)*(((Le=j.body[T].keypoints[H].distance)==null?void 0:Le[1])||0)+(((xe=C.distance)==null?void 0:xe[1])||0))/A:(Mo=C.distance)==null?void 0:Mo[1],j.body[T].keypoints[H]?((A-1)*(((Po=j.body[T].keypoints[H].distance)==null?void 0:Po[2])||0)+(((vo=C.distance)==null?void 0:vo[2])||0))/A:(To=C.distance)==null?void 0:To[2]]}}),Q={},o0={connected:{}};(i=(a=t.body)==null?void 0:a.modelPath)!=null&&i.includes("efficientpose")?o0=mt:(d=(x=t.body)==null?void 0:x.modelPath)!=null&&d.includes("blazepose")?o0=yt:(y=(l=t.body)==null?void 0:l.modelPath)!=null&&y.includes("movenet")&&(o0=Ue);for(let[C,H]of Object.entries(o0.connected)){let C0=[];for(let O0=0;O0xe.part===H[O0]),Le=D.find(xe=>xe.part===H[O0+1]);Ie&&Le&&C0.push([Ie.position,Le.position])}Q[C]=C0}j.body[T]={...e.body[T],box:e0,boxRaw:E,keypoints:D,annotations:Q}}if(!j.hand||e.hand.length!==j.hand.length)j.hand=JSON.parse(JSON.stringify(e.hand));else for(let T=0;T((A-1)*j.hand[T].box[C]+o0)/A),E=e.hand[T].boxRaw.map((o0,C)=>((A-1)*j.hand[T].boxRaw[C]+o0)/A);j.hand[T].keypoints.length!==e.hand[T].keypoints.length&&(j.hand[T].keypoints=e.hand[T].keypoints);let D=e.hand[T].keypoints&&e.hand[T].keypoints.length>0?e.hand[T].keypoints.map((o0,C)=>o0.map((H,C0)=>((A-1)*(j.hand[T].keypoints[C][C0]||1)+(H||0))/A)):[],Q={};if(Object.keys(j.hand[T].annotations).length!==Object.keys(e.hand[T].annotations).length)j.hand[T].annotations=e.hand[T].annotations,Q=j.hand[T].annotations;else if(e.hand[T].annotations)for(let o0 of Object.keys(e.hand[T].annotations))Q[o0]=e.hand[T].annotations[o0]&&e.hand[T].annotations[o0][0]?e.hand[T].annotations[o0].map((C,H)=>C.map((C0,O0)=>((A-1)*j.hand[T].annotations[o0][H][O0]+C0)/A)):null;j.hand[T]={...e.hand[T],box:e0,boxRaw:E,keypoints:D,annotations:Q}}if(!j.face||e.face.length!==j.face.length)j.face=JSON.parse(JSON.stringify(e.face));else for(let T=0;T((A-1)*j.face[T].box[Q]+D)/A),E=e.face[T].boxRaw.map((D,Q)=>((A-1)*j.face[T].boxRaw[Q]+D)/A);if(e.face[T].rotation){let D={matrix:[0,0,0,0,0,0,0,0,0],angle:{roll:0,yaw:0,pitch:0},gaze:{bearing:0,strength:0}};D.matrix=(c=e.face[T].rotation)==null?void 0:c.matrix,D.angle={roll:((A-1)*(((h=(f=j.face[T].rotation)==null?void 0:f.angle)==null?void 0:h.roll)||0)+(((v=(m=e.face[T].rotation)==null?void 0:m.angle)==null?void 0:v.roll)||0))/A,yaw:((A-1)*(((u=(M=j.face[T].rotation)==null?void 0:M.angle)==null?void 0:u.yaw)||0)+(((P=(p=e.face[T].rotation)==null?void 0:p.angle)==null?void 0:P.yaw)||0))/A,pitch:((A-1)*(((S=(w=j.face[T].rotation)==null?void 0:w.angle)==null?void 0:S.pitch)||0)+(((W=(O=e.face[T].rotation)==null?void 0:O.angle)==null?void 0:W.pitch)||0))/A},D.gaze={bearing:((A-1)*(((V=(I=j.face[T].rotation)==null?void 0:I.gaze)==null?void 0:V.bearing)||0)+(((B=(G=e.face[T].rotation)==null?void 0:G.gaze)==null?void 0:B.bearing)||0))/A,strength:((A-1)*(((z=(J=j.face[T].rotation)==null?void 0:J.gaze)==null?void 0:z.strength)||0)+(((p0=(P0=e.face[T].rotation)==null?void 0:P0.gaze)==null?void 0:p0.strength)||0))/A},j.face[T]={...e.face[T],rotation:D,box:e0,boxRaw:E}}j.face[T]={...e.face[T],box:e0,boxRaw:E}}if(!j.object||e.object.length!==j.object.length)j.object=JSON.parse(JSON.stringify(e.object));else for(let T=0;T((A-1)*j.object[T].box[Q]+D)/A),E=e.object[T].boxRaw.map((D,Q)=>((A-1)*j.object[T].boxRaw[Q]+D)/A);j.object[T]={...e.object[T],box:e0,boxRaw:E}}if(e.persons){let T=e.persons;if(!j.persons||T.length!==j.persons.length)j.persons=JSON.parse(JSON.stringify(T));else for(let e0=0;e0((A-1)*j.persons[e0].box[D]+E)/A)}e.gesture&&(j.gesture=e.gesture);let s=g();return ho=R.perfadd?ho+Math.round(s-o):Math.round(s-o),e.performance&&(j.performance={...e.performance,interpolate:ho}),j}var lr={};ee(lr,{distance:()=>Qe,match:()=>go,similarity:()=>bo});function Qe(e,t,o={order:2,multiplier:25}){let n=0;for(let A=0;A{if(e===0)return 1;let A=t===2?Math.sqrt(e):e**(1/t),s=(1-A/100-o)/(n-o);return Math.max(Math.min(s,1),0)};function bo(e,t,o={order:2,multiplier:25,min:.2,max:.8}){let n=Qe(e,t,o);return ir(n,o.order||2,o.min||0,o.max||1)}function go(e,t,o={order:2,multiplier:25,threshold:0,min:.2,max:.8}){if(!Array.isArray(e)||!Array.isArray(t)||e.length<64||t.length===0||e.length!==t[0].length)return{index:-1,distance:Number.POSITIVE_INFINITY,similarity:0};let n=Number.MAX_SAFE_INTEGER,A=-1;for(let a=0;az.box[0]&&O.box[0]z.box[1]&&O.box[1]+O.box[3]W.body.box[0]&&z.box[0]+z.box[2]W.body.box[1]&&z.box[1]+z.box[3]W.body.box[0]&&z.box[1]+z.box[3]>W.body.box[1]&&z.box[1]+z.box[3]{z&&z.length===4&&(I.push(z[0],z[0]+z[2]),V.push(z[1],z[1]+z[3]))};G((M=W.face)==null?void 0:M.box),G((u=W.body)==null?void 0:u.box),G((P=(p=W.hands)==null?void 0:p.left)==null?void 0:P.box),G((S=(w=W.hands)==null?void 0:w.right)==null?void 0:S.box);let B=Math.min(...I),J=Math.min(...V);W.box=[B,J,Math.max(...I)-B,Math.max(...V)-J],A&&A[1]&&A[2]&&(W.boxRaw=[W.box[0]/A[2],W.box[1]/A[1],W.box[2]/A[2],W.box[3]/A[1]]),a.push(W)}return a}var Gt=`
/9j/4AAQSkZJRgABAQEAYABgAAD/4QBoRXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUA
AAABAAAARgEoAAMAAAABAAIAAAExAAIAAAARAAAATgAAAAAAAABgAAAAAQAAAGAAAAABcGFpbnQu
bmV0IDQuMi4xMwAA/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcUGBgXFBYWGh0lHxob
@@ -259,7 +259,7 @@ PQ4GJ+ashuK0MhWaoWcA0AaOmASMK7jRNPWYBmHyiuepO2x10qfcv6vYxCzYqoGK4HVYVTJrmb5l
c6oaM5TUJ8EgGsG4kLNUHT0M64OaqMMikSRsuKbnFMRLG3zVehOaGNE445NNlnVFpDMu6uie9Vo1
8z5mOAOST2pDK91cNN+5tsrH3PrW54a06KxT7fdrlh/q1Pc+tJ6IUdZGvHPLezMcnBOWbsPap5r3
ylFtbdT1xUWNWzU0/Zbwlgfmx8zGsHWtRHmMqE59aAMyNifvHPc1f0gtPdqkY5JosJHeNci2tktY
-euPnNY+oXWZEVJNrZ9aun8SIq/CzodHuriIokhDIR1ronbKZr0o6o8ipoz//2Q==`,Gt=`
+euPnNY+oXWZEVJNrZ9aun8SIq/CzodHuriIokhDIR1ronbKZr0o6o8ipoz//2Q==`,Bt=`
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAsICAoIBwsKCQoNDAsNERwSEQ8PESIZGhQcKSQrKigk
JyctMkA3LTA9MCcnOEw5PUNFSElIKzZPVU5GVEBHSEX/2wBDAQwNDREPESESEiFFLicuRUVFRUVF
RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUX/wAARCASwBLADASIA
@@ -827,7 +827,7 @@ AAAAAAJAAAAAAAAAAAAAABAJEAAAAAAAAAAAAAAAIEoBKAAAAAAAAAAAAAAABAlAAAAAAAIAAAAA
BAkBAkBAkBAlACEgMZjdjbFW8bWrEx8YWANb6Fp+bfwab+vLDKMFK9qxH5L0bAr8OPRPKz2AY7J2
SbAjYZAI2E7AIEgIEgIEgMdkSy2NgY7MdlmyNoBXsxmFuyNgVTVjNV3KjlBRNTlXTVHKCrlIqt5T
lBhEMohlFerLlBjEMohMVTEARDKCITsAk2AEgAAAkAAAAAAAAAAAAAAAAAAAAAAAASAAAAAAAAD/
-2Q==`;async function Y2(e){let t=(A,s="application/octet-stream")=>fetch(`data:${s};base64,${A}`).then(a=>a.blob()),o,n;switch(e.config.warmup){case"face":o=await t(Nt);break;case"body":case"full":o=await t(Gt);break;default:o=null}if(o){let A=await createImageBitmap(o);n=await e.detect(A,e.config),A.close()}return n}async function K2(e){return new Promise(t=>{let o;switch(e.config.warmup){case"face":o="data:image/jpeg;base64,"+Nt;break;case"full":case"body":o="data:image/jpeg;base64,"+Gt;break;default:o=null}let n;if(typeof Image!="undefined")n=new Image;else if(w.Image)n=new w.Image;else return;n.onload=async()=>{let A=a0(n.naturalWidth,n.naturalHeight);if(!A)b("Warmup: Canvas not found"),t(void 0);else{let s=A.getContext("2d");s&&s.drawImage(n,0,0);let a=await e.image(A),i=await e.detect(a.tensor,e.config);t(i)}},o?n.src=o:t(void 0)})}async function Q2(e){let t=A=>Buffer.from(A,"base64"),o;e.config.warmup==="face"?o=t(Nt):o=t(Gt);let n;if("node"in r){let A=r.node.decodeJpeg(o),s=A.expandDims(0);e.tf.dispose(A),n=await e.detect(s,e.config),e.tf.dispose(s)}else e.config.debug&&b("Warmup tfjs-node not loaded");return n}async function _2(e){let t;return typeof createImageBitmap=="function"?t=await Y2(e):typeof Image!="undefined"||w.Canvas!==void 0?t=await K2(e):t=await Q2(e),t}async function yr(e,t){let o=g();return e.state="warmup",t&&(e.config=Y(e.config,t)),!e.config.warmup||e.config.warmup.length===0||e.config.warmup==="none"?{face:[],body:[],hand:[],gesture:[],object:[],performance:e.performance,timestamp:g(),persons:[],error:null}:new Promise(async n=>{let A=await _2(e),s=g();e.config.debug&&b("warmup",e.config.warmup,Math.round(s-o),"ms"),e.emit("warmup"),n(A)})}var We,Qe,_e,Bt,xr=class{constructor(t){k(this,"version");k(this,"config");k(this,"result");k(this,"state");k(this,"process");k(this,"tf");k(this,"env");k(this,"draw");k(this,"models");k(this,"events");k(this,"faceTriangulation");k(this,"faceUVMap");k(this,"performance");Ne(this,We,void 0);Ne(this,Qe,void 0);Ne(this,_e,void 0);k(this,"gl");k(this,"analyze",(...t)=>{if(!Le(this,Qe))return;let o=this.tf.engine().state.numTensors,n=Le(this,We);Ge(this,We,o);let A=o-n;A!==0&&b(...t,A)});Ne(this,Bt,t=>{if(!Le(this,_e))return null;if(!t)return"input is not defined";if(this.env.node&&!(t instanceof xe))return"input must be a tensor";try{this.tf.getBackend()}catch(o){return"backend not loaded"}return null});k(this,"similarity",ho);k(this,"distance",Ke);k(this,"match",bo);k(this,"emit",t=>{var o;this.events&&this.events.dispatchEvent&&((o=this.events)==null||o.dispatchEvent(new Event(t)))});this.env=w,ee.wasmPath=Be["tfjs-core"].includes("-")?"https://vladmandic.github.io/tfjs/dist/":`https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${r.version_core}/dist/`,ee.modelBasePath=w.browser?"../models/":"file://models/",ee.backend=w.browser?"humangl":"tensorflow",this.version=qt,Object.defineProperty(this,"version",{value:qt}),this.config=JSON.parse(JSON.stringify(ee)),Object.seal(this.config),this.config.cacheModels=typeof indexedDB!="undefined",t&&(this.config=Y(this.config,t)),Lo(this.config),this.tf=r,this.state="idle",Ge(this,We,0),Ge(this,Qe,!1),Ge(this,_e,!1),this.performance={},this.events=typeof EventTarget!="undefined"?new EventTarget:void 0,this.models=new Ye,this.draw={options:n0,canvas:(o,n)=>co(o,n),face:(o,n,A)=>ke(o,n,A),body:(o,n,A)=>Ee(o,n,A),hand:(o,n,A)=>ze(o,n,A),gesture:(o,n,A)=>Se(o,n,A),object:(o,n,A)=>je(o,n,A),person:(o,n,A)=>xo(o,n,A),all:(o,n,A)=>fo(o,n,A)},this.result={face:[],body:[],hand:[],gesture:[],object:[],performance:{},timestamp:0,persons:[],error:null},this.process={tensor:null,canvas:null},this.faceTriangulation=Jn,this.faceUVMap=Yn,this.gl=q,this.emit("create")}reset(){let t=this.config.backend;this.config=JSON.parse(JSON.stringify(ee)),this.config.backend=t}validate(t){return Ht(ee,t||this.config)}now(){return g()}image(t,o=!0){return de(t,this.config,o)}async segmentation(t,o){return JA(t,o,this.config)}enhance(t){return j5(t)}compare(t,o){return Io(this.config,t,o)}async init(){await Lt(this,!0),await this.tf.ready()}async load(t){this.state="load";let o=g(),n=Object.values(this.models).filter(a=>a).length;t&&(this.config=Y(this.config,t)),this.env.initial&&(this.config.debug&&b(`version: ${this.version}`),this.config.debug&&b(`tfjs version: ${this.tf.version["tfjs-core"]}`),await Lt(this)||b("error: backend check failed"),await r.ready(),this.env.browser&&(this.config.debug&&b("configuration:",this.config),this.config.debug&&b("environment:",this.env),this.config.debug&&b("tf flags:",this.tf.ENV.flags))),await ro(this),this.env.initial&&this.config.debug&&b("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),this.env.initial=!1,Object.values(this.models).filter(a=>a).length!==n&&(await so(this),this.emit("load"));let s=Math.trunc(g()-o);s>(this.performance.loadModels||0)&&(this.performance.loadModels=this.env.perfadd?(this.performance.loadModels||0)+s:s)}next(t=this.result){return sr(t,this.config)}async warmup(t){let o=g(),n=await yr(this,t),A=g();return this.performance.warmup=Math.trunc(A-o),n}async profile(t,o){let n=await this.tf.profile(()=>this.detect(t,o)),A={};for(let i of n.kernels)A[i.name]?A[i.name]+=i.kernelTimeMs:A[i.name]=i.kernelTimeMs;let s=[];Object.entries(A).forEach(i=>s.push({name:i[0],ms:i[1]})),s.sort((i,x)=>x.ms-i.ms),s.length=20;let a={};for(let i of s)a[i.name]=i.ms;return a}async detect(t,o){return this.state="detect",new Promise(async n=>{var v,M,u,p,P,R,S,O,C,I,V,G,B,J,z,p0,V0,T,e0,E,X,Q;this.state="config";let A;this.config=Y(this.config,o),this.state="check";let s=Le(this,Bt).call(this,t);s&&(b(s,t),this.emit("error"),n({face:[],body:[],hand:[],gesture:[],object:[],performance:this.performance,timestamp:g(),persons:[],error:s}));let a=g();await Lt(this),await this.load(),A=g(),this.state="image";let i=await de(t,this.config);if(this.process=i,this.performance.inputProcess=this.env.perfadd?(this.performance.inputProcess||0)+Math.trunc(g()-A):Math.trunc(g()-A),this.analyze("Get Image:"),!i.tensor){this.config.debug&&b("could not convert input to tensor"),this.emit("error"),n({face:[],body:[],hand:[],gesture:[],object:[],performance:this.performance,timestamp:g(),persons:[],error:"could not convert input to tensor"});return}this.emit("image"),A=g(),this.config.skipAllowed=await Oo(this.config,i.tensor),this.performance.totalFrames||(this.performance.totalFrames=0),this.performance.cachedFrames||(this.performance.cachedFrames=0),this.performance.totalFrames++,this.config.skipAllowed&&this.performance.cachedFrames++,this.performance.cacheCheck=this.env.perfadd?(this.performance.cacheCheck||0)+Math.trunc(g()-A):Math.trunc(g()-A),this.analyze("Check Changed:");let x=[],d=[],l=[],y=[];this.state="detect:face",this.config.async?(x=this.config.face.enabled?po(this,i.tensor):[],this.performance.face&&delete this.performance.face):(A=g(),x=this.config.face.enabled?await po(this,i.tensor):[],this.performance.face=this.env.perfadd?(this.performance.face||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.config.async&&(this.config.body.maxDetected===-1||this.config.hand.maxDetected===-1)&&(x=await x),this.analyze("Start Body:"),this.state="detect:body";let c=this.config.body.maxDetected===-1?Y(this.config,{body:{maxDetected:this.config.face.enabled?1*x.length:1}}):this.config;this.config.async?((v=this.config.body.modelPath)!=null&&v.includes("posenet")?d=this.config.body.enabled?oo(i.tensor,c):[]:(M=this.config.body.modelPath)!=null&&M.includes("blazepose")?d=this.config.body.enabled?f5(i.tensor,c):[]:(u=this.config.body.modelPath)!=null&&u.includes("efficientpose")?d=this.config.body.enabled?M5(i.tensor,c):[]:(p=this.config.body.modelPath)!=null&&p.includes("movenet")&&(d=this.config.body.enabled?Y5(i.tensor,c):[]),this.performance.body&&delete this.performance.body):(A=g(),(P=this.config.body.modelPath)!=null&&P.includes("posenet")?d=this.config.body.enabled?await oo(i.tensor,c):[]:(R=this.config.body.modelPath)!=null&&R.includes("blazepose")?d=this.config.body.enabled?await f5(i.tensor,c):[]:(S=this.config.body.modelPath)!=null&&S.includes("efficientpose")?d=this.config.body.enabled?await M5(i.tensor,c):[]:(O=this.config.body.modelPath)!=null&&O.includes("movenet")&&(d=this.config.body.enabled?await Y5(i.tensor,c):[]),this.performance.body=this.env.perfadd?(this.performance.body||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.state="detect:hand";let f=this.config.hand.maxDetected===-1?Y(this.config,{hand:{maxDetected:this.config.face.enabled?2*x.length:1}}):this.config;this.config.async?((I=(C=this.config.hand.detector)==null?void 0:C.modelPath)!=null&&I.includes("handdetect")?l=this.config.hand.enabled?N5(i.tensor,f):[]:(G=(V=this.config.hand.detector)==null?void 0:V.modelPath)!=null&&G.includes("handtrack")&&(l=this.config.hand.enabled?H5(i.tensor,f):[]),this.performance.hand&&delete this.performance.hand):(A=g(),(J=(B=this.config.hand.detector)==null?void 0:B.modelPath)!=null&&J.includes("handdetect")?l=this.config.hand.enabled?await N5(i.tensor,f):[]:(p0=(z=this.config.hand.detector)==null?void 0:z.modelPath)!=null&&p0.includes("handtrack")&&(l=this.config.hand.enabled?await H5(i.tensor,f):[]),this.performance.hand=this.env.perfadd?(this.performance.hand||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.state="detect:object",this.config.async?((V0=this.config.object.modelPath)!=null&&V0.includes("nanodet")?y=this.config.object.enabled?Q5(i.tensor,this.config):[]:(T=this.config.object.modelPath)!=null&&T.includes("centernet")&&(y=this.config.object.enabled?u5(i.tensor,this.config):[]),this.performance.object&&delete this.performance.object):(A=g(),(e0=this.config.object.modelPath)!=null&&e0.includes("nanodet")?y=this.config.object.enabled?await Q5(i.tensor,this.config):[]:(E=this.config.object.modelPath)!=null&&E.includes("centernet")&&(y=this.config.object.enabled?await u5(i.tensor,this.config):[]),this.performance.object=this.env.perfadd?(this.performance.object||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.analyze("End Object:"),this.state="detect:await",this.config.async&&([x,d,l,y]=await Promise.all([x,d,l,y])),this.state="detect:gesture";let h=[];this.config.gesture.enabled&&(A=g(),h=[...nr(x),...or(d),...rr(l),...Ar(x)],this.config.async?this.performance.gesture&&delete this.performance.gesture:this.performance.gesture=this.env.perfadd?(this.performance.gesture||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.performance.total=this.env.perfadd?(this.performance.total||0)+Math.trunc(g()-a):Math.trunc(g()-a);let m=((Q=(X=this.process)==null?void 0:X.tensor)==null?void 0:Q.shape)||[];this.result={face:x,body:d,hand:l,gesture:h,object:y,performance:this.performance,canvas:this.process.canvas,timestamp:Date.now(),error:null,get persons(){return lr(x,d,l,h,m)}},r.dispose(i.tensor),this.emit("detect"),this.state="idle",n(this.result)})}};We=new WeakMap,Qe=new WeakMap,_e=new WeakMap,Bt=new WeakMap;export{xr as Human,xr as default,ee as defaults,$A as draw,w as env,ir as match,ao as models};
+2Q==`;async function K2(e){let t=(A,s="application/octet-stream")=>fetch(`data:${s};base64,${A}`).then(a=>a.blob()),o,n;switch(e.config.warmup){case"face":o=await t(Gt);break;case"body":case"full":o=await t(Bt);break;default:o=null}if(o){let A=await createImageBitmap(o);n=await e.detect(A,e.config),A.close()}return n}async function Q2(e){return new Promise(t=>{let o;switch(e.config.warmup){case"face":o="data:image/jpeg;base64,"+Gt;break;case"full":case"body":o="data:image/jpeg;base64,"+Bt;break;default:o=null}let n;if(typeof Image!="undefined")n=new Image;else if(R.Image)n=new R.Image;else return;n.onload=async()=>{let A=a0(n.naturalWidth,n.naturalHeight);if(!A)b("Warmup: Canvas not found"),t(void 0);else{let s=A.getContext("2d");s&&s.drawImage(n,0,0);let a=await e.image(A),i=await e.detect(a.tensor,e.config);t(i)}},o?n.src=o:t(void 0)})}async function _2(e){let t=A=>Buffer.from(A,"base64"),o;e.config.warmup==="face"?o=t(Gt):o=t(Bt);let n;if("node"in r){let A=r.node.decodeJpeg(o),s=A.expandDims(0);e.tf.dispose(A),n=await e.detect(s,e.config),e.tf.dispose(s)}else e.config.debug&&b("Warmup tfjs-node not loaded");return n}async function $2(e){let t;return typeof createImageBitmap=="function"?t=await K2(e):typeof Image!="undefined"||R.Canvas!==void 0?t=await Q2(e):t=await _2(e),t}async function xr(e,t){let o=g();return e.state="warmup",t&&(e.config=Y(e.config,t)),!e.config.warmup||e.config.warmup.length===0||e.config.warmup==="none"?{face:[],body:[],hand:[],gesture:[],object:[],performance:e.performance,timestamp:g(),persons:[],error:null}:new Promise(async n=>{let A=await $2(e),s=g();e.config.debug&&b("warmup",e.config.warmup,Math.round(s-o),"ms"),e.emit("warmup"),n(A)})}var Oe,_e,$e,Ft,cr=class{constructor(t){k(this,"version");k(this,"config");k(this,"result");k(this,"state");k(this,"process");k(this,"tf");k(this,"env");k(this,"draw");k(this,"models");k(this,"events");k(this,"faceTriangulation");k(this,"faceUVMap");k(this,"performance");Ge(this,Oe,void 0);Ge(this,_e,void 0);Ge(this,$e,void 0);k(this,"gl");k(this,"analyze",(...t)=>{if(!Ne(this,_e))return;let o=this.tf.engine().state.numTensors,n=Ne(this,Oe);Be(this,Oe,o);let A=o-n;A!==0&&b(...t,A)});Ge(this,Ft,t=>{if(!Ne(this,$e))return null;if(!t)return"input is not defined";if(this.env.node&&!(t instanceof ce))return"input must be a tensor";try{this.tf.getBackend()}catch(o){return"backend not loaded"}return null});k(this,"similarity",bo);k(this,"distance",Qe);k(this,"match",go);k(this,"emit",t=>{var o;this.events&&this.events.dispatchEvent&&((o=this.events)==null||o.dispatchEvent(new Event(t)))});this.env=R,te.wasmPath=Fe["tfjs-core"].includes("-")?"https://vladmandic.github.io/tfjs/dist/":`https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-wasm@${r.version_core}/dist/`,te.modelBasePath=R.browser?"../models/":"file://models/",te.backend=R.browser?"humangl":"tensorflow",this.version=Ut,Object.defineProperty(this,"version",{value:Ut}),this.config=JSON.parse(JSON.stringify(te)),Object.seal(this.config),this.config.cacheModels=typeof indexedDB!="undefined",t&&(this.config=Y(this.config,t)),No(this.config),this.tf=r,this.state="idle",Be(this,Oe,0),Be(this,_e,!1),Be(this,$e,!1),this.performance={},this.events=typeof EventTarget!="undefined"?new EventTarget:void 0,this.models=new Ke,this.draw={options:n0,canvas:(o,n)=>fo(o,n),face:(o,n,A)=>Ee(o,n,A),body:(o,n,A)=>ze(o,n,A),hand:(o,n,A)=>je(o,n,A),gesture:(o,n,A)=>We(o,n,A),object:(o,n,A)=>Se(o,n,A),person:(o,n,A)=>co(o,n,A),all:(o,n,A)=>mo(o,n,A)},this.result={face:[],body:[],hand:[],gesture:[],object:[],performance:{},timestamp:0,persons:[],error:null},this.process={tensor:null,canvas:null},this.faceTriangulation=Yn,this.faceUVMap=Kn,this.gl=q,this.emit("create")}reset(){let t=this.config.backend;this.config=JSON.parse(JSON.stringify(te)),this.config.backend=t}validate(t){return Vt(te,t||this.config)}now(){return g()}image(t,o=!0){return fe(t,this.config,o)}async segmentation(t,o){return YA(t,o,this.config)}enhance(t){return S5(t)}compare(t,o){return Lo(this.config,t,o)}async init(){await Nt(this,!0),await this.tf.ready()}async load(t){this.state="load";let o=g(),n=Object.values(this.models).filter(a=>a).length;t&&(this.config=Y(this.config,t)),this.env.initial&&(this.config.debug&&b(`version: ${this.version}`),this.config.debug&&b(`tfjs version: ${this.tf.version["tfjs-core"]}`),await Nt(this)||b("error: backend check failed"),await r.ready(),this.env.browser&&(this.config.debug&&b("configuration:",this.config),this.config.debug&&b("environment:",this.env),this.config.debug&&b("tf flags:",this.tf.ENV.flags))),await so(this),this.env.initial&&this.config.debug&&b("tf engine state:",this.tf.engine().state.numBytes,"bytes",this.tf.engine().state.numTensors,"tensors"),this.env.initial=!1,Object.values(this.models).filter(a=>a).length!==n&&(await ao(this),this.emit("load"));let s=Math.trunc(g()-o);s>(this.performance.loadModels||0)&&(this.performance.loadModels=this.env.perfadd?(this.performance.loadModels||0)+s:s)}next(t=this.result){return ar(t,this.config)}async warmup(t){let o=g(),n=await xr(this,t),A=g();return this.performance.warmup=Math.trunc(A-o),n}async profile(t,o){let n=await this.tf.profile(()=>this.detect(t,o)),A={};for(let i of n.kernels)A[i.name]?A[i.name]+=i.kernelTimeMs:A[i.name]=i.kernelTimeMs;let s=[];Object.entries(A).forEach(i=>s.push({name:i[0],ms:i[1]})),s.sort((i,x)=>x.ms-i.ms),s.length=20;let a={};for(let i of s)a[i.name]=i.ms;return a}async detect(t,o){return this.state="detect",new Promise(async n=>{var v,M,u,p,P,w,S,O,W,I,V,G,B,J,z,P0,p0,T,e0,E,D,Q;this.state="config";let A;this.config=Y(this.config,o),this.state="check";let s=Ne(this,Ft).call(this,t);s&&(b(s,t),this.emit("error"),n({face:[],body:[],hand:[],gesture:[],object:[],performance:this.performance,timestamp:g(),persons:[],error:s}));let a=g();await Nt(this),await this.load(),A=g(),this.state="image";let i=await fe(t,this.config);if(this.process=i,this.performance.inputProcess=this.env.perfadd?(this.performance.inputProcess||0)+Math.trunc(g()-A):Math.trunc(g()-A),this.analyze("Get Image:"),!i.tensor){this.config.debug&&b("could not convert input to tensor"),this.emit("error"),n({face:[],body:[],hand:[],gesture:[],object:[],performance:this.performance,timestamp:g(),persons:[],error:"could not convert input to tensor"});return}this.emit("image"),A=g(),this.config.skipAllowed=await Io(this.config,i.tensor),this.performance.totalFrames||(this.performance.totalFrames=0),this.performance.cachedFrames||(this.performance.cachedFrames=0),this.performance.totalFrames++,this.config.skipAllowed&&this.performance.cachedFrames++,this.performance.cacheCheck=this.env.perfadd?(this.performance.cacheCheck||0)+Math.trunc(g()-A):Math.trunc(g()-A),this.analyze("Check Changed:");let x=[],d=[],l=[],y=[];this.state="detect:face",this.config.async?(x=this.config.face.enabled?uo(this,i.tensor):[],this.performance.face&&delete this.performance.face):(A=g(),x=this.config.face.enabled?await uo(this,i.tensor):[],this.performance.face=this.env.perfadd?(this.performance.face||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.config.async&&(this.config.body.maxDetected===-1||this.config.hand.maxDetected===-1)&&(x=await x),this.analyze("Start Body:"),this.state="detect:body";let c=this.config.body.maxDetected===-1?Y(this.config,{body:{maxDetected:this.config.face.enabled?1*x.length:1}}):this.config;this.config.async?((v=this.config.body.modelPath)!=null&&v.includes("posenet")?d=this.config.body.enabled?no(i.tensor,c):[]:(M=this.config.body.modelPath)!=null&&M.includes("blazepose")?d=this.config.body.enabled?m5(i.tensor,c):[]:(u=this.config.body.modelPath)!=null&&u.includes("efficientpose")?d=this.config.body.enabled?P5(i.tensor,c):[]:(p=this.config.body.modelPath)!=null&&p.includes("movenet")&&(d=this.config.body.enabled?K5(i.tensor,c):[]),this.performance.body&&delete this.performance.body):(A=g(),(P=this.config.body.modelPath)!=null&&P.includes("posenet")?d=this.config.body.enabled?await no(i.tensor,c):[]:(w=this.config.body.modelPath)!=null&&w.includes("blazepose")?d=this.config.body.enabled?await m5(i.tensor,c):[]:(S=this.config.body.modelPath)!=null&&S.includes("efficientpose")?d=this.config.body.enabled?await P5(i.tensor,c):[]:(O=this.config.body.modelPath)!=null&&O.includes("movenet")&&(d=this.config.body.enabled?await K5(i.tensor,c):[]),this.performance.body=this.env.perfadd?(this.performance.body||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.analyze("End Body:"),this.analyze("Start Hand:"),this.state="detect:hand";let f=this.config.hand.maxDetected===-1?Y(this.config,{hand:{maxDetected:this.config.face.enabled?2*x.length:1}}):this.config;this.config.async?((I=(W=this.config.hand.detector)==null?void 0:W.modelPath)!=null&&I.includes("handdetect")?l=this.config.hand.enabled?G5(i.tensor,f):[]:(G=(V=this.config.hand.detector)==null?void 0:V.modelPath)!=null&&G.includes("handtrack")&&(l=this.config.hand.enabled?V5(i.tensor,f):[]),this.performance.hand&&delete this.performance.hand):(A=g(),(J=(B=this.config.hand.detector)==null?void 0:B.modelPath)!=null&&J.includes("handdetect")?l=this.config.hand.enabled?await G5(i.tensor,f):[]:(P0=(z=this.config.hand.detector)==null?void 0:z.modelPath)!=null&&P0.includes("handtrack")&&(l=this.config.hand.enabled?await V5(i.tensor,f):[]),this.performance.hand=this.env.perfadd?(this.performance.hand||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.analyze("End Hand:"),this.analyze("Start Object:"),this.state="detect:object",this.config.async?((p0=this.config.object.modelPath)!=null&&p0.includes("nanodet")?y=this.config.object.enabled?_5(i.tensor,this.config):[]:(T=this.config.object.modelPath)!=null&&T.includes("centernet")&&(y=this.config.object.enabled?h5(i.tensor,this.config):[]),this.performance.object&&delete this.performance.object):(A=g(),(e0=this.config.object.modelPath)!=null&&e0.includes("nanodet")?y=this.config.object.enabled?await _5(i.tensor,this.config):[]:(E=this.config.object.modelPath)!=null&&E.includes("centernet")&&(y=this.config.object.enabled?await h5(i.tensor,this.config):[]),this.performance.object=this.env.perfadd?(this.performance.object||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.analyze("End Object:"),this.state="detect:await",this.config.async&&([x,d,l,y]=await Promise.all([x,d,l,y])),this.state="detect:gesture";let h=[];this.config.gesture.enabled&&(A=g(),h=[...Ar(x),...nr(d),...sr(l),...rr(x)],this.config.async?this.performance.gesture&&delete this.performance.gesture:this.performance.gesture=this.env.perfadd?(this.performance.gesture||0)+Math.trunc(g()-A):Math.trunc(g()-A)),this.performance.total=this.env.perfadd?(this.performance.total||0)+Math.trunc(g()-a):Math.trunc(g()-a);let m=((Q=(D=this.process)==null?void 0:D.tensor)==null?void 0:Q.shape)||[];this.result={face:x,body:d,hand:l,gesture:h,object:y,performance:this.performance,canvas:this.process.canvas,timestamp:Date.now(),error:null,get persons(){return yr(x,d,l,h,m)}},r.dispose(i.tensor),this.emit("detect"),this.state="idle",n(this.result)})}};Oe=new WeakMap,_e=new WeakMap,$e=new WeakMap,Ft=new WeakMap;export{cr as Human,cr as default,te as defaults,er as draw,R as env,lr as match,io as models};
/**
* Human main module
* @default Human Library
diff --git a/dist/human.esm-nobundle.js.map b/dist/human.esm-nobundle.js.map
index 530285cb..5b30d78c 100644
--- a/dist/human.esm-nobundle.js.map
+++ b/dist/human.esm-nobundle.js.map
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../src/util/util.ts", "../src/config.ts", "tfjs.esm.js", "../src/image/imagefxshaders.ts", "../src/image/imagefx.ts", "../src/image/enhance.ts", "../src/image/image.ts", "../src/util/env.ts", "../src/tfjs/load.ts", "../src/models.ts", "../src/gear/gear.ts", "../src/tfjs/constants.ts", "../src/gear/ssrnet-age.ts", "../src/gear/ssrnet-gender.ts", "../src/face/antispoof.ts", "../src/face/facemeshcoords.ts", "../src/face/facemeshutil.ts", "../src/face/blazeface.ts", "../src/body/blazeposecoords.ts", "../src/body/blazeposedetector.ts", "../src/util/box.ts", "../src/body/blazepose.ts", "../src/object/labels.ts", "../src/object/centernet.ts", "../src/body/efficientposecoords.ts", "../src/body/efficientpose.ts", "../src/gear/emotion.ts", "../src/face/mobilefacenet.ts", "../src/face/iris.ts", "../src/face/attention.ts", "../src/face/facemesh.ts", "../src/face/faceres.ts", "../src/hand/handposeutil.ts", "../src/hand/handposeanchors.ts", "../src/hand/handposedetector.ts", "../src/hand/handposepipeline.ts", "../src/hand/fingerdef.ts", "../src/hand/fingergesture.ts", "../src/hand/fingerpose.ts", "../src/hand/handpose.ts", "../src/hand/handtrack.ts", "../src/face/liveness.ts", "../src/body/movenetcoords.ts", "../src/body/movenetfix.ts", "../src/body/movenet.ts", "../src/object/nanodet.ts", "../src/body/posenetutils.ts", "../src/body/posenet.ts", "../src/segmentation/segmentation.ts", "../src/tfjs/humangl.ts", "../src/tfjs/backend.ts", "../src/draw/draw.ts", "../src/draw/options.ts", "../src/draw/primitives.ts", "../src/draw/face.ts", "../src/draw/body.ts", "../src/draw/hand.ts", "../src/draw/object.ts", "../src/draw/gesture.ts", "../src/face/mask.ts", "../src/face/angles.ts", "../src/face/face.ts", "../src/gesture/gesture.ts", "../src/util/interpolate.ts", "../src/face/match.ts", "../src/util/persons.ts", "../src/sample.ts", "../src/warmup.ts", "../src/human.ts"],
- "sourcesContent": ["import type { Config } from '../exports';\n\n/**\n * Simple helper functions used accross codebase\n */\n\n// helper function: wrapper around console output\nexport function log(...msg): void {\n const dt = new Date();\n const ts = `${dt.getHours().toString().padStart(2, '0')}:${dt.getMinutes().toString().padStart(2, '0')}:${dt.getSeconds().toString().padStart(2, '0')}.${dt.getMilliseconds().toString().padStart(3, '0')}`;\n // eslint-disable-next-line no-console\n if (msg) console.log(ts, 'Human:', ...msg);\n}\n\n// helper function: join two paths\nexport function join(folder: string, file: string): string {\n const separator = folder.endsWith('/') ? '' : '/';\n const skipJoin = file.startsWith('.') || file.startsWith('/') || file.startsWith('http:') || file.startsWith('https:') || file.startsWith('file:');\n const path = skipJoin ? `${file}` : `${folder}${separator}${file}`;\n if (!path.toLocaleLowerCase().includes('.json')) throw new Error(`modelpath error: expecting json file: ${path}`);\n return path;\n}\n\n// helper function: gets elapsed time on both browser and nodejs\nexport const now = () => {\n if (typeof performance !== 'undefined') return performance.now();\n return parseInt((Number(process.hrtime.bigint()) / 1000 / 1000).toString());\n};\n\n// helper function: checks current config validity\nexport function validate(defaults: Partial, config: Partial, parent = 'config', msgs: Array<{ reason: string, where: string, expected?: string }> = []) {\n for (const key of Object.keys(config)) {\n if (typeof config[key] === 'object') {\n validate(defaults[key], config[key], key, msgs);\n } else {\n const defined = defaults && (typeof defaults[key] !== 'undefined');\n if (!defined) msgs.push({ reason: 'unknown property', where: `${parent}.${key} = ${config[key]}` });\n const same = defaults && typeof defaults[key] === typeof config[key];\n if (defined && !same) msgs.push({ reason: 'property type mismatch', where: `${parent}.${key} = ${config[key]}`, expected: typeof defaults[key] });\n }\n // ok = ok && defined && same;\n }\n if (config.debug && parent === 'config' && msgs.length > 0) log('invalid configuration', msgs);\n return msgs;\n}\n\n// helper function: perform deep merge of multiple objects so it allows full inheritance with overrides\nexport function mergeDeep(...objects) {\n const isObject = (obj) => obj && typeof obj === 'object';\n return objects.reduce((prev, obj) => {\n Object.keys(obj || {}).forEach((key) => {\n const pVal = prev[key];\n const oVal = obj[key];\n if (Array.isArray(pVal) && Array.isArray(oVal)) prev[key] = pVal.concat(...oVal);\n else if (isObject(pVal) && isObject(oVal)) prev[key] = mergeDeep(pVal, oVal);\n else prev[key] = oVal;\n });\n return prev;\n }, {});\n}\n\n// helper function: return min and max from input array\nexport const minmax = (data: Array) => data.reduce((acc: Array, val) => {\n acc[0] = (acc[0] === undefined || val < acc[0]) ? val : acc[0];\n acc[1] = (acc[1] === undefined || val > acc[1]) ? val : acc[1];\n return acc;\n}, []);\n\n// helper function: async wait\nexport async function wait(time: number) {\n const waiting = new Promise((resolve) => { setTimeout(() => resolve(true), time); });\n await waiting;\n}\n", "/* eslint-disable indent */\n/* eslint-disable no-multi-spaces */\n\n/** Generic config type inherited by all module types */\nexport interface GenericConfig {\n /** is module enabled? */\n enabled: boolean,\n /** path to model json file (relative to `modelBasePath` */\n modelPath: string,\n /** how many max frames to go without re-running model if cached results are acceptable\n * for two-phase models such as face and hand caching applies to bounding boxes detection only */\n skipFrames: number,\n /** how many max milliseconds to go without re-running model if cached results are acceptable\n * for two-phase models such as face and hand caching applies to bounding boxes detection only */\n skipTime: number,\n}\n\n/** Detector part of face configuration */\nexport interface FaceDetectorConfig extends GenericConfig {\n /** is face rotation correction performed after detecting face?\n * used to correctly analyze faces under high angles\n */\n rotation: boolean,\n /** maximum number of detected faces */\n maxDetected: number,\n /** minimum confidence for a detected face before results are discarded */\n minConfidence: number,\n /** minimum overlap between two detected faces before one is discarded */\n iouThreshold: number,\n /** should child models perform on masked image of a face */\n mask: boolean,\n /** should face detection return processed and cropped face tensor that can with an external model for addtional processing?\n * if enabled it must be manually deallocated to avoid memory leak */\n return: boolean,\n}\n\n/** Mesh part of face configuration */\nexport interface FaceMeshConfig extends GenericConfig {}\n\n/** Iris part of face configuration */\nexport interface FaceIrisConfig extends GenericConfig {}\n\n/** Attention part of face configuration */\nexport interface FaceAttentionConfig extends GenericConfig {}\n\n/** Description or face embedding part of face configuration\n * - also used by age and gender detection\n */\nexport interface FaceDescriptionConfig extends GenericConfig {\n /** minimum confidence for a detected face before results are discarded */\n minConfidence: number,\n}\n\n/** Emotion part of face configuration */\nexport interface FaceEmotionConfig extends GenericConfig {\n /** minimum confidence for a detected face before results are discarded */\n minConfidence: number,\n}\n\n/** Anti-spoofing part of face configuration */\nexport interface FaceAntiSpoofConfig extends GenericConfig {}\n\n/** Liveness part of face configuration */\nexport interface FaceLivenessConfig extends GenericConfig {}\n\n/** Configures all face-specific options: face detection, mesh analysis, age, gender, emotion detection and face description */\nexport interface FaceConfig extends GenericConfig {\n detector: Partial,\n mesh: Partial,\n attention: Partial,\n iris: Partial,\n description: Partial,\n emotion: Partial,\n antispoof: Partial,\n liveness: Partial,\n}\n\n/** Configures all body detection specific options */\nexport interface BodyConfig extends GenericConfig {\n /** maximum number of detected bodies */\n maxDetected: number,\n /** minimum confidence for a detected body before results are discarded */\n minConfidence: number,\n /* experimental\n /** experimental: detector used for body model before actual analysis\n detector?: {\n /** experimental: enable body detector before body landmarks\n enabled: boolean,\n /** experimental: path to optional body detector model json file\n modelPath: string,\n /** experimental: minimum confidence for a detected body before results are discarded\n minConfidence: number,\n /** experimental: minimum overlap between two detected bodies before one is discarded\n iouThreshold: number\n },\n */\n}\n\n/** Configures all hand detection specific options */\nexport interface HandConfig extends GenericConfig {\n /** should hand rotation correction be performed after hand detection? */\n rotation: boolean,\n /** minimum confidence for a detected hand before results are discarded */\n minConfidence: number,\n /** minimum overlap between two detected hands before one is discarded */\n iouThreshold: number,\n /** maximum number of detected hands */\n maxDetected: number,\n /** should hand landmarks be detected or just return detected hand box */\n landmarks: boolean,\n detector: {\n /** path to hand detector model json */\n modelPath?: string,\n },\n skeleton: {\n /** path to hand skeleton model json */\n modelPath?: string,\n },\n}\n\n/** Configures all object detection specific options */\nexport interface ObjectConfig extends GenericConfig {\n /** minimum confidence for a detected objects before results are discarded */\n minConfidence: number,\n /** minimum overlap between two detected objects before one is discarded */\n iouThreshold: number,\n /** maximum number of detected objects */\n maxDetected: number,\n}\n\n/** Configures all body segmentation module\n * removes background from input containing person\n * if segmentation is enabled it will run as preprocessing task before any other model\n * alternatively leave it disabled and use it on-demand using human.segmentation method which can\n * remove background or replace it with user-provided background\n*/\nexport interface SegmentationConfig extends GenericConfig {\n /** blur segmentation output by pixels for more realistic image */\n blur: number,\n}\n\n/** Run input through image filters before inference\n * - available only in Browser environments\n * - image filters run with near-zero latency as they are executed on the GPU using WebGL\n*/\nexport interface FilterConfig {\n /** are image filters enabled? */\n enabled: boolean,\n /** perform image histogram equalization\n * - equalization is performed on input as a whole and detected face before its passed for further analysis\n */\n equalization: boolean,\n /** resize input width\n * - if both width and height are set to 0, there is no resizing\n * - if just one is set, second one is scaled automatically\n * - if both are set, values are used as-is\n */\n width: number,\n /** resize input height\n * - if both width and height are set to 0, there is no resizing\n * - if just one is set, second one is scaled automatically\n * - if both are set, values are used as-is\n */\n height: number,\n /** return processed canvas imagedata in result */\n return: boolean,\n /** flip input as mirror image */\n flip: boolean,\n /** range: -1 (darken) to 1 (lighten) */\n brightness: number,\n /** range: -1 (reduce contrast) to 1 (increase contrast) */\n contrast: number,\n /** range: 0 (no sharpening) to 1 (maximum sharpening) */\n sharpness: number,\n /** range: 0 (no blur) to N (blur radius in pixels) */\n blur: number\n /** range: -1 (reduce saturation) to 1 (increase saturation) */\n saturation: number,\n /** range: 0 (no change) to 360 (hue rotation in degrees) */\n hue: number,\n /** image negative */\n negative: boolean,\n /** image sepia colors */\n sepia: boolean,\n /** image vintage colors */\n vintage: boolean,\n /** image kodachrome colors */\n kodachrome: boolean,\n /** image technicolor colors */\n technicolor: boolean,\n /** image polaroid camera effect */\n polaroid: boolean,\n /** range: 0 (no pixelate) to N (number of pixels to pixelate) */\n pixelate: number,\n}\n\n/** Controlls gesture detection */\nexport interface GestureConfig {\n /** is gesture detection enabled? */\n enabled: boolean,\n}\n/** Possible TensorFlow backends */\nexport type BackendType = ['cpu', 'wasm', 'webgl', 'humangl', 'tensorflow', 'webgpu'];\n\n/** Possible values for `human.warmup` */\nexport type WarmupType = ['' | 'none' | 'face' | 'full' | 'body'];\n\n/**\n * Configuration interface definition for **Human** library\n * Contains all configurable parameters\n * Defaults: [config](https://github.com/vladmandic/human/blob/main/src/config.ts#L262)\n */\nexport interface Config {\n /** Backend used for TFJS operations\n * valid build-in backends are:\n * - Browser: `cpu`, `wasm`, `webgl`, `humangl`, `webgpu`\n * - NodeJS: `cpu`, `wasm`, `tensorflow`\n * default: `humangl` for browser and `tensorflow` for nodejs\n */\n backend: '' | 'cpu' | 'wasm' | 'webgl' | 'humangl' | 'tensorflow' | 'webgpu',\n\n /** Path to *.wasm files if backend is set to `wasm`\n *\n * default: auto-detects to link to CDN `jsdelivr` when running in browser\n */\n wasmPath: string,\n\n /** Force WASM loader to use platform fetch\n *\n * default: auto-detects to link to CDN `jsdelivr` when running in browser\n */\n wasmPlatformFetch: boolean,\n\n /** Print debug statements to console\n *\n * default: `true`\n */\n debug: boolean,\n\n /** Perform model loading and inference concurrently or sequentially\n *\n * default: `true`\n */\n async: boolean,\n\n /** What to use for `human.warmup()`\n * - warmup pre-initializes all models for faster inference but can take significant time on startup\n * - used by `webgl`, `humangl` and `webgpu` backends\n *\n * default: `full`\n */\n warmup: '' | 'none' | 'face' | 'full' | 'body',\n\n /** Base model path (typically starting with file://, http:// or https://) for all models\n * - individual modelPath values are relative to this path\n *\n * default: `../models/` for browsers and `file://models/` for nodejs\n */\n modelBasePath: string,\n\n /** Cache models in IndexDB on first sucessfull load\n * default: true if indexdb is available (browsers), false if its not (nodejs)\n */\n cacheModels: boolean,\n\n /** Cache sensitivity\n * - values 0..1 where 0.01 means reset cache if input changed more than 1%\n * - set to 0 to disable caching\n *\n * default: 0.7\n */\n cacheSensitivity: number;\n\n /** Perform immediate garbage collection on deallocated tensors instead of caching them */\n deallocate: boolean;\n\n /** Internal Variable */\n skipAllowed: boolean;\n\n /** Filter config {@link FilterConfig} */\n filter: Partial,\n\n /** Gesture config {@link GestureConfig} */\n gesture: Partial;\n\n /** Face config {@link FaceConfig} */\n face: Partial,\n\n /** Body config {@link BodyConfig} */\n body: Partial,\n\n /** Hand config {@link HandConfig} */\n hand: Partial,\n\n /** Object config {@link ObjectConfig} */\n object: Partial,\n\n /** Segmentation config {@link SegmentationConfig} */\n segmentation: Partial,\n}\n\n/** - [See all default Config values...](https://github.com/vladmandic/human/blob/main/src/config.ts#L262) */\nconst config: Config = {\n backend: '',\n modelBasePath: '',\n cacheModels: true,\n wasmPath: '',\n wasmPlatformFetch: false,\n debug: true,\n async: true,\n warmup: 'full',\n cacheSensitivity: 0.70,\n skipAllowed: false,\n deallocate: false,\n filter: {\n enabled: true,\n equalization: false,\n width: 0,\n height: 0,\n flip: false,\n return: true,\n brightness: 0,\n contrast: 0,\n sharpness: 0,\n blur: 0,\n saturation: 0,\n hue: 0,\n negative: false,\n sepia: false,\n vintage: false,\n kodachrome: false,\n technicolor: false,\n polaroid: false,\n pixelate: 0,\n },\n gesture: {\n enabled: true,\n },\n face: {\n enabled: true,\n detector: {\n modelPath: 'blazeface.json',\n rotation: true,\n maxDetected: 1,\n skipFrames: 99,\n skipTime: 2500,\n minConfidence: 0.2,\n iouThreshold: 0.1,\n mask: false,\n return: false,\n },\n mesh: {\n enabled: true,\n modelPath: 'facemesh.json',\n },\n attention: {\n enabled: false,\n modelPath: 'facemesh-attention.json',\n },\n iris: {\n enabled: true,\n modelPath: 'iris.json',\n },\n emotion: {\n enabled: true,\n minConfidence: 0.1,\n skipFrames: 99,\n skipTime: 1500,\n modelPath: 'emotion.json',\n },\n description: {\n enabled: true,\n modelPath: 'faceres.json',\n skipFrames: 99,\n skipTime: 3000,\n minConfidence: 0.1,\n },\n antispoof: {\n enabled: false,\n skipFrames: 99,\n skipTime: 4000,\n modelPath: 'antispoof.json',\n },\n liveness: {\n enabled: false,\n skipFrames: 99,\n skipTime: 4000,\n modelPath: 'liveness.json',\n },\n },\n body: {\n enabled: true,\n modelPath: 'movenet-lightning.json',\n maxDetected: -1,\n minConfidence: 0.3,\n skipFrames: 1,\n skipTime: 200,\n },\n hand: {\n enabled: true,\n rotation: true,\n skipFrames: 99,\n skipTime: 1000,\n minConfidence: 0.50,\n iouThreshold: 0.2,\n maxDetected: -1,\n landmarks: true,\n detector: {\n modelPath: 'handtrack.json',\n },\n skeleton: {\n modelPath: 'handlandmark-full.json',\n },\n },\n object: {\n enabled: false,\n modelPath: 'mb3-centernet.json',\n minConfidence: 0.2,\n iouThreshold: 0.4,\n maxDetected: 10,\n skipFrames: 99,\n skipTime: 2000,\n },\n segmentation: {\n enabled: false,\n modelPath: 'selfie.json',\n blur: 8,\n },\n};\n\nexport { config as defaults };\n", "/*\n Human\n homepage: \n author: '\n*/\n\nexport*from\"@tensorflow/tfjs/dist/index.js\";export*from\"@tensorflow/tfjs-backend-webgl/dist/index.js\";var r=\"3.15.0\",a=\"3.15.0\",e=\"3.15.0\",o=\"3.15.0\",t=\"3.15.0\",s=\"3.15.0\",f=\"3.15.0\",v=\"3.15.0\",j={tfjs:r,\"tfjs-core\":a,\"tfjs-data\":e,\"tfjs-layers\":o,\"tfjs-converter\":t,\"tfjs-backend-cpu\":s,\"tfjs-backend-webgl\":f,\"tfjs-backend-wasm\":v};import{Tensor as b}from\"@tensorflow/tfjs/dist/index.js\";import{GraphModel as i}from\"@tensorflow/tfjs-converter/dist/index\";export{i as GraphModel,b as Tensor,j as version};\n", "export const vertexIdentity = `\n precision highp float;\n attribute vec2 pos;\n attribute vec2 uv;\n varying vec2 vUv;\n uniform float flipY;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(pos.x, pos.y*flipY, 0.0, 1.);\n }\n`;\n\nexport const fragmentIdentity = `\n precision highp float;\n varying vec2 vUv;\n uniform sampler2D texture;\n void main(void) {\n gl_FragColor = texture2D(texture, vUv);\n }\n`;\n\nexport const colorMatrixWithAlpha = `\n precision highp float;\n varying vec2 vUv;\n uniform sampler2D texture;\n uniform float m[20];\n void main(void) {\n vec4 c = texture2D(texture, vUv);\n gl_FragColor.r = m[0] * c.r + m[1] * c.g + m[2] * c.b + m[3] * c.a + m[4];\n gl_FragColor.g = m[5] * c.r + m[6] * c.g + m[7] * c.b + m[8] * c.a + m[9];\n gl_FragColor.b = m[10] * c.r + m[11] * c.g + m[12] * c.b + m[13] * c.a + m[14];\n gl_FragColor.a = m[15] * c.r + m[16] * c.g + m[17] * c.b + m[18] * c.a + m[19];\n }\n`;\n\nexport const colorMatrixWithoutAlpha = `\n precision highp float;\n varying vec2 vUv;\n uniform sampler2D texture;\n uniform float m[20];\n void main(void) {\n vec4 c = texture2D(texture, vUv);\n gl_FragColor.r = m[0] * c.r + m[1] * c.g + m[2] * c.b + m[4];\n gl_FragColor.g = m[5] * c.r + m[6] * c.g + m[7] * c.b + m[9];\n gl_FragColor.b = m[10] * c.r + m[11] * c.g + m[12] * c.b + m[14];\n gl_FragColor.a = c.a;\n }\n`;\n\nexport const pixelate = `\n precision highp float;\n varying vec2 vUv;\n uniform vec2 size;\n uniform sampler2D texture;\n vec2 pixelate(vec2 coord, vec2 size) {\n return floor( coord / size ) * size;\n }\n void main(void) {\n gl_FragColor = vec4(0.0);\n vec2 coord = pixelate(vUv, size);\n gl_FragColor += texture2D(texture, coord);\n }\n`;\n\nexport const blur = `\n precision highp float;\n varying vec2 vUv;\n uniform sampler2D texture;\n uniform vec2 px;\n void main(void) {\n gl_FragColor = vec4(0.0);\n gl_FragColor += texture2D(texture, vUv + vec2(-7.0*px.x, -7.0*px.y))*0.0044299121055113265;\n gl_FragColor += texture2D(texture, vUv + vec2(-6.0*px.x, -6.0*px.y))*0.00895781211794;\n gl_FragColor += texture2D(texture, vUv + vec2(-5.0*px.x, -5.0*px.y))*0.0215963866053;\n gl_FragColor += texture2D(texture, vUv + vec2(-4.0*px.x, -4.0*px.y))*0.0443683338718;\n gl_FragColor += texture2D(texture, vUv + vec2(-3.0*px.x, -3.0*px.y))*0.0776744219933;\n gl_FragColor += texture2D(texture, vUv + vec2(-2.0*px.x, -2.0*px.y))*0.115876621105;\n gl_FragColor += texture2D(texture, vUv + vec2(-1.0*px.x, -1.0*px.y))*0.147308056121;\n gl_FragColor += texture2D(texture, vUv )*0.159576912161;\n gl_FragColor += texture2D(texture, vUv + vec2( 1.0*px.x, 1.0*px.y))*0.147308056121;\n gl_FragColor += texture2D(texture, vUv + vec2( 2.0*px.x, 2.0*px.y))*0.115876621105;\n gl_FragColor += texture2D(texture, vUv + vec2( 3.0*px.x, 3.0*px.y))*0.0776744219933;\n gl_FragColor += texture2D(texture, vUv + vec2( 4.0*px.x, 4.0*px.y))*0.0443683338718;\n gl_FragColor += texture2D(texture, vUv + vec2( 5.0*px.x, 5.0*px.y))*0.0215963866053;\n gl_FragColor += texture2D(texture, vUv + vec2( 6.0*px.x, 6.0*px.y))*0.00895781211794;\n gl_FragColor += texture2D(texture, vUv + vec2( 7.0*px.x, 7.0*px.y))*0.0044299121055113265;\n }\n`;\n\nexport const convolution = `\n precision highp float;\n varying vec2 vUv;\n uniform sampler2D texture;\n uniform vec2 px;\n uniform float m[9];\n void main(void) {\n vec4 c11 = texture2D(texture, vUv - px); // top left\n vec4 c12 = texture2D(texture, vec2(vUv.x, vUv.y - px.y)); // top center\n vec4 c13 = texture2D(texture, vec2(vUv.x + px.x, vUv.y - px.y)); // top right\n vec4 c21 = texture2D(texture, vec2(vUv.x - px.x, vUv.y) ); // mid left\n vec4 c22 = texture2D(texture, vUv); // mid center\n vec4 c23 = texture2D(texture, vec2(vUv.x + px.x, vUv.y) ); // mid right\n vec4 c31 = texture2D(texture, vec2(vUv.x - px.x, vUv.y + px.y) ); // bottom left\n vec4 c32 = texture2D(texture, vec2(vUv.x, vUv.y + px.y) ); // bottom center\n vec4 c33 = texture2D(texture, vUv + px ); // bottom right\n gl_FragColor = \n c11 * m[0] + c12 * m[1] + c22 * m[2] +\n c21 * m[3] + c22 * m[4] + c23 * m[5] +\n c31 * m[6] + c32 * m[7] + c33 * m[8];\n gl_FragColor.a = c22.a;\n }\n`;\n", "/**\n * Image Filters in WebGL algoritm implementation\n * Based on: [WebGLImageFilter](https://github.com/phoboslab/WebGLImageFilter)\n */\n\nimport * as shaders from './imagefxshaders';\nimport { canvas } from './image';\nimport { log } from '../util/util';\n\nconst collect = (source, prefix, collection) => {\n const r = new RegExp('\\\\b' + prefix + ' \\\\w+ (\\\\w+)', 'ig');\n source.replace(r, (match, name) => {\n collection[name] = 0;\n return match;\n });\n};\n\nclass GLProgram {\n uniform = {};\n attribute = {};\n gl: WebGLRenderingContext;\n id: WebGLProgram;\n\n constructor(gl, vertexSource, fragmentSource) {\n this.gl = gl;\n const vertexShader = this.compile(vertexSource, this.gl.VERTEX_SHADER);\n const fragmentShader = this.compile(fragmentSource, this.gl.FRAGMENT_SHADER);\n this.id = this.gl.createProgram() as WebGLProgram;\n if (!vertexShader || !fragmentShader) return;\n if (!this.id) {\n log('filter: could not create webgl program');\n return;\n }\n this.gl.attachShader(this.id, vertexShader);\n this.gl.attachShader(this.id, fragmentShader);\n this.gl.linkProgram(this.id);\n if (!this.gl.getProgramParameter(this.id, this.gl.LINK_STATUS)) {\n log(`filter: gl link failed: ${this.gl.getProgramInfoLog(this.id)}`);\n return;\n }\n this.gl.useProgram(this.id);\n collect(vertexSource, 'attribute', this.attribute); // Collect attributes\n for (const a in this.attribute) this.attribute[a] = this.gl.getAttribLocation(this.id, a);\n collect(vertexSource, 'uniform', this.uniform); // Collect uniforms\n collect(fragmentSource, 'uniform', this.uniform);\n for (const u in this.uniform) this.uniform[u] = this.gl.getUniformLocation(this.id, u);\n }\n\n compile = (source, type): WebGLShader | null => {\n const shader = this.gl.createShader(type) as WebGLShader;\n if (!shader) {\n log('filter: could not create shader');\n return null;\n }\n this.gl.shaderSource(shader, source);\n this.gl.compileShader(shader);\n if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n log(`filter: gl compile failed: ${this.gl.getShaderInfoLog(shader)}`);\n return null;\n }\n return shader;\n };\n}\n\n// function that is instantiated as class so it has private this members\n/**\n * @class GLImageFilter\n * @property {function} reset reset current filter chain\n * @property {function} add add specified filter to filter chain\n * @property {function} apply execute filter chain and draw result\n * @property {function} draw just draw input to result\n */\n\nexport function GLImageFilter() {\n let drawCount = 0;\n let sourceTexture: WebGLTexture | null = null;\n let lastInChain = false;\n let currentFramebufferIndex = -1;\n let tempFramebuffers: [null, null] | [{ fbo: WebGLFramebuffer | null, texture: WebGLTexture | null }] = [null, null];\n let filterChain: Record[] = [];\n let vertexBuffer: WebGLBuffer | null = null;\n let currentProgram: GLProgram | null = null;\n const fxcanvas = canvas(100, 100);\n const shaderProgramCache = { }; // key is the shader program source, value is the compiled program\n const DRAW = { INTERMEDIATE: 1 };\n const gl = fxcanvas.getContext('webgl') as WebGLRenderingContext;\n if (!gl) {\n log('filter: cannot get webgl context');\n return;\n }\n // @ts-ignore used for sanity checks outside of imagefx\n this.gl = gl;\n\n function resize(width, height) {\n if (width === fxcanvas.width && height === fxcanvas.height) return; // Same width/height? Nothing to do here\n fxcanvas.width = width;\n fxcanvas.height = height;\n if (!vertexBuffer) { // Create the context if we don't have it yet\n const vertices = new Float32Array([-1, -1, 0, 1, 1, -1, 1, 1, -1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 1, 1, 1, 1, 1, 0]); // Create the vertex buffer for the two triangles [x, y, u, v] * 6\n vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n }\n gl.viewport(0, 0, fxcanvas.width, fxcanvas.height);\n tempFramebuffers = [null, null]; // Delete old temp framebuffers\n }\n\n function createFramebufferTexture(width, height) {\n const fbo = gl.createFramebuffer() as WebGLFramebuffer;\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n const renderbuffer = gl.createRenderbuffer();\n gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);\n const texture = gl.createTexture() as WebGLTexture;\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n return { fbo, texture };\n }\n\n function getTempFramebuffer(index): { fbo: WebGLFramebuffer | null, texture: WebGLTexture | null } {\n tempFramebuffers[index] = tempFramebuffers[index] || createFramebufferTexture(fxcanvas.width, fxcanvas.height);\n return tempFramebuffers[index] as { fbo: WebGLFramebuffer, texture: WebGLTexture };\n }\n\n function draw(flags = 0) {\n if (!currentProgram) return;\n let source: WebGLTexture | null = null;\n let target: WebGLFramebuffer | null = null;\n let flipY = false;\n if (drawCount === 0) source = sourceTexture; // First draw call - use the source texture\n else source = getTempFramebuffer(currentFramebufferIndex).texture || null; // All following draw calls use the temp buffer last drawn to\n drawCount++;\n if (lastInChain && !(flags & DRAW.INTERMEDIATE)) { // Last filter in our chain - draw directly to the WebGL Canvas. We may also have to flip the image vertically now\n target = null;\n flipY = drawCount % 2 === 0;\n } else {\n currentFramebufferIndex = (currentFramebufferIndex + 1) % 2;\n target = getTempFramebuffer(currentFramebufferIndex).fbo || null; // Intermediate draw call - get a temp buffer to draw to\n }\n gl.bindTexture(gl.TEXTURE_2D, source); // Bind the source and target and draw the two triangles\n gl.bindFramebuffer(gl.FRAMEBUFFER, target);\n gl.uniform1f(currentProgram.uniform['flipY'], (flipY ? -1 : 1));\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n function compileShader(fragmentSource): GLProgram | null {\n if (shaderProgramCache[fragmentSource]) {\n currentProgram = shaderProgramCache[fragmentSource];\n gl.useProgram((currentProgram ? currentProgram.id : null) || null);\n return currentProgram as GLProgram;\n }\n currentProgram = new GLProgram(gl, shaders.vertexIdentity, fragmentSource);\n if (!currentProgram) {\n log('filter: could not get webgl program');\n return null;\n }\n const floatSize = Float32Array.BYTES_PER_ELEMENT;\n const vertSize = 4 * floatSize;\n gl.enableVertexAttribArray(currentProgram.attribute['pos']);\n gl.vertexAttribPointer(currentProgram.attribute['pos'], 2, gl.FLOAT, false, vertSize, 0 * floatSize);\n gl.enableVertexAttribArray(currentProgram.attribute['uv']);\n gl.vertexAttribPointer(currentProgram.attribute['uv'], 2, gl.FLOAT, false, vertSize, 2 * floatSize);\n shaderProgramCache[fragmentSource] = currentProgram;\n return currentProgram as GLProgram;\n }\n\n const filter = {\n colorMatrix: (matrix) => { // general color matrix filter\n const m = new Float32Array(matrix);\n m[4] /= 255;\n m[9] /= 255;\n m[14] /= 255;\n m[19] /= 255;\n const shader = (m[18] === 1 && m[3] === 0 && m[8] === 0 && m[13] === 0 && m[15] === 0 && m[16] === 0 && m[17] === 0 && m[19] === 0) // Can we ignore the alpha value? Makes things a bit faster.\n ? shaders.colorMatrixWithoutAlpha\n : shaders.colorMatrixWithAlpha;\n const program = compileShader(shader);\n if (!program) return;\n gl.uniform1fv(program.uniform['m'], m);\n draw();\n },\n\n brightness: (brightness) => {\n const b = (brightness || 0) + 1;\n filter.colorMatrix([\n b, 0, 0, 0, 0,\n 0, b, 0, 0, 0,\n 0, 0, b, 0, 0,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n saturation: (amount) => {\n const x = (amount || 0) * 2 / 3 + 1;\n const y = ((x - 1) * -0.5);\n filter.colorMatrix([\n x, y, y, 0, 0,\n y, x, y, 0, 0,\n y, y, x, 0, 0,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n desaturate: () => {\n filter.saturation(-1);\n },\n\n contrast: (amount) => {\n const v = (amount || 0) + 1;\n const o = -128 * (v - 1);\n filter.colorMatrix([\n v, 0, 0, 0, o,\n 0, v, 0, 0, o,\n 0, 0, v, 0, o,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n negative: () => {\n filter.contrast(-2);\n },\n\n hue: (rotation) => {\n rotation = (rotation || 0) / 180 * Math.PI;\n const cos = Math.cos(rotation);\n const sin = Math.sin(rotation);\n const lumR = 0.213;\n const lumG = 0.715;\n const lumB = 0.072;\n filter.colorMatrix([\n lumR + cos * (1 - lumR) + sin * (-lumR), lumG + cos * (-lumG) + sin * (-lumG), lumB + cos * (-lumB) + sin * (1 - lumB), 0, 0,\n lumR + cos * (-lumR) + sin * (0.143), lumG + cos * (1 - lumG) + sin * (0.140), lumB + cos * (-lumB) + sin * (-0.283), 0, 0,\n lumR + cos * (-lumR) + sin * (-(1 - lumR)), lumG + cos * (-lumG) + sin * (lumG), lumB + cos * (1 - lumB) + sin * (lumB), 0, 0,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n desaturateLuminance: () => {\n filter.colorMatrix([\n 0.2764723, 0.9297080, 0.0938197, 0, -37.1,\n 0.2764723, 0.9297080, 0.0938197, 0, -37.1,\n 0.2764723, 0.9297080, 0.0938197, 0, -37.1,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n sepia: () => {\n filter.colorMatrix([\n 0.393, 0.7689999, 0.18899999, 0, 0,\n 0.349, 0.6859999, 0.16799999, 0, 0,\n 0.272, 0.5339999, 0.13099999, 0, 0,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n brownie: () => {\n filter.colorMatrix([\n 0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873,\n -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127,\n 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n vintagePinhole: () => {\n filter.colorMatrix([\n 0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123,\n 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591,\n 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n kodachrome: () => {\n filter.colorMatrix([\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n technicolor: () => {\n filter.colorMatrix([\n 1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337,\n -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398,\n -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n polaroid: () => {\n filter.colorMatrix([\n 1.438, -0.062, -0.062, 0, 0,\n -0.122, 1.378, -0.122, 0, 0,\n -0.016, -0.016, 1.483, 0, 0,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n shiftToBGR: () => {\n filter.colorMatrix([\n 0, 0, 1, 0, 0,\n 0, 1, 0, 0, 0,\n 1, 0, 0, 0, 0,\n 0, 0, 0, 1, 0,\n ]);\n },\n\n convolution: (matrix) => { // general convolution Filter\n const m = new Float32Array(matrix);\n const pixelSizeX = 1 / fxcanvas.width;\n const pixelSizeY = 1 / fxcanvas.height;\n const program = compileShader(shaders.convolution);\n if (!program) return;\n gl.uniform1fv(program.uniform['m'], m);\n gl.uniform2f(program.uniform['px'], pixelSizeX, pixelSizeY);\n draw();\n },\n\n detectEdges: () => {\n // @ts-ignore this\n filter.convolution.call(this, [\n 0, 1, 0,\n 1, -4, 1,\n 0, 1, 0,\n ]);\n },\n\n sobelX: () => {\n // @ts-ignore this\n filter.convolution.call(this, [\n -1, 0, 1,\n -2, 0, 2,\n -1, 0, 1,\n ]);\n },\n\n sobelY: () => {\n // @ts-ignore this\n filter.convolution.call(this, [\n -1, -2, -1,\n 0, 0, 0,\n 1, 2, 1,\n ]);\n },\n\n sharpen: (amount) => {\n const a = amount || 1;\n // @ts-ignore this\n filter.convolution.call(this, [\n 0, -1 * a, 0,\n -1 * a, 1 + 4 * a, -1 * a,\n 0, -1 * a, 0,\n ]);\n },\n\n emboss: (size) => {\n const s = size || 1;\n // @ts-ignore this\n filter.convolution.call(this, [\n -2 * s, -1 * s, 0,\n -1 * s, 1, 1 * s,\n 0, 1 * s, 2 * s,\n ]);\n },\n\n blur: (size) => {\n const blurSizeX = (size / 7) / fxcanvas.width;\n const blurSizeY = (size / 7) / fxcanvas.height;\n const program = compileShader(shaders.blur);\n if (!program) return;\n // Vertical\n gl.uniform2f(program.uniform['px'], 0, blurSizeY);\n draw(DRAW.INTERMEDIATE);\n // Horizontal\n gl.uniform2f(program.uniform['px'], blurSizeX, 0);\n draw();\n },\n\n pixelate: (size) => {\n const blurSizeX = (size) / fxcanvas.width;\n const blurSizeY = (size) / fxcanvas.height;\n const program = compileShader(shaders.pixelate);\n if (!program) return;\n gl.uniform2f(program.uniform['size'], blurSizeX, blurSizeY);\n draw();\n },\n };\n\n // @ts-ignore this\n this.add = function (name) {\n // eslint-disable-next-line prefer-rest-params\n const args = Array.prototype.slice.call(arguments, 1);\n const func = filter[name];\n filterChain.push({ func, args });\n };\n\n // @ts-ignore this\n this.reset = function () {\n filterChain = [];\n };\n\n // @ts-ignore this\n this.get = function () {\n return filterChain;\n };\n\n // @ts-ignore this\n this.apply = function (image) {\n resize(image.width, image.height);\n drawCount = 0;\n if (!sourceTexture) sourceTexture = gl.createTexture(); // Create the texture for the input image if we haven't yet\n gl.bindTexture(gl.TEXTURE_2D, sourceTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);\n for (let i = 0; i < filterChain.length; i++) {\n lastInChain = (i === filterChain.length - 1);\n const f = filterChain[i];\n // @ts-ignore function assigment\n f.func.apply(this, f.args || []);\n }\n return fxcanvas;\n };\n\n // @ts-ignore this\n this.draw = function (image) {\n this.add('brightness', 0);\n return this.apply(image);\n };\n}\n", "/**\n * Image enhancements\n */\n\nimport * as tf from '../../dist/tfjs.esm.js';\nimport type { Tensor } from '../exports';\n\nexport async function histogramEqualization(inputImage: Tensor): Promise {\n // const maxValue = 254; // using 255 results in values slightly larger than 1 due to math rounding errors\n const squeeze = inputImage.shape.length === 4 ? tf.squeeze(inputImage) : inputImage;\n const channels = tf.split(squeeze, 3, 2);\n const min: Tensor[] = [tf.min(channels[0]), tf.min(channels[1]), tf.min(channels[2])];\n const max: Tensor[] = [tf.max(channels[0]), tf.max(channels[1]), tf.max(channels[2])];\n const absMax = await Promise.all(max.map((channel) => channel.data()));\n const maxValue = 0.99 * Math.max(absMax[0][0], absMax[1][0], absMax[2][0]);\n const sub = [tf.sub(channels[0], min[0]), tf.sub(channels[1], min[1]), tf.sub(channels[2], min[2])];\n const range = [tf.sub(max[0], min[0]), tf.sub(max[1], min[1]), tf.sub(max[2], min[2])];\n const fact = [tf.div(maxValue, range[0]), tf.div(maxValue, range[1]), tf.div(maxValue, range[2])];\n const enh = [tf.mul(sub[0], fact[0]), tf.mul(sub[1], fact[1]), tf.mul(sub[2], fact[2])];\n const rgb = tf.stack([enh[0], enh[1], enh[2]], 2);\n const reshape = tf.reshape(rgb, [1, squeeze.shape[0], squeeze.shape[1], 3]);\n tf.dispose([...channels, ...min, ...max, ...sub, ...range, ...fact, ...enh, rgb, squeeze]);\n return reshape; // output shape is [1, height, width, 3]\n}\n", "/**\n * Image Processing algorithm implementation\n */\n\nimport * as tf from '../../dist/tfjs.esm.js';\nimport * as fxImage from './imagefx';\nimport type { Input, AnyCanvas, Tensor, Config } from '../exports';\nimport { env } from '../util/env';\nimport { log } from '../util/util';\nimport * as enhance from './enhance';\n\nconst maxSize = 2048;\n// internal temp canvases\nlet inCanvas: AnyCanvas | null = null; // use global variable to avoid recreating canvas on each frame\nlet outCanvas: AnyCanvas | null = null; // use global variable to avoid recreating canvas on each frame\nlet tmpCanvas: AnyCanvas | null = null; // use global variable to avoid recreating canvas on each frame\n// @ts-ignore // imagefx is js module that should be converted to a class\nlet fx: fxImage.GLImageFilter | null; // instance of imagefx\n\nconst last: { inputSum: number, cacheDiff: number, sumMethod: number, inputTensor: undefined | Tensor } = {\n inputSum: 0,\n cacheDiff: 1,\n sumMethod: 0,\n inputTensor: undefined,\n};\n\nexport function canvas(width: number, height: number): AnyCanvas {\n let c;\n if (env.browser) { // browser defines canvas object\n if (env.worker) { // if runing in web worker use OffscreenCanvas\n if (typeof OffscreenCanvas === 'undefined') throw new Error('canvas error: attempted to run in web worker but OffscreenCanvas is not supported');\n c = new OffscreenCanvas(width, height);\n } else { // otherwise use DOM canvas\n if (typeof document === 'undefined') throw new Error('canvas error: attempted to run in browser but DOM is not defined');\n c = document.createElement('canvas');\n c.width = width;\n c.height = height;\n }\n } else { // if not running in browser, there is no \"default\" canvas object, so we need monkey patch or fail\n // @ts-ignore // env.canvas is an external monkey-patch\n if (typeof env.Canvas !== 'undefined') c = new env.Canvas(width, height);\n else if (typeof globalThis.Canvas !== 'undefined') c = new globalThis.Canvas(width, height);\n // else throw new Error('canvas error: attempted to use canvas in nodejs without canvas support installed');\n }\n return c;\n}\n\n// helper function to copy canvas from input to output\nexport function copy(input: AnyCanvas, output?: AnyCanvas) {\n const outputCanvas = output || canvas(input.width, input.height);\n const ctx = outputCanvas.getContext('2d') as CanvasRenderingContext2D;\n ctx.drawImage(input, 0, 0);\n return outputCanvas;\n}\n\n// process input image and return tensor\n// input can be tensor, imagedata, htmlimageelement, htmlvideoelement\n// input is resized and run through imagefx filter\nexport async function process(input: Input, config: Config, getTensor: boolean = true): Promise<{ tensor: Tensor | null, canvas: AnyCanvas | null }> {\n if (!input) {\n // throw new Error('input is missing');\n if (config.debug) log('input error: input is missing');\n return { tensor: null, canvas: null }; // video may become temporarily unavailable due to onresize\n }\n // sanity checks since different browsers do not implement all dom elements\n if (\n !(input instanceof tf.Tensor)\n && !(typeof Image !== 'undefined' && input instanceof Image)\n && !(typeof env.Canvas !== 'undefined' && input instanceof env.Canvas)\n && !(typeof globalThis.Canvas !== 'undefined' && input instanceof globalThis.Canvas)\n && !(typeof ImageData !== 'undefined' && input instanceof ImageData)\n && !(typeof ImageBitmap !== 'undefined' && input instanceof ImageBitmap)\n && !(typeof HTMLImageElement !== 'undefined' && input instanceof HTMLImageElement)\n && !(typeof HTMLMediaElement !== 'undefined' && input instanceof HTMLMediaElement)\n && !(typeof HTMLVideoElement !== 'undefined' && input instanceof HTMLVideoElement)\n && !(typeof HTMLCanvasElement !== 'undefined' && input instanceof HTMLCanvasElement)\n && !(typeof OffscreenCanvas !== 'undefined' && input instanceof OffscreenCanvas)\n ) {\n throw new Error('input error: type is not recognized');\n }\n if (input instanceof tf.Tensor) { // if input is tensor use as-is without filters but correct shape as needed\n let tensor: Tensor | null = null;\n if ((input as Tensor)['isDisposedInternal']) throw new Error('input error: attempted to use tensor but it is disposed');\n if (!(input as Tensor)['shape']) throw new Error('input error: attempted to use tensor without a shape');\n if ((input as Tensor).shape.length === 3) { // [height, width, 3 || 4]\n if ((input as Tensor).shape[2] === 3) { // [height, width, 3] so add batch\n tensor = tf.expandDims(input, 0);\n } else if ((input as Tensor).shape[2] === 4) { // [height, width, 4] so strip alpha and add batch\n const rgb = tf.slice3d(input, [0, 0, 0], [-1, -1, 3]);\n tensor = tf.expandDims(rgb, 0);\n tf.dispose(rgb);\n }\n } else if ((input as Tensor).shape.length === 4) { // [1, width, height, 3 || 4]\n if ((input as Tensor).shape[3] === 3) { // [1, width, height, 3] just clone\n tensor = tf.clone(input);\n } else if ((input as Tensor).shape[3] === 4) { // [1, width, height, 4] so strip alpha\n tensor = tf.slice4d(input, [0, 0, 0, 0], [-1, -1, -1, 3]);\n }\n }\n // at the end shape must be [1, height, width, 3]\n if (tensor == null || tensor.shape.length !== 4 || tensor.shape[0] !== 1 || tensor.shape[3] !== 3) throw new Error(`input error: attempted to use tensor with unrecognized shape: ${input['shape']}`);\n if ((tensor as Tensor).dtype === 'int32') {\n const cast = tf.cast(tensor, 'float32');\n tf.dispose(tensor);\n tensor = cast;\n }\n return { tensor, canvas: (config.filter.return ? outCanvas : null) };\n } else {\n // check if resizing will be needed\n if (typeof input['readyState'] !== 'undefined' && input['readyState'] <= 2) {\n if (config.debug) log('input stream is not ready');\n return { tensor: null, canvas: inCanvas }; // video may become temporarily unavailable due to onresize\n }\n const originalWidth = input['naturalWidth'] || input['videoWidth'] || input['width'] || (input['shape'] && (input['shape'][1] > 0));\n const originalHeight = input['naturalHeight'] || input['videoHeight'] || input['height'] || (input['shape'] && (input['shape'][2] > 0));\n if (!originalWidth || !originalHeight) {\n if (config.debug) log('cannot determine input dimensions');\n return { tensor: null, canvas: inCanvas }; // video may become temporarily unavailable due to onresize\n }\n let targetWidth = originalWidth;\n let targetHeight = originalHeight;\n if (targetWidth > maxSize) {\n targetWidth = maxSize;\n targetHeight = Math.trunc(targetWidth * originalHeight / originalWidth);\n }\n if (targetHeight > maxSize) {\n targetHeight = maxSize;\n targetWidth = Math.trunc(targetHeight * originalWidth / originalHeight);\n }\n\n // create our canvas and resize it if needed\n if ((config.filter.width || 0) > 0) targetWidth = config.filter.width;\n else if ((config.filter.height || 0) > 0) targetWidth = originalWidth * ((config.filter.height || 0) / originalHeight);\n if ((config.filter.height || 0) > 0) targetHeight = config.filter.height;\n else if ((config.filter.width || 0) > 0) targetHeight = originalHeight * ((config.filter.width || 0) / originalWidth);\n if (!targetWidth || !targetHeight) throw new Error('input error: cannot determine dimension');\n if (!inCanvas || (inCanvas?.width !== targetWidth) || (inCanvas?.height !== targetHeight)) inCanvas = canvas(targetWidth, targetHeight);\n\n // draw input to our canvas\n const inCtx = inCanvas.getContext('2d') as CanvasRenderingContext2D;\n if ((typeof ImageData !== 'undefined') && (input instanceof ImageData)) {\n inCtx.putImageData(input, 0, 0);\n } else {\n if (config.filter.flip && typeof inCtx.translate !== 'undefined') {\n inCtx.translate(originalWidth, 0);\n inCtx.scale(-1, 1);\n inCtx.drawImage(input as AnyCanvas, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas?.width, inCanvas?.height);\n inCtx.setTransform(1, 0, 0, 1, 0, 0); // resets transforms to defaults\n } else {\n inCtx.drawImage(input as AnyCanvas, 0, 0, originalWidth, originalHeight, 0, 0, inCanvas?.width, inCanvas?.height);\n }\n }\n\n if (!outCanvas || (inCanvas.width !== outCanvas.width) || (inCanvas?.height !== outCanvas?.height)) outCanvas = canvas(inCanvas.width, inCanvas.height); // init output canvas\n\n // imagefx transforms using gl from input canvas to output canvas\n if (config.filter.enabled && env.webgl.supported) {\n if (!fx) fx = env.browser ? new fxImage.GLImageFilter() : null; // && (typeof document !== 'undefined')\n env.filter = !!fx;\n if (!fx || !fx.add) {\n if (config.debug) log('input process error: cannot initialize filters');\n env.webgl.supported = false;\n config.filter.enabled = false;\n copy(inCanvas, outCanvas); // filter failed to initialize\n // return { tensor: null, canvas: inCanvas };\n } else {\n fx.reset();\n if (config.filter.brightness !== 0) fx.add('brightness', config.filter.brightness);\n if (config.filter.contrast !== 0) fx.add('contrast', config.filter.contrast);\n if (config.filter.sharpness !== 0) fx.add('sharpen', config.filter.sharpness);\n if (config.filter.blur !== 0) fx.add('blur', config.filter.blur);\n if (config.filter.saturation !== 0) fx.add('saturation', config.filter.saturation);\n if (config.filter.hue !== 0) fx.add('hue', config.filter.hue);\n if (config.filter.negative) fx.add('negative');\n if (config.filter.sepia) fx.add('sepia');\n if (config.filter.vintage) fx.add('brownie');\n if (config.filter.sepia) fx.add('sepia');\n if (config.filter.kodachrome) fx.add('kodachrome');\n if (config.filter.technicolor) fx.add('technicolor');\n if (config.filter.polaroid) fx.add('polaroid');\n if (config.filter.pixelate !== 0) fx.add('pixelate', config.filter.pixelate);\n if (fx.get() > 0) outCanvas = fx.apply(inCanvas);\n else outCanvas = fx.draw(inCanvas);\n }\n } else {\n copy(inCanvas, outCanvas); // if no filters applied, output canvas is input canvas\n if (fx) fx = null;\n env.filter = !!fx;\n }\n\n if (!getTensor) return { tensor: null, canvas: outCanvas }; // just canvas was requested\n if (!outCanvas) throw new Error('canvas error: cannot create output');\n\n // create tensor from image unless input was a tensor already\n let pixels;\n let depth = 3;\n if ((typeof ImageData !== 'undefined' && input instanceof ImageData) || (input['data'] && input['width'] && input['height'])) { // if input is imagedata, just use it\n if (env.browser && tf.browser) {\n pixels = tf.browser ? tf.browser.fromPixels(input) : null;\n } else {\n depth = input['data'].length / input['height'] / input['width'];\n // const arr = Uint8Array.from(input['data']);\n const arr = new Uint8Array(input['data']['buffer']);\n pixels = tf.tensor(arr, [input['height'], input['width'], depth], 'int32');\n }\n } else {\n if (!tmpCanvas || (outCanvas.width !== tmpCanvas.width) || (outCanvas.height !== tmpCanvas.height)) tmpCanvas = canvas(outCanvas.width, outCanvas.height); // init output canvas\n if (tf.browser && env.browser) {\n if (config.backend === 'webgl' || config.backend === 'humangl' || config.backend === 'webgpu') {\n pixels = tf.browser.fromPixels(outCanvas); // safe to reuse since both backend and context are gl based\n } else {\n tmpCanvas = copy(outCanvas); // cannot use output canvas as it already has gl context so we do a silly one more canvas\n pixels = tf.browser.fromPixels(tmpCanvas);\n }\n } else {\n const tempCanvas = copy(outCanvas); // cannot use output canvas as it already has gl context so we do a silly one more canvas\n const tempCtx = tempCanvas.getContext('2d') as CanvasRenderingContext2D;\n const tempData = tempCtx.getImageData(0, 0, targetWidth, targetHeight);\n depth = tempData.data.length / targetWidth / targetHeight;\n const arr = new Uint8Array(tempData.data.buffer);\n pixels = tf.tensor(arr, [targetWidth, targetHeight, depth]);\n }\n }\n if (depth === 4) { // rgba to rgb\n const rgb = tf.slice3d(pixels, [0, 0, 0], [-1, -1, 3]); // strip alpha channel\n tf.dispose(pixels);\n pixels = rgb;\n }\n if (!pixels) throw new Error('input error: cannot create tensor');\n const casted = tf.cast(pixels, 'float32');\n const tensor = config.filter.equalization ? await enhance.histogramEqualization(casted) : tf.expandDims(casted, 0);\n tf.dispose([pixels, casted]);\n return { tensor, canvas: (config.filter.return ? outCanvas : null) };\n }\n}\n\n/*\nconst checksum = async (input: Tensor): Promise => { // use tf sum or js based sum loop depending on which is faster\n const resizeFact = 48;\n const reduced: Tensor = tf.image.resizeBilinear(input, [Math.trunc((input.shape[1] || 1) / resizeFact), Math.trunc((input.shape[2] || 1) / resizeFact)]);\n const tfSum = async (): Promise => {\n const sumT = tf.sum(reduced);\n const sum0 = await sumT.data();\n tf.dispose(sumT);\n return sum0[0];\n };\n const jsSum = async (): Promise => {\n const reducedData = await reduced.data(); // raw image rgb array\n let sum0 = 0;\n for (let i = 0; i < reducedData.length / 3; i++) sum0 += reducedData[3 * i + 2]; // look only at green value of each pixel\n return sum0;\n };\n if (last.sumMethod === 0) {\n const t0 = now();\n await jsSum();\n const t1 = now();\n await tfSum();\n const t2 = now();\n last.sumMethod = t1 - t0 < t2 - t1 ? 1 : 2;\n }\n const res = last.sumMethod === 1 ? await jsSum() : await tfSum();\n tf.dispose(reduced);\n return res;\n};\n*/\n\nexport async function skip(config: Partial, input: Tensor) {\n let skipFrame = false;\n if (config.cacheSensitivity === 0 || !input.shape || input.shape.length !== 4 || input.shape[1] > 2048 || input.shape[2] > 2048) return skipFrame; // cache disabled or input is invalid or too large for cache analysis\n\n /*\n const checkSum = await checksum(input);\n const diff = 100 * (Math.max(checkSum, last.inputSum) / Math.min(checkSum, last.inputSum) - 1);\n last.inputSum = checkSum;\n // if previous frame was skipped, skip this frame if changed more than cacheSensitivity\n // if previous frame was not skipped, then look for cacheSensitivity or difference larger than one in previous frame to avoid resetting cache in subsequent frames unnecessarily\n let skipFrame = diff < Math.max(config.cacheSensitivity, last.cacheDiff);\n // if difference is above 10x threshold, don't use last value to force reset cache for significant change of scenes or images\n last.cacheDiff = diff > 10 * config.cacheSensitivity ? 0 : diff;\n skipFrame = skipFrame && (last.cacheDiff > 0); // if no cached diff value then force no skip\n */\n\n if (!last.inputTensor) {\n last.inputTensor = tf.clone(input);\n } else if (last.inputTensor.shape[1] !== input.shape[1] || last.inputTensor.shape[2] !== input.shape[2]) { // input resolution changed\n tf.dispose(last.inputTensor);\n last.inputTensor = tf.clone(input);\n } else {\n const t: Record = {};\n t.diff = tf.sub(input, last.inputTensor);\n t.squared = tf.mul(t.diff, t.diff);\n t.sum = tf.sum(t.squared);\n const diffSum = await t.sum.data();\n const diffRelative = diffSum[0] / (input.shape[1] || 1) / (input.shape[2] || 1) / 255 / 3; // squared difference relative to input resolution and averaged per channel\n tf.dispose([last.inputTensor, t.diff, t.squared, t.sum]);\n last.inputTensor = tf.clone(input);\n skipFrame = diffRelative <= (config.cacheSensitivity || 0);\n }\n return skipFrame;\n}\n\nexport async function compare(config: Partial, input1: Tensor, input2: Tensor): Promise {\n const t: Record = {};\n if (!input1 || !input2 || input1.shape.length !== 4 || input1.shape.length !== input2.shape.length) {\n if (!config.debug) log('invalid input tensor or tensor shapes do not match:', input1.shape, input2.shape);\n return 0;\n }\n if (input1.shape[0] !== 1 || input2.shape[0] !== 1 || input1.shape[3] !== 3 || input2.shape[3] !== 3) {\n if (!config.debug) log('input tensors must be of shape [1, height, width, 3]:', input1.shape, input2.shape);\n return 0;\n }\n t.input1 = tf.clone(input1);\n t.input2 = (input1.shape[1] !== input2.shape[1] || input1.shape[2] !== input2.shape[2]) ? tf.image.resizeBilinear(input2, [input1.shape[1], input1.shape[2]]) : tf.clone(input2);\n t.diff = tf.sub(t.input1, t.input2);\n t.squared = tf.mul(t.diff, t.diff);\n t.sum = tf.sum(t.squared);\n const diffSum = await t.sum.data();\n const diffRelative = diffSum[0] / (input1.shape[1] || 1) / (input1.shape[2] || 1) / 255 / 3;\n tf.dispose([t.input1, t.input2, t.diff, t.squared, t.sum]);\n return diffRelative;\n}\n", "import * as tf from '../../dist/tfjs.esm.js';\nimport * as image from '../image/image';\n\n/** Env class that holds detected capabilities */\nexport class Env {\n /** Running in Browser */\n browser: boolean;\n /** Running in NodeJS */\n node: boolean;\n /** Running in WebWorker thread */\n worker: boolean;\n /** Detected platform */\n platform: string = '';\n /** Detected agent */\n agent: string = '';\n /** List of supported backends */\n backends: string[] = [];\n /** Has any work been performed so far */\n initial: boolean;\n /** Are image filters supported? */\n filter: boolean | undefined;\n /** TFJS instance details */\n tfjs: {\n version: undefined | string,\n };\n /** Is offscreenCanvas supported? */\n offscreen: undefined | boolean;\n /** Are performance counter instant values or additive */\n perfadd: boolean = false;\n /** WASM detected capabilities */\n wasm: {\n supported: undefined | boolean,\n backend: undefined | boolean,\n simd: undefined | boolean,\n multithread: undefined | boolean,\n } = {\n supported: undefined,\n backend: undefined,\n simd: undefined,\n multithread: undefined,\n };\n /** WebGL detected capabilities */\n webgl: {\n supported: undefined | boolean,\n backend: undefined | boolean,\n version: undefined | string,\n renderer: undefined | string,\n } = {\n supported: undefined,\n backend: undefined,\n version: undefined,\n renderer: undefined,\n };\n /** WebGPU detected capabilities */\n webgpu: {\n supported: undefined | boolean,\n backend: undefined | boolean,\n adapter: undefined | string,\n } = {\n supported: undefined,\n backend: undefined,\n adapter: undefined,\n };\n /** CPU info */\n cpu: {\n model: undefined | string,\n flags: string[],\n } = {\n model: undefined,\n flags: [],\n };\n /** List of supported kernels for current backend */\n kernels: string[] = [];\n /** MonkeyPatch for Canvas */\n Canvas: undefined;\n /** MonkeyPatch for Image */\n Image: undefined;\n /** MonkeyPatch for ImageData */\n ImageData: undefined;\n\n constructor() {\n this.browser = typeof navigator !== 'undefined';\n this.node = (typeof process !== 'undefined') && (typeof process.versions !== 'undefined') && (typeof process.versions.node !== 'undefined');\n this.tfjs = { version: tf.version['tfjs-core'] };\n this.offscreen = typeof OffscreenCanvas !== 'undefined';\n this.initial = true;\n // @ts-ignore WorkerGlobalScope evaluated in browser only\n this.worker = this.browser && this.offscreen ? (typeof WorkerGlobalScope !== 'undefined') : undefined;\n if (typeof navigator !== 'undefined') {\n const raw = navigator.userAgent.match(/\\(([^()]+)\\)/g);\n if (raw && raw[0]) {\n const platformMatch = raw[0].match(/\\(([^()]+)\\)/g);\n this.platform = (platformMatch && platformMatch[0]) ? platformMatch[0].replace(/\\(|\\)/g, '') : '';\n this.agent = navigator.userAgent.replace(raw[0], '');\n if (this.platform[1]) this.agent = this.agent.replace(raw[1], '');\n this.agent = this.agent.replace(/ /g, ' ');\n // chrome offscreencanvas gpu memory leak\n /*\n const isChrome = env.agent.match(/Chrome\\/.[0-9]/g);\n const verChrome = isChrome && isChrome[0] ? isChrome[0].split('/')[1] : 0;\n if (verChrome > 92 && verChrome < 96) {\n log('disabling offscreenCanvas due to browser error:', isChrome ? isChrome[0] : 'unknown');\n this.offscreen = false;\n }\n */\n }\n } else if (typeof process !== 'undefined') {\n this.platform = `${process.platform} ${process.arch}`;\n this.agent = `NodeJS ${process.version}`;\n }\n }\n\n /** update backend information */\n async updateBackend() {\n // analyze backends\n this.backends = Object.keys(tf.engine().registryFactory);\n this.wasm.supported = typeof WebAssembly !== 'undefined';\n this.wasm.backend = this.backends.includes('wasm');\n if (this.wasm.supported && this.wasm.backend && tf.getBackend() === 'wasm') {\n this.wasm.simd = await tf.env().getAsync('WASM_HAS_SIMD_SUPPORT');\n this.wasm.multithread = await tf.env().getAsync('WASM_HAS_MULTITHREAD_SUPPORT');\n }\n const c = image.canvas(100, 100);\n const ctx = c ? c.getContext('webgl2') : undefined; // causes too many gl contexts\n // const ctx = typeof tf.backend().getGPGPUContext !== undefined ? tf.backend().getGPGPUContext : null;\n this.webgl.supported = typeof ctx !== 'undefined';\n this.webgl.backend = this.backends.includes('webgl');\n if (this.webgl.supported && this.webgl.backend && (tf.getBackend() === 'webgl' || tf.getBackend() === 'humangl')) {\n // @ts-ignore getGPGPUContext only exists on WebGL backend\n const gl = tf.backend().gpgpu !== 'undefined' ? await tf.backend().getGPGPUContext().gl : null;\n if (gl) {\n this.webgl.version = gl.getParameter(gl.VERSION);\n this.webgl.renderer = gl.getParameter(gl.RENDERER);\n }\n }\n // @ts-ignore navigator.gpu is only defined when webgpu is available in browser\n this.webgpu.supported = this.browser && typeof navigator['gpu'] !== 'undefined';\n this.webgpu.backend = this.backends.includes('webgpu');\n try {\n // @ts-ignore navigator.gpu is only defined when webgpu is available in browser\n if (this.webgpu.supported) this.webgpu.adapter = (await navigator['gpu'].requestAdapter()).name;\n } catch {\n this.webgpu.supported = false;\n }\n try {\n this.kernels = tf.getKernelsForBackend(tf.getBackend()).map((kernel) => kernel.kernelName.toLowerCase());\n } catch { /**/ }\n }\n\n /** update cpu information */\n async updateCPU() {\n const cpu = { model: '', flags: [] };\n if (this.node && this.platform.startsWith('linux')) {\n /*\n // eslint-disable-next-line global-require\n const fs = require('fs');\n try {\n const data = fs.readFileSync('/proc/cpuinfo').toString();\n for (const line of data.split('\\n')) {\n if (line.startsWith('model name')) {\n cpu.model = line.match(/:(.*)/g)[0].replace(':', '').trim();\n }\n if (line.startsWith('flags')) {\n cpu.flags = line.match(/:(.*)/g)[0].replace(':', '').trim().split(' ').sort();\n }\n }\n } catch { }\n */\n }\n if (!this['cpu']) Object.defineProperty(this, 'cpu', { value: cpu });\n else this['cpu'] = cpu;\n }\n}\n\nexport const env = new Env();\n", "import { log, join } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport type { GraphModel } from './types';\nimport type { Config } from '../config';\n\nconst options = {\n cacheModels: false,\n verbose: true,\n debug: false,\n modelBasePath: '',\n};\n\nasync function httpHandler(url, init?): Promise {\n if (options.debug) log('load model fetch:', url, init);\n return fetch(url, init);\n}\n\nexport function setModelLoadOptions(config: Config) {\n options.cacheModels = config.cacheModels;\n options.verbose = config.debug;\n options.modelBasePath = config.modelBasePath;\n}\n\nexport async function loadModel(modelPath: string | undefined): Promise {\n const modelUrl = join(options.modelBasePath, modelPath || '');\n const modelPathSegments = modelUrl.split('/');\n const cachedModelName = 'indexeddb://' + modelPathSegments[modelPathSegments.length - 1].replace('.json', ''); // generate short model name for cache\n const cachedModels = await tf.io.listModels(); // list all models already in cache\n const modelCached = options.cacheModels && Object.keys(cachedModels).includes(cachedModelName); // is model found in cache\n const tfLoadOptions = typeof fetch === 'undefined' ? {} : { fetchFunc: (url, init?) => httpHandler(url, init) };\n const model: GraphModel = new tf.GraphModel(modelCached ? cachedModelName : modelUrl, tfLoadOptions) as unknown as GraphModel; // create model prototype and decide if load from cache or from original modelurl\n let loaded = false;\n try {\n // @ts-ignore private function\n model.findIOHandler(); // decide how to actually load a model\n // @ts-ignore private property\n if (options.debug) log('model load handler:', model.handler);\n // @ts-ignore private property\n const artifacts = await model.handler.load(); // load manifest\n model.loadSync(artifacts); // load weights\n if (options.verbose) log('load model:', model['modelUrl']);\n loaded = true;\n } catch (err) {\n log('error loading model:', modelUrl, err);\n }\n if (loaded && options.cacheModels && !modelCached) { // save model to cache\n try {\n const saveResult = await model.save(cachedModelName);\n log('model saved:', cachedModelName, saveResult);\n } catch (err) {\n log('error saving model:', modelUrl, err);\n }\n }\n return model;\n}\n", "/**\n * Loader and Validator for all models used by Human\n */\n\nimport { env } from './util/env';\nimport { log } from './util/util';\nimport * as gear from './gear/gear';\nimport * as ssrnetAge from './gear/ssrnet-age';\nimport * as ssrnetGender from './gear/ssrnet-gender';\nimport * as antispoof from './face/antispoof';\nimport * as blazeface from './face/blazeface';\nimport * as blazepose from './body/blazepose';\nimport * as centernet from './object/centernet';\nimport * as efficientpose from './body/efficientpose';\nimport * as emotion from './gear/emotion';\nimport * as mobilefacenet from './face/mobilefacenet';\nimport * as facemesh from './face/facemesh';\nimport * as faceres from './face/faceres';\nimport * as handpose from './hand/handpose';\nimport * as handtrack from './hand/handtrack';\nimport * as iris from './face/iris';\nimport * as liveness from './face/liveness';\nimport * as movenet from './body/movenet';\nimport * as nanodet from './object/nanodet';\nimport * as posenet from './body/posenet';\nimport * as segmentation from './segmentation/segmentation';\nimport type { GraphModel } from './tfjs/types';\nimport type { Human } from './human';\n\n/** Instances of all possible TFJS Graph Models used by Human\n * - loaded as needed based on configuration\n * - initialized explictly with `human.load()` method\n * - initialized implicity on first call to `human.detect()`\n * - each model can be `null` if not loaded, instance of `GraphModel` if loaded or `Promise` if loading\n */\nexport class Models {\n ssrnetage: null | GraphModel | Promise = null;\n gear: null | GraphModel | Promise = null;\n blazeposedetect: null | GraphModel | Promise = null;\n blazepose: null | GraphModel | Promise = null;\n centernet: null | GraphModel | Promise = null;\n efficientpose: null | GraphModel | Promise = null;\n mobilefacenet: null | GraphModel | Promise = null;\n emotion: null | GraphModel | Promise = null;\n facedetect: null | GraphModel | Promise = null;\n faceiris: null | GraphModel | Promise = null;\n facemesh: null | GraphModel | Promise = null;\n faceres: null | GraphModel | Promise = null;\n ssrnetgender: null | GraphModel | Promise = null;\n handpose: null | GraphModel | Promise = null;\n handskeleton: null | GraphModel | Promise = null;\n handtrack: null | GraphModel | Promise = null;\n liveness: null | GraphModel | Promise = null;\n movenet: null | GraphModel | Promise = null;\n nanodet: null | GraphModel | Promise = null;\n posenet: null | GraphModel | Promise = null;\n segmentation: null | GraphModel | Promise = null;\n antispoof: null | GraphModel | Promise = null;\n}\n\nexport function reset(instance: Human): void {\n // if (instance.config.debug) log('resetting loaded models');\n for (const model of Object.keys(instance.models)) instance.models[model as keyof Models] = null;\n}\n\n/** Load method preloads all instance.configured models on-demand */\nexport async function load(instance: Human): Promise {\n if (env.initial) reset(instance);\n if (instance.config.hand.enabled) { // handpose model is a combo that must be loaded as a whole\n if (!instance.models.handpose && instance.config.hand.detector?.modelPath?.includes('handdetect')) [instance.models.handpose, instance.models.handskeleton] = await handpose.load(instance.config);\n if (!instance.models.handskeleton && instance.config.hand.landmarks && instance.config.hand.detector?.modelPath?.includes('handdetect')) [instance.models.handpose, instance.models.handskeleton] = await handpose.load(instance.config);\n }\n if (instance.config.body.enabled && !instance.models.blazepose && instance.config.body?.modelPath?.includes('blazepose')) instance.models.blazepose = blazepose.loadPose(instance.config);\n // @ts-ignore optional model\n if (instance.config.body.enabled && !instance.models.blazeposedetect && instance.config.body['detector'] && instance.config.body['detector']['modelPath']) instance.models.blazeposedetect = blazepose.loadDetect(instance.config);\n if (instance.config.body.enabled && !instance.models.efficientpose && instance.config.body?.modelPath?.includes('efficientpose')) instance.models.efficientpose = efficientpose.load(instance.config);\n if (instance.config.body.enabled && !instance.models.movenet && instance.config.body?.modelPath?.includes('movenet')) instance.models.movenet = movenet.load(instance.config);\n if (instance.config.body.enabled && !instance.models.posenet && instance.config.body?.modelPath?.includes('posenet')) instance.models.posenet = posenet.load(instance.config);\n if (instance.config.face.enabled && !instance.models.facedetect) instance.models.facedetect = blazeface.load(instance.config);\n if (instance.config.face.enabled && instance.config.face.antispoof?.enabled && !instance.models.antispoof) instance.models.antispoof = antispoof.load(instance.config);\n if (instance.config.face.enabled && instance.config.face.liveness?.enabled && !instance.models.liveness) instance.models.liveness = liveness.load(instance.config);\n if (instance.config.face.enabled && instance.config.face.description?.enabled && !instance.models.faceres) instance.models.faceres = faceres.load(instance.config);\n if (instance.config.face.enabled && instance.config.face.emotion?.enabled && !instance.models.emotion) instance.models.emotion = emotion.load(instance.config);\n if (instance.config.face.enabled && instance.config.face.iris?.enabled && !instance.models.faceiris) instance.models.faceiris = iris.load(instance.config);\n if (instance.config.face.enabled && instance.config.face.mesh?.enabled && !instance.models.facemesh) instance.models.facemesh = facemesh.load(instance.config);\n // @ts-ignore optional model\n if (instance.config.face.enabled && instance.config.face['gear']?.enabled && !instance.models.gear) instance.models.gear = gear.load(instance.config);\n // @ts-ignore optional model\n if (instance.config.face.enabled && instance.config.face['ssrnet']?.enabled && !instance.models.ssrnetage) instance.models.ssrnetage = ssrnetAge.load(instance.config);\n // @ts-ignore optional model\n if (instance.config.face.enabled && instance.config.face['ssrnet']?.enabled && !instance.models.ssrnetgender) instance.models.ssrnetgender = ssrnetGender.load(instance.config);\n // @ts-ignore optional model\n if (instance.config.face.enabled && instance.config.face['mobilefacenet']?.enabled && !instance.models.mobilefacenet) instance.models.mobilefacenet = mobilefacenet.load(instance.config);\n if (instance.config.hand.enabled && !instance.models.handtrack && instance.config.hand.detector?.modelPath?.includes('handtrack')) instance.models.handtrack = handtrack.loadDetect(instance.config);\n if (instance.config.hand.enabled && instance.config.hand.landmarks && !instance.models.handskeleton && instance.config.hand.detector?.modelPath?.includes('handtrack')) instance.models.handskeleton = handtrack.loadSkeleton(instance.config);\n if (instance.config.object.enabled && !instance.models.centernet && instance.config.object?.modelPath?.includes('centernet')) instance.models.centernet = centernet.load(instance.config);\n if (instance.config.object.enabled && !instance.models.nanodet && instance.config.object?.modelPath?.includes('nanodet')) instance.models.nanodet = nanodet.load(instance.config);\n if (instance.config.segmentation.enabled && !instance.models.segmentation) instance.models.segmentation = segmentation.load(instance.config);\n\n // models are loaded in parallel asynchronously so lets wait until they are actually loaded\n for await (const model of Object.keys(instance.models)) {\n if (instance.models[model as keyof Models] && typeof instance.models[model as keyof Models] !== 'undefined') instance.models[model as keyof Models] = await instance.models[model as keyof Models];\n }\n}\n\nexport async function validate(instance: Human): Promise {\n interface Op { name: string, category: string, op: string }\n const simpleOps = ['const', 'placeholder', 'noop', 'pad', 'squeeze', 'add', 'sub', 'mul', 'div'];\n for (const defined of Object.keys(instance.models)) {\n const model: GraphModel | null = instance.models[defined as keyof Models] as GraphModel | null;\n if (!model) continue;\n const ops: string[] = [];\n // @ts-ignore // executor is a private method\n const executor = model?.executor;\n if (executor && executor.graph.nodes) {\n for (const kernel of Object.values(executor.graph.nodes)) {\n const op = (kernel as Op).op.toLowerCase();\n if (!ops.includes(op)) ops.push(op);\n }\n } else {\n if (!executor && instance.config.debug) log('model signature not determined:', defined);\n }\n const missing: string[] = [];\n for (const op of ops) {\n if (!simpleOps.includes(op) // exclude simple ops\n && !instance.env.kernels.includes(op) // check actual kernel ops\n && !instance.env.kernels.includes(op.replace('_', '')) // check variation without _\n && !instance.env.kernels.includes(op.replace('native', '')) // check standard variation\n && !instance.env.kernels.includes(op.replace('v2', ''))) { // check non-versioned variation\n missing.push(op);\n }\n }\n // log('model validation ops:', defined, ops);\n if (instance.config.debug && missing.length > 0) log('model validation failed:', defined, missing);\n }\n}\n", "/**\n * GEAR [gender/emotion/age/race] model implementation\n *\n * Based on: [**GEAR Predictor**](https://github.com/Udolf15/GEAR-Predictor)\n */\n\nimport { log, now } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport type { Gender, Race } from '../result';\nimport type { Config } from '../config';\nimport type { GraphModel, Tensor } from '../tfjs/types';\nimport { env } from '../util/env';\n\nexport type GearType = { age: number, gender: Gender, genderScore: number, race: Array<{ score: number, race: Race }> }\nlet model: GraphModel | null;\nconst last: Array = [];\nconst raceNames = ['white', 'black', 'asian', 'indian', 'other'];\nconst ageWeights = [15, 23, 28, 35.5, 45.5, 55.5, 65];\nlet lastCount = 0;\nlet lastTime = 0;\nlet skipped = Number.MAX_SAFE_INTEGER;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function load(config: Config) {\n if (env.initial) model = null;\n if (!model) model = await loadModel(config.face['gear']);\n else if (config.debug) log('cached model:', model['modelUrl']);\n return model;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function predict(image: Tensor, config: Config, idx: number, count: number): Promise {\n if (!model) return { age: 0, gender: 'unknown', genderScore: 0, race: [] };\n const skipFrame = skipped < (config.face['gear']?.skipFrames || 0);\n const skipTime = (config.face['gear']?.skipTime || 0) > (now() - lastTime);\n if (config.skipAllowed && skipTime && skipFrame && (lastCount === count) && last[idx]) {\n skipped++;\n return last[idx];\n }\n skipped = 0;\n return new Promise(async (resolve) => {\n if (!model?.inputs[0].shape) return;\n const t: Record = {};\n // t.resize = tf.image.resizeBilinear(image, [model?.inputs[0].shape[2], model?.inputs[0].shape[1]], false);\n const box = [[0.0, 0.10, 0.90, 0.90]]; // empyrical values for top, left, bottom, right\n t.resize = tf.image.cropAndResize(image, box, [0], [model.inputs[0].shape[2], model.inputs[0].shape[1]]);\n const obj: GearType = { age: 0, gender: 'unknown', genderScore: 0, race: [] };\n if (config.face['gear']?.enabled) [t.age, t.gender, t.race] = model.execute(t.resize, ['age_output', 'gender_output', 'race_output']) as Tensor[];\n const gender = await t.gender.data();\n obj.gender = gender[0] > gender[1] ? 'male' : 'female';\n obj.genderScore = Math.round(100 * (gender[0] > gender[1] ? gender[0] : gender[1])) / 100;\n const race = await t.race.data();\n for (let i = 0; i < race.length; i++) {\n if (race[i] > (config.face['gear']?.minConfidence || 0.2)) obj.race.push({ score: Math.round(100 * race[i]) / 100, race: raceNames[i] as Race });\n }\n obj.race.sort((a, b) => b.score - a.score);\n // {0: 'Below20', 1: '21-25', 2: '26-30', 3: '31-40',4: '41-50', 5: '51-60', 6: 'Above60'}\n const ageDistribution = Array.from(await t.age.data());\n const ageSorted = ageDistribution.map((a, i) => [ageWeights[i], a]).sort((a, b) => b[1] - a[1]);\n let age = ageSorted[0][0]; // pick best starting point\n for (let i = 1; i < ageSorted.length; i++) age += ageSorted[i][1] * (ageSorted[i][0] - age); // adjust with each other choice by weight\n obj.age = Math.round(10 * age) / 10;\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n last[idx] = obj;\n lastCount = count;\n lastTime = now();\n resolve(obj);\n });\n}\n", "import * as tf from '../../dist/tfjs.esm.js';\nimport type { Tensor } from './types';\n\nexport const constants: Record = {\n tf255: 255,\n tf1: 1,\n tf2: 2,\n tf05: 0.5,\n tf127: 127.5,\n rgb: [0.2989, 0.5870, 0.1140],\n};\n\nexport function init() {\n constants.tf255 = tf.scalar(255, 'float32');\n constants.tf1 = tf.scalar(1, 'float32');\n constants.tf2 = tf.scalar(2, 'float32');\n constants.tf05 = tf.scalar(0.5, 'float32');\n constants.tf127 = tf.scalar(127.5, 'float32');\n constants.rgb = tf.tensor1d([0.2989, 0.5870, 0.1140], 'float32'); // factors for red/green/blue colors when converting to grayscale\n}\n", "/**\n * Age model implementation\n *\n * Based on: [**SSR-Net**](https://github.com/shamangary/SSR-Net)\n */\n\nimport { log, now } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport { env } from '../util/env';\nimport { constants } from '../tfjs/constants';\nimport type { Config } from '../config';\nimport type { GraphModel, Tensor } from '../tfjs/types';\n\nlet model: GraphModel | null;\nconst last: Array<{ age: number }> = [];\nlet lastCount = 0;\nlet lastTime = 0;\nlet skipped = Number.MAX_SAFE_INTEGER;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function load(config: Config) {\n if (env.initial) model = null;\n if (!model) model = await loadModel(config.face['ssrnet'].modelPathAge);\n else if (config.debug) log('cached model:', model['modelUrl']);\n return model;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function predict(image: Tensor, config: Config, idx: number, count: number): Promise<{ age: number }> {\n if (!model) return { age: 0 };\n const skipFrame = skipped < (config.face['ssrnet']?.skipFrames || 0);\n const skipTime = (config.face['ssrnet']?.skipTime || 0) > (now() - lastTime);\n if (config.skipAllowed && skipFrame && skipTime && (lastCount === count) && last[idx]?.age && (last[idx]?.age > 0)) {\n skipped++;\n return last[idx];\n }\n skipped = 0;\n return new Promise(async (resolve) => {\n if (!model?.inputs || !model.inputs[0] || !model.inputs[0].shape) return;\n const t: Record = {};\n t.resize = tf.image.resizeBilinear(image, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false);\n t.enhance = tf.mul(t.resize, constants.tf255);\n const obj = { age: 0 };\n if (config.face['ssrnet'].enabled) t.age = model.execute(t.enhance) as Tensor;\n if (t.age) {\n const data = await t.age.data();\n obj.age = Math.trunc(10 * data[0]) / 10;\n }\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n last[idx] = obj;\n lastCount = count;\n lastTime = now();\n resolve(obj);\n });\n}\n", "/**\n * Gender model implementation\n *\n * Based on: [**SSR-Net**](https://github.com/shamangary/SSR-Net)\n */\n\nimport { log, now } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport { constants } from '../tfjs/constants';\nimport type { Gender } from '../result';\nimport type { Config } from '../config';\nimport type { GraphModel, Tensor } from '../tfjs/types';\nimport { env } from '../util/env';\n\nlet model: GraphModel | null;\nconst last: Array<{ gender: Gender, genderScore: number }> = [];\nlet lastCount = 0;\nlet lastTime = 0;\nlet skipped = Number.MAX_SAFE_INTEGER;\n\n// tuning values\nconst rgb = [0.2989, 0.5870, 0.1140]; // factors for red/green/blue colors when converting to grayscale\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function load(config: Config | any) {\n if (env.initial) model = null;\n if (!model) model = await loadModel(config.face['ssrnet'].modelPathGender);\n else if (config.debug) log('cached model:', model['modelUrl']);\n return model;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function predict(image: Tensor, config: Config, idx, count): Promise<{ gender: Gender, genderScore: number }> {\n if (!model) return { gender: 'unknown', genderScore: 0 };\n const skipFrame = skipped < (config.face['ssrnet']?.skipFrames || 0);\n const skipTime = (config.face['ssrnet']?.skipTime || 0) > (now() - lastTime);\n if (config.skipAllowed && skipFrame && skipTime && (lastCount === count) && last[idx]?.gender && (last[idx]?.genderScore > 0)) {\n skipped++;\n return last[idx];\n }\n skipped = 0;\n return new Promise(async (resolve) => {\n if (!model?.inputs[0].shape) return;\n const t: Record = {};\n t.resize = tf.image.resizeBilinear(image, [model.inputs[0].shape[2], model.inputs[0].shape[1]], false);\n t.enhance = tf.tidy(() => {\n const [red, green, blue] = tf.split(t.resize, 3, 3);\n const redNorm = tf.mul(red, rgb[0]);\n const greenNorm = tf.mul(green, rgb[1]);\n const blueNorm = tf.mul(blue, rgb[2]);\n const grayscale = tf.addN([redNorm, greenNorm, blueNorm]);\n const normalize = tf.mul(tf.sub(grayscale, constants.tf05), 2); // range grayscale:-1..1\n return normalize;\n });\n const obj: { gender: Gender, genderScore: number } = { gender: 'unknown', genderScore: 0 };\n if (config.face['ssrnet'].enabled) t.gender = model.execute(t.enhance) as Tensor;\n const data = await t.gender.data();\n obj.gender = data[0] > data[1] ? 'female' : 'male'; // returns two values 0..1, bigger one is prediction\n obj.genderScore = data[0] > data[1] ? (Math.trunc(100 * data[0]) / 100) : (Math.trunc(100 * data[1]) / 100);\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n last[idx] = obj;\n lastCount = count;\n lastTime = now();\n resolve(obj);\n });\n}\n", "/**\n * Anti-spoofing model implementation\n */\n\nimport { log, now } from '../util/util';\nimport type { Config } from '../config';\nimport type { GraphModel, Tensor } from '../tfjs/types';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport { env } from '../util/env';\n\nlet model: GraphModel | null;\nconst cached: Array = [];\nlet skipped = Number.MAX_SAFE_INTEGER;\nlet lastCount = 0;\nlet lastTime = 0;\n\nexport async function load(config: Config): Promise {\n if (env.initial) model = null;\n if (!model) model = await loadModel(config.face.antispoof?.modelPath);\n else if (config.debug) log('cached model:', model['modelUrl']);\n return model;\n}\n\nexport async function predict(image: Tensor, config: Config, idx: number, count: number): Promise {\n if (!model) return 0;\n const skipTime = (config.face.antispoof?.skipTime || 0) > (now() - lastTime);\n const skipFrame = skipped < (config.face.antispoof?.skipFrames || 0);\n if (config.skipAllowed && skipTime && skipFrame && (lastCount === count) && cached[idx]) {\n skipped++;\n return cached[idx];\n }\n skipped = 0;\n return new Promise(async (resolve) => {\n const resize = tf.image.resizeBilinear(image, [model?.inputs[0].shape ? model.inputs[0].shape[2] : 0, model?.inputs[0].shape ? model.inputs[0].shape[1] : 0], false);\n const res = model?.execute(resize) as Tensor;\n const num = (await res.data())[0];\n cached[idx] = Math.round(100 * num) / 100;\n lastCount = count;\n lastTime = now();\n tf.dispose([resize, res]);\n resolve(cached[idx]);\n });\n}\n", "/**\n * BlazeFace, FaceMesh & Iris model implementation\n * See `facemesh.ts` for entry point\n */\n\nexport const meshAnnotations: Record = {\n silhouette: [\n 10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288,\n 397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136,\n 172, 58, 132, 93, 234, 127, 162, 21, 54, 103, 67, 109,\n ],\n lipsUpperOuter: [61, 185, 40, 39, 37, 0, 267, 269, 270, 409, 291],\n lipsLowerOuter: [146, 91, 181, 84, 17, 314, 405, 321, 375, 291],\n lipsUpperInner: [78, 191, 80, 81, 82, 13, 312, 311, 310, 415, 308],\n lipsLowerInner: [78, 95, 88, 178, 87, 14, 317, 402, 318, 324, 308],\n rightEyeUpper0: [246, 161, 160, 159, 158, 157, 173],\n rightEyeLower0: [33, 7, 163, 144, 145, 153, 154, 155, 133],\n rightEyeUpper1: [247, 30, 29, 27, 28, 56, 190],\n rightEyeLower1: [130, 25, 110, 24, 23, 22, 26, 112, 243],\n rightEyeUpper2: [113, 225, 224, 223, 222, 221, 189],\n rightEyeLower2: [226, 31, 228, 229, 230, 231, 232, 233, 244],\n rightEyeLower3: [143, 111, 117, 118, 119, 120, 121, 128, 245],\n rightEyebrowUpper: [156, 70, 63, 105, 66, 107, 55, 193],\n rightEyebrowLower: [35, 124, 46, 53, 52, 65],\n rightEyeIris: [473, 474, 475, 476, 477],\n leftEyeUpper0: [466, 388, 387, 386, 385, 384, 398],\n leftEyeLower0: [263, 249, 390, 373, 374, 380, 381, 382, 362],\n leftEyeUpper1: [467, 260, 259, 257, 258, 286, 414],\n leftEyeLower1: [359, 255, 339, 254, 253, 252, 256, 341, 463],\n leftEyeUpper2: [342, 445, 444, 443, 442, 441, 413],\n leftEyeLower2: [446, 261, 448, 449, 450, 451, 452, 453, 464],\n leftEyeLower3: [372, 340, 346, 347, 348, 349, 350, 357, 465],\n leftEyebrowUpper: [383, 300, 293, 334, 296, 336, 285, 417],\n leftEyebrowLower: [265, 353, 276, 283, 282, 295],\n leftEyeIris: [468, 469, 470, 471, 472],\n midwayBetweenEyes: [168],\n noseTip: [1],\n noseBottom: [2],\n noseRightCorner: [98],\n noseLeftCorner: [327],\n rightCheek: [205],\n leftCheek: [425],\n};\n\nexport const meshLandmarks: Record = {\n count: 468,\n mouth: 13,\n symmetryLine: [13, meshAnnotations['midwayBetweenEyes'][0]],\n};\n\nexport const blazeFaceLandmarks: Record = {\n leftEye: 0,\n rightEye: 1,\n nose: 2,\n mouth: 3,\n leftEar: 4,\n rightEar: 5,\n symmetryLine: [3, 2],\n};\n\nexport const MESH_TO_IRIS_INDICES_MAP: Array<{ key: string, indices: number[] }> = [ // A mapping from facemesh model keypoints to iris model keypoints.\n { key: 'EyeUpper0', indices: [9, 10, 11, 12, 13, 14, 15] },\n { key: 'EyeUpper1', indices: [25, 26, 27, 28, 29, 30, 31] },\n { key: 'EyeUpper2', indices: [41, 42, 43, 44, 45, 46, 47] },\n { key: 'EyeLower0', indices: [0, 1, 2, 3, 4, 5, 6, 7, 8] },\n { key: 'EyeLower1', indices: [16, 17, 18, 19, 20, 21, 22, 23, 24] },\n { key: 'EyeLower2', indices: [32, 33, 34, 35, 36, 37, 38, 39, 40] },\n { key: 'EyeLower3', indices: [54, 55, 56, 57, 58, 59, 60, 61, 62] },\n // { key: 'EyebrowUpper', indices: [63, 64, 65, 66, 67, 68, 69, 70] },\n // { key: 'EyebrowLower', indices: [48, 49, 50, 51, 52, 53] },\n];\n\nexport const UV468: [number, number][] = [\n [0.499976992607117, 0.652534008026123],\n [0.500025987625122, 0.547487020492554],\n [0.499974012374878, 0.602371990680695],\n [0.482113003730774, 0.471979022026062],\n [0.500150978565216, 0.527155995368958],\n [0.499909996986389, 0.498252987861633],\n [0.499523013830185, 0.40106201171875],\n [0.289712011814117, 0.380764007568359],\n [0.499954998493195, 0.312398016452789],\n [0.499987006187439, 0.269918978214264],\n [0.500023007392883, 0.107050001621246],\n [0.500023007392883, 0.666234016418457],\n [0.5000159740448, 0.679224014282227],\n [0.500023007392883, 0.692348003387451],\n [0.499976992607117, 0.695277988910675],\n [0.499976992607117, 0.70593398809433],\n [0.499976992607117, 0.719385027885437],\n [0.499976992607117, 0.737019002437592],\n [0.499967992305756, 0.781370997428894],\n [0.499816000461578, 0.562981009483337],\n [0.473773002624512, 0.573909997940063],\n [0.104906998574734, 0.254140973091125],\n [0.365929991006851, 0.409575998783112],\n [0.338757991790771, 0.41302502155304],\n [0.311120003461838, 0.409460008144379],\n [0.274657994508743, 0.389131009578705],\n [0.393361985683441, 0.403706014156342],\n [0.345234006643295, 0.344011008739471],\n [0.370094001293182, 0.346076011657715],\n [0.319321990013123, 0.347265005111694],\n [0.297903001308441, 0.353591024875641],\n [0.24779200553894, 0.410809993743896],\n [0.396889001131058, 0.842755019664764],\n [0.280097991228104, 0.375599980354309],\n [0.106310002505779, 0.399955987930298],\n [0.2099249958992, 0.391353011131287],\n [0.355807989835739, 0.534406006336212],\n [0.471751004457474, 0.65040397644043],\n [0.474155008792877, 0.680191993713379],\n [0.439785003662109, 0.657229006290436],\n [0.414617002010345, 0.66654098033905],\n [0.450374007225037, 0.680860996246338],\n [0.428770989179611, 0.682690978050232],\n [0.374971002340317, 0.727805018424988],\n [0.486716985702515, 0.547628998756409],\n [0.485300987958908, 0.527395009994507],\n [0.257764995098114, 0.314490020275116],\n [0.401223003864288, 0.455172002315521],\n [0.429818987846375, 0.548614978790283],\n [0.421351999044418, 0.533740997314453],\n [0.276895999908447, 0.532056987285614],\n [0.483370006084442, 0.499586999416351],\n [0.33721199631691, 0.282882988452911],\n [0.296391993761063, 0.293242990970612],\n [0.169294998049736, 0.193813979625702],\n [0.447580009698868, 0.302609980106354],\n [0.392390012741089, 0.353887975215912],\n [0.354490011930466, 0.696784019470215],\n [0.067304998636246, 0.730105042457581],\n [0.442739009857178, 0.572826027870178],\n [0.457098007202148, 0.584792017936707],\n [0.381974011659622, 0.694710969924927],\n [0.392388999462128, 0.694203019142151],\n [0.277076005935669, 0.271932005882263],\n [0.422551989555359, 0.563233017921448],\n [0.385919004678726, 0.281364023685455],\n [0.383103013038635, 0.255840003490448],\n [0.331431001424789, 0.119714021682739],\n [0.229923993349075, 0.232002973556519],\n [0.364500999450684, 0.189113974571228],\n [0.229622006416321, 0.299540996551514],\n [0.173287004232407, 0.278747975826263],\n [0.472878992557526, 0.666198015213013],\n [0.446828007698059, 0.668527007102966],\n [0.422762006521225, 0.673889994621277],\n [0.445307999849319, 0.580065965652466],\n [0.388103008270264, 0.693961024284363],\n [0.403039008378983, 0.706539988517761],\n [0.403629004955292, 0.693953037261963],\n [0.460041999816895, 0.557139039039612],\n [0.431158006191254, 0.692366003990173],\n [0.452181994915009, 0.692366003990173],\n [0.475387006998062, 0.692366003990173],\n [0.465828001499176, 0.779190003871918],\n [0.472328990697861, 0.736225962638855],\n [0.473087012767792, 0.717857003211975],\n [0.473122000694275, 0.704625964164734],\n [0.473033010959625, 0.695277988910675],\n [0.427942007780075, 0.695277988910675],\n [0.426479011774063, 0.703539967536926],\n [0.423162013292313, 0.711845993995667],\n [0.4183090031147, 0.720062971115112],\n [0.390094995498657, 0.639572978019714],\n [0.013953999616206, 0.560034036636353],\n [0.499913990497589, 0.58014702796936],\n [0.413199990987778, 0.69539999961853],\n [0.409626007080078, 0.701822996139526],\n [0.468080013990402, 0.601534962654114],\n [0.422728985548019, 0.585985004901886],\n [0.463079988956451, 0.593783974647522],\n [0.37211999297142, 0.47341400384903],\n [0.334562003612518, 0.496073007583618],\n [0.411671012639999, 0.546965003013611],\n [0.242175996303558, 0.14767599105835],\n [0.290776997804642, 0.201445996761322],\n [0.327338010072708, 0.256527006626129],\n [0.399509996175766, 0.748921036720276],\n [0.441727995872498, 0.261676013469696],\n [0.429764986038208, 0.187834024429321],\n [0.412198007106781, 0.108901023864746],\n [0.288955003023148, 0.398952007293701],\n [0.218936994671822, 0.435410976409912],\n [0.41278201341629, 0.398970007896423],\n [0.257135003805161, 0.355440020561218],\n [0.427684992551804, 0.437960982322693],\n [0.448339998722076, 0.536936044692993],\n [0.178560003638268, 0.45755398273468],\n [0.247308000922203, 0.457193970680237],\n [0.286267012357712, 0.467674970626831],\n [0.332827985286713, 0.460712015628815],\n [0.368755996227264, 0.447206974029541],\n [0.398963987827301, 0.432654976844788],\n [0.476410001516342, 0.405806005001068],\n [0.189241006970406, 0.523923993110657],\n [0.228962004184723, 0.348950982093811],\n [0.490725994110107, 0.562400996685028],\n [0.404670000076294, 0.485132992267609],\n [0.019469000399113, 0.401564002037048],\n [0.426243007183075, 0.420431017875671],\n [0.396993011236191, 0.548797011375427],\n [0.266469985246658, 0.376977026462555],\n [0.439121007919312, 0.51895797252655],\n [0.032313998788595, 0.644356966018677],\n [0.419054001569748, 0.387154996395111],\n [0.462783008813858, 0.505746960639954],\n [0.238978996872902, 0.779744982719421],\n [0.198220998048782, 0.831938028335571],\n [0.107550002634525, 0.540755033493042],\n [0.183610007166862, 0.740257024765015],\n [0.134409993886948, 0.333683013916016],\n [0.385764002799988, 0.883153975009918],\n [0.490967005491257, 0.579378008842468],\n [0.382384985685349, 0.508572995662689],\n [0.174399003386497, 0.397670984268188],\n [0.318785011768341, 0.39623498916626],\n [0.343364000320435, 0.400596976280212],\n [0.396100014448166, 0.710216999053955],\n [0.187885001301765, 0.588537991046906],\n [0.430987000465393, 0.944064974784851],\n [0.318993002176285, 0.898285031318665],\n [0.266247987747192, 0.869701027870178],\n [0.500023007392883, 0.190576016902924],\n [0.499976992607117, 0.954452991485596],\n [0.366169989109039, 0.398822009563446],\n [0.393207013607025, 0.39553701877594],\n [0.410373002290726, 0.391080021858215],\n [0.194993004202843, 0.342101991176605],\n [0.388664990663528, 0.362284004688263],\n [0.365961998701096, 0.355970978736877],\n [0.343364000320435, 0.355356991291046],\n [0.318785011768341, 0.35834002494812],\n [0.301414996385574, 0.363156020641327],\n [0.058132998645306, 0.319076001644135],\n [0.301414996385574, 0.387449026107788],\n [0.499987989664078, 0.618434011936188],\n [0.415838003158569, 0.624195992946625],\n [0.445681989192963, 0.566076993942261],\n [0.465844005346298, 0.620640993118286],\n [0.49992299079895, 0.351523995399475],\n [0.288718998432159, 0.819945991039276],\n [0.335278987884521, 0.852819979190826],\n [0.440512001514435, 0.902418971061707],\n [0.128294005990028, 0.791940987110138],\n [0.408771991729736, 0.373893976211548],\n [0.455606997013092, 0.451801002025604],\n [0.499877005815506, 0.908990025520325],\n [0.375436991453171, 0.924192011356354],\n [0.11421000212431, 0.615022003650665],\n [0.448662012815475, 0.695277988910675],\n [0.4480200111866, 0.704632043838501],\n [0.447111994028091, 0.715808033943176],\n [0.444831997156143, 0.730794012546539],\n [0.430011987686157, 0.766808986663818],\n [0.406787008047104, 0.685672998428345],\n [0.400738000869751, 0.681069016456604],\n [0.392399996519089, 0.677703022956848],\n [0.367855995893478, 0.663918972015381],\n [0.247923001646996, 0.601333022117615],\n [0.452769994735718, 0.420849978923798],\n [0.43639200925827, 0.359887003898621],\n [0.416164010763168, 0.368713974952698],\n [0.413385987281799, 0.692366003990173],\n [0.228018000721931, 0.683571994304657],\n [0.468268007040024, 0.352671027183533],\n [0.411361992359161, 0.804327011108398],\n [0.499989002943039, 0.469825029373169],\n [0.479153990745544, 0.442654013633728],\n [0.499974012374878, 0.439637005329132],\n [0.432112008333206, 0.493588984012604],\n [0.499886006116867, 0.866917014122009],\n [0.49991300702095, 0.821729004383087],\n [0.456548988819122, 0.819200992584229],\n [0.344549000263214, 0.745438992977142],\n [0.37890899181366, 0.574010014533997],\n [0.374292999505997, 0.780184984207153],\n [0.319687992334366, 0.570737957954407],\n [0.357154995203018, 0.604269981384277],\n [0.295284003019333, 0.621580958366394],\n [0.447750002145767, 0.862477004528046],\n [0.410986006259918, 0.508723020553589],\n [0.31395098567009, 0.775308012962341],\n [0.354128003120422, 0.812552988529205],\n [0.324548006057739, 0.703992962837219],\n [0.189096003770828, 0.646299958229065],\n [0.279776990413666, 0.71465802192688],\n [0.1338230073452, 0.682700991630554],\n [0.336768001317978, 0.644733011722565],\n [0.429883986711502, 0.466521978378296],\n [0.455527991056442, 0.548622965812683],\n [0.437114000320435, 0.558896005153656],\n [0.467287987470627, 0.529924988746643],\n [0.414712011814117, 0.335219979286194],\n [0.37704598903656, 0.322777986526489],\n [0.344107985496521, 0.320150971412659],\n [0.312875986099243, 0.32233202457428],\n [0.283526003360748, 0.333190023899078],\n [0.241245999932289, 0.382785975933075],\n [0.102986000478268, 0.468762993812561],\n [0.267612010240555, 0.424560010433197],\n [0.297879010438919, 0.433175981044769],\n [0.333433985710144, 0.433878004550934],\n [0.366427004337311, 0.426115989685059],\n [0.396012008190155, 0.416696012020111],\n [0.420121014118195, 0.41022801399231],\n [0.007561000064015, 0.480777025222778],\n [0.432949006557465, 0.569517970085144],\n [0.458638995885849, 0.479089021682739],\n [0.473466008901596, 0.545744001865387],\n [0.476087987422943, 0.563830018043518],\n [0.468472003936768, 0.555056989192963],\n [0.433990985155106, 0.582361996173859],\n [0.483518004417419, 0.562983989715576],\n [0.482482999563217, 0.57784903049469],\n [0.42645001411438, 0.389798998832703],\n [0.438998997211456, 0.39649498462677],\n [0.450067013502121, 0.400434017181396],\n [0.289712011814117, 0.368252992630005],\n [0.276670008897781, 0.363372981548309],\n [0.517862021923065, 0.471948027610779],\n [0.710287988185883, 0.380764007568359],\n [0.526226997375488, 0.573909997940063],\n [0.895093023777008, 0.254140973091125],\n [0.634069979190826, 0.409575998783112],\n [0.661242008209229, 0.41302502155304],\n [0.688880026340485, 0.409460008144379],\n [0.725341975688934, 0.389131009578705],\n [0.606630027294159, 0.40370500087738],\n [0.654766023159027, 0.344011008739471],\n [0.629905998706818, 0.346076011657715],\n [0.680678009986877, 0.347265005111694],\n [0.702096998691559, 0.353591024875641],\n [0.75221198797226, 0.410804986953735],\n [0.602918028831482, 0.842862963676453],\n [0.719901978969574, 0.375599980354309],\n [0.893692970275879, 0.399959981441498],\n [0.790081977844238, 0.391354024410248],\n [0.643998026847839, 0.534487962722778],\n [0.528249025344849, 0.65040397644043],\n [0.525849997997284, 0.680191040039062],\n [0.560214996337891, 0.657229006290436],\n [0.585384011268616, 0.66654098033905],\n [0.549625992774963, 0.680860996246338],\n [0.57122802734375, 0.682691991329193],\n [0.624852001667023, 0.72809898853302],\n [0.513050019741058, 0.547281980514526],\n [0.51509702205658, 0.527251958847046],\n [0.742246985435486, 0.314507007598877],\n [0.598631024360657, 0.454979002475739],\n [0.570338010787964, 0.548575043678284],\n [0.578631997108459, 0.533622980117798],\n [0.723087012767792, 0.532054007053375],\n [0.516445994377136, 0.499638974666595],\n [0.662801027297974, 0.282917976379395],\n [0.70362401008606, 0.293271005153656],\n [0.830704987049103, 0.193813979625702],\n [0.552385985851288, 0.302568018436432],\n [0.607609987258911, 0.353887975215912],\n [0.645429015159607, 0.696707010269165],\n [0.932694971561432, 0.730105042457581],\n [0.557260990142822, 0.572826027870178],\n [0.542901992797852, 0.584792017936707],\n [0.6180260181427, 0.694710969924927],\n [0.607590973377228, 0.694203019142151],\n [0.722943007946014, 0.271963000297546],\n [0.577413976192474, 0.563166975975037],\n [0.614082992076874, 0.281386971473694],\n [0.616907000541687, 0.255886018276215],\n [0.668509006500244, 0.119913995265961],\n [0.770092010498047, 0.232020974159241],\n [0.635536015033722, 0.189248979091644],\n [0.77039098739624, 0.299556016921997],\n [0.826722025871277, 0.278755009174347],\n [0.527121007442474, 0.666198015213013],\n [0.553171992301941, 0.668527007102966],\n [0.577238023281097, 0.673889994621277],\n [0.554691970348358, 0.580065965652466],\n [0.611896991729736, 0.693961024284363],\n [0.59696102142334, 0.706539988517761],\n [0.596370995044708, 0.693953037261963],\n [0.539958000183105, 0.557139039039612],\n [0.568841993808746, 0.692366003990173],\n [0.547818005084991, 0.692366003990173],\n [0.52461302280426, 0.692366003990173],\n [0.534089982509613, 0.779141008853912],\n [0.527670979499817, 0.736225962638855],\n [0.526912987232208, 0.717857003211975],\n [0.526877999305725, 0.704625964164734],\n [0.526966989040375, 0.695277988910675],\n [0.572058022022247, 0.695277988910675],\n [0.573521018028259, 0.703539967536926],\n [0.57683801651001, 0.711845993995667],\n [0.581691026687622, 0.720062971115112],\n [0.609944999217987, 0.639909982681274],\n [0.986046016216278, 0.560034036636353],\n [0.5867999792099, 0.69539999961853],\n [0.590372025966644, 0.701822996139526],\n [0.531915009021759, 0.601536989212036],\n [0.577268004417419, 0.585934996604919],\n [0.536915004253387, 0.593786001205444],\n [0.627542972564697, 0.473352015018463],\n [0.665585994720459, 0.495950996875763],\n [0.588353991508484, 0.546862006187439],\n [0.757824003696442, 0.14767599105835],\n [0.709249973297119, 0.201507985591888],\n [0.672684013843536, 0.256581008434296],\n [0.600408971309662, 0.74900496006012],\n [0.55826598405838, 0.261672019958496],\n [0.570303976535797, 0.187870979309082],\n [0.588165998458862, 0.109044015407562],\n [0.711045026779175, 0.398952007293701],\n [0.781069993972778, 0.435405015945435],\n [0.587247014045715, 0.398931980133057],\n [0.742869973182678, 0.355445981025696],\n [0.572156012058258, 0.437651991844177],\n [0.55186802148819, 0.536570012569427],\n [0.821442008018494, 0.457556009292603],\n [0.752701997756958, 0.457181990146637],\n [0.71375697851181, 0.467626988887787],\n [0.66711300611496, 0.460672974586487],\n [0.631101012229919, 0.447153985500336],\n [0.6008620262146, 0.432473003864288],\n [0.523481011390686, 0.405627012252808],\n [0.810747981071472, 0.523926019668579],\n [0.771045982837677, 0.348959028720856],\n [0.509127020835876, 0.562718033790588],\n [0.595292985439301, 0.485023975372314],\n [0.980530977249146, 0.401564002037048],\n [0.573499977588654, 0.420000016689301],\n [0.602994978427887, 0.548687994480133],\n [0.733529984951019, 0.376977026462555],\n [0.560611009597778, 0.519016981124878],\n [0.967685997486115, 0.644356966018677],\n [0.580985009670258, 0.387160003185272],\n [0.537728011608124, 0.505385041236877],\n [0.760966002941132, 0.779752969741821],\n [0.801778972148895, 0.831938028335571],\n [0.892440974712372, 0.54076099395752],\n [0.816350996494293, 0.740260004997253],\n [0.865594983100891, 0.333687007427216],\n [0.614073991775513, 0.883246004581451],\n [0.508952975273132, 0.579437971115112],\n [0.617941975593567, 0.508316040039062],\n [0.825608015060425, 0.397674977779388],\n [0.681214988231659, 0.39623498916626],\n [0.656635999679565, 0.400596976280212],\n [0.603900015354156, 0.710216999053955],\n [0.81208598613739, 0.588539004325867],\n [0.56801301240921, 0.944564998149872],\n [0.681007981300354, 0.898285031318665],\n [0.733752012252808, 0.869701027870178],\n [0.633830010890961, 0.398822009563446],\n [0.606792986392975, 0.39553701877594],\n [0.589659988880157, 0.391062021255493],\n [0.805015981197357, 0.342108011245728],\n [0.611334979534149, 0.362284004688263],\n [0.634037971496582, 0.355970978736877],\n [0.656635999679565, 0.355356991291046],\n [0.681214988231659, 0.35834002494812],\n [0.698584973812103, 0.363156020641327],\n [0.941866993904114, 0.319076001644135],\n [0.698584973812103, 0.387449026107788],\n [0.584177017211914, 0.624107003211975],\n [0.554318010807037, 0.566076993942261],\n [0.534153997898102, 0.62064003944397],\n [0.711217999458313, 0.819975018501282],\n [0.664629995822906, 0.852871000766754],\n [0.559099972248077, 0.902631998062134],\n [0.871706008911133, 0.791940987110138],\n [0.591234028339386, 0.373893976211548],\n [0.544341027736664, 0.451583981513977],\n [0.624562978744507, 0.924192011356354],\n [0.88577002286911, 0.615028977394104],\n [0.551338016986847, 0.695277988910675],\n [0.551980018615723, 0.704632043838501],\n [0.552887976169586, 0.715808033943176],\n [0.555167973041534, 0.730794012546539],\n [0.569944024085999, 0.767035007476807],\n [0.593203008174896, 0.685675978660583],\n [0.599261999130249, 0.681069016456604],\n [0.607599973678589, 0.677703022956848],\n [0.631937980651855, 0.663500010967255],\n [0.752032995223999, 0.601315021514893],\n [0.547226011753082, 0.420395016670227],\n [0.563543975353241, 0.359827995300293],\n [0.583841025829315, 0.368713974952698],\n [0.586614012718201, 0.692366003990173],\n [0.771915018558502, 0.683578014373779],\n [0.531597018241882, 0.352482974529266],\n [0.588370978832245, 0.804440975189209],\n [0.52079701423645, 0.442565023899078],\n [0.567984998226166, 0.493479013442993],\n [0.543282985687256, 0.819254994392395],\n [0.655317008495331, 0.745514988899231],\n [0.621008992195129, 0.574018001556396],\n [0.625559985637665, 0.78031200170517],\n [0.680198013782501, 0.570719003677368],\n [0.64276397228241, 0.604337990283966],\n [0.704662978649139, 0.621529996395111],\n [0.552012026309967, 0.862591981887817],\n [0.589071989059448, 0.508637011051178],\n [0.685944974422455, 0.775357007980347],\n [0.645735025405884, 0.812640011310577],\n [0.675342977046967, 0.703978002071381],\n [0.810858011245728, 0.646304965019226],\n [0.72012197971344, 0.714666962623596],\n [0.866151988506317, 0.682704985141754],\n [0.663187026977539, 0.644596993923187],\n [0.570082008838654, 0.466325998306274],\n [0.544561982154846, 0.548375964164734],\n [0.562758982181549, 0.558784961700439],\n [0.531987011432648, 0.530140042304993],\n [0.585271000862122, 0.335177004337311],\n [0.622952997684479, 0.32277899980545],\n [0.655896008014679, 0.320163011550903],\n [0.687132000923157, 0.322345972061157],\n [0.716481983661652, 0.333200991153717],\n [0.758756995201111, 0.382786989212036],\n [0.897013008594513, 0.468769013881683],\n [0.732392013072968, 0.424547016620636],\n [0.70211398601532, 0.433162987232208],\n [0.66652500629425, 0.433866024017334],\n [0.633504986763, 0.426087975502014],\n [0.603875994682312, 0.416586995124817],\n [0.579657971858978, 0.409945011138916],\n [0.992439985275269, 0.480777025222778],\n [0.567192018032074, 0.569419980049133],\n [0.54136598110199, 0.478899002075195],\n [0.526564002037048, 0.546118021011353],\n [0.523913025856018, 0.563830018043518],\n [0.531529009342194, 0.555056989192963],\n [0.566035985946655, 0.582329034805298],\n [0.51631098985672, 0.563053965568542],\n [0.5174720287323, 0.577877044677734],\n [0.573594987392426, 0.389806985855103],\n [0.560697972774506, 0.395331978797913],\n [0.549755990505219, 0.399751007556915],\n [0.710287988185883, 0.368252992630005],\n [0.723330020904541, 0.363372981548309],\n];\n\nexport const TRI468: Array = [\n 127, 34, 139, 11, 0, 37, 232, 231, 120, 72, 37, 39, 128, 121, 47, 232, 121, 128, 104, 69, 67, 175, 171, 148, 157, 154, 155, 118, 50, 101, 73, 39, 40, 9,\n 151, 108, 48, 115, 131, 194, 204, 211, 74, 40, 185, 80, 42, 183, 40, 92, 186, 230, 229, 118, 202, 212, 214, 83, 18, 17, 76, 61, 146, 160, 29, 30, 56,\n 157, 173, 106, 204, 194, 135, 214, 192, 203, 165, 98, 21, 71, 68, 51, 45, 4, 144, 24, 23, 77, 146, 91, 205, 50, 187, 201, 200, 18, 91, 106, 182, 90, 91,\n 181, 85, 84, 17, 206, 203, 36, 148, 171, 140, 92, 40, 39, 193, 189, 244, 159, 158, 28, 247, 246, 161, 236, 3, 196, 54, 68, 104, 193, 168, 8, 117,\n 228, 31, 189, 193, 55, 98, 97, 99, 126, 47, 100, 166, 79, 218, 155, 154, 26, 209, 49, 131, 135, 136, 150, 47, 126, 217, 223, 52, 53, 45, 51, 134, 211,\n 170, 140, 67, 69, 108, 43, 106, 91, 230, 119, 120, 226, 130, 247, 63, 53, 52, 238, 20, 242, 46, 70, 156, 78, 62, 96, 46, 53, 63, 143, 34, 227, 173,\n 155, 133, 123, 117, 111, 44, 125, 19, 236, 134, 51, 216, 206, 205, 154, 153, 22, 39, 37, 167, 200, 201, 208, 36, 142, 100, 57, 212, 202, 20, 60, 99, 28,\n 158, 157, 35, 226, 113, 160, 159, 27, 204, 202, 210, 113, 225, 46, 43, 202, 204, 62, 76, 77, 137, 123, 116, 41, 38, 72, 203, 129, 142, 64, 98, 240, 49,\n 102, 64, 41, 73, 74, 212, 216, 207, 42, 74, 184, 169, 170, 211, 170, 149, 176, 105, 66, 69, 122, 6, 168, 123, 147, 187, 96, 77, 90, 65, 55, 107, 89,\n 90, 180, 101, 100, 120, 63, 105, 104, 93, 137, 227, 15, 86, 85, 129, 102, 49, 14, 87, 86, 55, 8, 9, 100, 47, 121, 145, 23, 22, 88, 89, 179, 6, 122,\n 196, 88, 95, 96, 138, 172, 136, 215, 58, 172, 115, 48, 219, 42, 80, 81, 195, 3, 51, 43, 146, 61, 171, 175, 199, 81, 82, 38, 53, 46, 225, 144, 163, 110,\n 246, 33, 7, 52, 65, 66, 229, 228, 117, 34, 127, 234, 107, 108, 69, 109, 108, 151, 48, 64, 235, 62, 78, 191, 129, 209, 126, 111, 35, 143, 163, 161, 246,\n 117, 123, 50, 222, 65, 52, 19, 125, 141, 221, 55, 65, 3, 195, 197, 25, 7, 33, 220, 237, 44, 70, 71, 139, 122, 193, 245, 247, 130, 33, 71, 21, 162,\n 153, 158, 159, 170, 169, 150, 188, 174, 196, 216, 186, 92, 144, 160, 161, 2, 97, 167, 141, 125, 241, 164, 167, 37, 72, 38, 12, 145, 159, 160, 38, 82, 13,\n 63, 68, 71, 226, 35, 111, 158, 153, 154, 101, 50, 205, 206, 92, 165, 209, 198, 217, 165, 167, 97, 220, 115, 218, 133, 112, 243, 239, 238, 241, 214,\n 135, 169, 190, 173, 133, 171, 208, 32, 125, 44, 237, 86, 87, 178, 85, 86, 179, 84, 85, 180, 83, 84, 181, 201, 83, 182, 137, 93, 132, 76, 62, 183, 61,\n 76, 184, 57, 61, 185, 212, 57, 186, 214, 207, 187, 34, 143, 156, 79, 239, 237, 123, 137, 177, 44, 1, 4, 201, 194, 32, 64, 102, 129, 213, 215, 138, 59,\n 166, 219, 242, 99, 97, 2, 94, 141, 75, 59, 235, 24, 110, 228, 25, 130, 226, 23, 24, 229, 22, 23, 230, 26, 22, 231, 112, 26, 232, 189, 190, 243, 221, 56,\n 190, 28, 56, 221, 27, 28, 222, 29, 27, 223, 30, 29, 224, 247, 30, 225, 238, 79, 20, 166, 59, 75, 60, 75, 240, 147, 177, 215, 20, 79, 166, 187, 147, 213,\n 112, 233, 244, 233, 128, 245, 128, 114, 188, 114, 217, 174, 131, 115, 220, 217, 198, 236, 198, 131, 134, 177, 132, 58, 143, 35, 124, 110, 163, 7, 228,\n 110, 25, 356, 389, 368, 11, 302, 267, 452, 350, 349, 302, 303, 269, 357, 343, 277, 452, 453, 357, 333, 332, 297, 175, 152, 377, 384, 398, 382, 347,\n 348, 330, 303, 304, 270, 9, 336, 337, 278, 279, 360, 418, 262, 431, 304, 408, 409, 310, 415, 407, 270, 409, 410, 450, 348, 347, 422, 430, 434, 313,\n 314, 17, 306, 307, 375, 387, 388, 260, 286, 414, 398, 335, 406, 418, 364, 367, 416, 423, 358, 327, 251, 284, 298, 281, 5, 4, 373, 374, 253, 307, 320,\n 321, 425, 427, 411, 421, 313, 18, 321, 405, 406, 320, 404, 405, 315, 16, 17, 426, 425, 266, 377, 400, 369, 322, 391, 269, 417, 465, 464, 386, 257, 258,\n 466, 260, 388, 456, 399, 419, 284, 332, 333, 417, 285, 8, 346, 340, 261, 413, 441, 285, 327, 460, 328, 355, 371, 329, 392, 439, 438, 382, 341, 256,\n 429, 420, 360, 364, 394, 379, 277, 343, 437, 443, 444, 283, 275, 440, 363, 431, 262, 369, 297, 338, 337, 273, 375, 321, 450, 451, 349, 446, 342, 467,\n 293, 334, 282, 458, 461, 462, 276, 353, 383, 308, 324, 325, 276, 300, 293, 372, 345, 447, 382, 398, 362, 352, 345, 340, 274, 1, 19, 456, 248, 281, 436,\n 427, 425, 381, 256, 252, 269, 391, 393, 200, 199, 428, 266, 330, 329, 287, 273, 422, 250, 462, 328, 258, 286, 384, 265, 353, 342, 387, 259, 257, 424,\n 431, 430, 342, 353, 276, 273, 335, 424, 292, 325, 307, 366, 447, 345, 271, 303, 302, 423, 266, 371, 294, 455, 460, 279, 278, 294, 271, 272, 304, 432,\n 434, 427, 272, 407, 408, 394, 430, 431, 395, 369, 400, 334, 333, 299, 351, 417, 168, 352, 280, 411, 325, 319, 320, 295, 296, 336, 319, 403, 404, 330,\n 348, 349, 293, 298, 333, 323, 454, 447, 15, 16, 315, 358, 429, 279, 14, 15, 316, 285, 336, 9, 329, 349, 350, 374, 380, 252, 318, 402, 403, 6, 197, 419,\n 318, 319, 325, 367, 364, 365, 435, 367, 397, 344, 438, 439, 272, 271, 311, 195, 5, 281, 273, 287, 291, 396, 428, 199, 311, 271, 268, 283, 444, 445,\n 373, 254, 339, 263, 466, 249, 282, 334, 296, 449, 347, 346, 264, 447, 454, 336, 296, 299, 338, 10, 151, 278, 439, 455, 292, 407, 415, 358, 371, 355,\n 340, 345, 372, 390, 249, 466, 346, 347, 280, 442, 443, 282, 19, 94, 370, 441, 442, 295, 248, 419, 197, 263, 255, 359, 440, 275, 274, 300, 383, 368,\n 351, 412, 465, 263, 467, 466, 301, 368, 389, 380, 374, 386, 395, 378, 379, 412, 351, 419, 436, 426, 322, 373, 390, 388, 2, 164, 393, 370, 462, 461,\n 164, 0, 267, 302, 11, 12, 374, 373, 387, 268, 12, 13, 293, 300, 301, 446, 261, 340, 385, 384, 381, 330, 266, 425, 426, 423, 391, 429, 355, 437, 391,\n 327, 326, 440, 457, 438, 341, 382, 362, 459, 457, 461, 434, 430, 394, 414, 463, 362, 396, 369, 262, 354, 461, 457, 316, 403, 402, 315, 404, 403, 314,\n 405, 404, 313, 406, 405, 421, 418, 406, 366, 401, 361, 306, 408, 407, 291, 409, 408, 287, 410, 409, 432, 436, 410, 434, 416, 411, 264, 368, 383, 309,\n 438, 457, 352, 376, 401, 274, 275, 4, 421, 428, 262, 294, 327, 358, 433, 416, 367, 289, 455, 439, 462, 370, 326, 2, 326, 370, 305, 460, 455, 254,\n 449, 448, 255, 261, 446, 253, 450, 449, 252, 451, 450, 256, 452, 451, 341, 453, 452, 413, 464, 463, 441, 413, 414, 258, 442, 441, 257, 443, 442, 259,\n 444, 443, 260, 445, 444, 467, 342, 445, 459, 458, 250, 289, 392, 290, 290, 328, 460, 376, 433, 435, 250, 290, 392, 411, 416, 433, 341, 463, 464, 453,\n 464, 465, 357, 465, 412, 343, 412, 399, 360, 363, 440, 437, 399, 456, 420, 456, 363, 401, 435, 288, 372, 383, 353, 339, 255, 249, 448, 261, 255, 133,\n 243, 190, 133, 155, 112, 33, 246, 247, 33, 130, 25, 398, 384, 286, 362, 398, 414, 362, 463, 341, 263, 359, 467, 263, 249, 255, 466, 467, 260, 75, 60,\n 166, 238, 239, 79, 162, 127, 139, 72, 11, 37, 121, 232, 120, 73, 72, 39, 114, 128, 47, 233, 232, 128, 103, 104, 67, 152, 175, 148, 173, 157, 155,\n 119, 118, 101, 74, 73, 40, 107, 9, 108, 49, 48, 131, 32, 194, 211, 184, 74, 185, 191, 80, 183, 185, 40, 186, 119, 230, 118, 210, 202, 214, 84, 83, 17,\n 77, 76, 146, 161, 160, 30, 190, 56, 173, 182, 106, 194, 138, 135, 192, 129, 203, 98, 54, 21, 68, 5, 51, 4, 145, 144, 23, 90, 77, 91, 207, 205, 187, 83,\n 201, 18, 181, 91, 182, 180, 90, 181, 16, 85, 17, 205, 206, 36, 176, 148, 140, 165, 92, 39, 245, 193, 244, 27, 159, 28, 30, 247, 161, 174, 236, 196,\n 103, 54, 104, 55, 193, 8, 111, 117, 31, 221, 189, 55, 240, 98, 99, 142, 126, 100, 219, 166, 218, 112, 155, 26, 198, 209, 131, 169, 135, 150, 114, 47,\n 217, 224, 223, 53, 220, 45, 134, 32, 211, 140, 109, 67, 108, 146, 43, 91, 231, 230, 120, 113, 226, 247, 105, 63, 52, 241, 238, 242, 124, 46, 156, 95,\n 78, 96, 70, 46, 63, 116, 143, 227, 116, 123, 111, 1, 44, 19, 3, 236, 51, 207, 216, 205, 26, 154, 22, 165, 39, 167, 199, 200, 208, 101, 36, 100, 43,\n 57, 202, 242, 20, 99, 56, 28, 157, 124, 35, 113, 29, 160, 27, 211, 204, 210, 124, 113, 46, 106, 43, 204, 96, 62, 77, 227, 137, 116, 73, 41, 72, 36, 203,\n 142, 235, 64, 240, 48, 49, 64, 42, 41, 74, 214, 212, 207, 183, 42, 184, 210, 169, 211, 140, 170, 176, 104, 105, 69, 193, 122, 168, 50, 123, 187, 89, 96,\n 90, 66, 65, 107, 179, 89, 180, 119, 101, 120, 68, 63, 104, 234, 93, 227, 16, 15, 85, 209, 129, 49, 15, 14, 86, 107, 55, 9, 120, 100, 121, 153, 145, 22,\n 178, 88, 179, 197, 6, 196, 89, 88, 96, 135, 138, 136, 138, 215, 172, 218, 115, 219, 41, 42, 81, 5, 195, 51, 57, 43, 61, 208, 171, 199, 41, 81, 38,\n 224, 53, 225, 24, 144, 110, 105, 52, 66, 118, 229, 117, 227, 34, 234, 66, 107, 69, 10, 109, 151, 219, 48, 235, 183, 62, 191, 142, 129, 126, 116, 111,\n 143, 7, 163, 246, 118, 117, 50, 223, 222, 52, 94, 19, 141, 222, 221, 65, 196, 3, 197, 45, 220, 44, 156, 70, 139, 188, 122, 245, 139, 71, 162, 145,\n 153, 159, 149, 170, 150, 122, 188, 196, 206, 216, 92, 163, 144, 161, 164, 2, 167, 242, 141, 241, 0, 164, 37, 11, 72, 12, 144, 145, 160, 12, 38, 13, 70,\n 63, 71, 31, 226, 111, 157, 158, 154, 36, 101, 205, 203, 206, 165, 126, 209, 217, 98, 165, 97, 237, 220, 218, 237, 239, 241, 210, 214, 169, 140, 171, 32,\n 241, 125, 237, 179, 86, 178, 180, 85, 179, 181, 84, 180, 182, 83, 181, 194, 201, 182, 177, 137, 132, 184, 76, 183, 185, 61, 184, 186, 57, 185, 216, 212,\n 186, 192, 214, 187, 139, 34, 156, 218, 79, 237, 147, 123, 177, 45, 44, 4, 208, 201, 32, 98, 64, 129, 192, 213, 138, 235, 59, 219, 141, 242, 97, 97, 2,\n 141, 240, 75, 235, 229, 24, 228, 31, 25, 226, 230, 23, 229, 231, 22, 230, 232, 26, 231, 233, 112, 232, 244, 189, 243, 189, 221, 190, 222, 28, 221,\n 223, 27, 222, 224, 29, 223, 225, 30, 224, 113, 247, 225, 99, 60, 240, 213, 147, 215, 60, 20, 166, 192, 187, 213, 243, 112, 244, 244, 233, 245, 245,\n 128, 188, 188, 114, 174, 134, 131, 220, 174, 217, 236, 236, 198, 134, 215, 177, 58, 156, 143, 124, 25, 110, 7, 31, 228, 25, 264, 356, 368, 0, 11, 267,\n 451, 452, 349, 267, 302, 269, 350, 357, 277, 350, 452, 357, 299, 333, 297, 396, 175, 377, 381, 384, 382, 280, 347, 330, 269, 303, 270, 151, 9, 337,\n 344, 278, 360, 424, 418, 431, 270, 304, 409, 272, 310, 407, 322, 270, 410, 449, 450, 347, 432, 422, 434, 18, 313, 17, 291, 306, 375, 259, 387, 260,\n 424, 335, 418, 434, 364, 416, 391, 423, 327, 301, 251, 298, 275, 281, 4, 254, 373, 253, 375, 307, 321, 280, 425, 411, 200, 421, 18, 335, 321, 406,\n 321, 320, 405, 314, 315, 17, 423, 426, 266, 396, 377, 369, 270, 322, 269, 413, 417, 464, 385, 386, 258, 248, 456, 419, 298, 284, 333, 168, 417, 8,\n 448, 346, 261, 417, 413, 285, 326, 327, 328, 277, 355, 329, 309, 392, 438, 381, 382, 256, 279, 429, 360, 365, 364, 379, 355, 277, 437, 282, 443, 283,\n 281, 275, 363, 395, 431, 369, 299, 297, 337, 335, 273, 321, 348, 450, 349, 359, 446, 467, 283, 293, 282, 250, 458, 462, 300, 276, 383, 292, 308, 325,\n 283, 276, 293, 264, 372, 447, 346, 352, 340, 354, 274, 19, 363, 456, 281, 426, 436, 425, 380, 381, 252, 267, 269, 393, 421, 200, 428, 371, 266, 329,\n 432, 287, 422, 290, 250, 328, 385, 258, 384, 446, 265, 342, 386, 387, 257, 422, 424, 430, 445, 342, 276, 422, 273, 424, 306, 292, 307, 352, 366, 345,\n 268, 271, 302, 358, 423, 371, 327, 294, 460, 331, 279, 294, 303, 271, 304, 436, 432, 427, 304, 272, 408, 395, 394, 431, 378, 395, 400, 296, 334, 299,\n 6, 351, 168, 376, 352, 411, 307, 325, 320, 285, 295, 336, 320, 319, 404, 329, 330, 349, 334, 293, 333, 366, 323, 447, 316, 15, 315, 331, 358, 279,\n 317, 14, 316, 8, 285, 9, 277, 329, 350, 253, 374, 252, 319, 318, 403, 351, 6, 419, 324, 318, 325, 397, 367, 365, 288, 435, 397, 278, 344, 439, 310,\n 272, 311, 248, 195, 281, 375, 273, 291, 175, 396, 199, 312, 311, 268, 276, 283, 445, 390, 373, 339, 295, 282, 296, 448, 449, 346, 356, 264, 454, 337,\n 336, 299, 337, 338, 151, 294, 278, 455, 308, 292, 415, 429, 358, 355, 265, 340, 372, 388, 390, 466, 352, 346, 280, 295, 442, 282, 354, 19, 370, 285,\n 441, 295, 195, 248, 197, 457, 440, 274, 301, 300, 368, 417, 351, 465, 251, 301, 389, 385, 380, 386, 394, 395, 379, 399, 412, 419, 410, 436, 322, 387,\n 373, 388, 326, 2, 393, 354, 370, 461, 393, 164, 267, 268, 302, 12, 386, 374, 387, 312, 268, 13, 298, 293, 301, 265, 446, 340, 380, 385, 381, 280, 330,\n 425, 322, 426, 391, 420, 429, 437, 393, 391, 326, 344, 440, 438, 458, 459, 461, 364, 434, 394, 428, 396, 262, 274, 354, 457, 317, 316, 402, 316, 315,\n 403, 315, 314, 404, 314, 313, 405, 313, 421, 406, 323, 366, 361, 292, 306, 407, 306, 291, 408, 291, 287, 409, 287, 432, 410, 427, 434, 411, 372, 264,\n 383, 459, 309, 457, 366, 352, 401, 1, 274, 4, 418, 421, 262, 331, 294, 358, 435, 433, 367, 392, 289, 439, 328, 462, 326, 94, 2, 370, 289, 305, 455, 339,\n 254, 448, 359, 255, 446, 254, 253, 449, 253, 252, 450, 252, 256, 451, 256, 341, 452, 414, 413, 463, 286, 441, 414, 286, 258, 441, 258, 257, 442, 257,\n 259, 443, 259, 260, 444, 260, 467, 445, 309, 459, 250, 305, 289, 290, 305, 290, 460, 401, 376, 435, 309, 250, 392, 376, 411, 433, 453, 341, 464, 357,\n 453, 465, 343, 357, 412, 437, 343, 399, 344, 360, 440, 420, 437, 456, 360, 420, 363, 361, 401, 288, 265, 372, 353, 390, 339, 249, 339, 448, 255];\n\nexport const TRI68: Array = [0, 1, 36, 0, 36, 17, 1, 2, 41, 1, 41, 36, 2, 3, 31, 2, 31, 41, 3, 4, 48, 3, 48, 31, 4, 5, 48, 5, 6, 48, 6, 7, 59, 6, 59, 48, 7, 8, 58, 7, 58, 59,\n 8, 9, 56, 8, 56, 57, 8, 57, 58, 9, 10, 55, 9, 55, 56, 10, 11, 54, 10, 54, 55, 11, 12, 54, 12, 13, 54, 13, 14, 35, 13, 35, 54, 14, 15, 46, 14, 46, 35, 15, 16,\n 45, 15, 45, 46, 16, 26, 45, 17, 36, 18, 18, 37, 19, 18, 36, 37, 19, 38, 20, 19, 37, 38, 20, 39, 21, 20, 38, 39, 21, 39, 27, 22, 42, 23, 22, 27, 42, 23, 43, 24,\n 23, 42, 43, 24, 44, 25, 24, 43, 44, 25, 45, 26, 25, 44, 45, 27, 39, 28, 27, 28, 42, 28, 39, 29, 28, 29, 42, 29, 31, 30, 29, 30, 35, 29, 40, 31, 29, 35, 47, 29,\n 39, 40, 29, 47, 42, 30, 31, 32, 30, 32, 33, 30, 33, 34, 30, 34, 35, 31, 50, 32, 31, 40, 41, 31, 48, 49, 31, 49, 50, 32, 51, 33, 32, 50, 51, 33, 51, 34, 34, 52,\n 35, 34, 51, 52, 35, 46, 47, 35, 52, 53, 35, 53, 54, 36, 41, 37, 37, 40, 38, 37, 41, 40, 38, 40, 39, 42, 47, 43, 43, 47, 44, 44, 46, 45, 44, 47, 46, 48, 60, 49,\n 48, 59, 60, 49, 61, 50, 49, 60, 61, 50, 62, 51, 50, 61, 62, 51, 62, 52, 52, 63, 53, 52, 62, 63, 53, 64, 54, 53, 63, 64, 54, 64, 55, 55, 65, 56, 55, 64, 65, 56,\n 66, 57, 56, 65, 66, 57, 66, 58, 58, 67, 59, 58, 66, 67, 59, 67, 60, 60, 67, 61, 61, 66, 62, 61, 67, 66, 62, 66, 63, 63, 65, 64, 63, 66, 65, 21, 27, 22];\n\nexport const TRI33: Array = [\n /* eyes */ 0, 8, 7, 7, 8, 1, 2, 10, 9, 9, 10, 3,\n /* brows */ 17, 0, 18, 18, 0, 7, 18, 7, 19, 19, 7, 1, 19, 1, 11, 19, 11, 20, 21, 3, 22, 21, 9, 3, 20, 9, 21, 20, 2, 9, 20, 11, 2,\n /* 4head */ 23, 17, 18, 25, 21, 22, 24, 19, 20, 24, 18, 19, 24, 20, 21, 24, 23, 18, 24, 21, 25,\n /* nose */ 11, 12, 4, 11, 4, 13, 1, 12, 11, 11, 13, 2, 12, 14, 4, 4, 14, 13,\n /* up-lip */ 14, 5, 15, 14, 15, 6, 12, 5, 14, 14, 6, 13,\n /* cheeks */ 8, 12, 1, 2, 13, 10, 8, 26, 12, 10, 13, 27, 26, 5, 12, 13, 6, 27, 0, 26, 8, 10, 27, 3,\n /* chin */ 5, 32, 16, 16, 32, 6, 5, 30, 32, 6, 32, 31,\n /* cont */ 26, 30, 5, 27, 6, 31, 0, 28, 26, 3, 27, 29, 17, 28, 0, 3, 29, 22, 23, 28, 17, 22, 29, 25, 28, 30, 26, 27, 31, 29,\n];\n\nexport const TRI7: Array = [0, 4, 1, 2, 4, 3, 4, 5, 6];\n\nexport const VTX68: Array = [\n /* cont */ 127, 234, 132, 58, 172, 150, 149, 148, 152, 377, 378, 379, 397, 288, 361, 454, 356,\n /* brows */ 70, 63, 105, 66, 107, 336, 296, 334, 293, 300,\n /* nose */ 168, 6, 195, 4, 98, 97, 2, 326, 327,\n /* eyes */ 33, 160, 158, 133, 153, 144, 362, 385, 387, 263, 373, 380,\n /* lip */ 57, 40, 37, 0, 267, 270, 287, 321, 314, 17, 84, 91,\n /* mouth */ 78, 81, 13, 311, 308, 402, 14, 178,\n];\n\nexport const VTX33: Array = [33, 133, 362, 263, 1, 62, 308, 159, 145, 386, 374, 6, 102, 331, 2, 13, 14, 70, 105, 107, 336, 334, 300, 54, 10, 284, 50, 280, 234, 454, 58, 288, 152];\n\nexport const VTX7: Array = [33, 133, 362, 263, 1, 78, 308];\n\nexport const UV68 = VTX68.map((x) => UV468[x]);\n\nexport const UV33 = VTX33.map((x) => UV468[x]);\n\nexport const UV7 = VTX7.map((x) => UV468[x]);\n", "/**\n * BlazeFace, FaceMesh & Iris model implementation\n * See `facemesh.ts` for entry point\n */\n\nimport * as tf from '../../dist/tfjs.esm.js';\nimport * as coords from './facemeshcoords';\nimport { constants } from '../tfjs/constants';\nimport type { Box, Point } from '../result';\nimport { env } from '../util/env';\n\nexport const createBox = (startEndTensor) => ({ startPoint: tf.slice(startEndTensor, [0, 0], [-1, 2]), endPoint: tf.slice(startEndTensor, [0, 2], [-1, 2]) });\n\nexport const disposeBox = (t) => tf.dispose([t.startPoint, t.endPoint]);\n\nexport const getBoxSize = (box): [number, number] => [Math.abs(box.endPoint[0] - box.startPoint[0]), Math.abs(box.endPoint[1] - box.startPoint[1])];\n\nexport const getBoxCenter = (box): [number, number, number] => [box.startPoint[0] + (box.endPoint[0] - box.startPoint[0]) / 2, box.startPoint[1] + (box.endPoint[1] - box.startPoint[1]) / 2, 1];\n\nexport const clampBox = (box, input): Box => (box ? [\n Math.trunc(Math.max(0, box.startPoint[0])),\n Math.trunc(Math.max(0, box.startPoint[1])),\n Math.trunc(Math.min((input.shape[2] || 0), box.endPoint[0]) - Math.max(0, box.startPoint[0])),\n Math.trunc(Math.min((input.shape[1] || 0), box.endPoint[1]) - Math.max(0, box.startPoint[1])),\n] : [0, 0, 0, 0]);\n\nexport const getRawBox = (box, input): Box => (box ? [\n box.startPoint[0] / (input.shape[2] || 0),\n box.startPoint[1] / (input.shape[1] || 0),\n (box.endPoint[0] - box.startPoint[0]) / (input.shape[2] || 0),\n (box.endPoint[1] - box.startPoint[1]) / (input.shape[1] || 0),\n] : [0, 0, 0, 0]);\n\nexport const scaleBoxCoordinates = (box, factor) => {\n const startPoint: Point = [box.startPoint[0] * factor[0], box.startPoint[1] * factor[1]];\n const endPoint: Point = [box.endPoint[0] * factor[0], box.endPoint[1] * factor[1]];\n return { startPoint, endPoint, landmarks: box.landmarks, confidence: box.confidence };\n};\n\nexport const cutAndResize = (box, image, cropSize) => {\n const h = image.shape[1];\n const w = image.shape[2];\n const cutBox = [box.startPoint[1] / h, box.startPoint[0] / w, box.endPoint[1] / h, box.endPoint[0] / w];\n const crop = tf.image.cropAndResize(image, [cutBox], [0], cropSize);\n const norm = tf.div(crop, constants.tf255);\n tf.dispose(crop);\n return norm;\n};\n\nexport const enlargeBox = (box, factor) => {\n const center = getBoxCenter(box);\n const size = getBoxSize(box);\n const halfSize: [number, number] = [factor * size[0] / 2, factor * size[1] / 2];\n return { startPoint: [center[0] - halfSize[0], center[1] - halfSize[1]] as Point, endPoint: [center[0] + halfSize[0], center[1] + halfSize[1]] as Point, landmarks: box.landmarks, confidence: box.confidence };\n};\n\nexport const squarifyBox = (box) => {\n const centers = getBoxCenter(box);\n const size = getBoxSize(box);\n const halfSize = Math.max(...size) / 2;\n return { startPoint: [Math.round(centers[0] - halfSize), Math.round(centers[1] - halfSize)] as Point, endPoint: [Math.round(centers[0] + halfSize), Math.round(centers[1] + halfSize)] as Point, landmarks: box.landmarks, confidence: box.confidence };\n};\n\nexport const calculateLandmarksBoundingBox = (landmarks) => {\n const x = landmarks.map((d) => d[0]);\n const y = landmarks.map((d) => d[1]);\n return { startPoint: [Math.min(...x), Math.min(...y)] as Point, endPoint: [Math.max(...x), Math.max(...y)] as Point, landmarks };\n};\n\nexport const fixedRotationMatrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];\n\nexport const normalizeRadians = (angle) => angle - 2 * Math.PI * Math.floor((angle + Math.PI) / (2 * Math.PI));\n\nexport const computeRotation = (point1, point2) => normalizeRadians(Math.PI / 2 - Math.atan2(-(point2[1] - point1[1]), point2[0] - point1[0]));\n\nexport const radToDegrees = (rad) => rad * 180 / Math.PI;\n\nexport const buildTranslationMatrix = (x, y) => [[1, 0, x], [0, 1, y], [0, 0, 1]];\n\nexport const dot = (v1: number[], v2: number[]) => {\n let product = 0;\n for (let i = 0; i < v1.length; i++) product += v1[i] * v2[i];\n return product;\n};\n\nexport const getColumnFrom2DArr = (arr, columnIndex) => {\n const column: Array = [];\n for (let i = 0; i < arr.length; i++) column.push(arr[i][columnIndex]);\n return column;\n};\n\nexport const multiplyTransformMatrices = (mat1, mat2) => {\n const product: Array = [];\n const size = mat1.length;\n for (let row = 0; row < size; row++) {\n product.push([]);\n for (let col = 0; col < size; col++) product[row].push(dot(mat1[row], getColumnFrom2DArr(mat2, col)));\n }\n return product;\n};\n\nexport const buildRotationMatrix = (rotation, center) => {\n const cosA = Math.cos(rotation);\n const sinA = Math.sin(rotation);\n const rotationMatrix = [[cosA, -sinA, 0], [sinA, cosA, 0], [0, 0, 1]];\n const translationMatrix = buildTranslationMatrix(center[0], center[1]);\n const translationTimesRotation = multiplyTransformMatrices(translationMatrix, rotationMatrix);\n const negativeTranslationMatrix = buildTranslationMatrix(-center[0], -center[1]);\n return multiplyTransformMatrices(translationTimesRotation, negativeTranslationMatrix);\n};\n\nexport const invertTransformMatrix = (matrix) => {\n const rotationComponent = [[matrix[0][0], matrix[1][0]], [matrix[0][1], matrix[1][1]]];\n const translationComponent = [matrix[0][2], matrix[1][2]];\n const invertedTranslation = [-dot(rotationComponent[0], translationComponent), -dot(rotationComponent[1], translationComponent)];\n return [rotationComponent[0].concat(invertedTranslation[0]), rotationComponent[1].concat(invertedTranslation[1]), [0, 0, 1]];\n};\n\nexport const rotatePoint = (homogeneousCoordinate, rotationMatrix) => [dot(homogeneousCoordinate, rotationMatrix[0]), dot(homogeneousCoordinate, rotationMatrix[1])];\n\nexport const xyDistanceBetweenPoints = (a, b) => Math.sqrt(((a[0] - b[0]) ** 2) + ((a[1] - b[1]) ** 2));\n\nexport function generateAnchors(inputSize) {\n const spec = { strides: [inputSize / 16, inputSize / 8], anchors: [2, 6] };\n const anchors: Array<[number, number]> = [];\n for (let i = 0; i < spec.strides.length; i++) {\n const stride = spec.strides[i];\n const gridRows = Math.floor((inputSize + stride - 1) / stride);\n const gridCols = Math.floor((inputSize + stride - 1) / stride);\n const anchorsNum = spec.anchors[i];\n for (let gridY = 0; gridY < gridRows; gridY++) {\n const anchorY = stride * (gridY + 0.5);\n for (let gridX = 0; gridX < gridCols; gridX++) {\n const anchorX = stride * (gridX + 0.5);\n for (let n = 0; n < anchorsNum; n++) anchors.push([anchorX, anchorY]);\n }\n }\n }\n return anchors;\n}\n\nexport function transformRawCoords(coordsRaw, box, angle, rotationMatrix, inputSize) {\n const boxSize = getBoxSize(box);\n const coordsScaled = coordsRaw.map((coord) => ([ // scaled around zero-point\n (boxSize[0] / inputSize) * (coord[0] - (inputSize / 2)),\n (boxSize[1] / inputSize) * (coord[1] - (inputSize / 2)),\n (coord[2] || 0),\n ]));\n const largeAngle = angle && (angle !== 0) && (Math.abs(angle) > 0.2);\n const coordsRotationMatrix = largeAngle ? buildRotationMatrix(angle, [0, 0]) : fixedRotationMatrix;\n const coordsRotated = largeAngle ? coordsScaled.map((coord) => ([...rotatePoint(coord, coordsRotationMatrix), coord[2]])) : coordsScaled;\n const inverseRotationMatrix = largeAngle ? invertTransformMatrix(rotationMatrix) : fixedRotationMatrix;\n const boxCenter = getBoxCenter(box);\n const offsets = [dot(boxCenter, inverseRotationMatrix[0]), dot(boxCenter, inverseRotationMatrix[1])];\n return coordsRotated.map((coord) => ([\n Math.trunc(coord[0] + offsets[0]),\n Math.trunc(coord[1] + offsets[1]),\n Math.trunc(coord[2] || 0),\n ]));\n}\n\nexport function correctFaceRotation(rotate, box, input, inputSize) {\n const symmetryLine = (box.landmarks.length >= coords.meshLandmarks.count)\n ? coords.meshLandmarks.symmetryLine\n : coords.blazeFaceLandmarks.symmetryLine;\n let angle = 0; // default\n let rotationMatrix = fixedRotationMatrix; // default\n let face; // default\n\n if (rotate && env.kernels.includes('rotatewithoffset')) { // rotateWithOffset is not defined for tfjs-node\n angle = computeRotation(box.landmarks[symmetryLine[0]], box.landmarks[symmetryLine[1]]);\n const largeAngle = angle && (angle !== 0) && (Math.abs(angle) > 0.2);\n if (largeAngle) { // perform rotation only if angle is sufficiently high\n const center: Point = getBoxCenter(box);\n const centerRaw: Point = [center[0] / input.shape[2], center[1] / input.shape[1]];\n const rotated = tf.image.rotateWithOffset(input, angle, 0, centerRaw);\n rotationMatrix = buildRotationMatrix(-angle, center);\n face = cutAndResize(box, rotated, [inputSize, inputSize]);\n tf.dispose(rotated);\n } else {\n face = cutAndResize(box, input, [inputSize, inputSize]);\n }\n } else {\n face = cutAndResize(box, input, [inputSize, inputSize]);\n }\n return [angle, rotationMatrix, face];\n}\n\nexport const findFaceCenter = (mesh) => {\n const x = mesh.map((m) => m[0]);\n const y = mesh.map((m) => m[1]);\n // weighted center\n /*\n const sum = (arr: number[]) => arr.reduce((prev, curr) => prev + curr, 0);\n return [sum(x) / mesh.length, sum(y) / mesh.length];\n */\n // absolute center\n return [Math.min(...x) + (Math.max(...x) - Math.min(...x)) / 2, Math.min(...y) + (Math.max(...y) - Math.min(...y)) / 2];\n};\n\nexport const calculateFaceBox = (mesh, previousBox) => {\n const center = findFaceCenter(mesh);\n const boxSize = getBoxSize(previousBox);\n const calculatedBox = {\n startPoint: [center[0] - boxSize[0] / 2, center[1] - boxSize[1] / 2] as Point,\n endPoint: [center[0] + boxSize[0] / 2, center[1] + boxSize[1] / 2] as Point,\n };\n return calculatedBox;\n};\n", "/**\n * BlazeFace, FaceMesh & Iris model implementation\n * See `facemesh.ts` for entry point\n */\n\nimport { log } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport * as util from './facemeshutil';\nimport { loadModel } from '../tfjs/load';\nimport { constants } from '../tfjs/constants';\nimport type { Config } from '../config';\nimport type { Tensor, GraphModel } from '../tfjs/types';\nimport { env } from '../util/env';\nimport type { Point } from '../result';\n\nconst keypointsCount = 6;\nconst faceBoxScaleFactor = 1.4;\nlet model: GraphModel | null;\nlet anchors: Tensor | null = null;\nlet inputSize = 0;\nlet inputSizeT: Tensor | null = null;\n\ntype DetectBox = { startPoint: Point, endPoint: Point, landmarks: Array, confidence: number };\n\nexport const size = () => inputSize;\n\nexport async function load(config: Config): Promise {\n if (env.initial) model = null;\n if (!model) model = await loadModel(config.face.detector?.modelPath);\n else if (config.debug) log('cached model:', model['modelUrl']);\n inputSize = model.inputs[0].shape ? model.inputs[0].shape[2] : 0;\n inputSizeT = tf.scalar(inputSize, 'int32') as Tensor;\n anchors = tf.tensor2d(util.generateAnchors(inputSize)) as Tensor;\n return model;\n}\n\nfunction decodeBounds(boxOutputs: Tensor) {\n const t: Record = {};\n t.boxStarts = tf.slice(boxOutputs, [0, 1], [-1, 2]);\n t.centers = tf.add(t.boxStarts, anchors);\n t.boxSizes = tf.slice(boxOutputs, [0, 3], [-1, 2]);\n t.boxSizesNormalized = tf.div(t.boxSizes, inputSizeT);\n t.centersNormalized = tf.div(t.centers, inputSizeT);\n t.halfBoxSize = tf.div(t.boxSizesNormalized, constants.tf2);\n t.starts = tf.sub(t.centersNormalized, t.halfBoxSize);\n t.ends = tf.add(t.centersNormalized, t.halfBoxSize);\n t.startNormalized = tf.mul(t.starts, inputSizeT);\n t.endNormalized = tf.mul(t.ends, inputSizeT);\n const boxes = tf.concat2d([t.startNormalized, t.endNormalized], 1);\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n return boxes;\n}\n\nexport async function getBoxes(inputImage: Tensor, config: Config) {\n // sanity check on input\n if ((!inputImage) || (inputImage['isDisposedInternal']) || (inputImage.shape.length !== 4) || (inputImage.shape[1] < 1) || (inputImage.shape[2] < 1)) return [];\n const t: Record = {};\n t.resized = tf.image.resizeBilinear(inputImage, [inputSize, inputSize]);\n t.div = tf.div(t.resized, constants.tf127);\n t.normalized = tf.sub(t.div, constants.tf05);\n const res = model?.execute(t.normalized) as Tensor[];\n if (Array.isArray(res)) { // are we using tfhub or pinto converted model?\n const sorted = res.sort((a, b) => a.size - b.size);\n t.concat384 = tf.concat([sorted[0], sorted[2]], 2); // dim: 384, 1 + 16\n t.concat512 = tf.concat([sorted[1], sorted[3]], 2); // dim: 512, 1 + 16\n t.concat = tf.concat([t.concat512, t.concat384], 1);\n t.batch = tf.squeeze(t.concat, 0);\n } else {\n t.batch = tf.squeeze(res); // when using tfhub model\n }\n tf.dispose(res);\n t.boxes = decodeBounds(t.batch);\n t.logits = tf.slice(t.batch, [0, 0], [-1, 1]);\n t.sigmoid = tf.sigmoid(t.logits);\n t.scores = tf.squeeze(t.sigmoid);\n t.nms = await tf.image.nonMaxSuppressionAsync(t.boxes, t.scores, (config.face.detector?.maxDetected || 0), (config.face.detector?.iouThreshold || 0), (config.face.detector?.minConfidence || 0));\n const nms = await t.nms.array() as number[];\n const boxes: Array = [];\n const scores = await t.scores.data();\n for (let i = 0; i < nms.length; i++) {\n const confidence = scores[nms[i]];\n if (confidence > (config.face.detector?.minConfidence || 0)) {\n const b: Record = {};\n b.bbox = tf.slice(t.boxes, [nms[i], 0], [1, -1]);\n b.slice = tf.slice(t.batch, [nms[i], keypointsCount - 1], [1, -1]);\n b.squeeze = tf.squeeze(b.slice);\n b.landmarks = tf.reshape(b.squeeze, [keypointsCount, -1]);\n const points = await b.bbox.data();\n const rawBox = {\n startPoint: [points[0], points[1]] as Point,\n endPoint: [points[2], points[3]] as Point,\n landmarks: (await b.landmarks.array()) as Point[],\n confidence,\n };\n const scaledBox = util.scaleBoxCoordinates(rawBox, [(inputImage.shape[2] || 0) / inputSize, (inputImage.shape[1] || 0) / inputSize]);\n const enlargedBox = util.enlargeBox(scaledBox, config.face['scale'] || faceBoxScaleFactor);\n const squaredBox = util.squarifyBox(enlargedBox);\n boxes.push(squaredBox);\n Object.keys(b).forEach((tensor) => tf.dispose(b[tensor]));\n }\n }\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n return boxes;\n}\n", "/* eslint-disable no-multi-spaces */\n\nexport const kpt: Array = [\n 'nose', // 0\n 'leftEyeInside', // 1\n 'leftEye', // 2\n 'leftEyeOutside', // 3\n 'rightEyeInside', // 4\n 'rightEye', // 5\n 'rightEyeOutside', // 6\n 'leftEar', // 7\n 'rightEar', // 8\n 'leftMouth', // 9\n 'rightMouth', // 10\n 'leftShoulder', // 11\n 'rightShoulder', // 12\n 'leftElbow', // 13\n 'rightElbow', // 14\n 'leftWrist', // 15\n 'rightWrist', // 16\n 'leftPinky', // 17\n 'rightPinky', // 18\n 'leftIndex', // 19\n 'rightIndex', // 20\n 'leftThumb', // 21\n 'rightThumb', // 22\n 'leftHip', // 23\n 'rightHip', // 24\n 'leftKnee', // 25\n 'rightKnee', // 26\n 'leftAnkle', // 27\n 'rightAnkle', // 28\n 'leftHeel', // 29\n 'rightHeel', // 30\n 'leftFoot', // 31\n 'rightFoot', // 32\n 'bodyCenter', // 33\n 'bodyTop', // 34\n 'leftPalm', // 35 // z-coord not ok\n 'leftHand', // 36 // similar to wrist but z-coord not ok\n 'rightPalm', // 37 // z-coord not ok\n 'rightHand', // 38 // similar to wrist but z-coord not ok\n];\n\nexport const connected: Record = {\n shoulders: ['leftShoulder', 'rightShoulder'],\n hips: ['rightHip', 'leftHip'],\n mouth: ['leftMouth', 'rightMouth'],\n leftLegUpper: ['leftHip', 'leftKnee'],\n leftLegLower: ['leftKnee', 'leftAnkle'],\n leftFoot: ['leftAnkle', 'leftHeel', 'leftFoot'],\n leftTorso: ['leftShoulder', 'leftHip'],\n leftArmUpper: ['leftShoulder', 'leftElbow'],\n leftArmLower: ['leftElbow', 'leftWrist'],\n leftHand: ['leftWrist', 'leftPalm'],\n leftHandPinky: ['leftPalm', 'leftPinky'],\n leftHandIndex: ['leftPalm', 'leftIndex'],\n leftHandThumb: ['leftPalm', 'leftThumb'],\n leftEyeOutline: ['leftEyeInside', 'leftEyeOutside'],\n rightLegUpper: ['rightHip', 'rightKnee'],\n rightLegLower: ['rightKnee', 'rightAnkle'],\n rightFoot: ['rightAnkle', 'rightHeel', 'rightFoot'],\n rightTorso: ['rightShoulder', 'rightHip'],\n rightArmUpper: ['rightShoulder', 'rightElbow'],\n rightArmLower: ['rightElbow', 'rightWrist'],\n rightHand: ['rightWrist', 'rightPalm'],\n rightHandPinky: ['rightPalm', 'rightPinky'],\n rightHandIndex: ['rightPalm', 'rightIndex'],\n rightHandThumb: ['rightPalm', 'rightThumb'],\n rightEyeOutline: ['rightEyeInside', 'rightEyeOutside'],\n};\n", "import * as tf from '../../dist/tfjs.esm.js';\nimport type { Tensor } from '../tfjs/types';\nimport type { Box } from '../result';\nimport type { Config } from '../config';\n\ninterface DetectedBox { box: Box, boxRaw: Box, score: number }\n\nconst inputSize = 224;\nlet anchorTensor: { x, y };\nconst numLayers = 5;\nconst strides = [8, 16, 32, 32, 32];\n\nexport async function createAnchors() {\n const anchors: Array<{ x: number, y: number }> = [];\n let layerId = 0;\n while (layerId < numLayers) {\n let anchorCount = 0;\n let lastSameStrideLayer = layerId;\n while (lastSameStrideLayer < strides.length && strides[lastSameStrideLayer] === strides[layerId]) {\n anchorCount += 2;\n lastSameStrideLayer++;\n }\n const stride = strides[layerId];\n const featureMapHeight = Math.ceil(inputSize / stride);\n const featureMapWidth = Math.ceil(inputSize / stride);\n for (let y = 0; y < featureMapHeight; ++y) {\n for (let x = 0; x < featureMapWidth; ++x) {\n for (let anchorId = 0; anchorId < anchorCount; ++anchorId) {\n anchors.push({ x: (x + 0.5) / featureMapWidth, y: (y + 0.5) / featureMapHeight });\n }\n }\n }\n layerId = lastSameStrideLayer;\n }\n anchorTensor = { x: tf.tensor1d(anchors.map((a) => a.x)), y: tf.tensor1d(anchors.map((a) => a.y)) };\n}\n\nconst cropFactor = [5.0, 5.0];\nfunction decodeBoxes(boxesTensor, anchor): Tensor {\n return tf.tidy(() => {\n const split = tf.split(boxesTensor, 12, 1); // first 4 are box data [x,y,w,h] and 4 are keypoints data [x,y] for total of 12\n let xCenter = tf.squeeze(split[0]);\n let yCenter = tf.squeeze(split[1]);\n let width = tf.squeeze(split[2]);\n let height = tf.squeeze(split[3]);\n xCenter = tf.add(tf.div(xCenter, inputSize), anchor.x);\n yCenter = tf.add(tf.div(yCenter, inputSize), anchor.y);\n width = tf.mul(tf.div(width, inputSize), cropFactor[0]);\n height = tf.mul(tf.div(height, inputSize), cropFactor[1]);\n const xMin = tf.sub(xCenter, tf.div(width, 2));\n const yMin = tf.sub(yCenter, tf.div(height, 2));\n const boxes = tf.stack([xMin, yMin, width, height], 1);\n return boxes;\n });\n}\n\nexport async function decode(boxesTensor: Tensor, logitsTensor: Tensor, config: Config, outputSize: [number, number]): Promise {\n const t: Record = {};\n t.boxes = decodeBoxes(boxesTensor, anchorTensor);\n t.scores = tf.sigmoid(logitsTensor);\n t.argmax = tf.argMax(t.scores);\n const i = (await t.argmax.data())[0] as number;\n const scores = await t.scores.data();\n const detected: Array<{ box: Box, boxRaw: Box, score: number }> = [];\n const minScore = (config.body['detector'] && config.body['detector']['minConfidence']) ? config.body['detector']['minConfidence'] : 0;\n if (scores[i] >= minScore) {\n const boxes = await t.boxes.array();\n const boxRaw: Box = boxes[i];\n const box: Box = [boxRaw[0] * outputSize[0], boxRaw[1] * outputSize[1], boxRaw[2] * outputSize[0], boxRaw[3] * outputSize[1]];\n // console.log(box);\n detected.push({ box, boxRaw, score: scores[i] });\n }\n /*\n t.nms = await tf.image.nonMaxSuppressionAsync(t.boxes, t.scores, 1, config.body.detector?.minConfidence || 0.1, config.body.detector?.iouThreshold || 0.1);\n const boxes = t.boxes.arraySync();\n const scores = t.scores.dataSync();\n const nms = t.nms.dataSync();\n const detected: Array = [];\n for (const i of Array.from(nms)) {\n const boxRaw: Box = boxes[i];\n const box: Box = [boxRaw[0] * outputSize[0], boxRaw[0] * outputSize[1], boxRaw[3] * outputSize[0], boxRaw[2] * outputSize[1]];\n detected.push({ box, boxRaw, score: scores[i] });\n }\n */\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n return detected;\n}\n", "import type { Point, Box } from '../result';\n\nexport function calc(keypoints: Array, outputSize: [number, number] = [1, 1]) {\n const coords = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])]; // all x/y coords\n const min = [Math.min(...coords[0]), Math.min(...coords[1])];\n const max = [Math.max(...coords[0]), Math.max(...coords[1])];\n const box: Box = [min[0], min[1], max[0] - min[0], max[1] - min[1]];\n const boxRaw: Box = [box[0] / outputSize[0], box[1] / outputSize[1], box[2] / outputSize[0], box[3] / outputSize[1]];\n return { box, boxRaw };\n}\n\nexport function square(keypoints: Array, outputSize: [number, number] = [1, 1]) {\n const coords = [keypoints.map((pt) => pt[0]), keypoints.map((pt) => pt[1])]; // all x/y coords\n const min = [Math.min(...coords[0]), Math.min(...coords[1])];\n const max = [Math.max(...coords[0]), Math.max(...coords[1])];\n const center = [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2]; // find center x and y coord of all fingers\n const dist = Math.max(center[0] - min[0], center[1] - min[1], -center[0] + max[0], -center[1] + max[1]); // largest distance from center in any direction\n const box: Box = [Math.trunc(center[0] - dist), Math.trunc(center[1] - dist), Math.trunc(2 * dist), Math.trunc(2 * dist)];\n const boxRaw: Box = [box[0] / outputSize[0], box[1] / outputSize[1], box[2] / outputSize[0], box[3] / outputSize[1]];\n return { box, boxRaw };\n}\n\nexport function scale(box: Box, scaleFact: number) {\n const dist = [box[2] * scaleFact, box[3] * scaleFact];\n const newBox: Box = [\n box[0] - (dist[0] - box[2]) / 2,\n box[1] - (dist[1] - box[3]) / 2,\n dist[0],\n dist[1],\n ];\n return newBox;\n}\n\nexport function crop(box: Box) { // [y1, x1, y2, x2] clamped to 0..1\n const yxBox: Box = [Math.max(0, box[1]), Math.max(0, box[0]), Math.min(1, box[3] + box[1]), Math.min(1, box[2] + box[0])];\n return yxBox;\n}\n", "/**\n * BlazePose model implementation\n */\n\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport { constants } from '../tfjs/constants';\nimport { log, now } from '../util/util';\nimport type { BodyKeypoint, BodyResult, BodyLandmark, Box, Point, BodyAnnotation } from '../result';\nimport type { GraphModel, Tensor } from '../tfjs/types';\nimport type { Config } from '../config';\nimport * as coords from './blazeposecoords';\nimport * as detect from './blazeposedetector';\nimport * as box from '../util/box';\n\nconst env = { initial: true };\n// const models: [GraphModel | null, GraphModel | null] = [null, null];\nconst models: { detector: GraphModel | null, landmarks: GraphModel | null } = { detector: null, landmarks: null };\nconst inputSize: { detector: [number, number], landmarks: [number, number] } = { detector: [224, 224], landmarks: [256, 256] };\nlet skipped = Number.MAX_SAFE_INTEGER;\nconst outputNodes: { detector: string[], landmarks: string[] } = {\n landmarks: ['ld_3d', 'activation_segmentation', 'activation_heatmap', 'world_3d', 'output_poseflag'],\n detector: [],\n};\n\nlet cache: BodyResult | null = null;\nlet cropBox: Box | undefined;\nlet padding: [number, number][] = [[0, 0], [0, 0], [0, 0], [0, 0]];\nlet lastTime = 0;\n\nconst sigmoid = (x) => (1 - (1 / (1 + Math.exp(x))));\n\nexport async function loadDetect(config: Config): Promise {\n if (env.initial) models.detector = null;\n if (!models.detector && config.body['detector'] && config.body['detector']['modelPath'] || '') {\n models.detector = await loadModel(config.body['detector']['modelPath']);\n const inputs = Object.values(models.detector.modelSignature['inputs']);\n inputSize.detector[0] = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[1].size) : 0;\n inputSize.detector[1] = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[2].size) : 0;\n } else if (config.debug && models.detector) log('cached model:', models.detector['modelUrl']);\n await detect.createAnchors();\n return models.detector as GraphModel;\n}\n\nexport async function loadPose(config: Config): Promise {\n if (env.initial) models.landmarks = null;\n if (!models.landmarks) {\n models.landmarks = await loadModel(config.body.modelPath);\n const inputs = Object.values(models.landmarks.modelSignature['inputs']);\n inputSize.landmarks[0] = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[1].size) : 0;\n inputSize.landmarks[1] = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[2].size) : 0;\n } else if (config.debug) log('cached model:', models.landmarks['modelUrl']);\n return models.landmarks;\n}\n\nexport async function load(config: Config): Promise<[GraphModel | null, GraphModel | null]> {\n if (!models.detector) await loadDetect(config);\n if (!models.landmarks) await loadPose(config);\n return [models.detector, models.landmarks];\n}\n\nasync function prepareImage(input: Tensor, size: number): Promise {\n const t: Record = {};\n if (!input.shape || !input.shape[1] || !input.shape[2]) return input;\n let final: Tensor;\n if (cropBox) {\n t.cropped = tf.image.cropAndResize(input, [cropBox], [0], [input.shape[1], input.shape[2]]); // if we have cached box use it to crop input\n }\n if (input.shape[1] !== input.shape[2]) { // only pad if width different than height\n const height: [number, number] = [\n input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,\n input.shape[2] > input.shape[1] ? Math.trunc((input.shape[2] - input.shape[1]) / 2) : 0,\n ];\n const width: [number, number] = [\n input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,\n input.shape[1] > input.shape[2] ? Math.trunc((input.shape[1] - input.shape[2]) / 2) : 0,\n ];\n padding = [\n [0, 0], // dont touch batch\n height, // height before&after\n width, // width before&after\n [0, 0], // dont touch rbg\n ];\n t.pad = tf.pad(t.cropped || input, padding); // use cropped box if it exists\n t.resize = tf.image.resizeBilinear(t.pad, [size, size]);\n final = tf.div(t.resize, constants.tf255);\n } else if (input.shape[1] !== size) { // if input needs resizing\n t.resize = tf.image.resizeBilinear(t.cropped || input, [size, size]);\n final = tf.div(t.resize, constants.tf255);\n } else { // if input is already in a correct resolution just normalize it\n final = tf.div(t.cropped || input, constants.tf255);\n }\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n return final;\n}\n\nfunction rescaleKeypoints(keypoints: Array, outputSize: [number, number]): Array {\n for (const kpt of keypoints) { // first rescale due to padding\n kpt.position = [\n Math.trunc(kpt.position[0] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0] - padding[2][0]),\n Math.trunc(kpt.position[1] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1] - padding[1][0]),\n kpt.position[2] as number,\n ];\n kpt.positionRaw = [kpt.position[0] / outputSize[0], kpt.position[1] / outputSize[1], 2 * (kpt.position[2] as number) / (outputSize[0] + outputSize[1])];\n }\n if (cropBox) { // second rescale due to cropping\n for (const kpt of keypoints) {\n kpt.positionRaw = [\n kpt.positionRaw[0] + cropBox[1], // correct offset due to crop\n kpt.positionRaw[1] + cropBox[0], // correct offset due to crop\n kpt.positionRaw[2] as number,\n ];\n kpt.position = [\n Math.trunc(kpt.positionRaw[0] * outputSize[0]),\n Math.trunc(kpt.positionRaw[1] * outputSize[1]),\n kpt.positionRaw[2] as number,\n ];\n }\n }\n return keypoints;\n}\n\nasync function fixKeypoints(keypoints: Array) {\n // palm z-coord is incorrect around near-zero so we approximate it\n const leftPalm = keypoints.find((k) => k.part === 'leftPalm') as BodyKeypoint;\n const leftWrist = keypoints.find((k) => k.part === 'leftWrist') as BodyKeypoint;\n const leftIndex = keypoints.find((k) => k.part === 'leftIndex') as BodyKeypoint;\n leftPalm.position[2] = ((leftWrist.position[2] || 0) + (leftIndex.position[2] || 0)) / 2;\n const rightPalm = keypoints.find((k) => k.part === 'rightPalm') as BodyKeypoint;\n const rightWrist = keypoints.find((k) => k.part === 'rightWrist') as BodyKeypoint;\n const rightIndex = keypoints.find((k) => k.part === 'rightIndex') as BodyKeypoint;\n rightPalm.position[2] = ((rightWrist.position[2] || 0) + (rightIndex.position[2] || 0)) / 2;\n}\n\nasync function detectLandmarks(input: Tensor, config: Config, outputSize: [number, number]): Promise {\n /**\n * t.ld: 39 keypoints [x,y,z,score,presence] normalized to input size\n * t.segmentation:\n * t.heatmap:\n * t.world: 39 keypoints [x,y,z] normalized to -1..1\n * t.poseflag: body score\n */\n const t: Record = {};\n [t.ld/* 1,195(39*5) */, t.segmentation/* 1,256,256,1 */, t.heatmap/* 1,64,64,39 */, t.world/* 1,117(39*3) */, t.poseflag/* 1,1 */] = models.landmarks?.execute(input, outputNodes.landmarks) as Tensor[]; // run model\n const poseScore = (await t.poseflag.data())[0];\n const points = await t.ld.data();\n const distances = await t.world.data();\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor])); // dont need tensors after this\n const keypointsRelative: Array = [];\n const depth = 5; // each points has x,y,z,visibility,presence\n for (let i = 0; i < points.length / depth; i++) {\n const score = sigmoid(points[depth * i + 3]);\n const presence = sigmoid(points[depth * i + 4]);\n const adjScore = Math.trunc(100 * score * presence * poseScore) / 100;\n const positionRaw: Point = [points[depth * i + 0] / inputSize.landmarks[0], points[depth * i + 1] / inputSize.landmarks[1], points[depth * i + 2] + 0];\n const position: Point = [Math.trunc(outputSize[0] * positionRaw[0]), Math.trunc(outputSize[1] * positionRaw[1]), positionRaw[2] as number];\n const distance: Point = [distances[depth * i + 0], distances[depth * i + 1], distances[depth * i + 2] + 0];\n keypointsRelative.push({ part: coords.kpt[i] as BodyLandmark, positionRaw, position, distance, score: adjScore });\n }\n if (poseScore < (config.body.minConfidence || 0)) return null;\n fixKeypoints(keypointsRelative);\n const keypoints: Array = rescaleKeypoints(keypointsRelative, outputSize); // keypoints were relative to input image which is padded\n const kpts = keypoints.map((k) => k.position);\n const boxes = box.calc(kpts, [outputSize[0], outputSize[1]]); // now find boxes based on rescaled keypoints\n const annotations: Record = {} as Record;\n for (const [name, indexes] of Object.entries(coords.connected)) {\n const pt: Array = [];\n for (let i = 0; i < indexes.length - 1; i++) {\n const pt0 = keypoints.find((kpt) => kpt.part === indexes[i]);\n const pt1 = keypoints.find((kpt) => kpt.part === indexes[i + 1]);\n if (pt0 && pt1) pt.push([pt0.position, pt1.position]);\n }\n annotations[name] = pt;\n }\n const body = { id: 0, score: Math.trunc(100 * poseScore) / 100, box: boxes.box, boxRaw: boxes.boxRaw, keypoints, annotations };\n return body;\n}\n\n/*\ninterface DetectedBox { box: Box, boxRaw: Box, score: number }\n\nfunction rescaleBoxes(boxes: Array, outputSize: [number, number]): Array {\n for (const b of boxes) {\n b.box = [\n Math.trunc(b.box[0] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]),\n Math.trunc(b.box[1] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]),\n Math.trunc(b.box[2] * (outputSize[0] + padding[2][0] + padding[2][1]) / outputSize[0]),\n Math.trunc(b.box[3] * (outputSize[1] + padding[1][0] + padding[1][1]) / outputSize[1]),\n ];\n b.boxRaw = [b.box[0] / outputSize[0], b.box[1] / outputSize[1], b.box[2] / outputSize[0], b.box[3] / outputSize[1]];\n }\n return boxes;\n}\n\nasync function detectBoxes(input: Tensor, config: Config, outputSize: [number, number]) {\n const t: Record = {};\n t.res = models.detector?.execute(input, ['Identity']) as Tensor; //\n t.logitsRaw = tf.slice(t.res, [0, 0, 0], [1, -1, 1]);\n t.boxesRaw = tf.slice(t.res, [0, 0, 1], [1, -1, -1]);\n t.logits = tf.squeeze(t.logitsRaw);\n t.boxes = tf.squeeze(t.boxesRaw);\n const boxes = await detect.decode(t.boxes, t.logits, config, outputSize);\n rescaleBoxes(boxes, outputSize);\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n return boxes;\n}\n*/\n\nexport async function predict(input: Tensor, config: Config): Promise {\n const outputSize: [number, number] = [input.shape[2] || 0, input.shape[1] || 0];\n const skipTime = (config.body.skipTime || 0) > (now() - lastTime);\n const skipFrame = skipped < (config.body.skipFrames || 0);\n if (config.skipAllowed && skipTime && skipFrame && cache !== null) {\n skipped++;\n } else {\n const t: Record = {};\n /*\n if (config.body['detector'] && config.body['detector']['enabled']) {\n t.detector = await prepareImage(input, 224);\n const boxes = await detectBoxes(t.detector, config, outputSize);\n }\n */\n t.landmarks = await prepareImage(input, 256); // padded and resized\n cache = await detectLandmarks(t.landmarks, config, outputSize);\n /*\n cropBox = [0, 0, 1, 1]; // reset crop coordinates\n if (cache?.boxRaw && config.skipAllowed) {\n const cx = (2.0 * cache.boxRaw[0] + cache.boxRaw[2]) / 2;\n const cy = (2.0 * cache.boxRaw[1] + cache.boxRaw[3]) / 2;\n let size = cache.boxRaw[2] > cache.boxRaw[3] ? cache.boxRaw[2] : cache.boxRaw[3];\n size = (size * 1.0) / 2; // enlarge and half it\n if (cx > 0.1 && cx < 0.9 && cy > 0.1 && cy < 0.9 && size > 0.1) { // only update if box is sane\n const y = 0; // cy - size;\n const x = cx - size;\n cropBox = [y, x, y + 1, x + 1]; // [y0,x0,y1,x1] used for cropping but width/height are not yet implemented so we only reposition image to center of body\n }\n }\n */\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n lastTime = now();\n skipped = 0;\n }\n return cache ? [cache] : [];\n}\n", "/**\n * CoCo Labels used by object detection implementations\n */\nexport const labels = [\n { class: 1, label: 'person' },\n { class: 2, label: 'bicycle' },\n { class: 3, label: 'car' },\n { class: 4, label: 'motorcycle' },\n { class: 5, label: 'airplane' },\n { class: 6, label: 'bus' },\n { class: 7, label: 'train' },\n { class: 8, label: 'truck' },\n { class: 9, label: 'boat' },\n { class: 10, label: 'traffic light' },\n { class: 11, label: 'fire hydrant' },\n { class: 12, label: 'stop sign' },\n { class: 13, label: 'parking meter' },\n { class: 14, label: 'bench' },\n { class: 15, label: 'bird' },\n { class: 16, label: 'cat' },\n { class: 17, label: 'dog' },\n { class: 18, label: 'horse' },\n { class: 19, label: 'sheep' },\n { class: 20, label: 'cow' },\n { class: 21, label: 'elephant' },\n { class: 22, label: 'bear' },\n { class: 23, label: 'zebra' },\n { class: 24, label: 'giraffe' },\n { class: 25, label: 'backpack' },\n { class: 26, label: 'umbrella' },\n { class: 27, label: 'handbag' },\n { class: 28, label: 'tie' },\n { class: 29, label: 'suitcase' },\n { class: 30, label: 'frisbee' },\n { class: 31, label: 'skis' },\n { class: 32, label: 'snowboard' },\n { class: 33, label: 'sports ball' },\n { class: 34, label: 'kite' },\n { class: 35, label: 'baseball bat' },\n { class: 36, label: 'baseball glove' },\n { class: 37, label: 'skateboard' },\n { class: 38, label: 'surfboard' },\n { class: 39, label: 'tennis racket' },\n { class: 40, label: 'bottle' },\n { class: 41, label: 'wine glass' },\n { class: 42, label: 'cup' },\n { class: 43, label: 'fork' },\n { class: 44, label: 'knife' },\n { class: 45, label: 'spoon' },\n { class: 46, label: 'bowl' },\n { class: 47, label: 'banana' },\n { class: 48, label: 'apple' },\n { class: 49, label: 'sandwich' },\n { class: 50, label: 'orange' },\n { class: 51, label: 'broccoli' },\n { class: 52, label: 'carrot' },\n { class: 53, label: 'hot dog' },\n { class: 54, label: 'pizza' },\n { class: 55, label: 'donut' },\n { class: 56, label: 'cake' },\n { class: 57, label: 'chair' },\n { class: 58, label: 'couch' },\n { class: 59, label: 'potted plant' },\n { class: 60, label: 'bed' },\n { class: 61, label: 'dining table' },\n { class: 62, label: 'toilet' },\n { class: 63, label: 'tv' },\n { class: 64, label: 'laptop' },\n { class: 65, label: 'mouse' },\n { class: 66, label: 'remote' },\n { class: 67, label: 'keyboard' },\n { class: 68, label: 'cell phone' },\n { class: 69, label: 'microwave' },\n { class: 70, label: 'oven' },\n { class: 71, label: 'toaster' },\n { class: 72, label: 'sink' },\n { class: 73, label: 'refrigerator' },\n { class: 74, label: 'book' },\n { class: 75, label: 'clock' },\n { class: 76, label: 'vase' },\n { class: 77, label: 'scissors' },\n { class: 78, label: 'teddy bear' },\n { class: 79, label: 'hair drier' },\n { class: 80, label: 'toothbrush' },\n];\n", "/**\n * CenterNet object detection model implementation\n *\n * Based on: [**NanoDet**](https://github.com/RangiLyu/nanodet)\n */\n\nimport { log, now } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport { labels } from './labels';\nimport type { ObjectResult, ObjectType, Box } from '../result';\nimport type { GraphModel, Tensor } from '../tfjs/types';\nimport type { Config } from '../config';\nimport { env } from '../util/env';\n\nlet model: GraphModel | null;\nlet inputSize = 0;\nlet last: ObjectResult[] = [];\nlet lastTime = 0;\nlet skipped = Number.MAX_SAFE_INTEGER;\n\nexport async function load(config: Config): Promise {\n if (env.initial) model = null;\n if (!model) {\n // fakeOps(['floormod'], config);\n model = await loadModel(config.object.modelPath);\n const inputs = Object.values(model.modelSignature['inputs']);\n inputSize = Array.isArray(inputs) ? parseInt(inputs[0].tensorShape.dim[2].size) : 0;\n } else if (config.debug) log('cached model:', model['modelUrl']);\n return model;\n}\n\nasync function process(res: Tensor | null, outputShape: [number, number], config: Config) {\n if (!res) return [];\n const t: Record = {};\n const results: Array = [];\n const detections = await res.array() as number[][][];\n t.squeeze = tf.squeeze(res);\n const arr = tf.split(t.squeeze, 6, 1) as Tensor[]; // x1, y1, x2, y2, score, class\n t.stack = tf.stack([arr[1], arr[0], arr[3], arr[2]], 1); // reorder dims as tf.nms expects y, x\n t.boxes = tf.squeeze(t.stack);\n t.scores = tf.squeeze(arr[4]);\n t.classes = tf.squeeze(arr[5]);\n tf.dispose([res, ...arr]);\n t.nms = await tf.image.nonMaxSuppressionAsync(t.boxes, t.scores, config.object.maxDetected, config.object.iouThreshold, (config.object.minConfidence || 0));\n const nms = await t.nms.data();\n let i = 0;\n for (const id of Array.from(nms)) {\n const score = Math.trunc(100 * detections[0][id][4]) / 100;\n const classVal = detections[0][id][5];\n const label = labels[classVal].label as ObjectType;\n const [x, y] = [\n detections[0][id][0] / inputSize,\n detections[0][id][1] / inputSize,\n ];\n const boxRaw: Box = [\n x,\n y,\n detections[0][id][2] / inputSize - x,\n detections[0][id][3] / inputSize - y,\n ];\n const box: Box = [\n Math.trunc(boxRaw[0] * outputShape[0]),\n Math.trunc(boxRaw[1] * outputShape[1]),\n Math.trunc(boxRaw[2] * outputShape[0]),\n Math.trunc(boxRaw[3] * outputShape[1]),\n ];\n results.push({ id: i++, score, class: classVal, label, box, boxRaw });\n }\n Object.keys(t).forEach((tensor) => tf.dispose(t[tensor]));\n return results;\n}\n\nexport async function predict(input: Tensor, config: Config): Promise {\n const skipTime = (config.object.skipTime || 0) > (now() - lastTime);\n const skipFrame = skipped < (config.object.skipFrames || 0);\n if (config.skipAllowed && skipTime && skipFrame && (last.length > 0)) {\n skipped++;\n return last;\n }\n skipped = 0;\n return new Promise(async (resolve) => {\n const outputSize = [input.shape[2] || 0, input.shape[1] || 0] as [number, number];\n const resize = tf.image.resizeBilinear(input, [inputSize, inputSize]);\n const objectT = config.object.enabled ? model?.execute(resize, ['tower_0/detections']) as Tensor : null;\n lastTime = now();\n tf.dispose(resize);\n\n const obj = await process(objectT, outputSize, config);\n last = obj;\n\n resolve(obj);\n });\n}\n", "export const kpt: Array = [\n 'head',\n 'neck',\n 'rightShoulder',\n 'rightElbow',\n 'rightWrist',\n 'chest',\n 'leftShoulder',\n 'leftElbow',\n 'leftWrist',\n 'bodyCenter',\n 'rightHip',\n 'rightKnee',\n 'rightAnkle',\n 'leftHip',\n 'leftKnee',\n 'leftAnkle',\n];\n\nexport const connected: Record = {\n leftLeg: ['leftHip', 'leftKnee', 'leftAnkle'],\n rightLeg: ['rightHip', 'rightKnee', 'rightAnkle'],\n torso: ['leftShoulder', 'rightShoulder', 'rightHip', 'leftHip', 'leftShoulder'],\n leftArm: ['leftShoulder', 'leftElbow', 'leftWrist'],\n rightArm: ['rightShoulder', 'rightElbow', 'rightWrist'],\n head: [],\n};\n", "/**\n * EfficientPose model implementation\n *\n * Based on: [**EfficientPose**](https://github.com/daniegr/EfficientPose)\n */\n\nimport { log, now } from '../util/util';\nimport * as tf from '../../dist/tfjs.esm.js';\nimport { loadModel } from '../tfjs/load';\nimport * as coords from './efficientposecoords';\nimport { constants } from '../tfjs/constants';\nimport type { BodyResult, Point, BodyLandmark, BodyAnnotation } from '../result';\nimport type { GraphModel, Tensor } from '../tfjs/types';\nimport type { Config } from '../config';\nimport { env } from '../util/env';\n\nlet model: GraphModel | null;\nlet lastTime = 0;\nconst cache: BodyResult = { id: 0, keypoints: [], box: [0, 0, 0, 0], boxRaw: [0, 0, 0, 0], score: 0, annotations: {} as Record };\n\n// const keypoints: Array