3 lines
82 KiB
JavaScript
3 lines
82 KiB
JavaScript
var faceapi=(()=>{var Ge=Object.defineProperty,Yn=Object.prototype.hasOwnProperty,mr=(t,e)=>()=>(e||(e={exports:{}},t(e.exports,e)),e.exports),fr=t=>Ge(t,"__esModule",{value:!0}),He=(t,e)=>{fr(t);for(var o in e)Ge(t,o,{get:e[o],enumerable:!0})},Vn=(t,e)=>{if(fr(t),typeof e=="object"||typeof e=="function")for(let o in e)!Yn.call(t,o)&&o!=="default"&&Ge(t,o,{get:()=>e[o],enumerable:!0});return t},x=t=>t&&t.__esModule?t:Vn(Ge({},"default",{value:t,enumerable:!0}),t);var lr=mr((Jn,dr)=>{He(Jn,{isNodejs:()=>Xn});function Xn(){return typeof global=="object"&&!0&&typeof dr!="undefined"&&typeof process!="undefined"&&!!process.version}});var Zr=mr(qn=>{He(qn,{AgeGenderNet:()=>vo,BoundingBox:()=>se,Box:()=>T,ComposableTask:()=>Z,ComputeAllFaceDescriptorsTask:()=>Ft,ComputeFaceDescriptorsTaskBase:()=>ao,ComputeSingleFaceDescriptorTask:()=>Mt,DetectAllFaceLandmarksTask:()=>no,DetectAllFacesTask:()=>Te,DetectFaceLandmarksTaskBase:()=>ro,DetectFacesTaskBase:()=>eo,DetectSingleFaceLandmarksTask:()=>so,DetectSingleFaceTask:()=>oo,Dimensions:()=>B,FACE_EXPRESSION_LABELS:()=>po,FaceDetection:()=>D,FaceDetectionNet:()=>_r,FaceExpressionNet:()=>mo,FaceExpressions:()=>Pt,FaceLandmark68Net:()=>te,FaceLandmark68TinyNet:()=>co,FaceLandmarkNet:()=>Hr,FaceLandmarks:()=>G,FaceLandmarks5:()=>qr,FaceLandmarks68:()=>ne,FaceMatch:()=>Re,FaceMatcher:()=>Vo,FaceRecognitionNet:()=>Qt,Gender:()=>ct,LabeledBox:()=>Ce,LabeledFaceDescriptors:()=>Ct,NetInput:()=>lt,NeuralNetwork:()=>R,ObjectDetection:()=>zt,Point:()=>w,PredictedBox:()=>Xr,Rect:()=>re,SsdMobilenetv1:()=>Bt,SsdMobilenetv1Options:()=>X,TinyFaceDetector:()=>Zt,TinyFaceDetectorOptions:()=>qe,TinyYolov2:()=>qt,TinyYolov2Options:()=>it,TinyYolov2SizeType:()=>Xe,allFaces:()=>$r,allFacesSsdMobilenetv1:()=>Yo,allFacesTinyYolov2:()=>Ir,awaitMediaLoaded:()=>wo,bufferToImage:()=>xo,computeFaceDescriptor:()=>Lr,createCanvas:()=>Ot,createCanvasFromMedia:()=>oe,createFaceDetectionNet:()=>vr,createFaceRecognitionNet:()=>Gr,createSsdMobilenetv1:()=>$o,createTinyFaceDetector:()=>wr,createTinyYolov2:()=>xr,detectAllFaces:()=>Me,detectFaceLandmarks:()=>Go,detectFaceLandmarksTiny:()=>Tr,detectLandmarks:()=>Br,detectSingleFace:()=>Ur,draw:()=>Ye,env:()=>F,euclideanDistance:()=>fo,extendWithAge:()=>De,extendWithFaceDescriptor:()=>Ee,extendWithFaceDetection:()=>Lt,extendWithFaceExpressions:()=>Pe,extendWithFaceLandmarks:()=>Ut,extendWithGender:()=>Le,extractFaceTensors:()=>$t,extractFaces:()=>It,fetchImage:()=>Jr,fetchJson:()=>go,fetchNetWeights:()=>Vr,fetchOrThrow:()=>kt,getContext2dOrThrow:()=>A,getMediaDimensions:()=>Dt,imageTensorToCanvas:()=>uo,imageToSquare:()=>ho,inverseSigmoid:()=>yr,iou:()=>to,isMediaElement:()=>ke,isMediaLoaded:()=>ee,isWithAge:()=>zr,isWithFaceDetection:()=>ot,isWithFaceExpressions:()=>io,isWithFaceLandmarks:()=>Tt,isWithGender:()=>Or,loadAgeGenderModel:()=>jr,loadFaceDetectionModel:()=>Nr,loadFaceExpressionModel:()=>Sr,loadFaceLandmarkModel:()=>Cr,loadFaceLandmarkTinyModel:()=>Rr,loadFaceRecognitionModel:()=>Ar,loadSsdMobilenetv1Model:()=>Ho,loadTinyFaceDetectorModel:()=>Dr,loadTinyYolov2Model:()=>kr,loadWeightMap:()=>lo,locateFaces:()=>Wr,matchDimensions:()=>Yr,minBbox:()=>Qe,nets:()=>y,nonMaxSuppression:()=>Ke,normalize:()=>q,padToSquare:()=>Ze,predictAgeAndGender:()=>Er,recognizeFaceExpressions:()=>Pr,resizeResults:()=>Oo,resolveInput:()=>Et,shuffleArray:()=>br,sigmoid:()=>Kt,ssdMobilenetv1:()=>zo,tf:()=>hr,tinyFaceDetector:()=>Fr,tinyYolov2:()=>Mr,toNetInput:()=>M,utils:()=>Ve,validateConfig:()=>Je,version:()=>gr});const hr=x(require("@tensorflow/tfjs")),Zn=typeof process!="undefined"?process.version:!1,Kn=typeof navigator!="undefined"?navigator.userAgent:!1,gr={faceapi:ur,node:Zn,browser:Kn}});function ht(t,e,o=!1){if(t.beginPath(),e.slice(1).forEach(({x:r,y:n},s)=>{const i=e[s];t.moveTo(i.x,i.y),t.lineTo(r,n)}),o){const r=e[e.length-1],n=e[0];if(!r||!n)return;t.moveTo(r.x,r.y),t.lineTo(n.x,n.y)}t.stroke()}class B{constructor(t,e){if(!rt(t)||!rt(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 B(1/this.width,1/this.height)}}const Ve={};He(Ve,{computeReshapedDimensions:()=>qo,getCenterPoint:()=>Yt,isDimensions:()=>bo,isEven:()=>_o,isFloat:()=>Xo,isTensor:()=>Gt,isTensor1D:()=>Qn,isTensor2D:()=>Jo,isTensor3D:()=>ut,isTensor4D:()=>H,isValidNumber:()=>rt,isValidProbablitiy:()=>ae,range:()=>pt,round:()=>Ht});const Kr=x(require("@tensorflow/tfjs"));function Gt(t,e){return t instanceof Kr.Tensor&&t.shape.length===e}function Qn(t){return Gt(t,1)}function Jo(t){return Gt(t,2)}function ut(t){return Gt(t,3)}function H(t){return Gt(t,4)}function Xo(t){return t%1!==0}function _o(t){return t%2===0}function Ht(t,e=2){const o=Math.pow(10,e);return Math.floor(t*o)/o}function bo(t){return t&&t.width&&t.height}function qo({width:t,height:e},o){const r=o/Math.max(e,t);return new B(Math.round(t*r),Math.round(e*r))}function Yt(t){return t.reduce((e,o)=>e.add(o),new w(0,0)).div(new w(t.length,t.length))}function pt(t,e,o){return Array(t).fill(0).map((r,n)=>e+n*o)}function rt(t){return!!t&&t!==Infinity&&t!==-Infinity&&!isNaN(t)||t===0}function ae(t){return rt(t)&&0<=t&&t<=1}class w{constructor(t,e){this._x=t,this._y=e}get x(){return this._x}get y(){return this._y}add(t){return new w(this.x+t.x,this.y+t.y)}sub(t){return new w(this.x-t.x,this.y-t.y)}mul(t){return new w(this.x*t.x,this.y*t.y)}div(t){return new w(this.x/t.x,this.y/t.y)}abs(){return new w(Math.abs(this.x),Math.abs(this.y))}magnitude(){return Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2))}floor(){return new w(Math.floor(this.x),Math.floor(this.y))}}class T{constructor(t,e=!0){const o=t||{},r=[o.left,o.top,o.right,o.bottom].every(rt),n=[o.x,o.y,o.width,o.height].every(rt);if(!n&&!r)throw new Error(`Box.constructor - expected box to be IBoundingBox | IRect, instead have ${JSON.stringify(o)}`);const[s,i,a,c]=n?[o.x,o.y,o.width,o.height]:[o.left,o.top,o.right-o.left,o.bottom-o.top];T.assertIsValidBox({x:s,y:i,width:a,height:c},"Box.constructor",e),this._x=s,this._y=i,this._width=a,this._height=c}static isRect(t){return!!t&&[t.x,t.y,t.width,t.height].every(rt)}static assertIsValidBox(t,e,o=!1){if(!T.isRect(t))throw new Error(`${e} - invalid box: ${JSON.stringify(t)}, expected object with properties x, y, width, height`);if(!o&&(t.width<0||t.height<0))throw new Error(`${e} - width (${t.width}) and height (${t.height}) must be positive numbers`)}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 w(this.left,this.top)}get topRight(){return new w(this.right,this.top)}get bottomLeft(){return new w(this.left,this.bottom)}get bottomRight(){return new w(this.right,this.bottom)}round(){const[t,e,o,r]=[this.x,this.y,this.width,this.height].map(n=>Math.round(n));return new T({x:t,y:e,width:o,height:r})}floor(){const[t,e,o,r]=[this.x,this.y,this.width,this.height].map(n=>Math.floor(n));return new T({x:t,y:e,width:o,height:r})}toSquare(){let{x:t,y:e,width:o,height:r}=this;const n=Math.abs(o-r);return o<r&&(t-=n/2,o+=n),r<o&&(e-=n/2,r+=n),new T({x:t,y:e,width:o,height:r})}rescale(t){const e=bo(t)?t.width:t,o=bo(t)?t.height:t;return new T({x:this.x*e,y:this.y*o,width:this.width*e,height:this.height*o})}pad(t,e){let[o,r,n,s]=[this.x-t/2,this.y-e/2,this.width+t,this.height+e];return new T({x:o,y:r,width:n,height:s})}clipAtImageBorders(t,e){const{x:o,y:r,right:n,bottom:s}=this,i=Math.max(o,0),a=Math.max(r,0),c=n-i,p=s-a,m=Math.min(c,t-i),f=Math.min(p,e-a);return new T({x:i,y:a,width:m,height:f}).floor()}shift(t,e){const{width:o,height:r}=this,n=this.x+t,s=this.y+e;return new T({x:n,y:s,width:o,height:r})}padAtBorders(t,e){const o=this.width+1,r=this.height+1;let n=1,s=1,i=o,a=r,c=this.left,p=this.top,m=this.right,f=this.bottom;return m>e&&(i=-m+e+o,m=e),f>t&&(a=-f+t+r,f=t),c<1&&(a=2-c,c=1),p<1&&(a=2-p,p=1),{dy:s,edy:a,dx:n,edx:i,y:p,ey:f,x:c,ex:m,w:o,h:r}}calibrate(t){return new T({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()}}class se extends T{constructor(t,e,o,r,n=!1){super({left:t,top:e,right:o,bottom:r},n)}}class zt{constructor(t,e,o,r,n){this._imageDims=new B(n.width,n.height),this._score=t,this._classScore=e,this._className=o,this._box=new T(r).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 T(this._box).rescale(this.imageDims.reverse())}forSize(t,e){return new zt(this.score,this.classScore,this.className,this.relativeBox,{width:t,height:e})}}class D extends zt{constructor(t,e,o){super(t,t,"",e,o)}forSize(t,e){const{score:o,relativeBox:r,imageDims:n}=super.forSize(t,e);return new D(o,r,n)}}function to(t,e,o=!0){const r=Math.max(0,Math.min(t.right,e.right)-Math.max(t.left,e.left)),n=Math.max(0,Math.min(t.bottom,e.bottom)-Math.max(t.top,e.top)),s=r*n;return o?s/(t.area+e.area-s):s/Math.min(t.area,e.area)}function Qe(t){const e=t.map(a=>a.x),o=t.map(a=>a.y),r=e.reduce((a,c)=>c<a?c:a,Infinity),n=o.reduce((a,c)=>c<a?c:a,Infinity),s=e.reduce((a,c)=>a<c?c:a,0),i=o.reduce((a,c)=>a<c?c:a,0);return new se(r,n,s,i)}function Ke(t,e,o,r=!0){let n=e.map((i,a)=>({score:i,boxIndex:a})).sort((i,a)=>i.score-a.score).map(i=>i.boxIndex);const s=[];for(;n.length>0;){const i=n.pop();s.push(i);const a=n,c=[];for(let p=0;p<a.length;p++){const m=a[p],f=t[i],d=t[m];c.push(to(f,d,r))}n=n.filter((p,m)=>c[m]<=o)}return s}const mt=x(require("@tensorflow/tfjs"));function q(t,e){return mt.tidy(()=>{const[o,r,n]=e,s=mt.fill([...t.shape.slice(0,3),1],o),i=mt.fill([...t.shape.slice(0,3),1],r),a=mt.fill([...t.shape.slice(0,3),1],n),c=mt.concat([s,i,a],3);return mt.sub(t,c)})}const Rt=x(require("@tensorflow/tfjs"));function Ze(t,e=!1){return Rt.tidy(()=>{const[o,r]=t.shape.slice(1);if(o===r)return t;const n=Math.abs(o-r),s=Math.round(n*(e?.5:1)),i=o>r?2:1,a=d=>{const h=t.shape.slice();return h[i]=d,Rt.fill(h,0)},c=a(s),p=n-c.shape[i],m=e&&p?a(p):null,f=[m,t,c].filter(d=>!!d).map(d=>Rt.cast(d,"float32"));return Rt.concat(f,i)})}function br(t){const e=t.slice();for(let o=e.length-1;o>0;o--){const r=Math.floor(Math.random()*(o+1)),n=e[o];e[o]=e[r],e[r]=n}return e}function Kt(t){return 1/(1+Math.exp(-t))}function yr(t){return Math.log(t/(1-t))}class re extends T{constructor(t,e,o,r,n=!1){super({x:t,y:e,width:o,height:r},n)}}const ts=.5,es=.43,os=.45;class G{constructor(t,e,o=new w(0,0)){const{width:r,height:n}=e;this._imgDims=new B(r,n),this._shift=o,this._positions=t.map(s=>s.mul(new w(r,n)).add(o))}get shift(){return new w(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 w(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 w(t,e))}shiftByPoint(t){return this.shiftBy(t.x,t.y)}align(t,e={}){if(t){const n=t instanceof D?t.box.floor():new T(t);return this.shiftBy(n.x,n.y).align(null,e)}const{useDlibAlignment:o,minBoxPadding:r}=Object.assign({},{useDlibAlignment:!1,minBoxPadding:.2},e);return o?this.alignDlib():this.alignMinBbox(r)}alignDlib(){const t=this.getRefPointsForAlignment(),[e,o,r]=t,n=m=>r.sub(m).magnitude(),s=(n(e)+n(o))/2,i=Math.floor(s/os),a=Yt(t),c=Math.floor(Math.max(0,a.x-ts*i)),p=Math.floor(Math.max(0,a.y-es*i));return new re(c,p,Math.min(i,this.imageWidth+c),Math.min(i,this.imageHeight+p))}alignMinBbox(t){const e=Qe(this.positions);return e.pad(e.width*t,e.height*t)}getRefPointsForAlignment(){throw new Error("getRefPointsForAlignment not implemented by base class")}}class qr extends G{getRefPointsForAlignment(){const t=this.positions;return[t[0],t[1],Yt([t[3],t[4]])]}}class ne extends G{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(Yt)}}class Re{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)})`:""}`}}class Ce extends T{constructor(t,e){super(t);this._label=e}static assertIsValidLabeledBox(t,e){if(T.assertIsValidBox(t,e),!rt(t.label))throw new Error(`${e} - expected property label (${t.label}) to be a number`)}get label(){return this._label}}class Ct{constructor(t,e){if(!(typeof t=="string"))throw new Error("LabeledFaceDescriptors - constructor expected label to be a string");if(!Array.isArray(e)||e.some(o=>!(o 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){const e=t.descriptors.map(o=>new Float32Array(o));return new Ct(t.label,e)}}class Xr extends Ce{constructor(t,e,o,r){super(t,e);this._score=o,this._classScore=r}static assertIsValidPredictedBox(t,e){if(Ce.assertIsValidLabeledBox(t,e),!ae(t.score)||!ae(t.classScore))throw new Error(`${e} - expected properties score (${t.score}) and (${t.classScore}) to be a number between [0, 1]`)}get score(){return this._score}get classScore(){return this._classScore}}function ot(t){return t.detection instanceof D}function Lt(t,e){const o={detection:e};return Object.assign({},t,o)}function Zo(){const t=window.fetch||function(){throw new Error("fetch - missing fetch implementation for browser environment")},e=function(){throw new Error("readFile - filesystem not available for browser environment")};return{Canvas:HTMLCanvasElement,CanvasRenderingContext2D,Image:HTMLImageElement,ImageData,Video:HTMLVideoElement,createCanvasElement:()=>document.createElement("canvas"),createImageElement:()=>document.createElement("img"),fetch:t,readFile:e}}function yo(t){let e="";if(!t)try{t=require("fs")}catch(r){e=r.toString()}const o=t?function(r){return new Promise((n,s)=>{t.readFile(r,function(i,a){return i?s(i):n(a)})})}:function(){throw new Error(`readFile - failed to require fs in nodejs environment with error: ${e}`)};return{readFile:o}}function Ko(){const t=global.Canvas||global.HTMLCanvasElement,e=global.Image||global.HTMLImageElement,o=function(){if(t)return new t;throw new Error("createCanvasElement - missing Canvas implementation for nodejs environment")},r=function(){if(e)return new e;throw new Error("createImageElement - missing Image implementation for nodejs environment")},n=global.fetch||function(){throw new Error("fetch - missing fetch implementation for nodejs environment")},s=yo();return{Canvas:t||class{},CanvasRenderingContext2D:global.CanvasRenderingContext2D||class{},Image:e||class{},ImageData:global.ImageData||class{},Video:global.HTMLVideoElement||class{},createCanvasElement:o,createImageElement:r,fetch:n,...s}}function Qo(){return typeof window=="object"&&typeof document!="undefined"&&typeof HTMLImageElement!="undefined"&&typeof HTMLCanvasElement!="undefined"&&typeof HTMLVideoElement!="undefined"&&typeof ImageData!="undefined"&&typeof CanvasRenderingContext2D!="undefined"}const tr=x(lr());let C;function rs(){if(!C)throw new Error("getEnv - environment is not defined, check isNodejs() and isBrowser()");return C}function er(t){C=t}function or(){if(Qo())return er(Zo());if(tr.isNodejs())return er(Ko())}function ns(t){if(C||or(),!C)throw new Error("monkeyPatch - environment is not defined, check isNodejs() and isBrowser()");const{Canvas:e=C.Canvas,Image:o=C.Image}=t;C.Canvas=e,C.Image=o,C.createCanvasElement=t.createCanvasElement||(()=>new e),C.createImageElement=t.createImageElement||(()=>new o),C.ImageData=t.ImageData||C.ImageData,C.Video=t.Video||C.Video,C.fetch=t.fetch||C.fetch,C.readFile=t.readFile||C.readFile}const F={getEnv:rs,setEnv:er,initialize:or,createBrowserEnv:Zo,createFileSystem:yo,createNodejsEnv:Ko,monkeyPatch:ns,isBrowser:Qo,isNodejs:tr.isNodejs};or();function Et(t){return!F.isNodejs()&&typeof t=="string"?document.getElementById(t):t}function A(t){const{Canvas:e,CanvasRenderingContext2D:o}=F.getEnv();if(t instanceof o)return t;const r=Et(t);if(!(r instanceof e))throw new Error("resolveContext2d - expected canvas to be of instance of Canvas");const n=r.getContext("2d");if(!n)throw new Error("resolveContext2d - canvas 2d context is null");return n}var ft;(function(t){t.TOP_LEFT="TOP_LEFT",t.TOP_RIGHT="TOP_RIGHT",t.BOTTOM_LEFT="BOTTOM_LEFT",t.BOTTOM_RIGHT="BOTTOM_RIGHT"})(ft||(ft={}));class Fo{constructor(t={}){const{anchorPosition:e,backgroundColor:o,fontColor:r,fontSize:n,fontStyle:s,padding:i}=t;this.anchorPosition=e||ft.TOP_LEFT,this.backgroundColor=o||"rgba(0, 0, 0, 0.5)",this.fontColor=r||"rgba(255, 255, 255, 1)",this.fontSize=n||14,this.fontStyle=s||"Georgia",this.padding=i||4}}class ie{constructor(t,e,o={}){this.text=typeof t=="string"?[t]:t instanceof ie?t.text:t,this.anchor=e,this.options=new Fo(o)}measureWidth(t){const{padding:e}=this.options;return this.text.map(o=>t.measureText(o).width).reduce((o,r)=>o<r?r:o,0)+2*e}measureHeight(){const{fontSize:t,padding:e}=this.options;return this.text.length*t+2*e}getUpperLeft(t,e){const{anchorPosition:o}=this.options,r=o===ft.BOTTOM_RIGHT||o===ft.TOP_RIGHT,n=o===ft.BOTTOM_LEFT||o===ft.BOTTOM_RIGHT,s=this.measureWidth(t),i=this.measureHeight(),a=r?this.anchor.x-s:this.anchor.x,c=n?this.anchor.y-i:this.anchor.y;if(e){const{width:p,height:m}=e,f=Math.max(Math.min(a,p-s),0),d=Math.max(Math.min(c,m-i),0);return{x:f,y:d}}return{x:a,y:c}}draw(t){const e=Et(t),o=A(e),{backgroundColor:r,fontColor:n,fontSize:s,fontStyle:i,padding:a}=this.options;o.font=`${s}px ${i}`;const c=this.measureWidth(o),p=this.measureHeight();o.fillStyle=r;const m=this.getUpperLeft(o,e);o.fillRect(m.x,m.y,c,p),o.fillStyle=n,this.text.forEach((f,d)=>{const h=a+m.x,b=a+m.y+(d+1)*s;o.fillText(f,h,b)})}}class Qr{constructor(t={}){const{boxColor:e,lineWidth:o,label:r,drawLabelOptions:n}=t;this.boxColor=e||"rgba(0, 0, 255, 1)",this.lineWidth=o||2,this.label=r;const s={anchorPosition:ft.BOTTOM_LEFT,backgroundColor:this.boxColor};this.drawLabelOptions=new Fo(Object.assign({},s,n))}}class rr{constructor(t,e={}){this.box=new T(t),this.options=new Qr(e)}draw(t){const e=A(t),{boxColor:o,lineWidth:r}=this.options,{x:n,y:s,width:i,height:a}=this.box;e.strokeStyle=o,e.lineWidth=r,e.strokeRect(n,s,i,a);const{label:c}=this.options;c&&new ie([c],{x:n-r/2,y:s},this.options.drawLabelOptions).draw(t)}}function ss(t,e){const o=Array.isArray(e)?e:[e];o.forEach(r=>{const n=r instanceof D?r.score:ot(r)?r.detection.score:void 0,s=r instanceof D?r.box:ot(r)?r.detection.box:new T(r),i=n?`${Ht(n)}`:void 0;new rr(s,{label:i}).draw(t)})}function ee(t){const{Image:e,Video:o}=F.getEnv();return t instanceof e&&t.complete||t instanceof o&&t.readyState>=3}function wo(t){return new Promise((e,o)=>{if(t instanceof F.getEnv().Canvas||ee(t))return e(null);function r(s){if(!s.currentTarget)return;s.currentTarget.removeEventListener("load",r),s.currentTarget.removeEventListener("error",n),e(s)}function n(s){if(!s.currentTarget)return;s.currentTarget.removeEventListener("load",r),s.currentTarget.removeEventListener("error",n),o(s)}t.addEventListener("load",r),t.addEventListener("error",n)})}function xo(t){return new Promise((e,o)=>{if(!(t instanceof Blob))return o("bufferToImage - expected buf to be of type: Blob");const r=new FileReader;r.onload=()=>{if(typeof r.result!="string")return o("bufferToImage - expected reader.result to be a string, in onload");const n=F.getEnv().createImageElement();n.onload=()=>e(n),n.onerror=o,n.src=r.result},r.onerror=o,r.readAsDataURL(t)})}function Dt(t){const{Image:e,Video:o}=F.getEnv();return t instanceof e?new B(t.naturalWidth,t.naturalHeight):t instanceof o?new B(t.videoWidth,t.videoHeight):new B(t.width,t.height)}function Ot({width:t,height:e}){const{createCanvasElement:o}=F.getEnv(),r=o();return r.width=t,r.height=e,r}function oe(t,e){const{ImageData:o}=F.getEnv();if(!(t instanceof o)&&!ee(t))throw new Error("createCanvasFromMedia - media has not finished loading yet");const{width:r,height:n}=e||Dt(t),s=Ot({width:r,height:n});return t instanceof o?A(s).putImageData(t,0,0):A(s).drawImage(t,0,0,r,n),s}const Mo=x(require("@tensorflow/tfjs"));async function uo(t,e){const o=e||F.getEnv().createCanvasElement(),[r,n,s]=t.shape.slice(H(t)?1:0),i=Mo.tidy(()=>t.as3D(r,n,s).toInt());return await Mo.browser.toPixels(i,o),i.dispose(),o}function ke(t){const{Image:e,Canvas:o,Video:r}=F.getEnv();return t instanceof e||t instanceof o||t instanceof r}function ho(t,e,o=!1){const{Image:r,Canvas:n}=F.getEnv();if(!(t instanceof r||t instanceof n))throw new Error("imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement");const s=Dt(t),i=e/Math.max(s.height,s.width),a=i*s.width,c=i*s.height,p=Ot({width:e,height:e}),m=t instanceof n?t:oe(t),f=Math.abs(a-c)/2,d=o&&a<c?f:0,h=o&&c<a?f:0;return A(p).drawImage(m,d,h,a,c),p}const K=x(require("@tensorflow/tfjs"));class lt{constructor(t,e=!1){if(this._imageTensors=[],this._canvases=[],this._treatAsBatchInput=!1,this._inputDimensions=[],!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((o,r)=>{if(ut(o)){this._imageTensors[r]=o,this._inputDimensions[r]=o.shape;return}if(H(o)){const s=o.shape[0];if(s!==1)throw new Error(`NetInput - tf.Tensor4D with batchSize ${s} passed, but not supported in input array`);this._imageTensors[r]=o,this._inputDimensions[r]=o.shape.slice(1);return}const n=o instanceof F.getEnv().Canvas?o:oe(o);this._canvases[r]=n,this._inputDimensions[r]=[n.height,n.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 pt(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");const e=this.getInputWidth(t),o=this.getInputHeight(t);return qo({width:e,height:o},this.inputSize)}toBatchTensor(t,e=!0){return this._inputSize=t,K.tidy(()=>{const o=pt(this.batchSize,0,1).map(n=>{const s=this.getInput(n);if(s instanceof K.Tensor){let i=H(s)?s:s.expandDims();return i=Ze(i,e),(i.shape[1]!==t||i.shape[2]!==t)&&(i=K.image.resizeBilinear(i,[t,t])),i.as3D(t,t,3)}if(s instanceof F.getEnv().Canvas)return K.browser.fromPixels(ho(s,t,e));throw new Error(`toBatchTensor - at batchIdx ${n}, expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have ${s}`)}),r=K.stack(o.map(n=>K.cast(n,"float32"))).as4D(this.batchSize,t,t,3);return r})}}async function M(t){if(t instanceof lt)return t;let e=Array.isArray(t)?t:[t];if(!e.length)throw new Error("toNetInput - empty array passed as input");const o=n=>Array.isArray(t)?` at input index ${n}:`:"",r=e.map(Et);return r.forEach((n,s)=>{if(!ke(n)&&!ut(n)&&!H(n))throw typeof e[s]=="string"?new Error(`toNetInput -${o(s)} string passed, but could not resolve HTMLElement for element id ${e[s]}`):new Error(`toNetInput -${o(s)} expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id`);if(H(n)){const i=n.shape[0];if(i!==1)throw new Error(`toNetInput -${o(s)} tf.Tensor4D with batchSize ${i} passed, but not supported in input array`)}}),await Promise.all(r.map(n=>ke(n)&&wo(n))),new lt(r,Array.isArray(t))}async function It(t,e){const{Canvas:o}=F.getEnv();let r=t;if(!(t instanceof o)){const i=await M(t);if(i.batchSize>1)throw new Error("extractFaces - batchSize > 1 not supported");const a=i.getInput(0);r=a instanceof o?a:await uo(a)}const n=A(r),s=e.map(i=>i instanceof D?i.forSize(r.width,r.height).box.floor():i).map(i=>i.clipAtImageBorders(r.width,r.height));return s.map(({x:i,y:a,width:c,height:p})=>{const m=Ot({width:c,height:p});return A(m).putImageData(n.getImageData(i,a,c,p),0,0),m})}const To=x(require("@tensorflow/tfjs"));async function $t(t,e){if(!ut(t)&&!H(t))throw new Error("extractFaceTensors - expected image tensor to be 3D or 4D");if(H(t)&&t.shape[0]>1)throw new Error("extractFaceTensors - batchSize > 1 not supported");return To.tidy(()=>{const[o,r,n]=t.shape.slice(H(t)?1:0),s=e.map(a=>a instanceof D?a.forSize(r,o).box:a).map(a=>a.clipAtImageBorders(r,o)),i=s.map(({x:a,y:c,width:p,height:m})=>To.slice3d(t.as3D(o,r,n),[c,a,0],[m,p,n]));return i})}async function kt(t,e){const o=F.getEnv().fetch,r=await o(t,e);if(!(r.status<400))throw new Error(`failed to fetch: (${r.status}) ${r.statusText}, from url: ${r.url}`);return r}async function Jr(t){const e=await kt(t),o=await e.blob();if(!o.type.startsWith("image/"))throw new Error(`fetchImage - expected blob type to be of type image/*, instead have: ${o.type}, for url: ${e.url}`);return xo(o)}async function go(t){return(await kt(t)).json()}async function Vr(t){return new Float32Array(await(await kt(t)).arrayBuffer())}function Lo(t,e){const o=`${e}-weights_manifest.json`;if(!t)return{modelBaseUri:"",manifestUri:o};if(t==="/")return{modelBaseUri:"/",manifestUri:`/${o}`};const r=t.startsWith("http://")?"http://":t.startsWith("https://")?"https://":"";t=t.replace(r,"");const n=t.split("/").filter(a=>a),s=t.endsWith(".json")?n[n.length-1]:o;let i=r+(t.endsWith(".json")?n.slice(0,n.length-1):n).join("/");return i=t.startsWith("/")?`/${i}`:i,{modelBaseUri:i,manifestUri:i==="/"?`/${s}`:`${i}/${s}`}}const tn=x(require("@tensorflow/tfjs"));async function lo(t,e){const{manifestUri:o,modelBaseUri:r}=Lo(t,e);let n=await go(o);return tn.io.loadWeights(n,r)}function Yr(t,e,o=!1){const{width:r,height:n}=o?Dt(e):e;return t.width=r,t.height=n,{width:r,height:n}}const gt=x(require("@tensorflow/tfjs"));class R{constructor(t){this._name=t,this._params=void 0,this._paramMappings=[]}get params(){return this._params}get paramMappings(){return this._paramMappings}get isLoaded(){return!!this.params}getParamFromPath(t){const{obj:e,objProp:o}=this.traversePropertyPath(t);return e[o]}reassignParamFromPath(t,e){const{obj:o,objProp:r}=this.traversePropertyPath(t);o[r].dispose(),o[r]=e}getParamList(){return this._paramMappings.map(({paramPath:t})=>({path:t,tensor:this.getParamFromPath(t)}))}getTrainableParams(){return this.getParamList().filter(t=>t.tensor instanceof gt.Variable)}getFrozenParams(){return this.getParamList().filter(t=>!(t.tensor instanceof gt.Variable))}variable(){this.getFrozenParams().forEach(({path:t,tensor:e})=>{this.reassignParamFromPath(t,e.variable())})}freeze(){this.getTrainableParams().forEach(({path:t,tensor:e})=>{const o=gt.tensor(e.dataSync());e.dispose(),this.reassignParamFromPath(t,o)})}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`);const e=await lo(t,this.getDefaultModelName());this.loadFromWeightMap(e)}async loadFromDisk(t){if(t&&typeof t!="string")throw new Error(`${this._name}.loadFromDisk - expected model file path`);const{readFile:e}=F.getEnv(),{manifestUri:o,modelBaseUri:r}=Lo(t,this.getDefaultModelName()),n=c=>Promise.all(c.map(p=>e(p).then(m=>m.buffer))),s=gt.io.weightsLoaderFactory(n),i=JSON.parse((await e(o)).toString()),a=await s(i,r);this.loadFromWeightMap(a)}loadFromWeightMap(t){const{paramMappings:e,params:o}=this.extractParamsFromWeigthMap(t);this._paramMappings=e,this._params=o}extractWeights(t){const{paramMappings:e,params:o}=this.extractParams(t);this._paramMappings=e,this._params=o}traversePropertyPath(t){if(!this.params)throw new Error("traversePropertyPath - model has no loaded params");const e=t.split("/").reduce((n,s)=>{if(!n.nextObj.hasOwnProperty(s))throw new Error(`traversePropertyPath - object does not have property ${s}, for path ${t}`);return{obj:n.nextObj,objProp:s,nextObj:n.nextObj[s]}},{nextObj:this.params}),{obj:o,objProp:r}=e;if(!o||!r||!(o[r]instanceof gt.Tensor))throw new Error(`traversePropertyPath - parameter is not a tensor, for path ${t}`);return{obj:o,objProp:r}}}const ce=x(require("@tensorflow/tfjs"));function U(t,e,o){return ce.tidy(()=>{let r=ce.separableConv2d(t,e.depthwise_filter,e.pointwise_filter,o,"same");return r=ce.add(r,e.bias),r})}const L=x(require("@tensorflow/tfjs"));function Po(t,e,o=!1){return L.tidy(()=>{const r=L.relu(o?L.add(L.conv2d(t,e.conv0.filters,[2,2],"same"),e.conv0.bias):U(t,e.conv0,[2,2])),n=U(r,e.conv1,[1,1]),s=L.relu(L.add(r,n)),i=U(s,e.conv2,[1,1]);return L.relu(L.add(r,L.add(n,i)))})}function Ae(t,e,o=!1,r=!0){return L.tidy(()=>{const n=L.relu(o?L.add(L.conv2d(t,e.conv0.filters,r?[2,2]:[1,1],"same"),e.conv0.bias):U(t,e.conv0,r?[2,2]:[1,1])),s=U(n,e.conv1,[1,1]),i=L.relu(L.add(n,s)),a=U(i,e.conv2,[1,1]),c=L.relu(L.add(n,L.add(s,a))),p=U(c,e.conv3,[1,1]);return L.relu(L.add(n,L.add(s,L.add(a,p))))})}const At=x(require("@tensorflow/tfjs"));function Vt(t,e,o="same",r=!1){return At.tidy(()=>{const n=At.add(At.conv2d(t,e.filters,[1,1],o),e.bias);return r?At.relu(n):n})}function S(t,e){Object.keys(t).forEach(o=>{e.some(r=>r.originalPath===o)||t[o].dispose()})}const Eo=x(require("@tensorflow/tfjs"));function pe(t,e){return function(o,r,n,s){const i=Eo.tensor4d(t(o*r*n*n),[n,n,o,r]),a=Eo.tensor1d(t(r));return e.push({paramPath:`${s}/filters`},{paramPath:`${s}/bias`}),{filters:i,bias:a}}}const Do=x(require("@tensorflow/tfjs"));function ko(t,e){return function(o,r,n){const s=Do.tensor2d(t(o*r),[o,r]),i=Do.tensor1d(t(r));return e.push({paramPath:`${n}/weights`},{paramPath:`${n}/bias`}),{weights:s,bias:i}}}class nr{constructor(t,e,o){this.depthwise_filter=t,this.pointwise_filter=e,this.bias=o}}const Se=x(require("@tensorflow/tfjs"));function me(t,e){return function(o,r,n){const s=Se.tensor4d(t(3*3*o),[3,3,o,1]),i=Se.tensor4d(t(o*r),[1,1,o,r]),a=Se.tensor1d(t(r));return e.push({paramPath:`${n}/depthwise_filter`},{paramPath:`${n}/pointwise_filter`},{paramPath:`${n}/bias`}),new nr(s,i,a)}}function fe(t){return function(e){const o=t(`${e}/depthwise_filter`,4),r=t(`${e}/pointwise_filter`,4),n=t(`${e}/bias`,1);return new nr(o,r,n)}}function $(t,e){return function(o,r,n){const s=t[o];if(!Gt(s,r))throw new Error(`expected weightMap[${o}] to be a Tensor${r}D, instead have ${s}`);return e.push({originalPath:o,paramPath:n||o}),s}}function j(t){let e=t;function o(n){const s=e.slice(0,n);return e=e.slice(n),s}function r(){return e}return{extractWeights:o,getRemainingWeights:r}}function Co(t,e){const o=pe(t,e),r=me(t,e);function n(i,a,c,p=!1){const m=p?o(i,a,3,`${c}/conv0`):r(i,a,`${c}/conv0`),f=r(a,a,`${c}/conv1`),d=r(a,a,`${c}/conv2`);return{conv0:m,conv1:f,conv2:d}}function s(i,a,c,p=!1){const{conv0:m,conv1:f,conv2:d}=n(i,a,c,p),h=r(a,a,`${c}/conv3`);return{conv0:m,conv1:f,conv2:d,conv3:h}}return{extractDenseBlock3Params:n,extractDenseBlock4Params:s}}function en(t){const e=[],{extractWeights:o,getRemainingWeights:r}=j(t),{extractDenseBlock4Params:n}=Co(o,e),s=n(3,32,"dense0",!0),i=n(32,64,"dense1"),a=n(64,128,"dense2"),c=n(128,256,"dense3");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:e,params:{dense0:s,dense1:i,dense2:a,dense3:c}}}function Ro(t){return function(e){const o=t(`${e}/filters`,4),r=t(`${e}/bias`,1);return{filters:o,bias:r}}}function Ao(t,e){const o=$(t,e),r=Ro(o),n=fe(o);function s(a,c=!1){const p=c?r(`${a}/conv0`):n(`${a}/conv0`),m=n(`${a}/conv1`),f=n(`${a}/conv2`);return{conv0:p,conv1:m,conv2:f}}function i(a,c=!1){const p=c?r(`${a}/conv0`):n(`${a}/conv0`),m=n(`${a}/conv1`),f=n(`${a}/conv2`),d=n(`${a}/conv3`);return{conv0:p,conv1:m,conv2:f,conv3:d}}return{extractDenseBlock3Params:s,extractDenseBlock4Params:i}}function on(t){const e=[],{extractDenseBlock4Params:o}=Ao(t,e),r={dense0:o("dense0",!0),dense1:o("dense1"),dense2:o("dense2"),dense3:o("dense3")};return S(t,e),{params:r,paramMappings:e}}const de=x(require("@tensorflow/tfjs"));class So extends R{constructor(){super("FaceFeatureExtractor")}forwardInput(t){const{params:e}=this;if(!e)throw new Error("FaceFeatureExtractor - load model before inference");return de.tidy(()=>{const o=t.toBatchTensor(112,!0),r=[122.782,117.001,104.298],n=q(o,r).div(de.scalar(255));let s=Ae(n,e.dense0,!0);return s=Ae(s,e.dense1),s=Ae(s,e.dense2),s=Ae(s,e.dense3),s=de.avgPool(s,[7,7],[2,2],"valid"),s})}async forward(t){return this.forwardInput(await M(t))}getDefaultModelName(){return"face_feature_extractor_model"}extractParamsFromWeigthMap(t){return on(t)}extractParams(t){return en(t)}}const le=x(require("@tensorflow/tfjs"));function je(t,e){return le.tidy(()=>le.add(le.matMul(t,e.weights),e.bias))}function rn(t,e,o){const r=[],{extractWeights:n,getRemainingWeights:s}=j(t),i=ko(n,r),a=i(e,o,"fc");if(s().length!==0)throw new Error(`weights remaing after extract: ${s().length}`);return{paramMappings:r,params:{fc:a}}}function nn(t){const e=[],o=$(t,e);function r(s){const i=o(`${s}/weights`,2),a=o(`${s}/bias`,1);return{weights:i,bias:a}}const n={fc:r("fc")};return S(t,e),{params:n,paramMappings:e}}function jo(t){const e={},o={};return Object.keys(t).forEach(r=>{const n=r.startsWith("fc")?o:e;n[r]=t[r]}),{featureExtractorMap:e,classifierMap:o}}const sn=x(require("@tensorflow/tfjs"));class No extends R{constructor(t,e){super(t);this._faceFeatureExtractor=e}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){const{params:e}=this;if(!e)throw new Error(`${this._name} - load model before inference`);return sn.tidy(()=>{const o=t instanceof lt?this.faceFeatureExtractor.forwardInput(t):t;return je(o.as2D(o.shape[0],-1),e.fc)})}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){const{params:e,paramMappings:o}=this.extractClassifierParams(t);this._params=e,this._paramMappings=o}extractClassifierParams(t){return rn(t,this.getClassifierChannelsIn(),this.getClassifierChannelsOut())}extractParamsFromWeigthMap(t){const{featureExtractorMap:e,classifierMap:o}=jo(t);return this.faceFeatureExtractor.loadFromWeightMap(e),nn(o)}extractParams(t){const e=this.getClassifierChannelsIn(),o=this.getClassifierChannelsOut(),r=o*e+o,n=t.slice(0,t.length-r),s=t.slice(t.length-r);return this.faceFeatureExtractor.extractWeights(n),this.extractClassifierParams(s)}}const po=["neutral","happy","sad","angry","fearful","disgusted","surprised"];class Pt{constructor(t){if(t.length!==7)throw new Error(`FaceExpressions.constructor - expected probabilities.length to be 7, have: ${t.length}`);po.forEach((e,o)=>{this[e]=t[o]})}asSortedArray(){return po.map(t=>({expression:t,probability:this[t]})).sort((t,e)=>e.probability-t.probability)}}const he=x(require("@tensorflow/tfjs"));class mo extends No{constructor(t=new So){super("FaceExpressionNet",t)}forwardInput(t){return he.tidy(()=>he.softmax(this.runNet(t)))}async forward(t){return this.forwardInput(await M(t))}async predictExpressions(t){const e=await M(t),o=await this.forwardInput(e),r=await Promise.all(he.unstack(o).map(async s=>{const i=await s.data();return s.dispose(),i}));o.dispose();const n=r.map(s=>new Pt(s));return e.isBatchInput?n:n[0]}getDefaultModelName(){return"face_expression_model"}getClassifierChannelsIn(){return 256}getClassifierChannelsOut(){return 7}}function io(t){return t.expressions instanceof Pt}function Pe(t,e){const o={expressions:e};return Object.assign({},t,o)}function as(t,e,o=.1,r){const n=Array.isArray(e)?e:[e];n.forEach(s=>{const i=s instanceof Pt?s:io(s)?s.expressions:void 0;if(!i)throw new Error("drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof");const a=i.asSortedArray(),c=a.filter(f=>f.probability>o),p=ot(s)?s.detection.box.bottomLeft:r||new w(0,0),m=new ie(c.map(f=>`${f.expression} (${Ht(f.probability)})`),p);m.draw(t)})}function Tt(t){return ot(t)&&t.landmarks instanceof G&&t.unshiftedLandmarks instanceof G&&t.alignedRect instanceof D}function Ut(t,e){const{box:o}=t.detection,r=e.shiftBy(o.x,o.y),n=r.align(),{imageDims:s}=t.detection,i=new D(t.detection.score,n.rescale(s.reverse()),s),a={landmarks:r,unshiftedLandmarks:e,alignedRect:i};return Object.assign({},t,a)}class an{constructor(t={}){const{drawLines:e=!0,drawPoints:o=!0,lineWidth:r,lineColor:n,pointSize:s,pointColor:i}=t;this.drawLines=e,this.drawPoints=o,this.lineWidth=r||1,this.pointSize=s||2,this.lineColor=n||"rgba(0, 255, 255, 1)",this.pointColor=i||"rgba(255, 0, 255, 1)"}}class cn{constructor(t,e={}){this.faceLandmarks=t,this.options=new an(e)}draw(t){const e=A(t),{drawLines:o,drawPoints:r,lineWidth:n,lineColor:s,pointSize:i,pointColor:a}=this.options;if(o&&this.faceLandmarks instanceof ne&&(e.strokeStyle=s,e.lineWidth=n,ht(e,this.faceLandmarks.getJawOutline()),ht(e,this.faceLandmarks.getLeftEyeBrow()),ht(e,this.faceLandmarks.getRightEyeBrow()),ht(e,this.faceLandmarks.getNose()),ht(e,this.faceLandmarks.getLeftEye(),!0),ht(e,this.faceLandmarks.getRightEye(),!0),ht(e,this.faceLandmarks.getMouth(),!0)),r){e.strokeStyle=a,e.fillStyle=a;const c=p=>{e.beginPath(),e.arc(p.x,p.y,i,0,2*Math.PI),e.fill()};this.faceLandmarks.positions.forEach(c)}}}function is(t,e){const o=Array.isArray(e)?e:[e];o.forEach(r=>{const n=r instanceof G?r:Tt(r)?r.landmarks:void 0;if(!n)throw new Error("drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks<WithFaceDetection<{}>> or array thereof");new cn(n).draw(t)})}const Ye={};He(Ye,{AnchorPosition:()=>ft,DrawBox:()=>rr,DrawBoxOptions:()=>Qr,DrawFaceLandmarks:()=>cn,DrawFaceLandmarksOptions:()=>an,DrawTextField:()=>ie,DrawTextFieldOptions:()=>Fo,drawContour:()=>ht,drawDetections:()=>ss,drawFaceExpressions:()=>as,drawFaceLandmarks:()=>is});function cs(t,e){const o=pe(t,e),r=me(t,e);function n(i,a,c){const p=r(i,a,`${c}/separable_conv0`),m=r(a,a,`${c}/separable_conv1`),f=o(i,a,1,`${c}/expansion_conv`);return{separable_conv0:p,separable_conv1:m,expansion_conv:f}}function s(i,a){const c=r(i,i,`${a}/separable_conv0`),p=r(i,i,`${a}/separable_conv1`),m=r(i,i,`${a}/separable_conv2`);return{separable_conv0:c,separable_conv1:p,separable_conv2:m}}return{extractConvParams:o,extractSeparableConvParams:r,extractReductionBlockParams:n,extractMainBlockParams:s}}function pn(t,e){const o=[],{extractWeights:r,getRemainingWeights:n}=j(t),{extractConvParams:s,extractSeparableConvParams:i,extractReductionBlockParams:a,extractMainBlockParams:c}=cs(r,o),p=s(3,32,3,"entry_flow/conv_in"),m=a(32,64,"entry_flow/reduction_block_0"),f=a(64,128,"entry_flow/reduction_block_1"),d={conv_in:p,reduction_block_0:m,reduction_block_1:f},h={};pt(e,0,1).forEach(_=>{h[`main_block_${_}`]=c(128,`middle_flow/main_block_${_}`)});const b=a(128,256,"exit_flow/reduction_block"),u=i(256,512,"exit_flow/separable_conv"),v={reduction_block:b,separable_conv:u};if(n().length!==0)throw new Error(`weights remaing after extract: ${n().length}`);return{paramMappings:o,params:{entry_flow:d,middle_flow:h,exit_flow:v}}}function ps(t,e){const o=$(t,e),r=Ro(o),n=fe(o);function s(a){const c=n(`${a}/separable_conv0`),p=n(`${a}/separable_conv1`),m=r(`${a}/expansion_conv`);return{separable_conv0:c,separable_conv1:p,expansion_conv:m}}function i(a){const c=n(`${a}/separable_conv0`),p=n(`${a}/separable_conv1`),m=n(`${a}/separable_conv2`);return{separable_conv0:c,separable_conv1:p,separable_conv2:m}}return{extractConvParams:r,extractSeparableConvParams:n,extractReductionBlockParams:s,extractMainBlockParams:i}}function mn(t,e){const o=[],{extractConvParams:r,extractSeparableConvParams:n,extractReductionBlockParams:s,extractMainBlockParams:i}=ps(t,o),a=r("entry_flow/conv_in"),c=s("entry_flow/reduction_block_0"),p=s("entry_flow/reduction_block_1"),m={conv_in:a,reduction_block_0:c,reduction_block_1:p},f={};pt(e,0,1).forEach(u=>{f[`main_block_${u}`]=i(`middle_flow/main_block_${u}`)});const d=s("exit_flow/reduction_block"),h=n("exit_flow/separable_conv"),b={reduction_block:d,separable_conv:h};return S(t,o),{params:{entry_flow:m,middle_flow:f,exit_flow:b},paramMappings:o}}const k=x(require("@tensorflow/tfjs"));function fn(t,e,o){return k.add(k.conv2d(t,e.filters,o,"same"),e.bias)}function sr(t,e,o=!0){let r=o?k.relu(t):t;return r=U(r,e.separable_conv0,[1,1]),r=U(k.relu(r),e.separable_conv1,[1,1]),r=k.maxPool(r,[3,3],[2,2],"same"),r=k.add(r,fn(t,e.expansion_conv,[2,2])),r}function ms(t,e){let o=U(k.relu(t),e.separable_conv0,[1,1]);return o=U(k.relu(o),e.separable_conv1,[1,1]),o=U(k.relu(o),e.separable_conv2,[1,1]),o=k.add(o,t),o}class dn extends R{constructor(t){super("TinyXception");this._numMainBlocks=t}forwardInput(t){const{params:e}=this;if(!e)throw new Error("TinyXception - load model before inference");return k.tidy(()=>{const o=t.toBatchTensor(112,!0),r=[122.782,117.001,104.298],n=q(o,r).div(k.scalar(256));let s=k.relu(fn(n,e.entry_flow.conv_in,[2,2]));return s=sr(s,e.entry_flow.reduction_block_0,!1),s=sr(s,e.entry_flow.reduction_block_1),pt(this._numMainBlocks,0,1).forEach(i=>{s=ms(s,e.middle_flow[`main_block_${i}`])}),s=sr(s,e.exit_flow.reduction_block),s=k.relu(U(s,e.exit_flow.separable_conv,[1,1])),s})}async forward(t){return this.forwardInput(await M(t))}getDefaultModelName(){return"tiny_xception_model"}extractParamsFromWeigthMap(t){return mn(t,this._numMainBlocks)}extractParams(t){return pn(t,this._numMainBlocks)}}function ln(t){const e=[],{extractWeights:o,getRemainingWeights:r}=j(t),n=ko(o,e),s=n(512,1,"fc/age"),i=n(512,2,"fc/gender");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:e,params:{fc:{age:s,gender:i}}}}function hn(t){const e=[],o=$(t,e);function r(s){const i=o(`${s}/weights`,2),a=o(`${s}/bias`,1);return{weights:i,bias:a}}const n={fc:{age:r("fc/age"),gender:r("fc/gender")}};return S(t,e),{params:n,paramMappings:e}}var ct;(function(t){t.FEMALE="female",t.MALE="male"})(ct||(ct={}));const dt=x(require("@tensorflow/tfjs"));class vo extends R{constructor(t=new dn(2)){super("AgeGenderNet");this._faceFeatureExtractor=t}get faceFeatureExtractor(){return this._faceFeatureExtractor}runNet(t){const{params:e}=this;if(!e)throw new Error(`${this._name} - load model before inference`);return dt.tidy(()=>{const o=t instanceof lt?this.faceFeatureExtractor.forwardInput(t):t,r=dt.avgPool(o,[7,7],[2,2],"valid").as2D(o.shape[0],-1),n=je(r,e.fc.age).as1D(),s=je(r,e.fc.gender);return{age:n,gender:s}})}forwardInput(t){return dt.tidy(()=>{const{age:e,gender:o}=this.runNet(t);return{age:e,gender:dt.softmax(o)}})}async forward(t){return this.forwardInput(await M(t))}async predictAgeAndGender(t){const e=await M(t),o=await this.forwardInput(e),r=dt.unstack(o.age),n=dt.unstack(o.gender),s=r.map((a,c)=>({ageTensor:a,genderTensor:n[c]})),i=await Promise.all(s.map(async({ageTensor:a,genderTensor:c})=>{const p=(await a.data())[0],m=(await c.data())[0],f=m>.5,d=f?ct.MALE:ct.FEMALE,h=f?m:1-m;return a.dispose(),c.dispose(),{age:p,gender:d,genderProbability:h}}));return o.age.dispose(),o.gender.dispose(),e.isBatchInput?i:i[0]}getDefaultModelName(){return"age_gender_model"}dispose(t=!0){this.faceFeatureExtractor.dispose(t),super.dispose(t)}loadClassifierParams(t){const{params:e,paramMappings:o}=this.extractClassifierParams(t);this._params=e,this._paramMappings=o}extractClassifierParams(t){return ln(t)}extractParamsFromWeigthMap(t){const{featureExtractorMap:e,classifierMap:o}=jo(t);return this.faceFeatureExtractor.loadFromWeightMap(e),hn(o)}extractParams(t){const e=512*1+1+(512*2+2),o=t.slice(0,t.length-e),r=t.slice(t.length-e);return this.faceFeatureExtractor.extractWeights(o),this.extractClassifierParams(r)}}const O=x(require("@tensorflow/tfjs"));class Wo extends No{postProcess(t,e,o){const r=o.map(({width:s,height:i})=>{const a=e/Math.max(i,s);return{width:s*a,height:i*a}}),n=r.length;return O.tidy(()=>{const s=(m,f)=>O.stack([O.fill([68],m),O.fill([68],f)],1).as2D(1,136).as1D(),i=(m,f)=>{const{width:d,height:h}=r[m];return f(d,h)?Math.abs(d-h)/2:0},a=m=>i(m,(f,d)=>f<d),c=m=>i(m,(f,d)=>d<f),p=t.mul(O.fill([n,136],e)).sub(O.stack(Array.from(Array(n),(m,f)=>s(a(f),c(f))))).div(O.stack(Array.from(Array(n),(m,f)=>s(r[f].width,r[f].height))));return p})}forwardInput(t){return O.tidy(()=>{const e=this.runNet(t);return this.postProcess(e,t.inputSize,t.inputDimensions.map(([o,r])=>({height:o,width:r})))})}async forward(t){return this.forwardInput(await M(t))}async detectLandmarks(t){const e=await M(t),o=O.tidy(()=>O.unstack(this.forwardInput(e))),r=await Promise.all(o.map(async(n,s)=>{const i=Array.from(await n.data()),a=i.filter((p,m)=>_o(m)),c=i.filter((p,m)=>!_o(m));return new ne(Array(68).fill(0).map((p,m)=>new w(a[m],c[m])),{height:e.getInputHeight(s),width:e.getInputWidth(s)})}));return o.forEach(n=>n.dispose()),e.isBatchInput?r:r[0]}getClassifierChannelsOut(){return 136}}class te extends Wo{constructor(t=new So){super("FaceLandmark68Net",t)}getDefaultModelName(){return"face_landmark_68_model"}getClassifierChannelsIn(){return 256}}function un(t){const e=[],{extractDenseBlock3Params:o}=Ao(t,e),r={dense0:o("dense0",!0),dense1:o("dense1"),dense2:o("dense2")};return S(t,e),{params:r,paramMappings:e}}function gn(t){const e=[],{extractWeights:o,getRemainingWeights:r}=j(t),{extractDenseBlock3Params:n}=Co(o,e),s=n(3,32,"dense0",!0),i=n(32,64,"dense1"),a=n(64,128,"dense2");if(r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{paramMappings:e,params:{dense0:s,dense1:i,dense2:a}}}const ue=x(require("@tensorflow/tfjs"));class xn extends R{constructor(){super("TinyFaceFeatureExtractor")}forwardInput(t){const{params:e}=this;if(!e)throw new Error("TinyFaceFeatureExtractor - load model before inference");return ue.tidy(()=>{const o=t.toBatchTensor(112,!0),r=[122.782,117.001,104.298],n=q(o,r).div(ue.scalar(255));let s=Po(n,e.dense0,!0);return s=Po(s,e.dense1),s=Po(s,e.dense2),s=ue.avgPool(s,[14,14],[2,2],"valid"),s})}async forward(t){return this.forwardInput(await M(t))}getDefaultModelName(){return"face_feature_extractor_tiny_model"}extractParamsFromWeigthMap(t){return un(t)}extractParams(t){return gn(t)}}class co extends Wo{constructor(t=new xn){super("FaceLandmark68TinyNet",t)}getDefaultModelName(){return"face_landmark_68_tiny_model"}getClassifierChannelsIn(){return 128}}class Hr extends te{}const Bo=x(require("@tensorflow/tfjs"));function wn(t,e){return Bo.add(Bo.mul(t,e.weights),e.biases)}const ge=x(require("@tensorflow/tfjs"));function ar(t,e,o,r,n="same"){const{filters:s,bias:i}=e.conv;let a=ge.conv2d(t,s,o,n);return a=ge.add(a,i),a=wn(a,e.scale),r?ge.relu(a):a}function vn(t,e){return ar(t,e,[1,1],!0)}function ir(t,e){return ar(t,e,[1,1],!1)}function Uo(t,e){return ar(t,e,[2,2],!0,"valid")}const z=x(require("@tensorflow/tfjs"));function fs(t,e){function o(a,c,p){const m=t(a),f=m.length/(c*p*p);if(Xo(f))throw new Error(`depth has to be an integer: ${f}, weights.length: ${m.length}, numFilters: ${c}, filterSize: ${p}`);return z.tidy(()=>z.transpose(z.tensor4d(m,[c,f,p,p]),[2,3,1,0]))}function r(a,c,p,m){const f=o(a,c,p),d=z.tensor1d(t(c));return e.push({paramPath:`${m}/filters`},{paramPath:`${m}/bias`}),{filters:f,bias:d}}function n(a,c){const p=z.tensor1d(t(a)),m=z.tensor1d(t(a));return e.push({paramPath:`${c}/weights`},{paramPath:`${c}/biases`}),{weights:p,biases:m}}function s(a,c,p,m){const f=r(a,c,p,`${m}/conv`),d=n(c,`${m}/scale`);return{conv:f,scale:d}}function i(a,c,p,m,f=!1){const d=s((f?.5:1)*a,c,p,`${m}/conv1`),h=s(a,c,p,`${m}/conv2`);return{conv1:d,conv2:h}}return{extractConvLayerParams:s,extractResidualLayerParams:i}}function _n(t){const{extractWeights:e,getRemainingWeights:o}=j(t),r=[],{extractConvLayerParams:n,extractResidualLayerParams:s}=fs(e,r),i=n(4704,32,7,"conv32_down"),a=s(9216,32,3,"conv32_1"),c=s(9216,32,3,"conv32_2"),p=s(9216,32,3,"conv32_3"),m=s(36864,64,3,"conv64_down",!0),f=s(36864,64,3,"conv64_1"),d=s(36864,64,3,"conv64_2"),h=s(36864,64,3,"conv64_3"),b=s(147456,128,3,"conv128_down",!0),u=s(147456,128,3,"conv128_1"),v=s(147456,128,3,"conv128_2"),_=s(589824,256,3,"conv256_down",!0),g=s(589824,256,3,"conv256_1"),E=s(589824,256,3,"conv256_2"),W=s(589824,256,3,"conv256_down_out"),I=z.tidy(()=>z.transpose(z.tensor2d(e(256*128),[128,256]),[1,0]));if(r.push({paramPath:"fc"}),o().length!==0)throw new Error(`weights remaing after extract: ${o().length}`);const V={conv32_down:i,conv32_1:a,conv32_2:c,conv32_3:p,conv64_down:m,conv64_1:f,conv64_2:d,conv64_3:h,conv128_down:b,conv128_1:u,conv128_2:v,conv256_down:_,conv256_1:g,conv256_2:E,conv256_down_out:W,fc:I};return{params:V,paramMappings:r}}function ds(t,e){const o=$(t,e);function r(i){const a=o(`${i}/scale/weights`,1),c=o(`${i}/scale/biases`,1);return{weights:a,biases:c}}function n(i){const a=o(`${i}/conv/filters`,4),c=o(`${i}/conv/bias`,1),p=r(i);return{conv:{filters:a,bias:c},scale:p}}function s(i){return{conv1:n(`${i}/conv1`),conv2:n(`${i}/conv2`)}}return{extractConvLayerParams:n,extractResidualLayerParams:s}}function bn(t){const e=[],{extractConvLayerParams:o,extractResidualLayerParams:r}=ds(t,e),n=o("conv32_down"),s=r("conv32_1"),i=r("conv32_2"),a=r("conv32_3"),c=r("conv64_down"),p=r("conv64_1"),m=r("conv64_2"),f=r("conv64_3"),d=r("conv128_down"),h=r("conv128_1"),b=r("conv128_2"),u=r("conv256_down"),v=r("conv256_1"),_=r("conv256_2"),g=r("conv256_down_out"),E=t.fc;if(e.push({originalPath:"fc",paramPath:"fc"}),!Jo(E))throw new Error(`expected weightMap[fc] to be a Tensor2D, instead have ${E}`);const W={conv32_down:n,conv32_1:s,conv32_2:i,conv32_3:a,conv64_down:c,conv64_1:p,conv64_2:m,conv64_3:f,conv128_down:d,conv128_1:h,conv128_2:b,conv256_down:u,conv256_1:v,conv256_2:_,conv256_down_out:g,fc:E};return S(t,e),{params:W,paramMappings:e}}const N=x(require("@tensorflow/tfjs"));function nt(t,e){let o=vn(t,e.conv1);return o=ir(o,e.conv2),o=N.add(o,t),o=N.relu(o),o}function Ne(t,e){let o=Uo(t,e.conv1);o=ir(o,e.conv2);let r=N.avgPool(t,2,2,"valid");const n=N.zeros(r.shape),s=r.shape[3]!==o.shape[3],i=r.shape[1]!==o.shape[1]||r.shape[2]!==o.shape[2];if(i){const a=[...o.shape];a[1]=1;const c=N.zeros(a);o=N.concat([o,c],1);const p=[...o.shape];p[2]=1;const m=N.zeros(p);o=N.concat([o,m],2)}return r=s?N.concat([r,n],3):r,o=N.add(r,o),o=N.relu(o),o}const Y=x(require("@tensorflow/tfjs"));class Qt extends R{constructor(){super("FaceRecognitionNet")}forwardInput(t){const{params:e}=this;if(!e)throw new Error("FaceRecognitionNet - load model before inference");return Y.tidy(()=>{const o=Y.cast(t.toBatchTensor(150,!0),"float32"),r=[122.782,117.001,104.298],n=q(o,r).div(Y.scalar(256));let s=Uo(n,e.conv32_down);s=Y.maxPool(s,3,2,"valid"),s=nt(s,e.conv32_1),s=nt(s,e.conv32_2),s=nt(s,e.conv32_3),s=Ne(s,e.conv64_down),s=nt(s,e.conv64_1),s=nt(s,e.conv64_2),s=nt(s,e.conv64_3),s=Ne(s,e.conv128_down),s=nt(s,e.conv128_1),s=nt(s,e.conv128_2),s=Ne(s,e.conv256_down),s=nt(s,e.conv256_1),s=nt(s,e.conv256_2),s=Ne(s,e.conv256_down_out);const i=s.mean([1,2]),a=Y.matMul(i,e.fc);return a})}async forward(t){return this.forwardInput(await M(t))}async computeFaceDescriptor(t){const e=await M(t),o=Y.tidy(()=>Y.unstack(this.forwardInput(e))),r=await Promise.all(o.map(n=>n.data()));return o.forEach(n=>n.dispose()),e.isBatchInput?r:r[0]}getDefaultModelName(){return"face_recognition_model"}extractParamsFromWeigthMap(t){return bn(t)}extractParams(t){return _n(t)}}function Gr(t){const e=new Qt;return e.extractWeights(t),e}function Ee(t,e){const o={descriptor:e};return Object.assign({},t,o)}function zr(t){return typeof t.age=="number"}function De(t,e){const o={age:e};return Object.assign({},t,o)}function Or(t){return(t.gender===ct.MALE||t.gender===ct.FEMALE)&&ae(t.genderProbability)}function Le(t,e,o){const r={gender:e,genderProbability:o};return Object.assign({},t,r)}const st=x(require("@tensorflow/tfjs"));function ls(t,e){function o(c,p){const m=st.tensor4d(t(3*3*c),[3,3,c,1]),f=st.tensor1d(t(c)),d=st.tensor1d(t(c)),h=st.tensor1d(t(c)),b=st.tensor1d(t(c));return e.push({paramPath:`${p}/filters`},{paramPath:`${p}/batch_norm_scale`},{paramPath:`${p}/batch_norm_offset`},{paramPath:`${p}/batch_norm_mean`},{paramPath:`${p}/batch_norm_variance`}),{filters:m,batch_norm_scale:f,batch_norm_offset:d,batch_norm_mean:h,batch_norm_variance:b}}function r(c,p,m,f,d){const h=st.tensor4d(t(c*p*m*m),[m,m,c,p]),b=st.tensor1d(t(p));return e.push({paramPath:`${f}/filters`},{paramPath:`${f}/${d?"batch_norm_offset":"bias"}`}),{filters:h,bias:b}}function n(c,p,m,f){const{filters:d,bias:h}=r(c,p,m,f,!0);return{filters:d,batch_norm_offset:h}}function s(c,p,m){const f=o(c,`${m}/depthwise_conv`),d=n(c,p,1,`${m}/pointwise_conv`);return{depthwise_conv:f,pointwise_conv:d}}function i(){const c=n(3,32,3,"mobilenetv1/conv_0"),p=s(32,64,"mobilenetv1/conv_1"),m=s(64,128,"mobilenetv1/conv_2"),f=s(128,128,"mobilenetv1/conv_3"),d=s(128,256,"mobilenetv1/conv_4"),h=s(256,256,"mobilenetv1/conv_5"),b=s(256,512,"mobilenetv1/conv_6"),u=s(512,512,"mobilenetv1/conv_7"),v=s(512,512,"mobilenetv1/conv_8"),_=s(512,512,"mobilenetv1/conv_9"),g=s(512,512,"mobilenetv1/conv_10"),E=s(512,512,"mobilenetv1/conv_11"),W=s(512,1024,"mobilenetv1/conv_12"),I=s(1024,1024,"mobilenetv1/conv_13");return{conv_0:c,conv_1:p,conv_2:m,conv_3:f,conv_4:d,conv_5:h,conv_6:b,conv_7:u,conv_8:v,conv_9:_,conv_10:g,conv_11:E,conv_12:W,conv_13:I}}function a(){const c=n(1024,256,1,"prediction_layer/conv_0"),p=n(256,512,3,"prediction_layer/conv_1"),m=n(512,128,1,"prediction_layer/conv_2"),f=n(128,256,3,"prediction_layer/conv_3"),d=n(256,128,1,"prediction_layer/conv_4"),h=n(128,256,3,"prediction_layer/conv_5"),b=n(256,64,1,"prediction_layer/conv_6"),u=n(64,128,3,"prediction_layer/conv_7"),v=r(512,12,1,"prediction_layer/box_predictor_0/box_encoding_predictor"),_=r(512,9,1,"prediction_layer/box_predictor_0/class_predictor"),g=r(1024,24,1,"prediction_layer/box_predictor_1/box_encoding_predictor"),E=r(1024,18,1,"prediction_layer/box_predictor_1/class_predictor"),W=r(512,24,1,"prediction_layer/box_predictor_2/box_encoding_predictor"),I=r(512,18,1,"prediction_layer/box_predictor_2/class_predictor"),V=r(256,24,1,"prediction_layer/box_predictor_3/box_encoding_predictor"),J=r(256,18,1,"prediction_layer/box_predictor_3/class_predictor"),_t=r(256,24,1,"prediction_layer/box_predictor_4/box_encoding_predictor"),bt=r(256,18,1,"prediction_layer/box_predictor_4/class_predictor"),yt=r(128,24,1,"prediction_layer/box_predictor_5/box_encoding_predictor"),Nt=r(128,18,1,"prediction_layer/box_predictor_5/class_predictor"),Wt={box_encoding_predictor:v,class_predictor:_},$n={box_encoding_predictor:g,class_predictor:E},On={box_encoding_predictor:W,class_predictor:I},zn={box_encoding_predictor:V,class_predictor:J},Gn={box_encoding_predictor:_t,class_predictor:bt},Hn={box_encoding_predictor:yt,class_predictor:Nt};return{conv_0:c,conv_1:p,conv_2:m,conv_3:f,conv_4:d,conv_5:h,conv_6:b,conv_7:u,box_predictor_0:Wt,box_predictor_1:$n,box_predictor_2:On,box_predictor_3:zn,box_predictor_4:Gn,box_predictor_5:Hn}}return{extractMobilenetV1Params:i,extractPredictionLayerParams:a}}function yn(t){const e=[],{extractWeights:o,getRemainingWeights:r}=j(t),{extractMobilenetV1Params:n,extractPredictionLayerParams:s}=ls(o,e),i=n(),a=s(),c=st.tensor3d(o(5118*4),[1,5118,4]),p={extra_dim:c};if(e.push({paramPath:"output_layer/extra_dim"}),r().length!==0)throw new Error(`weights remaing after extract: ${r().length}`);return{params:{mobilenetv1:i,prediction_layer:a,output_layer:p},paramMappings:e}}function hs(t,e){const o=$(t,e);function r(p,m,f){const d=o(`${p}/Conv2d_${m}_pointwise/weights`,4,`${f}/filters`),h=o(`${p}/Conv2d_${m}_pointwise/convolution_bn_offset`,1,`${f}/batch_norm_offset`);return{filters:d,batch_norm_offset:h}}function n(p){const m=`mobilenetv1/conv_${p}`,f=`MobilenetV1/Conv2d_${p}_depthwise`,d=`${m}/depthwise_conv`,h=`${m}/pointwise_conv`,b=o(`${f}/depthwise_weights`,4,`${d}/filters`),u=o(`${f}/BatchNorm/gamma`,1,`${d}/batch_norm_scale`),v=o(`${f}/BatchNorm/beta`,1,`${d}/batch_norm_offset`),_=o(`${f}/BatchNorm/moving_mean`,1,`${d}/batch_norm_mean`),g=o(`${f}/BatchNorm/moving_variance`,1,`${d}/batch_norm_variance`);return{depthwise_conv:{filters:b,batch_norm_scale:u,batch_norm_offset:v,batch_norm_mean:_,batch_norm_variance:g},pointwise_conv:r("MobilenetV1",p,h)}}function s(){return{conv_0:r("MobilenetV1",0,"mobilenetv1/conv_0"),conv_1:n(1),conv_2:n(2),conv_3:n(3),conv_4:n(4),conv_5:n(5),conv_6:n(6),conv_7:n(7),conv_8:n(8),conv_9:n(9),conv_10:n(10),conv_11:n(11),conv_12:n(12),conv_13:n(13)}}function i(p,m){const f=o(`${p}/weights`,4,`${m}/filters`),d=o(`${p}/biases`,1,`${m}/bias`);return{filters:f,bias:d}}function a(p){const m=i(`Prediction/BoxPredictor_${p}/BoxEncodingPredictor`,`prediction_layer/box_predictor_${p}/box_encoding_predictor`),f=i(`Prediction/BoxPredictor_${p}/ClassPredictor`,`prediction_layer/box_predictor_${p}/class_predictor`);return{box_encoding_predictor:m,class_predictor:f}}function c(){return{conv_0:r("Prediction",0,"prediction_layer/conv_0"),conv_1:r("Prediction",1,"prediction_layer/conv_1"),conv_2:r("Prediction",2,"prediction_layer/conv_2"),conv_3:r("Prediction",3,"prediction_layer/conv_3"),conv_4:r("Prediction",4,"prediction_layer/conv_4"),conv_5:r("Prediction",5,"prediction_layer/conv_5"),conv_6:r("Prediction",6,"prediction_layer/conv_6"),conv_7:r("Prediction",7,"prediction_layer/conv_7"),box_predictor_0:a(0),box_predictor_1:a(1),box_predictor_2:a(2),box_predictor_3:a(3),box_predictor_4:a(4),box_predictor_5:a(5)}}return{extractMobilenetV1Params:s,extractPredictionLayerParams:c}}function Fn(t){const e=[],{extractMobilenetV1Params:o,extractPredictionLayerParams:r}=hs(t,e),n=t["Output/extra_dim"];if(e.push({originalPath:"Output/extra_dim",paramPath:"output_layer/extra_dim"}),!ut(n))throw new Error(`expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have ${n}`);const s={mobilenetv1:o(),prediction_layer:r(),output_layer:{extra_dim:n}};return S(t,e),{params:s,paramMappings:e}}const St=x(require("@tensorflow/tfjs"));function Q(t,e,o){return St.tidy(()=>{let r=St.conv2d(t,e.filters,o,"same");return r=St.add(r,e.batch_norm_offset),St.clipByValue(r,0,6)})}const xt=x(require("@tensorflow/tfjs")),us=.0010000000474974513;function gs(t,e,o){return xt.tidy(()=>{let r=xt.depthwiseConv2d(t,e.filters,o,"same");return r=xt.batchNorm(r,e.batch_norm_mean,e.batch_norm_variance,e.batch_norm_offset,e.batch_norm_scale,us),xt.clipByValue(r,0,6)})}function xs(t){return[2,4,6,12].some(e=>e===t)?[2,2]:[1,1]}function Mn(t,e){return xt.tidy(()=>{let o,r=Q(t,e.conv_0,[2,2]);const n=[e.conv_1,e.conv_2,e.conv_3,e.conv_4,e.conv_5,e.conv_6,e.conv_7,e.conv_8,e.conv_9,e.conv_10,e.conv_11,e.conv_12,e.conv_13];if(n.forEach((s,i)=>{const a=i+1,c=xs(a);r=gs(r,s.depthwise_conv,c),r=Q(r,s.pointwise_conv,[1,1]),a===11&&(o=r)}),o===null)throw new Error("mobileNetV1 - output of conv layer 11 is null");return{out:r,conv11:o}})}function Tn(t,e,o,r,n){const s=t.shape[0],i=Math.min(o,s),a=e.map((m,f)=>({score:m,boxIndex:f})).filter(m=>m.score>n).sort((m,f)=>f.score-m.score),c=m=>m<=r?1:0,p=[];return a.forEach(m=>{if(p.length>=i)return;const f=m.score;for(let d=p.length-1;d>=0;--d){const h=ws(t,m.boxIndex,p[d]);if(h===0)continue;if(m.score*=c(h),m.score<=n)break}f===m.score&&p.push(m.boxIndex)}),p}function ws(t,e,o){const r=t.arraySync(),n=Math.min(r[e][0],r[e][2]),s=Math.min(r[e][1],r[e][3]),i=Math.max(r[e][0],r[e][2]),a=Math.max(r[e][1],r[e][3]),c=Math.min(r[o][0],r[o][2]),p=Math.min(r[o][1],r[o][3]),m=Math.max(r[o][0],r[o][2]),f=Math.max(r[o][1],r[o][3]),d=(i-n)*(a-s),h=(m-c)*(f-p);if(d<=0||h<=0)return 0;const b=Math.max(n,c),u=Math.max(s,p),v=Math.min(i,m),_=Math.min(a,f),g=Math.max(v-b,0)*Math.max(_-u,0);return g/(d+h-g)}const l=x(require("@tensorflow/tfjs"));function vs(t){const e=l.unstack(l.transpose(t,[1,0])),o=[l.sub(e[2],e[0]),l.sub(e[3],e[1])],r=[l.add(e[0],l.div(o[0],l.scalar(2))),l.add(e[1],l.div(o[1],l.scalar(2)))];return{sizes:o,centers:r}}function _s(t,e){const{sizes:o,centers:r}=vs(t),n=l.unstack(l.transpose(e,[1,0])),s=l.div(l.mul(l.exp(l.div(n[2],l.scalar(5))),o[0]),l.scalar(2)),i=l.add(l.mul(l.div(n[0],l.scalar(10)),o[0]),r[0]),a=l.div(l.mul(l.exp(l.div(n[3],l.scalar(5))),o[1]),l.scalar(2)),c=l.add(l.mul(l.div(n[1],l.scalar(10)),o[1]),r[1]);return l.transpose(l.stack([l.sub(i,s),l.sub(c,a),l.add(i,s),l.add(c,a)]),[1,0])}function Ln(t,e,o){return l.tidy(()=>{const r=t.shape[0];let n=_s(l.reshape(l.tile(o.extra_dim,[r,1,1]),[-1,4]),l.reshape(t,[-1,4]));n=l.reshape(n,[r,n.shape[0]/r,4]);const s=l.sigmoid(l.slice(e,[0,0,1],[-1,-1,-1]));let i=l.slice(s,[0,0,0],[-1,-1,1]);i=l.reshape(i,[r,i.shape[1]]);const a=l.unstack(n),c=l.unstack(i);return{boxes:a,scores:c}})}const We=x(require("@tensorflow/tfjs"));function Jt(t,e){return We.tidy(()=>{const o=t.shape[0],r=We.reshape(Vt(t,e.box_encoding_predictor),[o,-1,1,4]),n=We.reshape(Vt(t,e.class_predictor),[o,-1,3]);return{boxPredictionEncoding:r,classPrediction:n}})}const Be=x(require("@tensorflow/tfjs"));function Pn(t,e,o){return Be.tidy(()=>{const r=Q(t,o.conv_0,[1,1]),n=Q(r,o.conv_1,[2,2]),s=Q(n,o.conv_2,[1,1]),i=Q(s,o.conv_3,[2,2]),a=Q(i,o.conv_4,[1,1]),c=Q(a,o.conv_5,[2,2]),p=Q(c,o.conv_6,[1,1]),m=Q(p,o.conv_7,[2,2]),f=Jt(e,o.box_predictor_0),d=Jt(t,o.box_predictor_1),h=Jt(n,o.box_predictor_2),b=Jt(i,o.box_predictor_3),u=Jt(c,o.box_predictor_4),v=Jt(m,o.box_predictor_5),_=Be.concat([f.boxPredictionEncoding,d.boxPredictionEncoding,h.boxPredictionEncoding,b.boxPredictionEncoding,u.boxPredictionEncoding,v.boxPredictionEncoding],1),g=Be.concat([f.classPrediction,d.classPrediction,h.classPrediction,b.classPrediction,u.classPrediction,v.classPrediction],1);return{boxPredictions:_,classPredictions:g}})}class X{constructor({minConfidence:t,maxResults:e}={}){if(this._name="SsdMobilenetv1Options",this._minConfidence=t||.5,this._maxResults=e||100,typeof this._minConfidence!="number"||this._minConfidence<=0||this._minConfidence>=1)throw new Error(`${this._name} - expected minConfidence to be a number between 0 and 1`);if(typeof this._maxResults!="number")throw new Error(`${this._name} - expected maxResults to be a number`)}get minConfidence(){return this._minConfidence}get maxResults(){return this._maxResults}}const at=x(require("@tensorflow/tfjs"));class Bt extends R{constructor(){super("SsdMobilenetv1")}forwardInput(t){const{params:e}=this;if(!e)throw new Error("SsdMobilenetv1 - load model before inference");return at.tidy(()=>{const o=at.cast(t.toBatchTensor(512,!1),"float32"),r=at.sub(at.mul(o,at.scalar(.007843137718737125)),at.scalar(1)),n=Mn(r,e.mobilenetv1),{boxPredictions:s,classPredictions:i}=Pn(n.out,n.conv11,e.prediction_layer);return Ln(s,i,e.output_layer)})}async forward(t){return this.forwardInput(await M(t))}async locateFaces(t,e={}){const{maxResults:o,minConfidence:r}=new X(e),n=await M(t),{boxes:s,scores:i}=this.forwardInput(n),a=s[0],c=i[0];for(let g=1;g<s.length;g++)s[g].dispose(),i[g].dispose();const p=Array.from(await c.data()),m=.5,f=Tn(a,p,o,m,r),d=n.getReshapedInputDimensions(0),h=n.inputSize,b=h/d.width,u=h/d.height,v=a.arraySync(),_=f.map(g=>{const[E,W]=[Math.max(0,v[g][0]),Math.min(1,v[g][2])].map(J=>J*u),[I,V]=[Math.max(0,v[g][1]),Math.min(1,v[g][3])].map(J=>J*b);return new D(p[g],new re(I,E,V-I,W-E),{height:n.getInputHeight(0),width:n.getInputWidth(0)})});return a.dispose(),c.dispose(),_}getDefaultModelName(){return"ssd_mobilenetv1_model"}extractParamsFromWeigthMap(t){return Fn(t)}extractParams(t){return yn(t)}}function $o(t){const e=new Bt;return e.extractWeights(t),e}function vr(t){return $o(t)}class _r extends Bt{}const En=.4,Dn=[new w(.738768,.874946),new w(2.42204,2.65704),new w(4.30971,7.04493),new w(10.246,4.59428),new w(12.6868,11.8741)],kn=[new w(1.603231,2.094468),new w(6.041143,7.080126),new w(2.882459,3.518061),new w(4.266906,5.178857),new w(9.041765,10.66308)],Cn=[117.001,114.697,97.404],Rn="tiny_yolov2_model",An="tiny_yolov2_separable_conv_model";const Io=t=>typeof t=="number";function Je(t){if(!t)throw new Error(`invalid config: ${t}`);if(typeof t.withSeparableConvs!="boolean")throw new Error(`config.withSeparableConvs has to be a boolean, have: ${t.withSeparableConvs}`);if(!Io(t.iouThreshold)||t.iouThreshold<0||t.iouThreshold>1)throw new Error(`config.iouThreshold has to be a number between [0, 1], have: ${t.iouThreshold}`);if(!Array.isArray(t.classes)||!t.classes.length||!t.classes.every(e=>typeof e=="string"))throw new Error(`config.classes has to be an array class names: string[], have: ${JSON.stringify(t.classes)}`);if(!Array.isArray(t.anchors)||!t.anchors.length||!t.anchors.map(e=>e||{}).every(e=>Io(e.x)&&Io(e.y)))throw new Error(`config.anchors has to be an array of { x: number, y: number }, have: ${JSON.stringify(t.anchors)}`);if(t.meanRgb&&(!Array.isArray(t.meanRgb)||t.meanRgb.length!==3||!t.meanRgb.every(Io)))throw new Error(`config.meanRgb has to be an array of shape [number, number, number], have: ${JSON.stringify(t.meanRgb)}`)}const tt=x(require("@tensorflow/tfjs"));function xe(t){return tt.tidy(()=>{const e=tt.mul(t,tt.scalar(.10000000149011612));return tt.add(tt.relu(tt.sub(t,e)),e)})}const et=x(require("@tensorflow/tfjs"));function wt(t,e){return et.tidy(()=>{let o=et.pad(t,[[0,0],[1,1],[1,1],[0,0]]);return o=et.conv2d(o,e.conv.filters,[1,1],"valid"),o=et.sub(o,e.bn.sub),o=et.mul(o,e.bn.truediv),o=et.add(o,e.conv.bias),xe(o)})}const jt=x(require("@tensorflow/tfjs"));function vt(t,e){return jt.tidy(()=>{let o=jt.pad(t,[[0,0],[1,1],[1,1],[0,0]]);return o=jt.separableConv2d(o,e.depthwise_filter,e.pointwise_filter,[1,1],"valid"),o=jt.add(o,e.bias),xe(o)})}const cr=x(require("@tensorflow/tfjs"));function bs(t,e){const o=pe(t,e);function r(i,a){const c=cr.tensor1d(t(i)),p=cr.tensor1d(t(i));return e.push({paramPath:`${a}/sub`},{paramPath:`${a}/truediv`}),{sub:c,truediv:p}}function n(i,a,c){const p=o(i,a,3,`${c}/conv`),m=r(a,`${c}/bn`);return{conv:p,bn:m}}const s=me(t,e);return{extractConvParams:o,extractConvWithBatchNormParams:n,extractSeparableConvParams:s}}function Sn(t,e,o,r){const{extractWeights:n,getRemainingWeights:s}=j(t),i=[],{extractConvParams:a,extractConvWithBatchNormParams:c,extractSeparableConvParams:p}=bs(n,i);let m;if(e.withSeparableConvs){const[f,d,h,b,u,v,_,g,E]=r,W=e.isFirstLayerConv2d?a(f,d,3,"conv0"):p(f,d,"conv0"),I=p(d,h,"conv1"),V=p(h,b,"conv2"),J=p(b,u,"conv3"),_t=p(u,v,"conv4"),bt=p(v,_,"conv5"),yt=g?p(_,g,"conv6"):void 0,Nt=E?p(g,E,"conv7"):void 0,Wt=a(E||g||_,5*o,1,"conv8");m={conv0:W,conv1:I,conv2:V,conv3:J,conv4:_t,conv5:bt,conv6:yt,conv7:Nt,conv8:Wt}}else{const[f,d,h,b,u,v,_,g,E]=r,W=c(f,d,"conv0"),I=c(d,h,"conv1"),V=c(h,b,"conv2"),J=c(b,u,"conv3"),_t=c(u,v,"conv4"),bt=c(v,_,"conv5"),yt=c(_,g,"conv6"),Nt=c(g,E,"conv7"),Wt=a(E,5*o,1,"conv8");m={conv0:W,conv1:I,conv2:V,conv3:J,conv4:_t,conv5:bt,conv6:yt,conv7:Nt,conv8:Wt}}if(s().length!==0)throw new Error(`weights remaing after extract: ${s().length}`);return{params:m,paramMappings:i}}function ys(t,e){const o=$(t,e);function r(a){const c=o(`${a}/sub`,1),p=o(`${a}/truediv`,1);return{sub:c,truediv:p}}function n(a){const c=o(`${a}/filters`,4),p=o(`${a}/bias`,1);return{filters:c,bias:p}}function s(a){const c=n(`${a}/conv`),p=r(`${a}/bn`);return{conv:c,bn:p}}const i=fe(o);return{extractConvParams:n,extractConvWithBatchNormParams:s,extractSeparableConvParams:i}}function jn(t,e){const o=[],{extractConvParams:r,extractConvWithBatchNormParams:n,extractSeparableConvParams:s}=ys(t,o);let i;if(e.withSeparableConvs){const a=e.filterSizes&&e.filterSizes.length||9;i={conv0:e.isFirstLayerConv2d?r("conv0"):s("conv0"),conv1:s("conv1"),conv2:s("conv2"),conv3:s("conv3"),conv4:s("conv4"),conv5:s("conv5"),conv6:a>7?s("conv6"):void 0,conv7:a>8?s("conv7"):void 0,conv8:r("conv8")}}else i={conv0:n("conv0"),conv1:n("conv1"),conv2:n("conv2"),conv3:n("conv3"),conv4:n("conv4"),conv5:n("conv5"),conv6:n("conv6"),conv7:n("conv7"),conv8:r("conv8")};return S(t,o),{params:i,paramMappings:o}}var Xe;(function(t){t[t.XS=224]="XS",t[t.SM=320]="SM",t[t.MD=416]="MD",t[t.LG=608]="LG"})(Xe||(Xe={}));class it{constructor({inputSize:t,scoreThreshold:e}={}){if(this._name="TinyYolov2Options",this._inputSize=t||416,this._scoreThreshold=e||.5,typeof this._inputSize!="number"||this._inputSize%32!==0)throw new Error(`${this._name} - expected inputSize to be a number divisible by 32`);if(typeof this._scoreThreshold!="number"||this._scoreThreshold<=0||this._scoreThreshold>=1)throw new Error(`${this._name} - expected scoreThreshold to be a number between 0 and 1`)}get inputSize(){return this._inputSize}get scoreThreshold(){return this._scoreThreshold}}const P=x(require("@tensorflow/tfjs"));class we extends R{constructor(t){super("TinyYolov2");Je(t),this._config=t}get config(){return this._config}get withClassScores(){return this.config.withClassScores||this.config.classes.length>1}get boxEncodingSize(){return 5+(this.withClassScores?this.config.classes.length:0)}runTinyYolov2(t,e){let o=wt(t,e.conv0);return o=P.maxPool(o,[2,2],[2,2],"same"),o=wt(o,e.conv1),o=P.maxPool(o,[2,2],[2,2],"same"),o=wt(o,e.conv2),o=P.maxPool(o,[2,2],[2,2],"same"),o=wt(o,e.conv3),o=P.maxPool(o,[2,2],[2,2],"same"),o=wt(o,e.conv4),o=P.maxPool(o,[2,2],[2,2],"same"),o=wt(o,e.conv5),o=P.maxPool(o,[2,2],[1,1],"same"),o=wt(o,e.conv6),o=wt(o,e.conv7),Vt(o,e.conv8,"valid",!1)}runMobilenet(t,e){let o=this.config.isFirstLayerConv2d?xe(Vt(t,e.conv0,"valid",!1)):vt(t,e.conv0);return o=P.maxPool(o,[2,2],[2,2],"same"),o=vt(o,e.conv1),o=P.maxPool(o,[2,2],[2,2],"same"),o=vt(o,e.conv2),o=P.maxPool(o,[2,2],[2,2],"same"),o=vt(o,e.conv3),o=P.maxPool(o,[2,2],[2,2],"same"),o=vt(o,e.conv4),o=P.maxPool(o,[2,2],[2,2],"same"),o=vt(o,e.conv5),o=P.maxPool(o,[2,2],[1,1],"same"),o=e.conv6?vt(o,e.conv6):o,o=e.conv7?vt(o,e.conv7):o,Vt(o,e.conv8,"valid",!1)}forwardInput(t,e){const{params:o}=this;if(!o)throw new Error("TinyYolov2 - load model before inference");return P.tidy(()=>{let r=P.cast(t.toBatchTensor(e,!1),"float32");return r=this.config.meanRgb?q(r,this.config.meanRgb):r,r=r.div(P.scalar(256)),this.config.withSeparableConvs?this.runMobilenet(r,o):this.runTinyYolov2(r,o)})}async forward(t,e){return await this.forwardInput(await M(t),e)}async detect(t,e={}){const{inputSize:o,scoreThreshold:r}=new it(e),n=await M(t),s=await this.forwardInput(n,o),i=P.tidy(()=>P.unstack(s)[0].expandDims()),a={width:n.getInputWidth(0),height:n.getInputHeight(0)},c=await this.extractBoxes(i,n.getReshapedInputDimensions(0),r);s.dispose(),i.dispose();const p=c.map(u=>u.box),m=c.map(u=>u.score),f=c.map(u=>u.classScore),d=c.map(u=>this.config.classes[u.label]),h=Ke(p.map(u=>u.rescale(o)),m,this.config.iouThreshold,!0),b=h.map(u=>new zt(m[u],f[u],d[u],p[u],a));return b}getDefaultModelName(){return""}extractParamsFromWeigthMap(t){return jn(t,this.config)}extractParams(t){const e=this.config.filterSizes||we.DEFAULT_FILTER_SIZES,o=e?e.length:void 0;if(o!==7&&o!==8&&o!==9)throw new Error(`TinyYolov2 - expected 7 | 8 | 9 convolutional filters, but found ${o} filterSizes in config`);return Sn(t,this.config,this.boxEncodingSize,e)}async extractBoxes(t,e,o){const{width:r,height:n}=e,s=Math.max(r,n),i=s/r,a=s/n,c=t.shape[1],p=this.config.anchors.length,[m,f,d]=P.tidy(()=>{const v=t.reshape([c,c,p,this.boxEncodingSize]),_=v.slice([0,0,0,0],[c,c,p,4]),g=v.slice([0,0,0,4],[c,c,p,1]),E=this.withClassScores?P.softmax(v.slice([0,0,0,5],[c,c,p,this.config.classes.length]),3):P.scalar(0);return[_,g,E]}),h=[],b=await f.array(),u=await m.array();for(let v=0;v<c;v++)for(let _=0;_<c;_++)for(let g=0;g<p;g++){const E=Kt(b[v][_][g][0]);if(!o||E>o){const W=(_+Kt(u[v][_][g][0]))/c*i,I=(v+Kt(u[v][_][g][1]))/c*a,V=Math.exp(u[v][_][g][2])*this.config.anchors[g].x/c*i,J=Math.exp(u[v][_][g][3])*this.config.anchors[g].y/c*a,_t=W-V/2,bt=I-J/2,yt={row:v,col:_,anchor:g},{classScore:Nt,label:Wt}=this.withClassScores?await this.extractPredictedClass(d,yt):{classScore:1,label:0};h.push({box:new se(_t,bt,_t+V,bt+J),score:E,classScore:E*Nt,label:Wt,...yt})}}return m.dispose(),f.dispose(),d.dispose(),h}async extractPredictedClass(t,e){const{row:o,col:r,anchor:n}=e,s=await t.array();return Array(this.config.classes.length).fill(0).map((i,a)=>s[o][r][n][a]).map((i,a)=>({classScore:i,label:a})).reduce((i,a)=>i.classScore>a.classScore?i:a)}}we.DEFAULT_FILTER_SIZES=[3,16,32,64,128,256,512,1024,1024];class qt extends we{constructor(t=!0){const e=Object.assign({},{withSeparableConvs:t,iouThreshold:En,classes:["face"]},t?{anchors:kn,meanRgb:Cn}:{anchors:Dn,withClassScores:!0});super(e)}get withSeparableConvs(){return this.config.withSeparableConvs}get anchors(){return this.config.anchors}async locateFaces(t,e){const o=await this.detect(t,e);return o.map(r=>new D(r.score,r.relativeBox,{width:r.imageWidth,height:r.imageHeight}))}getDefaultModelName(){return this.withSeparableConvs?An:Rn}extractParamsFromWeigthMap(t){return super.extractParamsFromWeigthMap(t)}}function xr(t,e=!0){const o=new qt(e);return o.extractWeights(t),o}class qe extends it{constructor(){super(...arguments);this._name="TinyFaceDetectorOptions"}}class Z{async then(t){return t(await this.run())}async run(){throw new Error("ComposableTask - run is not implemented")}}const pr=x(require("@tensorflow/tfjs"));async function Xt(t,e,o,r,n=({alignedRect:s})=>s){const s=t.map(c=>Tt(c)?n(c):c.detection),i=r||(e instanceof pr.Tensor?await $t(e,s):await It(e,s)),a=await o(i);return i.forEach(c=>c instanceof pr.Tensor&&c.dispose()),a}async function ve(t,e,o,r,n){return Xt([t],e,async s=>o(s[0]),r,n)}const Nn=.4,Wn=[new w(1.603231,2.094468),new w(6.041143,7.080126),new w(2.882459,3.518061),new w(4.266906,5.178857),new w(9.041765,10.66308)],Bn=[117.001,114.697,97.404];class Zt extends we{constructor(){const t={withSeparableConvs:!0,iouThreshold:Nn,classes:["face"],anchors:Wn,meanRgb:Bn,isFirstLayerConv2d:!0,filterSizes:[3,16,32,64,128,256,512]};super(t)}get anchors(){return this.config.anchors}async locateFaces(t,e){const o=await this.detect(t,e);return o.map(r=>new D(r.score,r.relativeBox,{width:r.imageWidth,height:r.imageHeight}))}getDefaultModelName(){return"tiny_face_detector_model"}extractParamsFromWeigthMap(t){return super.extractParamsFromWeigthMap(t)}}const y={ssdMobilenetv1:new Bt,tinyFaceDetector:new Zt,tinyYolov2:new qt,faceLandmark68Net:new te,faceLandmark68TinyNet:new co,faceRecognitionNet:new Qt,faceExpressionNet:new mo,ageGenderNet:new vo},zo=(t,e)=>y.ssdMobilenetv1.locateFaces(t,e),Fr=(t,e)=>y.tinyFaceDetector.locateFaces(t,e),Mr=(t,e)=>y.tinyYolov2.locateFaces(t,e),Go=t=>y.faceLandmark68Net.detectLandmarks(t),Tr=t=>y.faceLandmark68TinyNet.detectLandmarks(t),Lr=t=>y.faceRecognitionNet.computeFaceDescriptor(t),Pr=t=>y.faceExpressionNet.predictExpressions(t),Er=t=>y.ageGenderNet.predictAgeAndGender(t),Ho=t=>y.ssdMobilenetv1.load(t),Dr=t=>y.tinyFaceDetector.load(t),kr=t=>y.tinyYolov2.load(t),Cr=t=>y.faceLandmark68Net.load(t),Rr=t=>y.faceLandmark68TinyNet.load(t),Ar=t=>y.faceRecognitionNet.load(t),Sr=t=>y.faceExpressionNet.load(t),jr=t=>y.ageGenderNet.load(t),Nr=Ho,Wr=zo,Br=Go;class Un extends Z{constructor(t,e,o){super();this.parentTask=t,this.input=e,this.extractedFaces=o}}class $e extends Un{async run(){const t=await this.parentTask,e=await Xt(t,this.input,async o=>await Promise.all(o.map(r=>y.faceExpressionNet.predictExpressions(r))),this.extractedFaces);return t.map((o,r)=>Pe(o,e[r]))}withAgeAndGender(){return new Ue(this,this.input)}}class Oe extends Un{async run(){const t=await this.parentTask;if(!t)return;const e=await ve(t,this.input,o=>y.faceExpressionNet.predictExpressions(o),this.extractedFaces);return Pe(t,e)}withAgeAndGender(){return new Ie(this,this.input)}}class ye extends $e{withAgeAndGender(){return new _e(this,this.input)}withFaceDescriptors(){return new Ft(this,this.input)}}class Fe extends Oe{withAgeAndGender(){return new be(this,this.input)}withFaceDescriptor(){return new Mt(this,this.input)}}class In extends Z{constructor(t,e,o){super();this.parentTask=t,this.input=e,this.extractedFaces=o}}class Ue extends In{async run(){const t=await this.parentTask,e=await Xt(t,this.input,async o=>await Promise.all(o.map(r=>y.ageGenderNet.predictAgeAndGender(r))),this.extractedFaces);return t.map((o,r)=>{const{age:n,gender:s,genderProbability:i}=e[r];return De(Le(o,s,i),n)})}withFaceExpressions(){return new $e(this,this.input)}}class Ie extends In{async run(){const t=await this.parentTask;if(!t)return;const{age:e,gender:o,genderProbability:r}=await ve(t,this.input,n=>y.ageGenderNet.predictAgeAndGender(n),this.extractedFaces);return De(Le(t,o,r),e)}withFaceExpressions(){return new Oe(this,this.input)}}class _e extends Ue{withFaceExpressions(){return new ye(this,this.input)}withFaceDescriptors(){return new Ft(this,this.input)}}class be extends Ie{withFaceExpressions(){return new Fe(this,this.input)}withFaceDescriptor(){return new Mt(this,this.input)}}class ao extends Z{constructor(t,e){super();this.parentTask=t,this.input=e}}class Ft extends ao{async run(){const t=await this.parentTask,e=await Xt(t,this.input,o=>Promise.all(o.map(r=>y.faceRecognitionNet.computeFaceDescriptor(r))),null,o=>o.landmarks.align(null,{useDlibAlignment:!0}));return e.map((o,r)=>Ee(t[r],o))}withFaceExpressions(){return new ye(this,this.input)}withAgeAndGender(){return new _e(this,this.input)}}class Mt extends ao{async run(){const t=await this.parentTask;if(!t)return;const e=await ve(t,this.input,o=>y.faceRecognitionNet.computeFaceDescriptor(o),null,o=>o.landmarks.align(null,{useDlibAlignment:!0}));return Ee(t,e)}withFaceExpressions(){return new Fe(this,this.input)}withAgeAndGender(){return new be(this,this.input)}}const ze=x(require("@tensorflow/tfjs"));class ro extends Z{constructor(t,e,o){super();this.parentTask=t,this.input=e,this.useTinyLandmarkNet=o}get landmarkNet(){return this.useTinyLandmarkNet?y.faceLandmark68TinyNet:y.faceLandmark68Net}}class no extends ro{async run(){const t=await this.parentTask,e=t.map(n=>n.detection),o=this.input instanceof ze.Tensor?await $t(this.input,e):await It(this.input,e),r=await Promise.all(o.map(n=>this.landmarkNet.detectLandmarks(n)));return o.forEach(n=>n instanceof ze.Tensor&&n.dispose()),t.map((n,s)=>Ut(n,r[s]))}withFaceExpressions(){return new ye(this,this.input)}withAgeAndGender(){return new _e(this,this.input)}withFaceDescriptors(){return new Ft(this,this.input)}}class so extends ro{async run(){const t=await this.parentTask;if(!t)return;const{detection:e}=t,o=this.input instanceof ze.Tensor?await $t(this.input,[e]):await It(this.input,[e]),r=await this.landmarkNet.detectLandmarks(o[0]);return o.forEach(n=>n instanceof ze.Tensor&&n.dispose()),Ut(t,r)}withFaceExpressions(){return new Fe(this,this.input)}withAgeAndGender(){return new be(this,this.input)}withFaceDescriptor(){return new Mt(this,this.input)}}class eo extends Z{constructor(t,e=new X){super();this.input=t,this.options=e}}class Te extends eo{async run(){const{input:t,options:e}=this,o=e instanceof qe?r=>y.tinyFaceDetector.locateFaces(r,e):e instanceof X?r=>y.ssdMobilenetv1.locateFaces(r,e):e instanceof it?r=>y.tinyYolov2.locateFaces(r,e):null;if(!o)throw new Error("detectFaces - expected options to be instance of TinyFaceDetectorOptions | SsdMobilenetv1Options | MtcnnOptions | TinyYolov2Options");return o(t)}runAndExtendWithFaceDetections(){return new Promise(async t=>{const e=await this.run();return t(e.map(o=>Lt({},o)))})}withFaceLandmarks(t=!1){return new no(this.runAndExtendWithFaceDetections(),this.input,t)}withFaceExpressions(){return new $e(this.runAndExtendWithFaceDetections(),this.input)}withAgeAndGender(){return new Ue(this.runAndExtendWithFaceDetections(),this.input)}}class oo extends eo{async run(){const t=await new Te(this.input,this.options);let e=t[0];return t.forEach(o=>{o.score>e.score&&(e=o)}),e}runAndExtendWithFaceDetection(){return new Promise(async t=>{const e=await this.run();return t(e?Lt({},e):void 0)})}withFaceLandmarks(t=!1){return new so(this.runAndExtendWithFaceDetection(),this.input,t)}withFaceExpressions(){return new Oe(this.runAndExtendWithFaceDetection(),this.input)}withAgeAndGender(){return new Ie(this.runAndExtendWithFaceDetection(),this.input)}}function Ur(t,e=new X){return new oo(t,e)}function Me(t,e=new X){return new Te(t,e)}async function Yo(t,e){return console.warn("allFacesSsdMobilenetv1 is deprecated and will be removed soon, use the high level api instead"),await Me(t,new X(e?{minConfidence:e}:{})).withFaceLandmarks().withFaceDescriptors()}async function Ir(t,e={}){return console.warn("allFacesTinyYolov2 is deprecated and will be removed soon, use the high level api instead"),await Me(t,new it(e)).withFaceLandmarks().withFaceDescriptors()}const $r=Yo;function fo(t,e){if(t.length!==e.length)throw new Error("euclideanDistance: arr1.length !== arr2.length");const o=Array.from(t),r=Array.from(e);return Math.sqrt(o.map((n,s)=>n-r[s]).reduce((n,s)=>n+Math.pow(s,2),0))}class Vo{constructor(t,e=.6){this._distanceThreshold=e;const o=Array.isArray(t)?t:[t];if(!o.length)throw new Error("FaceRecognizer.constructor - expected atleast one input");let r=1;const n=()=>`person ${r++}`;this._labeledDescriptors=o.map(s=>{if(s instanceof Ct)return s;if(s instanceof Float32Array)return new Ct(n(),[s]);if(s.descriptor&&s.descriptor instanceof Float32Array)return new Ct(n(),[s.descriptor]);throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array | Array<LabeledFaceDescriptors | WithFaceDescriptor<any> | Float32Array>")})}get labeledDescriptors(){return this._labeledDescriptors}get distanceThreshold(){return this._distanceThreshold}computeMeanDistance(t,e){return e.map(o=>fo(o,t)).reduce((o,r)=>o+r,0)/(e.length||1)}matchDescriptor(t){return this.labeledDescriptors.map(({descriptors:e,label:o})=>new Re(o,this.computeMeanDistance(t,e))).reduce((e,o)=>e.distance<o.distance?e:o)}findBestMatch(t){const e=this.matchDescriptor(t);return e.distance<this.distanceThreshold?e:new Re("unknown",e.distance)}toJSON(){return{distanceThreshold:this.distanceThreshold,labeledDescriptors:this.labeledDescriptors.map(t=>t.toJSON())}}static fromJSON(t){const e=t.labeledDescriptors.map(o=>Ct.fromJSON(o));return new Vo(e,t.distanceThreshold)}}function wr(t){const e=new Zt;return e.extractWeights(t),e}function Oo(t,e){const{width:o,height:r}=new B(e.width,e.height);if(o<=0||r<=0)throw new Error(`resizeResults - invalid dimensions: ${JSON.stringify({width:o,height:r})}`);if(Array.isArray(t))return t.map(n=>Oo(n,{width:o,height:r}));if(Tt(t)){const n=t.detection.forSize(o,r),s=t.unshiftedLandmarks.forSize(n.box.width,n.box.height);return Ut(Lt(t,n),s)}return ot(t)?Lt(t,t.detection.forSize(o,r)):t instanceof G||t instanceof D?t.forSize(o,r):t}var ur="0.5.3";return Zr();})();
|
|
//# sourceMappingURL=face-api.min.js.map
|