@vladmandic/face-api
Version:
FaceAPI: AI-powered Face Detection & Rotation Tracking, Face Description & Recognition, Age & Gender & Emotion Prediction for Browser and NodeJS using TensorFlow/JS
7 lines (6 loc) • 82.9 kB
JavaScript
/*
Face-API
homepage: <https://github.com/vladmandic/face-api>
author: <https://github.com/vladmandic>'
*/
var ur=Object.defineProperty;var ho=Object.getOwnPropertyDescriptor;var bo=Object.getOwnPropertyNames;var go=Object.prototype.hasOwnProperty;var xo=(o=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(o,{get:(t,e)=>(typeof require!="undefined"?require:t)[e]}):o)(function(o){if(typeof require!="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var Ye=(o,t)=>{for(var e in t)ur(o,e,{get:t[e],enumerable:!0})},pr=(o,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of bo(t))!go.call(o,a)&&a!==e&&ur(o,a,{get:()=>t[a],enumerable:!(r=ho(t,a))||r.enumerable});return o},w=(o,t,e)=>(pr(o,t,"default"),e&&pr(e,t,"default"));var n={};Ye(n,{version:()=>Po});w(n,mn);w(n,pn);w(n,un);import*as mn from"@tensorflow/tfjs/dist/index.js";import*as pn from"@tensorflow/tfjs-backend-webgl/dist/index.js";import*as un from"@tensorflow/tfjs-backend-wasm/dist/index.js";var fr="4.22.0",vo="4.22.0",yo="4.22.0",To="4.22.0",_o="4.22.0",Po={tfjs:fr,"tfjs-core":fr,"tfjs-converter":vo,"tfjs-backend-cpu":yo,"tfjs-backend-webgl":To,"tfjs-backend-wasm":_o};var Sr={};Ye(Sr,{AnchorPosition:()=>Ke,DrawBox:()=>ee,DrawBoxOptions:()=>de,DrawFaceLandmarks:()=>De,DrawFaceLandmarksOptions:()=>Fe,DrawTextField:()=>xt,DrawTextFieldOptions:()=>Wt,drawContour:()=>Z,drawDetections:()=>Io,drawFaceExpressions:()=>No,drawFaceLandmarks:()=>So});function Z(o,t,e=!1){if(o.beginPath(),t.slice(1).forEach(({x:r,y:a},i)=>{let s=t[i];o.moveTo(s.x,s.y),o.lineTo(r,a)}),e){let r=t[t.length-1],a=t[0];if(!r||!a)return;o.moveTo(r.x,r.y),o.lineTo(a.x,a.y)}o.stroke()}var lr={};Ye(lr,{computeReshapedDimensions:()=>je,getCenterPoint:()=>bt,isDimensions:()=>ue,isEven:()=>pe,isFloat:()=>Ge,isTensor:()=>dt,isTensor1D:()=>wo,isTensor2D:()=>Ve,isTensor3D:()=>K,isTensor4D:()=>R,isValidNumber:()=>G,isValidProbablitiy:()=>Mt,range:()=>X,round:()=>ht});var A=class o{constructor(t,e){if(!G(t)||!G(e))throw new Error(`Dimensions.constructor - expected width and height to be valid numbers, instead have ${JSON.stringify({width:t,height:e})}`);this._width=t,this._height=e}get width(){return this._width}get height(){return this._height}reverse(){return new o(1/this.width,1/this.height)}};function dt(o,t){return o instanceof n.Tensor&&o.shape.length===t}function wo(o){return dt(o,1)}function Ve(o){return dt(o,2)}function K(o){return dt(o,3)}function R(o){return dt(o,4)}function Ge(o){return o%1!==0}function pe(o){return o%2===0}function ht(o,t=2){let e=10**t;return Math.floor(o*e)/e}function ue(o){return o&&o.width&&o.height}function je({width:o,height:t},e){let r=e/Math.max(t,o);return new A(Math.round(o*r),Math.round(t*r))}function bt(o){return o.reduce((t,e)=>t.add(e),new v(0,0)).div(new v(o.length,o.length))}function X(o,t,e){return Array(o).fill(0).map((r,a)=>t+a*e)}function G(o){return!!o&&o!==1/0&&o!==-1/0&&!Number.isNaN(o)||o===0}function Mt(o){return G(o)&&o>=0&&o<=1}var v=class o{constructor(t,e){this._x=t,this._y=e}get x(){return this._x}get y(){return this._y}add(t){return new o(this.x+t.x,this.y+t.y)}sub(t){return new o(this.x-t.x,this.y-t.y)}mul(t){return new o(this.x*t.x,this.y*t.y)}div(t){return new o(this.x/t.x,this.y/t.y)}abs(){return new o(Math.abs(this.x),Math.abs(this.y))}magnitude(){return Math.sqrt(this.x**2+this.y**2)}floor(){return new o(Math.floor(this.x),Math.floor(this.y))}};var C=class o{static isRect(t){return!!t&&[t.x,t.y,t.width,t.height].every(G)}static assertIsValidBox(t,e,r=!1){if(!o.isRect(t))throw new Error(`${e} - invalid box: ${JSON.stringify(t)}, expected object with properties x, y, width, height`);if(!r&&(t.width<0||t.height<0))throw new Error(`${e} - width (${t.width}) and height (${t.height}) must be positive numbers`)}constructor(t,e=!0){let r=t||{},a=[r.left,r.top,r.right,r.bottom].every(G),i=[r.x,r.y,r.width,r.height].every(G);if(!i&&!a)throw new Error(`Box.constructor - expected box to be IBoundingBox | IRect, instead have ${JSON.stringify(r)}`);let[s,c,m,p]=i?[r.x,r.y,r.width,r.height]:[r.left,r.top,r.right-r.left,r.bottom-r.top];o.assertIsValidBox({x:s,y:c,width:m,height:p},"Box.constructor",e),this._x=s,this._y=c,this._width=m,this._height=p}get x(){return this._x}get y(){return this._y}get width(){return this._width}get height(){return this._height}get left(){return this.x}get top(){return this.y}get right(){return this.x+this.width}get bottom(){return this.y+this.height}get area(){return this.width*this.height}get topLeft(){return new v(this.left,this.top)}get topRight(){return new v(this.right,this.top)}get bottomLeft(){return new v(this.left,this.bottom)}get bottomRight(){return new v(this.right,this.bottom)}round(){let[t,e,r,a]=[this.x,this.y,this.width,this.height].map(i=>Math.round(i));return new o({x:t,y:e,width:r,height:a})}floor(){let[t,e,r,a]=[this.x,this.y,this.width,this.height].map(i=>Math.floor(i));return new o({x:t,y:e,width:r,height:a})}toSquare(){let{x:t,y:e,width:r,height:a}=this,i=Math.abs(r-a);return r<a&&(t-=i/2,r+=i),a<r&&(e-=i/2,a+=i),new o({x:t,y:e,width:r,height:a})}rescale(t){let e=ue(t)?t.width:t,r=ue(t)?t.height:t;return new o({x:this.x*e,y:this.y*r,width:this.width*e,height:this.height*r})}pad(t,e){let[r,a,i,s]=[this.x-t/2,this.y-e/2,this.width+t,this.height+e];return new o({x:r,y:a,width:i,height:s})}clipAtImageBorders(t,e){let{x:r,y:a,right:i,bottom:s}=this,c=Math.max(r,0),m=Math.max(a,0),p=i-c,u=s-m,f=Math.min(p,t-c),l=Math.min(u,e-m);return new o({x:c,y:m,width:f,height:l}).floor()}shift(t,e){let{width:r,height:a}=this,i=this.x+t,s=this.y+e;return new o({x:i,y:s,width:r,height:a})}padAtBorders(t,e){let r=this.width+1,a=this.height+1,i=1,s=1,c=r,m=a,p=this.left,u=this.top,f=this.right,l=this.bottom;return f>e&&(c=-f+e+r,f=e),l>t&&(m=-l+t+a,l=t),p<1&&(m=2-p,p=1),u<1&&(m=2-u,u=1),{dy:s,edy:m,dx:i,edx:c,y:u,ey:l,x:p,ex:f,w:r,h:a}}calibrate(t){return new o({left:this.left+t.left*this.width,top:this.top+t.top*this.height,right:this.right+t.right*this.width,bottom:this.bottom+t.bottom*this.height}).toSquare().round()}};var Ct=class extends C{constructor(t,e,r,a,i=!1){super({left:t,top:e,right:r,bottom:a},i)}};var It=class o{constructor(t,e,r,a,i){this._imageDims=new A(i.width,i.height),this._score=t,this._classScore=e,this._className=r,this._box=new C(a).rescale(this._imageDims)}get score(){return this._score}get classScore(){return this._classScore}get className(){return this._className}get box(){return this._box}get imageDims(){return this._imageDims}get imageWidth(){return this.imageDims.width}get imageHeight(){return this.imageDims.height}get relativeBox(){return new C(this._box).rescale(this.imageDims.reverse())}forSize(t,e){return new o(this.score,this.classScore,this.className,this.relativeBox,{width:t,height:e})}};var D=class o extends It{constructor(t,e,r){super(t,t,"",e,r)}forSize(t,e){let{score:r,relativeBox:a,imageDims:i}=super.forSize(t,e);return new o(r,a,i)}};function dr(o,t,e=!0){let r=Math.max(0,Math.min(o.right,t.right)-Math.max(o.left,t.left)),a=Math.max(0,Math.min(o.bottom,t.bottom)-Math.max(o.top,t.top)),i=r*a;return e?i/(o.area+t.area-i):i/Math.min(o.area,t.area)}function hr(o){let t=o.map(c=>c.x),e=o.map(c=>c.y),r=t.reduce((c,m)=>m<c?m:c,1/0),a=e.reduce((c,m)=>m<c?m:c,1/0),i=t.reduce((c,m)=>c<m?m:c,0),s=e.reduce((c,m)=>c<m?m:c,0);return new Ct(r,a,i,s)}function br(o,t,e,r=!0){let a=t.map((s,c)=>({score:s,boxIndex:c})).sort((s,c)=>s.score-c.score).map(s=>s.boxIndex),i=[];for(;a.length>0;){let s=a.pop();i.push(s);let c=a,m=[];for(let p=0;p<c.length;p++){let u=c[p],f=o[s],l=o[u];m.push(dr(f,l,r))}a=a.filter((p,u)=>m[u]<=e)}return i}function J(o,t){return n.tidy(()=>{let[e,r,a]=t,i=n.fill([...o.shape.slice(0,3),1],e,"float32"),s=n.fill([...o.shape.slice(0,3),1],r,"float32"),c=n.fill([...o.shape.slice(0,3),1],a,"float32"),m=n.concat([i,s,c],3);return n.sub(o,m)})}function gr(o,t=!1){return n.tidy(()=>{let[e,r]=o.shape.slice(1);if(e===r)return o;let a=Math.abs(e-r),i=Math.round(a*(t?.5:1)),s=e>r?2:1,c=l=>{let d=o.shape.slice();return d[s]=l,n.fill(d,0,"float32")},m=c(i),p=a-m.shape[s],f=[t&&p?c(p):null,o,m].filter(l=>!!l).map(l=>n.cast(l,"float32"));return n.concat(f,s)})}function Rn(o){let t=o.slice();for(let e=t.length-1;e>0;e--){let r=Math.floor(Math.random()*(e+1)),a=t[e];t[e]=t[r],t[r]=a}return t}function fe(o){return 1/(1+Math.exp(-o))}function On(o){return Math.log(o/(1-o))}var Nt=class extends C{constructor(t,e,r,a,i=!1){super({x:t,y:e,width:r,height:a},i)}};var Fo=.5,Do=.43,Eo=.45,$=class{constructor(t,e,r=new v(0,0)){let{width:a,height:i}=e;this._imgDims=new A(a,i),this._shift=r,this._positions=t.map(s=>s.mul(new v(a,i)).add(r))}get shift(){return new v(this._shift.x,this._shift.y)}get imageWidth(){return this._imgDims.width}get imageHeight(){return this._imgDims.height}get positions(){return this._positions}get relativePositions(){return this._positions.map(t=>t.sub(this._shift).div(new v(this.imageWidth,this.imageHeight)))}forSize(t,e){return new this.constructor(this.relativePositions,{width:t,height:e})}shiftBy(t,e){return new this.constructor(this.relativePositions,this._imgDims,new v(t,e))}shiftByPoint(t){return this.shiftBy(t.x,t.y)}align(t,e={}){if(t){let i=t instanceof D?t.box.floor():new C(t);return this.shiftBy(i.x,i.y).align(null,e)}let{useDlibAlignment:r,minBoxPadding:a}={useDlibAlignment:!1,minBoxPadding:.2,...e};return r?this.alignDlib():this.alignMinBbox(a)}alignDlib(){let t=this.getRefPointsForAlignment(),[e,r,a]=t,i=f=>a.sub(f).magnitude(),s=(i(e)+i(r))/2,c=Math.floor(s/Eo),m=bt(t),p=Math.floor(Math.max(0,m.x-Fo*c)),u=Math.floor(Math.max(0,m.y-Do*c));return new Nt(p,u,Math.min(c,this.imageWidth+p),Math.min(c,this.imageHeight+u))}alignMinBbox(t){let e=hr(this.positions);return e.pad(e.width*t,e.height*t)}getRefPointsForAlignment(){throw new Error("getRefPointsForAlignment not implemented by base class")}};var xr=class extends ${getRefPointsForAlignment(){let t=this.positions;return[t[0],t[1],bt([t[3],t[4]])]}};var Lt=class extends ${getJawOutline(){return this.positions.slice(0,17)}getLeftEyeBrow(){return this.positions.slice(17,22)}getRightEyeBrow(){return this.positions.slice(22,27)}getNose(){return this.positions.slice(27,36)}getLeftEye(){return this.positions.slice(36,42)}getRightEye(){return this.positions.slice(42,48)}getMouth(){return this.positions.slice(48,68)}getRefPointsForAlignment(){return[this.getLeftEye(),this.getRightEye(),this.getMouth()].map(bt)}};var Kt=class{constructor(t,e){this._label=t,this._distance=e}get label(){return this._label}get distance(){return this._distance}toString(t=!0){return`${this.label}${t?` (${ht(this.distance)})`:""}`}};var Qt=class extends C{static assertIsValidLabeledBox(t,e){if(C.assertIsValidBox(t,e),!G(t.label))throw new Error(`${e} - expected property label (${t.label}) to be a number`)}constructor(t,e){super(t),this._label=e}get label(){return this._label}};var gt=class o{constructor(t,e){if(typeof t!="string")throw new Error("LabeledFaceDescriptors - constructor expected label to be a string");if(!Array.isArray(e)||e.some(r=>!(r instanceof Float32Array)))throw new Error("LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array");this._label=t,this._descriptors=e}get label(){return this._label}get descriptors(){return this._descriptors}toJSON(){return{label:this.label,descriptors:this.descriptors.map(t=>Array.from(t))}}static fromJSON(t){let e=t.descriptors.map(r=>new Float32Array(r));return new o(t.label,e)}};var vr=class extends Qt{static assertIsValidPredictedBox(t,e){if(Qt.assertIsValidLabeledBox(t,e),!Mt(t.score)||!Mt(t.classScore))throw new Error(`${e} - expected properties score (${t.score}) and (${t.classScore}) to be a number between [0, 1]`)}constructor(t,e,r,a){super(t,e),this._score=r,this._classScore=a}get score(){return this._score}get classScore(){return this._classScore}};function Q(o){return o.detection instanceof D}function St(o,t){return{...o,...{detection:t}}}function Ue(){let o=window.fetch;if(!o)throw new Error("fetch - missing fetch implementation for browser environment");return{Canvas:HTMLCanvasElement,CanvasRenderingContext2D,Image:HTMLImageElement,ImageData,Video:HTMLVideoElement,createCanvasElement:()=>document.createElement("canvas"),createImageElement:()=>document.createElement("img"),createVideoElement:()=>document.createElement("video"),fetch:o,readFile:()=>{throw new Error("readFile - filesystem not available for browser environment")}}}function te(){return typeof global=="object"&&typeof process!="undefined"&&process.versions!=null&&process.versions.node!=null}function le(o){let t="";if(!o&&te())try{o=xo("fs")}catch(r){t=r.toString()}return{readFile:o?r=>new Promise((a,i)=>{o.readFile(r,(s,c)=>s?i(s):a(c))}):()=>{throw new Error(`readFile - failed to require fs in nodejs environment with error: ${t}`)}}}function Xe(){let o=global.Canvas||global.HTMLCanvasElement,t=global.Image||global.HTMLImageElement,e=global.Video||global.HTMLVideoElement,r=()=>{if(o)return new o;throw new Error("createCanvasElement - missing Canvas implementation for nodejs environment")},a=()=>{if(t)return new t;throw new Error("createImageElement - missing Image implementation for nodejs environment")},i=()=>{if(e)return new e;throw new Error("createVideoElement - missing Video implementation for nodejs environment")},s=global.fetch,c=le();return{Canvas:o||class{},CanvasRenderingContext2D:global.CanvasRenderingContext2D||class{},Image:t||class{},ImageData:global.ImageData||class{},Video:global.HTMLVideoElement||class{},createCanvasElement:r,createImageElement:a,createVideoElement:i,fetch:s,...c}}function Je(){return typeof window=="object"&&typeof document!="undefined"&&typeof HTMLImageElement!="undefined"&&typeof HTMLCanvasElement!="undefined"&&typeof HTMLVideoElement!="undefined"&&typeof ImageData!="undefined"&&typeof CanvasRenderingContext2D!="undefined"}var M;function Mo(){if(!M)throw new Error("getEnv - environment is not defined, check isNodejs() and isBrowser()");return M}function qe(o){M=o}function Ze(){return Je()?qe(Ue()):te()?qe(Xe()):null}function Co(o){if(M||Ze(),!M)throw new Error("monkeyPatch - environment is not defined, check isNodejs() and isBrowser()");let{Canvas:t=M.Canvas,Image:e=M.Image}=o;M.Canvas=t,M.Image=e,M.createCanvasElement=o.createCanvasElement||(()=>new t),M.createImageElement=o.createImageElement||(()=>new e),M.ImageData=o.ImageData||M.ImageData,M.Video=o.Video||M.Video,M.fetch=o.fetch||M.fetch,M.readFile=o.readFile||M.readFile}var _={getEnv:Mo,setEnv:qe,initialize:Ze,createBrowserEnv:Ue,createFileSystem:le,createNodejsEnv:Xe,monkeyPatch:Co,isBrowser:Je,isNodejs:te};Ze();function At(o){return!_.isNodejs()&&typeof o=="string"?document.getElementById(o):o}function W(o){let{Canvas:t,CanvasRenderingContext2D:e}=_.getEnv();if(o instanceof e)return o;let r=At(o);if(!(r instanceof t))throw new Error("resolveContext2d - expected canvas to be of instance of Canvas");let a=r.getContext("2d",{willReadFrequently:!0});if(!a)throw new Error("resolveContext2d - canvas 2d context is null");return a}var Ke=(a=>(a.TOP_LEFT="TOP_LEFT",a.TOP_RIGHT="TOP_RIGHT",a.BOTTOM_LEFT="BOTTOM_LEFT",a.BOTTOM_RIGHT="BOTTOM_RIGHT",a))(Ke||{}),Wt=class{constructor(t={}){let{anchorPosition:e,backgroundColor:r,fontColor:a,fontSize:i,fontStyle:s,padding:c}=t;this.anchorPosition=e||"TOP_LEFT",this.backgroundColor=r||"rgba(0, 0, 0, 0.5)",this.fontColor=a||"rgba(255, 255, 255, 1)",this.fontSize=i||14,this.fontStyle=s||"Georgia",this.padding=c||4}},xt=class o{constructor(t,e,r={}){this.text=typeof t=="string"?[t]:t instanceof o?t.text:t,this.anchor=e,this.options=new Wt(r)}measureWidth(t){let{padding:e}=this.options;return this.text.map(r=>t.measureText(r).width).reduce((r,a)=>r<a?a:r,0)+2*e}measureHeight(){let{fontSize:t,padding:e}=this.options;return this.text.length*t+2*e}getUpperLeft(t,e){let{anchorPosition:r}=this.options,a=r==="BOTTOM_RIGHT"||r==="TOP_RIGHT",i=r==="BOTTOM_LEFT"||r==="BOTTOM_RIGHT",s=this.measureWidth(t),c=this.measureHeight(),m=a?this.anchor.x-s:this.anchor.x,p=i?this.anchor.y-c:this.anchor.y;if(e){let{width:u,height:f}=e,l=Math.max(Math.min(m,u-s),0),d=Math.max(Math.min(p,f-c),0);return{x:l,y:d}}return{x:m,y:p}}draw(t){let e=At(t),r=W(e),{backgroundColor:a,fontColor:i,fontSize:s,fontStyle:c,padding:m}=this.options;r.font=`${s}px ${c}`;let p=this.measureWidth(r),u=this.measureHeight();r.fillStyle=a;let f=this.getUpperLeft(r,e);r.fillRect(f.x,f.y,p,u),r.fillStyle=i,this.text.forEach((l,d)=>{let b=m+f.x,y=m+f.y+(d+1)*s;r.fillText(l,b,y)})}};var de=class{constructor(t={}){let{boxColor:e,lineWidth:r,label:a,drawLabelOptions:i}=t;this.boxColor=e||"rgba(0, 0, 255, 1)",this.lineWidth=r||2,this.label=a;let s={anchorPosition:"BOTTOM_LEFT",backgroundColor:this.boxColor};this.drawLabelOptions=new Wt({...s,...i})}},ee=class{constructor(t,e={}){this.box=new C(t),this.options=new de(e)}draw(t){let e=W(t),{boxColor:r,lineWidth:a}=this.options,{x:i,y:s,width:c,height:m}=this.box;e.strokeStyle=r,e.lineWidth=a,e.strokeRect(i,s,c,m);let{label:p}=this.options;p&&new xt([p],{x:i-a/2,y:s},this.options.drawLabelOptions).draw(t)}};function Io(o,t){(Array.isArray(t)?t:[t]).forEach(r=>{let a=r instanceof D?r.score:Q(r)?r.detection.score:void 0,i=r instanceof D?r.box:Q(r)?r.detection.box:new C(r),s=a?`${ht(a)}`:void 0;new ee(i,{label:s}).draw(o)})}function he(o){let{Image:t,Video:e}=_.getEnv();return o instanceof t&&o.complete||o instanceof e&&o.readyState>=3}function yr(o){return new Promise((t,e)=>{if(o instanceof _.getEnv().Canvas||he(o)){t(null);return}function r(i){i.currentTarget&&(i.currentTarget.removeEventListener("load",a),i.currentTarget.removeEventListener("error",r),e(i))}function a(i){i.currentTarget&&(i.currentTarget.removeEventListener("load",a),i.currentTarget.removeEventListener("error",r),t(i))}o.addEventListener("load",a),o.addEventListener("error",r)})}function Tr(o){return new Promise((t,e)=>{o instanceof Blob||e(new Error("bufferToImage - expected buf to be of type: Blob"));let r=new FileReader;r.onload=()=>{typeof r.result!="string"&&e(new Error("bufferToImage - expected reader.result to be a string, in onload"));let a=_.getEnv().createImageElement();a.onload=()=>t(a),a.onerror=e,a.src=r.result},r.onerror=e,r.readAsDataURL(o)})}function kt(o){let{Image:t,Video:e}=_.getEnv();return o instanceof t?new A(o.naturalWidth,o.naturalHeight):o instanceof e?new A(o.videoWidth,o.videoHeight):new A(o.width,o.height)}function Bt({width:o,height:t}){let{createCanvasElement:e}=_.getEnv(),r=e();return r.width=o,r.height=t,r}function be(o,t){let{ImageData:e}=_.getEnv();if(!(o instanceof e)&&!he(o))throw new Error("createCanvasFromMedia - media has not finished loading yet");let{width:r,height:a}=t||kt(o),i=Bt({width:r,height:a});return o instanceof e?W(i).putImageData(o,0,0):W(i).drawImage(o,0,0,r,a),i}async function _r(o,t){let e=t||_.getEnv().createCanvasElement(),[r,a,i]=o.shape.slice(R(o)?1:0),s=n.tidy(()=>o.as3D(r,a,i).toInt());return await n.browser.toPixels(s,e),s.dispose(),e}function Qe(o){let{Image:t,Canvas:e,Video:r}=_.getEnv();return o instanceof t||o instanceof e||o instanceof r}function Pr(o,t,e=!1){let{Image:r,Canvas:a}=_.getEnv();if(!(o instanceof r||o instanceof a))throw new Error("imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement");if(t<=0)return Bt({width:1,height:1});let i=kt(o),s=t/Math.max(i.height,i.width),c=s*i.width,m=s*i.height,p=Bt({width:t,height:t}),u=o instanceof a?o:be(o),f=Math.abs(c-m)/2,l=e&&c<m?f:0,d=e&&m<c?f:0;return u.width>0&&u.height>0&&W(p).drawImage(u,l,d,c,m),p}var tt=class{constructor(t,e=!1){this._imageTensors=[];this._canvases=[];this._treatAsBatchInput=!1;this._inputDimensions=[];this._inputSize=0;if(!Array.isArray(t))throw new Error(`NetInput.constructor - expected inputs to be an Array of TResolvedNetInput or to be instanceof tf.Tensor4D, instead have ${t}`);this._treatAsBatchInput=e,this._batchSize=t.length,t.forEach((r,a)=>{if(K(r)){this._imageTensors[a]=r,this._inputDimensions[a]=r.shape;return}if(R(r)){let s=r.shape[0];if(s!==1)throw new Error(`NetInput - tf.Tensor4D with batchSize ${s} passed, but not supported in input array`);this._imageTensors[a]=r,this._inputDimensions[a]=r.shape.slice(1);return}let i=r instanceof _.getEnv().Canvas?r:be(r);this._canvases[a]=i,this._inputDimensions[a]=[i.height,i.width,3]})}get imageTensors(){return this._imageTensors}get canvases(){return this._canvases}get isBatchInput(){return this.batchSize>1||this._treatAsBatchInput}get batchSize(){return this._batchSize}get inputDimensions(){return this._inputDimensions}get inputSize(){return this._inputSize}get reshapedInputDimensions(){return X(this.batchSize,0,1).map((t,e)=>this.getReshapedInputDimensions(e))}getInput(t){return this.canvases[t]||this.imageTensors[t]}getInputDimensions(t){return this._inputDimensions[t]}getInputHeight(t){return this._inputDimensions[t][0]}getInputWidth(t){return this._inputDimensions[t][1]}getReshapedInputDimensions(t){if(typeof this.inputSize!="number")throw new Error("getReshapedInputDimensions - inputSize not set, toBatchTensor has not been called yet");let e=this.getInputWidth(t),r=this.getInputHeight(t);return je({width:e,height:r},this.inputSize)}toBatchTensor(t,e=!0){return this._inputSize=t,n.tidy(()=>{let r=X(this.batchSize,0,1).map(i=>{let s=this.getInput(i);if(s instanceof n.Tensor){let c=R(s)?s:n.expandDims(s);return c=gr(c,e),(c.shape[1]!==t||c.shape[2]!==t)&&(c=n.image.resizeBilinear(c,[t,t],!1,!1)),c.as3D(t,t,3)}if(s instanceof _.getEnv().Canvas)return n.browser.fromPixels(Pr(s,t,e));throw new Error(`toBatchTensor - at batchIdx ${i}, expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have ${s}`)});return n.stack(r.map(i=>n.cast(i,"float32"))).as4D(this.batchSize,t,t,3)})}};async function F(o){if(o instanceof tt)return o;let t=Array.isArray(o)?o:[o];if(!t.length)throw new Error("toNetInput - empty array passed as input");let e=a=>Array.isArray(o)?` at input index ${a}:`:"",r=t.map(At);return r.forEach((a,i)=>{if(!Qe(a)&&!K(a)&&!R(a))throw typeof t[i]=="string"?new Error(`toNetInput -${e(i)} string passed, but could not resolve HTMLElement for element id ${t[i]}`):new Error(`toNetInput -${e(i)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`);if(R(a)){let s=a.shape[0];if(s!==1)throw new Error(`toNetInput -${e(i)} tf.Tensor4D with batchSize ${s} passed, but not supported in input array`)}}),await Promise.all(r.map(a=>Qe(a)&&yr(a))),new tt(r,Array.isArray(o))}async function re(o,t){let{Canvas:e}=_.getEnv(),r=o;if(!(o instanceof e)){let s=await F(o);if(s.batchSize>1)throw new Error("extractFaces - batchSize > 1 not supported");let c=s.getInput(0);r=c instanceof e?c:await _r(c)}let a=W(r);return t.map(s=>s instanceof D?s.forSize(r.width,r.height).box.floor():s).map(s=>s.clipAtImageBorders(r.width,r.height)).map(({x:s,y:c,width:m,height:p})=>{let u=Bt({width:m,height:p});return m>0&&p>0&&W(u).putImageData(a.getImageData(s,c,m,p),0,0),u})}async function oe(o,t){if(!K(o)&&!R(o))throw new Error("extractFaceTensors - expected image tensor to be 3D or 4D");if(R(o)&&o.shape[0]>1)throw new Error("extractFaceTensors - batchSize > 1 not supported");return n.tidy(()=>{let[e,r,a]=o.shape.slice(R(o)?1:0);return t.map(c=>c instanceof D?c.forSize(r,e).box:c).map(c=>c.clipAtImageBorders(r,e)).filter(c=>c.width>0&&c.height>0).map(({x:c,y:m,width:p,height:u})=>n.slice3d(o.as3D(e,r,a),[m,c,0],[u,p,a]))})}async function st(o,t){let{fetch:e}=_.getEnv(),r=await e(o,t);if(!(r.status<400))throw new Error(`failed to fetch: (${r.status}) ${r.statusText}, from url: ${r.url}`);return r}async function Fi(o){let t=await st(o),e=await t.blob();if(!e.type.startsWith("image/"))throw new Error(`fetchImage - expected blob type to be of type image/*, instead have: ${e.type}, for url: ${t.url}`);return Tr(e)}async function wr(o){return(await st(o)).json()}async function Ii(o){return new Float32Array(await(await st(o)).arrayBuffer())}function Fr(o){return new Promise((t,e)=>{o instanceof Blob||e(new Error("bufferToVideo - expected buf to be of type: Blob"));let r=_.getEnv().createVideoElement();r.oncanplay=()=>t(r),r.onerror=e,r.playsInline=!0,r.muted=!0,r.src=URL.createObjectURL(o),r.play()})}async function ki(o){let t=await st(o),e=await t.blob();if(!e.type.startsWith("video/"))throw new Error(`fetchVideo - expected blob type to be of type video/*, instead have: ${e.type}, for url: ${t.url}`);return Fr(e)}function ge(o,t){let e=`${t}-weights_manifest.json`;if(!o)return{modelBaseUri:"",manifestUri:e};if(o==="/")return{modelBaseUri:"/",manifestUri:`/${e}`};let r=o.startsWith("http://")?"http://":o.startsWith("https://")?"https://":"";o=o.replace(r,"");let a=o.split("/").filter(c=>c),i=o.endsWith(".json")?a[a.length-1]:e,s=r+(o.endsWith(".json")?a.slice(0,a.length-1):a).join("/");return s=o.startsWith("/")?`/${s}`:s,{modelBaseUri:s,manifestUri:s==="/"?`/${i}`:`${s}/${i}`}}async function Dr(o,t){let{manifestUri:e,modelBaseUri:r}=ge(o,t),a=await wr(e);return n.io.loadWeights(a,r)}function Yi(o,t,e=!1){let{width:r,height:a}=e?kt(t):t;return o.width=r,o.height=a,{width:r,height:a}}var I=class{constructor(t){this._params=void 0;this._paramMappings=[];this._name=t}get params(){return this._params}get paramMappings(){return this._paramMappings}get isLoaded(){return!!this.params}getParamFromPath(t){let{obj:e,objProp:r}=this.traversePropertyPath(t);return e[r]}reassignParamFromPath(t,e){let{obj:r,objProp:a}=this.traversePropertyPath(t);r[a].dispose(),r[a]=e}getParamList(){return this._paramMappings.map(({paramPath:t})=>({path:t,tensor:this.getParamFromPath(t)}))}getTrainableParams(){return this.getParamList().filter(t=>t.tensor instanceof n.Variable)}getFrozenParams(){return this.getParamList().filter(t=>!(t.tensor instanceof n.Variable))}variable(){this.getFrozenParams().forEach(({path:t,tensor:e})=>{this.reassignParamFromPath(t,e.variable())})}freeze(){this.getTrainableParams().forEach(({path:t,tensor:e})=>{let r=n.tensor(e.dataSync());e.dispose(),this.reassignParamFromPath(t,r)})}dispose(t=!0){this.getParamList().forEach(e=>{if(t&&e.tensor.isDisposed)throw new Error(`param tensor has already been disposed for path ${e.path}`);e.tensor.dispose()}),this._params=void 0}serializeParams(){return new Float32Array(this.getParamList().map(({tensor:t})=>Array.from(t.dataSync())).reduce((t,e)=>t.concat(e)))}async load(t){if(t instanceof Float32Array){this.extractWeights(t);return}await this.loadFromUri(t)}async loadFromUri(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromUri - expected model uri`);let e=await Dr(t,this.getDefaultModelName());this.loadFromWeightMap(e)}async loadFromDisk(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromDisk - expected model file path`);let{readFile:e}=_.getEnv(),{manifestUri:r,modelBaseUri:a}=ge(t,this.getDefaultModelName()),i=p=>Promise.all(p.map(u=>e(u).then(f=>typeof f=="string"?Buffer.from(f):f.buffer))),s=n.io.weightsLoaderFactory(i),c=JSON.parse((await e(r)).toString()),m=await s(c,a);this.loadFromWeightMap(m)}loadFromWeightMap(t){let{paramMappings:e,params:r}=this.extractParamsFromWeightMap(t);this._paramMappings=e,this._params=r}extractWeights(t){let{paramMappings:e,params:r}=this.extractParams(t);this._paramMappings=e,this._params=r}traversePropertyPath(t){if(!this.params)throw new Error("traversePropertyPath - model has no loaded params");let e=t.split("/").reduce((i,s)=>{if(!i.nextObj.hasOwnProperty(s))throw new Error(`traversePropertyPath - object does not have property ${s}, for path ${t}`);return{obj:i.nextObj,objProp:s,nextObj:i.nextObj[s]}},{nextObj:this.params}),{obj:r,objProp:a}=e;if(!r||!a||!(r[a]instanceof n.Tensor))throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${t}`);return{obj:r,objProp:a}}};function S(o,t,e){return n.tidy(()=>{let r=n.separableConv2d(o,t.depthwise_filter,t.pointwise_filter,e,"same");return r=n.add(r,t.bias),r})}function xe(o,t,e=!1){return n.tidy(()=>{let r=n.relu(e?n.add(n.conv2d(o,t.conv0.filters,[2,2],"same"),t.conv0.bias):S(o,t.conv0,[2,2])),a=S(r,t.conv1,[1,1]),i=n.relu(n.add(r,a)),s=S(i,t.conv2,[1,1]);return n.relu(n.add(r,n.add(a,s)))})}function ne(o,t,e=!1,r=!0){return n.tidy(()=>{let a=n.relu(e?n.add(n.conv2d(o,t.conv0.filters,r?[2,2]:[1,1],"same"),t.conv0.bias):S(o,t.conv0,r?[2,2]:[1,1])),i=S(a,t.conv1,[1,1]),s=n.relu(n.add(a,i)),c=S(s,t.conv2,[1,1]),m=n.relu(n.add(a,n.add(i,c))),p=S(m,t.conv3,[1,1]);return n.relu(n.add(a,n.add(i,n.add(c,p))))})}function vt(o,t,e="same",r=!1){return n.tidy(()=>{let a=n.add(n.conv2d(o,t.filters,[1,1],e),t.bias);return r?n.relu(a):a})}function N(o,t){Object.keys(o).forEach(e=>{t.some(r=>r.originalPath===e)||o[e].dispose()})}function Rt(o,t){return(e,r,a,i)=>{let s=n.tensor4d(o(e*r*a*a),[a,a,e,r]),c=n.tensor1d(o(r));return t.push({paramPath:`${i}/filters`},{paramPath:`${i}/bias`}),{filters:s,bias:c}}}function ve(o,t){return(e,r,a)=>{let i=n.tensor2d(o(e*r),[e,r]),s=n.tensor1d(o(r));return t.push({paramPath:`${a}/weights`},{paramPath:`${a}/bias`}),{weights:i,bias:s}}}var ae=class{constructor(t,e,r){this.depthwise_filter=t;this.pointwise_filter=e;this.bias=r}};function $t(o,t){return(e,r,a)=>{let i=n.tensor4d(o(9*e),[3,3,e,1]),s=n.tensor4d(o(e*r),[1,1,e,r]),c=n.tensor1d(o(r));return t.push({paramPath:`${a}/depthwise_filter`},{paramPath:`${a}/pointwise_filter`},{paramPath:`${a}/bias`}),new ae(i,s,c)}}function Ot(o){return t=>{let e=o(`${t}/depthwise_filter`,4),r=o(`${t}/pointwise_filter`,4),a=o(`${t}/bias`,1);return new ae(e,r,a)}}function k(o,t){return(e,r,a)=>{let i=o[e];if(!dt(i,r))throw new Error(`expected weightMap[${e}] to be a Tensor${r}D, instead have ${i}`);return t.push({originalPath:e,paramPath:a||e}),i}}function L(o){let t=o;function e(a){let i=t.slice(0,a);return t=t.slice(a),i}function r(){return t}return{extractWeights:e,getRemainingWeights:r}}function ye(o,t){let e=Rt(o,t),r=$t(o,t);function a(s,c,m,p=!1){let u=p?e(s,c,3,`${m}/conv0`):r(s,c,`${m}/conv0`),f=r(c,c,`${m}/conv1`),l=r(c,c,`${m}/conv2`);return{conv0:u,conv1:f,conv2:l}}function i(s,c,m,p=!1){let{conv0:u,conv1:f,conv2:l}=a(s,c,m,p),d=r(c,c,`${m}/conv3`);return{conv0:u,conv1:f,conv2:l,conv3:d}}return{extractDenseBlock3Params:a,extractDenseBlock4Params:i}}function Er(o){let t=[],{extractWeights:e,getRemainingWeights:r}=L(o),{extractDenseBlock4Params:a}=ye(e,t),i=a(3,32,"dense0",!0),s=a(32,64,"dense1"),c=a(64,128,"dense2"),m=a(128,256,"dense3");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{dense0:i,dense1:s,dense2:c,dense3:m}}}function Te(o){return t=>{let e=o(`${t}/filters`,4),r=o(`${t}/bias`,1);return{filters:e,bias:r}}}function _e(o,t){let e=k(o,t),r=Te(e),a=Ot(e);function i(c,m=!1){let p=m?r(`${c}/conv0`):a(`${c}/conv0`),u=a(`${c}/conv1`),f=a(`${c}/conv2`);return{conv0:p,conv1:u,conv2:f}}function s(c,m=!1){let p=m?r(`${c}/conv0`):a(`${c}/conv0`),u=a(`${c}/conv1`),f=a(`${c}/conv2`),l=a(`${c}/conv3`);return{conv0:p,conv1:u,conv2:f,conv3:l}}return{extractDenseBlock3Params:i,extractDenseBlock4Params:s}}function Mr(o){let t=[],{extractDenseBlock4Params:e}=_e(o,t),r={dense0:e("dense0",!0),dense1:e("dense1"),dense2:e("dense2"),dense3:e("dense3")};return N(o,t),{params:r,paramMappings:t}}var Ht=class extends I{constructor(){super("FaceFeatureExtractor")}forwardInput(t){let{params:e}=this;if(!e)throw new Error("FaceFeatureExtractor - load model before inference");return n.tidy(()=>{let r=n.cast(t.toBatchTensor(112,!0),"float32"),i=J(r,[122.782,117.001,104.298]).div(255),s=ne(i,e.dense0,!0);return s=ne(s,e.dense1),s=ne(s,e.dense2),s=ne(s,e.dense3),s=n.avgPool(s,[7,7],[2,2],"valid"),s})}async forward(t){return this.forwardInput(await F(t))}getDefaultModelName(){return"face_feature_extractor_model"}extractParamsFromWeightMap(t){return Mr(t)}extractParams(t){return Er(t)}};function se(o,t){return n.tidy(()=>n.add(n.matMul(o,t.weights),t.bias))}function Cr(o,t,e){let r=[],{extractWeights:a,getRemainingWeights:i}=L(o),c=ve(a,r)(t,e,"fc");if(i().length!==0)throw new Error(`weights remaing after extract: ${i().length}`);return{paramMappings:r,params:{fc:c}}}function Ir(o){let t=[],e=k(o,t);function r(i){let s=e(`${i}/weights`,2),c=e(`${i}/bias`,1);return{weights:s,bias:c}}let a={fc:r("fc")};return N(o,t),{params:a,paramMappings:t}}function Pe(o){let t={},e={};return Object.keys(o).forEach(r=>{let a=r.startsWith("fc")?e:t;a[r]=o[r]}),{featureExtractorMap:t,classifierMap:e}}var zt=class extends I{constructor(t,e){super(t),this._faceFeatureExtractor=e}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){let{params:e}=this;if(!e)throw new Error(`${this._name} - load model before inference`);return n.tidy(()=>{let r=t instanceof tt?this.faceFeatureExtractor.forwardInput(t):t;return se(r.as2D(r.shape[0],-1),e.fc)})}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){let{params:e,paramMappings:r}=this.extractClassifierParams(t);this._params=e,this._paramMappings=r}extractClassifierParams(t){return Cr(t,this.getClassifierChannelsIn(),this.getClassifierChannelsOut())}extractParamsFromWeightMap(t){let{featureExtractorMap:e,classifierMap:r}=Pe(t);return this.faceFeatureExtractor.loadFromWeightMap(e),Ir(r)}extractParams(t){let e=this.getClassifierChannelsIn(),r=this.getClassifierChannelsOut(),a=r*e+r,i=t.slice(0,t.length-a),s=t.slice(t.length-a);return this.faceFeatureExtractor.extractWeights(i),this.extractClassifierParams(s)}};var Nr=["neutral","happy","sad","angry","fearful","disgusted","surprised"],it=class{constructor(t){this.neutral=0;this.happy=0;this.sad=0;this.angry=0;this.fearful=0;this.disgusted=0;this.surprised=0;if(t.length!==7)throw new Error(`FaceExpressions.constructor - expected probabilities.length to be 7, have: ${t.length}`);Nr.forEach((e,r)=>{this[e]=t[r]})}asSortedArray(){return Nr.map(t=>({expression:t,probability:this[t]})).sort((t,e)=>e.probability-t.probability)}};var we=class extends zt{constructor(t=new Ht){super("FaceExpressionNet",t)}forwardInput(t){return n.tidy(()=>n.softmax(this.runNet(t)))}async forward(t){return this.forwardInput(await F(t))}async predictExpressions(t){let e=await F(t),r=await this.forwardInput(e),a=await Promise.all(n.unstack(r).map(async s=>{let c=s.dataSync();return s.dispose(),c}));r.dispose();let i=a.map(s=>new it(s));return e.isBatchInput?i:i[0]}getDefaultModelName(){return"face_expression_model"}getClassifierChannelsIn(){return 256}getClassifierChannelsOut(){return 7}};function Lr(o){return o.expressions instanceof it}function tr(o,t){return{...o,...{expressions:t}}}function No(o,t,e=.1,r){(Array.isArray(t)?t:[t]).forEach(i=>{let s=i instanceof it?i:Lr(i)?i.expressions:void 0;if(!s)throw new Error("drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof");let m=s.asSortedArray().filter(f=>f.probability>e),p=Q(i)?i.detection.box.bottomLeft:r||new v(0,0);new xt(m.map(f=>`${f.expression} (${ht(f.probability)})`),p).draw(o)})}function Yt(o){return Q(o)&&o.landmarks instanceof $&&o.unshiftedLandmarks instanceof $&&o.alignedRect instanceof D}function Lo(o){let t=m=>m*180/Math.PI,e=(m,p)=>Math.sqrt((m.x-p.x)**2+(m.y-p.y)**2),r={roll:void 0,pitch:void 0,yaw:void 0},a=(m,p,u)=>{let f=Math.floor(m.x-p.x),l=Math.floor(p.x-u.x);return f-l},i=(m,p)=>{let u=Math.hypot(p.x-m.x,p.y-m.y),f=p.y-m.y,l=Math.asin(f/u),d=t(l),b=Math.floor(90-d),y=p.x-m.x<0?-1:1;return b*y},s=(m,p,u)=>{let f=e(m,u),l=new v((m.x+u.x)/2,(m.y+u.y)/2),d=e(p,l),b=Math.atan(d/f),y=Math.floor(t(b)),h=l.y-p.y<0?-1:1;return y*h};if(!o||!o.positions||o.positions.length!==68)return r;let c=o.positions;return r.roll=i(c[27],c[66]),r.pitch=s(c[14],c[30],c[2]),r.yaw=a(c[14],c[33],c[2]),r}function ie(o,t){let{box:e}=o.detection,r=t.shiftBy(e.x,e.y),a=r.align(),{imageDims:i}=o.detection,s=new D(o.detection.score,a.rescale(i.reverse()),i),c=Lo(t);return{...o,...{landmarks:r,unshiftedLandmarks:t,alignedRect:s,angle:c}}}var Fe=class{constructor(t={}){let{drawLines:e=!0,drawPoints:r=!0,lineWidth:a,lineColor:i,pointSize:s,pointColor:c}=t;this.drawLines=e,this.drawPoints=r,this.lineWidth=a||1,this.pointSize=s||2,this.lineColor=i||"rgba(0, 255, 255, 1)",this.pointColor=c||"rgba(255, 0, 255, 1)"}},De=class{constructor(t,e={}){this.faceLandmarks=t,this.options=new Fe(e)}draw(t){let e=W(t),{drawLines:r,drawPoints:a,lineWidth:i,lineColor:s,pointSize:c,pointColor:m}=this.options;if(r&&this.faceLandmarks instanceof Lt&&(e.strokeStyle=s,e.lineWidth=i,Z(e,this.faceLandmarks.getJawOutline()),Z(e,this.faceLandmarks.getLeftEyeBrow()),Z(e,this.faceLandmarks.getRightEyeBrow()),Z(e,this.faceLandmarks.getNose()),Z(e,this.faceLandmarks.getLeftEye(),!0),Z(e,this.faceLandmarks.getRightEye(),!0),Z(e,this.faceLandmarks.getMouth(),!0)),a){e.strokeStyle=m,e.fillStyle=m;let p=u=>{e.beginPath(),e.arc(u.x,u.y,c,0,2*Math.PI),e.fill()};this.faceLandmarks.positions.forEach(p)}}};function So(o,t){(Array.isArray(t)?t:[t]).forEach(r=>{let a=r instanceof $?r:Yt(r)?r.landmarks:void 0;if(!a)throw new Error("drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks<WithFaceDetection<{}>> or array thereof");new De(a).draw(o)})}var Ar="1.7.15";function ko(o,t){let e=Rt(o,t),r=$t(o,t);function a(s,c,m){let p=r(s,c,`${m}/separable_conv0`),u=r(c,c,`${m}/separable_conv1`),f=e(s,c,1,`${m}/expansion_conv`);return{separable_conv0:p,separable_conv1:u,expansion_conv:f}}function i(s,c){let m=r(s,s,`${c}/separable_conv0`),p=r(s,s,`${c}/separable_conv1`),u=r(s,s,`${c}/separable_conv2`);return{separable_conv0:m,separable_conv1:p,separable_conv2:u}}return{extractConvParams:e,extractSeparableConvParams:r,extractReductionBlockParams:a,extractMainBlockParams:i}}function Wr(o,t){let e=[],{extractWeights:r,getRemainingWeights:a}=L(o),{extractConvParams:i,extractSeparableConvParams:s,extractReductionBlockParams:c,extractMainBlockParams:m}=ko(r,e),p=i(3,32,3,"entry_flow/conv_in"),u=c(32,64,"entry_flow/reduction_block_0"),f=c(64,128,"entry_flow/reduction_block_1"),l={conv_in:p,reduction_block_0:u,reduction_block_1:f},d={};X(t,0,1).forEach(g=>{d[`main_block_${g}`]=m(128,`middle_flow/main_block_${g}`)});let b=c(128,256,"exit_flow/reduction_block"),y=s(256,512,"exit_flow/separable_conv"),h={reduction_block:b,separable_conv:y};if(a().length!==0)throw new Error(`weights remaing after extract: ${a().length}`);return{paramMappings:e,params:{entry_flow:l,middle_flow:d,exit_flow:h}}}function Bo(o,t){let e=k(o,t),r=Te(e),a=Ot(e);function i(c){let m=a(`${c}/separable_conv0`),p=a(`${c}/separable_conv1`),u=r(`${c}/expansion_conv`);return{separable_conv0:m,separable_conv1:p,expansion_conv:u}}function s(c){let m=a(`${c}/separable_conv0`),p=a(`${c}/separable_conv1`),u=a(`${c}/separable_conv2`);return{separable_conv0:m,separable_conv1:p,separable_conv2:u}}return{extractConvParams:r,extractSeparableConvParams:a,extractReductionBlockParams:i,extractMainBlockParams:s}}function kr(o,t){let e=[],{extractConvParams:r,extractSeparableConvParams:a,extractReductionBlockParams:i,extractMainBlockParams:s}=Bo(o,e),c=r("entry_flow/conv_in"),m=i("entry_flow/reduction_block_0"),p=i("entry_flow/reduction_block_1"),u={conv_in:c,reduction_block_0:m,reduction_block_1:p},f={};X(t,0,1).forEach(y=>{f[`main_block_${y}`]=s(`middle_flow/main_block_${y}`)});let l=i("exit_flow/reduction_block"),d=a("exit_flow/separable_conv"),b={reduction_block:l,separable_conv:d};return N(o,e),{params:{entry_flow:u,middle_flow:f,exit_flow:b},paramMappings:e}}function Br(o,t,e){return n.add(n.conv2d(o,t.filters,e,"same"),t.bias)}function er(o,t,e=!0){let r=e?n.relu(o):o;return r=S(r,t.separable_conv0,[1,1]),r=S(n.relu(r),t.separable_conv1,[1,1]),r=n.maxPool(r,[3,3],[2,2],"same"),r=n.add(r,Br(o,t.expansion_conv,[2,2])),r}function Ro(o,t){let e=S(n.relu(o),t.separable_conv0,[1,1]);return e=S(n.relu(e),t.separable_conv1,[1,1]),e=S(n.relu(e),t.separable_conv2,[1,1]),e=n.add(e,o),e}var Ee=class extends I{constructor(t){super("TinyXception"),this._numMainBlocks=t}forwardInput(t){let{params:e}=this;if(!e)throw new Error("TinyXception - load model before inference");return n.tidy(()=>{let r=n.cast(t.toBatchTensor(112,!0),"float32"),i=J(r,[122.782,117.001,104.298]).div(255),s=n.relu(Br(i,e.entry_flow.conv_in,[2,2]));return s=er(s,e.entry_flow.reduction_block_0,!1),s=er(s,e.entry_flow.reduction_block_1),X(this._numMainBlocks,0,1).forEach(c=>{s=Ro(s,e.middle_flow[`main_block_${c}`])}),s=er(s,e.exit_flow.reduction_block),s=n.relu(S(s,e.exit_flow.separable_conv,[1,1])),s})}async forward(t){return this.forwardInput(await F(t))}getDefaultModelName(){return"tiny_xception_model"}extractParamsFromWeightMap(t){return kr(t,this._numMainBlocks)}extractParams(t){return Wr(t,this._numMainBlocks)}};function Rr(o){let t=[],{extractWeights:e,getRemainingWeights:r}=L(o),a=ve(e,t),i=a(512,1,"fc/age"),s=a(512,2,"fc/gender");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{fc:{age:i,gender:s}}}}function $r(o){let t=[],e=k(o,t);function r(i){let s=e(`${i}/weights`,2),c=e(`${i}/bias`,1);return{weights:s,bias:c}}let a={fc:{age:r("fc/age"),gender:r("fc/gender")}};return N(o,t),{params:a,paramMappings:t}}var rr=(e=>(e.FEMALE="female",e.MALE="male",e))(rr||{});var Me=class extends I{constructor(t=new Ee(2)){super("AgeGenderNet"),this._faceFeatureExtractor=t}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){let{params:e}=this;if(!e)throw new Error(`${this._name} - load model before inference`);return n.tidy(()=>{let r=t instanceof tt?this.faceFeatureExtractor.forwardInput(t):t,a=n.avgPool(r,[7,7],[2,2],"valid").as2D(r.shape[0],-1),i=se(a,e.fc.age).as1D(),s=se(a,e.fc.gender);return{age:i,gender:s}})}forwardInput(t){return n.tidy(()=>{let{age:e,gender:r}=this.runNet(t);return{age:e,gender:n.softmax(r)}})}async forward(t){return this.forwardInput(await F(t))}async predictAgeAndGender(t){let e=await F(t),r=await this.forwardInput(e),a=n.unstack(r.age),i=n.unstack(r.gender),s=a.map((m,p)=>({ageTensor:m,genderTensor:i[p]})),c=await Promise.all(s.map(async({ageTensor:m,genderTensor:p})=>{let u=m.dataSync()[0],f=p.dataSync()[0],l=f>.5,d=l?"male":"female",b=l?f:1-f;return m.dispose(),p.dispose(),{age:u,gender:d,genderProbability:b}}));return r.age.dispose(),r.gender.dispose(),e.isBatchInput?c:c[0]}getDefaultModelName(){return"age_gender_model"}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){let{params:e,paramMappings:r}=this.extractClassifierParams(t);this._params=e,this._paramMappings=r}extractClassifierParams(t){return Rr(t)}extractParamsFromWeightMap(t){let{featureExtractorMap:e,classifierMap:r}=Pe(t);return this.faceFeatureExtractor.loadFromWeightMap(e),$r(r)}extractParams(t){let r=t.slice(0,t.length-1539),a=t.slice(t.length-1539);return this.faceFeatureExtractor.extractWeights(r),this.extractClassifierParams(a)}};var Vt=class extends zt{postProcess(t,e,r){let a=r.map(({width:s,height:c})=>{let m=e/Math.max(c,s);return{width:s*m,height:c*m}}),i=a.length;return n.tidy(()=>{let s=(f,l)=>n.stack([n.fill([68],f,"float32"),n.fill([68],l,"float32")],1).as2D(1,136).as1D(),c=(f,l)=>{let{width:d,height:b}=a[f];return l(d,b)?Math.abs(d-b)/2:0},m=f=>c(f,(l,d)=>l<d),p=f=>c(f,(l,d)=>d<l);return t.mul(n.fill([i,136],e,"float32")).sub(n.stack(Array.from(Array(i),(f,l)=>s(m(l),p(l))))).div(n.stack(Array.from(Array(i),(f,l)=>s(a[l].width,a[l].height))))})}forwardInput(t){return n.tidy(()=>{let e=this.runNet(t);return this.postProcess(e,t.inputSize,t.inputDimensions.map(([r,a])=>({height:r,width:a})))})}async forward(t){return this.forwardInput(await F(t))}async detectLandmarks(t){let e=await F(t),r=n.tidy(()=>n.unstack(this.forwardInput(e))),a=await Promise.all(r.map(async(i,s)=>{let c=Array.from(i.dataSync()),m=c.filter((u,f)=>pe(f)),p=c.filter((u,f)=>!pe(f));return new Lt(Array(68).fill(0).map((u,f)=>new v(m[f],p[f])),{height:e.getInputHeight(s),width:e.getInputWidth(s)})}));return r.forEach(i=>i.dispose()),e.isBatchInput?a:a[0]}getClassifierChannelsOut(){return 136}};var Gt=class extends Vt{constructor(t=new Ht){super("FaceLandmark68Net",t)}getDefaultModelName(){return"face_landmark_68_model"}getClassifierChannelsIn(){return 256}};function Or(o){let t=[],{extractDenseBlock3Params:e}=_e(o,t),r={dense0:e("dense0",!0),dense1:e("dense1"),dense2:e("dense2")};return N(o,t),{params:r,paramMappings:t}}function Hr(o){let t=[],{extractWeights:e,getRemainingWeights:r}=L(o),{extractDenseBlock3Params:a}=ye(e,t),i=a(3,32,"dense0",!0),s=a(32,64,"dense1"),c=a(64,128,"dense2");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:t,params:{dense0:i,dense1:s,dense2:c}}}var Ce=class extends I{constructor(){super("TinyFaceFeatureExtractor")}forwardInput(t){let{params:e}=this;if(!e)throw new Error("TinyFaceFeatureExtractor - load model before inference");return n.tidy(()=>{let r=n.cast(t.toBatchTensor(112,!0),"float32"),i=J(r,[122.782,117.001,104.298]).div(255),s=xe(i,e.dense0,!0);return s=xe(s,e.dense1),s=xe(s,e.dense2),s=n.avgPool(s,[14,14],[2,2],"valid"),s})}async forward(t){return this.forwardInput(await F(t))}getDefaultModelName(){return"face_feature_extractor_tiny_model"}extractParamsFromWeightMap(t){return Or(t)}extractParams(t){return Hr(t)}};var Ie=class extends Vt{constructor(t=new Ce){super("FaceLandmark68TinyNet",t)}getDefaultModelName(){return"face_landmark_68_tiny_model"}getClassifierChannelsIn(){return 128}};var zr=class extends Gt{};function Yr(o,t){return n.add(n.mul(o,t.weights),t.biases)}function or(o,t,e,r,a="same"){let{filters:i,bias:s}=t.conv,c=n.conv2d(o,i,e,a);return c=n.add(c,s),c=Yr(c,t.scale),r?n.relu(c):c}function Vr(o,t){return or(o,t,[1,1],!0)}function nr(o,t){return or(o,t,[1,1],!1)}function Ne(o,t){return or(o,t,[2,2],!0,"valid")}function $o(o,t){function e(c,m,p){let u=o(c),f=u.length/(m*p*p);if(Ge(f))throw new Error(`depth has to be an integer: ${f}, weights.length: ${u.length}, numFilters: ${m}, filterSize: ${p}`);return n.tidy(()=>n.transpose(n.tensor4d(u,[m,f,p,p]),[2,3,1,0]))}function r(c,m,p,u){let f=e(c,m,p),l=n.tensor1d(o(m));return t.push({paramPath:`${u}/filters`},{paramPath:`${u}/bias`}),{filters:f,bias:l}}function a(c,m){let p=n.tensor1d(o(c)),u=n.tensor1d(o(c));return t.push({paramPath:`${m}/weights`},{paramPath:`${m}/biases`}),{weights:p,biases:u}}function i(c,m,p,u){let f=r(c,m,p,`${u}/conv`),l=a(m,`${u}/scale`);return{conv:f,scale:l}}function s(c,m,p,u,f=!1){let l=i((f?.5:1)*c,m,p,`${u}/conv1`),d=i(c,m,p,`${u}/conv2`);return{conv1:l,conv2:d}}return{extractConvLayerParams:i,extractResidualLayerParams:s}}function Gr(o){let{extractWeights:t,getRemainingWeights:e}=L(o),r=[],{extractConvLayerParams:a,extractResidualLayerParams:i}=$o(t,r),s=a(4704,32,7,"conv32_down"),c=i(9216,32,3,"conv32_1"),m=i(9216,32,3,"conv32_2"),p=i(9216,32,3,"conv32_3"),u=i(36864,64,3,"conv64_down",!0),f=i(36864,64,3,"conv64_1"),l=i(36864,64,3,"conv64_2"),d=i(36864,64,3,"conv64_3"),b=i(147456,128,3,"conv128_down",!0),y=i(147456,128,3,"conv128_1"),h=i(147456,128,3,"conv128_2"),g=i(589824,256,3,"conv256_down",!0),T=i(589824,256,3,"conv256_1"),x=i(589824,256,3,"conv256_2"),E=i(589824,256,3,"conv256_down_out"),B=n.tidy(()=>n.transpose(n.tensor2d(t(256*128),[128,256]),[1,0]));if(r.push({paramPath:"fc"}),e().length!==0)throw new Error(`weights remaing after extract: ${e().length}`);return{params:{conv32_down:s,conv32_1:c,conv32_2:m,conv32_3:p,conv64_down:u,conv64_1:f,conv64_2:l,conv64_3:d,conv128_down:b,conv128_1:y,conv128_2:h,conv256_down:g,conv256_1:T,conv256_2:x,conv256_down_out:E,fc:B},paramMappings:r}}function Oo(o,t){let e=k(o,t);function r(s){let c=e(`${s}/scale/weights`,1),m=e(`${s}/scale/biases`,1);return{weights:c,biases:m}}function a(s){let c=e(`${s}/conv/filters`,4),m=e(`${s}/conv/bias`,1),p=r(s);return{conv:{filters:c,bias:m},scale:p}}function i(s){return{conv1:a(`${s}/conv1`),conv2:a(`${s}/conv2`)}}return{extractConvLayerParams:a,extractResidualLayerParams:i}}function jr(o){let t=[],{extractConvLayerParams:e,extractResidualLayerParams:r}=Oo(o,t),a=e("conv32_down"),i=r("conv32_1"),s=r("conv32_2"),c=r("conv32_3"),m=r("conv64_down"),p=r("conv64_1"),u=r("conv64_2"),f=r("conv64_3"),l=r("conv128_down"),d=r("conv128_1"),b=r("conv128_2"),y=r("conv256_down"),h=r("conv256_1"),g=r("conv256_2"),T=r("conv256_down_out"),{fc:x}=o;if(t.push({originalPath:"fc",paramPath:"fc"}),!Ve(x))throw new Error(`expected weightMap[fc] to be a Tensor2D, instead have ${x}`);let E={conv32_down:a,conv32_1:i,conv32_2:s,conv32_3:c,conv64_down:m,conv64_1:p,conv64_2:u,conv64_3:f,conv128_down:l,conv128_1:d,conv128_2:b,conv256_down:y,conv256_1:h,conv256_2:g,conv256_down_out:T,fc:x};return N(o,t),{params:E,paramMappings:t}}function j(o,t){let e=Vr(o,t.conv1);return e=nr(e,t.conv2),e=n.add(e,o),e=n.relu(e),e}function ce(o,t){let e=Ne(o,t.conv1);e=nr(e,t.conv2);let r=n.avgPool(o,2,2,"valid"),a=n.zeros(r.shape),i=r.shape[3]!==e.shape[3];if(r.shape[1]!==e.shape[1]||r.shape[2]!==e.shape[2]){let c=[...e.shape];c[1]=1;let m=n.zeros(c);e=n.concat([e,m],1);let p=[...e.shape];p[2]=1;let u=n.zeros(p);e=n.concat([e,u],2)}return r=i?n.concat([r,a],3):r,e=n.add(r,e),e=n.relu(e),e}var jt=class extends I{constructor(){super("FaceRecognitionNet")}forwardInput(t){let{params:e}=this;if(!e)throw new Error("FaceRecognitionNet - load model before inference");return n.tidy(()=>{let r=n.cast(t.toBatchTensor(150,!0),"float32"),i=J(r,[122.782,117.001,104.298]).div(255),s=Ne(i,e.conv32_down);s=n.maxPool(s,3,2,"valid"),s=j(s,e.conv32_1),s=j(s,e.conv32_2),s=j(s,e.conv32_3),s=ce(s,e.conv64_down),s=j(s,e.conv64_1),s=j(s,e.conv64_2),s=j(s,e.conv64_3),s=ce(s,e.conv128_down),s=j(s,e.conv128_1),s=j(s,e.conv128_2),s=ce(s,e.conv256_down),s=j(s,e.conv256_1),s=j(s,e.conv256_2),s=ce(s,e.conv256_down_out);let c=s.mean([1,2]);return n.matMul(c,e.fc)})}async forward(t){return this.forwardInput(await F(t))}async computeFa