(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.faceapi = global.faceapi || {})); }(this, function (exports) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } /** * @license * Copyright 2019 Google LLC. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============================================================================= */ var t=function(e,n){return (t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e;}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);})(e,n)};function e(e,n){function r(){this.constructor=e;}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r);}var n=function(){return (n=Object.assign||function(t){for(var e,n=1,r=arguments.length;n0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0;)r=Math.random()*e|0,n=t[--e],t[e]=t[r],t[r]=n;}function h(t,e,n){return Math.max(t,Math.min(e,n))}function p(t){return t%2==0?t:t+1}function f(t){for(var e=0,n=0;n=n?o():setTimeout(i,s);}};i();})}function I(t,e){for(var n=1,r=-1,o=0;o=0)n*=t[o];else if(-1===t[o]){if(-1!==r)throw Error("Shapes can only have 1 implicit size. Found -1 at dim "+r+" and dim "+o);r=o;}else if(t[o]<0)throw Error("Shapes can not be < 0. Found "+t[o]+" at dim "+o);if(-1===r){if(e>0&&e!==n)throw Error("Size("+e+") must match the product of shape "+t);return t}if(0===n)throw Error("Cannot infer the missing size in ["+t+"] when there are 0 elements");if(e%n!=0)throw Error("The implicit shape can't be a fractional number. Got "+e+" / "+n);var a=t.slice();return a[r]=e/n,a}function S(t,e){var n=e.length;return d((t=null==t?e.map(function(t,e){return e}):[].concat(t)).every(function(t){return t>=-n&&ti)&&1===t[i]&&(n.push(t[i]),r.push(i)),o[a]<=i&&a++;}1!==t[i]&&(n.push(t[i]),r.push(i));}return {newShape:n,keptDims:r}}function k(t,e){var n=null;if(null==t||"float32"===t)n=new Float32Array(e);else if("int32"===t)n=new Int32Array(e);else{if("bool"!==t)throw new Error("Unknown data type "+t);n=new Uint8Array(e);}return n}function A(t,e){var n=null;if(null==t||"float32"===t)n=new Float32Array(e);else if("int32"===t)n=new Int32Array(e);else if("bool"===t)n=new Uint8Array(e);else{if("string"!==t)throw new Error("Unknown data type "+t);n=new Array(e);}return n}function T(t,e,n){if("float32"===e)for(var r=0;r=0;--r)n[r]=n[r+1]*t[r+1];return n}function q(t,e,n){if("string"===e)throw new Error("Cannot convert a string[] to a TypedArray");if(Array.isArray(t)&&(t=g(t)),n&&D(t,e),function(t,e){return t instanceof Float32Array&&"float32"===e||t instanceof Int32Array&&"int32"===e||t instanceof Uint8Array&&"bool"===e}(t,e))return t;if(null==e||"float32"===e||"complex64"===e)return new Float32Array(t);if("int32"===e)return new Int32Array(t);if("bool"===e){for(var r=new Uint8Array(t.length),o=0;o=0,function(){return "Tensor must have a shape comprised of positive integers but got shape ["+t+"]."});});}function Y(t,e){return s.platform.fetch(t,e)}var Q=Object.freeze({shuffle:c,clamp:h,nearestLargerEven:p,sum:f,randUniform:function(t,e){var n=Math.random();return e*n+(1-n)*t},distSquared:function(t,e){for(var n=0,r=0;r1)for(var l=0;ltt){var h=et*s,p=Array.from(e.slice(0,h)),f=Array.from(e.slice(u-et*s,u));return "complex64"===r&&(p=it(p),f=it(f)),["["+p.map(function(t,e){return ot(t,a[e],r)}).join(", ")+", ..., "+f.map(function(t,e){return ot(t,a[u-et+e],r)}).join(", ")+"]"]}var d="complex64"===r?it(e):Array.from(e);return ["["+d.map(function(t,e){return ot(t,a[e],r)}).join(", ")+"]"]}var v=n.slice(1);var m=o.slice(1);var g=o[0]*s;var y=[];if(u>tt){for(var x=0;x=this.shape[n]){var i="Requested out of range element at "+t+". Buffer shape="+this.shape;throw new Error(i)}n++;}for(var s=t[t.length-1],u=0;u0&&(t.unreliable=!0,null==t.reasons&&(t.reasons=[]),t.reasons.push("Memory usage by string tensors is approximate (2 bytes per character)")),t},t.prototype.profile=function(t){return r(this,void 0,void 0,function(){var e,n;return o(this,function(r){return this.state.profiling=!0,e=this.state.numBytes,n=this.state.numTensors,this.state.activeProfile.kernels=[],this.state.activeProfile.result=t(),this.state.profiling=!1,this.state.activeProfile.peakBytes=Math.max.apply(Math,this.state.activeProfile.kernels.map(function(t){return t.totalBytesSnapshot})),this.state.activeProfile.newBytes=this.state.numBytes-e,this.state.activeProfile.newTensors=this.state.numTensors-n,[2,this.state.activeProfile]})})},t.prototype.isTapeOn=function(){return this.state.gradientDepth>0&&0===this.state.kernelDepth},t.prototype.addTapeNode=function(t,e,n){var r={};t.forEach(function(t,e){r[e]=t;});var o={id:this.state.nextTapeNodeId++,name:this.state.activeScope.name,inputs:r,outputs:[e],gradient:function(t){var e=n(t),r={};return e.forEach(function(t,e){r[e]=function(){return t};}),r}};this.state.activeTape.push(o);},t.prototype.keep=function(t){return t.kept=!0,t},t.prototype.startTape=function(){0===this.state.gradientDepth&&(this.state.activeTape=[]),this.state.gradientDepth++;},t.prototype.endTape=function(){this.state.gradientDepth--;},t.prototype.startScope=function(t){var e={track:[],name:"unnamed scope",id:this.state.nextScopeId++};t&&(e.name=t),this.state.scopeStack.push(e),this.state.activeScope=e;},t.prototype.endScope=function(t){for(var e=this,n=Rt(t),r=new Set(n.map(function(t){return t.id})),o=0;o0,function(){return "gradients() received an empty list of xs."}),null!=n&&"float32"!==n.dtype)throw new Error("dy must have 'float32' dtype, but has '"+n.dtype+"'");var a=this.scopedRun(function(){return o.startTape()},function(){return o.endTape()},function(){return o.tidy("forward",t)});d(a instanceof ht,function(){return "The result y returned by f() must be a tensor."});var i=function(t,e,n){for(var r={},o={},a=0;a=0;a--)for(i=(d=t[a]).inputs,c=0;c0)throw new Error("Cannot compute gradient of y=f(x) with respect to x. Make sure that the f you passed encloses all operations that lead from x to y.");return this.tidy("backward",function(){var t,r,s={};s[a.id]=null==n?(t=a.shape,r=$(y(t),"float32"),ht.make(t,{values:r})):n,function(t,e,n){for(var r=function(r){var o=e[r],a=[];if(o.outputs.forEach(function(e){var n=t[e.id];if(null!=n)a.push(n);else{var r=ht.make(e.shape,{values:j(e.size,e.dtype)},e.dtype);a.push(r);}}),null==o.gradient)throw new Error("Cannot compute gradient: gradient function not found for "+o.name+".");var i=o.gradient(1===o.outputs.length?a[0]:a),s=function(e){if(!(e in i))throw new Error("Cannot backprop through input "+e+". Available gradients found: "+Object.keys(i)+".");var r=n(function(){return i[e]()});if("float32"!==r.dtype)throw new Error("Error in gradient for op "+o.name+". The gradient of input "+e+" must have 'float32' dtype, but has '"+r.dtype+"'");var a=o.inputs[e];if(!x(r.shape,a.shape))throw new Error("Error in gradient for op "+o.name+". The gradient of input '"+e+"' has shape '"+r.shape+"', which does not match the shape of the input '"+a.shape+"'");if(null==t[a.id])t[a.id]=r;else{var s=t[a.id];t[a.id]=s.add(r),s.dispose();}};for(var u in o.inputs)s(u);},o=e.length-1;o>=0;o--)r(o);}(s,i,function(t){return o.tidy(t)});var u=e.map(function(t){return s[t.id]});return 0===o.state.gradientDepth&&(o.state.activeTape.forEach(function(t){for(var e in t.saved)t.saved[e].dispose();}),o.state.activeTape=null),{value:a,grads:u}})},t.prototype.customGrad=function(t){var e=this;return d(z(t),function(){return "The f passed in customGrad(f) must be a function."}),function(){for(var n,r=[],o=0;on||e>n){r="["+t+"x"+e+"]";throw new Error("Requested texture size "+r+" greater than WebGL maximum on this browser / GPU "+("["+n+"x"+n+"]")+".")}}function Zt(t,e){return le(t,e,function(){return t.createFramebuffer()},"Unable to create WebGLFramebuffer.")}function te(t,e,n,r,o,a,i,s){var u=t.getAttribLocation(n,r);return -1!==u&&(Mt(t,e,function(){return t.bindBuffer(t.ARRAY_BUFFER,o)}),Mt(t,e,function(){return t.vertexAttribPointer(u,a,t.FLOAT,!1,i,s)}),Mt(t,e,function(){return t.enableVertexAttribArray(u)}),!0)}function ee(t,e,n,r){ce(t,r),Mt(t,e,function(){return t.activeTexture(t.TEXTURE0+r)}),Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,n)});}function ne(t,e,n,r){return le(t,e,function(){return t.getUniformLocation(n,r)},'uniform "'+r+'" not present in program.')}function re(t,e,n){return t.getUniformLocation(e,n)}function oe(t,e,n,r,o,a){Mt(t,e,function(){return ee(t,e,r,a)}),Mt(t,e,function(){return t.uniform1i(o,a)});}function ae(t,e,n,r){Mt(t,e,function(){return t.bindFramebuffer(t.FRAMEBUFFER,r)}),Mt(t,e,function(){return t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,n,0)});}function ie(t,e,n){Mt(t,e,function(){return t.bindFramebuffer(t.FRAMEBUFFER,n)}),Mt(t,e,function(){return t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,null,0)});}function se(t){var e=t.checkFramebufferStatus(t.FRAMEBUFFER);if(e!==t.FRAMEBUFFER_COMPLETE)throw new Error("Error binding framebuffer: "+ue(t,e))}function ue(t,e){switch(e){case t.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:return "FRAMEBUFFER_INCOMPLETE_ATTACHMENT";case t.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:return "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";case t.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:return "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";case t.FRAMEBUFFER_UNSUPPORTED:return "FRAMEBUFFER_UNSUPPORTED";default:return "unknown error "+e}}function le(t,e,n,r){var o=Mt(t,e,function(){return n()});if(null==o)throw new Error(r);return o}function ce(t,e){var n=t.MAX_COMBINED_TEXTURE_IMAGE_UNITS-1,r=e+t.TEXTURE0;if(rn)throw new Error("textureUnit must be in "+("[gl.TEXTURE0, gl.TEXTURE"+n+"]")+".")}function he(t,e){return void 0===e&&(e=2),y(t.slice(0,t.length-e))}function pe(t){if(0===t.length)throw Error("Cannot get rows and columns of an empty shape array.");return [t.length>1?t[t.length-2]:1,t[t.length-1]]}function fe(t){var e=[1,1,1];return 0===t.length||1===t.length&&1===t[0]||(e=[he(t)].concat(pe(t))),e}function de(t,e){var n;void 0===e&&(e=!1);var r=s.getNumber("WEBGL_MAX_TEXTURE_SIZE");if(e&&(r*=2,1===(t=t.map(function(e,n){return n>=t.length-2?p(t[n]):t[n]})).length&&(t=[2,t[0]])),2!==t.length){var o=N(t);t=o.newShape;}var a=y(t);if(t.length<=1&&a<=r)return [1,a];if(2===t.length&&t[0]<=r&&t[1]<=r)return t;if(3===t.length&&t[0]*t[1]<=r&&t[2]<=r)return [t[0]*t[1],t[2]];if(3===t.length&&t[0]<=r&&t[1]*t[2]<=r)return [t[0],t[1]*t[2]];if(4===t.length&&t[0]*t[1]*t[2]<=r&&t[3]<=r)return [t[0]*t[1]*t[2],t[3]];if(4===t.length&&t[0]<=r&&t[1]*t[2]*t[3]<=r)return [t[0],t[1]*t[2]*t[3]];if(e){var i=he(t),u=2,l=2;return t.length&&(u=(n=pe(t))[0],l=n[1]),C(a=i*(u/2)*(l/2)).map(function(t){return 2*t})}return C(a)}function ve(t){return t%2==0}function me(t,e){if(x(t=t.slice(-2),e=e.slice(-2)))return !0;if(!t.length||!e.length)return !0;if(0===t[0]||0===t[1]||0===e[0]||0===e[1])return !0;if(t.length!==e.length){var n=t.slice(-1)[0],r=e.slice(-1)[0];if(n===r)return !0;if(ve(n)&&ve(r)&&(1===t[0]||1===e[0]))return !0}return t[1]===e[1]&&ve(t[0])&&ve(e[0])}function ge(t){if(null==Gt){var e=Ft(t);Gt=e.getParameter(e.MAX_TEXTURE_SIZE);}return Gt}function ye(t){if(null==qt){var e=Ft(t);qt=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS);}return Math.min(16,qt)}function xe(t){if(0===t)return 0;var e=Ft(t);return be(e,"EXT_disjoint_timer_query_webgl2")&&2===t?2:be(e,"EXT_disjoint_timer_query")?1:0}function be(t,e){return null!=t.getExtension(e)}function we(t){try{if(null!=Ft(t))return !0}catch(t){return !1}return !1}function Ce(t){if(0===t)return !1;var e=Ft(t);if(1===t){if(!be(e,"OES_texture_float"))return !1}else if(!be(e,"EXT_color_buffer_float"))return !1;return Re(e,t)}function Ee(t){if(0===t)return !1;var e=Ft(t);if(1===t){if(!be(e,"OES_texture_float"))return !1;if(!be(e,"WEBGL_color_buffer_float"))return !1}else if(!be(e,"EXT_color_buffer_float"))return !1;return Re(e,t)}function Re(t,e){var n=t.createFramebuffer(),r=t.createTexture();t.bindTexture(t.TEXTURE_2D,r);var o=2===e?t.RGBA32F:t.RGBA;t.texImage2D(t.TEXTURE_2D,0,o,1,1,0,t.RGBA,t.FLOAT,null),t.bindFramebuffer(t.FRAMEBUFFER,n),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,r,0);var a=t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE;return t.bindTexture(t.TEXTURE_2D,null),t.bindFramebuffer(t.FRAMEBUFFER,null),t.deleteTexture(r),t.deleteFramebuffer(n),a}function Ie(t){return 2===t&&null!=Ft(t).fenceSync}var Se=Object.freeze({callAndCheck:Mt,canBeRepresented:Lt,getWebGLErrorMessage:Wt,getExtensionOrThrow:Ut,createVertexShader:zt,createFragmentShader:Vt,createProgram:$t,linkProgram:jt,validateProgram:Kt,createStaticVertexBuffer:Xt,createStaticIndexBuffer:Yt,getNumChannels:function(){return 2===s.getNumber("WEBGL_VERSION")?1:4},createTexture:Qt,validateTextureSize:Jt,createFramebuffer:Zt,bindVertexBufferToProgramAttribute:te,bindTextureUnit:ee,unbindTextureUnit:function(t,e,n){ce(t,n),Mt(t,e,function(){return t.activeTexture(t.TEXTURE0+n)}),Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)});},getProgramUniformLocationOrThrow:ne,getProgramUniformLocation:re,bindTextureToProgramUniformSampler:oe,bindCanvasToFramebuffer:function(t,e){Mt(t,e,function(){return t.bindFramebuffer(t.FRAMEBUFFER,null)}),Mt(t,e,function(){return t.viewport(0,0,t.canvas.width,t.canvas.height)}),Mt(t,e,function(){return t.scissor(0,0,t.canvas.width,t.canvas.height)});},bindColorTextureToFramebuffer:ae,unbindColorTextureFromFramebuffer:ie,validateFramebuffer:se,getFramebufferErrorMessage:ue,getBatchDim:he,getRowsCols:pe,getShapeAs3D:fe,getTextureShapeFromLogicalShape:de,isReshapeFree:me,get MAX_TEXTURE_SIZE(){return Gt},get MAX_TEXTURES_IN_SHADER(){return qt},getWebGLMaxTextureSize:ge,getMaxTexturesInShader:ye,getWebGLDisjointQueryTimerVersion:xe,isWebGLVersionEnabled:we,isRenderToFloatTextureEnabled:Ce,isDownloadFloatTextureEnabled:Ee,isWebGLFenceEnabled:Ie});function Ne(){s.set("PROD",!0);}function ke(){s.set("DEBUG",!0);}function Ae(){s.set("DEPRECATION_WARNINGS_ENABLED",!1),console.warn("TensorFlow.js deprecation warnings have been disabled.");}function Te(t){s.getBool("DEPRECATION_WARNINGS_ENABLED")&&console.warn(t+" You can disable deprecation warnings with tf.disableDeprecationWarnings().");}function De(){At.disposeVariables();}function _e(){return At.memory()}function Oe(t){return At.profile(t)}function Fe(t,e){return At.tidy(t,e)}function Me(t){Rt(t).forEach(function(t){return t.dispose()});}function Be(t){return At.keep(t)}function Pe(t){return At.time(t)}function Le(t){return At.setBackend(t)}function We(){return At.ready()}function Ue(){return At.backendName}function ze(t){At.removeBackend(t);}function Ve(t){return At.findBackend(t)}function Ge(t){return At.findBackendFactory(t)}function qe(t,e,n){return void 0===n&&(n=1),At.registerBackend(t,e,n)}function He(){return At.backend}function $e(t,e){s.setPlatform(t,e);}function je(){for(var t=[],e=0;e0,function(){return "Element arr["+r.join("][")+"] should be a primitive, but is an array of "+e.length+" elements"});d(e.length===n[0],function(){return "Element arr["+r.join("][")+"] should have "+n[0]+" elements, but has "+e.length+" elements"});var o=n.slice(1);for(var a=0;a=0&&(o=r),Xe(r,o,e,n),null==t||!F(t)&&!Array.isArray(t)&&"number"!=typeof t&&"boolean"!=typeof t&&"string"!=typeof t){var a=null==t?"null":t.constructor.name;throw new Error("Argument '"+e+"' passed to '"+n+"' must be a Tensor or TensorLike, but got '"+a+"'")}var i=Ke(t);F(t)||Array.isArray(t)||(t=[t]);var u="string"!==o?q(t,o,s.getBool("DEBUG")):g(t);return ht.make(i,{values:u},o)}function Qe(t,e,n,r){if(void 0===r&&(r="numeric"),!Array.isArray(t))throw new Error("Argument "+e+" passed to "+n+" must be a `Tensor[]` or `TensorLike[]`");return t.map(function(t,r){return Ye(t,e+"["+r+"]",n)},r)}function Je(t,e){for(var n=0;n=0&&e0}),s.registerFlag("WEBGL_VERSION",function(){return we(2)?2:we(1)?1:0}),s.registerFlag("WEBGL_BUFFER_SUPPORTED",function(){return 2===s.get("WEBGL_VERSION")}),s.registerFlag("WEBGL_CPU_FORWARD",function(){return !0}),s.registerFlag("WEBGL_PACK",function(){return s.getBool("HAS_WEBGL")}),s.registerFlag("WEBGL_PACK_NORMALIZATION",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_PACK_CLIP",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_PACK_DEPTHWISECONV",function(){return !1}),s.registerFlag("WEBGL_PACK_BINARY_OPERATIONS",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_PACK_ARRAY_OPERATIONS",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_PACK_IMAGE_OPERATIONS",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_PACK_REDUCE",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_LAZILY_UNPACK",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_CONV_IM2COL",function(){return s.getBool("WEBGL_PACK")}),s.registerFlag("WEBGL_MAX_TEXTURE_SIZE",function(){return ge(s.getNumber("WEBGL_VERSION"))}),s.registerFlag("WEBGL_MAX_TEXTURES_IN_SHADER",function(){return ye(s.getNumber("WEBGL_VERSION"))}),s.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION",function(){var t=s.getNumber("WEBGL_VERSION");return 0===t?0:xe(t)}),s.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE",function(){return s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0&&(t=navigator.userAgent||navigator.vendor||window.opera,!(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4))));var t;}),s.registerFlag("WEBGL_RENDER_FLOAT32_ENABLED",function(){return Ce(s.getNumber("WEBGL_VERSION"))}),s.registerFlag("WEBGL_DOWNLOAD_FLOAT_ENABLED",function(){return Ee(s.getNumber("WEBGL_VERSION"))}),s.registerFlag("WEBGL_FENCE_API_ENABLED",function(){return Ie(s.getNumber("WEBGL_VERSION"))}),s.registerFlag("WEBGL_SIZE_UPLOAD_UNIFORM",function(){return s.getBool("WEBGL_RENDER_FLOAT32_ENABLED")?4:0}),ct=Te;var cn=ln({complex_:function(t,e){var n=Ye(t,"real","complex"),r=Ye(e,"imag","complex");return v(n.shape,r.shape,"real and imag shapes, "+n.shape+" and "+r.shape+", must match in call to tf.complex()."),At.runKernel(function(t){return t.complex(n,r)},{$real:n,$imag:r})}}),hn=ln({real_:function(t){var e=Ye(t,"input","real");return At.runKernel(function(t){return t.real(e)},{$input:e})}}),pn=ln({imag_:function(t){var e=Ye(t,"input","imag");return At.runKernel(function(t){return t.imag(e)},{$input:e})}});function fn(t,e,n){return dn(t,e,Ke(t),n)}function dn(t,e,n,r){if(null==r&&(r=U(t)),"complex64"===r)throw new Error("Cannot construct a complex64 tensor directly. Please use tf.complex(real, imag).");if(!F(t)&&!Array.isArray(t)&&"number"!=typeof t&&"boolean"!=typeof t&&"string"!=typeof t)throw new Error("values passed to tensor(values) must be a number/boolean/string or an array of numbers/booleans/strings, or a TypedArray");if(null!=e){X(e);var o=y(e),a=y(n);d(o===a,function(){return "Based on the provided shape, ["+e+"], the tensor should have "+o+" values but has "+a});for(var i=0;i1)return En([0],r);var o=j(Math.abs(Math.ceil((e-t)/n)),r);e=1,function(){return "Pass at least one tensor to concat"});var n=Qe(t,"tensors","concat");e=S(e,n[0].shape)[0];var r=un(n.map(function(t){return t.shape}),e);if(0===y(r))return fn([],r);if(1===(n=n.filter(function(t){return t.size>0})).length)return n[0];var o=n.map(function(t){return t.shape});sn(o,e);var a=n;return At.runKernel(function(t){return t.concat(n,e)},a,function(t){var n=o.map(function(t){return t[e]});return Fn(t,n,e).map(function(t){return function(){return t}})})}}),Tn=ln({concat1d_:function(t){return An(t,0)}}),Dn=ln({concat2d_:function(t,e){return An(t,e)}}),_n=ln({concat3d_:function(t,e){return An(t,e)}}),On=ln({concat4d_:function(t,e){return An(t,e)}}),Fn=ln({split_:function(t,e,n){void 0===n&&(n=0);var r,o=Ye(t,"x","split");return n=S(n,o.shape)[0],"number"==typeof e?(d(o.shape[n]%e==0,function(){return "Number of splits must evenly divide the axis."}),r=new Array(e).fill(o.shape[n]/e)):(d(o.shape[n]===e.reduce(function(t,e){return t+e}),function(){return "The sum of sizes must match the size of the axis dimension."}),r=e),At.runKernel(function(t){return t.split(o,r,n)},{$x:o},function(t){return {$x:function(){return An(t,n)}}})}});function Mn(t,e){return t(e={exports:{}},e.exports),e.exports}var Bn=Mn(function(t){!function(t,e,n){function r(t){var e,n=this,r=(e=4022871197,function(t){t=t.toString();for(var n=0;n>>0,e=(r*=e)>>>0,e+=4294967296*(r-=e);}return 2.3283064365386963e-10*(e>>>0)});n.next=function(){var t=2091639*n.s0+2.3283064365386963e-10*n.c;return n.s0=n.s1,n.s1=n.s2,n.s2=t-(n.c=0|t)},n.c=1,n.s0=r(" "),n.s1=r(" "),n.s2=r(" "),n.s0-=r(t),n.s0<0&&(n.s0+=1),n.s1-=r(t),n.s1<0&&(n.s1+=1),n.s2-=r(t),n.s2<0&&(n.s2+=1),r=null;}function o(t,e){return e.c=t.c,e.s0=t.s0,e.s1=t.s1,e.s2=t.s2,e}function a(t,e){var n=new r(t),a=e&&e.state,i=n.next;return i.int32=function(){return 4294967296*n.next()|0},i.double=function(){return i()+1.1102230246251565e-16*(2097152*i()|0)},i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.alea=a;}(0,t,!1);}),Pn=Mn(function(t){!function(t,e,n){function r(t){var e=this,n="";e.x=0,e.y=0,e.z=0,e.w=0,e.next=function(){var t=e.x^e.x<<11;return e.x=e.y,e.y=e.z,e.z=e.w,e.w^=e.w>>>19^t^t>>>8},t===(0|t)?e.x=t:n+=t;for(var r=0;r>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21);}while(0===t);return t},i.int32=n.next,i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xor128=a;}(0,t,!1);}),Ln=Mn(function(t){!function(t,e,n){function r(t){var e=this,n="";e.next=function(){var t=e.x^e.x>>>2;return e.x=e.y,e.y=e.z,e.z=e.w,e.w=e.v,(e.d=e.d+362437|0)+(e.v=e.v^e.v<<4^t^t<<1)|0},e.x=0,e.y=0,e.z=0,e.w=0,e.v=0,t===(0|t)?e.x=t:n+=t;for(var r=0;r>>4),e.next();}function o(t,e){return e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e.v=t.v,e.d=t.d,e}function a(t,e){var n=new r(t),a=e&&e.state,i=function(){return (n.next()>>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21);}while(0===t);return t},i.int32=n.next,i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xorwow=a;}(0,t,!1);}),Wn=Mn(function(t){!function(t,e,n){function r(t){var e=this;e.next=function(){var t,n,r=e.x,o=e.i;return t=r[o],n=(t^=t>>>7)^t<<24,n^=(t=r[o+1&7])^t>>>10,n^=(t=r[o+3&7])^t>>>3,n^=(t=r[o+4&7])^t<<7,t=r[o+7&7],n^=(t^=t<<13)^t<<9,r[o]=n,e.i=o+1&7,n},function(t,e){var n,r=[];if(e===(0|e))r[0]=e;else for(e=""+e,n=0;n0;--n)t.next();}(e,t);}function o(t,e){return e.x=t.x.slice(),e.i=t.i,e}function a(t,e){null==t&&(t=+new Date);var n=new r(t),a=e&&e.state,i=function(){return (n.next()>>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21);}while(0===t);return t},i.int32=n.next,i.quick=i,a&&(a.x&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xorshift7=a;}(0,t,!1);}),Un=Mn(function(t){!function(t,e,n){function r(t){var e=this;e.next=function(){var t,n,r=e.w,o=e.X,a=e.i;return e.w=r=r+1640531527|0,n=o[a+34&127],t=o[a=a+1&127],n^=n<<13,t^=t<<17,n^=n>>>15,t^=t>>>12,n=o[a]=n^t,e.i=a,n+(r^r>>>16)|0},function(t,e){var n,r,o,a,i,s=[],u=128;for(e===(0|e)?(r=e,e=null):(e+="\0",r=0,u=Math.max(u,e.length)),o=0,a=-32;a>>15,r^=r<<4,r^=r>>>13,a>=0&&(i=i+1640531527|0,o=0==(n=s[127&a]^=r+i)?o+1:0);for(o>=128&&(s[127&(e&&e.length||0)]=-1),o=127,a=512;a>0;--a)r=s[o+34&127],n=s[o=o+1&127],r^=r<<13,n^=n<<17,r^=r>>>15,n^=n>>>12,s[o]=r^n;t.w=i,t.X=s,t.i=o;}(e,t);}function o(t,e){return e.i=t.i,e.w=t.w,e.X=t.X.slice(),e}function a(t,e){null==t&&(t=+new Date);var n=new r(t),a=e&&e.state,i=function(){return (n.next()>>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21);}while(0===t);return t},i.int32=n.next,i.quick=i,a&&(a.X&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xor4096=a;}(0,t,!1);}),zn=Mn(function(t){!function(t,e,n){function r(t){var e=this,n="";e.next=function(){var t=e.b,n=e.c,r=e.d,o=e.a;return t=t<<25^t>>>7^n,n=n-r|0,r=r<<24^r>>>8^o,o=o-t|0,e.b=t=t<<20^t>>>12^n,e.c=n=n-r|0,e.d=r<<16^n>>>16^o,e.a=o-t|0},e.a=0,e.b=0,e.c=-1640531527,e.d=1367130551,t===Math.floor(t)?(e.a=t/4294967296|0,e.b=0|t):n+=t;for(var r=0;r>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21);}while(0===t);return t},i.int32=n.next,i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.tychei=a;}(0,t,!1);}),Vn=Mn(function(t){!function(e,n){var r,o=this,a=256,i=6,s="random",u=n.pow(a,i),l=n.pow(2,52),c=2*l,h=a-1;function p(t,h,p){var g=[],y=v(function t(e,n){var r,o=[],a=typeof e;if(n&&"object"==a)for(r in e)try{o.push(t(e[r],n-1));}catch(t){}return o.length?o:"string"==a?e:e+"\0"}((h=1==h?{entropy:!0}:h||{}).entropy?[t,m(e)]:null==t?function(){try{var t;return r&&(t=r.randomBytes)?t=t(a):(t=new Uint8Array(a),(o.crypto||o.msCrypto).getRandomValues(t)),m(t)}catch(t){var n=o.navigator,i=n&&n.plugins;return [+new Date,o,i,o.screen,m(e)]}}():t,3),g),x=new f(g),b=function(){for(var t=x.g(i),e=u,n=0;t=c;)t/=2,e/=2,n>>>=1;return (t+n)/e};return b.int32=function(){return 0|x.g(4)},b.quick=function(){return x.g(4)/4294967296},b.double=b,v(m(x.S),e),(h.pass||p||function(t,e,r,o){return o&&(o.S&&d(o,x),t.state=function(){return d(x,{})}),r?(n[s]=t,e):t})(b,y,"global"in h?h.global:this==n,h.state)}function f(t){var e,n=t.length,r=this,o=0,i=r.i=r.j=0,s=r.S=[];for(n||(t=[n++]);o=1||0===i);var s=Math.sqrt(-2*Math.log(i)/i);e=this.mean+this.stdDev*o*s,n=this.mean+this.stdDev*a*s,this.truncated&&!this.isValidTruncated(e)||(r=!0);}return this.truncated&&!this.isValidTruncated(n)||(this.nextVal=this.convertValue(n)),this.convertValue(e)},t.prototype.convertValue=function(t){return null==this.dtype||"float32"===this.dtype?t:Math.round(t)},t.prototype.isValidTruncated=function(t){return t<=this.upper&&t>=this.lower},t}(),Hn=function(){function t(t,e,n,r){void 0===t&&(t=0),void 0===e&&(e=1);var o=this;if(this.canReturnFloat=function(){return null==o.dtype||"float32"===o.dtype},this.min=t,this.range=e-t,this.dtype=n,null==r&&(r=Math.random()),"number"==typeof r&&(r=r.toString()),!this.canReturnFloat()&&this.range<=1)throw new Error("The difference between "+t+" - "+e+" <= 1 and dtype is not float");this.random=Gn(r);}return t.prototype.convertValue=function(t){return this.canReturnFloat()?t:Math.round(t)},t.prototype.nextValue=function(){return this.convertValue(this.min+this.range*this.random())},t}();function $n(t,e,n){return void 0===e&&(e="float32"),e=e||"float32",X(t),new st(t,e,n)}function jn(t,e){void 0===e&&(e=!1),console.log(t.toString(e));}var Kn=ln({batchToSpaceND_:function(t,e,n){var r=Ye(t,"x","batchToSpaceND"),o=e.reduce(function(t,e){return t*e});return d(r.rank>=1+e.length,function(){return "input rank is "+r.rank+" but should be > than blockShape.length "+e.length}),d(n.length===e.length,function(){return "crops.length is "+n.length+" but should be equal to blockShape.length "+e.length}),d(r.shape[0]%o==0,function(){return "input tensor batch is "+r.shape[0]+" but is not divisible by the product of the elements of blockShape "+e.join(" * ")+" === "+o}),At.runKernel(function(t){return t.batchToSpaceND(r,e,n)},{$x:r},function(t){return {$x:function(){return t.spaceToBatchND(e,n)}}})}}),Xn=ln({cast_:function(t,e){var n=Ye(t,"x","cast");if(!_(e))throw new Error("Failed to cast to unknown dtype "+e);if("string"===e&&"string"!==n.dtype||"string"!==e&&"string"===n.dtype)throw new Error("Only strings can be casted to strings");return At.runKernel(function(t){return t.cast(n,e)},{$x:n},function(t){return {$x:function(){return t.clone()}}})}}),Yn=ln({clone_:function(t){var e=Ye(t,"x","clone",null);return At.runKernel(function(t){return ht.make(e.shape,{dataId:e.dataId},e.dtype)},{$x:e},function(t){return {$x:function(){return t.toFloat()}}})}}),Qn=ln({cumsum_:function(t,e,n,r){void 0===e&&(e=0),void 0===n&&(n=!1),void 0===r&&(r=!1);var o=Ye(t,"x","cumsum"),a=rn([e|=0],o.rank),i=o;null!=a&&(i=o.transpose(a));var s=an(1,o.rank)[0],u=At.runKernel(function(t){return t.cumsum(i,s,n,r)},{permutedX:i},function(t){return {permutedX:function(){return t.cumsum(e,n,!r)}}});return null!=a&&(u=u.transpose(a)),u}}),Jn=ln({depthToSpace_:function(t,e,n){void 0===n&&(n="NHWC");var r=Ye(t,"x","depthToSpace"),o="NHWC"===n?r.shape[1]:r.shape[2],a="NHWC"===n?r.shape[2]:r.shape[3],i="NHWC"===n?r.shape[3]:r.shape[1];return d(o*e>=0,function(){return "Negative dimension size caused by overflow when multiplying\n "+o+" and "+e+" for depthToSpace with input shape\n "+r.shape}),d(a*e>=0,function(){return "Negative dimension size caused by overflow when multiplying\n "+a+" and "+e+" for depthToSpace with input shape\n "+r.shape}),d(i%(e*e)==0,function(){return "Dimension size must be evenly divisible by "+e*e+" but is "+i+" for depthToSpace with input shape "+r.shape}),At.runKernel(function(t){return t.depthToSpace(r,e,n)},{$x:r})}}),Zn=ln({expandDims_:function(t,e){void 0===e&&(e=0);var n=Ye(t,"x","expandDims",null);d(e<=n.rank,function(){return "Axis must be <= rank of the tensor"});var r=n.shape.slice();return e<0&&(d(-(n.rank+1)<=e,function(){return "Axis must be in the interval ["+-(n.rank+1)+", "+n.rank+"]"}),e=n.rank+e+1),r.splice(e,0,1),hr(n,r)}}),tr=ln({eye_:function(t,e,n,r){void 0===r&&(r="float32"),null==e&&(e=t);for(var o=$n([t,e],r),a=t<=e?t:e,i=0;i2)throw new Error("Rank of probabilities must be 1 or 2, but is "+i);n=n||Math.random();var s=1===i?o.as2D(1,-1):o,u=At.runKernel(function(t){return t.multinomial(s,r,e,n)},{logits2D:s});return 1===i?u.as1D():u}}),nr=ln({oneHot_:function(t,e,n,r){if(void 0===n&&(n=1),void 0===r&&(r=0),e<2)throw new Error("Error in oneHot: depth must be >=2, but it is "+e);var o=Ye(t,"indices","oneHot","int32"),a=o.shape.concat([e]);return o=o.flatten(),At.runKernel(function(t){return t.oneHot(o,e,n,r)},{$indices:o},function(t){return {$indices:function(){return En(o.shape,"float32")}}}).reshape(a)}}),rr=ln({pad_:function(t,e,n){void 0===n&&(n=0);var r=Ye(t,"x","pad");if(0===r.rank)throw new Error("pad(scalar) is not defined. Pass non-scalar to pad");var o=e.map(function(t){return t[0]});return At.runKernel(function(t){return t.pad(r,e,n)},{$x:r},function(t){return {$x:function(){return t.slice(o,r.shape)}}})}}),or=ln({pad1d_:function(t,e,n){return void 0===n&&(n=0),d(2===e.length,function(){return "Invalid number of paddings. Must be length of 2."}),rr(t,[e],n)}}),ar=ln({pad2d_:function(t,e,n){return void 0===n&&(n=0),d(2===e.length&&2===e[0].length&&2===e[1].length,function(){return "Invalid number of paddings. Must be length of 2 each."}),rr(t,e,n)}}),ir=ln({pad3d_:function(t,e,n){return void 0===n&&(n=0),d(3===e.length&&2===e[0].length&&2===e[1].length&&2===e[2].length,function(){return "Invalid number of paddings. Must be length of 2 each."}),rr(t,e,n)}}),sr=ln({pad4d_:function(t,e,n){return void 0===n&&(n=0),d(4===e.length&&2===e[0].length&&2===e[1].length&&2===e[2].length&&2===e[3].length,function(){return "Invalid number of paddings. Must be length of 2 each."}),rr(t,e,n)}}),ur=ln({rand_:function(t,e,n){var r=y(t),o=null;if(null==n||"float32"===n)o=new Float32Array(r);else if("int32"===n)o=new Int32Array(r);else{if("bool"!==n)throw new Error("Unknown data type "+n);o=new Uint8Array(r);}for(var a=0;a=1+e.length,function(){return "input rank "+r.rank+" should be > than [blockShape] "+e.length}),d(n.length===e.length,function(){return "paddings.shape[0] "+n.length+" must be equal to [blockShape] "+e.length}),d(r.shape.reduce(function(t,r,o){return o>0&&o<=e.length?t&&(r+n[o-1][0]+n[o-1][1])%e[o-1]==0:t},!0),function(){return "input spatial dimensions "+r.shape.slice(1)+" with paddings "+n.toString()+" must be divisible by blockShapes "+e.toString()}),At.runKernel(function(t){return t.spaceToBatchND(r,e,n)},{$x:r},function(t){return {$x:function(){return t.batchToSpaceND(e,n)}}})}}),fr=ln({squeeze_:function(t,e){var n=Ye(t,"x","squeeze");return hr(n,N(n.shape,e).newShape)}}),dr=ln({stack_:function(t,e){void 0===e&&(e=0);var n=Qe(t,"tensors","stack");if(d(n.length>=1,function(){return "Pass at least one tensor to tf.stack"}),1===n.length)return n[0].expandDims(e);var r=n[0].rank,o=n[0].shape,a=n[0].dtype;d(e<=r,function(){return "Axis must be <= rank of the tensor"}),n.forEach(function(t){v(o,t.shape,"All tensors passed to stack must have matching shapes");}),n.forEach(function(t){d(a===t.dtype,function(){return "All tensors passed to stack must have matching dtypes"});});var i=n.map(function(t){return t.expandDims(e)});return An(i,e)}}),vr=ln({tile_:function(t,e){var n=Ye(t,"x","tile",null);return d(n.rank===e.length,function(){return "Error in transpose: rank of input "+n.rank+" must match length of reps "+e+"."}),At.runKernel(function(t,r){var o=t.tile(n,e);return r([n]),o},{$x:n},function(t,n){var r=n[0];return {$x:function(){var n=kn(r);if(1===r.rank)for(var o=0;o=-n.shape.length&&e=2*e+1||o%2==1?i.push(o):a.push(o);r.push.apply(r,a),r.push(0),r.push.apply(r,i);}return r}function wr(t,e,n,r){void 0===r&&(r=!0);var o=[];r?o.push(t[0]/n):o.push(t[0]*n);for(var a=1;at.rank)throw new Error("index innermost dimension length must be <= tensor rank; saw: "+e.shape[e.rank-1]+" vs. "+t.rank);if(0===t.size)throw new Error("Requested more than 0 entries, but input is empty. Input shape: "+t.shape+".");for(var n=e.shape,r=n[n.length-1],o=1,a=0;a1?e.shape[e.rank-1]:1,o=e.rank>1?e.rank-1:1,a="Must have updates.shape = indices.shape[:batchDim] + shape[sliceDim:], got updates.shape: "+n.shape+", indices.shape: "+e.shape+", shape: "+t+", sliceDim: "+r+", and batchDim: "+o+".";if(n.rank1?e.shape[e.rank-1]:1,o=n.length,a=1,i=r;i0?a>=c[e]:a<=c[e]);a+=o)n+=1;return n}),[l,f,h]}function Tr(t,e,n,r,o){var a=e[o],i=n[o]||1;(t&1<0?Number.MIN_SAFE_INTEGER:Number.MAX_SAFE_INTEGER);var s=r[o];return a<0&&(a+=s),a=h(0,a,s-1)}function Dr(t,e,n,r,o){var a=e[o],i=n[o]||1;(t&1<0?Number.MAX_SAFE_INTEGER:Number.MIN_SAFE_INTEGER);var s=r[o];return a<0&&(a+=s),a=i>0?h(0,a,s):h(-1,a,s-1)}function _r(t,e,n){for(var r=n.length,o=0;o1){r=o;break}for(o=r+1;o0||n[o]!==t[o])return !1;return !0}function Or(t,e){for(var n=t.length>0?t[t.length-1]:1,r=0;r0,function(){return "variableGrads() expects at least one of the input variables to be trainable, but none of the "+a+" variables is trainable."});var i=At.gradients(t,e,null,!0),s=i.value,u=i.grads;d(u.some(function(t){return null!=t}),function(){return "Cannot find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize()."}),d(0===s.rank,function(){return "The f passed in variableGrads(f) must return a scalar, but it returned a rank-"+s.rank+" tensor"});var l={};return e.forEach(function(t,e){null!=u[e]&&(l[t.name]=u[e]);}),null!=o&&o.forEach(function(t){return l[t.name]=null}),{value:s,grads:l}}function Wr(t){return At.customGrad(t)}function Ur(t){if(t.filter(function(t){return null==t}).length>0)throw new Error("Cannot compute gradient of y=f(x) with respect to x. Make sure that\n the f you passed encloses all operations that lead from x to y.")}var zr=ln({softmax_:function(t,e){void 0===e&&(e=-1);var n=Ye(t,"logits","softmax");if(-1===e&&(e=n.rank-1),e!==n.rank-1)throw Error("Softmax along a non-last dimension is not yet supported. Logits was rank "+n.rank+" and dim was "+e);return Wr(function(t,n){var r=t.logSumExp([e],!0),o=t.toFloat().sub(r).exp();return n([o]),{value:o,gradFunc:function(t,n){var r=n[0],o=t.mul(r);return o.sub(o.sum([e],!0).mul(r))}}})(n)}}),Vr=ln({logSoftmax_:function(t,e){void 0===e&&(e=-1);var n=Ye(t,"logits","logSoftmax");if(-1===e&&(e=n.rank-1),e!==n.rank-1)throw Error("Log Softmax along a non-last dimension is not yet supported. Logits was rank "+n.rank+" and axis was "+e);return Wr(function(t,n){var r=t.max(e,!0),o=t.sub(r),a=o.toFloat().sub(o.exp().sum(e,!0).log());return n([a]),{value:a,gradFunc:function(t,n){var r=n[0].exp();return t.sub(t.sum(e,!0).mul(r))}}})(n)}}),Gr=function(){function t(t,e){this.backend=t,this.dataMover=e,this.data=new WeakMap;}return t.prototype.get=function(t){return this.data.has(t)||this.dataMover.moveData(this.backend,t),this.data.get(t)},t.prototype.set=function(t,e){this.data.set(t,e);},t.prototype.has=function(t){return this.data.has(t)},t.prototype.delete=function(t){return this.data.delete(t)},t}(),qr=function(){function t(){}return t.prototype.time=function(t){throw new Error("Not yet implemented.")},t.prototype.read=function(t){throw new Error("Not yet implemented.")},t.prototype.readSync=function(t){throw new Error("Not yet implemented.")},t.prototype.disposeData=function(t){throw new Error("Not yet implemented.")},t.prototype.write=function(t,e){throw new Error("Not yet implemented.")},t.prototype.fromPixels=function(t,e){throw new Error("Not yet implemented.")},t.prototype.register=function(t,e,n){throw new Error("Not yet implemented.")},t.prototype.memory=function(){throw new Error("Not yet implemented.")},t.prototype.floatPrecision=function(){throw new Error("Not yet implemented")},t.prototype.epsilon=function(){return 32===this.floatPrecision()?1e-7:1e-4},t.prototype.batchMatMul=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.fusedBatchMatMul=function(t,e,n,r,o,a){throw new Error("Not yet implemented")},t.prototype.slice=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.stridedSlice=function(t,e,n,r,o,a,i,s,u){throw new Error("Not yet implemented")},t.prototype.unstack=function(t,e){throw new Error("Not yet implemented")},t.prototype.reverse=function(t,e){throw new Error("Not yet implemented")},t.prototype.concat=function(t,e){throw new Error("Not yet implemented")},t.prototype.neg=function(t){throw new Error("Not yet implemented")},t.prototype.add=function(t,e){throw new Error("Not yet implemented")},t.prototype.addN=function(t){throw new Error("Not yet implemented")},t.prototype.subtract=function(t,e){throw new Error("Not yet implemented")},t.prototype.multiply=function(t,e){throw new Error("Not yet implemented")},t.prototype.realDivide=function(t,e){throw new Error("Not yet implemented")},t.prototype.floorDiv=function(t,e){throw new Error("Not yet implemented")},t.prototype.sum=function(t,e){throw new Error("Not yet implemented")},t.prototype.prod=function(t,e){throw new Error("Not yet implemented")},t.prototype.unsortedSegmentSum=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.argMin=function(t,e){throw new Error("Not yet implemented")},t.prototype.argMax=function(t,e){throw new Error("Not yet implemented")},t.prototype.equal=function(t,e){throw new Error("Not yet implemented")},t.prototype.notEqual=function(t,e){throw new Error("Not yet implemented")},t.prototype.less=function(t,e){throw new Error("Not yet implemented")},t.prototype.lessEqual=function(t,e){throw new Error("Not yet implemented")},t.prototype.greater=function(t,e){throw new Error("Not yet implemented")},t.prototype.greaterEqual=function(t,e){throw new Error("Not yet implemented")},t.prototype.logicalNot=function(t){throw new Error("Not yet implemented")},t.prototype.logicalAnd=function(t,e){throw new Error("Not yet implemented")},t.prototype.logicalOr=function(t,e){throw new Error("Not yet implemented")},t.prototype.where=function(t){throw new Error("Not yet implemented")},t.prototype.select=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.topk=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.min=function(t,e){throw new Error("Not yet implemented")},t.prototype.minimum=function(t,e){throw new Error("Not yet implemented")},t.prototype.mod=function(t,e){throw new Error("Not yet implemented")},t.prototype.max=function(t,e){throw new Error("Not yet implemented")},t.prototype.maximum=function(t,e){throw new Error("Not yet implemented")},t.prototype.all=function(t,e){throw new Error("Not yet implemented")},t.prototype.any=function(t,e){throw new Error("Not yet implemented")},t.prototype.squaredDifference=function(t,e){throw new Error("Not yet implemented")},t.prototype.ceil=function(t){throw new Error("Not yet implemented")},t.prototype.floor=function(t){throw new Error("Not yet implemented")},t.prototype.round=function(t){throw new Error("Not yet implemented")},t.prototype.sign=function(t){throw new Error("Not yet implemented")},t.prototype.isNaN=function(t){throw new Error("Not yet implemented")},t.prototype.isInf=function(t){throw new Error("Not yet implemented")},t.prototype.isFinite=function(t){throw new Error("Not yet implemented")},t.prototype.pow=function(t,e){throw new Error("Not yet implemented")},t.prototype.exp=function(t){throw new Error("Not yet implemented")},t.prototype.expm1=function(t){throw new Error("Not yet implemented")},t.prototype.log=function(t){throw new Error("Not yet implemented")},t.prototype.log1p=function(t){throw new Error("Not yet implemented")},t.prototype.sqrt=function(t){throw new Error("Not yet implemented")},t.prototype.rsqrt=function(t){throw new Error("Not yet implemented")},t.prototype.square=function(t){throw new Error("Not yet implemented")},t.prototype.reciprocal=function(t){throw new Error("Not yet implemented")},t.prototype.relu=function(t){throw new Error("Not yet implemented")},t.prototype.prelu=function(t,e){throw new Error("Not yet implemented")},t.prototype.elu=function(t){throw new Error("Not yet implemented")},t.prototype.eluDer=function(t,e){throw new Error("Not yet implemented")},t.prototype.selu=function(t){throw new Error("Not yet implemented")},t.prototype.int=function(t){throw new Error("Not yet implemented")},t.prototype.clip=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.abs=function(t){throw new Error("Not yet implemented")},t.prototype.complexAbs=function(t){throw new Error("Not yet implemented")},t.prototype.sigmoid=function(t){throw new Error("Not yet implemented")},t.prototype.softplus=function(t){throw new Error("Not yet implemented")},t.prototype.sin=function(t){throw new Error("Not yet implemented")},t.prototype.cos=function(t){throw new Error("Not yet implemented")},t.prototype.tan=function(t){throw new Error("Not yet implemented")},t.prototype.asin=function(t){throw new Error("Not yet implemented")},t.prototype.acos=function(t){throw new Error("Not yet implemented")},t.prototype.atan=function(t){throw new Error("Not yet implemented")},t.prototype.atan2=function(t,e){throw new Error("Not yet implemented")},t.prototype.sinh=function(t){throw new Error("Not yet implemented")},t.prototype.cosh=function(t){throw new Error("Not yet implemented")},t.prototype.tanh=function(t){throw new Error("Not yet implemented")},t.prototype.asinh=function(t){throw new Error("Not yet implemented")},t.prototype.acosh=function(t){throw new Error("Not yet implemented")},t.prototype.atanh=function(t){throw new Error("Not yet implemented")},t.prototype.erf=function(t){throw new Error("Not yet implemented")},t.prototype.step=function(t,e){throw new Error("Not yet implemented")},t.prototype.conv2d=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv2dDerInput=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv2dDerFilter=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.depthwiseConv2D=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.depthwiseConv2DDerInput=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.depthwiseConv2DDerFilter=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv3d=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv3dDerInput=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv3dDerFilter=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.maxPool=function(t,e){throw new Error("Not yet implemented")},t.prototype.maxPoolBackprop=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.avgPool=function(t,e){throw new Error("Not yet implemented")},t.prototype.avgPoolBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.reshape=function(t,e){throw new Error("Not yet implemented")},t.prototype.cast=function(t,e){throw new Error("Not yet implemented")},t.prototype.tile=function(t,e){throw new Error("Not yet implemented")},t.prototype.pad=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.transpose=function(t,e){throw new Error("Not yet implemented")},t.prototype.gather=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.gatherND=function(t,e){throw new Error("Not yet implemented")},t.prototype.scatterND=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.batchToSpaceND=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.spaceToBatchND=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.resizeBilinear=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.resizeBilinearBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.resizeNearestNeighbor=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.resizeNearestNeighborBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.batchNormalization=function(t,e,n,r,o,a){throw new Error("Not yet implemented")},t.prototype.localResponseNormalization4D=function(t,e,n,r,o){throw new Error("Not yet implemented")},t.prototype.LRNGrad=function(t,e,n,r,o,a,i){throw new Error("Not yet implemented")},t.prototype.multinomial=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.oneHot=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.cumsum=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.nonMaxSuppression=function(t,e,n,r,o){throw new Error("Not yet implemented")},t.prototype.fft=function(t){throw new Error("Not yet implemented")},t.prototype.ifft=function(t){throw new Error("Not yet implemented")},t.prototype.complex=function(t,e){throw new Error("Not yet implemented")},t.prototype.real=function(t){throw new Error("Not yet implemented")},t.prototype.imag=function(t){throw new Error("Not yet implemented")},t.prototype.cropAndResize=function(t,e,n,r,o,a){throw new Error("Not yet implemented")},t.prototype.depthToSpace=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.split=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.sparseToDense=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.fill=function(t,e,n){throw new Error("Not yet implemented.")},t.prototype.onesLike=function(t){throw new Error("Not yet implemented")},t.prototype.zerosLike=function(t){throw new Error("Not yet implemented")},t.prototype.linspace=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.dispose=function(){throw new Error("Not yet implemented")},t}();function Hr(t,e){for(var n=t.length,r=[],o=0;o1&&1===i&&r.unshift(a);}return r}function $r(t,e){for(var n=[],r=0;r1)&&n.unshift(a);}return n}function jr(t,e){for(var n=[],r=Math.max(t.length,e.length),o=0;oo}).sort(function(t,e){return e.score-t.score}),i=[],s=0;s=0;--p){if(fo(t,c,i[p])>=r){h=!0;break}}if(!h&&(i.push(c),i.length>=n))break}return mn(i,"int32")}function fo(t,e,n){var r=t.subarray(4*e,4*e+4),o=t.subarray(4*n,4*n+4),a=Math.min(r[0],r[2]),i=Math.min(r[1],r[3]),s=Math.max(r[0],r[2]),u=Math.max(r[1],r[3]),l=Math.min(o[0],o[2]),c=Math.min(o[1],o[3]),h=Math.max(o[0],o[2]),p=Math.max(o[1],o[3]),f=(s-a)*(u-i),d=(h-l)*(p-c);if(f<=0||d<=0)return 0;var v=Math.max(a,l),m=Math.max(i,c),g=Math.min(s,h),y=Math.min(u,p),x=Math.max(g-v,0)*Math.max(y-m,0);return x/(f+d-x)}function vo(t,e,n){var r=new Array(t.rank).fill(0),o=t.shape.slice();return e.map(function(e){o[n]=e;var a=t.slice(r,o);return r[n]+=e,a})}function mo(t,e){for(var n=new Array(t.rank),r=0;r":"<",u=n?"inOffset + i;":"round(getBestIndicesA(batch, inOffset + i));";this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = outIdx * "+r+";\n\n int bestIndex = inOffset;\n float bestValue = getA(batch, bestIndex);\n\n for (int i = 0; i < "+r+"; i++) {\n int inIdx = "+u+";\n float candidate = getA(batch, inIdx);\n if (candidate "+s+" bestValue) {\n bestValue = candidate;\n bestIndex = inIdx;\n }\n }\n setOutput(float(bestIndex));\n }\n ";}}();function Co(t,e){return ["x","y","z","w","u","v"].slice(0,e).map(function(e){return t+"."+e})}function Eo(t,e){return 1===e?[t]:Co(t,e)}function Ro(){var t,e,n,r,o,a,i,u,l,c;return 2===s.getNumber("WEBGL_VERSION")?(t="#version 300 es",e="in",n="out",r="in",o="texture",a="outputColor",i="out vec4 outputColor;",u="\n bool isnan_custom(float val) {\n return (val > 0. || val < 0. || val == 0.) ? false : true;\n }\n ",l="\n const float INFINITY = uintBitsToFloat(uint(0x7f800000));\n ",c="\n #define round(value) newRound(value)\n int newRound(float value) {\n return int(floor(value + 0.5));\n }\n\n ivec4 newRound(vec4 value) {\n return ivec4(floor(value + vec4(0.5)));\n }\n "):(t="",e="attribute",n="varying",r="varying",o="texture2D",a="gl_FragColor",i="",u="\n bool isnan_custom(float val) {\n return (val > 0. || val < 1. || val == 0.) ? false : true;\n }\n ",l="\n uniform float INFINITY;\n\n bool isinf(float val) {\n return abs(val) == INFINITY;\n }\n bvec4 isinf(vec4 val) {\n return equal(abs(val), vec4(INFINITY));\n }\n ",c="\n int round(float value) {\n return int(floor(value + 0.5));\n }\n\n ivec4 round(vec4 value) {\n return ivec4(floor(value + vec4(0.5)));\n }\n "),{version:t,attribute:e,varyingVs:n,varyingFs:r,texture2D:o,output:a,defineOutput:i,defineSpecialNaN:u,defineSpecialInf:l,defineRound:c}}function Io(t,e,n){void 0===n&&(n="index");var r=G(e);return r.map(function(e,o){return "int "+t[o]+" = "+n+" / "+e+"; "+(o===r.length-1?"int "+t[o+1]+" = "+n+" - "+t[o]+" * "+e:"index -= "+t[o]+" * "+e)+";"}).join("")}function So(t){var e=G(t).map(function(t){return t.toString()});return "\n int getFlatIndex(ivec3 coords) {\n return coords.x * "+e[0]+" + coords.y * "+e[1]+" + coords.z;\n }\n"}var No="\n const float FLOAT_MAX = 1.70141184e38;\n const float FLOAT_MIN = 1.17549435e-38;\n\n lowp vec4 encode_float(highp float v) {\n if (isnan(v)) {\n return vec4(255, 255, 255, 255);\n }\n\n highp float av = abs(v);\n\n if(av < FLOAT_MIN) {\n return vec4(0.0, 0.0, 0.0, 0.0);\n } else if(v > FLOAT_MAX) {\n return vec4(0.0, 0.0, 128.0, 127.0) / 255.0;\n } else if(v < -FLOAT_MAX) {\n return vec4(0.0, 0.0, 128.0, 255.0) / 255.0;\n }\n\n highp vec4 c = vec4(0,0,0,0);\n\n highp float e = floor(log2(av));\n highp float m = exp2(fract(log2(av))) - 1.0;\n\n c[2] = floor(128.0 * m);\n m -= c[2] / 128.0;\n c[1] = floor(32768.0 * m);\n m -= c[1] / 32768.0;\n c[0] = floor(8388608.0 * m);\n\n highp float ebias = e + 127.0;\n c[3] = floor(ebias / 2.0);\n ebias -= c[3] * 2.0;\n c[2] += floor(ebias) * 128.0;\n\n c[3] += 128.0 * step(0.0, -v);\n\n return c / 255.0;\n }\n";function ko(t,e,n,r){var o=[];t.forEach(function(t){var e=y(t.shapeInfo.logicalShape);t.shapeInfo.isUniform?o.push("uniform float "+t.name+(e>1?"["+e+"]":"")+";"):(o.push("uniform sampler2D "+t.name+";"),o.push("uniform int offset"+t.name+";"));});var a,i,s=o.join("\n"),u=t.map(function(t){return function(t,e,n){void 0===n&&(n=!1);var r="";r+=n?To(t):Ao(t);var o=t.shapeInfo.logicalShape,a=e.logicalShape;o.length<=a.length&&(r+=n?function(t,e){var n,r=t.name,o=r.charAt(0).toUpperCase()+r.slice(1),a="get"+o+"AtOutCoords",i=t.shapeInfo.logicalShape.length,s=e.logicalShape.length,u=Hr(t.shapeInfo.logicalShape,e.logicalShape),l=Po(s),c=s-i,h=["x","y","z","w","u","v"];n=0===i?"":s<2&&u.length>=1?"coords = 0;":u.map(function(t){return "coords."+h[t+c]+" = 0;"}).join("\n");var p="";p=s<2&&i>0?"coords":t.shapeInfo.logicalShape.map(function(t,e){return "coords."+h[e+c]}).join(", ");var f="return outputValue;",d=1===y(t.shapeInfo.logicalShape),v=1===y(e.logicalShape);if(1!==i||d||v){if(d&&!v)f=1===s?"\n return vec4(outputValue.x, outputValue.x, 0., 0.);\n ":"\n return vec4(outputValue.x);\n ";else if(u.length){var m=i-2,g=i-1;u.indexOf(m)>-1&&u.indexOf(g)>-1?f="return vec4(outputValue.x);":u.indexOf(m)>-1?f="return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);":u.indexOf(g)>-1&&(f="return vec4(outputValue.xx, outputValue.zz);");}}else f="\n return vec4(outputValue.xy, outputValue.xy);\n ";return "\n vec4 "+a+"() {\n "+l+" coords = getOutputCoords();\n "+n+"\n vec4 outputValue = get"+o+"("+p+");\n "+f+"\n }\n "}(t,e):function(t,e){var n=t.name,r=n.charAt(0).toUpperCase()+n.slice(1),o="get"+r+"AtOutCoords",a=e.texShape,i=t.shapeInfo.texShape,s=t.shapeInfo.logicalShape.length,u=e.logicalShape.length;if(!t.shapeInfo.isUniform&&s===u&&null==t.shapeInfo.flatOffset&&x(i,a))return "\n float "+o+"() {\n return sampleTexture("+n+", resultUV);\n }\n ";var l,c=Po(u),h=Hr(t.shapeInfo.logicalShape,e.logicalShape),p=u-s,f=["x","y","z","w","u","v"];l=0===s?"":u<2&&h.length>=1?"coords = 0;":h.map(function(t){return "coords."+f[t+p]+" = 0;"}).join("\n");var d="";d=u<2&&s>0?"coords":t.shapeInfo.logicalShape.map(function(t,e){return "coords."+f[e+p]}).join(", ");return "\n float "+o+"() {\n "+c+" coords = getOutputCoords();\n "+l+"\n return get"+r+"("+d+");\n }\n "}(t,e));return r}(t,e,r)}).join("\n"),l=e.texShape,c=Ro(),h=function(t){return "\n float sampleTexture(sampler2D textureSampler, vec2 uv) {\n return "+t.texture2D+"(textureSampler, uv).r;\n }\n "}(c),p=function(t){return t.version+"\n precision highp float;\n precision highp int;\n precision highp sampler2D;\n "+t.varyingFs+" vec2 resultUV;\n "+t.defineOutput+"\n const vec2 halfCR = vec2(0.5, 0.5);\n\n struct ivec5\n {\n int x;\n int y;\n int z;\n int w;\n int u;\n };\n\n struct ivec6\n {\n int x;\n int y;\n int z;\n int w;\n int u;\n int v;\n };\n\n uniform float NAN;\n #define isnan(value) isnan_custom(value)\n "+t.defineSpecialNaN+"\n bvec4 isnan_custom(vec4 val) {\n return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w));\n }\n\n "+t.defineSpecialInf+"\n "+t.defineRound+"\n\n int imod(int x, int y) {\n return x - y * (x / y);\n }\n\n int idiv(int a, int b, float sign) {\n int res = a / b;\n int mod = imod(a, b);\n if (sign < 0. && mod != 0) {\n res -= 1;\n }\n return res;\n }\n\n //Based on the work of Dave Hoskins\n //https://www.shadertoy.com/view/4djSRW\n #define HASHSCALE1 443.8975\n float random(float seed){\n vec2 p = resultUV * seed;\n vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n "+Do+"\n "+_o+"\n "+Oo+"\n "}(c);return e.isPacked?(a=function(t,e){switch(t.length){case 0:return "\n int getOutputCoords() {\n return 0;\n }\n ";case 1:return function(t,e){var n=[Math.ceil(e[0]/2),Math.ceil(e[1]/2)];if(1===n[0])return "\n int getOutputCoords() {\n return 2 * int(resultUV.x * "+n[1]+".0);\n }\n ";if(1===n[1])return "\n int getOutputCoords() {\n return 2 * int(resultUV.y * "+n[0]+".0);\n }\n ";return "\n int getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+n[0]+", "+n[1]+"));\n return 2 * (resTexRC.x * "+n[1]+" + resTexRC.y);\n }\n "}(0,e);case 2:return function(t,e){var n=[Math.ceil(e[0]/2),Math.ceil(e[1]/2)];if(x(t,e))return "\n ivec2 getOutputCoords() {\n return 2 * ivec2(resultUV.yx * vec2("+n[0]+", "+n[1]+"));\n }\n ";var r=Math.ceil(t[1]/2);return "\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+n[0]+", "+n[1]+"));\n\n int index = resTexRC.x * "+n[1]+" + resTexRC.y;\n int r = 2 * (index / "+r+");\n int c = imod(index, "+r+") * 2;\n\n return ivec2(r, c);\n }\n "}(t,e);case 3:return n=t,r=e,o=[Math.ceil(r[0]/2),Math.ceil(r[1]/2)],a=Math.ceil(n[2]/2),i=a*Math.ceil(n[1]/2),"\n ivec3 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+o[0]+", "+o[1]+"));\n int index = resTexRC.x * "+o[1]+" + resTexRC.y;\n\n int b = index / "+i+";\n index -= b * "+i+";\n\n int r = 2 * (index / "+a+");\n int c = imod(index, "+a+") * 2;\n\n return ivec3(b, r, c);\n }\n ";default:return function(t,e){for(var n=[Math.ceil(e[0]/2),Math.ceil(e[1]/2)],r=Math.ceil(t[t.length-1]/2),o=r*Math.ceil(t[t.length-2]/2),a=o,i="",s="b, r, c",u=2;u2,function(){return "Packed arg"+(n.charAt(0).toUpperCase()+n.slice(1))+" supports only inputs with rank above 2."});var o=t[t.length-1],a=Math.ceil(o/e);this.outputShape=t.slice(0,-1),a>1&&this.outputShape.push(a),r||this.variableNames.push("bestIndicesA");var i,s,u=this.outputShape,l=u.length,c=Po(l),h=Eo("coords",l);if(1===a){var p=Po(s=l+1);i="\n "+p+" sourceLocR = "+p+"("+h.join()+", 0);\n ++"+h[l-1]+";\n "+p+" sourceLocG = "+p+"("+h.join()+", 0);\n ++"+h[l-2]+";\n "+p+" sourceLocA = "+p+"("+h.join()+", 0);\n --"+h[l-1]+";\n "+p+" sourceLocB = "+p+"("+h.join()+", 0);\n --"+h[l-2]+";";}else s=l,i="\n "+c+" sourceLocR = coords;\n ++"+h[l-1]+";\n "+c+" sourceLocG = coords;\n ++"+h[l-2]+";\n "+c+" sourceLocA = coords;\n --"+h[l-1]+";\n "+c+" sourceLocB = coords;\n --"+h[l-2]+";";var f=["x","y","z","w","u","v"].slice(0,s),v="."+f[s-1],m=f.map(function(t){return "int "+t}),g=Eo("sourceLocR",s-1).concat("inIdx.r"),y=Eo("sourceLocG",s-1).concat("inIdx.g"),x=Eo("sourceLocB",s-1).concat("inIdx.b"),b=Eo("sourceLocA",s-1).concat("inIdx.a"),w="max"===n?"greaterThan":"lessThan",C=r?"":"\n inIdx = round(vec4(getBestIndicesAChannel("+g.join()+"),\n getBestIndicesAChannel("+y.join()+"),\n getBestIndicesAChannel("+x.join()+"),\n getBestIndicesAChannel("+b.join()+")));",E="vec4(\n getAChannel("+g.join()+"),\n hasNextCol ? getAChannel("+y.join()+") : 0.,\n hasNextRow ? getAChannel("+x.join()+") : 0.,\n hasNextRow && hasNextCol ? getAChannel("+b.join()+") : 0.)",R=r?"":"\n float getBestIndicesAChannel("+m.join()+") {\n return getChannel(getBestIndicesA("+f.join()+"),\n vec2("+f.slice(-2).join()+"));\n }";this.userCode="\n float getAChannel("+m.join()+") {\n return getChannel(getA("+f.join()+"),\n vec2("+f.slice(-2).join()+"));\n }\n "+R+"\n void main() {\n "+c+" coords = getOutputCoords();\n bool hasNextCol = "+h[l-1]+" < "+(u[l-1]-1)+";\n bool hasNextRow = "+h[l-2]+" < "+(u[l-2]-1)+";\n "+i+"\n ivec4 srcIdx = ivec4(sourceLocR"+v+", sourceLocG"+v+",\n sourceLocB"+v+", sourceLocA"+v+") * "+e+";\n ivec4 inIdx = srcIdx;\n vec4 bestIndex = vec4(inIdx);\n vec4 bestValue = "+E+";\n\n for (int i = 0; i < "+e+"; i++) {\n inIdx = srcIdx;\n "+C+"\n vec4 candidate = "+E+";\n bvec4 nan = isnan(candidate);\n bvec4 replace = bvec4(\n vec4("+w+"(candidate, bestValue)) * (vec4(1.0) - vec4(nan)));\n\n bestValue = vec4(replace.x ? candidate.x : bestValue.x,\n replace.y ? candidate.y : bestValue.y,\n replace.z ? candidate.z : bestValue.z,\n replace.w ? candidate.w : bestValue.w);\n bestIndex = mix(bestIndex, vec4(inIdx), vec4(replace));\n srcIdx++;\n }\n setOutput(bestIndex);\n }\n ";}}(),zo=function(){return function(t){this.variableNames=["dy"],this.outputShape=t.inShape;var e=t.filterHeight,n=t.filterWidth,r=t.strideHeight,o=t.strideWidth,a=t.dilationHeight,i=t.dilationWidth,s=t.effectiveFilterHeight,u=t.effectiveFilterWidth,l=s-1-t.padInfo.top,c=u-1-t.padInfo.left,h=1/(e*n);this.userCode="\n const ivec2 pads = ivec2("+l+", "+c+");\n const float avgMultiplier = float("+h+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n\n ivec2 dyRCCorner = coords.yz - pads;\n int dyRCorner = dyRCCorner.x;\n int dyCCorner = dyRCCorner.y;\n\n // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+s+";\n wR += "+a+") {\n float dyR = float(dyRCorner + wR) / "+r+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < "+u+";\n wC+= "+i+") {\n float dyC = float(dyCCorner + wC) / "+o+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(b, idyR, idyC, d);\n\n dotProd += dyValue * avgMultiplier;\n }\n }\n setOutput(dotProd);\n }\n ";}}(),Vo=function(){return function(t,e,n,r,o,a){this.outputShape=[],this.variableNames=["x","mean","variance"],jr(t,e),jr(t,n);var i="0.0";null!=r&&(jr(t,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");var s="1.0";null!=o&&(jr(t,o),this.variableNames.push("scale"),s="getScaleAtOutCoords()"),this.outputShape=t,this.userCode="\n void main() {\n float x = getXAtOutCoords();\n float mean = getMeanAtOutCoords();\n float variance = getVarianceAtOutCoords();\n float offset = "+i+";\n float scale = "+s+";\n float inv = scale * inversesqrt(variance + float("+a+"));\n setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1)));\n }\n ";}}(),Go=function(){return function(t,e,n,r,o,a){this.usesPackedTextures=!0,this.variableNames=["x","mean","variance"],jr(t,e),jr(t,n);var i="vec4(0.0)";null!=r&&(jr(t,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");var s="vec4(1.0)";null!=o&&(jr(t,o),this.variableNames.push("scale"),s="getScaleAtOutCoords()"),this.outputShape=t,this.userCode="\n void main() {\n vec4 offset = "+i+";\n vec4 scale = "+s+";\n\n vec4 x = getXAtOutCoords();\n vec4 mean = getMeanAtOutCoords();\n vec4 variance = getVarianceAtOutCoords();\n\n vec4 inv = scale * inversesqrt(variance + vec4("+a+"));\n\n setOutput((x - mean) * inv + offset);\n }\n ";}}(),qo="return areal * breal - aimag * bimag;",Ho="return areal * bimag + aimag * breal;",$o=function(){return function(t,e,n){this.variableNames=["AReal","AImag","BReal","BImag"],this.outputShape=jr(e,n),this.userCode="\n float binaryOpComplex(\n float areal, float aimag, float breal, float bimag) {\n "+t+"\n }\n\n void main() {\n float areal = getARealAtOutCoords();\n float aimag = getAImagAtOutCoords();\n float breal = getBRealAtOutCoords();\n float bimag = getBImagAtOutCoords();\n setOutput(binaryOpComplex(areal, aimag, breal, bimag));\n }\n ";}}(),jo="return a + b;",Ko="return a - b;",Xo="return a * b;",Yo=function(){return function(t,e,n){this.variableNames=["A","B"],this.outputShape=jr(e,n),this.userCode="\n float binaryOperation(float a, float b) {\n "+t+"\n }\n\n void main() {\n float a = getAAtOutCoords();\n float b = getBAtOutCoords();\n setOutput(binaryOperation(a, b));\n }\n ";}}(),Qo=function(){return function(t,e,n,r){void 0===r&&(r=!1),this.variableNames=["A","B"],this.supportsBroadcasting=!0,this.usesPackedTextures=!0,this.outputShape=jr(e,n);var o=this.outputShape.length,a="";if(r)if(0===o||1===y(this.outputShape))a="\n result.y = 0.;\n result.z = 0.;\n result.w = 0.;\n ";else if(a="\n "+Po(o)+" coords = getOutputCoords();\n ",1===o)a+="\n result.y = (coords + 1) >= "+this.outputShape[0]+" ? 0. : result.y;\n result.z = 0.;\n result.w = 0.;\n ";else{var i=Eo("coords",o);a+="\n bool nextRowOutOfBounds =\n ("+i[o-2]+" + 1) >= "+this.outputShape[o-2]+";\n bool nextColOutOfBounds =\n ("+i[o-1]+" + 1) >= "+this.outputShape[o-1]+";\n result.y = nextColOutOfBounds ? 0. : result.y;\n result.z = nextRowOutOfBounds ? 0. : result.z;\n result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w;\n ";}this.userCode="\n vec4 binaryOperation(vec4 a, vec4 b) {\n "+t+"\n }\n\n void main() {\n vec4 a = getAAtOutCoords();\n vec4 b = getBAtOutCoords();\n\n vec4 result = binaryOperation(a, b);\n "+a+"\n\n setOutput(result);\n }\n ";}}(),Jo=function(){function t(t){this.variableNames=["A"],this.outputShape=t,this.userCode="\n uniform float min;\n uniform float max;\n\n void main() {\n float value = getAAtOutCoords();\n if (isnan(value)) {\n setOutput(value);\n return;\n }\n\n setOutput(clamp(value, min, max));\n }\n ";}return t.prototype.getCustomSetupFunc=function(t,e){var n=this;return function(r,o){null==n.minLoc&&(n.minLoc=r.getUniformLocationNoThrow(o,"min"),n.maxLoc=r.getUniformLocationNoThrow(o,"max")),r.gl.uniform1f(n.minLoc,t),r.gl.uniform1f(n.maxLoc,e);}},t}(),Zo=function(){function t(t){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t,this.userCode="\n uniform float min;\n uniform float max;\n\n void main() {\n vec4 value = getAAtOutCoords();\n\n if (any(isnan(value))) {\n setOutput(value);\n return;\n }\n\n setOutput(clamp(value, vec4(min), vec4(max)));\n }\n ";}return t.prototype.getCustomSetupFunc=function(t,e){var n=this;return function(r,o){null==n.minLoc&&(n.minLoc=r.getUniformLocationNoThrow(o,"min"),n.maxLoc=r.getUniformLocationNoThrow(o,"max")),r.gl.uniform1f(n.minLoc,t),r.gl.uniform1f(n.maxLoc,e);}},t}(),ta=function(){return function(t){this.variableNames=["real","imag"],this.outputShape=t,this.userCode="\n void main() {\n float re = abs(getRealAtOutCoords());\n float im = abs(getImagAtOutCoords());\n float mx = max(re, im);\n\n // sadly the length function in glsl is not underflow-safe\n // (at least not on Intel GPUs). So the safe solution is\n // to ensure underflow-safety in all cases.\n setOutput(\n mx == 0.0 ? 0.0 : mx * length(vec2(1, min(re, im)/mx))\n );\n }\n ";}}(),ea=function(){return function(t){this.outputShape=[],this.outputShape=un(t,1),this.variableNames=t.map(function(t,e){return "T"+e});var e=new Array(t.length-1);e[0]=t[0][1];for(var n=1;n= "+t.inHeight+") {\n continue;\n }\n\n for (int yC = 0; yC < "+t.outWidth+"; yC++) {\n int xC = wC + yC * "+n+" - "+o+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float dyValue = getDy(b, yR, yC, d2);\n float xValue = getX(b, xR, xC, d1);\n dotProd += (xValue * dyValue);\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),oa=function(){return function(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;var e=t.filterHeight,n=t.filterWidth,r=t.strideHeight,o=t.strideWidth,a=e-1-t.padInfo.top,i=n-1-t.padInfo.left;this.userCode="\n const ivec2 pads = ivec2("+a+", "+i+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords[3];\n\n ivec2 dyCorner = coords.yz - pads;\n int dyRCorner = dyCorner.x;\n int dyCCorner = dyCorner.y;\n\n // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+e+"; wR++) {\n float dyR = float(dyRCorner + wR) / "+r+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = "+e+" - 1 - wR;\n\n for (int wC = 0; wC < "+n+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+o+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = "+n+" - 1 - wC;\n\n for (int d2 = 0; d2 < "+t.outChannels+"; d2++) {\n float xValue = getDy(batch, idyR, idyC, d2);\n float wValue = getW(wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),aa=function(){return function(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;var e=t.strideDepth,n=t.strideHeight,r=t.strideWidth,o=t.padInfo.front,a=t.padInfo.top,i=t.padInfo.left;this.userCode="\n void main() {\n ivec5 coords = getOutputCoords();\n int wF = coords.x;\n int wR = coords.y;\n int wC = coords.z;\n int d1 = coords.w;\n int d2 = coords.u;\n\n float dotProd = 0.0;\n\n for (int b = 0; b < "+t.batchSize+"; b++) {\n for (int yF = 0; yF < "+t.outDepth+"; yF++) {\n int xF = wF + yF * "+e+" - "+o+";\n\n if (xF < 0 || xF >= "+t.inDepth+") {\n continue;\n }\n\n for (int yR = 0; yR < "+t.outHeight+"; yR++) {\n int xR = wR + yR * "+n+" - "+a+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int yC = 0; yC < "+t.outWidth+"; yC++) {\n int xC = wC + yC * "+r+" - "+i+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float dyValue = getDy(b, yF, yR, yC, d2);\n float xValue = getX(b, xF, xR, xC, d1);\n dotProd += (xValue * dyValue);\n }\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),ia=function(){return function(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;var e=t.filterDepth,n=t.filterHeight,r=t.filterWidth,o=t.strideDepth,a=t.strideHeight,i=t.strideWidth,s=e-1-t.padInfo.front,u=n-1-t.padInfo.top,l=r-1-t.padInfo.left;this.userCode="\n const ivec3 pads = ivec3("+s+", "+u+", "+l+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int d1 = coords.u;\n\n\n ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n int dyFCorner = dyCorner.x;\n int dyRCorner = dyCorner.y;\n int dyCCorner = dyCorner.z;\n\n float dotProd = 0.0;\n for (int wF = 0; wF < "+e+"; wF++) {\n float dyF = float(dyFCorner + wF) / "+o+".0;\n\n if (dyF < 0.0 || dyF >= "+t.outDepth+".0 || fract(dyF) > 0.0) {\n continue;\n }\n int idyF = int(dyF);\n\n int wFPerm = "+e+" - 1 - wF;\n\n for (int wR = 0; wR < "+n+"; wR++) {\n float dyR = float(dyRCorner + wR) / "+a+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 ||\n fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = "+n+" - 1 - wR;\n\n for (int wC = 0; wC < "+r+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+i+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = "+r+" - 1 - wC;\n\n for (int d2 = 0; d2 < "+t.outChannels+"; d2++) {\n float xValue = getDy(batch, idyF, idyR, idyC, d2);\n float wValue = getW(wFPerm, wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n }\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),sa=function(){return function(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;var e=t.strideHeight,n=t.strideWidth,r=t.padInfo.top,o=t.padInfo.left,a=t.outChannels/t.inChannels;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int wR = coords.x;\n int wC = coords.y;\n int d1 = coords.z;\n int dm = coords.w;\n int d2 = d1 * "+a+" + dm;\n\n float dotProd = 0.0;\n\n // TODO: Vec4 over the batch size\n for (int b = 0; b < "+t.batchSize+"; b++) {\n for (int yR = 0; yR < "+t.outHeight+"; yR++) {\n int xR = wR + yR * "+e+" - "+r+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int yC = 0; yC < "+t.outWidth+"; yC++) {\n int xC = wC + yC * "+n+" - "+o+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float dyValue = getDy(b, yR, yC, d2);\n float xValue = getX(b, xR, xC, d1);\n dotProd += (xValue * dyValue);\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),ua=function(){return function(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;var e=t.filterHeight,n=t.filterWidth,r=t.strideHeight,o=t.strideWidth,a=e-1-t.padInfo.top,i=n-1-t.padInfo.left,s=t.outChannels/t.inChannels;this.userCode="\n const ivec2 pads = ivec2("+a+", "+i+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords[3];\n ivec2 dyCorner = coords.yz - pads;\n int dyRCorner = dyCorner.x;\n int dyCCorner = dyCorner.y;\n\n float dotProd = 0.0;\n\n for (int wR = 0; wR < "+e+"; wR++) {\n float dyR = float(dyRCorner + wR) / "+r+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = "+e+" - 1 - wR;\n\n for (int wC = 0; wC < "+n+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+o+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = "+n+" - 1 - wC;\n\n // TODO: Vec4 over the channelMul\n for (int dm = 0; dm < "+s+"; dm++) {\n int d2 = d1 * "+s+" + dm;\n float xValue = getDy(batch, idyR, idyC, d2);\n float wValue = getW(wRPerm, wCPerm, d1, dm);\n dotProd += xValue * wValue;\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),la=function(){return function(t){this.variableNames=["x","W"],this.outputShape=t.outShape;var e=t.padInfo.top,n=t.padInfo.left,r=t.strideHeight,o=t.strideWidth,a=t.dilationHeight,i=t.dilationWidth,s=t.filterHeight,u=t.filterWidth,l=4*Math.floor(t.inChannels/4),c=t.inChannels%4;this.userCode="\n const ivec2 strides = ivec2("+r+", "+o+");\n const ivec2 pads = ivec2("+e+", "+n+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d2 = coords[3];\n\n ivec2 xRCCorner = coords.yz * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+s+"; wR++) {\n int xR = xRCorner + wR * "+a+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+u+"; wC++) {\n int xC = xCCorner + wC * "+i+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n for (int d1 = 0; d1 < "+l+"; d1 += 4) {\n vec4 xValues = vec4(\n getX(batch, xR, xC, d1),\n getX(batch, xR, xC, d1 + 1),\n getX(batch, xR, xC, d1 + 2),\n getX(batch, xR, xC, d1 + 3)\n );\n vec4 wValues = vec4(\n getW(wR, wC, d1, d2),\n getW(wR, wC, d1 + 1, d2),\n getW(wR, wC, d1 + 2, d2),\n getW(wR, wC, d1 + 3, d2)\n );\n\n dotProd += dot(xValues, wValues);\n }\n\n if ("+(1===c)+") {\n dotProd +=\n getX(batch, xR, xC, "+l+") *\n getW(wR, wC, "+l+", d2);\n } else if ("+(2===c)+") {\n vec2 xValues = vec2(\n getX(batch, xR, xC, "+l+"),\n getX(batch, xR, xC, "+l+" + 1)\n );\n vec2 wValues = vec2(\n getW(wR, wC, "+l+", d2),\n getW(wR, wC, "+l+" + 1, d2)\n );\n dotProd += dot(xValues, wValues);\n } else if ("+(3===c)+") {\n vec3 xValues = vec3(\n getX(batch, xR, xC, "+l+"),\n getX(batch, xR, xC, "+l+" + 1),\n getX(batch, xR, xC, "+l+" + 2)\n );\n vec3 wValues = vec3(\n getW(wR, wC, "+l+", d2),\n getW(wR, wC, "+l+" + 1, d2),\n getW(wR, wC, "+l+" + 2, d2)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),ca=function(){return function(t){this.variableNames=["x","W"],this.outputShape=t.outShape;var e=t.padInfo.front,n=t.padInfo.top,r=t.padInfo.left,o=t.strideDepth,a=t.strideHeight,i=t.strideWidth,s=t.dilationDepth,u=t.dilationHeight,l=t.dilationWidth,c=t.filterDepth,h=t.filterHeight,p=t.filterWidth,f=4*Math.floor(t.inChannels/4),d=t.inChannels%4;this.userCode="\n const ivec3 strides = ivec3("+o+", "+a+", "+i+");\n const ivec3 pads = ivec3("+e+", "+n+", "+r+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int d2 = coords.u;\n\n ivec3 xFRCCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n int xFCorner = xFRCCorner.x;\n int xRCorner = xFRCCorner.y;\n int xCCorner = xFRCCorner.z;\n\n // Convolve x(?, ?, ?, d1) with w(:, :, :, d1, d2) to get\n // y(yF, yR, yC, d2). ? = to be determined. : = across all\n // values in that axis.\n float dotProd = 0.0;\n for (int wF = 0; wF < "+c+"; wF++) {\n int xF = xFCorner + wF * "+s+";\n\n if (xF < 0 || xF >= "+t.inDepth+") {\n continue;\n }\n\n for (int wR = 0; wR < "+h+"; wR++) {\n int xR = xRCorner + wR * "+u+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+p+"; wC++) {\n int xC = xCCorner + wC * "+l+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n for (int d1 = 0; d1 < "+f+"; d1 += 4) {\n vec4 xValues = vec4(\n getX(batch, xF, xR, xC, d1),\n getX(batch, xF, xR, xC, d1 + 1),\n getX(batch, xF, xR, xC, d1 + 2),\n getX(batch, xF, xR, xC, d1 + 3)\n );\n vec4 wValues = vec4(\n getW(wF, wR, wC, d1, d2),\n getW(wF, wR, wC, d1 + 1, d2),\n getW(wF, wR, wC, d1 + 2, d2),\n getW(wF, wR, wC, d1 + 3, d2)\n );\n\n dotProd += dot(xValues, wValues);\n }\n\n if ("+(1===d)+") {\n dotProd +=\n getX(batch, xF, xR, xC, "+f+") *\n getW(wF, wR, wC, "+f+", d2);\n } else if ("+(2===d)+") {\n vec2 xValues = vec2(\n getX(batch, xF, xR, xC, "+f+"),\n getX(batch, xF, xR, xC, "+f+" + 1)\n );\n vec2 wValues = vec2(\n getW(wF, wR, wC, "+f+", d2),\n getW(wF, wR, wC, "+f+" + 1, d2)\n );\n dotProd += dot(xValues, wValues);\n } else if ("+(3===d)+") {\n vec3 xValues = vec3(\n getX(batch, xF, xR, xC, "+f+"),\n getX(batch, xF, xR, xC, "+f+" + 1),\n getX(batch, xF, xR, xC, "+f+" + 2)\n );\n vec3 wValues = vec3(\n getW(wF, wR, wC, "+f+", d2),\n getW(wF, wR, wC, "+f+" + 1, d2),\n getW(wF, wR, wC, "+f+" + 2, d2)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n }\n }\n setOutput(dotProd);\n }\n ";}}(),ha=function(){return function(t){this.variableNames=["x","W"],this.outputShape=t.outShape;var e=t.inHeight,n=t.inWidth,r=t.padInfo.top,o=t.padInfo.left,a=t.strideHeight,i=t.strideWidth,s=t.dilationHeight,u=t.dilationWidth,l=t.filterHeight,c=t.filterWidth,h=t.outChannels/t.inChannels;this.userCode="\n const ivec2 strides = ivec2("+a+", "+i+");\n const ivec2 pads = ivec2("+r+", "+o+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords.x;\n ivec2 xRCCorner = coords.yz * strides - pads;\n int d2 = coords.w;\n int d1 = d2 / "+h+";\n int q = d2 - d1 * "+h+";\n\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n // TODO(dsmilkov): Flatten the two for loops and vec4 the operations.\n for (int wR = 0; wR < "+l+"; wR++) {\n int xR = xRCorner + wR * "+s+";\n\n if (xR < 0 || xR >= "+e+") {\n continue;\n }\n\n for (int wC = 0; wC < "+c+"; wC++) {\n int xC = xCCorner + wC * "+u+";\n\n if (xC < 0 || xC >= "+n+") {\n continue;\n }\n\n float xVal = getX(batch, xR, xC, d1);\n float wVal = getW(wR, wC, d1, q);\n dotProd += xVal * wVal;\n }\n }\n setOutput(dotProd);\n }\n ";}}(),pa=function(){return function(t){this.variableNames=["x","W"],this.usesPackedTextures=!0,this.outputShape=t.outShape;for(var e=t.inHeight,n=t.inWidth,r=t.padInfo.top,o=t.padInfo.left,a=t.strideHeight,i=t.strideWidth,s=t.dilationHeight,u=t.dilationWidth,l=t.filterHeight,c=t.filterWidth,h=c,f="int xR; int xC; int xCOffset;",d=0;d= 0 && xR < "+e+" && xCOffset >= 0 && xCOffset < "+n+") {\n xTexelR"+d+"C"+v+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+d+"C"+v+" = vec4(0.);\n }\n\n xCOffset = xC + 1 - 2;\n if(xR >= 0 && xR < "+e+" && xCOffset >= 0 && xCOffset < "+n+") {\n vec4 previous = getX(batch, xR, xCOffset, d1);\n xR"+d+"C"+v+" = vec4(previous.zw, xTexelR"+d+"C"+v+".xy);\n } else {\n xR"+d+"C"+v+" = vec4(0, 0, xTexelR"+d+"C"+v+".xy);\n }\n ":"\n if(xR >= 0 && xR < "+e+" && xC >= 0 && xC < "+n+") {\n xTexelR"+d+"C"+v+" = getX(batch, xR, xC, d1);\n } else {\n xTexelR"+d+"C"+v+" = vec4(0.);\n }\n\n xR"+d+"C"+v+" = xTexelR"+d+"C"+v+";\n ",v+1= 0 && xR < "+e+" &&\n xCOffset >= 0 && xCOffset < "+n+") {\n xTexelR"+d+"C"+(v+2)+" = getX(batch, xR, xCOffset, d1);\n }\n ",u>1&&(f+="\n xCOffset -= 2;\n if(xR >= 0 && xR < "+e+" &&\n xCOffset >= 0 && xCOffset < "+n+") {\n xTexelR"+d+"C"+v+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+d+"C"+v+" = vec4(0.);\n }\n "),f+="\n xR"+d+"C"+(v+1)+" = vec4(\n xTexelR"+d+"C"+v+".zw, xTexelR"+d+"C"+(v+2)+".xy);\n "):f+="\n xCOffset = xC + "+g+";\n\n if(xR >= 0 && xR < "+e+" &&\n xCOffset >= 0 && xCOffset < "+n+") {\n xTexelR"+d+"C"+(v+2)+" = getX(batch, xR, xCOffset, d1);\n }\n\n xR"+d+"C"+(v+1)+" = xTexelR"+d+"C"+(v+2)+";\n ";}}else v= 0 && xR < "+e+") {\n ",o%2==1?(f+="\n xCOffset = xC + 1 - "+i+";\n if(xCOffset >= 0 && xCOffset < "+n+") {\n xTexelR"+d+"C"+v+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+d+"C"+v+" = vec4(0.);\n }\n\n if(xC + 1 >= 0 && xC + 1 < "+n+") {\n xTexelR"+d+"C"+(v+2)+" = getX(batch, xR, xC + 1, d1);\n } else {\n xTexelR"+d+"C"+(v+2)+" = vec4(0.);\n }\n\n xR"+d+"C"+v+" = vec4(\n xTexelR"+d+"C"+v+".zw, xTexelR"+d+"C"+(v+2)+".zw);\n ",v+1= 0 && xCOffset < "+n+") {\n final = getX(batch, xR, xCOffset, d1);\n }\n xR"+d+"C"+(v+1)+" = vec4(xTexelR"+d+"C"+(v+2)+".xy, final.xy);\n ")):(f+="\n if(xC >= 0 && xC < "+n+") {\n xTexelR"+d+"C"+v+" = getX(batch, xR, xC, d1);\n } else {\n xTexelR"+d+"C"+v+" = vec4(0.);\n }\n\n xCOffset = xC + "+i+";\n if(xCOffset >= 0 && xCOffset < "+n+") {\n xTexelR"+d+"C"+(v+2)+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+d+"C"+(v+2)+" = vec4(0.);\n }\n\n xR"+d+"C"+v+" = vec4(\n xTexelR"+d+"C"+v+".xy, xTexelR"+d+"C"+(v+2)+".xy);\n ",v+11?[""+(i-1)/(c-1),"(y2-y1) * height_ratio","y1*"+d+" + float(y)*(height_scale)"]:["0.0","0.0","0.5 * (y1+y2) * "+d],g=m[0],y=m[1],x=m[2],b=h>1?[""+(s-1)/(h-1),"(x2-x1) * width_ratio","x1*"+v+" + float(x)*(width_scale)"]:["0.0","0.0","0.5 * (x1+x2) * "+v],w=b[0],C=b[1],E=b[2];this.userCode="\n const float height_ratio = float("+g+");\n const float width_ratio = float("+w+");\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int y = coords[1];\n int x = coords[2];\n int d = coords[3];\n\n // get box vals\n float y1 = getBoxes(b,0);\n float x1 = getBoxes(b,1);\n float y2 = getBoxes(b,2);\n float x2 = getBoxes(b,3);\n\n // get image in batch index\n int bInd = round(getBoxInd(b));\n if(bInd < 0 || bInd >= "+a+") {\n return;\n }\n\n float height_scale = "+y+";\n float width_scale = "+C+";\n\n float in_y = "+x+";\n if( in_y < 0.0 || in_y > "+d+" ) {\n setOutput(float("+o+"));\n return;\n }\n float in_x = "+E+";\n if( in_x < 0.0 || in_x > "+v+" ) {\n setOutput(float("+o+"));\n return;\n }\n\n vec2 sourceFracIndexCR = vec2(in_x,in_y);\n if("+p+" == 1) {\n // Compute the four integer indices.\n ivec2 sourceFloorCR = ivec2(sourceFracIndexCR);\n ivec2 sourceCeilCR = ivec2(ceil(sourceFracIndexCR));\n\n float topLeft = getImage(b, sourceFloorCR.y, sourceFloorCR.x, d);\n float bottomLeft = getImage(b, sourceCeilCR.y, sourceFloorCR.x, d);\n float topRight = getImage(b, sourceFloorCR.y, sourceCeilCR.x, d);\n float bottomRight = getImage(b, sourceCeilCR.y, sourceCeilCR.x, d);\n\n vec2 fracCR = sourceFracIndexCR - vec2(sourceFloorCR);\n\n float top = topLeft + (topRight - topLeft) * fracCR.x;\n float bottom = bottomLeft + (bottomRight - bottomLeft) * fracCR.x;\n float newValue = top + (bottom - top) * fracCR.y;\n setOutput(newValue);\n } else {\n // Compute the coordinators of nearest neighbor point.\n ivec2 sourceNearestCR = ivec2(floor(\n sourceFracIndexCR + vec2(0.5,0.5)));\n float newValue = getImage(b, sourceNearestCR.y, sourceNearestCR.x, d);\n setOutput(newValue);\n }\n }\n ";}}(),da=function(){return function(t,e,n){this.variableNames=["x"],this.outputShape=t;var r=t.length,o=t[t.length-1],a=n?"<":">";this.userCode="\n int getIndex(int i) {\n "+(n?"return "+o+" -i - 1;":"return i;")+"\n }\n\n void main() {\n "+Po(r)+" coords = getOutputCoords();\n int end = "+va(r,"coords")+";\n float val = 0.0;\n for (int i = "+o+" - 1; i >= 0; i -= 1) {\n int idx = getIndex(i);\n if (idx "+a+" end) {\n continue;\n }\n if (idx == end && "+e+") {\n continue;\n }\n "+va(r,"coords")+" = idx;\n val += getX("+function(t,e){if(1===t)return ""+e;if(2===t)return e+".x, "+e+".y";if(3===t)return e+".x, "+e+".y, "+e+".z";if(4===t)return e+".x, "+e+".y, "+e+".z, "+e+".w";throw Error("Cumulative sum for rank "+t+" is not yet supported")}(r,"coords")+");\n }\n setOutput(val);\n }\n ";}}();function va(t,e){if(1===t)return ""+e;if(2===t)return e+".y";if(3===t)return e+".z";if(4===t)return e+".w";throw Error("Cumulative sum for rank "+t+" is not yet supported")}var ma=function(){return function(t,e){this.variableNames=["A"];var n=Ro();this.outputShape=t,this.userCode="\n ivec3 outCoordsFromFlatIndex(int index) {\n "+Io(["r","c","d"],t)+"\n return ivec3(r, c, d);\n }\n\n void main() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+e[0]+", "+e[1]+"));\n int index = 4 * (resTexRC.x * "+e[1]+" + resTexRC.y);\n\n vec4 result = vec4(0.);\n\n for (int i=0; i<4; i++) {\n int flatIndex = index + i;\n ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n result[i] = getA(rc.x, rc.y, rc.z);\n }\n\n "+n.output+" = result;\n }\n ";}}(),ga=function(){return function(t,e){this.variableNames=["A"],this.usesPackedTextures=!0;var n=Ro();this.outputShape=t,this.userCode="\n ivec3 outCoordsFromFlatIndex(int index) {\n "+Io(["r","c","d"],t)+"\n return ivec3(r, c, d);\n }\n\n void main() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+e[0]+", "+e[1]+"));\n int index = 4 * (resTexRC.x * "+e[1]+" + resTexRC.y);\n\n vec4 result = vec4(0.);\n\n for (int i=0; i<4; i++) {\n int flatIndex = index + i;\n ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n result[i] = getChannel(getA(rc.x, rc.y, rc.z), vec2(rc.y, rc.z));\n }\n\n "+n.output+" = result;\n }\n ";}}(),ya=function(){function t(t,e,n){this.variableNames=["x"],this.outputShape=[],this.outputShape=t,this.blockSize=e,this.dataFormat=n,this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int h = "+this.getHeightCoordString()+";\n int w = "+this.getWidthCoordString()+";\n int d = "+this.getDepthCoordString()+";\n\n int in_h = h / "+e+";\n int offset_h = imod(h, "+e+");\n int in_w = w / "+e+";\n int offset_w = imod(w, "+e+");\n int offset_d = (offset_h * "+e+" + offset_w) *\n "+this.getOutputDepthSize()+";\n int in_d = d + offset_d;\n\n float result = "+this.getInputSamplingString()+";\n setOutput(result);\n }\n ";}return t.prototype.getHeightCoordString=function(){return "NHWC"===this.dataFormat?"coords[1]":"coords[2]"},t.prototype.getWidthCoordString=function(){return "NHWC"===this.dataFormat?"coords[2]":"coords[3]"},t.prototype.getDepthCoordString=function(){return "NHWC"===this.dataFormat?"coords[3]":"coords[1]"},t.prototype.getOutputDepthSize=function(){return "NHWC"===this.dataFormat?this.outputShape[3]:this.outputShape[1]},t.prototype.getInputSamplingString=function(){return "NHWC"===this.dataFormat?"getX(b, in_h, in_w, in_d)":"getX(b, in_d, in_h, in_w)"},t}(),xa=function(){return function(t){this.variableNames=["A"];var e=Ro();this.outputShape=t,this.userCode="\n "+No+"\n\n void main() {\n float x = getAAtOutCoords();\n "+e.output+" = encode_float(x);\n }\n ";}}(),ba=function(){return function(t){this.variableNames=["A"],this.usesPackedTextures=!0;var e=Ro();this.outputShape=t,this.userCode="\n "+No+"\n\n void main() {\n ivec3 coords = getOutputCoords();\n float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z));\n "+e.output+" = encode_float(x);\n }\n ";}}(),wa=function(){return function(t,e,n){void 0===n&&(n=!1),this.variableNames=["A"];var r=Ro(),o=e[0],a=e[1];this.outputShape=t;var i="result";n&&(i="floor(result * 255. + 0.5)"),this.userCode="\n "+So(t)+"\n\n void main() {\n ivec3 coords = getOutputCoords();\n\n int flatIndex = getFlatIndex(coords);\n int offset = imod(flatIndex, 4);\n\n flatIndex /= 4;\n int r = flatIndex / "+a+";\n int c = imod(flatIndex, "+a+");\n vec2 uv = (vec2(c, r) + halfCR) / vec2("+a+".0, "+o+".0);\n vec4 values = "+r.texture2D+"(A, uv);\n\n float result;\n\n if(offset == 0) {\n result = values[0];\n } else if(offset == 1) {\n result = values[1];\n } else if(offset == 2) {\n result = values[2];\n } else {\n result = values[3];\n }\n\n "+r.output+" = vec4("+i+", 0., 0., 0.);\n }\n ";}}(),Ca=function(){return function(t,e,n){void 0===n&&(n=!1),this.variableNames=["A"];var r=Ro(),o=e[0],a=e[1];this.outputShape=t;var i="",s="result";n&&(s="floor(result * 255. + 0.5)");for(var u=0;u<=1;u++)for(var l=0;l<=1;l++){var c=2*u+l;i+="\n localCoords = coords;\n if(localCoords[2] + "+l+" < "+t[2]+") {\n localCoords[2] += "+l+";\n if(localCoords[1] + "+u+" < "+t[1]+") {\n localCoords[1] += "+u+";\n\n flatIndex = getFlatIndex(localCoords);\n offset = imod(flatIndex, 4);\n \n flatIndex /= 4;\n r = flatIndex / "+a+";\n c = imod(flatIndex, "+a+");\n uv = (vec2(c, r) + halfCR) / vec2("+a+".0, "+o+".0);\n values = "+r.texture2D+"(A, uv);\n\n if(offset == 0) {\n result["+c+"] = values[0];\n } else if(offset == 1) {\n result["+c+"] = values[1];\n } else if(offset == 2) {\n result["+c+"] = values[2];\n } else {\n result["+c+"] = values[3];\n }\n }\n }\n ";}this.userCode="\n "+So(t)+"\n\n void main() {\n ivec3 coords = getOutputCoords();\n\n vec4 result = vec4(0.);\n int flatIndex, r, c, offset;\n ivec3 localCoords;\n vec2 uv;\n vec4 values;\n \n "+i+"\n\n "+r.output+" = "+s+";\n }\n ";}}(),Ea="return real * expR - imag * expI;",Ra="return real * expI + imag * expR;",Ia=function(){return function(t,e,n){this.variableNames=["real","imag"];var r=e[1];this.outputShape=e;var o=n?"2.0 * "+Math.PI:"-2.0 * "+Math.PI,a=n?r+".0":"1.0";this.userCode="\n const float exponentMultiplier = "+o+";\n\n float unaryOpComplex(float real, float expR, float imag, float expI) {\n "+t+"\n }\n\n float mulMatDFT(int batch, int index) {\n float indexRatio = float(index) / float("+r+");\n float exponentMultiplierTimesIndexRatio =\n exponentMultiplier * indexRatio;\n\n float result = 0.0;\n\n for (int i = 0; i < "+r+"; i++) {\n // x = (-2|2 * PI / N) * index * i;\n float x = exponentMultiplierTimesIndexRatio * float(i);\n float expR = cos(x);\n float expI = sin(x);\n float real = getReal(batch, i);\n float imag = getImag(batch, i);\n\n result +=\n unaryOpComplex(real, expR, imag, expI) / "+a+";\n }\n\n return result;\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n setOutput(mulMatDFT(coords[0], coords[1]));\n }\n ";}}(),Sa=function(){function t(t,e){this.outputShape=[],this.variableNames=["x"],this.outputShape=t,this.userCode="\n uniform float value;\n void main() {\n // Input can be obtained from uniform value.\n setOutput(value);\n }\n ";}return t.prototype.getCustomSetupFunc=function(t){var e=this;return function(n,r){null==e.valueLoc&&(e.valueLoc=n.getUniformLocationNoThrow(r,"value")),n.gl.uniform1f(e.valueLoc,t);}},t}(),Na=function(){return function(t){this.variableNames=["A"];var e=Ro(),n=t[0],r=t[1];this.outputShape=t,this.userCode="\n void main() {\n ivec3 coords = getOutputCoords();\n int texR = coords[0];\n int texC = coords[1];\n int depth = coords[2];\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2("+r+".0, "+n+".0);\n\n vec4 values = "+e.texture2D+"(A, uv);\n float value;\n if (depth == 0) {\n value = values.r;\n } else if (depth == 1) {\n value = values.g;\n } else if (depth == 2) {\n value = values.b;\n } else if (depth == 3) {\n value = values.a;\n }\n\n setOutput(floor(value * 255.0 + 0.5));\n }\n ";}}(),ka=function(){return function(t){this.variableNames=["A"];var e=Ro(),n=t[0],r=t[1];this.outputShape=t,this.userCode="\n void main() {\n ivec3 coords = getOutputCoords();\n int texR = coords[0];\n int texC = coords[1];\n int depth = coords[2];\n\n vec4 result = vec4(0.);\n\n for(int row=0; row<=1; row++) {\n for(int col=0; col<=1; col++) {\n texC = coords[1] + row;\n depth = coords[2] + col;\n\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2("+r+".0, "+n+".0);\n vec4 values = "+e.texture2D+"(A, uv);\n float value;\n if (depth == 0) {\n value = values.r;\n } else if (depth == 1) {\n value = values.g;\n } else if (depth == 2) {\n value = values.b;\n } else if (depth == 3) {\n value = values.a;\n }\n\n result[row * 2 + col] = floor(value * 255.0 + 0.5);\n }\n }\n\n "+e.output+" = result;\n }\n ";}}(),Aa=function(){return function(t,e,n){this.variableNames=["A","indices"];var r=t.slice();r[n]=e,this.outputShape=r,this.rank=r.length;var o=Po(this.rank),a=function(t,e){var n=t.length;if(n>4)throw Error("Gather for rank "+n+" is not yet supported");if(1===n)return "int(getIndices(resRC))";for(var r=["resRC.x","resRC.y","resRC.z","resRC.w"],o=[],a=0;a1?"strides[j]":"strides";this.userCode="\n "+r+" strides = "+r+"("+this.strides+");\n void main() {\n "+o+" coords = getOutputCoords();\n int flattenIndex = 0;\n for (int j = 0; j < "+this.sliceDim+"; j++) {\n int index = round(getIndices(coords[0], j));\n flattenIndex += index * "+a+";\n }\n setOutput(getX(flattenIndex, coords[1]));\n }\n ";}}();function Oa(t,e){return [e,t]}function Fa(t){var e=y(t);return C(Math.ceil(e/4))}function Ma(t,e){return [Math.max(1,Math.ceil(e/2)),Math.max(1,Math.ceil(t/2))]}function Ba(t,e){var n=Ro();return zt(t,e,n.version+"\n precision highp float;\n "+n.attribute+" vec3 clipSpacePos;\n "+n.attribute+" vec2 uv;\n "+n.varyingVs+" vec2 resultUV;\n\n void main() {\n gl_Position = vec4(clipSpacePos, 1);\n resultUV = uv;\n }")}function Pa(t,e){return Xt(t,e,new Float32Array([-1,1,0,0,1,-1,-1,0,0,0,1,1,0,1,1,1,-1,0,1,0]))}function La(t,e){return Yt(t,e,new Uint16Array([0,1,2,2,1,3]))}function Wa(t,e){var n,r,o,a,i,u,l,c,h=t;return 2===s.getNumber("WEBGL_VERSION")?(n=h.R32F,r=h.R16F,o=h.RGBA16F,a=h.RGBA32F,i=h.RED,u=4,l=1,c=h.HALF_FLOAT):(n=t.RGBA,r=t.RGBA,o=t.RGBA,a=h.RGBA,i=t.RGBA,u=4,l=4,c=null!=e?e.HALF_FLOAT_OES:null),{internalFormatFloat:n,internalFormatHalfFloat:r,internalFormatPackedHalfFloat:o,internalFormatPackedFloat:a,textureFormatFloat:i,downloadTextureFormat:t.RGBA,downloadUnpackNumChannels:u,defaultNumChannels:l,textureTypeHalfFloat:c}}function Ua(t,e,n,r,o,a,i){Jt(n,r);var s=Qt(t,e),u=t.TEXTURE_2D;return Mt(t,e,function(){return t.bindTexture(u,s)}),Mt(t,e,function(){return t.texParameteri(u,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE)}),Mt(t,e,function(){return t.texParameteri(u,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE)}),Mt(t,e,function(){return t.texParameteri(u,t.TEXTURE_MIN_FILTER,t.NEAREST)}),Mt(t,e,function(){return t.texParameteri(u,t.TEXTURE_MAG_FILTER,t.NEAREST)}),Mt(t,e,function(){return t.texImage2D(u,0,o,n,r,0,a,i,null)}),Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)}),s}function za(t,e,n,r,o){var a=Oa(n,r);return Ua(t,e,a[0],a[1],o.internalFormatFloat,o.textureFormatFloat,t.FLOAT)}function Va(t,e,n,r,o){var a=Oa(n,r);return Ua(t,e,a[0],a[1],o.internalFormatHalfFloat,o.textureFormatFloat,o.textureTypeHalfFloat)}function Ga(t,e,n,r,o){var a=Oa(n,r);return Ua(t,e,a[0],a[1],t.RGBA,t.RGBA,t.UNSIGNED_BYTE)}function qa(t,e,n,r,o){var a=Ma(n,r);return Ua(t,e,a[0],a[1],o.internalFormatPackedFloat,t.RGBA,t.FLOAT)}function Ha(t,e,n,r,o){var a=Ma(n,r);return Ua(t,e,a[0],a[1],o.internalFormatPackedHalfFloat,t.RGBA,o.textureTypeHalfFloat)}function $a(t,e,n,r){return Mt(t,e,function(){return t.bindBuffer(t.ARRAY_BUFFER,r)}),te(t,e,n,"clipSpacePos",r,3,20,0)&&te(t,e,n,"uv",r,2,20,12)}function ja(t,e,n,r,o,a,i){var s,u,l;Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,n)}),a instanceof Uint8Array?(s=new Uint8Array(r*o*4),u=t.UNSIGNED_BYTE,l=t.RGBA):(s=new Float32Array(r*o*4),u=t.FLOAT,l=i.internalFormatPackedFloat),s.set(a),Mt(t,e,function(){return t.texImage2D(t.TEXTURE_2D,0,l,r,o,0,t.RGBA,u,s)}),Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)});}function Ka(t,e,n,r){Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,n)}),r.data instanceof Uint8Array?Mt(t,e,function(){return t.texImage2D(t.TEXTURE_2D,0,t.RGBA,r.width,r.height,0,t.RGBA,t.UNSIGNED_BYTE,r.data)}):Mt(t,e,function(){return t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,r)}),Mt(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)});}function Xa(t,e,n,r,o){var a=t.createBuffer();Mt(t,e,function(){return t.bindBuffer(t.PIXEL_PACK_BUFFER,a)});var i=16*n*r;return Mt(t,e,function(){return t.bufferData(t.PIXEL_PACK_BUFFER,i,t.STREAM_READ)}),Mt(t,e,function(){return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,0)}),Mt(t,e,function(){return t.bindBuffer(t.PIXEL_PACK_BUFFER,null)}),a}function Ya(t,e,n){var r=t,o=new Float32Array(n);return r.bindBuffer(r.PIXEL_PACK_BUFFER,e),r.getBufferSubData(r.PIXEL_PACK_BUFFER,0,o),r.bindBuffer(r.PIXEL_PACK_BUFFER,null),o}function Qa(t,e,n,r,o){var a=Oa(n,r),i=a[0],s=a[1],u=new Uint8Array(n*r*4);return Mt(t,e,function(){return t.readPixels(0,0,i,s,o.downloadTextureFormat,t.UNSIGNED_BYTE,u)}),new Float32Array(u.buffer)}function Ja(t,e,n,r,o,a,i,s){var u=t,l=new Float32Array(function(t,e){var n=Ma(t,e);return n[0]*n[1]*4}(a,i));return u.bindBuffer(u.PIXEL_PACK_BUFFER,e),u.getBufferSubData(u.PIXEL_PACK_BUFFER,0,l),u.bindBuffer(u.PIXEL_PACK_BUFFER,null),l}function Za(t,e,n,r){var o=new Float32Array(n*r*4);return Mt(t,e,function(){return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,o)}),o}!function(t){t[t.RENDER=0]="RENDER",t[t.UPLOAD=1]="UPLOAD",t[t.PIXELS=2]="PIXELS",t[t.DOWNLOAD=3]="DOWNLOAD";}(Ta||(Ta={})),function(t){t[t.UNPACKED_FLOAT16=0]="UNPACKED_FLOAT16",t[t.UNPACKED_FLOAT32=1]="UNPACKED_FLOAT32",t[t.PACKED_4X1_UNSIGNED_BYTE=2]="PACKED_4X1_UNSIGNED_BYTE",t[t.PACKED_2X2_FLOAT32=3]="PACKED_2X2_FLOAT32",t[t.PACKED_2X2_FLOAT16=4]="PACKED_2X2_FLOAT16";}(Da||(Da={}));var ti=Object.freeze({createVertexShader:Ba,createVertexBuffer:Pa,createIndexBuffer:La,getTextureConfig:Wa,createFloat32MatrixTexture:za,createFloat16MatrixTexture:Va,createUnsignedBytesMatrixTexture:Ga,createPackedMatrixTexture:qa,createFloat16PackedMatrixTexture:Ha,bindVertexProgramAttributeStreams:$a,uploadDenseMatrixToTexture:ja,uploadPixelDataToTexture:Ka,createBufferFromOutputTexture:Xa,downloadFloat32MatrixFromBuffer:Ya,downloadByteEncodedFloatMatrixFromOutputTexture:Qa,downloadPackedMatrixFromBuffer:Ja,downloadMatrixFromPackedOutputTexture:Za}),ei=function(){function t(t){this.outputTexture=null,this.program=null,this.disposed=!1,this.vertexAttrsAreBound=!1,this.itemsToPoll=[];var e=s.getNumber("WEBGL_VERSION");null!=t?(this.gl=t,Ot(e,t)):this.gl=Ft(e),1===s.getNumber("WEBGL_VERSION")?(this.textureFloatExtension=Ut(this.gl,this.debug,"OES_texture_float"),this.colorBufferFloatExtension=this.gl.getExtension("WEBGL_color_buffer_float"),s.getBool("WEBGL_RENDER_FLOAT32_ENABLED")||(this.textureHalfFloatExtension=Ut(this.gl,this.debug,"OES_texture_half_float"),this.colorBufferHalfFloatExtension=this.gl.getExtension("EXT_color_buffer_half_float"))):this.colorBufferFloatExtension=Ut(this.gl,this.debug,"EXT_color_buffer_float"),this.vertexBuffer=Pa(this.gl,this.debug),this.indexBuffer=La(this.gl,this.debug),this.framebuffer=Zt(this.gl,this.debug),this.textureConfig=Wa(this.gl,this.textureHalfFloatExtension);}return Object.defineProperty(t.prototype,"debug",{get:function(){return s.getBool("DEBUG")},enumerable:!0,configurable:!0}),t.prototype.dispose=function(){var t=this;if(!this.disposed){null!=this.program&&console.warn("Disposing a GPGPUContext that still has a bound WebGLProgram. This is probably a resource leak, delete the program with GPGPUContext.deleteProgram before disposing."),null!=this.outputTexture&&console.warn("Disposing a GPGPUContext that still has a bound output matrix texture. This is probably a resource leak, delete the output matrix texture with GPGPUContext.deleteMatrixTexture before disposing.");var e=this.gl;Mt(e,this.debug,function(){return e.finish()}),Mt(e,this.debug,function(){return e.bindFramebuffer(e.FRAMEBUFFER,null)}),Mt(e,this.debug,function(){return e.deleteFramebuffer(t.framebuffer)}),Mt(e,this.debug,function(){return e.bindBuffer(e.ARRAY_BUFFER,null)}),Mt(e,this.debug,function(){return e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null)}),Mt(e,this.debug,function(){return e.deleteBuffer(t.indexBuffer)}),this.disposed=!0;}},t.prototype.createFloat32MatrixTexture=function(t,e){return this.throwIfDisposed(),za(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.createFloat16MatrixTexture=function(t,e){return this.throwIfDisposed(),Va(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.createUnsignedBytesMatrixTexture=function(t,e){return this.throwIfDisposed(),Ga(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.uploadPixelDataToTexture=function(t,e){this.throwIfDisposed(),Ka(this.gl,this.debug,t,e);},t.prototype.uploadDenseMatrixToTexture=function(t,e,n,r){this.throwIfDisposed(),ja(this.gl,this.debug,t,e,n,r,this.textureConfig);},t.prototype.createFloat16PackedMatrixTexture=function(t,e){return this.throwIfDisposed(),Ha(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.createPackedMatrixTexture=function(t,e){return this.throwIfDisposed(),qa(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.deleteMatrixTexture=function(t){var e=this;this.throwIfDisposed(),this.outputTexture===t&&(ie(this.gl,this.debug,this.framebuffer),this.outputTexture=null),Mt(this.gl,this.debug,function(){return e.gl.deleteTexture(t)});},t.prototype.downloadByteEncodedFloatMatrixFromOutputTexture=function(t,e,n){var r=this;return this.downloadMatrixDriver(t,function(){return Qa(r.gl,r.debug,e,n,r.textureConfig)})},t.prototype.downloadPackedMatrixFromBuffer=function(t,e,n,r,o,a){return Ja(this.gl,t,0,0,0,o,a,this.textureConfig)},t.prototype.downloadFloat32MatrixFromBuffer=function(t,e){return Ya(this.gl,t,e)},t.prototype.createBufferFromTexture=function(t,e,n){this.bindTextureToFrameBuffer(t);var r=Xa(this.gl,this.debug,e,n,this.textureConfig);return this.unbindTextureToFrameBuffer(),r},t.prototype.createAndWaitForFence=function(){var t=this.createFence(this.gl);return this.pollFence(t)},t.prototype.createFence=function(t){var e,n,r=this;if(s.getBool("WEBGL_FENCE_API_ENABLED")){var o=t,a=o.fenceSync(o.SYNC_GPU_COMMANDS_COMPLETE,0);t.flush(),n=function(){var t=o.clientWaitSync(a,0,0);return t===o.ALREADY_SIGNALED||t===o.CONDITION_SATISFIED},e=a;}else s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?(e=this.beginQuery(),this.endQuery(),n=function(){return r.isQueryAvailable(e,s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))}):n=function(){return !0};return {query:e,isFencePassed:n}},t.prototype.downloadMatrixFromPackedTexture=function(t,e,n){var r=this;return this.downloadMatrixDriver(t,function(){return Za(r.gl,r.debug,e,n)})},t.prototype.createProgram=function(t){this.throwIfDisposed();var e=this.gl,n=Vt(e,this.debug,t),r=Ba(e,this.debug),o=$t(e,this.debug);return Mt(e,this.debug,function(){return e.attachShader(o,r)}),Mt(e,this.debug,function(){return e.attachShader(o,n)}),jt(e,this.debug,o),this.debug&&Kt(e,this.debug,o),this.vertexAttrsAreBound||(this.setProgram(o),this.vertexAttrsAreBound=$a(e,this.debug,this.program,this.vertexBuffer)),o},t.prototype.deleteProgram=function(t){var e=this;this.throwIfDisposed(),t===this.program&&(this.program=null),null!=t&&Mt(this.gl,this.debug,function(){return e.gl.deleteProgram(t)});},t.prototype.setProgram=function(t){var e=this;this.throwIfDisposed(),this.program=t,null!=this.program&&this.debug&&Kt(this.gl,this.debug,this.program),Mt(this.gl,this.debug,function(){return e.gl.useProgram(t)});},t.prototype.getUniformLocation=function(t,e,n){return void 0===n&&(n=!0),this.throwIfDisposed(),n?ne(this.gl,this.debug,t,e):re(this.gl,t,e)},t.prototype.getAttributeLocation=function(t,e){var n=this;return this.throwIfDisposed(),Mt(this.gl,this.debug,function(){return n.gl.getAttribLocation(t,e)})},t.prototype.getUniformLocationNoThrow=function(t,e){return this.throwIfDisposed(),this.gl.getUniformLocation(t,e)},t.prototype.setInputMatrixTexture=function(t,e,n){this.throwIfDisposed(),this.throwIfNoProgram(),oe(this.gl,this.debug,this.program,t,e,n);},t.prototype.setOutputMatrixTexture=function(t,e,n){this.setOutputMatrixTextureDriver(t,n,e);},t.prototype.setOutputPackedMatrixTexture=function(t,e,n){this.throwIfDisposed();var r=Ma(e,n),o=r[0],a=r[1];this.setOutputMatrixTextureDriver(t,o,a);},t.prototype.setOutputMatrixWriteRegion=function(t,e,n,r){this.setOutputMatrixWriteRegionDriver(n,t,r,e);},t.prototype.setOutputPackedMatrixWriteRegion=function(t,e,n,r){throw new Error("setOutputPackedMatrixWriteRegion not implemented.")},t.prototype.debugValidate=function(){null!=this.program&&Kt(this.gl,this.debug,this.program),se(this.gl);},t.prototype.executeProgram=function(){this.throwIfDisposed(),this.throwIfNoProgram();var t=this.gl;this.debug&&this.debugValidate(),Mt(t,this.debug,function(){return t.drawElements(t.TRIANGLES,6,t.UNSIGNED_SHORT,0)});},t.prototype.blockUntilAllProgramsCompleted=function(){var t=this;this.throwIfDisposed(),Mt(this.gl,this.debug,function(){return t.gl.finish()});},t.prototype.getQueryTimerExtension=function(){return null==this.disjointQueryTimerExtension&&(this.disjointQueryTimerExtension=Ut(this.gl,this.debug,2===s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")?"EXT_disjoint_timer_query_webgl2":"EXT_disjoint_timer_query")),this.disjointQueryTimerExtension},t.prototype.getQueryTimerExtensionWebGL2=function(){return this.getQueryTimerExtension()},t.prototype.getQueryTimerExtensionWebGL1=function(){return this.getQueryTimerExtension()},t.prototype.beginQuery=function(){if(2===s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){var t=this.gl,e=this.getQueryTimerExtensionWebGL2(),n=t.createQuery();return t.beginQuery(e.TIME_ELAPSED_EXT,n),n}var r=this.getQueryTimerExtensionWebGL1(),o=r.createQueryEXT();return r.beginQueryEXT(r.TIME_ELAPSED_EXT,o),o},t.prototype.endQuery=function(){if(2!==s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){var t=this.getQueryTimerExtensionWebGL1();t.endQueryEXT(t.TIME_ELAPSED_EXT);}else{var e=this.gl,n=this.getQueryTimerExtensionWebGL2();e.endQuery(n.TIME_ELAPSED_EXT);}},t.prototype.waitForQueryAndGetTime=function(t){return r(this,void 0,void 0,function(){var e=this;return o(this,function(n){switch(n.label){case 0:return [4,R(function(){return e.disposed||e.isQueryAvailable(t,s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))})];case 1:return n.sent(),[2,this.getQueryTime(t,s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))]}})})},t.prototype.getQueryTime=function(t,e){if(0===e)return null;if(2===e){var n=this.gl;return n.getQueryParameter(t,n.QUERY_RESULT)/1e6}var r=this.getQueryTimerExtensionWebGL1();return r.getQueryObjectEXT(t,r.QUERY_RESULT_EXT)/1e6},t.prototype.isQueryAvailable=function(t,e){if(0===e)return !0;if(2===e){var n=this.gl,r=this.getQueryTimerExtensionWebGL2(),o=n.getQueryParameter(t,n.QUERY_RESULT_AVAILABLE);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(r.GPU_DISJOINT_EXT)),o&&!this.disjoint}o=(r=this.getQueryTimerExtensionWebGL1()).getQueryObjectEXT(t,r.QUERY_RESULT_AVAILABLE_EXT);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(r.GPU_DISJOINT_EXT)),o&&!this.disjoint},t.prototype.pollFence=function(t){var e=this;return new Promise(function(n){e.addItemToPoll(function(){return t.isFencePassed()},function(){return n()});})},t.prototype.pollItems=function(){for(var t=function(t){for(var e=0;e1||R(function(){return n.pollItems(),0===n.itemsToPoll.length});},t.prototype.bindTextureToFrameBuffer=function(t){this.throwIfDisposed(),ae(this.gl,this.debug,t,this.framebuffer),this.debug&&se(this.gl);},t.prototype.unbindTextureToFrameBuffer=function(){null!=this.outputTexture?(ae(this.gl,this.debug,this.outputTexture,this.framebuffer),this.debug&&se(this.gl)):ie(this.gl,this.debug,this.framebuffer);},t.prototype.downloadMatrixDriver=function(t,e){this.bindTextureToFrameBuffer(t);var n=e();return this.unbindTextureToFrameBuffer(),n},t.prototype.setOutputMatrixTextureDriver=function(t,e,n){this.throwIfDisposed();var r=this.gl;ae(r,this.debug,t,this.framebuffer),this.debug&&se(r),this.outputTexture=t,Mt(r,this.debug,function(){return r.viewport(0,0,e,n)}),Mt(r,this.debug,function(){return r.scissor(0,0,e,n)});},t.prototype.setOutputMatrixWriteRegionDriver=function(t,e,n,r){var o=this;this.throwIfDisposed(),Mt(this.gl,this.debug,function(){return o.gl.scissor(t,e,n,r)});},t.prototype.throwIfDisposed=function(){if(this.disposed)throw new Error("Attempted to use disposed GPGPUContext.")},t.prototype.throwIfNoProgram=function(){if(null==this.program)throw new Error("No GPU program is currently set.")},t}();function ni(t,e){if(t.length!==e.length)throw Error("Binary was compiled with "+t.length+" inputs, but was executed with "+e.length+" inputs");t.forEach(function(t,n){var r=t.logicalShape,o=e[n],a=o.shape;if(!x(r,a))throw Error("Binary was compiled with different shapes than the current args. Shapes "+r+" and "+a+" must match");if(!t.isUniform||!o.isUniform){var i=t.texShape,s=o.isUniform?null:o.texData.texShape;if(!x(i,s))throw Error("Binary was compiled with different texture shapes than the current args. Shape "+i+" and "+s+" must match")}});}var ri=function(){return function(t,e,n){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t;var r=n.filterWidth,o=n.inChannels,a=n.strideWidth,i=n.strideHeight,s=n.padInfo,u=n.outWidth,l=n.dilationWidth,c=n.dilationHeight,h=s.left,p=s.top,f=o*r,d=Ro();this.userCode="\n void main() {\n ivec2 rc = getOutputCoords();\n\n vec4 result = vec4(0);\n\n for(int row=0; row<=1; row++) {\n for(int col=0; col<=1; col++) {\n int blockIndex = rc.y + col;\n int pos = rc.x + row;\n\n if(blockIndex >= "+t[1]+" || pos >= "+t[0]+") continue;\n\n int offsetY = int(blockIndex / ("+u+")) * "+i+" - "+p+";\n int d0 = offsetY + "+c+" * (pos / "+f+");\n\n if(d0 >= "+e[0]+" || d0 < 0) continue;\n\n int offsetX = int(mod(float(blockIndex), "+u+".) * "+a+". - "+h+".);\n int d1 = offsetX + "+l+" * (int(mod(float(pos), "+f+".) / "+o+".));\n\n if(d1 >= "+e[1]+" || d1 < 0) continue;\n\n vec2 innerDims = vec2(d1, int(mod(float(pos), "+o+".)));\n result[row * 2 + col] = getChannel(getA(d0, int(innerDims.x),\n int(innerDims.y)), innerDims);\n }\n }\n\n "+d.output+" = result;\n }\n ";}}(),oi=function(){return function(t,e,n,r,o){this.variableNames=["x"],this.outputShape=[];var a,i=e,s=t[3]-1;this.outputShape=t;var u="float("+n+") + float("+r+") * sum";a=.5===o?"inversesqrt("+u+")":1===o?"1.0/("+u+")":"exp(log("+u+") * float(-"+o+"));",this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int r = coords[1];\n int c = coords[2];\n int d = coords[3];\n float x = getX(b, r, c, d);\n float sum = 0.0;\n for (int j = -"+i+"; j <= "+i+"; j++) {\n int idx = d + j;\n if (idx >= 0 && idx <= "+s+") {\n float z = getX(b, r, c, idx);\n sum += z * z;\n }\n }\n float val = x * "+a+";\n setOutput(val);\n }\n ";}}(),ai=function(){return function(t,e,n,r,o){this.variableNames=["inputImage","outputImage","dy"],this.outputShape=[],this.outputShape=t,this.depth=t[3],this.depthRadius=e,this.bias=n,this.alpha=r,this.beta=o,this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int r = coords[1];\n int c = coords[2];\n\n float result = 0.0;\n for (int d = 0; d < "+this.depth+"; ++d) {\n int depthBegin = int(max(0.0, float(d - "+e+")));\n int depthEnd = int(min(float("+this.depth+"),\n float(d + "+e+" + 1)));\n\n const int MIN_DEPTH_BEGIN = 0;\n const int MAX_DEPTH_END = "+this.depth+";\n\n float norm = 0.0;\n for (int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k) {\n if (k < depthBegin){\n continue;\n }\n else if (k >= depthBegin && k < depthEnd) {\n norm += getInputImage(b, r, c, k) * getInputImage(b, r, c, k);\n }\n else {\n break;\n }\n }\n\n norm = float("+r+") * norm + float("+n+");\n\n for(int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k){\n if (k < depthBegin){\n continue;\n }\n else if (k >= depthBegin && k < depthEnd){\n float dyi = -2.0 * float("+r+")\n * float("+o+")\n * getInputImage(b ,r ,c, k) * getOutputImage(b, r, c, d)\n / norm;\n if (k == d) {\n dyi += pow(norm, -1.0 * "+o+");\n }\n if (k == coords[3]) {\n dyi *= getDy(b, r, c, d);\n result += dyi;\n }\n }\n else {\n break;\n }\n }\n }\n setOutput(result);\n }\n ";}}(),ii=function(){return function(t,e,n,r,o){this.variableNames=["x"],this.outputShape=[],this.usesPackedTextures=!0;var a,i=e,s=t[3]-1;this.outputShape=t;var u="float("+n+") + float("+r+") * sum";a=.5===o?"inversesqrt("+u+")":1===o?"1.0/("+u+")":"exp(log("+u+") * float(-"+o+"));",this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords.x;\n int r = coords.y;\n int c = coords.z;\n int d = coords.w;\n\n bool hasNextCol = d < "+this.outputShape[3]+";\n bool hasNextRow = c < "+this.outputShape[2]+";\n\n vec4 sum = vec4(0.);\n vec4 xFragAtOutputCoords = getX(b, r, c, d);\n\n vec4 xAtOutputCoords = vec4(\n getChannel(xFragAtOutputCoords, vec2(c, d)),\n hasNextCol ?\n getChannel(xFragAtOutputCoords, vec2(c, d + 1)) : 0.0,\n hasNextRow ?\n getChannel(xFragAtOutputCoords , vec2(c + 1, d)) : 0.0,\n (hasNextRow && hasNextCol) ?\n getChannel(xFragAtOutputCoords, vec2(c + 1, d + 1)) : 0.0\n );\n\n int firstChannel = d - "+i+";\n vec2 cache = vec2(0.);\n if(firstChannel >= 0){\n vec4 firstChannelFrag = getX(b, r, c, firstChannel);\n cache.x = getChannel(firstChannelFrag, vec2(c, firstChannel));\n if(hasNextRow){\n cache.y = getChannel(firstChannelFrag, vec2(c + 1, firstChannel));\n }\n }\n\n ivec2 depth = ivec2(d, d + 1);\n for (int j = - "+i+"; j <= "+i+"; j++) {\n ivec2 idx = depth + j;\n bvec2 aboveLowerBound = greaterThanEqual(idx, ivec2(0));\n bvec2 belowUpperBound = lessThanEqual(idx, ivec2("+s+"));\n\n bool depthInRange = aboveLowerBound.x && belowUpperBound.x;\n bool depthPlusOneInRange = aboveLowerBound.y && belowUpperBound.y;\n\n if(depthInRange || depthPlusOneInRange){\n vec4 z = vec4(0.);\n vec4 xFragAtCurrentDepth;\n z.xz = cache.xy;\n if(depthPlusOneInRange && hasNextCol){\n xFragAtCurrentDepth = idx.y != d ?\n getX(b, r, c, idx.y) : xFragAtOutputCoords;\n z.y = getChannel(xFragAtCurrentDepth, vec2(c, idx.y));\n if(hasNextRow){\n z.w = getChannel(xFragAtCurrentDepth, vec2(c + 1, idx.y));\n }\n }\n cache.xy = z.yw;\n sum += z * z;\n }\n }\n vec4 result = xAtOutputCoords * "+a+";\n setOutput(result);\n }\n ";}}(),si=function(){return function(t){this.variableNames=["dy","maxPos"],this.outputShape=t.inShape;var e=t.strideHeight,n=t.strideWidth,r=t.dilationHeight,o=t.effectiveFilterHeight,a=t.effectiveFilterWidth,i=o-1-t.padInfo.top,s=a-1-t.padInfo.left,u=o*a-1;this.userCode="\n const ivec2 pads = ivec2("+i+", "+s+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n\n ivec2 dyRCCorner = coords.yz - pads;\n int dyRCorner = dyRCCorner.x;\n int dyCCorner = dyRCCorner.y;\n\n // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+o+";\n wR += "+r+") {\n float dyR = float(dyRCorner + wR) / "+e+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < "+a+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+n+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(b, idyR, idyC, d);\n int maxPosValue = "+u+" - int(getMaxPos(b, idyR, idyC, d));\n\n // Get the current value, check it against the value from the\n // position matrix.\n int curPosValue = wR * "+a+" + wC;\n float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n dotProd += dyValue * mask;\n }\n }\n setOutput(dotProd);\n }\n ";}}(),ui=function(){return function(t,e,n,r,o,a){void 0===n&&(n=!1),void 0===r&&(r=!1),void 0===o&&(o=!1),void 0===a&&(a=null),this.variableNames=["matrixA","matrixB"],this.usesPackedTextures=!0,this.outputShape=e;var i=n?t[1]:t[2],s=Math.ceil(i/2),u=n?"i * 2, rc.y":"rc.y, i * 2",l=r?"rc.z, i * 2":"i * 2, rc.z",c=n?["a.xxyy","a.zzww"]:["a.xxzz","a.yyww"],h=r?["b.xzxz","b.ywyw"]:["b.xyxy","b.zwzw"],p="",f="";a&&(p="vec4 activation(vec4 x) {\n "+a+"\n }",f="result = activation(result);");var d=o?"result += getBiasAtOutCoords();":"";o&&this.variableNames.push("bias"),this.userCode="\n "+p+"\n\n const float sharedDimension = "+s+".0;\n\n vec4 dot2x2ARowBCol(ivec3 rc) {\n vec4 result = vec4(0);\n for (int i = 0; i < "+s+"; i++) {\n vec4 a = getMatrixA(rc.x, "+u+");\n vec4 b = getMatrixB(rc.x, "+l+");\n\n result += ("+c[0]+" * "+h[0]+") + ("+c[1]+" * "+h[1]+");\n }\n return result;\n }\n\n void main() {\n ivec3 rc = getOutputCoords();\n vec4 result = dot2x2ARowBCol(rc);\n\n "+d+"\n\n "+f+"\n\n setOutput(result);\n }\n ";}}(),li=function(){function t(t,e,n){this.variableNames=["probs"],this.outputShape=[t,n],this.userCode="\n uniform float seed;\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n\n float r = random(seed);\n float cdf = 0.0;\n\n for (int i = 0; i < "+(e-1)+"; i++) {\n cdf += getProbs(batch, i);\n\n if (r < cdf) {\n setOutput(float(i));\n return;\n }\n }\n\n // If no other event happened, last event happened.\n setOutput(float("+(e-1)+"));\n }\n ";}return t.prototype.getCustomSetupFunc=function(t){var e=this;return function(n,r){null==e.seedLoc&&(e.seedLoc=n.getUniformLocation(r,"seed")),n.gl.uniform1f(e.seedLoc,t);}},t}(),ci=function(){return function(t,e,n,r){this.variableNames=["indices"],this.outputShape=[t,e],this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n int index = round(getIndices(coords.x));\n setOutput(mix(float("+r+"), float("+n+"),\n float(index == coords.y)));\n }\n ";}}(),hi=function(){return function(t){this.variableNames=["A"],this.outputShape=t;var e=t.length;if(0===e)this.userCode="\n void main() {\n setOutput(vec4(getA(), 0., 0., 0.));\n }\n ";else{var n=Eo("rc",e),r=Po(e),o=function(t,e,n){if(1===t)return "rc > "+e[0];for(var r="",o=t-2;o= "+e[o],o= "+e+";\n bool rEdge = rp1 >= "+n+";\n "}(e,t[t.length-1],t[t.length-2],n),i=function(t,e){var n=t.length,r=function(t,e){for(var n=[],r=0;r<=1;r++)for(var o=0;o<=1;o++){for(var a=(0===r?"r":"rp1")+", "+(0===o?"c":"cp1"),i=2;i= "+t[0]+" ? 0. : getA(rc + 1),\n 0, 0":"getA("+r[0]+"),\n cEdge ? 0. : getA("+r[1]+"),\n rEdge ? 0. : getA("+r[2]+"),\n rEdge || cEdge ? 0. : getA("+r[3]+")"}(t,n);this.userCode="\n void main() {\n "+r+" rc = getOutputCoords();\n\n if("+o+") {\n setOutput(vec4(0));\n } else {\n "+a+"\n\n setOutput(vec4("+i+"));\n }\n }\n ";}}}();var pi=function(){return function(t,e,n){this.variableNames=["x"],this.outputShape=e.map(function(e,n){return e[0]+t[n]+e[1]});var r=t.length,o=Po(r),a=e.map(function(t){return t[0]}).join(","),i=e.map(function(e,n){return e[0]+t[n]}).join(","),s=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,r);this.userCode=1!==r?"\n "+o+" start = "+o+"("+a+");\n "+o+" end = "+o+"("+i+");\n\n void main() {\n "+o+" outC = getOutputCoords();\n if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) {\n setOutput(float("+n+"));\n } else {\n "+o+" coords = outC - start;\n setOutput(getX("+s+"));\n }\n }\n ":"\n int start = "+a+";\n int end = "+i+";\n\n void main() {\n int outC = getOutputCoords();\n if (outC < start || outC >= end) {\n setOutput(float("+n+"));\n } else {\n setOutput(getX(outC - start));\n }\n }\n ";}}(),fi=function(){return function(t,e,n){this.variableNames=["x"],this.usesPackedTextures=!0,this.outputShape=e.map(function(e,n){return e[0]+t[n]+e[1]});for(var r=t.length,o=Po(r),a=e.map(function(t){return t[0]}).join(","),i=e.map(function(e,n){return e[0]+t[n]}).join(","),s=Eo("rc",r),u=Eo("source",r),l=s[r-1]+" < "+this.outputShape[r-1],c=1===r?"source":"vec2("+u.slice(-2).join()+")",h=[o+" rc = outputLoc;",s[r-1]+" += 1;\n if("+l+") {\n ",1===r?"":"}\n rc = outputLoc;\n "+s[r-2]+" += 1;\n if("+s[r-2]+" < "+this.outputShape[r-2]+") {",1===r?"":" "+s[r-1]+" += 1;\n if("+l+") {"],p=1===r?"rc < start || rc >= end":"any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))",f="",d=0,v=1===r?2:4;d= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+l+";\n wC += "+s+") {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float value = getX(batch, xR, xC, d);\n\n // If a min / max value has already been found, use it. If not,\n // use the current value.\n float currMinMaxValue = mix(\n value, minMaxValue, minMaxValueFound);\n if (value >= currMinMaxValue) {\n minMaxValue = value;\n minMaxValueFound = 1.0;\n minMaxPosition = wR * "+l+" + wC;\n }\n }\n }\n setOutput(float(minMaxPosition));\n }\n ";else{var d=e+"("+e+"("+e+"(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"avg"===e&&(d="avgValue / count");var v=4*Math.floor(r/4),m=r%4,g="\n if ("+p+") {\n avgValue += dot(values, ones);\n } else {\n minMaxValue = max(values, minMaxValue);\n }\n ";this.userCode="\n const ivec2 strides = ivec2("+o+", "+a+");\n const ivec2 pads = ivec2("+c+", "+h+");\n const float initializationValue = "+f+";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float count = 0.0;\n\n float getValue(int batch, int xR, int xC, int d) {\n if (xC < 0 || xC >= "+t.inWidth+") {\n return initializationValue;\n }\n count += 1.0;\n return getX(batch, xR, xC, d);\n }\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d = coords[3];\n\n ivec2 xRCCorner = coords.yz * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // max/min x(?, ?, d) to get y(yR, yC, d).\n // ? = to be determined\n vec4 minMaxValue = vec4("+f+");\n float avgValue = 0.0;\n count = 0.0;\n\n for (int wR = 0; wR < "+u+";\n wR += "+i+") {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+v+"; wC += 4) {\n int xC = xCCorner + wC * "+s+";\n\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + "+s+", d),\n getValue(batch, xR, xC + 2 * "+s+", d),\n getValue(batch, xR, xC + 3 * "+s+", d)\n );\n\n "+g+"\n }\n\n int xC = xCCorner + "+v+";\n if ("+(1===m)+") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n "+g+"\n } else if ("+(2===m)+") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + "+s+", d),\n initializationValue,\n initializationValue\n );\n\n "+g+"\n } else if ("+(3===m)+") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + "+s+", d),\n getValue(batch, xR, xC + 2 * "+s+", d),\n initializationValue\n );\n\n "+g+"\n }\n }\n setOutput("+d+");\n }\n ";}}}(),vi=function(){return function(t,e){this.variableNames=["x"];var n=t.windowSize,r=t.batchSize,o=t.inSize,a=Math.ceil(o/n);this.outputShape=[r,a];var i="0.0",s="";"prod"===e?i="1.0":"min"===e?(i="1.0 / 1e-20",s="min"):"max"===e&&(i="-1.0 / 1e-20",s="max");var u=e+"("+e+"("+e+"(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"sum"===e?u="sumValue":"prod"===e?u="prodValue":"all"===e?u="allValue":"any"===e&&(u="anyValue");var l=4*Math.floor(n/4),c=n%4,h="\n if ("+("sum"===e)+") {\n sumValue += dot(values, ones);\n } else if ("+("prod"===e)+") {\n vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]);\n prodValue *= tmp[0] * tmp[1];\n } else {\n minMaxValue = "+s+"(values, minMaxValue);\n }\n ",p="vec4";"all"===e?(i="1.0",h="\n bool reducedAllValue = all(values);\n float floatedReducedAllValue = float(reducedAllValue);\n allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0);\n ",p="bvec4"):"any"===e&&(i="0.0",h="\n bool reducedAnyValue = any(values);\n float floatedReducedAnyValue = float(reducedAnyValue);\n anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0);\n ",p="bvec4");var f="";o%n>0&&(f="\n if (inIdx < 0 || inIdx >= "+o+") {\n return initializationValue;\n }\n "),this.userCode="\n const float initializationValue = "+i+";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float getValue(int batch, int inIdx) {\n "+f+"\n return getX(batch, inIdx);\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = outIdx * "+n+";\n\n vec4 minMaxValue = vec4("+i+");\n float prodValue = 1.0;\n float sumValue = 0.0;\n float allValue = 1.0;\n float anyValue = 0.0;\n\n for (int i = 0; i < "+l+"; i += 4) {\n int inIdx = inOffset + i;\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n getValue(batch, inIdx + 3)\n );\n\n "+h+"\n }\n\n int inIdx = inOffset + "+l+";\n if ("+(1===c)+") {\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n "+h+"\n } else if ("+(2===c)+") {\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n initializationValue,\n initializationValue\n );\n\n "+h+"\n } else if ("+(3===c)+") {\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n initializationValue\n );\n\n "+h+"\n }\n setOutput("+u+");\n }\n ";}}(),mi=function(){return function(t,e){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t;for(var n="",r=0;r<4;r++){var o="thisRC = rc;";r%2==1&&(o+="thisRC.z += 1;"),r>1&&(o+="thisRC.y += 1;"),n+="\n "+o+"\n "+(r>0?"if(thisRC.y < rows && thisRC.z < cols){":"")+"\n int flatIndex = getFlatIndex(thisRC);\n\n ivec3 inputRC = inputCoordsFromReshapedOutCoords(flatIndex);\n vec2 inputRCInnerDims = vec2(float(inputRC.y),float(inputRC.z));\n\n result["+r+"] =\n getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims);\n "+(r>0?"}":"")+"\n ";}this.userCode="\n \n ivec3 inputCoordsFromReshapedOutCoords(int index) {\n "+Io(["r","c","d"],e)+"\n return ivec3(r, c, d);\n }\n \n "+So(t)+"\n\n void main() {\n ivec3 rc = getOutputCoords();\n\n vec4 result = vec4(0.);\n\n ivec3 thisRC;\n int rows = "+t[1]+";\n int cols = "+t[2]+";\n\n "+n+"\n\n setOutput(result);\n }\n ";}}();var gi=function(){return function(t,e,n){this.variableNames=["dy"],this.outputShape=[],this.outputShape=e.shape;var r=e.shape,o=r[1],a=r[2],i=t.shape,s=i[1],u=i[2],l=[n&&s>1?o-1:o,n&&u>1?a-1:a],c=[n&&s>1?s-1:s,n&&u>1?u-1:u],h=l[0]/c[0],p=l[1]/c[1],f=1/h,d=1/p,v=2*Math.ceil(f)+2,m=2*Math.ceil(d)+2;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n int r = coords[1];\n int c = coords[2];\n\n float accumulator = 0.0;\n\n const float heightScale = float("+h+");\n const float widthScale = float("+p+");\n\n const float invHeightScale = float("+f+");\n const float invWidthScale = float("+d+");\n\n const int winHeight = int("+v+");\n const int winWidth = int("+m+");\n\n // Compute bounds for where in dy we will look\n float startRLerp = floor(float(r) * invHeightScale);\n int startDyR = int(startRLerp - float(winHeight / 2));\n\n float startCLerp = floor(float(c) * invWidthScale);\n int startDyC = int(startCLerp - float(winWidth / 2));\n\n // Loop over dy\n for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n int dyR = dyROffset + startDyR;\n\n // Guard against the window exceeding the bounds of dy\n if (dyR < 0 || dyR >= "+s+") {\n continue;\n }\n\n for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n int dyC = dyCOffset + startDyC;\n\n // Guard against the window exceeding the bounds of dy\n if (dyC < 0 || dyC >= "+u+") {\n continue;\n }\n\n float dxR = float(dyR) * heightScale;\n int topDxRIndex = int(floor(dxR));\n int bottomDxRIndex = int(min(ceil(dxR), "+(o-1)+".0));\n float dxRLerp = dxR - float(topDxRIndex);\n float inverseDxRLerp = 1.0 - dxRLerp;\n\n float dxC = float(dyC) * widthScale;\n int leftDxCIndex = int(floor(dxC));\n int rightDxCIndex = int(min(ceil(dxC), "+(a-1)+".0));\n float dxCLerp = dxC - float(leftDxCIndex);\n float inverseDxCLerp = 1.0 - dxCLerp;\n\n if (r == topDxRIndex && c == leftDxCIndex) {\n // topLeft\n accumulator +=\n getDy(b, dyR, dyC, d) * inverseDxRLerp * inverseDxCLerp;\n }\n\n if (r == topDxRIndex && c == rightDxCIndex) {\n // topRight\n accumulator += getDy(b, dyR, dyC, d) * inverseDxRLerp * dxCLerp;\n }\n\n if (r == bottomDxRIndex && c == leftDxCIndex) {\n // bottomLeft\n accumulator += getDy(b, dyR, dyC, d) * dxRLerp * inverseDxCLerp;\n }\n\n if (r == bottomDxRIndex && c == rightDxCIndex) {\n // bottomRight\n accumulator += getDy(b, dyR, dyC, d) * dxRLerp * dxCLerp;\n }\n }\n }\n // End loop over dy\n\n setOutput(accumulator);\n }\n ";}}(),yi=function(){return function(t,e,n,r){this.variableNames=["A"],this.outputShape=[];var o=t[0],a=t[1],i=t[2],s=t[3];this.outputShape=[o,e,n,s];var u=[r&&e>1?a-1:a,r&&n>1?i-1:i],l=[r&&e>1?e-1:e,r&&n>1?n-1:n];this.userCode="\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n "+u[0]/l[0]+",\n "+u[1]/l[1]+");\n const vec2 inputShapeRC = vec2("+a+".0, "+i+".0);\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n ivec2 yRC = coords.yz;\n\n // Fractional source index.\n vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the four integer indices.\n ivec2 sourceFloorRC = ivec2(sourceFracIndexRC);\n ivec2 sourceCeilRC = ivec2(\n min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d);\n float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d);\n float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d);\n float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d);\n\n vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);\n\n float top = topLeft + (topRight - topLeft) * fracRC.y;\n float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;\n float newValue = top + (bottom - top) * fracRC.x;\n\n setOutput(newValue);\n }\n ";}}(),xi=function(){return function(t,e,n,r){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=[];var o=t[0],a=t[1],i=t[2],s=t[3];this.outputShape=[o,e,n,s];var u=[r&&e>1?a-1:a,r&&n>1?i-1:i],l=[r&&e>1?e-1:e,r&&n>1?n-1:n];this.userCode="\n const vec3 effectiveInputOverOutputRatioRC = vec3(\n "+u[0]/l[0]+",\n "+u[1]/l[1]+",\n "+u[1]/l[1]+");\n const vec3 inputShapeRC = vec3("+a+".0, "+i+".0,\n "+i+".0);\n\n float getAValue(int b, int r, int c, int d) {\n return getChannel(getA(b, r, c, d), vec2(c, d));\n }\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n // Calculate values for next column in yRC.z.\n ivec3 yRC = coords.yzz + ivec3(0, 0, 1);\n\n // Fractional source index.\n vec3 sourceFracIndexRC = vec3(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the four integer indices.\n ivec3 sourceFloorRC = ivec3(sourceFracIndexRC);\n ivec3 sourceCeilRC = ivec3(\n min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n \n // Should we calculate next column and row elements in 2x2 packed cell.\n bool hasNextCol = d < "+(s-1)+"; \n bool hasNextRow = coords.z < "+(n-1)+";\n\n // In parallel, construct four corners for all four components in\n // packed 2x2 cell.\n vec4 topLeft = vec4(\n getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d),\n hasNextCol ? getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n vec4 bottomLeft = vec4(\n getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d),\n hasNextCol ? getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n vec4 topRight = vec4(\n getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d),\n hasNextCol ? getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n vec4 bottomRight = vec4(\n getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d),\n hasNextCol ? getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n vec3 fracRC = sourceFracIndexRC - vec3(sourceFloorRC);\n\n vec4 top = mix(topLeft, topRight, fracRC.yyzz);\n vec4 bottom = mix(bottomLeft, bottomRight, fracRC.yyzz);\n vec4 newValue = mix(top, bottom, fracRC.x);\n\n setOutput(newValue);\n }\n ";}}(),bi=function(){return function(t,e,n){this.variableNames=["dy"],this.outputShape=[],this.outputShape=e.shape;var r=e.shape,o=r[1],a=r[2],i=t.shape,s=i[1],u=i[2],l=[n&&s>1?o-1:o,n&&u>1?a-1:a],c=[n&&s>1?s-1:s,n&&u>1?u-1:u],h=l[0]/c[0],p=l[1]/c[1],f=1/h,d=1/p,v=2*Math.ceil(f)+2,m=2*Math.ceil(d)+2;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n int r = coords[1];\n int c = coords[2];\n\n float accumulator = 0.0;\n\n const float heightScale = float("+h+");\n const float widthScale = float("+p+");\n\n const float invHeightScale = float("+f+");\n const float invWidthScale = float("+d+");\n\n const int winHeight = int("+v+");\n const int winWidth = int("+m+");\n\n // Compute bounds for where in dy we will look\n float startRLerp = floor(float(r) * invHeightScale);\n int startDyR = int(floor(startRLerp - float(winHeight / 2)));\n\n float startCLerp = floor(float(c) * invWidthScale);\n int startDyC = int(floor(startCLerp - float(winWidth / 2)));\n\n // Loop over dy\n for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n int dyR = dyROffset + startDyR;\n\n // Guard against the window exceeding the bounds of dy\n if (dyR < 0 || dyR >= "+s+") {\n continue;\n }\n\n for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n int dyC = dyCOffset + startDyC;\n\n // Guard against the window exceeding the bounds of dy\n if (dyC < 0 || dyC >= "+u+") {\n continue;\n }\n\n float sourceFracRow =\n float("+l[0]+") *\n (float(dyR) / float("+c[0]+"));\n\n float sourceFracCol =\n float("+l[1]+") *\n (float(dyC) / float("+c[1]+"));\n\n int sourceNearestRow = int(min(\n float(int("+o+") - 1),\n "+n+" ? float(round(sourceFracRow)) :\n float(floor(sourceFracRow))));\n\n int sourceNearestCol = int(min(\n float(int("+a+") - 1),\n "+n+" ? float(round(sourceFracCol)) :\n float(floor(sourceFracCol))));\n\n if (r == sourceNearestRow && c == sourceNearestCol) {\n accumulator += getDy(b, dyR, dyC, d);\n }\n }\n }\n // End loop over dy\n\n setOutput(accumulator);\n }\n ";}}(),wi=function(){return function(t,e,n,r){this.variableNames=["A"],this.outputShape=[];var o=t[0],a=t[1],i=t[2],s=t[3];this.outputShape=[o,e,n,s];var u=[r&&e>1?a-1:a,r&&n>1?i-1:i],l=[r&&e>1?e-1:e,r&&n>1?n-1:n],c=r?"0.5":"0.0";this.userCode="\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n "+u[0]/l[0]+",\n "+u[1]/l[1]+");\n const vec2 inputShapeRC = vec2("+a+".0, "+i+".0);\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n ivec2 yRC = coords.yz;\n\n // Fractional source index.\n vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the coordinators of nearest neighbor point.\n ivec2 sourceNearestRC = ivec2(\n min(inputShapeRC - 1.0, floor(sourceFracIndexRC + "+c+")));\n\n float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d);\n\n setOutput(newValue);\n }\n ";}}(),Ci=function(){return function(t,e){this.variableNames=["x"];var n=t.length;if(n>4)throw new Error("WebGL backend: Reverse of rank-"+n+" tensor is not yet supported");if(this.outputShape=t,1!==n){var r=t.map(function(n,r){return function(n){return -1!==e.indexOf(n)&&1!==t[n]?t[n]+" - coords["+n+"] - 1":"coords["+n+"]"}(r)}).join(","),o=Po(n);this.userCode="\n void main() {\n "+o+" coords = getOutputCoords();\n setOutput(getX("+r+"));\n }\n ";}else this.userCode="\n void main() {\n int coord = getOutputCoords();\n setOutput(getX("+t[0]+" - coord - 1));\n }\n ";}}(),Ei=function(){return function(t,e){this.variableNames=["x"],this.usesPackedTextures=!0;var n=t.length;if(n>4)throw new Error("WebGL backend: Reverse of rank-"+n+" tensor is not yet supported");this.outputShape=t;var r=Eo("rc",n),o=r[n-1]+" + 1 < "+this.outputShape[n-1],a=r[n-2]+" + 1 < "+this.outputShape[n-2],i=Po(n);function s(n){var r=t.map(function(r,o){return function(n,r){return -1!==e.indexOf(n)&&1!==t[n]?t[n]+" - "+r[n]+" - 1":""+r[n]}(o,n)});return "getChannel(getX("+r.join(",")+"), vec2("+r.slice(-2).join(",")+"))"}this.userCode=1===n?"\n void main(){\n int rc = getOutputCoords();\n vec4 result = vec4(0.);\n result.r = getChannel(getX("+t[0]+" - rc - 1),\n "+t[0]+" - rc - 1);\n if("+o+"){\n result.g = getChannel(getX("+t[0]+" - (rc + 1) - 1),\n "+t[0]+" - (rc + 1) - 1);\n }\n setOutput(result);\n }\n ":"\n void main() {\n "+i+" rc = getOutputCoords();\n vec4 result = vec4(0.);\n result.r = "+function(t){return s(t)}(r.slice())+";\n if("+o+"){\n result.g = "+function(t){return t[n-1]="("+t[n-1]+" + 1)",s(t)}(r.slice())+";\n }\n if("+a+") {\n result.b = "+function(t){return t[n-2]="("+t[n-2]+" + 1)",s(t)}(r.slice())+";\n if("+o+") {\n result.a = "+function(t){return t[n-1]="("+t[n-1]+" + 1)",t[n-2]="("+t[n-2]+" + 1)",s(t)}(r.slice())+";\n }\n }\n setOutput(result);\n }\n ";}}(),Ri=function(){return function(t,e,n,r,o,a,i){this.variableNames=["updates","indices","defaultValue"],this.outputShape=a;var s=Po(o.length),u=Po(a.length),l="";1===n?l="i":2===n&&(l="i, j");var c="getIndices("+l+")",h="";1===r?h="i":2===r&&(h="i, coords[1]");var p="getUpdates("+h+")",f=e>1?"strides[j]":"strides";this.userCode="\n "+s+" strides = "+s+"("+o+");\n\n void main() {\n "+u+" coords = getOutputCoords();\n float sum = 0.0;\n bool found = false;\n for (int i = 0; i < "+t+"; i++) {\n int flattenedIndex = 0;\n for (int j = 0; j < "+e+"; j++) {\n int index = round("+c+");\n flattenedIndex += index * "+f+";\n }\n if (flattenedIndex == coords[0]) {\n sum += "+p+";\n found = true;\n }\n }\n setOutput(mix(getDefaultValue(), sum, float(found)));\n }\n ";}}(),Ii=function(){return function(t,e){this.variableNames=["x","segmentIds"];var n=t.windowSize,r=t.batchSize,o=t.inSize,a=t.numSegments,i=a*Math.ceil(o/n);this.outputShape=[r,i];var s=4*Math.floor(n/4),u=n%4,l="\n sumValue += dot(values, segFilter);\n ",c="";o%n>0&&(c="\n if (inIdx < 0 || inIdx >= "+o+") {\n return initializationValue;\n }\n ");var h="";o%n>0&&(h="\n if (inIdx < 0 || inIdx >= "+o+") {\n return -1.0;\n }\n "),this.userCode="\n const float initializationValue = 0.0;\n\n float getValue(int batch, int inIdx) {\n "+c+"\n return getX(batch, inIdx);\n }\n\n float getSegmentIdAtIndex(int inIdx) {\n "+h+"\n return getSegmentIds(inIdx);\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = int(floor(float(outIdx) / float(\n "+a+")) * float("+n+"));\n int currentSeg = int(mod(float(outIdx), float("+a+")));\n\n float sumValue = 0.0;\n\n for (int i = 0; i < "+s+"; i += 4) {\n int inIdx = inOffset + i;\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n getValue(batch, inIdx + 3)\n );\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 3)) == currentSeg ? 1 : 0\n );\n\n "+l+"\n }\n\n int inIdx = inOffset + "+s+";\n if ("+(1===u)+") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n int inIdxSeg = int(getSegmentIdAtIndex(inIdx));\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n 0,\n 0,\n 0\n );\n\n "+l+"\n } else if ("+(2===u)+") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n initializationValue,\n initializationValue\n );\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n 0,\n 0\n );\n\n "+l+"\n } else if ("+(3===u)+") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n initializationValue\n );\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n 0\n );\n\n "+l+"\n }\n setOutput(sumValue);\n }\n ";}}(),Si=function(){return function(t,e,n){var r,o;if(this.variableNames=["c","a","b"],this.outputShape=e,n>4)throw Error("Where for rank "+n+" is not yet supported");if(1===n)o="resRC",r="resRC";else{for(var a=["resRC.x","resRC.y","resRC.z","resRC.w"],i=[],s=[],u=0;u= 1.0) {\n setOutput(getA("+o+"));\n } else {\n setOutput(getB("+o+"));\n }\n }\n ";}}(),Ni=function(){function t(t){this.variableNames=["source"],this.outputShape=t,this.rank=t.length;var e,n=Po(this.rank),r="uniform int start["+this.rank+"];",o=function(t){if(1===t)return "sourceLoc";if(t<=6)return ki.slice(0,t).map(function(t){return "sourceLoc."+t}).join(",");throw Error("Slicing for rank "+t+" is not yet supported")}(this.rank);e="\n "+n+" sourceLoc;\n "+n+" coords = getOutputCoords();\n "+t.map(function(t,e){return "sourceLoc."+ki[e]+" = start["+e+"] + coords."+ki[e]+";"}).join("\n")+"\n ",this.userCode="\n "+r+"\n void main() {\n "+e+"\n setOutput(getSource("+o+"));\n }\n ";}return t.prototype.getCustomSetupFunc=function(t){var e=this;if(t.length!==this.rank)throw Error("The rank ("+this.rank+") of the program must match the length of start ("+t.length+")");return function(n,r){null==e.startLoc&&(e.startLoc=n.getUniformLocationNoThrow(r,"start"),null==e.startLoc)||n.gl.uniform1iv(e.startLoc,t);}},t}(),ki=["x","y","z","w","u","v"];var Ai=function(){function t(t){this.variableNames=["source"],this.usesPackedTextures=!0,this.outputShape=t,this.rank=t.length;var e=Po(this.rank),n=Eo("coords",this.rank),r=Eo("sourceLoc",this.rank),o=1===this.rank?"sourceLoc":"vec2("+r.slice(-2).join()+")",a="getChannel(getSource("+r.join()+"), "+o+")",i="\n result.x = "+a+";\n if (++"+n[this.rank-1]+" < "+t[this.rank-1]+") {\n ++"+r[this.rank-1]+";\n result.y = "+a+";\n --"+r[this.rank-1]+";\n }\n ",s=1===this.rank?"":"\n --"+n[this.rank-1]+";\n if (++"+n[this.rank-2]+" < "+t[this.rank-2]+") {\n ++"+r[this.rank-2]+";\n result.z = "+a+";\n if (++"+n[this.rank-1]+" < "+t[this.rank-1]+") {\n ++"+r[this.rank-1]+";\n result.w = "+a+";\n }\n }\n ",u=this.rank<=4?"sourceLoc = coords +\n "+e+"("+t.map(function(t,e){return "start["+e+"]"}).join()+");":t.map(function(t,e){return r[e]+" = "+n[e]+" + start["+e+"];"}).join("\n");this.userCode="\n uniform int start["+this.rank+"];\n void main() {\n "+e+" coords = getOutputCoords();\n "+e+" sourceLoc;\n "+u+" \n vec4 result = vec4(0.);\n "+i+"\n "+s+"\n setOutput(result);\n }\n ";}return t.prototype.getCustomSetupFunc=function(t){var e=this;if(t.length!==this.rank)throw Error("The rank ("+this.rank+") of the program must match the length of start ("+t.length+")");return function(n,r){null==e.startLoc&&(e.startLoc=n.getUniformLocationNoThrow(r,"start"),null==e.startLoc)||n.gl.uniform1iv(e.startLoc,t);}},t}(),Ti=function(){return function(t,e,n,r){this.variableNames=["x"];var o=n.filter(function(t,e){return -1===r.indexOf(e)});this.outputShape=o;var a=n.length,i=Po(n.length),s=Po(o.length),u="";if(1===a)u="coords * strides + begin";else{var l=0;u=n.map(function(t,e){return -1===r.indexOf(e)?(l++,1===o.length?"coords * strides["+e+"] + begin["+e+"]":"coords["+(l-1)+"] * strides["+e+"] + begin["+e+"]"):"begin["+e+"]"}).join(",");}this.userCode="\n "+i+" begin = "+i+"("+t+");\n "+i+" strides = "+i+"("+e+");\n\n void main() {\n "+s+" coords = getOutputCoords();\n setOutput(getX("+u+"));\n }\n ";}}(),Di=function(){function t(t){this.gpgpu=t,this.numUsedTextures=0,this.numFreeTextures=0,this.freeTextures={},this.logEnabled=!1,this.usedTextures={};}return t.prototype.acquireTexture=function(t,e,n){var r,o=_i(e,n),a=Oi(t,o,n);if(a in this.freeTextures||(this.freeTextures[a]=[]),a in this.usedTextures||(this.usedTextures[a]=[]),this.freeTextures[a].length>0){this.numFreeTextures--,this.numUsedTextures++,this.log();var i=this.freeTextures[a].shift();return this.usedTextures[a].push(i),i}return this.numUsedTextures++,this.log(),o===Da.PACKED_2X2_FLOAT32?r=this.gpgpu.createPackedMatrixTexture(t[0],t[1]):o===Da.PACKED_2X2_FLOAT16?r=this.gpgpu.createFloat16PackedMatrixTexture(t[0],t[1]):o===Da.UNPACKED_FLOAT32?r=this.gpgpu.createFloat32MatrixTexture(t[0],t[1]):o===Da.UNPACKED_FLOAT16?r=this.gpgpu.createFloat16MatrixTexture(t[0],t[1]):o===Da.PACKED_4X1_UNSIGNED_BYTE&&(r=this.gpgpu.createUnsignedBytesMatrixTexture(t[0],t[1])),this.usedTextures[a].push(r),r},t.prototype.releaseTexture=function(t,e,n,r){if(null!=this.freeTextures){var o=Oi(e,_i(n,r),r);o in this.freeTextures||(this.freeTextures[o]=[]),this.freeTextures[o].push(t),this.numFreeTextures++,this.numUsedTextures--;var a=this.usedTextures[o],i=a.indexOf(t);if(i<0)throw new Error("Cannot release a texture that was never provided by this texture manager");a.splice(i,1),this.log();}},t.prototype.log=function(){if(this.logEnabled){var t=this.numFreeTextures+this.numUsedTextures;console.log("Free/Used",this.numFreeTextures+" / "+this.numUsedTextures,"("+t+")");}},t.prototype.getNumUsedTextures=function(){return this.numUsedTextures},t.prototype.getNumFreeTextures=function(){return this.numFreeTextures},t.prototype.dispose=function(){var t=this;if(null!=this.freeTextures){for(var e in this.freeTextures)this.freeTextures[e].forEach(function(e){t.gpgpu.deleteMatrixTexture(e);});for(var e in this.usedTextures)this.usedTextures[e].forEach(function(e){t.gpgpu.deleteMatrixTexture(e);});this.freeTextures=null,this.usedTextures=null,this.numUsedTextures=0,this.numFreeTextures=0;}},t}();function _i(t,e){if(t===Ta.UPLOAD)return Da.PACKED_2X2_FLOAT32;if(t===Ta.RENDER||null==t)return e?s.getBool("WEBGL_RENDER_FLOAT32_ENABLED")?Da.PACKED_2X2_FLOAT32:Da.PACKED_2X2_FLOAT16:s.getBool("WEBGL_RENDER_FLOAT32_ENABLED")?Da.UNPACKED_FLOAT32:Da.UNPACKED_FLOAT16;if(t===Ta.DOWNLOAD||t===Ta.PIXELS)return Da.PACKED_4X1_UNSIGNED_BYTE;throw new Error("Unknown logical texture type "+t)}function Oi(t,e,n){return t[0]+"_"+t[1]+"_"+e+"_"+n}var Fi=function(){return function(t,e){this.variableNames=["A"];for(var n=new Array(t.length),r=0;r5)throw Error("Tile for rank "+e+" is not yet supported");if(1===e)return "imod(resRC, "+t[0]+")";for(var n=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u"],r=[],o=0;o6)throw Error("Transpose for rank "+e+" is not yet supported");for(var n=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u","resRC.v"],r=new Array(e),o=0;o6)throw Error("Packed transpose for rank "+this.rank+" is not yet supported.");var o=Po(this.rank),a=Co("rc",this.rank),i=new Array(this.rank);for(r=0;r= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);\n";var qi="return exp(x);",Hi=Ui+"\n return sin(x);\n",$i=Ui+"\n return cos(x);\n",ji=Ui+"\n return atan(x);\n",Ki=Ui+"\n if (x < 1.0) return NAN;\n return log(x + sqrt(x * x - 1.0));",Xi=Ui+"\n if ((x < -1.0) || (x > 1.0)) return NAN;\n return (log(1.0 + x) - log(1.0 - x)) / 2.0;",Yi="return x;",Qi="\n vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));\n bvec4 isNaN = isnan(x);\n\n result.r = isNaN.r ? x.r : result.r;\n result.g = isNaN.g ? x.g : result.g;\n result.b = isNaN.b ? x.b : result.b;\n result.a = isNaN.a ? x.a : result.a;\n\n return result;\n",Ji=function(){return function(t,e){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t,this.userCode="\n vec4 unaryOperation(vec4 x) {\n "+e+"\n }\n\n void main() {\n vec4 x = getAAtOutCoords();\n vec4 y = unaryOperation(x);\n\n setOutput(y);\n }\n ";}}(),Zi=function(){return function(t){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t;var e=t.length,n=Eo("rc",e),r=Po(e),o=function(t,e){if(1===t)return "rc";for(var n="",r=0;r0?this.gpgpu.beginQuery():{startMs:performance.now(),endMs:null}},t.prototype.endTimer=function(t){return s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?(this.gpgpu.endQuery(),t):(t.endMs=performance.now(),t)},t.prototype.getQueryTime=function(t){return r(this,void 0,void 0,function(){var e;return o(this,function(n){return s.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?[2,this.gpgpu.waitForQueryAndGetTime(t)]:[2,(e=t).endMs-e.startMs]})})},t.prototype.disposeData=function(t){if(!this.pendingDisposal.has(t))if(this.pendingRead.has(t))this.pendingDisposal.add(t);else if(this.texData.has(t)){this.releaseGPUData(t);var e=this.texData.get(t).complexTensors;null!=e&&(e.real.dispose(),e.imag.dispose()),this.texData.delete(t);}},t.prototype.releaseGPUData=function(t){var e=this.texData.get(t),n=e.texture,r=e.dtype,o=e.texShape,a=e.usage,i=e.isPacked,s=e.slice,u=s&&s.origDataId||t,l=this.dataRefCount.get(u);l>1?this.dataRefCount.set(u,l-1):(this.dataRefCount.delete(u),null!=n&&(this.numBytesInGPU-=this.computeBytes(o,r),this.textureManager.releaseTexture(n,o,a,i)));var c=this.texData.get(t);c.texture=null,c.texShape=null,c.isPacked=!1,c.slice=null;},t.prototype.getTexture=function(t){return this.uploadToGPU(t),this.texData.get(t).texture},t.prototype.getCPUBackend=function(){return s.getBool("WEBGL_CPU_FORWARD")?(null==this.cpuBackend&&(this.cpuBackend=At.findBackend("cpu")),this.cpuBackend):null},t.prototype.shouldExecuteOnCPU=function(t,e){var n=this;return void 0===e&&(e=128),null!=this.getCPUBackend()&&t.every(function(t){return null==n.texData.get(t.dataId).texture&&t.sizes.getNumber("WEBGL_MAX_TEXTURES_IN_SHADER")){var n=Math.floor(t.length/2),r=this.concat(t.slice(0,n),e),o=this.concat(t.slice(n),e);return this.concat([r,o],e)}if(s.getBool("WEBGL_PACK_ARRAY_OPERATIONS")&&t[0].rank>1){var a=new na(t.map(function(t){return t.shape}),e);return this.compileAndRun(a,t)}var i=un(t.map(function(t){return t.shape}),e),u=t.map(function(t){return t.as2D(-1,y(t.shape.slice(e)))}),l=new ea(u.map(function(t){return t.shape}));return this.compileAndRun(l,u).reshape(i)},t.prototype.neg=function(t){var e=new Wi(t.shape,"return -x;");return this.compileAndRun(e,[t])},t.prototype.batchMatMul=function(t,e,n,r){var o=n?t.shape[2]:t.shape[1],a=r?e.shape[1]:e.shape[2],i=n?t.shape[1]:t.shape[2],s=t.shape[0];if((1===o||1===a)&&i>1e3){n&&(t=t.transpose([0,2,1])),r&&(e=e.transpose([0,2,1]));var u=1===a?t:t.as3D(s,i,1),l=1===a?2:1,c=1===a?e.as3D(s,1,i):e;return this.multiply(u,c).sum(l,!0)}var h=bt(t.dtype,e.dtype),p=new ui(t.shape,[s,o,a],n,r),f=this.makePackedTensor(p.outputShape,h);return this.compileAndRun(p,[t,e],f)},t.prototype.fusedBatchMatMul=function(t,e,n,r,o,a){var i=n?t.shape[2]:t.shape[1],s=r?e.shape[1]:e.shape[2],u=t.shape[0],l=bt(t.dtype,e.dtype),c=new ui(t.shape,[u,i,s],n,r,!!o,a?function(t,e){if(void 0===e&&(e=!1),"linear"===t)return e?Yi:zi;if("relu"===t)return e?Qi:Vi;throw new Error("Activation "+t+" has not been implemented for the WebGL backend.")}(a,!0):null),h=this.makePackedTensor(c.outputShape,l),p=[t,e];return o&&p.push(o),this.compileAndRun(c,p,h)},t.prototype.multiply=function(t,e){if("complex64"===t.dtype){var n=this.texData.get(t.dataId),r=this.texData.get(e.dataId),o=new $o(qo,t.shape,e.shape),a=new $o(Ho,t.shape,e.shape),i=[this.makeComplexComponentTensorHandle(t,n.complexTensors.real),this.makeComplexComponentTensorHandle(t,n.complexTensors.imag),this.makeComplexComponentTensorHandle(e,r.complexTensors.real),this.makeComplexComponentTensorHandle(e,r.complexTensors.imag)],u=this.compileAndRun(o,i),l=this.compileAndRun(a,i),c=this.complex(u,l);return u.dispose(),l.dispose(),c}if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.multiply(t,e);if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,Xo,t.dtype);var h=new Yo(Xo,t.shape,e.shape),p=this.makeOutputArray(h.outputShape,t.dtype);return this.compileAndRun(h,[t,e],p)},t.prototype.batchNormalization=function(t,e,n,r,o,a){var i=[t,e,n],u=null;null!=a&&(u=a.shape,i.push(a));var l=null;if(null!=o&&(l=o.shape,i.push(o)),s.getBool("WEBGL_PACK_NORMALIZATION")){var c=new Go(t.shape,e.shape,n.shape,u,l,r);return this.compileAndRun(c,i)}var h=new Vo(t.shape,e.shape,n.shape,u,l,r);return this.compileAndRun(h,i)},t.prototype.localResponseNormalization4D=function(t,e,n,r,o){var a=s.getBool("WEBGL_PACK_NORMALIZATION")?new ii(t.shape,e,n,r,o):new oi(t.shape,e,n,r,o);return this.compileAndRun(a,[t])},t.prototype.LRNGrad=function(t,e,n,r,o,a,i){var s=new ai(e.shape,r,o,a,i);return this.compileAndRun(s,[e,n,t])},t.prototype.tile=function(t,e){if("string"===t.dtype)return mo($n(t.shape,t.dtype,this.readSync(t.dataId)),e);var n=new Fi(t.shape,e);return this.compileAndRun(n,[t])},t.prototype.pad=function(t,e,n){var r=s.getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new fi(t.shape,e,n):new pi(t.shape,e,n);return this.compileAndRun(r,[t])},t.prototype.transpose=function(t,e){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.transpose(t,e);var n=s.getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Bi(t.shape,e):new Mi(t.shape,e);return this.compileAndRun(n,[t])},t.prototype.gather=function(t,e,n){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.gather(t,e,n);var r=new Aa(t.shape,e.size,n);return this.compileAndRun(r,[t,e])},t.prototype.batchToSpaceND=function(t,e,n){d(t.rank<=4,function(){return "batchToSpaceND for rank > 4 with a WebGL backend not implemented yet"});var r=e.reduce(function(t,e){return t*e}),o=xr(t.shape,e,r),a=br(o.length,e.length),i=wr(t.shape,e,r),s=Cr(n,e.length),u=Er(i,n,e.length);return t.reshape(o).transpose(a).reshape(i).slice(s,u)},t.prototype.spaceToBatchND=function(t,e,n){d(t.rank<=4,function(){return "spaceToBatchND for rank > 4 with a WebGL backend not implemented yet"});var r=e.reduce(function(t,e){return t*e}),o=[[0,0]];o.push.apply(o,n);for(var a=1+e.length;ae||n===t?r=!0:n=V(t,n+1);return n}(i,o),u=new Ii({windowSize:s,inSize:i,batchSize:a,numSegments:o},e),l=u.outputShape,c=l[0],h=l[1],p=this.makeOutputArray([c,h],r);return this.compileAndRun(u,[t,n],p),p.shape[1]===o?p:(n=Sn(0,o).tile([i/s]),this.segOpCompute(p,e,n,r,o))},t.prototype.argMinMaxReduce=function(t,e,n){var r=[e];if(nn("arg"+n.charAt(0).toUpperCase()+n.slice(1),r,t.rank),!s.getBool("WEBGL_PACK_REDUCE")||t.rank<=2){var o=tn(t.shape,r),a=o[0],i=y(o[1]),u=t.as2D(-1,i);return this.argReduce(u,n).reshape(a)}return this.argReducePacked(t,n)},t.prototype.argMin=function(t,e){return this.argMinMaxReduce(t,e,"min")},t.prototype.argMax=function(t,e){return this.argMinMaxReduce(t,e,"max")},t.prototype.cumsum=function(t,e,n,r){if(e!==t.rank-1)throw new Error("WebGL cumsum shader expects an inner-most axis="+(t.rank-1)+" but got axis="+e);var o=new da(t.shape,n,r);return this.compileAndRun(o,[t])},t.prototype.equal=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(equal(a, b));\n","bool");var n=new Yo("return float(a == b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.notEqual=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(notEqual(a, b));\n","bool");var n=new Yo("return float(a != b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.less=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.less(t,e);if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(lessThan(a, b));\n","bool");var n=new Yo("return float(a < b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.lessEqual=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(lessThanEqual(a, b));\n","bool");var n=new Yo("return float(a <= b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.greater=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.greater(t,e);if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(greaterThan(a, b));\n","bool");var n=new Yo("return float(a > b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.greaterEqual=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(greaterThanEqual(a, b));\n","bool");var n=new Yo("return float(a >= b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.logicalNot=function(t){var e=new Wi(t.shape,"return float(!(x >= 1.0));");return this.compileAndRun(e,[t])},t.prototype.logicalAnd=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(\n vec4(greaterThanEqual(a, vec4(1.0))) *\n vec4(greaterThanEqual(b, vec4(1.0))));\n","bool");var n=new Yo("return float(a >= 1.0 && b >= 1.0);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.logicalOr=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return min(\n vec4(greaterThanEqual(a, vec4(1.0))) +\n vec4(greaterThanEqual(b, vec4(1.0))),\n vec4(1.0));\n","bool");var n=new Yo("return float(a >= 1.0 || b >= 1.0);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.select=function(t,e,n){var r=new Si(t.rank,e.shape,e.rank),o=this.makeOutputArray(r.outputShape,bt(e.dtype,n.dtype));return this.compileAndRun(r,[t,e,n],o)},t.prototype.where=function(t){je("tf.where() in webgl locks the UI thread. Call tf.whereAsync() instead");var e=t.dataSync();return yo(t.shape,e)},t.prototype.topk=function(t,e,n){return go(t.dataSync(),t.shape,t.dtype,e)},t.prototype.min=function(t,e){nn("min",e,t.rank);var n=tn(t.shape,e),r=n[0],o=y(n[1]),a=t.as2D(-1,o);return this.reduce(a,"min",a.dtype).reshape(r)},t.prototype.minimum=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.minimum(t,e);var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("\n vec4 result = vec4(min(a, b));\n vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new Yo("\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return min(a, b);\n",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.mod=function(t,e){var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("\n vec4 result = mod(a, b);\n vec4 isNaN = vec4(equal(b, vec4(0.0)));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new Yo("if (b == 0.0) return NAN;\n return mod(a, b);",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.max=function(t,e){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.max(t,e);nn("max",e,t.rank);var n=tn(t.shape,e),r=n[0],o=y(n[1]),a=t.as2D(-1,o);return this.reduce(a,"max",a.dtype).reshape(r)},t.prototype.maximum=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.maximum(t,e);var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("\n vec4 result = vec4(max(a, b));\n vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new Yo("\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return max(a, b);\n",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.all=function(t,e){nn("all",e,t.rank);var n=tn(t.shape,e),r=n[0],o=y(n[1]),a=t.as2D(-1,o);return this.reduce(a,"all",a.dtype).reshape(r)},t.prototype.any=function(t,e){nn("any",e,t.rank);var n=tn(t.shape,e),r=n[0],o=y(n[1]),a=t.as2D(-1,o);return this.reduce(a,"any",a.dtype).reshape(r)},t.prototype.squaredDifference=function(t,e){var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("return (a - b) * (a - b);",t.shape,e.shape):new Yo("return (a - b) * (a - b);",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.realDivide=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS")){return this.packedBinaryOp(t,e,"\n // vec4 one = vec4(equal(a, b));\n // return one + (vec4(1.0) - one) * a / b;\n vec4 result = a / b;\n if(b.x == 0.0) {\n result.x = NAN;\n } else if(a.x == b.x) {\n result.x = 1.;\n }\n if(b.y == 0.0) {\n result.y = NAN;\n } else if(a.y == b.y) {\n result.y = 1.;\n }\n if(b.z == 0.0) {\n result.z = NAN;\n } else if(a.z == b.z) {\n result.z = 1.;\n }\n if(b.w == 0.0) {\n result.w = NAN;\n } else if(a.w == b.w) {\n result.w = 1.;\n }\n \n return result;\n","float32",!0)}var n=new Yo("\nif (b == 0.0) {\n return NAN;\n} \nif (a == b) {\n return 1.0;\n};\nreturn a / b;",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"float32");return this.compileAndRun(n,[t,e],r)},t.prototype.floorDiv=function(t,e){if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n ivec4 ia = round(a);\n ivec4 ib = round(b);\n bvec4 cond = notEqual(ib, ivec4(0));\n ivec4 result = ivec4(0);\n vec4 s = sign(a) * sign(b);\n\n // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n if (cond[0]) {\n result[0] = idiv(ia[0], ib[0], s[0]);\n }\n if (cond[1]) {\n result[1] = idiv(ia[1], ib[1], s[1]);\n }\n if (cond[2]) {\n result[2] = idiv(ia[2], ib[2], s[2]);\n }\n if (cond[3]) {\n result[3] = idiv(ia[3], ib[3], s[3]);\n }\n return vec4(result);\n","int32");var n=new Yo("\n float s = sign(a) * sign(b);\n int ia = round(a);\n int ib = round(b);\n if (ib != 0) {\n // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n return float(idiv(ia, ib, s));\n } else {\n return NAN;\n }\n",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"int32");return this.compileAndRun(n,[t,e],r)},t.prototype.add=function(t,e){if("complex64"===t.dtype&&"complex64"===e.dtype)return this.complexSeparableBinaryOp(t,e,jo);if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.add(t,e);var n=bt(t.dtype,e.dtype);if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,jo,n);var r=new Yo(jo,t.shape,e.shape),o=this.makeOutputArray(r.outputShape,n);return this.compileAndRun(r,[t,e],o)},t.prototype.packedBinaryOp=function(t,e,n,r,o){void 0===o&&(o=!1);var a=new Qo(n,t.shape,e.shape,o),i=this.makePackedTensor(a.outputShape,r);return this.compileAndRun(a,[t,e],i)},t.prototype.complexSeparableBinaryOp=function(t,e,n){var r=this,o=this.texData.get(t.dataId),a=this.texData.get(e.dataId),i=[[o.complexTensors.real,a.complexTensors.real],[o.complexTensors.imag,a.complexTensors.imag]].map(function(o){var a=o[0],i=o[1],s=r.makeComplexComponentTensorHandle(t,a),u=r.makeComplexComponentTensorHandle(e,i),l=new Yo(n,t.shape,e.shape),c=r.makeOutputArray(l.outputShape,bt(a.dtype,i.dtype));return r.compileAndRun(l,[s,u],c)}),s=i[0],u=i[1],l=this.complex(s,u);return s.dispose(),u.dispose(),l},t.prototype.makeComplexComponentTensorHandle=function(t,e){return {dataId:e.dataId,dtype:e.dtype,shape:t.shape}},t.prototype.addN=function(t){if(1===t.length)return t[0];if(t.length>s.get("WEBGL_MAX_TEXTURES_IN_SHADER")){var e=Math.floor(t.length/2),n=this.addN(t.slice(0,e)),r=this.addN(t.slice(e));return this.addN([n,r])}var o=t.map(function(t){return t.dtype}).reduce(function(t,e){return bt(t,e)}),a=t.map(function(t){return t.shape}),i=s.getBool("WEBGL_PACK"),u=i?new bo(t[0].shape,a):new xo(t[0].shape,a),l=i?this.makePackedTensor(u.outputShape,o):this.makeOutputArray(u.outputShape,o);return this.compileAndRun(u,t,l)},t.prototype.subtract=function(t,e){if("complex64"===t.dtype&&"complex64"===e.dtype)return this.complexSeparableBinaryOp(t,e,Ko);if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.subtract(t,e);var n=bt(t.dtype,e.dtype);if(s.getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,Ko,t.dtype);var r=new Yo(Ko,t.shape,e.shape),o=this.makeOutputArray(r.outputShape,n);return this.compileAndRun(r,[t,e],o)},t.prototype.pow=function(t,e){var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS"),r=n?new Qo("\n // isModRound1 has 1 for components with round(mod(b, 2.0)) == 1, 0 otherwise.\n vec4 isModRound1 = vec4(equal(round(mod(b, 2.0)), ivec4(1)));\n vec4 multiplier = sign(a) * isModRound1 + (vec4(1.0) - isModRound1);\n vec4 result = multiplier * pow(abs(a), b);\n\n vec4 isNaN = vec4(lessThan(a, vec4(0.0))) * vec4(lessThan(floor(b), b));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new Yo("\nif(a < 0.0 && floor(b) < b){\n return NAN;\n}\nreturn (round(mod(b, 2.0)) != 1) ?\n pow(abs(a), b) : sign(a) * pow(abs(a), b);\n",t.shape,e.shape),o=bt(t.dtype,e.dtype),a=n?this.makePackedTensor(r.outputShape,o):this.makeOutputArray(r.outputShape,o);return this.compileAndRun(r,[t,e],a)},t.prototype.ceil=function(t){var e=new Wi(t.shape,"return ceil(x);");return this.compileAndRun(e,[t])},t.prototype.floor=function(t){var e=new Wi(t.shape,"return floor(x);");return this.compileAndRun(e,[t])},t.prototype.sign=function(t){var e=new Wi(t.shape,"\n if (isnan(x)) { return 0.0; }\n return sign(x);\n");return this.compileAndRun(e,[t])},t.prototype.isNaN=function(t){var e=new Wi(t.shape,"return float(isnan(x));"),n=this.makeOutputArray(e.outputShape,"bool");return this.compileAndRun(e,[t],n)},t.prototype.isInf=function(t){var e=new Wi(t.shape,"return float(isinf(x));"),n=this.makeOutputArray(e.outputShape,"bool");return this.compileAndRun(e,[t],n)},t.prototype.isFinite=function(t){var e=new Wi(t.shape,"return float(!isnan(x) && !isinf(x));"),n=this.makeOutputArray(e.outputShape,"bool");return this.compileAndRun(e,[t],n)},t.prototype.round=function(t){var e=new Wi(t.shape,"\n // OpenGL ES does not support round function.\n // The algorithm is based on banker's rounding.\n float base = floor(x);\n if ((x - base) < 0.5) {\n return floor(x);\n } else if ((x - base) > 0.5) {\n return ceil(x);\n } else {\n if (mod(base, 2.0) == 0.0) {\n return base;\n } else {\n return base + 1.0;\n }\n }\n");return this.compileAndRun(e,[t])},t.prototype.exp=function(t){var e;return e=s.getBool("WEBGL_PACK")?new Ji(t.shape,qi):new Wi(t.shape,qi),this.compileAndRun(e,[t])},t.prototype.expm1=function(t){var e=new Wi(t.shape,"return exp(x) - 1.0;");return this.compileAndRun(e,[t])},t.prototype.log=function(t){var e;return e=s.getBool("WEBGL_PACK")?new Ji(t.shape,"\n vec4 result = log(x);\n vec4 isNaN = vec4(lessThan(x, vec4(0.0)));\n result.r = isNaN.r == 1.0 ? NAN : result.r;\n result.g = isNaN.g == 1.0 ? NAN : result.g;\n result.b = isNaN.b == 1.0 ? NAN : result.b;\n result.a = isNaN.a == 1.0 ? NAN : result.a;\n\n return result;\n"):new Wi(t.shape,"if (x < 0.0) return NAN;\n return log(x);"),this.compileAndRun(e,[t])},t.prototype.log1p=function(t){var e=new Wi(t.shape,"return log(1.0 + x);");return this.compileAndRun(e,[t])},t.prototype.sqrt=function(t){var e=new Wi(t.shape,"return sqrt(x);");return this.compileAndRun(e,[t])},t.prototype.rsqrt=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.rsqrt(t);var e=new Wi(t.shape,"return inversesqrt(x);");return this.compileAndRun(e,[t])},t.prototype.square=function(t){var e=new Wi(t.shape,"return x * x;");return this.compileAndRun(e,[t])},t.prototype.reciprocal=function(t){var e=new Wi(t.shape,"return 1.0 / x;");return this.compileAndRun(e,[t])},t.prototype.relu=function(t){var e;return e=s.getBool("WEBGL_PACK")?new Ji(t.shape,Qi):new Wi(t.shape,Vi),this.compileAndRun(e,[t])},t.prototype.prelu=function(t,e){var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("\n vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n",t.shape,e.shape):new Yo("return (a < 0.) ? b * a : a;",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.elu=function(t){var e=new Wi(t.shape,"return (x >= 0.0) ? x : (exp(x) - 1.0);");return this.compileAndRun(e,[t])},t.prototype.eluDer=function(t,e){var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("\n vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.)));\n return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0))));\n",t.shape,e.shape):new Yo("return (b >= 1.0) ? a : a * (b + 1.0);",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.selu=function(t){var e=new Wi(t.shape,Gi);return this.compileAndRun(e,[t])},t.prototype.int=function(t){var e=new Wi(t.shape,"return float(int(x));"),n=this.makeOutputArray(e.outputShape,"int32");return this.compileAndRun(e,[t],n)},t.prototype.clip=function(t,e,n){var r,o=(r=s.getBool("WEBGL_PACK_CLIP")?new Zo(t.shape):new Jo(t.shape)).getCustomSetupFunc(e,n);return this.compileAndRun(r,[t],null,o)},t.prototype.abs=function(t){var e=new Wi(t.shape,"return abs(x);");return this.compileAndRun(e,[t])},t.prototype.complexAbs=function(t){var e=this.texData.get(t.dataId),n=new ta(t.shape),r=[this.makeComplexComponentTensorHandle(t,e.complexTensors.real),this.makeComplexComponentTensorHandle(t,e.complexTensors.imag)];return this.compileAndRun(n,r)},t.prototype.sigmoid=function(t){var e=new Wi(t.shape,"return 1.0 / (1.0 + exp(-1.0 * x));");return this.compileAndRun(e,[t])},t.prototype.softplus=function(t){var e=new Wi(t.shape,"\n float epsilon = 1.1920928955078125e-7;\n float threshold = log(epsilon) + 2.0;\n\n bool too_large = x > -threshold;\n bool too_small = x < threshold;\n\n float result;\n float exp_x = exp(x);\n\n if (too_large){\n result = x;\n }\n else if (too_small){\n result = exp_x;\n }\n else{\n result = log(exp_x + 1.0);\n }\n return result;\n");return this.compileAndRun(e,[t])},t.prototype.sin=function(t){var e=new Wi(t.shape,Hi);return this.compileAndRun(e,[t])},t.prototype.cos=function(t){var e=new Wi(t.shape,$i);return this.compileAndRun(e,[t])},t.prototype.tan=function(t){var e=new Wi(t.shape,"return tan(x);");return this.compileAndRun(e,[t])},t.prototype.asin=function(t){var e=new Wi(t.shape,"return asin(x);");return this.compileAndRun(e,[t])},t.prototype.acos=function(t){var e=new Wi(t.shape,"return acos(x);");return this.compileAndRun(e,[t])},t.prototype.atan=function(t){var e=new Wi(t.shape,ji);return this.compileAndRun(e,[t])},t.prototype.atan2=function(t,e){var n=s.getBool("WEBGL_PACK_BINARY_OPERATIONS")?new Qo("\n vec4 result = atan(a, b);\n vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new Yo("\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return atan(a, b);\n",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.sinh=function(t){var e=new Wi(t.shape,"\n float e2x = exp(x);\n return (e2x - 1.0 / e2x) / 2.0;\n");return this.compileAndRun(e,[t])},t.prototype.cosh=function(t){var e=new Wi(t.shape,"\n float e2x = exp(-x);\n return (e2x + 1.0 / e2x) / 2.0;\n");return this.compileAndRun(e,[t])},t.prototype.tanh=function(t){var e=new Wi(t.shape,"\n float e2x = exp(-2.0 * abs(x));\n return sign(x) * (1.0 - e2x) / (1.0 + e2x);\n");return this.compileAndRun(e,[t])},t.prototype.asinh=function(t){var e=new Wi(t.shape,"return log(x + sqrt(x * x + 1.0));");return this.compileAndRun(e,[t])},t.prototype.acosh=function(t){var e=new Wi(t.shape,Ki);return this.compileAndRun(e,[t])},t.prototype.atanh=function(t){var e=new Wi(t.shape,Xi);return this.compileAndRun(e,[t])},t.prototype.erf=function(t){var e=new Wi(t.shape,'\n // Error function is calculated approximately with elementary function.\n // See "Handbook of Mathematical Functions with Formulas,\n // Graphs, and Mathematical Tables", Abramowitz and Stegun.\n float p = 0.3275911;\n float a1 = 0.254829592;\n float a2 = -0.284496736;\n float a3 = 1.421413741;\n float a4 = -1.453152027;\n float a5 = 1.061405429;\n\n float t = 1.0 / (1.0 + p * x);\n return 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);\n');return this.compileAndRun(e,[t])},t.prototype.step=function(t,e){var n=new Wi(t.shape,function(t){return void 0===t&&(t=0),Ui+"\n return x > 0.0 ? 1.0 : float("+t+");\n "}(e));return this.compileAndRun(n,[t])},t.prototype.conv2dByMatMul=function(t,e,n){var r=t.shape,o=this.texData.get(t.dataId),a=n.inChannels,i=r[0]*r[1]*r[2],u=n.outChannels,l=(1===i||1===u)&&a>1e3,c=r[2]%2!=0&&!!o.isPacked;if(l||!s.getBool("WEBGL_LAZILY_UNPACK")||!s.getBool("WEBGL_PACK_BINARY_OPERATIONS")||!c){var h=this.reshape(t,[1,r[0]*r[1]*r[2],n.inChannels]),p=this.reshape(e,[1,n.inChannels,n.outChannels]);return this.reshape(this.batchMatMul(h,p,!1,!1),n.outShape)}var f=ht.make([1,r[0]*r[1]*(r[2]+1),n.inChannels],{dataId:t.dataId},t.dtype,this),v=o.shape;o.shape=o.shape.slice(),o.shape[o.shape.length-2]++,d(me(o.shape,f.shape),function(){return "packed reshape "+o.shape+" to "+f.shape+" isn't free"});var m=this.reshape(e,[1,n.inChannels,n.outChannels]),g=this.batchMatMul(f,m,!1,!1),y=this.texData.get(g.dataId);return d(y.isPacked,function(){return "batchMatMul result is expected to be packed"}),o.shape=v,y.shape=n.outShape,ht.make(n.outShape,{dataId:g.dataId},g.dtype,this)},t.prototype.conv2dWithIm2Row=function(t,e,n){var r=n.filterWidth,o=n.filterHeight,a=n.inChannels,i=n.outWidth,s=n.outHeight,u=r*o*a,l=s*i,c=[u,l],h=t.squeeze([0]),p=e.reshape([1,u,-1]),f=new ri(c,h.shape,n),d=this.compileAndRun(f,[h]).reshape([1,c[0],c[1]]),v=new ui(d.shape,[1,l,n.outChannels],!0,!1);return this.compileAndRun(v,[d,p]).reshape([1,s,i,n.outChannels])},t.prototype.conv2d=function(t,e,n){if(1===n.filterHeight&&1===n.filterWidth&&1===n.dilationHeight&&1===n.dilationWidth&&1===n.strideHeight&&1===n.strideWidth&&("SAME"===n.padInfo.type||"VALID"===n.padInfo.type))return this.conv2dByMatMul(t,e,n);if(s.getBool("WEBGL_CONV_IM2COL")&&1===t.shape[0])return this.conv2dWithIm2Row(t,e,n);var r=new la(n);return this.compileAndRun(r,[t,e])},t.prototype.conv2dDerInput=function(t,e,n){var r=new oa(n);return this.compileAndRun(r,[t,e])},t.prototype.conv2dDerFilter=function(t,e,n){var r=new ra(n);return this.compileAndRun(r,[t,e])},t.prototype.depthwiseConv2D=function(t,e,n){var r;return s.getBool("WEBGL_PACK_DEPTHWISECONV")&&n.strideWidth<=2&&n.outChannels/n.inChannels==1?(r=new pa(n),this.compileAndRun(r,[t,e],this.makePackedTensor(n.outShape,t.dtype))):(r=new ha(n),this.compileAndRun(r,[t,e]))},t.prototype.depthwiseConv2DDerInput=function(t,e,n){var r=new ua(n);return this.compileAndRun(r,[t,e])},t.prototype.depthwiseConv2DDerFilter=function(t,e,n){var r=new sa(n);return this.compileAndRun(r,[t,e])},t.prototype.conv3d=function(t,e,n){var r=new ca(n);return this.compileAndRun(r,[t,e])},t.prototype.conv3dDerInput=function(t,e,n){var r=new ia(n);return this.compileAndRun(r,[t,e])},t.prototype.conv3dDerFilter=function(t,e,n){var r=new aa(n);return this.compileAndRun(r,[t,e])},t.prototype.maxPool=function(t,e){var n=new di(e,"max",!1),r=this.makeOutputArray(n.outputShape,t.dtype);return this.compileAndRun(n,[t],r)},t.prototype.avgPool=function(t,e){var n=new di(e,"avg",!1),r=this.makeOutputArray(n.outputShape,"float32");return this.compileAndRun(n,[t],r)},t.prototype.maxPoolBackprop=function(t,e,n,r){var o=new di(r,"max",!0),a=this.compileAndRun(o,[e]),i=new si(r),s=this.makeOutputArray(i.outputShape,e.dtype),u=this.compileAndRun(i,[t,a],s);return a.dispose(),u},t.prototype.avgPoolBackprop=function(t,e,n){var r=new zo(n),o=this.makeOutputArray(r.outputShape,e.dtype);return this.compileAndRun(r,[t],o)},t.prototype.cast=function(t,e){return oo(t,e,this)},t.prototype.unstack=function(t,e){for(var n=t.shape[e],r=new Array(t.rank-1),o=0,a=0;a1,function(){return "blockSize should be > 1 for depthToSpace, but was: "+e});var r=t.shape[0],o="NHWC"===n?t.shape[1]:t.shape[2],a="NHWC"===n?t.shape[2]:t.shape[3],i="NHWC"===n?t.shape[3]:t.shape[1],s=o*e,u=a*e,l=i/(e*e),c=new ya("NHWC"===n?[r,s,u,l]:[r,l,s,u],e,n);return this.compileAndRun(c,[t])},t.prototype.split=function(t,e,n){return vo(t,e,n)},t.prototype.scatterND=function(t,e,n){var r=kr(0,t,n),o=r.sliceRank,a=r.numUpdates,i=r.sliceSize,s=r.strides,u=r.outputSize,l=[u/i,i],c=t.reshape([a,o]),h=e.reshape([a,i]);if(0===u)return ao(fn([]),n);var p=vn(0),f=new Ri(a,o,c.rank,h.rank,s,l);return this.compileAndRun(f,[h,c,p]).reshape(n)},t.prototype.sparseToDense=function(t,e,n,r){var o=kr(0,t,n),a=o.sliceRank,i=o.numUpdates,s=o.strides,u=o.outputSize,l=new Ri(i,a,t.rank,e.rank,s,[u,1],!1);return this.compileAndRun(l,[e,t,r]).reshape(n)},t.prototype.fft=function(t){return this.fftImpl(t,!1)},t.prototype.ifft=function(t){return this.fftImpl(t,!0)},t.prototype.fftImpl=function(t,e){var n=this.texData.get(t.dataId),r=new Ia(Ea,t.shape,e),o=new Ia(Ra,t.shape,e),a=[this.makeComplexComponentTensorHandle(t,n.complexTensors.real),this.makeComplexComponentTensorHandle(t,n.complexTensors.imag)],i=this.compileAndRun(r,a),s=this.compileAndRun(o,a),u=this.complex(i,s).as2D(t.shape[0],t.shape[1]);return i.dispose(),s.dispose(),u},t.prototype.gatherND=function(t,e){var n=e.shape,r=n[n.length-1],o=Rr(t,e),a=o[0],i=o[1],s=o[2],u=o[3],l=e.reshape([i,r]),c=t.reshape([t.size/s,s]),h=new _a(r,u,[i,s]);return this.compileAndRun(h,[c,l]).reshape(a)},t.prototype.fill=function(t,e,n){if("string"===(n=n||U(e))){var r=A(n,y(t));return r.fill(e),ht.make(t,{values:r},n)}var o=new Sa(t,e),a=o.getCustomSetupFunc(e),i=this.makeOutputArray(t,n);return this.compileAndRun(o,[],i,a)},t.prototype.onesLike=function(t){if("string"===t.dtype)throw new Error("onesLike is not supported under string dtype");return this.fill(t.shape,1,t.dtype)},t.prototype.zerosLike=function(t){return this.fill(t.shape,"string"===t.dtype?"":0,t.dtype)},t.prototype.linspace=function(t,e,n){return io(t,e,n)},t.prototype.makeOutputArray=function(t,e){return ht.make(t,{},e,this)},t.prototype.makePackedTensor=function(t,e){var n=ht.make(t,{},e,this);return this.texData.get(n.dataId).isPacked=!0,n},t.prototype.unpackTensor=function(t){var e=new Zi(t.shape);return this.compileAndRun(e,[t],ht.make(e.outputShape,{},t.dtype,this))},t.prototype.packTensor=function(t){var e=new hi(t.shape);return this.compileAndRun(e,[t],this.makePackedTensor(t.shape,t.dtype),null,!0)},t.prototype.packedReshape=function(t,e){var n=t.reshape([he(t.shape)].concat(pe(t.shape))),r=[he(e)].concat(pe(e)),o=new mi(r,n.shape);return this.compileAndRun(o,[n]).reshape(e)},t.prototype.decode=function(t){var e,n=this.texData.get(t),r=n.isPacked,o=n.shape,a=n.dtype,i=fe(o),s=Fa(o),u=this.makeTensorHandle(o,"float32");return this.texData.get(u.dataId).isPacked=!0,this.texData.get(u.dataId).dtype=a,this.texData.get(u.dataId).texShape=s.map(function(t){return 2*t}),e=r?new ga(i,s):new ma(i,s),this.compileAndRun(e,[{shape:i,dtype:a,dataId:t}],u,null,!0),u},t.prototype.compileAndRun=function(t,e,n,r,o){var a=this;if(void 0===o&&(o=!1),null==n&&(n=t.usesPackedTextures?this.makePackedTensor(t.outputShape,e[0].dtype):this.makeOutputArray(t.outputShape,e[0].dtype)),0===n.size)return this.texData.get(n.dataId).values=k(n.dtype,0),n;var i=e.map(function(e){if("complex64"===e.dtype)throw new Error("GPGPUProgram does not support complex64 input. For complex64 dtypes, please separate the program into real and imaginary parts.");var n=a.texData.get(e.dataId);if(null==n.texture){if(!t.usesPackedTextures&&y(e.shape)<=s.getNumber("WEBGL_SIZE_UPLOAD_UNIFORM"))return {shape:e.shape,texData:null,isUniform:!0,uniformValues:n.values};t.usesPackedTextures&&(n.isPacked=!0,n.shape=e.shape);}else if(!!n.isPacked!=!!t.usesPackedTextures)e=n.isPacked?a.unpackTensor(e):a.packTensor(e),n=a.texData.get(e.dataId);else if(n.isPacked&&!me(n.shape,e.shape)){var r=e,o=e.shape;e.shape=n.shape,e=a.packedReshape(e,o),n=a.texData.get(e.dataId),r.shape=o;}return a.uploadToGPU(e.dataId),{shape:e.shape,texData:n,isUniform:!1}});this.uploadToGPU(n.dataId);var u,l={shape:n.shape,texData:this.texData.get(n.dataId),isUniform:!1},c=function(t,e,n){var r="";e.concat(n).forEach(function(t){var e=null!=t.texData&&null!=t.texData.slice&&t.texData.slice.flatOffset>0,n=t.isUniform?"uniform":t.texData.texShape;r+=t.shape+"_"+n+"_"+e;});var o=t.userCode,a=t.constructor.name;return a+="_"+r+"_"+o}(t,i,l),h=this.getAndSaveBinary(c,function(){return function(t,e,n,r){var o=e.userCode,a=n.map(function(t,n){var r={logicalShape:t.shape,texShape:t.isUniform?null:t.texData.texShape,isUniform:t.isUniform,isPacked:!t.isUniform&&t.texData.isPacked,flatOffset:null};return null!=t.texData&&null!=t.texData.slice&&t.texData.slice.flatOffset>0&&(r.flatOffset=t.texData.slice.flatOffset),{name:e.variableNames[n],shapeInfo:r}}),i=a.map(function(t){return t.shapeInfo}),u={logicalShape:r.shape,texShape:r.texData.texShape,isUniform:!1,isPacked:r.texData.isPacked,flatOffset:null},l=ko(a,u,o,e.usesPackedTextures),c=t.createProgram(l),h=null,p=t.getUniformLocation(c,"NAN",!1);1===s.getNumber("WEBGL_VERSION")&&(h=t.getUniformLocation(c,"INFINITY",!1));for(var f={},d=0;d0?32:16})),this.floatPrecisionValue},t.prototype.epsilon=function(){return 32===this.floatPrecision()?1e-7:1e-4},t.prototype.uploadToGPU=function(t){var e,n=this.texData.get(t),r=n.shape,o=n.dtype,a=n.values,i=n.texture,s=n.usage,u=n.isPacked;if(null==i){var l,c=null!=this.activeTimers;c&&(l=performance.now());var h=n.texShape;if(null==h&&(h=de(r,u),n.texShape=h),null!=a){var p=fe(r),f=void 0,d=h[1],v=h[0],m=a instanceof Uint8Array;u?(d=(e=Ma(h[0],h[1]))[0],v=e[1],f=new Ca(p,[v,d],m)):f=new wa(p,[v,d],m);var g=this.makeTensorHandle([v,d],o);this.texData.get(g.dataId).usage=m?Ta.PIXELS:Ta.UPLOAD,this.gpgpu.uploadDenseMatrixToTexture(this.getTexture(g.dataId),d,v,a);var x=this.makeTensorHandle(f.outputShape,g.dtype);x.size=y(f.outputShape),this.texData.get(x.dataId).isPacked=u,this.compileAndRun(f,[g],x);var b=this.texData.get(x.dataId);n.texture=b.texture,n.texShape=b.texShape,n.isPacked=b.isPacked,n.usage=b.usage,this.disposeData(g.dataId),this.texData.delete(x.dataId),n.values=null,c&&(this.uploadWaitMs+=performance.now()-l);}else{var w=this.acquireTexture(h,s,o,u);n.texture=w;}}},t.prototype.convertAndCacheOnCPU=function(t,e){var n=this.texData.get(t),r=n.dtype;return this.releaseGPUData(t),null!=e&&(n.values=function(t,e){if("float32"===e||"complex64"===e)return t;if("int32"===e||"bool"===e){for(var n="int32"===e?new Int32Array(t.length):new Uint8Array(t.length),r=0;r1024*this.numMBBeforeWarning*1024){var o=(this.numBytesInGPU/1024/1024).toFixed(2);this.warnedAboutMemory=!0,console.warn("High memory usage in GPU: "+o+" MB, most likely due to a memory leak");}return this.textureManager.acquireTexture(t,e,r)},t.prototype.computeBytes=function(t,e){return t[0]*t[1]*M(e)},t}();Tt()&&At.registerBackend("webgl",function(){return new ns},2);var rs=ln({abs_:function(t){var e=Ye(t,"x","abs");return "complex64"===e.dtype?At.runKernel(function(t){return t.complexAbs(e)},{$x:e}):At.runKernel(function(t,n){var r=t.abs(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.toFloat().step(-1))}}})}}),os=ln({acos_:function(t){var e=Ye(t,"x","acos");return At.runKernel(function(t,n){var r=t.acos(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.divStrict(vn(1).sub(n.toFloat().square()).sqrt()).neg()}}})}}),as=ln({acosh_:function(t){var e=Ye(t,"x","acosh");return At.runKernel(function(t,n){var r=t.acosh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.divStrict(n.toFloat().square().sub(1).sqrt())}}})}}),is=ln({asin_:function(t){var e=Ye(t,"x","asin");return At.runKernel(function(t,n){var r=t.asin(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.divStrict(vn(1).sub(n.toFloat().square()).sqrt())}}})}}),ss=ln({asinh_:function(t){var e=Ye(t,"x","asinh");return At.runKernel(function(t,n){var r=t.asinh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.divStrict(vn(1).add(n.toFloat().square()).sqrt())}}})}}),us=ln({atan_:function(t){var e=Ye(t,"x","atan");return At.runKernel(function(t,n){var r=t.atan(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.toFloat().square().add(1))}}})}}),ls=ln({atanh_:function(t){var e=Ye(t,"x","atanh");return At.runKernel(function(t,n){var r=t.atanh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(vn(1).sub(n.toFloat().square()))}}})}}),cs=ln({ceil_:function(t){var e=Ye(t,"x","ceil");return At.runKernel(function(t){return t.ceil(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),hs=ln({clipByValue_:function(t,e,n){var r=Ye(t,"x","clipByValue");return d(e<=n,function(){return "Error in clip: min ("+e+") must be less than or equal to max ("+n+")."}),At.runKernel(function(t,o){var a=t.clip(r,e,n);return o([r]),a},{$x:r},function(t,r){var o=r[0];return {$x:function(){return t.where(o.greaterEqual(e).logicalAnd(o.lessEqual(n)),kn(t))}}})}}),ps=ln({cos_:function(t){var e=Ye(t,"x","cos");return At.runKernel(function(t,n){var r=t.cos(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return n.toFloat().sin().neg().mul(t)}}})}}),fs=ln({cosh_:function(t){var e=Ye(t,"x","cosh");return At.runKernel(function(t,n){var r=t.cosh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return n.toFloat().sinh().mulStrict(t)}}})}}),ds=ln({erf_:function(t){var e=Ye(t,"x","erf");return d("int32"===e.dtype||"float32"===e.dtype,function(){return "Input dtype must be `int32` or `float32`."}),"int32"===e.dtype&&(e=e.toFloat()),At.runKernel(function(t,n){var r=t.erf(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.square().neg().exp().mul(2/Math.sqrt(Math.PI)))}}})}}),vs=ln({exp_:function(t){var e=Ye(t,"x","exp");return At.runKernel(function(t,n){var r=t.exp(e);return n([r]),r},{$x:e},function(t,e){return {$x:function(){return t.mulStrict(e[0])}}})}}),ms=ln({expm1_:function(t){var e=Ye(t,"x","expm1");return At.runKernel(function(t,n){var r=t.expm1(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.exp())}}})}}),gs=ln({floor_:function(t){var e=Ye(t,"x","floor");return At.runKernel(function(t){return t.floor(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),ys=ln({log_:function(t){var e=Ye(t,"x","log");return At.runKernel(function(t,n){var r=t.log(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.toFloat())}}})}}),xs=ln({log1p_:function(t){var e=Ye(t,"x","log1p");return At.runKernel(function(t,n){var r=t.log1p(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.add(1))}}})}}),bs=ln({logSigmoid_:function(t){var e=Ye(t,"x","logSigmoid");return At.runKernel(function(t,n){var r=t.softplus(e.neg()).neg();return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.neg().sigmoid())}}})}}),ws=ln({neg_:function(t){var e=Ye(t,"x","neg");return At.runKernel(function(t){return t.neg(e)},{$x:e},function(t){return {$x:function(){return t.neg()}}})}}),Cs=ln({reciprocal_:function(t){var e=Ye(t,"x","reciprocal");return At.runKernel(function(t,n){var r=t.reciprocal(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.square().neg())}}})}}),Es=ln({round_:function(t){var e=Ye(t,"x","round");return At.runKernel(function(t){return t.round(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),Rs=ln({rsqrt_:function(t){var e=Ye(t,"x","rsqrt");return At.runKernel(function(t,n){var r=t.rsqrt(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.pow(1.5).mul(2)).neg()}}})}}),Is=ln({sigmoid_:function(t){var e=Ye(t,"x","sigmoid");return At.runKernel(function(t,n){var r=t.sigmoid(e);return n([r]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.mul(vn(1).sub(n)))}}})}}),Ss=ln({sign_:function(t){var e=Ye(t,"x","sign");return At.runKernel(function(t){return t.sign(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),Ns=ln({isNaN_:function(t){var e=Ye(t,"x","isNaN");return At.runKernel(function(t){return t.isNaN(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),ks=ln({isInf_:function(t){var e=Ye(t,"x","isInf");return At.runKernel(function(t){return t.isInf(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),As=ln({isFinite_:function(t){var e=Ye(t,"x","isFinite");return At.runKernel(function(t){return t.isFinite(e)},{$x:e},function(t){return {$x:function(){return kn(t)}}})}}),Ts=ln({sin_:function(t){var e=Ye(t,"x","sin");return At.runKernel(function(t,n){var r=t.sin(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return n.toFloat().cos().mul(t)}}})}}),Ds=ln({sinh_:function(t){var e=Ye(t,"x","sinh");return At.runKernel(function(t,n){var r=t.sinh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return n.toFloat().cosh().mulStrict(t)}}})}}),_s=ln({softplus_:function(t){var e=Ye(t,"x","softplus");return At.runKernel(function(t,n){var r=t.softplus(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.sigmoid())}}})}}),Os=ln({sqrt_:function(t){var e=Ye(t,"x","sqrt");return At.runKernel(function(t,n){var r=t.sqrt(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.toFloat().sqrt().mul(2))}}})}}),Fs=ln({square_:function(t){var e=Ye(t,"x","square");return At.runKernel(function(t,n){return n([e]),t.square(e)},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mul(n.toFloat().mul(2))}}})}}),Ms=ln({step_:function(t,e){void 0===e&&(e=0);var n=Ye(t,"x","step");return At.runKernel(function(t){return t.step(n,e)},{$x:n},function(t){return {$x:function(){return kn(t)}}})}}),Bs=ln({tan_:function(t){var e=Ye(t,"x","tan");return At.runKernel(function(t,n){var r=t.tan(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.div(n.cos().square())}}})}}),Ps=ln({tanh_:function(t){var e=Ye(t,"x","tanh");return At.runKernel(function(t,n){var r=t.tanh(e);return n([r]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return vn(1).sub(n.square()).mulStrict(t)}}})}});function Ls(t,e,n,r,o,a){var i,s,u=Ye(t,"x","batchNorm"),l=Ye(e,"mean","batchNorm"),c=Ye(n,"variance","batchNorm");return null!=o&&(i=Ye(o,"scale","batchNorm")),null!=r&&(s=Ye(r,"offset","batchNorm")),d(2===u.rank,function(){return "Error in batchNorm3D: x must be rank 3 but got rank "+u.rank+"."}),d(2===l.rank||1===l.rank,function(){return "Error in batchNorm2D: mean must be rank 2 or rank 1 but got rank "+l.rank+"."}),d(2===c.rank||1===c.rank,function(){return "Error in batchNorm2D: variance must be rank 2 or rank 1 but got rank "+c.rank+"."}),null!=i&&d(2===i.rank||1===i.rank,function(){return "Error in batchNorm2D: scale must be rank 2 or rank 1 but got rank "+i.rank+"."}),null!=s&&d(2===s.rank||1===s.rank,function(){return "Error in batchNorm2D: offset must be rank 2 or rank 1 but got rank "+s.rank+"."}),zs(u,l,c,s,i,a)}function Ws(t,e,n,r,o,a){var i,s,u=Ye(t,"x","batchNorm"),l=Ye(e,"mean","batchNorm"),c=Ye(n,"variance","batchNorm");return null!=o&&(i=Ye(o,"scale","batchNorm")),null!=r&&(s=Ye(r,"offset","batchNorm")),d(3===u.rank,function(){return "Error in batchNorm3D: x must be rank 3 but got rank "+u.rank+"."}),d(3===l.rank||1===l.rank,function(){return "Error in batchNorm3D: mean must be rank 3 or rank 1 but got rank "+l.rank+"."}),d(3===c.rank||1===c.rank,function(){return "Error in batchNorm3D: variance must be rank 3 or rank 1 but got rank "+c.rank+"."}),null!=i&&d(3===i.rank||1===i.rank,function(){return "Error in batchNorm3D: scale must be rank 3 or rank 1 but got rank "+i.rank+"."}),null!=s&&d(3===s.rank||1===s.rank,function(){return "Error in batchNorm3D: offset must be rank 3 or rank 1 but got rank "+s.rank+"."}),zs(u,l,c,s,i,a)}function Us(t,e,n,r,o,a){var i,s,u=Ye(t,"x","batchNorm"),l=Ye(e,"mean","batchNorm"),c=Ye(n,"variance","batchNorm");return null!=o&&(i=Ye(o,"scale","batchNorm")),null!=r&&(s=Ye(r,"offset","batchNorm")),d(4===u.rank,function(){return "Error in batchNorm4D: x must be rank 4 but got rank "+u.rank+"."}),d(4===l.rank||1===l.rank,function(){return "Error in batchNorm4D: mean must be rank 4 or rank 1 but got rank "+l.rank+"."}),d(4===c.rank||1===c.rank,function(){return "Error in batchNorm4D: variance must be rank 4 or rank 1 but got rank "+c.rank+"."}),null!=i&&d(4===i.rank||1===i.rank,function(){return "Error in batchNorm4D: scale must be rank 4 or rank 1 but got rank "+i.rank+"."}),null!=s&&d(4===s.rank||1===s.rank,function(){return "Error in batchNorm4D: offset must be rank 4 or rank 1 but got rank "+s.rank+"."}),zs(u,l,c,s,i,a)}function zs(t,e,n,r,o,a){null==a&&(a=.001);var i,s,u,l=Ye(t,"x","batchNorm"),c=Ye(e,"mean","batchNorm"),h=Ye(n,"variance","batchNorm");null!=o&&(i=Ye(o,"scale","batchNorm")),null!=r&&(s=Ye(r,"offset","batchNorm")),d(c.rank===h.rank,function(){return "Batch normalization gradient requires mean and variance to have equal ranks."}),d(null==s||c.rank===s.rank,function(){return "Batch normalization gradient requires mean and offset to have equal ranks."}),d(null==i||c.rank===i.rank,function(){return "Batch normalization gradient requires mean and scale to have equal ranks."}),u=0===l.rank||1===l.rank?l.as4D(1,1,1,l.size):2===l.rank?l.as4D(1,1,l.shape[0],l.shape[1]):3===l.rank?l.as4D(1,l.shape[0],l.shape[1],l.shape[2]):l;return At.runKernel(function(t,e){var n=t.batchNormalization(u,Vs(c),Vs(h),a,Vs(i),Vs(s));return e([l,c,h,i]),n},{$x:l,$mean:c,$variance:h,$scale:i,$offset:s},function(t,e){var n=e,r=n[0],o=n[1],i=n[2],s=n[3],l=null==s?vn(1):s,c=$r(o.shape,u.shape),h=[];if(1===o.rank){for(var p=0;p=2&&i.rank>=2&&a.rank===i.rank,function(){return "Error in matMul: inputs must have the same rank of at least 2, got ranks "+a.rank+" and "+i.rank+"."}),d(x(h,p),function(){return "Error in matMul: outer dimensions ("+h+") and ("+p+") of Tensors with shapes "+a.shape+" and "+i.shape+" must match."}),d(s===u,function(){return "Error in matMul: inner shapes ("+s+") and ("+u+") of Tensors with shapes "+a.shape+" and "+i.shape+" and transposeA="+n+" and transposeB="+r+" must match."});var m=a.shape.slice(0,-2).concat([l,c]),g=n?a.as3D(f,s,l):a.as3D(f,l,s),b=r?i.as3D(v,c,u):i.as3D(v,u,c);return At.runKernel(function(t,e){var o=t.batchMatMul(g,b,n,r);return e([g,b]),o},{$a:g,$b:b},function(t,e){var o=e,a=o[0],i=o[1];return n||r?!n&&r?{$a:function(){return t.matMul(i,!1,!1)},$b:function(){return t.matMul(a,!0,!1)}}:n&&!r?{$a:function(){return i.matMul(t,!1,!0)},$b:function(){return a.matMul(t,!1,!1)}}:{$a:function(){return i.matMul(t,!0,!0)},$b:function(){return t.matMul(a,!0,!0)}}:{$a:function(){return t.matMul(i,!1,!0)},$b:function(){return a.matMul(t,!0,!1)}}}).reshape(m)}}),lu=ln({dot_:function(t,e){var n=Ye(t,"t1","dot"),r=Ye(e,"t2","dot");d(!(1!==n.rank&&2!==n.rank||1!==r.rank&&2!==r.rank),function(){return "Error in dot: inputs must all be rank 1 or 2, but got ranks "+n.rank+" and "+r.rank+"."});var o=1===n.rank?n.size:n.shape[1],a=1===r.rank?r.size:r.shape[0];return d(o===a,function(){return "Error in dot: inner dimensions of inputs must match, but got "+o+" and "+a+"."}),1===n.rank&&1===r.rank?n.as2D(1,-1).matMul(r.as2D(-1,1)).asScalar():1===n.rank&&2===r.rank?n.as2D(1,-1).matMul(r.as2D(r.shape[0],r.shape[1])).as1D():2===n.rank&&1===r.rank?n.matMul(r.as2D(-1,1)).as1D():n.matMul(r.as2D(r.shape[0],r.shape[1]))}}),cu=ln({outerProduct_:function(t,e){var n=Ye(t,"v1","outerProduct"),r=Ye(e,"v2","outerProduct");return d(1===n.rank&&1===r.rank,function(){return "Error in outerProduct: inputs must be rank 1, but got ranks "+n.rank+" and "+r.rank+"."}),n.as2D(-1,1).matMul(r.as2D(1,-1))}});var hu=ln({reverse_:function(t,e){var n=Ye(t,"x","reverse");if(0===n.rank)return n.clone();var r=S(e,n.shape);return At.runKernel(function(t){return t.reverse(n,r)},{$x:n},function(t){return {$x:function(){return t.reverse(r)}}}).reshapeAs(n)}}),pu=ln({reverse1d_:function(t){var e=Ye(t,"x","reverse");return d(1===e.rank,function(){return "Error in reverse1D: x must be rank 1 but got rank "+e.rank+"."}),hu(e,0)}}),fu=ln({reverse2d_:function(t,e){var n=Ye(t,"x","reverse");return d(2===n.rank,function(){return "Error in reverse2D: x must be rank 2 but got rank "+n.rank+"."}),hu(n,e)}}),du=ln({reverse3d_:function(t,e){var n=Ye(t,"x","reverse");return d(3===n.rank,function(){return "Error in reverse3D: x must be rank 3 but got rank "+n.rank+"."}),hu(n,e)}}),vu=ln({reverse4d_:function(t,e){var n=Ye(t,"x","reverse");return d(4===n.rank,function(){return "Error in reverse4D: x must be rank 4 but got rank "+n.rank+"."}),hu(n,e)}});function mu(t,e,n,r,o,a){var i=Ye(t,"x","maxPool"),s=i,u=!1;3===i.rank&&(u=!0,s=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),null==r&&(r=[1,1]),d(4===s.rank,function(){return "Error in maxPool: input must be rank 4 but got rank "+s.rank+"."}),d(ro(n,r),function(){return "Error in maxPool: Either strides or dilations must be 1. Got strides "+n+" and dilations '"+r+"'"}),null!=a&&d(b(o),function(){return "Error in maxPool: pad must be an integer when using, dimRoundingMode "+a+" but got pad "+o+"."});var l=Kr(s.shape,e,n,r,o,a),c=At.runKernel(function(t,e){var n=t.maxPool(s,l);return e([s,n]),n},{x:s},function(t,a){var i=a[0],s=a[1];return {x:function(){return function(t,e,n,r,o,a,i,s){var u=Ye(t,"dy","maxPoolBackprop"),l=Ye(e,"input","maxPoolBackprop"),c=Ye(n,"output","maxPoolBackprop");d(l.rank===u.rank,function(){return "Rank of input ("+l.rank+") does not match rank of dy ("+u.rank+")"}),null==a&&(a=[1,1]),d(ro(o,a),function(){return "Error in maxPoolBackProp: Either strides or dilations must be 1. Got strides "+o+" and dilations '"+a+"'"}),d(4===u.rank,function(){return "Error in maxPoolBackprop: dy must be rank 4 but got rank "+u.rank+"."}),d(4===l.rank,function(){return "Error in maxPoolBackprop: input must be rank 4 but got rank "+l.rank+"."}),null!=s&&d(b(i),function(){return "Error in maxPoolBackprop: pad must be an integer when using, dimRoundingMode "+s+" but got pad "+i+"."});var h=Kr(l.shape,r,o,a,i,s);return At.runKernel(function(t){return t.maxPoolBackprop(u,l,c,h)},{$dy:u,$input:l})}(t,i,s,e,n,r,o)}}});return u?c.as3D(c.shape[1],c.shape[2],c.shape[3]):c}function gu(t,e,n,r,o,a){var i=Ye(t,"x","avgPool","float32");null==r&&(r=[1,1]),d(ro(n,r),function(){return "Error in avgPool: Either strides or dilations must be 1. Got strides "+n+" and dilations '"+r+"'"});var s=i,u=!1;3===i.rank&&(u=!0,s=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),d(4===s.rank,function(){return "Error in avgPool: x must be rank 4 but got rank "+s.rank+"."}),null!=a&&d(b(o),function(){return "Error in avgPool: pad must be an integer when using, dimRoundingMode "+a+" but got pad "+o+"."});var l=Kr(s.shape,e,n,r,o,a),c=At.runKernel(function(t){return t.avgPool(s,l)},{x:s},function(t){return {x:function(){return function(t,e,n,r,o,a){var i=Ye(t,"dy","avgPoolBackprop"),s=Ye(e,"input","avgPoolBackprop");d(s.rank===i.rank,function(){return "Rank of input ("+s.rank+") does not match rank of dy ("+i.rank+")"}),null==o&&(o=[1,1]),d(ro(r,o),function(){return "Error in avgPoolBackprop: Either strides or dilations must be 1. Got strides "+r+" and dilations '"+o+"'"});var u=s,l=i,c=!1;3===s.rank&&(c=!0,u=s.as4D(1,s.shape[0],s.shape[1],s.shape[2]),l=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),d(4===l.rank,function(){return "Error in avgPoolBackprop: dy must be rank 4 but got rank "+l.rank+"."}),d(4===u.rank,function(){return "Error in avgPoolBackprop: input must be rank 4 but got rank "+u.rank+"."});var h=Kr(u.shape,n,r,o,a),p=At.runKernel(function(t){return t.avgPoolBackprop(l,u,h)},{dy4D:l,input4D:u});return c?p.as3D(p.shape[1],p.shape[2],p.shape[3]):p}(t,s,e,n,r,o)}}});return c=c.cast(i.dtype),u?c.as3D(c.shape[1],c.shape[2],c.shape[3]):c}var yu=ln({maxPool_:function(t,e,n,r,o){return mu(t,e,n,1,r,o)}}),xu=ln({avgPool_:function(t,e,n,r,o){return gu(t,e,n,1,r,o)}}),bu=ln({pool_:function(t,e,n,r,o,a){null==o&&(o=[1,1]),null==a&&(a=1),0===r&&(r="valid");var i=Ye(t,"x","maxPool"),s=i,u=!1;3===i.rank&&(u=!0,s=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),d(ro(a,o),function(){return "Error in pool: Either strides or dilations must be 1. Got strides "+a+" and dilations '"+o+"'"});var l,c=Kr(s.shape,e,a,o,r),h=[c.dilationHeight,c.dilationWidth];l="same"===r?function(t,e){var n=t.map(function(t,n){return t+(t-1)*(e[n]-1)}).map(function(t){return t-1}),r=n.map(function(t){return Math.floor(t/2)}),o=n.map(function(t,e){return t-r[e]});return n.map(function(t,e){return [r[e],o[e]]})}([c.filterHeight,c.filterWidth],h):[[0,0],[0,0]];var p=1===h[0]&&1===h[1],f=function(t,e,n){var r=n.map(function(t){return t[0]}),o=n.map(function(t){return t[1]}),a=t.concat(r,o),i=e.map(function(t,e){return (t-a[e]%t)%t}),s=o.map(function(t,e){return t+i[e]}),u=e.map(function(t,e){return [r[e],s[e]]}),l=e.map(function(t,e){return [0,i[e]]});return [u,l]}([c.inHeight,c.inWidth],h,l),v=f[0],m=f[1],g=p?r:"valid",y=p?s:pr(s,h,v),x=("avg"===n?function(){return gu(y,e,a,1,g)}:function(){return mu(y,e,a,1,g)})(),b=p?x:Kn(x,h,m);return u?b.as3D(b.shape[1],b.shape[2],b.shape[3]):b}});var wu=ln({slice_:function(t,e,n){var r,o,a=Ye(t,"x","slice");if(0===a.rank)throw new Error("Slicing scalar is not possible");r="number"==typeof e?[e].concat(new Array(a.rank-1).fill(0)):e.length=0?t:(d(-1===t,function(){return "Bad value in size"}),a.shape[e]-r[e])}),function(t,e,n){d(t.rank===e.length,function(){return "Error in slice"+t.rank+"D: Length of begin "+e+" must match the rank of the array ("+t.rank+")."}),d(t.rank===n.length,function(){return "Error in slice"+t.rank+"D: Length of size "+n+" must match the rank of the array ("+t.rank+")."});for(var r=function(r){d(e[r]+n[r]<=t.shape[r],function(){return "Error in slice"+t.rank+"D: begin["+r+"] + size["+r+"] ("+(e[r]+n[r])+") would overflow input.shape["+r+"] ("+t.shape[r]+")"});},o=0;o0&&(e=e.sum(n)),e.reshape(r.shape)},$b:function(){var e=t,n=$r(o.shape,a);return n.length>0&&(e=e.sum(n)),e.reshape(o.shape)}}})}}),Qu=ln({addN_:function(t){d(Array.isArray(t),function(){return "The argument passed to tf.addN() must be a list of tensors"}),d(t.length>=1,function(){return "Must pass at least one tensor to tf.addN(), but got "+t.length});var e=t.map(function(t,e){return Ye(t,"tensors"+e,"addN")}),n=e[0];e.forEach(function(t){if(t.dtype!==n.dtype)throw new Error("All tensors passed to tf.addN() must have the same dtype")}),e.forEach(function(t){if(!x(t.shape,n.shape))throw new Error("All tensors passed to tf.addN() must have the same shape")});var r=e;return At.runKernel(function(t){return t.addN(e)},r,function(t){var n={};return e.forEach(function(e,r){n[r]=function(){return t.clone()};}),n})}}),Ju=ln({addStrict_:function(t,e){var n=Ye(t,"a","addStrict"),r=Ye(e,"b","addStrict");return v(n.shape,r.shape,"Error in addStrict: "),n.add(r)}}),Zu=ln({atan2_:function(t,e){var n,r=Ye(t,"a","atan2"),o=Ye(e,"b","atan2");n=Ct(r,o),r=n[0],o=n[1];var a=jr(r.shape,o.shape);return At.runKernel(function(t,e){var n=t.atan2(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){var e=Yu(n.square(),r.square()),o=t.mul(r.div(e)),i=$r(n.shape,a);return i.length>0&&(o=o.sum(i)),o.reshape(n.shape)},$b:function(){var e=Yu(n.square(),r.square()),o=ws(t.mul(n.div(e))),i=$r(r.shape,a);return i.length>0&&(o=o.sum(i)),o.reshape(r.shape)}}})}}),tl=ln({div_:function(t,e){var n,r=Ye(t,"a","div"),o=Ye(e,"b","div");if(n=Ct(r,o),r=n[0],o=n[1],"int32"===r.dtype&&"int32"===o.dtype)return nl(r,o);var a=jr(r.shape,o.shape);return At.runKernel(function(t,e){var n=t.realDivide(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){var e=t.div(r.toFloat()),o=$r(n.shape,a);return o.length>0?e.sum(o).reshape(n.shape):e},$b:function(){var e=t.mul(n.toFloat()),o=$r(r.shape,a);o.length>0&&(e=e.sum(o).reshape(r.shape));var i=r.square();return e.div(i.toFloat()).neg()}}})}}),el=ln({divStrict_:function(t,e){var n=Ye(t,"a","div"),r=Ye(e,"b","div");return v(n.shape,r.shape,"Error in divideStrict: "),n.div(r)}}),nl=ln({floorDiv_:function(t,e){var n,r=Ye(t,"a","floorDiv"),o=Ye(e,"b","floorDiv");n=Ct(r,o),r=n[0],o=n[1];var a=jr(r.shape,o.shape);return At.runKernel(function(t,e){var n=t.floorDiv(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){var e=t.div(r.toFloat()),o=$r(n.shape,a);return o.length>0?e.sum(o).reshape(n.shape):e},$b:function(){var e=t.mul(n.toFloat()),o=$r(r.shape,a);o.length>0&&(e=e.sum(o).reshape(r.shape));var i=r.square();return e.div(i.toFloat()).neg()}}})}}),rl=ln({maximum_:function(t,e){var n,r=Ye(t,"a","maximum"),o=Ye(e,"b","maximum");return n=Ct(r,o),r=n[0],o=n[1],"bool"===r.dtype&&(r=r.toInt(),o=o.toInt()),jr(r.shape,o.shape),At.runKernel(function(t,e){var n=t.maximum(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){return t.mul(n.greaterEqual(r).toFloat())},$b:function(){return t.mul(n.less(r).toFloat())}}})}}),ol=ln({maximumStrict_:function(t,e){var n=Ye(t,"a","maximumStrict"),r=Ye(e,"b","maximumStrict");return v(n.shape,r.shape,"Error in maximumStrict: "),n.maximum(r)}}),al=ln({minimum_:function(t,e){var n,r=Ye(t,"a","minimum"),o=Ye(e,"b","minimum");return n=Ct(r,o),r=n[0],o=n[1],"bool"===r.dtype&&(r=r.toInt(),o=o.toInt()),jr(r.shape,o.shape),At.runKernel(function(t,e){var n=t.minimum(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){return t.mul(n.lessEqual(r).toFloat())},$b:function(){return t.mul(n.greater(r).toFloat())}}})}}),il=ln({minimumStrict_:function(t,e){var n=Ye(t,"a","minimumStrict"),r=Ye(e,"b","minimumStrict");return v(n.shape,r.shape,"Error in minimumStrict: "),n.minimum(r)}}),sl=ln({mod_:function(t,e){var n,r=Ye(t,"a","mod"),o=Ye(e,"b","mod");n=Ct(r,o),r=n[0],o=n[1];var a=jr(r.shape,o.shape);return At.runKernel(function(t,e){var n=t.mod(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){var e=$r(n.shape,a);return e.length>0?t.sum(e).reshape(n.shape):t},$b:function(){var e=t.mul(n.div(r).floor().neg()),o=$r(r.shape,a);return o.length>0?e.sum(o).reshape(r.shape):e}}})}}),ul=ln({modStrict_:function(t,e){var n=Ye(t,"a","modStrict"),r=Ye(e,"b","modStrict");return v(n.shape,r.shape,"Error in modStrict: "),n.mod(r)}}),ll=ln({mul_:function(t,e){var n,r=Ye(t,"a","mul"),o=Ye(e,"b","mul");n=Ct(r,o),r=n[0],o=n[1];var a=jr(r.shape,o.shape);return At.runKernel(function(t,e){var n=t.multiply(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return {$a:function(){var e=t.mul(r.toFloat()),o=$r(n.shape,a);return o.length>0?e.sum(o).reshape(n.shape):e},$b:function(){var e=t.mul(n.toFloat()),o=$r(r.shape,a);return o.length>0?e.sum(o).reshape(r.shape):e}}})}}),cl=ln({mulStrict_:function(t,e){var n=Ye(t,"a","mul"),r=Ye(e,"b","mul");return v(n.shape,r.shape,"Error in multiplyStrict: "),n.mul(r)}}),hl=ln({pow_:function(t,e){var n=Ye(t,"base","pow"),r=Ye(e,"exp","pow"),o=jr(n.shape,r.shape);return t=n.cast(bt(n.dtype,r.dtype)),e=r.cast(bt(n.dtype,r.dtype)),At.runKernel(function(t,e){var o=t.pow(n,r);return e([n,r,o]),o},{$base:n,$exp:r},function(t,e){var n=e[0],r=e[1],a=e[2];return {$base:function(){var e=r.toFloat(),a=t.mul(e.mul(n.pow(e.sub(vn(1))))),i=$r(n.shape,o);return i.length>0&&(a=a.sum(i)),a.reshape(n.shape)},$exp:function(){var e=n.greater(0),i=n.log().where(e,kn(n)),s=t.mul(a.mul(i)),u=$r(r.shape,o);return u.length>0&&(s=s.sum(u)),s.reshape(r.shape)}}})}}),pl=ln({powStrict_:function(t,e){return v(t.shape,e.shape,"Error in powStrict: "),t.pow(e)}}),fl=ln({squaredDifference_:function(t,e){var n,r=Ye(t,"a","squaredDifference"),o=Ye(e,"b","squaredDifference");return n=Ct(r,o),r=n[0],o=n[1],jr(r.shape,o.shape),At.runKernel(function(t,e){var n=t.squaredDifference(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1],o=vn(2);return {$a:function(){return t.mul(n.sub(r).mul(o))},$b:function(){return t.mul(r.sub(n).mul(o))}}})}}),dl=ln({squaredDifferenceStrict_:function(t,e){var n=Ye(t,"a","squaredDifferenceStrict"),r=Ye(e,"b","squaredDifferenceStrict");return v(n.shape,r.shape,"Error in squaredDifferenceStrict: "),n.squaredDifference(r)}}),vl=ln({sub_:function(t,e){var n,r=Ye(t,"a","sub"),o=Ye(e,"b","sub");n=Ct(r,o),r=n[0],o=n[1];var a=jr(r.shape,o.shape);return At.runKernel(function(t){return t.subtract(r,o)},{$a:r,$b:o},function(t){return {$a:function(){var e=t,n=$r(r.shape,a);return n.length>0&&(e=e.sum(n)),e.reshape(r.shape)},$b:function(){var e=t,n=$r(o.shape,a);return n.length>0&&(e=e.sum(n)),e.neg().reshape(o.shape)}}})}}),ml=ln({subStrict_:function(t,e){var n=Ye(t,"a","subStrict"),r=Ye(e,"b","subStrict");return v(n.shape,r.shape,"Error in subStrict: "),n.sub(r)}});var gl=ln({logicalAnd_:function(t,e){var n=Ye(t,"a","logicalAnd","bool"),r=Ye(e,"b","logicalAnd","bool");return jr(n.shape,r.shape),At.runKernel(function(t){return t.logicalAnd(n,r)},{$a:n,$b:r})}}),yl=ln({logicalNot_:function(t){var e=Ye(t,"x","logicalNot","bool");return At.runKernel(function(t){return t.logicalNot(e)},{$x:e})}}),xl=ln({logicalOr_:function(t,e){var n=Ye(t,"a","logicalOr","bool"),r=Ye(e,"b","logicalOr","bool");return jr(n.shape,r.shape),At.runKernel(function(t){return t.logicalOr(n,r)},{$a:n,$b:r})}}),bl=ln({logicalXor_:function(t,e){var n=Ye(t,"a","logicalXor","bool"),r=Ye(e,"b","logicalXor","bool");return jr(n.shape,r.shape),xl(t,e).logicalAnd(gl(t,e).logicalNot())}}),wl=ln({where_:function(t,e,n){var r=Ye(e,"a","where"),o=Ye(n,"b","where"),a=Ye(t,"condition","where","bool");return v(r.shape,o.shape,"Error in where: "),1===a.rank?d(a.shape[0]===r.shape[0],function(){return "The first dimension of `a` must match the size of `condition`."}):v(a.shape,o.shape,"Error in where: "),At.runKernel(function(t,e){var n=t.select(a,r,o);return e([a]),n},{$condition:a,$a:r,$b:o},function(t,e){var n=e[0];return {$condition:function(){return kn(n).toFloat()},$a:function(){return t.mul(n.cast(t.dtype))},$b:function(){return t.mul(n.logicalNot().cast(t.dtype))}}})}}),Cl=function(t){return r(this,void 0,void 0,function(){var e,n,r;return o(this,function(o){switch(o.label){case 0:return [4,(e=Ye(t,"condition","whereAsync","bool")).data()];case 1:return n=o.sent(),r=yo(e.shape,n),t!==e&&e.dispose(),[2,r]}})})};var El=ln({elu_:function(t){var e=Ye(t,"x","elu");return At.runKernel(function(t,n){var r=t.elu(e);return n([r]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return At.runKernel(function(e){return e.eluDer(t,n)},{dy:t,y:n})}}})}}),Rl=ln({leakyRelu_:function(t,e){void 0===e&&(e=.2);var n=Ye(t,"x","leakyRelu");return rl(vn(e).mul(n),n)}}),Il=ln({prelu_:function(t,e){var n=Ye(t,"x","prelu"),r=Ye(e,"alpha","prelu");return At.runKernel(function(t,e){var o=t.prelu(n,r);return e([n,r]),o},{$x:n,$alpha:r},function(t,e){var n=e[0],r=e[1],o=n.greater(0);return {$x:function(){return wl(o,t,t.mul(r))},$alpha:function(){var e=wl(o,kn(t),t.mul(n)),a=$r(r.shape,t.shape);return a.length>0&&(e=e.sum(a)),e.reshape(r.shape)}}})}}),Sl=ln({relu_:function(t){var e=Ye(t,"x","relu");return "bool"===e.dtype?e.toInt():At.runKernel(function(t,n){var r=t.relu(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){return t.mulStrict(n.step().toFloat())}}})}}),Nl=ln({selu_:function(t){var e=Ye(t,"x","selu");return At.runKernel(function(t,n){var r=t.selu(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return {$x:function(){var e=n.greater(vn(0)),r=vn(Pi),o=vn(Li),a=t.mul(o),i=t.mul(r).mul(n.toFloat().exp());return wl(e,a,i)}}})}});var kl=ln({transpose_:function(t,e){var n=Ye(t,"x","transpose");return null==e&&(e=n.shape.map(function(t,e){return e}).reverse()),d(n.rank===e.length,function(){return "Error in transpose: rank of input "+n.rank+" must match length of perm "+e+"."}),e.forEach(function(t){d(t>=0&&to)throw new Error("'k' passed to topk() must be <= the last dimension ("+o+") but got "+e);var a=At.runKernel(function(t){return t.topk(r,e,n)},{$x:r});return {values:a[0],indices:a[1]}}});var Ul=ln({scatterND_:function(t,e,n){var r=Ye(t,"indices","scatterND","int32"),o=Ye(e,"updates","scatterND");return Nr(o,r,n),At.runKernel(function(t){return t.scatterND(r,o,n)},{$indices:r,$updates:o})}});var zl=ln({fft_:function(t){d("complex64"===t.dtype,function(){return "The dtype for tf.spectral.fft() must be complex64 but got "+t.dtype+"."});var e=t.shape[t.shape.length-1],n=t.size/e,r=t.as2D(n,e);return At.runKernel(function(t){return t.fft(r)},{input:t}).reshape(t.shape)}}),Vl=ln({ifft_:function(t){d("complex64"===t.dtype,function(){return "The dtype for tf.spectral.ifft() must be complex64 but got "+t.dtype+"."});var e=t.shape[t.shape.length-1],n=t.size/e,r=t.as2D(n,e);return At.runKernel(function(t){return t.ifft(r)},{input:t}).reshape(t.shape)}}),Gl=ln({rfft_:function(t,e){d("float32"===t.dtype,function(){return "The dtype for rfft() must be real value but got "+t.dtype});var n,r=t.shape[t.shape.length-1],o=t.size/r;if(null!=e&&er){var s=t.shape.map(function(t){return t});s[t.shape.length-1]=e-r,n=t.concat(En(s),t.shape.length-1),r=e;}else n=t;var u=n.zerosLike(),l=cn(n,u).as2D(o,r),c=zl(l),h=Math.floor(r/2)+1,p=hn(c),f=pn(c),v=p.split([h,r-h],p.shape.length-1),m=f.split([h,r-h],f.shape.length-1),g=n.shape.slice();return g[n.shape.length-1]=h,cn(v[0],m[0]).reshape(g)}}),ql=ln({irfft_:function(t){var e=t.shape[t.shape.length-1],n=t.size/e;if(e<=2){var r=t.as2D(n,e),o=Vl(r);return hn(o)}var a=[n,2*(e-1)],i=hn(t).as2D(n,e),s=pn(t).as2D(n,e),u=i.slice([0,1],[n,e-2]).reverse(1),l=s.slice([0,1],[n,e-2]).reverse(1).mul(vn(-1)),c=i.concat(u,1),h=s.concat(l,1);return r=cn(c,h).as2D(a[0],a[1]),o=Vl(r),hn(o)}}),Hl=Object.freeze({fft:zl,ifft:Vl,rfft:Gl,irfft:ql});var $l=ln({sparseToDense_:function(t,e,n,r){void 0===r&&(r=0);var o=Ye(t,"sparseIndices","sparseToDense","int32"),a=Ye(e,"sparseValues","sparseToDense"),i=Ye(r,"defaultValue","sparseToDense",a.dtype);return function(t,e,n,r){if("int32"!==t.dtype)throw new Error("tf.sparseToDense() expects the indices to be int32 type, but the dtype was "+t.dtype+".");if(t.rank>2)throw new Error("sparseIndices should be a scalar, vector, or matrix, but got shape "+t.shape+".");var o=t.rank>0?t.shape[0]:1,a=t.rank>1?t.shape[1]:1;if(n.length!==a)throw new Error("outputShape has incorrect number of elements:, "+n.length+", should be: "+a+".");var i=e.size;if(0!==e.rank&&(1!==e.rank||i!==o))throw new Error("sparseValues has incorrect shape "+e.shape+", should be [] or ["+o+"]");if(e.dtype!==r.dtype)throw new Error("sparseValues.dtype must match defaultValues.dtype")}(o,a,n,i),At.runKernel(function(t){return t.sparseToDense(o,a,n,i)},{$sparseIndices:o,$sparseValues:a,$defaultValue:i})}});var jl=ln({gatherND_:function(t,e){var n=Ye(e,"indices","gatherND","int32"),r=Ye(t,"x","gatherND");return At.runKernel(function(t){return t.gatherND(r,n)},{$x:r,$indices:n})}});var Kl=ln({dropout_:function(t,e,n,r){if(null!=n&&!x(t.shape,n))throw new Error("Non-default noise shape is not implemented yet: "+JSON.stringify(n));var o=cr(t.shape,0,1,"float32",r).greater(e);return o=o.div(vl(1,e)),t.mul(o)}});function Xl(t,e,n){for(var r=1-t%2,o=new Float32Array(t),a=0;a1?s.div(vn(i)):s}if(n===Yl.SUM_BY_NONZERO_WEIGHTS){if(null==o)return a.sum().div(vn(r.size));var u=o.mul(Cn(r.shape)).notEqual(vn(0)).sum().toFloat();return a.sum().div(u)}throw Error("Unknown reduction: "+n)}}),rc=ln({cosineDistance_:function(t,e,n,r,o){void 0===o&&(o=Yl.SUM_BY_NONZERO_WEIGHTS);var a=Ye(t,"labels","cosineDistance"),i=Ye(e,"predictions","cosineDistance"),s=null;null!=r&&(s=Ye(r,"weights","cosineDistance")),v(a.shape,i.shape,"Error in cosineDistance: ");var u=vn(1).sub(a.mul(i).sum(n,!0));return nc(u,s,o)}}),oc=ln({hingeLoss_:function(t,e,n,r){void 0===r&&(r=Yl.SUM_BY_NONZERO_WEIGHTS);var o=Ye(t,"labels","hingeLoss"),a=Ye(e,"predictions","hingeLoss"),i=null;null!=n&&(i=Ye(n,"weights","hingeLoss")),v(o.shape,a.shape,"Error in hingeLoss: ");var s=vn(1);o=vn(2).mul(o).sub(s);var u=s.sub(o.mul(a)).relu();return nc(u,i,r)}}),ac=ln({huberLoss_:function(t,e,n,r,o){void 0===r&&(r=1),void 0===o&&(o=Yl.SUM_BY_NONZERO_WEIGHTS);var a=Ye(t,"labels","huberLoss"),i=Ye(e,"predictions","huberLoss"),s=null;null!=n&&(s=Ye(n,"weights","huberLoss")),v(a.shape,i.shape,"Error in huberLoss: ");var u=vn(r),l=i.sub(a).abs(),c=al(l,u),h=l.sub(c),p=vn(.5).mul(c.square()).add(u.mul(h));return nc(p,s,o)}}),ic=ln({logLoss_:function(t,e,n,r,o){void 0===r&&(r=1e-7),void 0===o&&(o=Yl.SUM_BY_NONZERO_WEIGHTS);var a=Ye(t,"labels","logLoss"),i=Ye(e,"predictions","logLoss"),s=null;null!=n&&(s=Ye(n,"weights","logLoss")),v(a.shape,i.shape,"Error in logLoss: ");var u=vn(1),l=vn(r),c=a.mul(i.add(l).log()).neg().sub(u.sub(a).mul(u.sub(i).add(l).log()));return nc(c,s,o)}}),sc=ln({meanSquaredError_:function(t,e,n,r){void 0===r&&(r=Yl.SUM_BY_NONZERO_WEIGHTS);var o=Ye(t,"labels","meanSquaredError"),a=Ye(e,"predictions","meanSquaredError"),i=null;null!=n&&(i=Ye(n,"weights","meanSquaredError")),v(o.shape,a.shape,"Error in meanSquaredError: ");var s=o.squaredDifference(a);return nc(s,i,r)}}),uc=ln({sigmoidCrossEntropy_:function(t,e,n,r,o){void 0===r&&(r=0),void 0===o&&(o=Yl.SUM_BY_NONZERO_WEIGHTS);var a=Ye(t,"multiClassLabels","sigmoidCrossEntropy"),i=Ye(e,"logits","sigmoidCrossEntropy"),s=null;if(null!=n&&(s=Ye(n,"weights","sigmoidCrossEntropy")),v(a.shape,i.shape,"Error in sigmoidCrossEntropy: "),r>0){var u=vn(r),l=vn(1),c=vn(.5);a=a.mul(l.sub(u)).add(c.mul(u));}var h=function(t,e){var n=Ye(t,"labels","sigmoidCrossEntropyWithLogits"),r=Ye(e,"logits","sigmoidCrossEntropyWithLogits");v(n.shape,r.shape,"Error in sigmoidCrossEntropyWithLogits: ");var o=r.relu(),a=r.mul(n),i=r.abs().neg().exp().log1p();return o.sub(a).add(i)}(a,i);return nc(h,s,o)}}),lc=ln({softmaxCrossEntropy_:function(t,e,n,r,o){void 0===r&&(r=0),void 0===o&&(o=Yl.SUM_BY_NONZERO_WEIGHTS);var a=Ye(t,"onehotLabels","softmaxCrossEntropy"),i=Ye(e,"logits","softmaxCrossEntropy"),s=null;if(null!=n&&(s=Ye(n,"weights","softmaxCrossEntropy")),v(a.shape,i.shape,"Error in softmaxCrossEntropy: "),r>0){var u=vn(r),l=vn(1),c=vn(a.shape[1]);a=a.mul(l.sub(u)).add(u.div(c));}var h=function(t,e,n){if(void 0===n&&(n=-1),-1===n&&(n=e.rank-1),n!==e.rank-1)throw Error("Softmax cross entropy along a non-last dimension is not yet supported. Labels / logits was rank "+e.rank+" and dim was "+n);return Wr(function(t,e,r){var o=e.logSumExp([n],!0),a=e.toFloat().sub(o);return r([t,a]),{value:a.mul(t).neg().sum([n]),gradFunc:function(t,e){var r=e[0],o=e[1],a=en(t.shape,[n]);return [t.reshape(a).mul(r.toFloat().sub(o.exp())),t.reshape(a).mul(o.exp().sub(r.toFloat()))]}}})(t,e)}(a,i);return nc(h,s,o)}}),cc=Object.freeze({get Reduction(){return Yl},absoluteDifference:ec,computeWeightedLoss:nc,cosineDistance:rc,hingeLoss:oc,huberLoss:ac,logLoss:ic,meanSquaredError:sc,sigmoidCrossEntropy:uc,softmaxCrossEntropy:lc});function hc(t,e){return void 0===e&&(e=!1),At.tidy(function(){if(2!==t.shape.length)throw new Error("qr2d() requires a 2D Tensor, but got a "+t.shape.length+"D Tensor.");for(var n=t.shape[0],r=t.shape[1],o=tr(n),a=t.clone(),i=gn([[1]],[1,1]),s=i.clone(),u=n>=r?r:n,l=function(t){var e,u=a,l=s,c=o;e=At.tidy(function(){var e=a.slice([t,t],[n-t,1]),u=e.norm(),l=a.slice([t,t],[1,1]),c=l.sign().neg(),h=l.sub(c.mul(u)),p=e.div(h);s=1===p.shape[0]?i.clone():i.concat(p.slice([1,0],[p.shape[0]-1,p.shape[1]]),0);var f=c.matMul(h).div(u).neg(),d=a.slice([t,0],[n-t,r]),v=f.mul(s);a=0===t?d.sub(v.matMul(s.transpose().matMul(d))):a.slice([0,0],[t,r]).concat(d.sub(v.matMul(s.transpose().matMul(d))),0);var m=o.slice([0,t],[n,o.shape[1]-t]);return o=0===t?m.sub(m.matMul(s).matMul(v.transpose())):o.slice([0,0],[n,t]).concat(m.sub(m.matMul(s).matMul(v.transpose())),1),[s,a,o]}),s=e[0],a=e[1],o=e[2],Me([u,l,c]);},c=0;cr&&(o=o.slice([0,0],[n,r]),a=a.slice([0,0],[r,r])),[o,a]})}var pc=ln({gramSchmidt_:function(t){var e;if(Array.isArray(t)){e=!1,d(null!=t&&t.length>0,function(){return "Gram-Schmidt process: input must not be null, undefined, or empty"});for(var n=t[0].shape[0],r=function(e){d(t[e].shape[0]===n,function(){return "Gram-Schmidt: Non-unique lengths found in the input vectors: ("+t[e].shape[0]+" vs. "+n+")"});},o=1;o0)for(var n=0;n= 2, but got rank "+t.rank);if(2===t.rank)return hc(t,e);var n=t.shape.slice(0,t.shape.length-2).reduce(function(t,e){return t*e}),r=gr(t.reshape([n,t.shape[t.shape.length-2],t.shape[t.shape.length-1]]),0),o=[],a=[];return r.forEach(function(t){var n=hc(t,e),r=n[0],i=n[1];o.push(r),a.push(i);}),[dr(o,0).reshape(t.shape),dr(a,0).reshape(t.shape)]}}),dc=Object.freeze({gramSchmidt:pc,qr:fc});function vc(t,e,n,r,o){null==r&&(r=.5),null==o&&(o=Number.NEGATIVE_INFINITY);var a=t.shape[0];return n=Math.min(n,a),d(0<=r&&r<=1,function(){return "iouThreshold must be in [0, 1], but was '"+r+"'"}),d(2===t.rank,function(){return "boxes must be a 2D tensor, but was of rank '"+t.rank+"'"}),d(4===t.shape[1],function(){return "boxes must have 4 columns, but 2nd dimension was "+t.shape[1]}),d(1===e.rank,function(){return "scores must be a 1D tensor"}),d(e.shape[0]===a,function(){return "scores has incompatible shape with boxes. Expected "+a+", but was "+e.shape[0]}),{maxOutputSize:n,iouThreshold:r,scoreThreshold:o}}var mc=ln({resizeBilinear_:function(t,e,n){void 0===n&&(n=!1);var r=Ye(t,"images","resizeBilinear");d(3===r.rank||4===r.rank,function(){return "Error in resizeBilinear: x must be rank 3 or 4, but got rank "+r.rank+"."}),d(2===e.length,function(){return "Error in resizeBilinear: new shape must 2D, but got shape "+e+"."});var o=r,a=!1;3===r.rank&&(a=!0,o=r.as4D(1,r.shape[0],r.shape[1],r.shape[2]));var i=e[0],s=e[1],u=At.runKernel(function(t,e){return e([o]),t.resizeBilinear(o,i,s,n)},{batchImages:o},function(t,e){return {batchImages:function(){return At.runKernel(function(r){return r.resizeBilinearBackprop(t,e[0],n)},{})}}});return a?u.as3D(u.shape[1],u.shape[2],u.shape[3]):u}}),gc=ln({resizeNearestNeighbor_:function(t,e,n){void 0===n&&(n=!1);var r=Ye(t,"images","resizeNearestNeighbor");d(3===r.rank||4===r.rank,function(){return "Error in resizeNearestNeighbor: x must be rank 3 or 4, but got rank "+r.rank+"."}),d(2===e.length,function(){return "Error in resizeNearestNeighbor: new shape must 2D, but got shape "+e+"."}),d("float32"===r.dtype||"int32"===r.dtype,function(){return "`images` must have `int32` or `float32` as dtype"});var o=r,a=!1;3===r.rank&&(a=!0,o=r.as4D(1,r.shape[0],r.shape[1],r.shape[2]));var i=e[0],s=e[1],u=At.runKernel(function(t,e){return e([o]),t.resizeNearestNeighbor(o,i,s,n)},{batchImages:o},function(t,e){return {batchImages:function(){return At.runKernel(function(r){return r.resizeNearestNeighborBackprop(t,e[0],n)},{})}}});return a?u.as3D(u.shape[1],u.shape[2],u.shape[3]):u}}),yc=ln({nonMaxSuppression_:function(t,e,n,r,o){void 0===r&&(r=.5),void 0===o&&(o=Number.NEGATIVE_INFINITY);var a=Ye(t,"boxes","nonMaxSuppression"),i=Ye(e,"scores","nonMaxSuppression"),s=vc(a,i,n,r,o);return n=s.maxOutputSize,r=s.iouThreshold,o=s.scoreThreshold,At.runKernel(function(t){return t.nonMaxSuppression(a,i,n,r,o)},{$boxes:a})}}),xc=function(t,e,n,a,i){return void 0===a&&(a=.5),void 0===i&&(i=Number.NEGATIVE_INFINITY),r(this,void 0,void 0,function(){var r,s,u,l,c,h;return o(this,function(o){switch(o.label){case 0:return r=Ye(t,"boxes","nonMaxSuppressionAsync"),s=Ye(e,"scores","nonMaxSuppressionAsync"),u=vc(r,s,n,a,i),n=u.maxOutputSize,a=u.iouThreshold,i=u.scoreThreshold,[4,r.data()];case 1:return l=o.sent(),[4,s.data()];case 2:return c=o.sent(),h=po(l,c,n,a,i),r!==t&&r.dispose(),s!==e&&s.dispose(),[2,h]}})})},bc=ln({cropAndResize_:function(t,e,n,r,o,a){var i=Ye(t,"image","cropAndResize","float32"),s=Ye(e,"boxes","cropAndResize","float32"),u=Ye(n,"boxInd","cropAndResize","int32");o=o||"bilinear",a=a||0;var l=s.shape[0];return d(4===i.rank,function(){return "Error in cropAndResize: image must be rank 4,but got rank "+i.rank+"."}),d(2===s.rank&&4===s.shape[1],function(){return "Error in cropAndResize: boxes must be have size ["+l+",4] but had shape "+s.shape+"."}),d(1===u.rank&&u.shape[0]===l,function(){return "Error in cropAndResize: boxInd must be have size ["+l+"] but had shape "+s.shape+"."}),d(2===r.length,function(){return "Error in cropAndResize: cropSize must be of length 2, but got length "+r.length+"."}),d(r[0]>=1&&r[1]>=1,function(){return "cropSize must be atleast [1,1], but was "+r}),d("bilinear"===o||"nearest"===o,function(){return "method must be bilinear or nearest, but was "+o}),At.runKernel(function(t,e){return t.cropAndResize(i,s,u,r,o,a)},{$image:i,$boxes:s})}}),wc=Object.freeze({resizeBilinear:mc,resizeNearestNeighbor:gc,nonMaxSuppression:yc,nonMaxSuppressionAsync:xc,cropAndResize:bc});var Cc=ln({matMul_:function(t,e,n,r,o,a){var i;void 0===n&&(n=!1),void 0===r&&(r=!1),void 0===a&&(a="linear");var s=Ye(t,"a","fused matMul"),u=Ye(e,"b","fused matMul");i=Ct(s,u),s=i[0],u=i[1];var l=n?s.shape[s.rank-2]:s.shape[s.rank-1],c=r?u.shape[u.rank-1]:u.shape[u.rank-2],h=n?s.shape[s.rank-1]:s.shape[s.rank-2],p=r?u.shape[u.rank-2]:u.shape[u.rank-1],f=s.shape.slice(0,-2),v=u.shape.slice(0,-2),m=y(f),g=y(v);d(s.rank>=2&&u.rank>=2&&s.rank===u.rank,function(){return "Error in fused matMul: inputs must have the same rank of at least 2, got ranks "+s.rank+" and "+u.rank+"."}),d(x(f,v),function(){return "Error in fused matMul: outer dimensions ("+f+") and ("+v+") of Tensors with shapes "+s.shape+" and "+u.shape+" must match."}),d(l===c,function(){return "Error in fused matMul: inner shapes ("+l+") and ("+c+") of Tensors with shapes "+s.shape+" and "+u.shape+" and transposeA="+n+" and transposeB="+r+" must match."});var b,w=s.shape.slice(0,-2).concat([h,p]),C=n?s.as3D(m,l,h):s.as3D(m,h,l),E=r?u.as3D(g,p,c):u.as3D(g,c,p);null!=o&&jr(w,(b=Ct(b=Ye(o,"bias","fused matMul"),s)[0]).shape);var R={$a:C,$b:E};return null!=o&&(R.$bias=b),At.runKernel(function(t,e){var o=t.fusedBatchMatMul(C,E,n,r,b,a);return e([C,E,o]),o},R,function(t,e){var i,s=e[0],u=e[1],l=e[2];if(null==a||"linear"===a)i=t;else{if("relu"!==a)throw new Error("Gradient for activation "+a+" has not been implemented yet.");i=t.mul(l.step());}var c={};return null!=o&&(c={$bias:function(){var t=i,e=$r(b.shape,i.shape);return e.length>0&&(t=t.sum(e)),t.reshape(b.shape)}}),n||r?!n&&r?Object.assign({$a:function(){return i.matMul(u,!1,!1)},$b:function(){return i.matMul(s,!0,!1)}},c):n&&!r?Object.assign({$a:function(){return u.matMul(i,!1,!0)},$b:function(){return s.matMul(i,!1,!1)}},c):Object.assign({$a:function(){return u.matMul(i,!0,!0)},$b:function(){return i.matMul(s,!0,!0)}},c):Object.assign({$a:function(){return i.matMul(u,!1,!0)},$b:function(){return s.matMul(i,!0,!1)}},c)}).reshape(w)}}),Ec=Object.freeze({matMul:Cc}),Rc=Object.freeze({image:wc,linalg:dc,losses:cc,spectral:Hl,fused:Ec,signal:tc,op:ln,batchNormalization2d:qs,batchNormalization3d:Hs,batchNormalization4d:$s,batchNormalization:js,batchNorm:Ks,batchNorm2d:Xs,batchNorm3d:Ys,batchNorm4d:Qs,complex:cn,real:hn,imag:pn,concat:An,concat1d:Tn,concat2d:Dn,concat3d:_n,concat4d:On,split:Fn,conv1d:eu,conv2d:nu,conv3d:ru,conv2dDerFilter:ou,depthwiseConv2d:au,separableConv2d:iu,conv2dTranspose:su,matMul:uu,dot:lu,outerProduct:cu,reverse:hu,reverse1d:pu,reverse2d:fu,reverse3d:du,reverse4d:vu,maxPool:yu,avgPool:xu,pool:bu,slice:wu,slice1d:Cu,slice2d:Eu,slice3d:Ru,slice4d:Iu,abs:rs,acos:os,acosh:as,asin:is,asinh:ss,atan:us,atanh:ls,ceil:cs,clipByValue:hs,cos:ps,cosh:fs,erf:ds,exp:vs,expm1:ms,floor:gs,log:ys,log1p:xs,logSigmoid:bs,neg:ws,reciprocal:Cs,round:Es,rsqrt:Rs,sigmoid:Is,sign:Ss,isNaN:Ns,isInf:ks,isFinite:As,sin:Ts,sinh:Ds,softplus:_s,sqrt:Os,square:Fs,step:Ms,tan:Bs,tanh:Ps,all:Nu,any:ku,argMax:Au,argMin:Tu,logSumExp:Du,max:_u,mean:Ou,min:Fu,moments:Mu,sum:Bu,prod:Pu,equal:Lu,equalStrict:Wu,greater:Uu,greaterEqual:zu,greaterEqualStrict:Vu,greaterStrict:Gu,less:qu,lessEqual:Hu,lessEqualStrict:$u,lessStrict:ju,notEqual:Ku,notEqualStrict:Xu,add:Yu,addN:Qu,addStrict:Ju,atan2:Zu,div:tl,divStrict:el,floorDiv:nl,maximum:rl,maximumStrict:ol,minimum:al,minimumStrict:il,mod:sl,modStrict:ul,mul:ll,mulStrict:cl,pow:hl,powStrict:pl,squaredDifference:fl,squaredDifferenceStrict:dl,sub:vl,subStrict:ml,elu:El,leakyRelu:Rl,prelu:Il,relu:Sl,selu:Nl,logicalAnd:gl,logicalNot:yl,logicalOr:xl,logicalXor:bl,where:wl,whereAsync:Cl,buffer:$n,print:jn,batchToSpaceND:Kn,cast:Xn,clone:Yn,cumsum:Qn,depthToSpace:Jn,expandDims:Zn,eye:tr,multinomial:er,oneHot:nr,pad:rr,pad1d:or,pad2d:ar,pad3d:ir,pad4d:sr,rand:ur,randomNormal:lr,randomUniform:cr,reshape:hr,spaceToBatchND:pr,squeeze:fr,stack:dr,tile:vr,truncatedNormal:mr,unstack:gr,setdiff1dAsync:yr,fill:Rn,linspace:In,ones:Cn,range:Sn,scalar:vn,tensor:fn,tensor1d:mn,tensor2d:gn,tensor3d:yn,tensor4d:xn,tensor5d:bn,tensor6d:wn,zeros:En,onesLike:Nn,zerosLike:kn,transpose:kl,softmax:zr,logSoftmax:Vr,localResponseNormalization:Al,norm:Tl,gather:Ol,unsortedSegmentSum:Fl,basicLSTMCell:Ml,multiRNNCell:Bl,movingAverage:Pl,stridedSlice:Ll,topk:Wl,scatterND:Ul,fft:zl,ifft:Vl,rfft:Gl,irfft:ql,sparseToDense:$l,gatherND:jl,dropout:Kl,hannWindow:Ql,hammingWindow:Jl,frame:Zl});var Ic=function(){function t(){if(this.blockSize=48,this.firstUse=!0,s.get("IS_BROWSER")){var t=function(){if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(300,150);if("undefined"!=typeof document)return document.createElement("canvas");throw new Error("Cannot create a canvas in this context")}();this.fromPixels2DContext=t.getContext("2d");}this.data=new Gr(this,At);}return t.prototype.register=function(t,e,n){if(this.firstUse&&(this.firstUse=!1,s.get("IS_NODE")&&je("\n============================\nHi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.\n============================\n")),this.data.has(t))throw new Error("Data buffer is already registered");this.data.set(t,{dtype:n});},t.prototype.write=function(t,e){if(null==e)throw new Error("MathBackendCPU.write(): values can not be null");this.data.get(t).values=e;},t.prototype.fromPixels=function(t,e){if(null==t)throw new Error("pixels passed to tf.browser.fromPixels() can not be null");var n,r;if(s.get("IS_NODE")&&null==t.getContext)throw new Error("When running in node, pixels must be an HTMLCanvasElement like the one returned by the `canvas` npm package");if(null!=t.getContext)n=t.getContext("2d").getImageData(0,0,t.width,t.height).data;else if(t instanceof ImageData||t.data instanceof Uint8Array)n=t.data;else{if(!(t instanceof HTMLImageElement||t instanceof HTMLVideoElement))throw new Error("pixels passed to tf.browser.fromPixels() must be either an HTMLVideoElement, HTMLImageElement, HTMLCanvasElement, ImageData or {data: Uint32Array, width: number, height: number}, but was "+t.constructor.name);if(null==this.fromPixels2DContext)throw new Error("Can't read pixels from HTMLImageElement outside the browser.");this.fromPixels2DContext.canvas.width=t.width,this.fromPixels2DContext.canvas.height=t.height,this.fromPixels2DContext.drawImage(t,0,0,t.width,t.height),n=this.fromPixels2DContext.getImageData(0,0,t.width,t.height).data;}if(4===e)r=new Int32Array(n);else{var o=t.width*t.height;r=new Int32Array(o*e);for(var a=0;ap&&(p=v,f=d);}u[c]=f;}return i},t.prototype.cumsum=function(t,e,n,r){if(this.assertNotComplex(t,"cumsum"),e!==t.rank-1)throw new Error("backend.cumsum in CPU expects an inner-most axis="+(t.rank-1)+" but got axis="+e);for(var o=bt(t.dtype,"int32"),a=En(t.shape,o),i=this.readSync(a.dataId),s=this.readSync(t.dataId),u=t.shape[t.rank-1],l=r?function(t,e){return t+u-e-1}:function(t,e){return t+e},c=0;ce?1:0})},t.prototype.greaterEqual=function(t,e){return this.assertNotComplex([t,e],"greaterEqual"),this.broadcastedBinaryOp(t,e,"bool",function(t,e){return t>=e?1:0})},t.prototype.logicalNot=function(t){this.assertNotComplex(t,"logicalNot");for(var e=this.readSync(t.dataId),n=new Uint8Array(e.length),r=0;r1||1===e.rank?1:e.shape[1],c=0;c=0&&e>=0?n:(n+e)%e})},t.prototype.max=function(t,e){this.assertNotComplex(t,"max"),nn("max",e,t.rank);for(var n=tn(t.shape,e),r=n[0],o=n[1],a=En(r,t.dtype),i=y(o),s=this.readSync(a.dataId),u=this.readSync(t.dataId),l=0;lh&&(h=f);}s[l]=h;}return a},t.prototype.maximum=function(t,e){return this.assertNotComplex([t,e],"maximum"),this.broadcastedBinaryOp(t,e,t.dtype,function(t,e){return Math.max(t,e)})},t.prototype.all=function(t,e){this.assertNotComplex(t,"all"),nn("all",e,t.rank);for(var n=tn(t.shape,e),r=n[0],o=n[1],a=En(r,t.dtype),i=y(o),s=this.readSync(a.dataId),u=this.readSync(t.dataId),l=0;l0?n[r]=1:n[r]=0;return ht.make(t.shape,{values:n})},t.prototype.isNaN=function(t){this.assertNotComplex(t,"x");for(var e=this.readSync(t.dataId),n=new Uint8Array(e.length),r=0;r.5?n[r]=Math.ceil(e[r]):n[r]=o%2==0?o:o+1;}return ht.make(t.shape,{values:n})},t.prototype.exp=function(t){this.assertNotComplex(t,"exp");for(var e=this.readSync(t.dataId),n=new Float32Array(e.length),r=0;r=0?o:Math.exp(o)-1;}return ht.make(t.shape,{values:e})},t.prototype.eluDer=function(t,e){this.assertNotComplex([t,e],"eluDer");for(var n=new Float32Array(e.size),r=this.readSync(e.dataId),o=this.readSync(t.dataId),a=0;a=1?o[a]:o[a]*(i+1);}return ht.make(e.shape,{values:n})},t.prototype.selu=function(t){this.assertNotComplex(t,"selu");for(var e=Pi,n=Li,r=new Float32Array(t.size),o=this.readSync(t.dataId),a=0;a=0?n*i:e*(Math.exp(i)-1);}return ht.make(t.shape,{values:r})},t.prototype.clip=function(t,e,n){this.assertNotComplex(t,"clip");for(var r=new Float32Array(t.size),o=this.readSync(t.dataId),a=0;an?n:i-e,i=r[o]0?1:e;}return ht.make(t.shape,{values:n})},t.prototype.conv2d=function(t,e,n){this.assertNotComplex([t,e],"conv2d");for(var r=n.filterHeight,o=n.filterWidth,a=n.dilationHeight,i=n.dilationWidth,s=n.padInfo.left,u=n.padInfo.top,l=$n(n.outShape,t.dtype),c=this.readSync(t.dataId),h=this.readSync(e.dataId),p=l.values,f=0;f=n.inHeight))for(var w=x*e.strides[0],C=d+b*t.strides[1],E=0;E=n.inWidth))for(var k=w+S*e.strides[1],A=C+N*n.inChannels,T=k,D=0;D=n.inDepth))for(var R=C*e.strides[0],I=g+E*t.strides[1],S=0;S=n.inHeight))for(var D=R+A*e.strides[1],_=I+T*t.strides[2],O=0;O=n.inWidth))for(var L=D+B*e.strides[2],W=_+P*n.inChannels,U=L,z=0;z=n.inHeight))for(var C=b*e.strides[0],E=v+w*t.strides[1],R=0;R=n.inWidth))for(var A=C+N*e.strides[1],T=E+k*n.inChannels,D=I,_=A,O=0;OD?D=P:"avg"===n&&(_+=P,O++);}if(isNaN(D))break}d[S+N*g+w]="avg"===n?_/O:D;}return f.toTensor()},t.prototype.maxPool=function(t,e){return this.pool(t,e,"max")},t.prototype.maxPoolPositions=function(t,e){for(var n=$n(e.outShape,"int32"),r=e.strideHeight,o=e.strideWidth,a=e.dilationHeight,i=e.dilationWidth,s=e.effectiveFilterHeight,u=e.effectiveFilterWidth,l=e.padInfo.top,c=e.padInfo.left,h=this.bufferSync(t),p=0;pC&&(C=k,E=I*u+N);}n.set(E,p,d,y,f);}}return n.toTensor()},t.prototype.maxPoolBackprop=function(t,e,n,r){this.assertNotComplex([e,n],"maxPoolBackprop");for(var o=this.maxPoolPositions(e,r),a=r.strideHeight,i=r.strideWidth,s=r.dilationHeight,u=r.dilationWidth,l=r.effectiveFilterHeight,c=r.effectiveFilterWidth,h=c-1-r.padInfo.left,p=l-1-r.padInfo.top,f=$n(e.shape,"float32"),d=this.bufferSync(o),v=this.bufferSync(t),m=0;m=r.outHeight||Math.floor(R)!==R))for(var I=0;I=r.outWidth||Math.floor(S)!==S)){var N=l*c-1-d.get(m,R,S,g)===E*c+I?1:0;if(0!==N)C+=v.get(m,R,S,g)*N;}}}f.set(C,m,y,x,g);}return f.toTensor()},t.prototype.avgPoolBackprop=function(t,e,n){this.assertNotComplex([t,e],"avgPoolBackprop");for(var r=n.strideHeight,o=n.strideWidth,a=n.filterHeight,i=n.filterWidth,s=n.dilationHeight,u=n.dilationWidth,l=n.effectiveFilterHeight,c=n.effectiveFilterWidth,h=c-1-n.padInfo.left,p=l-1-n.padInfo.top,f=$n(e.shape,"float32"),d=1/(a*i),v=this.bufferSync(t),m=0;m=n.outHeight||Math.floor(R)!==R))for(var I=0;I=n.outWidth||Math.floor(S)!==S))C+=v.get(m,R,S,g);}}f.set(C*d,m,y,x,g);}return f.toTensor()},t.prototype.cast=function(t,e){return oo(t,e,this)},t.prototype.reshape=function(t,e){return ao(t,e)},t.prototype.avgPool=function(t,e){return this.assertNotComplex(t,"avgPool"),this.pool(t,e,"avg").toFloat()},t.prototype.resizeBilinear=function(t,e,n,r){this.assertNotComplex(t,"resizeBilinear");for(var o=t.shape,a=o[0],i=o[1],s=o[2],u=o[3],l=this.readSync(t.dataId),c=new Float32Array(y([a,e,n,u])),h=[r&&e>1?i-1:i,r&&n>1?s-1:s],p=[r&&e>1?e-1:e,r&&n>1?n-1:n],f=0,d=h[0]/p[0],v=h[1]/p[1],m=0;m1?a-1:a,n&&c>1?i-1:i],f=[n&&l>1?l-1:l,n&&c>1?c-1:c],d=p[0]/f[0],v=p[1]/f[1],m=this.readSync(t.dataId),g=0,y=0;y1?i-1:i,r&&n>1?s-1:s],p=[r&&e>1?e-1:e,r&&n>1?n-1:n],f=h[0]/p[0],d=h[1]/p[1],v=0,m=0;m1?a-1:a,n&&c>1?i-1:i],d=[n&&l>1?l-1:l,n&&c>1?c-1:c],v=f[0]/d[0],m=f[1]/d[1],g=1/v,y=1/m,x=2*Math.ceil(g)+2,b=2*Math.ceil(y)+2,w=0;w=l)){var M=C+F*t.strides[1],B=F*v;if(E===Math.min(a-1,n?Math.round(B):Math.floor(B)))for(var P=0;P=c)){var W=M+L*t.strides[2],U=L*m;N===Math.min(i-1,n?Math.round(U):Math.floor(U))&&(_+=p[W+D]);}}}}h[k+D]=_;}return xn(h,e.shape,e.dtype)},t.prototype.batchNormalization=function(t,e,n,r,o,a){this.assertNotComplex([t,e,n,o,a],"batchNorm");for(var i=this.readSync(t.dataId),s=this.readSync(e.dataId),u=this.readSync(n.dataId),l=o?this.readSync(o.dataId):new Float32Array([1]),c=a?this.readSync(a.dataId):new Float32Array([0]),h=new Float32Array(i.length),p=c.length,f=l.length,d=u.length,v=s.length,m=0,g=0,y=0,x=0,b=0;b=p&&(m=0),g>=v&&(g=0),y>=f&&(y=0),x>=d&&(x=0);return xn(h,t.shape)},t.prototype.localResponseNormalization4D=function(t,e,n,r,o){this.assertNotComplex(t,"localResponseNormalization4D");var a=t.shape[3],i=a-1,s=this.readSync(t.dataId),u=t.size,l=new Float32Array(u);function c(t){for(var n=t%a,r=t-n+Math.max(0,n-e),o=t-n+Math.min(n+e,i),u=0;r<=o;r++){var l=s[r];u+=l*l;}return u}for(var h=0;h=0&&a[i]1,function(){return "blockSize should be > 1 for depthToSpace, but was: "+e});for(var r=t.shape[0],o=t.shape[1],a=t.shape[2],i=t.shape[3],s=o*e,u=a*e,l=i/(e*e),c=this.readSync(t.dataId),h=new Float32Array(r*s*u*l),p=0,f=0;f=s))for(var N=p>1?(R-C)*(u-1)/(p-1):0,k=f>1?(I-E)*(l-1)/(f-1):0,A=0;A1?C*(u-1)+A*N:.5*(C+R)*(u-1);if(T<0||T>u-1)for(var D=0;D1?E*(l-1)+D*k:.5*(E+I)*(l-1))<0||H>l-1)for(_=0;_1?E*(l-1)+D*k:.5*(E+I)*(l-1))<0||H>l-1)for(_=0;_=t.size/s)throw new Error("Invalid indices: "+f+" does not index into "+t.shape);for(var g=0;g=r/o)throw new Error("Invalid indices: "+v+" does not index into "+n);for(var x=0;x0,function(){return "scheme must not be an empty string."});var r=t.getInstance();d(null==r.managers[e],function(){return "A model store manager is already registered for scheme '"+e+"'."}),r.managers[e]=n;},t.getManager=function(t){var e=this.getInstance().managers[t];if(null==e)throw new Error("Cannot find model manager for scheme '"+t+"'");return e},t.getSchemes=function(){return Object.keys(this.getInstance().managers)},t}();function Vc(t){if(-1===t.indexOf(Uc))throw new Error("The url string provided does not contain a scheme. Supported schemes are: "+zc.getSchemes().join(","));return {scheme:t.split(Uc)[0],path:t.split(Uc)[1]}}function Gc(t,e,n){return void 0===n&&(n=!1),r(this,void 0,void 0,function(){var r,a,i,s,u,l,c,h,p;return o(this,function(o){switch(o.label){case 0:return d(t!==e,function(){return "Old path and new path are the same: '"+t+"'"}),d((r=Wc.getLoadHandlers(t)).length>0,function(){return "Copying failed because no load handler is found for source URL "+t+"."}),d(r.length<2,function(){return "Copying failed because more than one ("+r.length+") load handlers for source URL "+t+"."}),a=r[0],d((i=Wc.getSaveHandlers(e)).length>0,function(){return "Copying failed because no save handler is found for destination URL "+e+"."}),d(i.length<2,function(){return "Copying failed because more than one ("+r.length+") save handlers for destination URL "+e+"."}),s=i[0],u=Vc(t).scheme,l=Vc(t).path,c=u===Vc(t).scheme,[4,a.load()];case 1:return h=o.sent(),n&&c?[4,zc.getManager(u).removeModel(l)]:[3,3];case 2:o.sent(),o.label=3;case 3:return [4,s.save(h)];case 4:return p=o.sent(),!n||c?[3,6]:[4,zc.getManager(u).removeModel(l)];case 5:o.sent(),o.label=6;case 6:return [2,p.modelArtifactsInfo]}})})}var qc="models_store",Hc="model_info_store";function $c(){if(!s.getBool("IS_BROWSER"))throw new Error("Failed to obtain IndexedDB factory because the current environmentis not a web browser.");var t=window,e=t.indexedDB||t.mozIndexedDB||t.webkitIndexedDB||t.msIndexedDB||t.shimIndexedDB;if(null==e)throw new Error("The current browser does not appear to support IndexedDB.");return e}function jc(t){var e=t.result;e.createObjectStore(qc,{keyPath:"modelPath"}),e.createObjectStore(Hc,{keyPath:"modelPath"});}var Kc=function(){function t(t){if(this.indexedDB=$c(),null==t||!t)throw new Error("For IndexedDB, modelPath must not be null, undefined or empty.");this.modelPath=t;}return t.prototype.save=function(t){return r(this,void 0,void 0,function(){return o(this,function(e){if(t.modelTopology instanceof ArrayBuffer)throw new Error("BrowserLocalStorage.save() does not support saving model topology in binary formats yet.");return [2,this.databaseAction(this.modelPath,t)]})})},t.prototype.load=function(){return r(this,void 0,void 0,function(){return o(this,function(t){return [2,this.databaseAction(this.modelPath)]})})},t.prototype.databaseAction=function(t,e){var n=this;return new Promise(function(t,r){var o=n.indexedDB.open("tensorflowjs",1);o.onupgradeneeded=function(){return jc(o)},o.onsuccess=function(){var a=o.result;if(null==e){var i=a.transaction(qc,"readonly"),s=i.objectStore(qc).get(n.modelPath);s.onsuccess=function(){if(null==s.result)return a.close(),r(new Error("Cannot find model with path '"+n.modelPath+"' in IndexedDB."));t(s.result.modelArtifacts);},s.onerror=function(t){return a.close(),r(s.error)},i.oncomplete=function(){return a.close()};}else{var u,l=Lc(e),c=a.transaction(Hc,"readwrite"),h=c.objectStore(Hc),p=h.put({modelPath:n.modelPath,modelArtifactsInfo:l});p.onsuccess=function(){var o=(u=a.transaction(qc,"readwrite")).objectStore(qc).put({modelPath:n.modelPath,modelArtifacts:e,modelArtifactsInfo:l});o.onsuccess=function(){return t({modelArtifactsInfo:l})},o.onerror=function(t){var e=(h=c.objectStore(Hc)).delete(n.modelPath);e.onsuccess=function(){return a.close(),r(o.error)},e.onerror=function(t){return a.close(),r(o.error)};};},p.onerror=function(t){return a.close(),r(p.error)},c.oncomplete=function(){null==u?a.close():u.oncomplete=function(){return a.close()};};}},o.onerror=function(t){return r(o.error)};})},t.URL_SCHEME="indexeddb://",t}(),Xc=function(t){return s.getBool("IS_BROWSER")&&!Array.isArray(t)&&t.startsWith(Kc.URL_SCHEME)?(e=t.slice(Kc.URL_SCHEME.length),new Kc(e)):null;var e;};Wc.registerSaveRouter(Xc),Wc.registerLoadRouter(Xc);var Yc=function(){function t(){this.indexedDB=$c();}return t.prototype.listModels=function(){return r(this,void 0,void 0,function(){var t=this;return o(this,function(e){return [2,new Promise(function(e,n){var r=t.indexedDB.open("tensorflowjs",1);r.onupgradeneeded=function(){return jc(r)},r.onsuccess=function(){var t=r.result,o=t.transaction(Hc,"readonly"),a=o.objectStore(Hc).getAll();a.onsuccess=function(){for(var t={},n=0,r=a.result;n0,function(){return "promises must be a none empty array"});}(t),function(t,e){d(t>=0&&t<=1,function(){return "Progress fraction must be in range [0, 1], but got startFraction "+t}),d(e>=0&&e<=1,function(){return "Progress fraction must be in range [0, 1], but got endFraction "+e}),d(e>=t,function(){return "startFraction must be no more than endFraction, but got startFraction "+t+" and endFraction "+e});}(n=null==n?0:n,r=null==r?1:r);var o=0;return Promise.all(t.map(function(a){return a.then(function(a){var i=n+ ++o/t.length*(r-n);return e(i),a}),a}))}function mh(t,e){return r(this,void 0,void 0,function(){var n,r,a,i,s,u,l,c,h;return o(this,function(o){switch(o.label){case 0:return null==e&&(e={}),n=null==e.fetchFunc?Y:e.fetchFunc,r=t.map(function(t){return n(t,e.requestInit)}),a=0,i=.5,null!=e.onProgress?[3,2]:[4,Promise.all(r)];case 1:return s=o.sent(),[3,4];case 2:return [4,vh(r,e.onProgress,a,i)];case 3:s=o.sent(),o.label=4;case 4:return u=s.map(function(t){return t.arrayBuffer()}),l=.5,c=1,null!=e.onProgress?[3,6]:[4,Promise.all(u)];case 5:return h=o.sent(),[3,8];case 6:return [4,vh(u,e.onProgress,l,c)];case 7:h=o.sent(),o.label=8;case 8:return [2,h]}})})}function gh(t){var e=this;return function(n,a,i){return void 0===a&&(a=""),r(e,void 0,void 0,function(){var e,r,s,u,l,c,h,p,f,d;return o(this,function(o){switch(o.label){case 0:if(e=n.map(function(){return !1}),r={},s=null!=i?i.map(function(){return !1}):[],u=[],n.forEach(function(t,n){var o=0;t.weights.forEach(function(t){var a="quantization"in t?t.quantization.dtype:t.dtype,l=Tc[a]*y(t.shape),c=function(){e[n]=!0,null==r[n]&&(r[n]=[]),r[n].push({manifestEntry:t,groupOffset:o,sizeBytes:l});};null!=i?i.forEach(function(e,n){e===t.name&&(c(),s[n]=!0);}):c(),u.push(t.name),o+=l;});}),!s.every(function(t){return t}))throw l=i.filter(function(t,e){return !s[e]}),new Error("Could not find weights in manifest with names: "+l.join(", ")+". \nManifest JSON has weights with names: "+u.join(", ")+".");return c=e.reduce(function(t,e,n){return e&&t.push(n),t},[]),h=[],c.forEach(function(t){n[t].paths.forEach(function(t){var e=a+(a.endsWith("/")?"":"/")+t;h.push(e);});}),[4,t(h)];case 1:return p=o.sent(),f={},d=0,c.forEach(function(t){for(var e=n[t].paths.length,o=0,a=0;a0,function(){return "URL path for http must not be null, undefined or empty."}),Array.isArray(t)&&d(2===t.length,function(){return "URL paths for http must have a length of 2, (actual length is "+t.length+")."}),this.path=t,null!=e.requestInit&&null!=e.requestInit.body)throw new Error("requestInit is expected to have no pre-existing body, but has one.");this.requestInit=e.requestInit||{};}return t.prototype.save=function(t){return r(this,void 0,void 0,function(){var e,n,r,a;return o(this,function(o){switch(o.label){case 0:if(t.modelTopology instanceof ArrayBuffer)throw new Error("BrowserHTTPRequest.save() does not support saving model topology in binary formats yet.");return (e=Object.assign({method:this.DEFAULT_METHOD},this.requestInit)).body=new FormData,n=[{paths:["./model.weights.bin"],weights:t.weightSpecs}],r={modelTopology:t.modelTopology,format:t.format,generatedBy:t.generatedBy,convertedBy:t.convertedBy,weightsManifest:n},e.body.append("model.json",new Blob([JSON.stringify(r)],{type:"application/json"}),"model.json"),null!=t.weightData&&e.body.append("model.weights.bin",new Blob([t.weightData],{type:"application/octet-stream"}),"model.weights.bin"),[4,this.fetch(this.path,e)];case 1:if((a=o.sent()).ok)return [2,{modelArtifactsInfo:Lc(t),responses:[a]}];throw new Error("BrowserHTTPRequest.save() failed due to HTTP response status "+a.status+".")}})})},t.prototype.load=function(){return r(this,void 0,void 0,function(){var t,e,n,r,a,i,s,u;return o(this,function(o){switch(o.label){case 0:return [4,this.fetch(this.path,this.requestInit)];case 1:if(!(t=o.sent()).ok)throw new Error("Request to "+this.path+" failed with status code "+t.status+". Please verify this URL points to the model JSON of the model to load.");o.label=2;case 2:return o.trys.push([2,4,,5]),[4,t.json()];case 3:return e=o.sent(),[3,5];case 4:throw o.sent(),n="Failed to parse model JSON of response from "+this.path+".",this.path.endsWith(".pb")?n+=" Your path contains a .pb file extension. Support for .pb models have been removed in TensorFlow.js 1.0 in favor of .json models. You can re-convert your Python TensorFlow model using the TensorFlow.js 1.0 conversion scripts or you can convert your.pb models with the 'pb2json'NPM script in the tensorflow/tfjs-converter repository.":n+=" Please make sure the server is serving valid JSON for this request.",new Error(n);case 5:if(r=e.modelTopology,a=e.weightsManifest,null==r&&null==a)throw new Error("The JSON from HTTP path "+this.path+" contains neither model topology or manifest for weights.");return null==a?[3,7]:[4,this.loadWeights(a)];case 6:u=o.sent(),i=u[0],s=u[1],o.label=7;case 7:return [2,{modelTopology:r,weightSpecs:i,weightData:s}]}})})},t.prototype.loadWeights=function(t){return r(this,void 0,void 0,function(){var e,n,r,a,i,s,u,l,c,h,p;return o(this,function(o){switch(o.label){case 0:for(e=Array.isArray(this.path)?this.path[1]:this.path,n=function(t){var e=t.lastIndexOf("/"),n=t.lastIndexOf("?"),r=t.substring(0,e),o=n>e?t.substring(n):"";return [r+"/",o]}(e),r=n[0],a=n[1],i=this.weightPathPrefix||r,s=[],u=0,l=t;u0&&(t=n({weightSpecs:this.weightSpecs},t)),null!=this.weightData&&this.weightData.byteLength>0&&(t=n({weightData:this.weightData},t)),null!=this.trainingConfig&&(t=n({trainingConfig:this.trainingConfig},t)),[2,t]})})},t}(),Eh=function(){function t(t){this.saveHandler=t;}return t.prototype.save=function(t){return r(this,void 0,void 0,function(){return o(this,function(e){return [2,this.saveHandler(t)]})})},t}();var Rh=Object.freeze({browserFiles:function(t){return new dh(t)},browserHTTPRequest:function(t,e){return wh(t,e)},concatenateArrayBuffers:Bc,decodeWeights:_c,encodeWeights:function(t,e){return r(this,void 0,void 0,function(){var n,a,i,u,l,c=this;return o(this,function(h){switch(h.label){case 0:for(n=[],a=[],i=Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t),u=function(u){var l=i[u],h=Array.isArray(t)?t[u].tensor:t[l];if("float32"!==h.dtype&&"int32"!==h.dtype&&"bool"!==h.dtype&&"string"!==h.dtype)throw new Error("Unsupported dtype in weight '"+l+"': "+h.dtype);var p={name:l,shape:h.shape,dtype:h.dtype};if("string"===h.dtype){var f=new Promise(function(t){return r(c,void 0,void 0,function(){var e,n,r;return o(this,function(o){switch(o.label){case 0:return e=p,[4,h.data()];case 1:return n=o.sent(),r=s.platform.encodeUTF8(n.join(Dc)),e.byteLength=r.length,e.delimiter=Dc,t(r),[2]}})})});a.push(f);}else a.push(h.data());null!=e&&(p.group=e),n.push(p);},l=0;l0&&Number.isInteger(n),function(){return "If provided, numClasses must be a positive integer, but got "+n}),d(1===r.rank,function(){return "Expected the rank of labels to be 1, but got "+r.rank}),d(1===o.rank,function(){return "Expected the rank of predictions to be 1, but got "+o.rank}),d(r.shape[0]===o.shape[0],function(){return "Mismatch in the number of examples: "+r.shape[0]+" vs. "+o.shape[0]+". Labels and predictions should have the same number of elements."}),d(n>0&&Number.isInteger(n),function(){return "numClasses is required to be a positive integer, but got "+n});var a=nr(r.asType("int32"),n),i=nr(o.asType("int32"),n);return a.transpose().matMul(i).asType("int32")}}),Sh=Object.freeze({confusionMatrix:Ih});var Nh=ln({fromPixels_:function(t,e){if(void 0===e&&(e=3),e>4)throw new Error("Cannot construct Tensor with more than 4 channels from pixels.");return At.fromPixels(t,e)}}),kh=Object.freeze({toPixels:function(t,e){return r(this,void 0,void 0,function(){var n,r,a,i,s,u,l,c,h,p,f,d,v,m,g,y,x,b,w,C,E,R,I;return o(this,function(o){switch(o.label){case 0:if(n=Ye(t,"img","toPixels"),t instanceof ht||(n=n.toInt()),2!==n.rank&&3!==n.rank)throw new Error("toPixels only supports rank 2 or 3 tensors, got rank "+n.rank+".");if(r=n.shape.slice(0,2),a=r[0],i=r[1],(s=2===n.rank?1:n.shape[2])>4||2===s)throw new Error("toPixels only supports depth of size 1, 3 or 4 but got "+s);return [4,n.data()];case 1:return u=o.sent(),l=n.min(),c=n.max(),[4,Promise.all([l.data(),c.data()])];case 2:if(h=o.sent(),p=h[0],f=h[1],d=p[0],v=f[0],l.dispose(),c.dispose(),"float32"===n.dtype){if(d<0||v>1)throw new Error("Tensor values for a float32 Tensor must be in the range [0 - 1] but got range ["+d+" - "+v+"].")}else{if("int32"!==n.dtype)throw new Error("Unsupported type for toPixels: "+n.dtype+". Please use float32 or int32 tensors.");if(d<0||v>255)throw new Error("Tensor values for a int32 Tensor must be in the range [0 - 255] but got range ["+d+" - "+v+"].")}for(m="float32"===n.dtype?255:1,g=new Uint8ClampedArray(i*a*4),y=0;y0,function(){return "Class being registered has an empty-string as its className, which is disallowed."}),Th.register(t);}var _h=Object.freeze({Serializable:Ah,SerializationMap:Th,registerClass:Dh}),Oh=.001,Fh=.1;function Mh(){return 32===At.backend.floatPrecision()?Oh:Fh}function Bh(t,e,n){var r=!0;if((F(t)||F(e))&&(r=!1),F(t)&&F(e)&&(r=!0),r){var o=t.constructor.name,a=e.constructor.name;if(o!==a)throw new Error("Arrays are of different type. Actual: "+o+". Expected: "+a)}if(Array.isArray(t)&&Array.isArray(e)){var i=Ke(t),s=Ke(e);if(!x(i,s))throw new Error("Arrays have different shapes. Actual: ["+i+"]. Expected: ["+s+"]")}var u=F(t)?t:g(t),l=F(e)?e:g(e);if(u.length!==l.length)throw new Error("Arrays have different lengths actual: "+u.length+" vs expected: "+l.length+".\nActual: "+u+".\nExpected: "+l+".");for(var c=0;cn)}var Lh=Object.freeze({TEST_EPSILON_FLOAT16:Fh,expectArraysClose:function(t,e,n){return null==n&&(n=Mh()),Bh(t,e,function(t,e){return Ph(t,e,n)})},testEpsilon:Mh,expectPromiseToFail:function(t,e){t().then(function(){return e.fail()},function(){return e()});},expectArraysEqual:function(t,e){var n="string"==typeof e||"number"==typeof e||"boolean"==typeof e?[e]:e;return P(t)||P(t[0])||P(e)||P(e[0])?Bh(t,n,function(t,e){return t==e}):Bh(t,e,function(t,e){return Ph(t,e,0)})},expectNumbersClose:function(t,e,n){if(null==n&&(n=Mh()),!Ph(t,e,n))throw new Error("Numbers differ: actual === "+t+", expected === "+e)},expectValuesInRange:function(t,e,n){for(var r=0;rn)throw new Error("Value out of range:"+t[r]+" low: "+e+", high: "+n)},expectArrayBuffersEqual:function(t,e){expect(new Float32Array(t)).toEqual(new Float32Array(e));}}),Wh="1.2.2",Uh=Object.freeze({gpgpu_util:ti,webgl_util:Se,MathBackendWebGL:ns,setWebGLContext:Ot,GPGPUContext:ei}),zh=function(t){function n(){return null!==t&&t.apply(this,arguments)||this}return e(n,t),n.prototype.minimize=function(t,e,n){void 0===e&&(e=!1);var r=this.computeGradients(t,n),o=r.value,a=r.grads;if(null!=n){var i=n.map(function(t){return {name:t.name,tensor:a[t.name]}});this.applyGradients(i);}else this.applyGradients(a);return Me(a),e?o:(o.dispose(),null)},Object.defineProperty(n.prototype,"iterations",{get:function(){return null==this.iterations_&&(this.iterations_=0),this.iterations_},enumerable:!0,configurable:!0}),n.prototype.incrementIterations=function(){this.iterations_=this.iterations+1;},n.prototype.computeGradients=function(t,e){return Lr(t,e)},n.prototype.dispose=function(){null!=this.iterations_&&Me(this.iterations_);},n.prototype.saveIterations=function(){return r(this,void 0,void 0,function(){return o(this,function(t){return null==this.iterations_&&(this.iterations_=0),[2,{name:"iter",tensor:vn(this.iterations_,"int32")}]})})},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){return o(this,function(t){throw new Error("getWeights() is not implemented for this optimizer yet.")})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){return o(this,function(t){throw new Error("setWeights() is not implemented for this optimizer class "+this.getClassName())})})},n.prototype.extractIterations=function(t){return r(this,void 0,void 0,function(){var e;return o(this,function(n){switch(n.label){case 0:return e=this,[4,t[0].tensor.data()];case 1:return e.iterations_=n.sent()[0],[2,t.slice(1)]}})})},n}(Ah);Object.defineProperty(zh,Symbol.hasInstance,{value:function(t){return null!=t.minimize&&null!=t.computeGradients&&null!=t.applyGradients}});var Vh=function(t){function n(e,n,r){void 0===r&&(r=null);var o=t.call(this)||this;return o.learningRate=e,o.rho=n,o.epsilon=r,o.accumulatedGrads=[],o.accumulatedUpdates=[],null==r&&(o.epsilon=At.backend.epsilon()),o}return e(n,t),n.prototype.applyGradients=function(t){var e=this;(Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t)).forEach(function(n,r){var o=At.registeredVariables[n];null==e.accumulatedGrads[r]&&(e.accumulatedGrads[r]={originalName:n+"/accum_grad",variable:Fe(function(){return kn(o).variable(!1)})}),null==e.accumulatedUpdates[r]&&(e.accumulatedUpdates[r]={originalName:n+"/accum_var",variable:Fe(function(){return kn(o).variable(!1)})});var a=Array.isArray(t)?t[r].tensor:t[n];if(null!=a){var i=e.accumulatedGrads[r].variable,s=e.accumulatedUpdates[r].variable;Fe(function(){var t=i.mul(e.rho).add(a.square().mul(1-e.rho)),n=s.add(e.epsilon).sqrt().div(i.add(e.epsilon).sqrt()).mul(a),r=s.mul(e.rho).add(n.square().mul(1-e.rho));i.assign(t),s.assign(r);var u=n.mul(-e.learningRate).add(o);o.assign(u);});}}),this.incrementIterations();},n.prototype.dispose=function(){null!=this.accumulatedUpdates&&(Me(this.accumulatedGrads.map(function(t){return t.variable})),Me(this.accumulatedUpdates.map(function(t){return t.variable})));},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){var t;return o(this,function(e){switch(e.label){case 0:return t=this.accumulatedGrads.concat(this.accumulatedUpdates),[4,this.saveIterations()];case 1:return [2,[e.sent()].concat(t.map(function(t){return {name:t.originalName,tensor:t.variable}}))]}})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){var e;return o(this,function(n){switch(n.label){case 0:return [4,this.extractIterations(t)];case 1:return t=n.sent(),e=t.length/2,this.accumulatedGrads=t.slice(0,e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),this.accumulatedUpdates=t.slice(e,2*e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),[2]}})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate,rho:this.rho,epsilon:this.epsilon}},n.fromConfig=function(t,e){return new t(e.learningRate,e.rho,e.epsilon)},n.className="AdadeltaOptimizer",n}(zh);Dh(Vh);var Gh=function(t){function n(e,n){void 0===n&&(n=.1);var r=t.call(this)||this;return r.learningRate=e,r.initialAccumulatorValue=n,r.accumulatedGrads=[],r}return e(n,t),n.prototype.applyGradients=function(t){var e=this;(Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t)).forEach(function(n,r){var o=At.registeredVariables[n];if(null==e.accumulatedGrads[r]){e.accumulatedGrads[r]={originalName:n+"/accumulator",variable:Fe(function(){return Rn(o.shape,e.initialAccumulatorValue).variable(!1)})};}var a=Array.isArray(t)?t[r].tensor:t[n];if(null!=a){var i=e.accumulatedGrads[r].variable;Fe(function(){var t=i.add(a.square());i.assign(t);var n=a.div(t.add(At.backend.epsilon()).sqrt()).mul(-e.learningRate).add(o);o.assign(n);});}}),this.incrementIterations();},n.prototype.dispose=function(){null!=this.accumulatedGrads&&Me(this.accumulatedGrads.map(function(t){return t.variable}));},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){return o(this,function(t){switch(t.label){case 0:return [4,this.saveIterations()];case 1:return [2,[t.sent()].concat(this.accumulatedGrads.map(function(t){return {name:t.originalName,tensor:t.variable}}))]}})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){return o(this,function(e){switch(e.label){case 0:return [4,this.extractIterations(t)];case 1:return t=e.sent(),this.accumulatedGrads=t.map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),[2]}})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate,initialAccumulatorValue:this.initialAccumulatorValue}},n.fromConfig=function(t,e){return new t(e.learningRate,e.initialAccumulatorValue)},n.className="Adagrad",n}(zh);Dh(Gh);var qh=function(t){function n(e,n,r,o){void 0===o&&(o=null);var a=t.call(this)||this;return a.learningRate=e,a.beta1=n,a.beta2=r,a.epsilon=o,a.accumulatedFirstMoment=[],a.accumulatedSecondMoment=[],Fe(function(){a.accBeta1=vn(n).variable(),a.accBeta2=vn(r).variable();}),null==o&&(a.epsilon=At.backend.epsilon()),a}return e(n,t),n.prototype.applyGradients=function(t){var e=this,n=Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t);Fe(function(){var r=vl(1,e.accBeta1),o=vl(1,e.accBeta2);n.forEach(function(n,a){var i=At.registeredVariables[n];null==e.accumulatedFirstMoment[a]&&(e.accumulatedFirstMoment[a]={originalName:n+"/m",variable:Fe(function(){return kn(i).variable(!1)})}),null==e.accumulatedSecondMoment[a]&&(e.accumulatedSecondMoment[a]={originalName:n+"/v",variable:Fe(function(){return kn(i).variable(!1)})});var s=Array.isArray(t)?t[a].tensor:t[n];if(null!=s){var u=e.accumulatedFirstMoment[a].variable,l=e.accumulatedSecondMoment[a].variable,c=u.mul(e.beta1).add(s.mul(1-e.beta1)),h=l.mul(e.beta2).add(s.square().mul(1-e.beta2)),p=c.div(r),f=h.div(o);u.assign(c),l.assign(h);var d=p.div(f.sqrt().add(e.epsilon)).mul(-e.learningRate).add(i);i.assign(d);}}),e.accBeta1.assign(e.accBeta1.mul(e.beta1)),e.accBeta2.assign(e.accBeta2.mul(e.beta2));}),this.incrementIterations();},n.prototype.dispose=function(){this.accBeta1.dispose(),this.accBeta2.dispose(),null!=this.accumulatedFirstMoment&&Me(this.accumulatedFirstMoment.map(function(t){return t.variable})),null!=this.accumulatedSecondMoment&&Me(this.accumulatedSecondMoment.map(function(t){return t.variable}));},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){var t;return o(this,function(e){switch(e.label){case 0:return t=this.accumulatedFirstMoment.concat(this.accumulatedSecondMoment),[4,this.saveIterations()];case 1:return [2,[e.sent()].concat(t.map(function(t){return {name:t.originalName,tensor:t.variable}}))]}})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){var e,n=this;return o(this,function(r){switch(r.label){case 0:return [4,this.extractIterations(t)];case 1:return t=r.sent(),Fe(function(){n.accBeta1.assign(hl(n.beta1,n.iterations_+1)),n.accBeta2.assign(hl(n.beta2,n.iterations_+1));}),e=t.length/2,this.accumulatedFirstMoment=t.slice(0,e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),this.accumulatedSecondMoment=t.slice(e,2*e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),[2]}})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate,beta1:this.beta1,beta2:this.beta2,epsilon:this.epsilon}},n.fromConfig=function(t,e){return new t(e.learningRate,e.beta1,e.beta2,e.epsilon)},n.className="Adam",n}(zh);Dh(qh);var Hh=function(t){function n(e,n,r,o,a){void 0===o&&(o=null),void 0===a&&(a=0);var i=t.call(this)||this;return i.learningRate=e,i.beta1=n,i.beta2=r,i.epsilon=o,i.decay=a,i.accumulatedFirstMoment=[],i.accumulatedWeightedInfNorm=[],Fe(function(){i.iteration=vn(0).variable(),i.accBeta1=vn(n).variable();}),null==o&&(i.epsilon=At.backend.epsilon()),i}return e(n,t),n.prototype.applyGradients=function(t){var e=this,n=Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t);Fe(function(){var r=vl(1,e.accBeta1),o=tl(-e.learningRate,e.iteration.mul(e.decay).add(1));n.forEach(function(n,a){var i=At.registeredVariables[n];null==e.accumulatedFirstMoment[a]&&(e.accumulatedFirstMoment[a]={originalName:n+"/m",variable:kn(i).variable(!1)}),null==e.accumulatedWeightedInfNorm[a]&&(e.accumulatedWeightedInfNorm[a]={originalName:n+"/v",variable:kn(i).variable(!1)});var s=Array.isArray(t)?t[a].tensor:t[n];if(null!=s){var u=e.accumulatedFirstMoment[a].variable,l=e.accumulatedWeightedInfNorm[a].variable,c=u.mul(e.beta1).add(s.mul(1-e.beta1)),h=l.mul(e.beta2),p=s.abs(),f=h.maximum(p);u.assign(c),l.assign(f);var d=o.div(r).mul(c.div(f.add(e.epsilon))).add(i);i.assign(d);}}),e.iteration.assign(e.iteration.add(1)),e.accBeta1.assign(e.accBeta1.mul(e.beta1));}),this.incrementIterations();},n.prototype.dispose=function(){this.accBeta1.dispose(),this.iteration.dispose(),null!=this.accumulatedFirstMoment&&Me(this.accumulatedFirstMoment.map(function(t){return t.variable})),null!=this.accumulatedWeightedInfNorm&&Me(this.accumulatedWeightedInfNorm.map(function(t){return t.variable}));},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){return o(this,function(t){throw new Error("getWeights() is not implemented for Adamax yet.")})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){return o(this,function(t){throw new Error("setWeights() is not implemented for Adamax yet.")})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate,beta1:this.beta1,beta2:this.beta2,epsilon:this.epsilon,decay:this.decay}},n.fromConfig=function(t,e){return new t(e.learningRate,e.beta1,e.beta2,e.epsilon,e.decay)},n.className="Adamax",n}(zh);Dh(Hh);var $h=function(t){function n(e){var n=t.call(this)||this;return n.learningRate=e,n.setLearningRate(e),n}return e(n,t),n.prototype.applyGradients=function(t){var e=this;(Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t)).forEach(function(n,r){var o=Array.isArray(t)?t[r].tensor:t[n];if(null!=o){var a=At.registeredVariables[n];Fe(function(){var t=e.c.mul(o).add(a);a.assign(t);});}}),this.incrementIterations();},n.prototype.setLearningRate=function(t){this.learningRate=t,null!=this.c&&this.c.dispose(),this.c=Be(vn(-t));},n.prototype.dispose=function(){this.c.dispose();},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){return o(this,function(t){switch(t.label){case 0:return [4,this.saveIterations()];case 1:return [2,[t.sent()]]}})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){return o(this,function(e){switch(e.label){case 0:return [4,this.extractIterations(t)];case 1:if(0!==(t=e.sent()).length)throw new Error("SGD optimizer does not have settable weights.");return [2]}})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate}},n.fromConfig=function(t,e){return new t(e.learningRate)},n.className="SGD",n}(zh);Dh($h);var jh=function(t){function n(e,n,r){void 0===r&&(r=!1);var o=t.call(this,e)||this;return o.learningRate=e,o.momentum=n,o.useNesterov=r,o.accumulations=[],o.m=vn(o.momentum),o}return e(n,t),n.prototype.applyGradients=function(t){var e=this;(Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t)).forEach(function(n,r){var o=At.registeredVariables[n];if(null==e.accumulations[r]){e.accumulations[r]={originalName:n+"/momentum",variable:Fe(function(){return kn(o).variable(!1)})};}var a=e.accumulations[r].variable,i=Array.isArray(t)?t[r].tensor:t[n];null!=i&&Fe(function(){var t,n=e.m.mul(a).add(i);t=e.useNesterov?e.c.mul(i.add(n.mul(e.m))).add(o):e.c.mul(n).add(o),a.assign(n),o.assign(t);});}),this.incrementIterations();},n.prototype.dispose=function(){this.m.dispose(),null!=this.accumulations&&Me(this.accumulations.map(function(t){return t.variable}));},n.prototype.setMomentum=function(t){this.momentum=t;},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){return o(this,function(t){switch(t.label){case 0:return [4,this.saveIterations()];case 1:return [2,[t.sent()].concat(this.accumulations.map(function(t){return {name:t.originalName,tensor:t.variable}}))]}})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){return o(this,function(e){switch(e.label){case 0:return [4,this.extractIterations(t)];case 1:return t=e.sent(),this.accumulations=t.map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),[2]}})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate,momentum:this.momentum,useNesterov:this.useNesterov}},n.fromConfig=function(t,e){return new t(e.learningRate,e.momentum,e.useNesterov)},n.className="MomentumOptimizer",n}($h);Dh(jh);var Kh=function(t){function n(e,n,r,o,a){void 0===n&&(n=.9),void 0===r&&(r=0),void 0===o&&(o=null),void 0===a&&(a=!1);var i=t.call(this)||this;return i.learningRate=e,i.decay=n,i.momentum=r,i.epsilon=o,i.accumulatedMeanSquares=[],i.accumulatedMoments=[],i.accumulatedMeanGrads=[],i.centered=a,null==o&&(i.epsilon=At.backend.epsilon()),i}return e(n,t),n.prototype.applyGradients=function(t){var e=this;(Array.isArray(t)?t.map(function(t){return t.name}):Object.keys(t)).forEach(function(n,r){var o=At.registeredVariables[n];null==e.accumulatedMeanSquares[r]&&(e.accumulatedMeanSquares[r]={originalName:n+"/rms",variable:Fe(function(){return kn(o).variable(!1)})}),null==e.accumulatedMoments[r]&&(e.accumulatedMoments[r]={originalName:n+"/momentum",variable:Fe(function(){return kn(o).variable(!1)})}),null==e.accumulatedMeanGrads[r]&&e.centered&&(e.accumulatedMeanGrads[r]={originalName:n+"/mg",variable:Fe(function(){return kn(o).variable(!1)})});var a=Array.isArray(t)?t[r].tensor:t[n];if(null!=a){var i=e.accumulatedMeanSquares[r].variable,s=e.accumulatedMoments[r].variable;Fe(function(){var t=i.mul(e.decay).add(a.square().mul(1-e.decay));if(e.centered){var n=e.accumulatedMeanGrads[r].variable,u=n.mul(e.decay).add(a.mul(1-e.decay)),l=s.mul(e.momentum).add(a.mul(e.learningRate).div(t.sub(u.square().add(e.epsilon)).sqrt()));i.assign(t),n.assign(u),s.assign(l);var c=o.sub(l);o.assign(c);}else{var h=i.mul(e.decay).add(a.square().mul(1-e.decay));l=s.mul(e.momentum).add(a.mul(e.learningRate).div(h.add(e.epsilon).sqrt()));i.assign(h),s.assign(l);c=o.sub(l);o.assign(c);}});}}),this.incrementIterations();},n.prototype.dispose=function(){null!=this.accumulatedMeanSquares&&Me(this.accumulatedMeanSquares.map(function(t){return t.variable})),null!=this.accumulatedMeanGrads&&this.centered&&Me(this.accumulatedMeanGrads.map(function(t){return t.variable})),null!=this.accumulatedMoments&&Me(this.accumulatedMoments.map(function(t){return t.variable}));},n.prototype.getWeights=function(){return r(this,void 0,void 0,function(){var t;return o(this,function(e){switch(e.label){case 0:return t=this.accumulatedMeanSquares.concat(this.accumulatedMoments),this.centered&&t.push.apply(t,this.accumulatedMeanGrads),[4,this.saveIterations()];case 1:return [2,[e.sent()].concat(t.map(function(t){return {name:t.originalName,tensor:t.variable}}))]}})})},n.prototype.setWeights=function(t){return r(this,void 0,void 0,function(){var e;return o(this,function(n){switch(n.label){case 0:return [4,this.extractIterations(t)];case 1:return t=n.sent(),e=this.centered?t.length/3:t.length/2,this.accumulatedMeanSquares=t.slice(0,e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),this.accumulatedMoments=t.slice(e,2*e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}}),this.centered&&(this.accumulatedMeanGrads=t.slice(2*e,3*e).map(function(t){return {originalName:t.name,variable:t.tensor.variable(!1)}})),[2]}})})},n.prototype.getConfig=function(){return {learningRate:this.learningRate,decay:this.decay,momentum:this.momentum,epsilon:this.epsilon,centered:this.centered}},n.fromConfig=function(t,e){return new t(e.learningRate,e.decay,e.momentum,e.epsilon,e.centered)},n.className="RMSProp",n}(zh);Dh(Kh);var Xh=function(){function t(){}return t.sgd=function(t){return new $h(t)},t.momentum=function(t,e,n){return void 0===n&&(n=!1),new jh(t,e,n)},t.rmsprop=function(t,e,n,r,o){return void 0===e&&(e=.9),void 0===n&&(n=0),void 0===r&&(r=null),void 0===o&&(o=!1),new Kh(t,e,n,r,o)},t.adam=function(t,e,n,r){return void 0===t&&(t=.001),void 0===e&&(e=.9),void 0===n&&(n=.999),void 0===r&&(r=null),new qh(t,e,n,r)},t.adadelta=function(t,e,n){return void 0===t&&(t=.001),void 0===e&&(e=.95),void 0===n&&(n=null),new Vh(t,e,n)},t.adamax=function(t,e,n,r,o){return void 0===t&&(t=.002),void 0===e&&(e=.9),void 0===n&&(n=.999),void 0===r&&(r=null),void 0===o&&(o=0),new Hh(t,e,n,r,o)},t.adagrad=function(t,e){return void 0===e&&(e=.1),new Gh(t,e)},t}(),Yh={sgd:Xh.sgd,momentum:Xh.momentum,adadelta:Xh.adadelta,adagrad:Xh.adagrad,rmsprop:Xh.rmsprop,adamax:Xh.adamax,adam:Xh.adam},Qh="undefined"!=typeof requestAnimationFrame?requestAnimationFrame:"undefined"!=typeof setImmediate?setImmediate:function(t){return t()};function Jh(){return new Promise(function(t){return Qh(function(){return t()})})}lt=Rc; var tfCore_esm = /*#__PURE__*/Object.freeze({ AdadeltaOptimizer: Vh, AdagradOptimizer: Gh, AdamOptimizer: qh, AdamaxOptimizer: Hh, DataStorage: Gr, get ENV () { return s; }, Environment: a, KernelBackend: qr, MomentumOptimizer: jh, Optimizer: zh, RMSPropOptimizer: Kh, get Rank () { return ft; }, get Reduction () { return Yl; }, SGDOptimizer: $h, Tensor: ht, TensorBuffer: st, Variable: pt, abs: rs, acos: os, acosh: as, add: Yu, addN: Qu, addStrict: Ju, all: Nu, any: ku, argMax: Au, argMin: Tu, asin: is, asinh: ss, atan: us, atan2: Zu, atanh: ls, avgPool: xu, backend: He, backend_util: so, basicLSTMCell: Ml, batchNorm: Ks, batchNorm2d: Xs, batchNorm3d: Ys, batchNorm4d: Qs, batchNormalization: js, batchNormalization2d: qs, batchNormalization3d: Hs, batchNormalization4d: $s, batchToSpaceND: Kn, browser: kh, buffer: $n, cast: Xn, ceil: cs, clipByValue: hs, clone: Yn, complex: cn, concat: An, concat1d: Tn, concat2d: Dn, concat3d: _n, concat4d: On, conv1d: eu, conv2d: nu, conv2dDerFilter: ou, conv2dTranspose: su, conv3d: ru, cos: ps, cosh: fs, cumsum: Qn, customGrad: Wr, deprecationWarn: Te, depthToSpace: Jn, depthwiseConv2d: au, disableDeprecationWarnings: Ae, dispose: Me, disposeVariables: De, div: tl, divStrict: el, dot: lu, dropout: Kl, elu: El, enableDebugMode: ke, enableProdMode: Ne, environment: l, equal: Lu, equalStrict: Wu, erf: ds, exp: vs, expandDims: Zn, expm1: ms, eye: tr, fft: zl, fill: Rn, findBackend: Ve, findBackendFactory: Ge, floor: gs, floorDiv: nl, frame: Zl, fused: Ec, gather: Ol, gatherND: jl, getBackend: Ue, grad: Fr, grads: Mr, greater: Uu, greaterEqual: zu, greaterEqualStrict: Vu, greaterStrict: Gu, hammingWindow: Jl, hannWindow: Ql, ifft: Vl, imag: pn, image: wc, io: Rh, irfft: ql, isFinite: As, isInf: ks, isNaN: Ns, keep: Be, leakyRelu: Rl, less: qu, lessEqual: Hu, lessEqualStrict: $u, lessStrict: ju, linalg: dc, linspace: In, localResponseNormalization: Al, log: ys, log1p: xs, logSigmoid: bs, logSoftmax: Vr, logSumExp: Du, logicalAnd: gl, logicalNot: yl, logicalOr: xl, logicalXor: bl, losses: cc, matMul: uu, math: Sh, max: _u, maxPool: yu, maximum: rl, maximumStrict: ol, mean: Ou, memory: _e, min: Fu, minimum: al, minimumStrict: il, mod: sl, modStrict: ul, moments: Mu, movingAverage: Pl, mul: ll, mulStrict: cl, multiRNNCell: Bl, multinomial: er, neg: ws, nextFrame: Jh, norm: Tl, notEqual: Ku, notEqualStrict: Xu, oneHot: nr, ones: Cn, onesLike: Nn, op: ln, outerProduct: cu, pad: rr, pad1d: or, pad2d: ar, pad3d: ir, pad4d: sr, pool: bu, pow: hl, powStrict: pl, prelu: Il, print: jn, prod: Pu, profile: Oe, rand: ur, randomNormal: lr, randomUniform: cr, range: Sn, ready: We, real: hn, reciprocal: Cs, registerBackend: qe, relu: Sl, removeBackend: ze, reshape: hr, reverse: hu, reverse1d: pu, reverse2d: fu, reverse3d: du, reverse4d: vu, rfft: Gl, round: Es, rsqrt: Rs, scalar: vn, scatterND: Ul, selu: Nl, separableConv2d: iu, serialization: _h, setBackend: Le, setPlatform: $e, setdiff1dAsync: yr, sigmoid: Is, sign: Ss, signal: tc, sin: Ts, sinh: Ds, slice: wu, slice1d: Cu, slice2d: Eu, slice3d: Ru, slice4d: Iu, softmax: zr, softplus: _s, spaceToBatchND: pr, sparseToDense: $l, spectral: Hl, split: Fn, sqrt: Os, square: Fs, squaredDifference: fl, squaredDifferenceStrict: dl, squeeze: fr, stack: dr, step: Ms, stridedSlice: Ll, sub: vl, subStrict: ml, sum: Bu, tan: Bs, tanh: Ps, tensor: fn, tensor1d: mn, tensor2d: gn, tensor3d: yn, tensor4d: xn, tensor5d: bn, tensor6d: wn, tensor_util: St, test_util: Lh, tidy: Fe, tile: vr, time: Pe, topk: Wl, train: Yh, transpose: kl, truncatedNormal: mr, unsortedSegmentSum: Fl, unstack: gr, util: Q, valueAndGrad: Br, valueAndGrads: Pr, variable: yt, variableGrads: Lr, version_core: Wh, webgl: Uh, where: wl, whereAsync: Cl, zeros: En, zerosLike: kn }); var Dimensions = /** @class */ (function () { function Dimensions(width, height) { if (!isValidNumber(width) || !isValidNumber(height)) { throw new Error("Dimensions.constructor - expected width and height to be valid numbers, instead have " + JSON.stringify({ width: width, height: height })); } this._width = width; this._height = height; } Object.defineProperty(Dimensions.prototype, "width", { get: function () { return this._width; }, enumerable: true, configurable: true }); Object.defineProperty(Dimensions.prototype, "height", { get: function () { return this._height; }, enumerable: true, configurable: true }); Dimensions.prototype.reverse = function () { return new Dimensions(1 / this.width, 1 / this.height); }; return Dimensions; }()); var Point = /** @class */ (function () { function Point(x, y) { this._x = x; this._y = y; } Object.defineProperty(Point.prototype, "x", { get: function () { return this._x; }, enumerable: true, configurable: true }); Object.defineProperty(Point.prototype, "y", { get: function () { return this._y; }, enumerable: true, configurable: true }); Point.prototype.add = function (pt) { return new Point(this.x + pt.x, this.y + pt.y); }; Point.prototype.sub = function (pt) { return new Point(this.x - pt.x, this.y - pt.y); }; Point.prototype.mul = function (pt) { return new Point(this.x * pt.x, this.y * pt.y); }; Point.prototype.div = function (pt) { return new Point(this.x / pt.x, this.y / pt.y); }; Point.prototype.abs = function () { return new Point(Math.abs(this.x), Math.abs(this.y)); }; Point.prototype.magnitude = function () { return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2)); }; Point.prototype.floor = function () { return new Point(Math.floor(this.x), Math.floor(this.y)); }; return Point; }()); function isTensor(tensor, dim) { return tensor instanceof ht && tensor.shape.length === dim; } function isTensor1D(tensor) { return isTensor(tensor, 1); } function isTensor2D(tensor) { return isTensor(tensor, 2); } function isTensor3D(tensor) { return isTensor(tensor, 3); } function isTensor4D(tensor) { return isTensor(tensor, 4); } function isFloat(num) { return num % 1 !== 0; } function isEven(num) { return num % 2 === 0; } function round(num, prec) { if (prec === void 0) { prec = 2; } var f = Math.pow(10, prec); return Math.floor(num * f) / f; } function isDimensions(obj) { return obj && obj.width && obj.height; } function computeReshapedDimensions(_a, inputSize) { var width = _a.width, height = _a.height; var scale = inputSize / Math.max(height, width); return new Dimensions(Math.round(width * scale), Math.round(height * scale)); } function getCenterPoint(pts) { return pts.reduce(function (sum, pt) { return sum.add(pt); }, new Point(0, 0)) .div(new Point(pts.length, pts.length)); } function range(num, start, step) { return Array(num).fill(0).map(function (_, i) { return start + (i * step); }); } function isValidNumber(num) { return !!num && num !== Infinity && num !== -Infinity && !isNaN(num) || num === 0; } function isValidProbablitiy(num) { return isValidNumber(num) && 0 <= num && num <= 1.0; } var Box = /** @class */ (function () { function Box(_box, allowNegativeDimensions) { if (allowNegativeDimensions === void 0) { allowNegativeDimensions = true; } var box = (_box || {}); var isBbox = [box.left, box.top, box.right, box.bottom].every(isValidNumber); var isRect = [box.x, box.y, box.width, box.height].every(isValidNumber); if (!isRect && !isBbox) { throw new Error("Box.constructor - expected box to be IBoundingBox | IRect, instead have " + JSON.stringify(box)); } var _a = isRect ? [box.x, box.y, box.width, box.height] : [box.left, box.top, box.right - box.left, box.bottom - box.top], x = _a[0], y = _a[1], width = _a[2], height = _a[3]; Box.assertIsValidBox({ x: x, y: y, width: width, height: height }, 'Box.constructor', allowNegativeDimensions); this._x = x; this._y = y; this._width = width; this._height = height; } Box.isRect = function (rect) { return !!rect && [rect.x, rect.y, rect.width, rect.height].every(isValidNumber); }; Box.assertIsValidBox = function (box, callee, allowNegativeDimensions) { if (allowNegativeDimensions === void 0) { allowNegativeDimensions = false; } if (!Box.isRect(box)) { throw new Error(callee + " - invalid box: " + JSON.stringify(box) + ", expected object with properties x, y, width, height"); } if (!allowNegativeDimensions && (box.width < 0 || box.height < 0)) { throw new Error(callee + " - width (" + box.width + ") and height (" + box.height + ") must be positive numbers"); } }; Object.defineProperty(Box.prototype, "x", { get: function () { return this._x; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "y", { get: function () { return this._y; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "width", { get: function () { return this._width; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "height", { get: function () { return this._height; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "left", { get: function () { return this.x; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "top", { get: function () { return this.y; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "right", { get: function () { return this.x + this.width; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "bottom", { get: function () { return this.y + this.height; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "area", { get: function () { return this.width * this.height; }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "topLeft", { get: function () { return new Point(this.left, this.top); }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "topRight", { get: function () { return new Point(this.right, this.top); }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "bottomLeft", { get: function () { return new Point(this.left, this.bottom); }, enumerable: true, configurable: true }); Object.defineProperty(Box.prototype, "bottomRight", { get: function () { return new Point(this.right, this.bottom); }, enumerable: true, configurable: true }); Box.prototype.round = function () { var _a = [this.x, this.y, this.width, this.height] .map(function (val) { return Math.round(val); }), x = _a[0], y = _a[1], width = _a[2], height = _a[3]; return new Box({ x: x, y: y, width: width, height: height }); }; Box.prototype.floor = function () { var _a = [this.x, this.y, this.width, this.height] .map(function (val) { return Math.floor(val); }), x = _a[0], y = _a[1], width = _a[2], height = _a[3]; return new Box({ x: x, y: y, width: width, height: height }); }; Box.prototype.toSquare = function () { var _a = this, x = _a.x, y = _a.y, width = _a.width, height = _a.height; var diff = Math.abs(width - height); if (width < height) { x -= (diff / 2); width += diff; } if (height < width) { y -= (diff / 2); height += diff; } return new Box({ x: x, y: y, width: width, height: height }); }; Box.prototype.rescale = function (s) { var scaleX = isDimensions(s) ? s.width : s; var scaleY = isDimensions(s) ? s.height : s; return new Box({ x: this.x * scaleX, y: this.y * scaleY, width: this.width * scaleX, height: this.height * scaleY }); }; Box.prototype.pad = function (padX, padY) { var _a = [ this.x - (padX / 2), this.y - (padY / 2), this.width + padX, this.height + padY ], x = _a[0], y = _a[1], width = _a[2], height = _a[3]; return new Box({ x: x, y: y, width: width, height: height }); }; Box.prototype.clipAtImageBorders = function (imgWidth, imgHeight) { var _a = this, x = _a.x, y = _a.y, right = _a.right, bottom = _a.bottom; var clippedX = Math.max(x, 0); var clippedY = Math.max(y, 0); var newWidth = right - clippedX; var newHeight = bottom - clippedY; var clippedWidth = Math.min(newWidth, imgWidth - clippedX); var clippedHeight = Math.min(newHeight, imgHeight - clippedY); return (new Box({ x: clippedX, y: clippedY, width: clippedWidth, height: clippedHeight })).floor(); }; Box.prototype.shift = function (sx, sy) { var _a = this, width = _a.width, height = _a.height; var x = this.x + sx; var y = this.y + sy; return new Box({ x: x, y: y, width: width, height: height }); }; Box.prototype.padAtBorders = function (imageHeight, imageWidth) { var w = this.width + 1; var h = this.height + 1; var dx = 1; var dy = 1; var edx = w; var edy = h; var x = this.left; var y = this.top; var ex = this.right; var ey = this.bottom; if (ex > imageWidth) { edx = -ex + imageWidth + w; ex = imageWidth; } if (ey > imageHeight) { edy = -ey + imageHeight + h; ey = imageHeight; } if (x < 1) { edy = 2 - x; x = 1; } if (y < 1) { edy = 2 - y; y = 1; } return { dy: dy, edy: edy, dx: dx, edx: edx, y: y, ey: ey, x: x, ex: ex, w: w, h: h }; }; Box.prototype.calibrate = function (region) { return new Box({ left: this.left + (region.left * this.width), top: this.top + (region.top * this.height), right: this.right + (region.right * this.width), bottom: this.bottom + (region.bottom * this.height) }).toSquare().round(); }; return Box; }()); var BoundingBox = /** @class */ (function (_super) { __extends(BoundingBox, _super); function BoundingBox(left, top, right, bottom, allowNegativeDimensions) { if (allowNegativeDimensions === void 0) { allowNegativeDimensions = false; } return _super.call(this, { left: left, top: top, right: right, bottom: bottom }, allowNegativeDimensions) || this; } return BoundingBox; }(Box)); var LabeledBox = /** @class */ (function (_super) { __extends(LabeledBox, _super); function LabeledBox(box, label) { var _this = _super.call(this, box) || this; _this._label = label; return _this; } LabeledBox.assertIsValidLabeledBox = function (box, callee) { Box.assertIsValidBox(box, callee); if (!isValidNumber(box.label)) { throw new Error(callee + " - expected property label (" + box.label + ") to be a number"); } }; Object.defineProperty(LabeledBox.prototype, "label", { get: function () { return this._label; }, enumerable: true, configurable: true }); return LabeledBox; }(Box)); var ObjectDetection = /** @class */ (function () { function ObjectDetection(score, classScore, className, relativeBox, imageDims) { this._imageDims = new Dimensions(imageDims.width, imageDims.height); this._score = score; this._classScore = classScore; this._className = className; this._box = new Box(relativeBox).rescale(this._imageDims); } Object.defineProperty(ObjectDetection.prototype, "score", { get: function () { return this._score; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "classScore", { get: function () { return this._classScore; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "className", { get: function () { return this._className; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "box", { get: function () { return this._box; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "imageDims", { get: function () { return this._imageDims; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "imageWidth", { get: function () { return this.imageDims.width; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "imageHeight", { get: function () { return this.imageDims.height; }, enumerable: true, configurable: true }); Object.defineProperty(ObjectDetection.prototype, "relativeBox", { get: function () { return new Box(this._box).rescale(this.imageDims.reverse()); }, enumerable: true, configurable: true }); ObjectDetection.prototype.forSize = function (width, height) { return new ObjectDetection(this.score, this.classScore, this.className, this.relativeBox, { width: width, height: height }); }; return ObjectDetection; }()); var PredictedBox = /** @class */ (function (_super) { __extends(PredictedBox, _super); function PredictedBox(box, label, score, classScore) { var _this = _super.call(this, box, label) || this; _this._score = score; _this._classScore = classScore; return _this; } PredictedBox.assertIsValidPredictedBox = function (box, callee) { LabeledBox.assertIsValidLabeledBox(box, callee); if (!isValidProbablitiy(box.score) || !isValidProbablitiy(box.classScore)) { throw new Error(callee + " - expected properties score (" + box.score + ") and (" + box.classScore + ") to be a number between [0, 1]"); } }; Object.defineProperty(PredictedBox.prototype, "score", { get: function () { return this._score; }, enumerable: true, configurable: true }); Object.defineProperty(PredictedBox.prototype, "classScore", { get: function () { return this._classScore; }, enumerable: true, configurable: true }); return PredictedBox; }(LabeledBox)); var Rect = /** @class */ (function (_super) { __extends(Rect, _super); function Rect(x, y, width, height, allowNegativeDimensions) { if (allowNegativeDimensions === void 0) { allowNegativeDimensions = false; } return _super.call(this, { x: x, y: y, width: width, height: height }, allowNegativeDimensions) || this; } return Rect; }(Box)); function createBrowserEnv() { var fetch = window['fetch'] || function () { throw new Error('fetch - missing fetch implementation for browser environment'); }; var readFile = function () { throw new Error('readFile - filesystem not available for browser environment'); }; return { Canvas: HTMLCanvasElement, CanvasRenderingContext2D: CanvasRenderingContext2D, Image: HTMLImageElement, ImageData: ImageData, Video: HTMLVideoElement, createCanvasElement: function () { return document.createElement('canvas'); }, createImageElement: function () { return document.createElement('img'); }, fetch: fetch, readFile: readFile }; } function createFileSystem(fs) { var requireFsError = ''; if (!fs) { try { fs = require('fs'); } catch (err) { requireFsError = err.toString(); } } var readFile = fs ? function (filePath) { return new Promise(function (res, rej) { fs.readFile(filePath, function (err, buffer) { return err ? rej(err) : res(buffer); }); }); } : function () { throw new Error("readFile - failed to require fs in nodejs environment with error: " + requireFsError); }; return { readFile: readFile }; } function createNodejsEnv() { var Canvas = global['Canvas'] || global['HTMLCanvasElement']; var Image = global['Image'] || global['HTMLImageElement']; var createCanvasElement = function () { if (Canvas) { return new Canvas(); } throw new Error('createCanvasElement - missing Canvas implementation for nodejs environment'); }; var createImageElement = function () { if (Image) { return new Image(); } throw new Error('createImageElement - missing Image implementation for nodejs environment'); }; var fetch = global['fetch'] || function () { throw new Error('fetch - missing fetch implementation for nodejs environment'); }; var fileSystem = createFileSystem(); return __assign({ Canvas: Canvas || /** @class */ (function () { function Canvas() { } return Canvas; }()), CanvasRenderingContext2D: global['CanvasRenderingContext2D'] || /** @class */ (function () { function class_1() { } return class_1; }()), Image: Image || /** @class */ (function () { function Image() { } return Image; }()), ImageData: global['ImageData'] || /** @class */ (function () { function class_2() { } return class_2; }()), Video: global['HTMLVideoElement'] || /** @class */ (function () { function class_3() { } return class_3; }()), createCanvasElement: createCanvasElement, createImageElement: createImageElement, fetch: fetch }, fileSystem); } function isBrowser() { return typeof window === 'object' && typeof document !== 'undefined' && typeof HTMLImageElement !== 'undefined' && typeof HTMLCanvasElement !== 'undefined' && typeof HTMLVideoElement !== 'undefined' && typeof ImageData !== 'undefined' && typeof CanvasRenderingContext2D !== 'undefined'; } function isNodejs() { return typeof global === 'object' && typeof require === 'function' && typeof module !== 'undefined' // issues with gatsby.js: module.exports is undefined // && !!module.exports && typeof process !== 'undefined' && !!process.version; } var environment; function getEnv() { if (!environment) { throw new Error('getEnv - environment is not defined, check isNodejs() and isBrowser()'); } return environment; } function setEnv(env) { environment = env; } function initialize() { // check for isBrowser() first to prevent electron renderer process // to be initialized with wrong environment due to isNodejs() returning true if (isBrowser()) { setEnv(createBrowserEnv()); } if (isNodejs()) { setEnv(createNodejsEnv()); } } function monkeyPatch(env) { if (!environment) { initialize(); } if (!environment) { throw new Error('monkeyPatch - environment is not defined, check isNodejs() and isBrowser()'); } var _a = env.Canvas, Canvas = _a === void 0 ? environment.Canvas : _a, _b = env.Image, Image = _b === void 0 ? environment.Image : _b; environment.Canvas = Canvas; environment.Image = Image; environment.createCanvasElement = env.createCanvasElement || (function () { return new Canvas(); }); environment.createImageElement = env.createImageElement || (function () { return new Image(); }); environment.ImageData = env.ImageData || environment.ImageData; environment.Video = env.Video || environment.Video; environment.fetch = env.fetch || environment.fetch; environment.readFile = env.readFile || environment.readFile; } var env = { getEnv: getEnv, setEnv: setEnv, initialize: initialize, createBrowserEnv: createBrowserEnv, createFileSystem: createFileSystem, createNodejsEnv: createNodejsEnv, monkeyPatch: monkeyPatch, isBrowser: isBrowser, isNodejs: isNodejs }; initialize(); function resolveInput(arg) { if (!env.isNodejs() && typeof arg === 'string') { return document.getElementById(arg); } return arg; } function getContext2dOrThrow(canvasArg) { var _a = env.getEnv(), Canvas = _a.Canvas, CanvasRenderingContext2D = _a.CanvasRenderingContext2D; if (canvasArg instanceof CanvasRenderingContext2D) { return canvasArg; } var canvas = resolveInput(canvasArg); if (!(canvas instanceof Canvas)) { throw new Error('resolveContext2d - expected canvas to be of instance of Canvas'); } var ctx = canvas.getContext('2d'); if (!ctx) { throw new Error('resolveContext2d - canvas 2d context is null'); } return ctx; } var AnchorPosition; (function (AnchorPosition) { AnchorPosition["TOP_LEFT"] = "TOP_LEFT"; AnchorPosition["TOP_RIGHT"] = "TOP_RIGHT"; AnchorPosition["BOTTOM_LEFT"] = "BOTTOM_LEFT"; AnchorPosition["BOTTOM_RIGHT"] = "BOTTOM_RIGHT"; })(AnchorPosition || (AnchorPosition = {})); var DrawTextFieldOptions = /** @class */ (function () { function DrawTextFieldOptions(options) { if (options === void 0) { options = {}; } var anchorPosition = options.anchorPosition, backgroundColor = options.backgroundColor, fontColor = options.fontColor, fontSize = options.fontSize, fontStyle = options.fontStyle, padding = options.padding; this.anchorPosition = anchorPosition || AnchorPosition.TOP_LEFT; this.backgroundColor = backgroundColor || 'rgba(0, 0, 0, 0.5)'; this.fontColor = fontColor || 'rgba(255, 255, 255, 1)'; this.fontSize = fontSize || 14; this.fontStyle = fontStyle || 'Georgia'; this.padding = padding || 4; } return DrawTextFieldOptions; }()); var DrawTextField = /** @class */ (function () { function DrawTextField(text, anchor, options) { if (options === void 0) { options = {}; } this.text = typeof text === 'string' ? [text] : (text instanceof DrawTextField ? text.text : text); this.anchor = anchor; this.options = new DrawTextFieldOptions(options); } DrawTextField.prototype.measureWidth = function (ctx) { var padding = this.options.padding; return this.text.map(function (l) { return ctx.measureText(l).width; }).reduce(function (w0, w1) { return w0 < w1 ? w1 : w0; }, 0) + (2 * padding); }; DrawTextField.prototype.measureHeight = function () { var _a = this.options, fontSize = _a.fontSize, padding = _a.padding; return this.text.length * fontSize + (2 * padding); }; DrawTextField.prototype.getUpperLeft = function (ctx, canvasDims) { var anchorPosition = this.options.anchorPosition; var isShiftLeft = anchorPosition === AnchorPosition.BOTTOM_RIGHT || anchorPosition === AnchorPosition.TOP_RIGHT; var isShiftTop = anchorPosition === AnchorPosition.BOTTOM_LEFT || anchorPosition === AnchorPosition.BOTTOM_RIGHT; var textFieldWidth = this.measureWidth(ctx); var textFieldHeight = this.measureHeight(); var x = (isShiftLeft ? this.anchor.x - textFieldWidth : this.anchor.x); var y = isShiftTop ? this.anchor.y - textFieldHeight : this.anchor.y; // adjust anchor if text box exceeds canvas borders if (canvasDims) { var width = canvasDims.width, height = canvasDims.height; var newX = Math.max(Math.min(x, width - textFieldWidth), 0); var newY = Math.max(Math.min(y, height - textFieldHeight), 0); return { x: newX, y: newY }; } return { x: x, y: y }; }; DrawTextField.prototype.draw = function (canvasArg) { var canvas = resolveInput(canvasArg); var ctx = getContext2dOrThrow(canvas); var _a = this.options, backgroundColor = _a.backgroundColor, fontColor = _a.fontColor, fontSize = _a.fontSize, fontStyle = _a.fontStyle, padding = _a.padding; ctx.font = fontSize + "px " + fontStyle; var maxTextWidth = this.measureWidth(ctx); var textHeight = this.measureHeight(); ctx.fillStyle = backgroundColor; var upperLeft = this.getUpperLeft(ctx, canvas); ctx.fillRect(upperLeft.x, upperLeft.y, maxTextWidth, textHeight); ctx.fillStyle = fontColor; this.text.forEach(function (textLine, i) { var x = padding + upperLeft.x; var y = padding + upperLeft.y + ((i + 1) * fontSize); ctx.fillText(textLine, x, y); }); }; return DrawTextField; }()); var DrawBoxOptions = /** @class */ (function () { function DrawBoxOptions(options) { if (options === void 0) { options = {}; } var boxColor = options.boxColor, lineWidth = options.lineWidth, label = options.label, drawLabelOptions = options.drawLabelOptions; this.boxColor = boxColor || 'rgba(0, 0, 255, 1)'; this.lineWidth = lineWidth || 2; this.label = label; var defaultDrawLabelOptions = { anchorPosition: AnchorPosition.BOTTOM_LEFT, backgroundColor: this.boxColor }; this.drawLabelOptions = new DrawTextFieldOptions(Object.assign({}, defaultDrawLabelOptions, drawLabelOptions)); } return DrawBoxOptions; }()); var DrawBox = /** @class */ (function () { function DrawBox(box, options) { if (options === void 0) { options = {}; } this.box = new Box(box); this.options = new DrawBoxOptions(options); } DrawBox.prototype.draw = function (canvasArg) { var ctx = getContext2dOrThrow(canvasArg); var _a = this.options, boxColor = _a.boxColor, lineWidth = _a.lineWidth; var _b = this.box, x = _b.x, y = _b.y, width = _b.width, height = _b.height; ctx.strokeStyle = boxColor; ctx.lineWidth = lineWidth; ctx.strokeRect(x, y, width, height); var label = this.options.label; if (label) { new DrawTextField([label], { x: x - (lineWidth / 2), y: y }, this.options.drawLabelOptions).draw(canvasArg); } }; return DrawBox; }()); var drawBase = /*#__PURE__*/Object.freeze({ DrawBoxOptions: DrawBoxOptions, DrawBox: DrawBox, get AnchorPosition () { return AnchorPosition; }, DrawTextFieldOptions: DrawTextFieldOptions, DrawTextField: DrawTextField }); function convLayer(x, params, padding, withRelu) { if (padding === void 0) { padding = 'same'; } if (withRelu === void 0) { withRelu = false; } return Fe(function () { var out = Yu(nu(x, params.filters, [1, 1], padding), params.bias); return withRelu ? Sl(out) : out; }); } function disposeUnusedWeightTensors(weightMap, paramMappings) { Object.keys(weightMap).forEach(function (path) { if (!paramMappings.some(function (pm) { return pm.originalPath === path; })) { weightMap[path].dispose(); } }); } function extractConvParamsFactory(extractWeights, paramMappings) { return function (channelsIn, channelsOut, filterSize, mappedPrefix) { var filters = xn(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]); var bias = mn(extractWeights(channelsOut)); paramMappings.push({ paramPath: mappedPrefix + "/filters" }, { paramPath: mappedPrefix + "/bias" }); return { filters: filters, bias: bias }; }; } function extractFCParamsFactory(extractWeights, paramMappings) { return function (channelsIn, channelsOut, mappedPrefix) { var fc_weights = gn(extractWeights(channelsIn * channelsOut), [channelsIn, channelsOut]); var fc_bias = mn(extractWeights(channelsOut)); paramMappings.push({ paramPath: mappedPrefix + "/weights" }, { paramPath: mappedPrefix + "/bias" }); return { weights: fc_weights, bias: fc_bias }; }; } var SeparableConvParams = /** @class */ (function () { function SeparableConvParams(depthwise_filter, pointwise_filter, bias) { this.depthwise_filter = depthwise_filter; this.pointwise_filter = pointwise_filter; this.bias = bias; } return SeparableConvParams; }()); function extractSeparableConvParamsFactory(extractWeights, paramMappings) { return function (channelsIn, channelsOut, mappedPrefix) { var depthwise_filter = xn(extractWeights(3 * 3 * channelsIn), [3, 3, channelsIn, 1]); var pointwise_filter = xn(extractWeights(channelsIn * channelsOut), [1, 1, channelsIn, channelsOut]); var bias = mn(extractWeights(channelsOut)); paramMappings.push({ paramPath: mappedPrefix + "/depthwise_filter" }, { paramPath: mappedPrefix + "/pointwise_filter" }, { paramPath: mappedPrefix + "/bias" }); return new SeparableConvParams(depthwise_filter, pointwise_filter, bias); }; } function loadSeparableConvParamsFactory(extractWeightEntry) { return function (prefix) { var depthwise_filter = extractWeightEntry(prefix + "/depthwise_filter", 4); var pointwise_filter = extractWeightEntry(prefix + "/pointwise_filter", 4); var bias = extractWeightEntry(prefix + "/bias", 1); return new SeparableConvParams(depthwise_filter, pointwise_filter, bias); }; } function extractWeightEntryFactory(weightMap, paramMappings) { return function (originalPath, paramRank, mappedPath) { var tensor = weightMap[originalPath]; if (!isTensor(tensor, paramRank)) { throw new Error("expected weightMap[" + originalPath + "] to be a Tensor" + paramRank + "D, instead have " + tensor); } paramMappings.push({ originalPath: originalPath, paramPath: mappedPath || originalPath }); return tensor; }; } function extractWeightsFactory(weights) { var remainingWeights = weights; function extractWeights(numWeights) { var ret = remainingWeights.slice(0, numWeights); remainingWeights = remainingWeights.slice(numWeights); return ret; } function getRemainingWeights() { return remainingWeights; } return { extractWeights: extractWeights, getRemainingWeights: getRemainingWeights }; } function getModelUris(uri, defaultModelName) { var defaultManifestFilename = defaultModelName + "-weights_manifest.json"; if (!uri) { return { modelBaseUri: '', manifestUri: defaultManifestFilename }; } if (uri === '/') { return { modelBaseUri: '/', manifestUri: "/" + defaultManifestFilename }; } var protocol = uri.startsWith('http://') ? 'http://' : uri.startsWith('https://') ? 'https://' : ''; uri = uri.replace(protocol, ''); var parts = uri.split('/').filter(function (s) { return s; }); var manifestFile = uri.endsWith('.json') ? parts[parts.length - 1] : defaultManifestFilename; var modelBaseUri = protocol + (uri.endsWith('.json') ? parts.slice(0, parts.length - 1) : parts).join('/'); modelBaseUri = uri.startsWith('/') ? "/" + modelBaseUri : modelBaseUri; return { modelBaseUri: modelBaseUri, manifestUri: modelBaseUri === '/' ? "/" + manifestFile : modelBaseUri + "/" + manifestFile }; } function isMediaLoaded(media) { var _a = env.getEnv(), Image = _a.Image, Video = _a.Video; return (media instanceof Image && media.complete) || (media instanceof Video && media.readyState >= 3); } function awaitMediaLoaded(media) { return new Promise(function (resolve, reject) { if (media instanceof env.getEnv().Canvas || isMediaLoaded(media)) { return resolve(); } function onLoad(e) { if (!e.currentTarget) return; e.currentTarget.removeEventListener('load', onLoad); e.currentTarget.removeEventListener('error', onError); resolve(e); } function onError(e) { if (!e.currentTarget) return; e.currentTarget.removeEventListener('load', onLoad); e.currentTarget.removeEventListener('error', onError); reject(e); } media.addEventListener('load', onLoad); media.addEventListener('error', onError); }); } function bufferToImage(buf) { return new Promise(function (resolve, reject) { if (!(buf instanceof Blob)) { return reject('bufferToImage - expected buf to be of type: Blob'); } var reader = new FileReader(); reader.onload = function () { if (typeof reader.result !== 'string') { return reject('bufferToImage - expected reader.result to be a string, in onload'); } var img = env.getEnv().createImageElement(); img.onload = function () { return resolve(img); }; img.onerror = reject; img.src = reader.result; }; reader.onerror = reject; reader.readAsDataURL(buf); }); } function getMediaDimensions(input) { var _a = env.getEnv(), Image = _a.Image, Video = _a.Video; if (input instanceof Image) { return new Dimensions(input.naturalWidth, input.naturalHeight); } if (input instanceof Video) { return new Dimensions(input.videoWidth, input.videoHeight); } return new Dimensions(input.width, input.height); } function createCanvas(_a) { var width = _a.width, height = _a.height; var createCanvasElement = env.getEnv().createCanvasElement; var canvas = createCanvasElement(); canvas.width = width; canvas.height = height; return canvas; } function createCanvasFromMedia(media, dims) { var ImageData = env.getEnv().ImageData; if (!(media instanceof ImageData) && !isMediaLoaded(media)) { throw new Error('createCanvasFromMedia - media has not finished loading yet'); } var _a = dims || getMediaDimensions(media), width = _a.width, height = _a.height; var canvas = createCanvas({ width: width, height: height }); if (media instanceof ImageData) { getContext2dOrThrow(canvas).putImageData(media, 0, 0); } else { getContext2dOrThrow(canvas).drawImage(media, 0, 0, width, height); } return canvas; } function fetchOrThrow(url, init) { return __awaiter(this, void 0, void 0, function () { var fetch, res; return __generator(this, function (_a) { switch (_a.label) { case 0: fetch = env.getEnv().fetch; return [4 /*yield*/, fetch(url, init)]; case 1: res = _a.sent(); if (!(res.status < 400)) { throw new Error("failed to fetch: (" + res.status + ") " + res.statusText + ", from url: " + res.url); } return [2 /*return*/, res]; } }); }); } function fetchImage(uri) { return __awaiter(this, void 0, void 0, function () { var res, blob; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, fetchOrThrow(uri)]; case 1: res = _a.sent(); return [4 /*yield*/, (res).blob()]; case 2: blob = _a.sent(); if (!blob.type.startsWith('image/')) { throw new Error("fetchImage - expected blob type to be of type image/*, instead have: " + blob.type + ", for url: " + res.url); } return [2 /*return*/, bufferToImage(blob)]; } }); }); } function fetchJson(uri) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, fetchOrThrow(uri)]; case 1: return [2 /*return*/, (_a.sent()).json()]; } }); }); } function fetchNetWeights(uri) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = Float32Array.bind; return [4 /*yield*/, fetchOrThrow(uri)]; case 1: return [4 /*yield*/, (_b.sent()).arrayBuffer()]; case 2: return [2 /*return*/, new (_a.apply(Float32Array, [void 0, _b.sent()]))()]; } }); }); } function imageTensorToCanvas(imgTensor, canvas) { return __awaiter(this, void 0, void 0, function () { var targetCanvas, _a, height, width, numChannels, imgTensor3D; return __generator(this, function (_b) { switch (_b.label) { case 0: targetCanvas = canvas || env.getEnv().createCanvasElement(); _a = imgTensor.shape.slice(isTensor4D(imgTensor) ? 1 : 0), height = _a[0], width = _a[1], numChannels = _a[2]; imgTensor3D = Fe(function () { return imgTensor.as3D(height, width, numChannels).toInt(); }); return [4 /*yield*/, kh.toPixels(imgTensor3D, targetCanvas)]; case 1: _b.sent(); imgTensor3D.dispose(); return [2 /*return*/, targetCanvas]; } }); }); } function imageToSquare(input, inputSize, centerImage) { if (centerImage === void 0) { centerImage = false; } var _a = env.getEnv(), Image = _a.Image, Canvas = _a.Canvas; if (!(input instanceof Image || input instanceof Canvas)) { throw new Error('imageToSquare - expected arg0 to be HTMLImageElement | HTMLCanvasElement'); } var dims = getMediaDimensions(input); var scale = inputSize / Math.max(dims.height, dims.width); var width = scale * dims.width; var height = scale * dims.height; var targetCanvas = createCanvas({ width: inputSize, height: inputSize }); var inputCanvas = input instanceof Canvas ? input : createCanvasFromMedia(input); var offset = Math.abs(width - height) / 2; var dx = centerImage && width < height ? offset : 0; var dy = centerImage && height < width ? offset : 0; getContext2dOrThrow(targetCanvas).drawImage(inputCanvas, dx, dy, width, height); return targetCanvas; } function isMediaElement(input) { var _a = env.getEnv(), Image = _a.Image, Canvas = _a.Canvas, Video = _a.Video; return input instanceof Image || input instanceof Canvas || input instanceof Video; } function loadWeightMap(uri, defaultModelName) { return __awaiter(this, void 0, void 0, function () { var _a, manifestUri, modelBaseUri, manifest; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = getModelUris(uri, defaultModelName), manifestUri = _a.manifestUri, modelBaseUri = _a.modelBaseUri; return [4 /*yield*/, fetchJson(manifestUri)]; case 1: manifest = _b.sent(); return [2 /*return*/, Rh.loadWeights(manifest, modelBaseUri)]; } }); }); } function matchDimensions(input, reference, useMediaDimensions) { if (useMediaDimensions === void 0) { useMediaDimensions = false; } var _a = useMediaDimensions ? getMediaDimensions(reference) : reference, width = _a.width, height = _a.height; input.width = width; input.height = height; return { width: width, height: height }; } /** * Pads the smaller dimension of an image tensor with zeros, such that width === height. * * @param imgTensor The image tensor. * @param isCenterImage (optional, default: false) If true, add an equal amount of padding on * both sides of the minor dimension oof the image. * @returns The padded tensor with width === height. */ function padToSquare(imgTensor, isCenterImage) { if (isCenterImage === void 0) { isCenterImage = false; } return Fe(function () { var _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1]; if (height === width) { return imgTensor; } var dimDiff = Math.abs(height - width); var paddingAmount = Math.round(dimDiff * (isCenterImage ? 0.5 : 1)); var paddingAxis = height > width ? 2 : 1; var createPaddingTensor = function (paddingAmount) { var paddingTensorShape = imgTensor.shape.slice(); paddingTensorShape[paddingAxis] = paddingAmount; return Rn(paddingTensorShape, 0); }; var paddingTensorAppend = createPaddingTensor(paddingAmount); var remainingPaddingAmount = dimDiff - paddingTensorAppend.shape[paddingAxis]; var paddingTensorPrepend = isCenterImage && remainingPaddingAmount ? createPaddingTensor(remainingPaddingAmount) : null; var tensorsToStack = [ paddingTensorPrepend, imgTensor, paddingTensorAppend ] .filter(function (t) { return !!t; }) .map(function (t) { return t.toFloat(); }); return An(tensorsToStack, paddingAxis); }); } var NetInput = /** @class */ (function () { function NetInput(inputs, treatAsBatchInput) { var _this = this; if (treatAsBatchInput === void 0) { treatAsBatchInput = false; } this._imageTensors = []; this._canvases = []; this._treatAsBatchInput = false; this._inputDimensions = []; if (!Array.isArray(inputs)) { throw new Error("NetInput.constructor - expected inputs to be an Array of TResolvedNetInput or to be instanceof tf.Tensor4D, instead have " + inputs); } this._treatAsBatchInput = treatAsBatchInput; this._batchSize = inputs.length; inputs.forEach(function (input, idx) { if (isTensor3D(input)) { _this._imageTensors[idx] = input; _this._inputDimensions[idx] = input.shape; return; } if (isTensor4D(input)) { var batchSize = input.shape[0]; if (batchSize !== 1) { throw new Error("NetInput - tf.Tensor4D with batchSize " + batchSize + " passed, but not supported in input array"); } _this._imageTensors[idx] = input; _this._inputDimensions[idx] = input.shape.slice(1); return; } var canvas = input instanceof env.getEnv().Canvas ? input : createCanvasFromMedia(input); _this._canvases[idx] = canvas; _this._inputDimensions[idx] = [canvas.height, canvas.width, 3]; }); } Object.defineProperty(NetInput.prototype, "imageTensors", { get: function () { return this._imageTensors; }, enumerable: true, configurable: true }); Object.defineProperty(NetInput.prototype, "canvases", { get: function () { return this._canvases; }, enumerable: true, configurable: true }); Object.defineProperty(NetInput.prototype, "isBatchInput", { get: function () { return this.batchSize > 1 || this._treatAsBatchInput; }, enumerable: true, configurable: true }); Object.defineProperty(NetInput.prototype, "batchSize", { get: function () { return this._batchSize; }, enumerable: true, configurable: true }); Object.defineProperty(NetInput.prototype, "inputDimensions", { get: function () { return this._inputDimensions; }, enumerable: true, configurable: true }); Object.defineProperty(NetInput.prototype, "inputSize", { get: function () { return this._inputSize; }, enumerable: true, configurable: true }); Object.defineProperty(NetInput.prototype, "reshapedInputDimensions", { get: function () { var _this = this; return range(this.batchSize, 0, 1).map(function (_, batchIdx) { return _this.getReshapedInputDimensions(batchIdx); }); }, enumerable: true, configurable: true }); NetInput.prototype.getInput = function (batchIdx) { return this.canvases[batchIdx] || this.imageTensors[batchIdx]; }; NetInput.prototype.getInputDimensions = function (batchIdx) { return this._inputDimensions[batchIdx]; }; NetInput.prototype.getInputHeight = function (batchIdx) { return this._inputDimensions[batchIdx][0]; }; NetInput.prototype.getInputWidth = function (batchIdx) { return this._inputDimensions[batchIdx][1]; }; NetInput.prototype.getReshapedInputDimensions = function (batchIdx) { if (typeof this.inputSize !== 'number') { throw new Error('getReshapedInputDimensions - inputSize not set, toBatchTensor has not been called yet'); } var width = this.getInputWidth(batchIdx); var height = this.getInputHeight(batchIdx); return computeReshapedDimensions({ width: width, height: height }, this.inputSize); }; /** * Create a batch tensor from all input canvases and tensors * with size [batchSize, inputSize, inputSize, 3]. * * @param inputSize Height and width of the tensor. * @param isCenterImage (optional, default: false) If true, add an equal amount of padding on * both sides of the minor dimension oof the image. * @returns The batch tensor. */ NetInput.prototype.toBatchTensor = function (inputSize, isCenterInputs) { var _this = this; if (isCenterInputs === void 0) { isCenterInputs = true; } this._inputSize = inputSize; return Fe(function () { var inputTensors = range(_this.batchSize, 0, 1).map(function (batchIdx) { var input = _this.getInput(batchIdx); if (input instanceof ht) { var imgTensor = isTensor4D(input) ? input : input.expandDims(); imgTensor = padToSquare(imgTensor, isCenterInputs); if (imgTensor.shape[1] !== inputSize || imgTensor.shape[2] !== inputSize) { imgTensor = wc.resizeBilinear(imgTensor, [inputSize, inputSize]); } return imgTensor.as3D(inputSize, inputSize, 3); } if (input instanceof env.getEnv().Canvas) { return kh.fromPixels(imageToSquare(input, inputSize, isCenterInputs)); } throw new Error("toBatchTensor - at batchIdx " + batchIdx + ", expected input to be instanceof tf.Tensor or instanceof HTMLCanvasElement, instead have " + input); }); var batchTensor = dr(inputTensors.map(function (t) { return t.toFloat(); })).as4D(_this.batchSize, inputSize, inputSize, 3); return batchTensor; }); }; return NetInput; }()); /** * Validates the input to make sure, they are valid net inputs and awaits all media elements * to be finished loading. * * @param input The input, which can be a media element or an array of different media elements. * @returns A NetInput instance, which can be passed into one of the neural networks. */ function toNetInput(inputs) { return __awaiter(this, void 0, void 0, function () { var inputArgArray, getIdxHint, inputArray; return __generator(this, function (_a) { switch (_a.label) { case 0: if (inputs instanceof NetInput) { return [2 /*return*/, inputs]; } inputArgArray = Array.isArray(inputs) ? inputs : [inputs]; if (!inputArgArray.length) { throw new Error('toNetInput - empty array passed as input'); } getIdxHint = function (idx) { return Array.isArray(inputs) ? " at input index " + idx + ":" : ''; }; inputArray = inputArgArray.map(resolveInput); inputArray.forEach(function (input, i) { if (!isMediaElement(input) && !isTensor3D(input) && !isTensor4D(input)) { if (typeof inputArgArray[i] === 'string') { throw new Error("toNetInput -" + getIdxHint(i) + " string passed, but could not resolve HTMLElement for element id " + inputArgArray[i]); } throw new Error("toNetInput -" + getIdxHint(i) + " expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id"); } if (isTensor4D(input)) { // if tf.Tensor4D is passed in the input array, the batch size has to be 1 var batchSize = input.shape[0]; if (batchSize !== 1) { throw new Error("toNetInput -" + getIdxHint(i) + " tf.Tensor4D with batchSize " + batchSize + " passed, but not supported in input array"); } } }); // wait for all media elements being loaded return [4 /*yield*/, Promise.all(inputArray.map(function (input) { return isMediaElement(input) && awaitMediaLoaded(input); }))]; case 1: // wait for all media elements being loaded _a.sent(); return [2 /*return*/, new NetInput(inputArray, Array.isArray(inputs))]; } }); }); } var NeuralNetwork = /** @class */ (function () { function NeuralNetwork(_name) { this._name = _name; this._params = undefined; this._paramMappings = []; } Object.defineProperty(NeuralNetwork.prototype, "params", { get: function () { return this._params; }, enumerable: true, configurable: true }); Object.defineProperty(NeuralNetwork.prototype, "paramMappings", { get: function () { return this._paramMappings; }, enumerable: true, configurable: true }); Object.defineProperty(NeuralNetwork.prototype, "isLoaded", { get: function () { return !!this.params; }, enumerable: true, configurable: true }); NeuralNetwork.prototype.getParamFromPath = function (paramPath) { var _a = this.traversePropertyPath(paramPath), obj = _a.obj, objProp = _a.objProp; return obj[objProp]; }; NeuralNetwork.prototype.reassignParamFromPath = function (paramPath, tensor) { var _a = this.traversePropertyPath(paramPath), obj = _a.obj, objProp = _a.objProp; obj[objProp].dispose(); obj[objProp] = tensor; }; NeuralNetwork.prototype.getParamList = function () { var _this = this; return this._paramMappings.map(function (_a) { var paramPath = _a.paramPath; return ({ path: paramPath, tensor: _this.getParamFromPath(paramPath) }); }); }; NeuralNetwork.prototype.getTrainableParams = function () { return this.getParamList().filter(function (param) { return param.tensor instanceof pt; }); }; NeuralNetwork.prototype.getFrozenParams = function () { return this.getParamList().filter(function (param) { return !(param.tensor instanceof pt); }); }; NeuralNetwork.prototype.variable = function () { var _this = this; this.getFrozenParams().forEach(function (_a) { var path = _a.path, tensor = _a.tensor; _this.reassignParamFromPath(path, tensor.variable()); }); }; NeuralNetwork.prototype.freeze = function () { var _this = this; this.getTrainableParams().forEach(function (_a) { var path = _a.path, variable = _a.tensor; var tensor = fn(variable.dataSync()); variable.dispose(); _this.reassignParamFromPath(path, tensor); }); }; NeuralNetwork.prototype.dispose = function (throwOnRedispose) { if (throwOnRedispose === void 0) { throwOnRedispose = true; } this.getParamList().forEach(function (param) { if (throwOnRedispose && param.tensor.isDisposed) { throw new Error("param tensor has already been disposed for path " + param.path); } param.tensor.dispose(); }); this._params = undefined; }; NeuralNetwork.prototype.serializeParams = function () { return new Float32Array(this.getParamList() .map(function (_a) { var tensor = _a.tensor; return Array.from(tensor.dataSync()); }) .reduce(function (flat, arr) { return flat.concat(arr); })); }; NeuralNetwork.prototype.load = function (weightsOrUrl) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (weightsOrUrl instanceof Float32Array) { this.extractWeights(weightsOrUrl); return [2 /*return*/]; } return [4 /*yield*/, this.loadFromUri(weightsOrUrl)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; NeuralNetwork.prototype.loadFromUri = function (uri) { return __awaiter(this, void 0, void 0, function () { var weightMap; return __generator(this, function (_a) { switch (_a.label) { case 0: if (uri && typeof uri !== 'string') { throw new Error(this._name + ".loadFromUri - expected model uri"); } return [4 /*yield*/, loadWeightMap(uri, this.getDefaultModelName())]; case 1: weightMap = _a.sent(); this.loadFromWeightMap(weightMap); return [2 /*return*/]; } }); }); }; NeuralNetwork.prototype.loadFromDisk = function (filePath) { return __awaiter(this, void 0, void 0, function () { var readFile, _a, manifestUri, modelBaseUri, fetchWeightsFromDisk, loadWeights, manifest, _b, _c, weightMap; return __generator(this, function (_d) { switch (_d.label) { case 0: if (filePath && typeof filePath !== 'string') { throw new Error(this._name + ".loadFromDisk - expected model file path"); } readFile = env.getEnv().readFile; _a = getModelUris(filePath, this.getDefaultModelName()), manifestUri = _a.manifestUri, modelBaseUri = _a.modelBaseUri; fetchWeightsFromDisk = function (filePaths) { return Promise.all(filePaths.map(function (filePath) { return readFile(filePath).then(function (buf) { return buf.buffer; }); })); }; loadWeights = Rh.weightsLoaderFactory(fetchWeightsFromDisk); _c = (_b = JSON).parse; return [4 /*yield*/, readFile(manifestUri)]; case 1: manifest = _c.apply(_b, [(_d.sent()).toString()]); return [4 /*yield*/, loadWeights(manifest, modelBaseUri)]; case 2: weightMap = _d.sent(); this.loadFromWeightMap(weightMap); return [2 /*return*/]; } }); }); }; NeuralNetwork.prototype.loadFromWeightMap = function (weightMap) { var _a = this.extractParamsFromWeigthMap(weightMap), paramMappings = _a.paramMappings, params = _a.params; this._paramMappings = paramMappings; this._params = params; }; NeuralNetwork.prototype.extractWeights = function (weights) { var _a = this.extractParams(weights), paramMappings = _a.paramMappings, params = _a.params; this._paramMappings = paramMappings; this._params = params; }; NeuralNetwork.prototype.traversePropertyPath = function (paramPath) { if (!this.params) { throw new Error("traversePropertyPath - model has no loaded params"); } var result = paramPath.split('/').reduce(function (res, objProp) { if (!res.nextObj.hasOwnProperty(objProp)) { throw new Error("traversePropertyPath - object does not have property " + objProp + ", for path " + paramPath); } return { obj: res.nextObj, objProp: objProp, nextObj: res.nextObj[objProp] }; }, { nextObj: this.params }); var obj = result.obj, objProp = result.objProp; if (!obj || !objProp || !(obj[objProp] instanceof ht)) { throw new Error("traversePropertyPath - parameter is not a tensor, for path " + paramPath); } return { obj: obj, objProp: objProp }; }; return NeuralNetwork; }()); function iou(box1, box2, isIOU) { if (isIOU === void 0) { isIOU = true; } var width = Math.max(0.0, Math.min(box1.right, box2.right) - Math.max(box1.left, box2.left)); var height = Math.max(0.0, Math.min(box1.bottom, box2.bottom) - Math.max(box1.top, box2.top)); var interSection = width * height; return isIOU ? interSection / (box1.area + box2.area - interSection) : interSection / Math.min(box1.area, box2.area); } function minBbox(pts) { var xs = pts.map(function (pt) { return pt.x; }); var ys = pts.map(function (pt) { return pt.y; }); var minX = xs.reduce(function (min, x) { return x < min ? x : min; }, Infinity); var minY = ys.reduce(function (min, y) { return y < min ? y : min; }, Infinity); var maxX = xs.reduce(function (max, x) { return max < x ? x : max; }, 0); var maxY = ys.reduce(function (max, y) { return max < y ? y : max; }, 0); return new BoundingBox(minX, minY, maxX, maxY); } function nonMaxSuppression(boxes, scores, iouThreshold, isIOU) { if (isIOU === void 0) { isIOU = true; } var indicesSortedByScore = scores .map(function (score, boxIndex) { return ({ score: score, boxIndex: boxIndex }); }) .sort(function (c1, c2) { return c1.score - c2.score; }) .map(function (c) { return c.boxIndex; }); var pick = []; var _loop_1 = function () { var curr = indicesSortedByScore.pop(); pick.push(curr); var indices = indicesSortedByScore; var outputs = []; for (var i = 0; i < indices.length; i++) { var idx = indices[i]; var currBox = boxes[curr]; var idxBox = boxes[idx]; outputs.push(iou(currBox, idxBox, isIOU)); } indicesSortedByScore = indicesSortedByScore.filter(function (_, j) { return outputs[j] <= iouThreshold; }); }; while (indicesSortedByScore.length > 0) { _loop_1(); } return pick; } function normalize(x, meanRgb) { return Fe(function () { var r = meanRgb[0], g = meanRgb[1], b = meanRgb[2]; var avg_r = Rn(x.shape.slice(0, 3).concat([1]), r); var avg_g = Rn(x.shape.slice(0, 3).concat([1]), g); var avg_b = Rn(x.shape.slice(0, 3).concat([1]), b); var avg_rgb = An([avg_r, avg_g, avg_b], 3); return vl(x, avg_rgb); }); } function shuffleArray(inputArray) { var array = inputArray.slice(); for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var x = array[i]; array[i] = array[j]; array[j] = x; } return array; } function sigmoid(x) { return 1 / (1 + Math.exp(-x)); } function inverseSigmoid(x) { return Math.log(x / (1 - x)); } var isNumber = function (arg) { return typeof arg === 'number'; }; function validateConfig(config) { if (!config) { throw new Error("invalid config: " + config); } if (typeof config.withSeparableConvs !== 'boolean') { throw new Error("config.withSeparableConvs has to be a boolean, have: " + config.withSeparableConvs); } if (!isNumber(config.iouThreshold) || config.iouThreshold < 0 || config.iouThreshold > 1.0) { throw new Error("config.iouThreshold has to be a number between [0, 1], have: " + config.iouThreshold); } if (!Array.isArray(config.classes) || !config.classes.length || !config.classes.every(function (c) { return typeof c === 'string'; })) { throw new Error("config.classes has to be an array class names: string[], have: " + JSON.stringify(config.classes)); } if (!Array.isArray(config.anchors) || !config.anchors.length || !config.anchors.map(function (a) { return a || {}; }).every(function (a) { return isNumber(a.x) && isNumber(a.y); })) { throw new Error("config.anchors has to be an array of { x: number, y: number }, have: " + JSON.stringify(config.anchors)); } if (config.meanRgb && (!Array.isArray(config.meanRgb) || config.meanRgb.length !== 3 || !config.meanRgb.every(isNumber))) { throw new Error("config.meanRgb has to be an array of shape [number, number, number], have: " + JSON.stringify(config.meanRgb)); } } function leaky(x) { return Fe(function () { var min = ll(x, vn(0.10000000149011612)); return Yu(Sl(vl(x, min)), min); //return tf.maximum(x, min) }); } function convWithBatchNorm(x, params) { return Fe(function () { var out = rr(x, [[0, 0], [1, 1], [1, 1], [0, 0]]); out = nu(out, params.conv.filters, [1, 1], 'valid'); out = vl(out, params.bn.sub); out = ll(out, params.bn.truediv); out = Yu(out, params.conv.bias); return leaky(out); }); } function depthwiseSeparableConv(x, params) { return Fe(function () { var out = rr(x, [[0, 0], [1, 1], [1, 1], [0, 0]]); out = iu(out, params.depthwise_filter, params.pointwise_filter, [1, 1], 'valid'); out = Yu(out, params.bias); return leaky(out); }); } function extractorsFactory(extractWeights, paramMappings) { var extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); function extractBatchNormParams(size, mappedPrefix) { var sub = mn(extractWeights(size)); var truediv = mn(extractWeights(size)); paramMappings.push({ paramPath: mappedPrefix + "/sub" }, { paramPath: mappedPrefix + "/truediv" }); return { sub: sub, truediv: truediv }; } function extractConvWithBatchNormParams(channelsIn, channelsOut, mappedPrefix) { var conv = extractConvParams(channelsIn, channelsOut, 3, mappedPrefix + "/conv"); var bn = extractBatchNormParams(channelsOut, mappedPrefix + "/bn"); return { conv: conv, bn: bn }; } var extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); return { extractConvParams: extractConvParams, extractConvWithBatchNormParams: extractConvWithBatchNormParams, extractSeparableConvParams: extractSeparableConvParams }; } function extractParams(weights, config, boxEncodingSize, filterSizes) { var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var paramMappings = []; var _b = extractorsFactory(extractWeights, paramMappings), extractConvParams = _b.extractConvParams, extractConvWithBatchNormParams = _b.extractConvWithBatchNormParams, extractSeparableConvParams = _b.extractSeparableConvParams; var params; if (config.withSeparableConvs) { var s0 = filterSizes[0], s1 = filterSizes[1], s2 = filterSizes[2], s3 = filterSizes[3], s4 = filterSizes[4], s5 = filterSizes[5], s6 = filterSizes[6], s7 = filterSizes[7], s8 = filterSizes[8]; var conv0 = config.isFirstLayerConv2d ? extractConvParams(s0, s1, 3, 'conv0') : extractSeparableConvParams(s0, s1, 'conv0'); var conv1 = extractSeparableConvParams(s1, s2, 'conv1'); var conv2 = extractSeparableConvParams(s2, s3, 'conv2'); var conv3 = extractSeparableConvParams(s3, s4, 'conv3'); var conv4 = extractSeparableConvParams(s4, s5, 'conv4'); var conv5 = extractSeparableConvParams(s5, s6, 'conv5'); var conv6 = s7 ? extractSeparableConvParams(s6, s7, 'conv6') : undefined; var conv7 = s8 ? extractSeparableConvParams(s7, s8, 'conv7') : undefined; var conv8 = extractConvParams(s8 || s7 || s6, 5 * boxEncodingSize, 1, 'conv8'); params = { conv0: conv0, conv1: conv1, conv2: conv2, conv3: conv3, conv4: conv4, conv5: conv5, conv6: conv6, conv7: conv7, conv8: conv8 }; } else { var s0 = filterSizes[0], s1 = filterSizes[1], s2 = filterSizes[2], s3 = filterSizes[3], s4 = filterSizes[4], s5 = filterSizes[5], s6 = filterSizes[6], s7 = filterSizes[7], s8 = filterSizes[8]; var conv0 = extractConvWithBatchNormParams(s0, s1, 'conv0'); var conv1 = extractConvWithBatchNormParams(s1, s2, 'conv1'); var conv2 = extractConvWithBatchNormParams(s2, s3, 'conv2'); var conv3 = extractConvWithBatchNormParams(s3, s4, 'conv3'); var conv4 = extractConvWithBatchNormParams(s4, s5, 'conv4'); var conv5 = extractConvWithBatchNormParams(s5, s6, 'conv5'); var conv6 = extractConvWithBatchNormParams(s6, s7, 'conv6'); var conv7 = extractConvWithBatchNormParams(s7, s8, 'conv7'); var conv8 = extractConvParams(s8, 5 * boxEncodingSize, 1, 'conv8'); params = { conv0: conv0, conv1: conv1, conv2: conv2, conv3: conv3, conv4: conv4, conv5: conv5, conv6: conv6, conv7: conv7, conv8: conv8 }; } if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { params: params, paramMappings: paramMappings }; } function extractorsFactory$1(weightMap, paramMappings) { var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); function extractBatchNormParams(prefix) { var sub = extractWeightEntry(prefix + "/sub", 1); var truediv = extractWeightEntry(prefix + "/truediv", 1); return { sub: sub, truediv: truediv }; } function extractConvParams(prefix) { var filters = extractWeightEntry(prefix + "/filters", 4); var bias = extractWeightEntry(prefix + "/bias", 1); return { filters: filters, bias: bias }; } function extractConvWithBatchNormParams(prefix) { var conv = extractConvParams(prefix + "/conv"); var bn = extractBatchNormParams(prefix + "/bn"); return { conv: conv, bn: bn }; } var extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); return { extractConvParams: extractConvParams, extractConvWithBatchNormParams: extractConvWithBatchNormParams, extractSeparableConvParams: extractSeparableConvParams }; } function extractParamsFromWeigthMap(weightMap, config) { var paramMappings = []; var _a = extractorsFactory$1(weightMap, paramMappings), extractConvParams = _a.extractConvParams, extractConvWithBatchNormParams = _a.extractConvWithBatchNormParams, extractSeparableConvParams = _a.extractSeparableConvParams; var params; if (config.withSeparableConvs) { var numFilters = (config.filterSizes && config.filterSizes.length || 9); params = { conv0: config.isFirstLayerConv2d ? extractConvParams('conv0') : extractSeparableConvParams('conv0'), conv1: extractSeparableConvParams('conv1'), conv2: extractSeparableConvParams('conv2'), conv3: extractSeparableConvParams('conv3'), conv4: extractSeparableConvParams('conv4'), conv5: extractSeparableConvParams('conv5'), conv6: numFilters > 7 ? extractSeparableConvParams('conv6') : undefined, conv7: numFilters > 8 ? extractSeparableConvParams('conv7') : undefined, conv8: extractConvParams('conv8') }; } else { params = { conv0: extractConvWithBatchNormParams('conv0'), conv1: extractConvWithBatchNormParams('conv1'), conv2: extractConvWithBatchNormParams('conv2'), conv3: extractConvWithBatchNormParams('conv3'), conv4: extractConvWithBatchNormParams('conv4'), conv5: extractConvWithBatchNormParams('conv5'), conv6: extractConvWithBatchNormParams('conv6'), conv7: extractConvWithBatchNormParams('conv7'), conv8: extractConvParams('conv8') }; } disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } var TinyYolov2SizeType; (function (TinyYolov2SizeType) { TinyYolov2SizeType[TinyYolov2SizeType["XS"] = 224] = "XS"; TinyYolov2SizeType[TinyYolov2SizeType["SM"] = 320] = "SM"; TinyYolov2SizeType[TinyYolov2SizeType["MD"] = 416] = "MD"; TinyYolov2SizeType[TinyYolov2SizeType["LG"] = 608] = "LG"; })(TinyYolov2SizeType || (TinyYolov2SizeType = {})); var TinyYolov2Options = /** @class */ (function () { function TinyYolov2Options(_a) { var _b = _a === void 0 ? {} : _a, inputSize = _b.inputSize, scoreThreshold = _b.scoreThreshold; this._name = 'TinyYolov2Options'; this._inputSize = inputSize || 416; this._scoreThreshold = scoreThreshold || 0.5; if (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"); } } Object.defineProperty(TinyYolov2Options.prototype, "inputSize", { get: function () { return this._inputSize; }, enumerable: true, configurable: true }); Object.defineProperty(TinyYolov2Options.prototype, "scoreThreshold", { get: function () { return this._scoreThreshold; }, enumerable: true, configurable: true }); return TinyYolov2Options; }()); var TinyYolov2 = /** @class */ (function (_super) { __extends(TinyYolov2, _super); function TinyYolov2(config) { var _this = _super.call(this, 'TinyYolov2') || this; validateConfig(config); _this._config = config; return _this; } Object.defineProperty(TinyYolov2.prototype, "config", { get: function () { return this._config; }, enumerable: true, configurable: true }); Object.defineProperty(TinyYolov2.prototype, "withClassScores", { get: function () { return this.config.withClassScores || this.config.classes.length > 1; }, enumerable: true, configurable: true }); Object.defineProperty(TinyYolov2.prototype, "boxEncodingSize", { get: function () { return 5 + (this.withClassScores ? this.config.classes.length : 0); }, enumerable: true, configurable: true }); TinyYolov2.prototype.runTinyYolov2 = function (x, params) { var out = convWithBatchNorm(x, params.conv0); out = yu(out, [2, 2], [2, 2], 'same'); out = convWithBatchNorm(out, params.conv1); out = yu(out, [2, 2], [2, 2], 'same'); out = convWithBatchNorm(out, params.conv2); out = yu(out, [2, 2], [2, 2], 'same'); out = convWithBatchNorm(out, params.conv3); out = yu(out, [2, 2], [2, 2], 'same'); out = convWithBatchNorm(out, params.conv4); out = yu(out, [2, 2], [2, 2], 'same'); out = convWithBatchNorm(out, params.conv5); out = yu(out, [2, 2], [1, 1], 'same'); out = convWithBatchNorm(out, params.conv6); out = convWithBatchNorm(out, params.conv7); return convLayer(out, params.conv8, 'valid', false); }; TinyYolov2.prototype.runMobilenet = function (x, params) { var out = this.config.isFirstLayerConv2d ? leaky(convLayer(x, params.conv0, 'valid', false)) : depthwiseSeparableConv(x, params.conv0); out = yu(out, [2, 2], [2, 2], 'same'); out = depthwiseSeparableConv(out, params.conv1); out = yu(out, [2, 2], [2, 2], 'same'); out = depthwiseSeparableConv(out, params.conv2); out = yu(out, [2, 2], [2, 2], 'same'); out = depthwiseSeparableConv(out, params.conv3); out = yu(out, [2, 2], [2, 2], 'same'); out = depthwiseSeparableConv(out, params.conv4); out = yu(out, [2, 2], [2, 2], 'same'); out = depthwiseSeparableConv(out, params.conv5); out = yu(out, [2, 2], [1, 1], 'same'); out = params.conv6 ? depthwiseSeparableConv(out, params.conv6) : out; out = params.conv7 ? depthwiseSeparableConv(out, params.conv7) : out; return convLayer(out, params.conv8, 'valid', false); }; TinyYolov2.prototype.forwardInput = function (input, inputSize) { var _this = this; var params = this.params; if (!params) { throw new Error('TinyYolov2 - load model before inference'); } return Fe(function () { var batchTensor = input.toBatchTensor(inputSize, false).toFloat(); batchTensor = _this.config.meanRgb ? normalize(batchTensor, _this.config.meanRgb) : batchTensor; batchTensor = batchTensor.div(vn(256)); return _this.config.withSeparableConvs ? _this.runMobilenet(batchTensor, params) : _this.runTinyYolov2(batchTensor, params); }); }; TinyYolov2.prototype.forward = function (input, inputSize) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [4 /*yield*/, _a.apply(this, [_b.sent(), inputSize])]; case 2: return [2 /*return*/, _b.sent()]; } }); }); }; TinyYolov2.prototype.detect = function (input, forwardParams) { if (forwardParams === void 0) { forwardParams = {}; } return __awaiter(this, void 0, void 0, function () { var _a, inputSize, scoreThreshold, netInput, out, out0, inputDimensions, results, boxes, scores, classScores, classNames, indices, detections; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = new TinyYolov2Options(forwardParams), inputSize = _a.inputSize, scoreThreshold = _a.scoreThreshold; return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _b.sent(); return [4 /*yield*/, this.forwardInput(netInput, inputSize)]; case 2: out = _b.sent(); out0 = Fe(function () { return gr(out)[0].expandDims(); }); inputDimensions = { width: netInput.getInputWidth(0), height: netInput.getInputHeight(0) }; return [4 /*yield*/, this.extractBoxes(out0, netInput.getReshapedInputDimensions(0), scoreThreshold)]; case 3: results = _b.sent(); out.dispose(); out0.dispose(); boxes = results.map(function (res) { return res.box; }); scores = results.map(function (res) { return res.score; }); classScores = results.map(function (res) { return res.classScore; }); classNames = results.map(function (res) { return _this.config.classes[res.label]; }); indices = nonMaxSuppression(boxes.map(function (box) { return box.rescale(inputSize); }), scores, this.config.iouThreshold, true); detections = indices.map(function (idx) { return new ObjectDetection(scores[idx], classScores[idx], classNames[idx], boxes[idx], inputDimensions); }); return [2 /*return*/, detections]; } }); }); }; TinyYolov2.prototype.getDefaultModelName = function () { return ''; }; TinyYolov2.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMap(weightMap, this.config); }; TinyYolov2.prototype.extractParams = function (weights) { var filterSizes = this.config.filterSizes || TinyYolov2.DEFAULT_FILTER_SIZES; var numFilters = filterSizes ? filterSizes.length : undefined; if (numFilters !== 7 && numFilters !== 8 && numFilters !== 9) { throw new Error("TinyYolov2 - expected 7 | 8 | 9 convolutional filters, but found " + numFilters + " filterSizes in config"); } return extractParams(weights, this.config, this.boxEncodingSize, filterSizes); }; TinyYolov2.prototype.extractBoxes = function (outputTensor, inputBlobDimensions, scoreThreshold) { return __awaiter(this, void 0, void 0, function () { var width, height, inputSize, correctionFactorX, correctionFactorY, numCells, numBoxes, _a, boxesTensor, scoresTensor, classScoresTensor, results, scoresData, boxesData, row, col, anchor, score, ctX, ctY, width_1, height_1, x, y, pos, _b, classScore, label, _c; var _this = this; return __generator(this, function (_d) { switch (_d.label) { case 0: width = inputBlobDimensions.width, height = inputBlobDimensions.height; inputSize = Math.max(width, height); correctionFactorX = inputSize / width; correctionFactorY = inputSize / height; numCells = outputTensor.shape[1]; numBoxes = this.config.anchors.length; _a = Fe(function () { var reshaped = outputTensor.reshape([numCells, numCells, numBoxes, _this.boxEncodingSize]); var boxes = reshaped.slice([0, 0, 0, 0], [numCells, numCells, numBoxes, 4]); var scores = reshaped.slice([0, 0, 0, 4], [numCells, numCells, numBoxes, 1]); var classScores = _this.withClassScores ? zr(reshaped.slice([0, 0, 0, 5], [numCells, numCells, numBoxes, _this.config.classes.length]), 3) : vn(0); return [boxes, scores, classScores]; }), boxesTensor = _a[0], scoresTensor = _a[1], classScoresTensor = _a[2]; results = []; return [4 /*yield*/, scoresTensor.array()]; case 1: scoresData = _d.sent(); return [4 /*yield*/, boxesTensor.array()]; case 2: boxesData = _d.sent(); row = 0; _d.label = 3; case 3: if (!(row < numCells)) return [3 /*break*/, 12]; col = 0; _d.label = 4; case 4: if (!(col < numCells)) return [3 /*break*/, 11]; anchor = 0; _d.label = 5; case 5: if (!(anchor < numBoxes)) return [3 /*break*/, 10]; score = sigmoid(scoresData[row][col][anchor][0]); if (!(!scoreThreshold || score > scoreThreshold)) return [3 /*break*/, 9]; ctX = ((col + sigmoid(boxesData[row][col][anchor][0])) / numCells) * correctionFactorX; ctY = ((row + sigmoid(boxesData[row][col][anchor][1])) / numCells) * correctionFactorY; width_1 = ((Math.exp(boxesData[row][col][anchor][2]) * this.config.anchors[anchor].x) / numCells) * correctionFactorX; height_1 = ((Math.exp(boxesData[row][col][anchor][3]) * this.config.anchors[anchor].y) / numCells) * correctionFactorY; x = (ctX - (width_1 / 2)); y = (ctY - (height_1 / 2)); pos = { row: row, col: col, anchor: anchor }; if (!this.withClassScores) return [3 /*break*/, 7]; return [4 /*yield*/, this.extractPredictedClass(classScoresTensor, pos)]; case 6: _c = _d.sent(); return [3 /*break*/, 8]; case 7: _c = { classScore: 1, label: 0 }; _d.label = 8; case 8: _b = _c, classScore = _b.classScore, label = _b.label; results.push(__assign({ box: new BoundingBox(x, y, x + width_1, y + height_1), score: score, classScore: score * classScore, label: label }, pos)); _d.label = 9; case 9: anchor++; return [3 /*break*/, 5]; case 10: col++; return [3 /*break*/, 4]; case 11: row++; return [3 /*break*/, 3]; case 12: boxesTensor.dispose(); scoresTensor.dispose(); classScoresTensor.dispose(); return [2 /*return*/, results]; } }); }); }; TinyYolov2.prototype.extractPredictedClass = function (classesTensor, pos) { return __awaiter(this, void 0, void 0, function () { var row, col, anchor, classesData; return __generator(this, function (_a) { switch (_a.label) { case 0: row = pos.row, col = pos.col, anchor = pos.anchor; return [4 /*yield*/, classesTensor.array()]; case 1: classesData = _a.sent(); return [2 /*return*/, Array(this.config.classes.length).fill(0) .map(function (_, i) { return classesData[row][col][anchor][i]; }) .map(function (classScore, label) { return ({ classScore: classScore, label: label }); }) .reduce(function (max, curr) { return max.classScore > curr.classScore ? max : curr; })]; } }); }); }; TinyYolov2.DEFAULT_FILTER_SIZES = [ 3, 16, 32, 64, 128, 256, 512, 1024, 1024 ]; return TinyYolov2; }(NeuralNetwork)); var tfjsImageRecognitionBase = /*#__PURE__*/Object.freeze({ convLayer: convLayer, disposeUnusedWeightTensors: disposeUnusedWeightTensors, extractConvParamsFactory: extractConvParamsFactory, extractFCParamsFactory: extractFCParamsFactory, extractSeparableConvParamsFactory: extractSeparableConvParamsFactory, loadSeparableConvParamsFactory: loadSeparableConvParamsFactory, extractWeightEntryFactory: extractWeightEntryFactory, extractWeightsFactory: extractWeightsFactory, getModelUris: getModelUris, SeparableConvParams: SeparableConvParams, TinyYolov2: TinyYolov2, get TinyYolov2SizeType () { return TinyYolov2SizeType; }, TinyYolov2Options: TinyYolov2Options, validateConfig: validateConfig }); function drawContour(ctx, points, isClosed) { if (isClosed === void 0) { isClosed = false; } ctx.beginPath(); points.slice(1).forEach(function (_a, prevIdx) { var x = _a.x, y = _a.y; var from = points[prevIdx]; ctx.moveTo(from.x, from.y); ctx.lineTo(x, y); }); if (isClosed) { var from = points[points.length - 1]; var to = points[0]; if (!from || !to) { return; } ctx.moveTo(from.x, from.y); ctx.lineTo(to.x, to.y); } ctx.stroke(); } var FaceDetection = /** @class */ (function (_super) { __extends(FaceDetection, _super); function FaceDetection(score, relativeBox, imageDims) { return _super.call(this, score, score, '', relativeBox, imageDims) || this; } FaceDetection.prototype.forSize = function (width, height) { var _a = _super.prototype.forSize.call(this, width, height), score = _a.score, relativeBox = _a.relativeBox, imageDims = _a.imageDims; return new FaceDetection(score, relativeBox, imageDims); }; return FaceDetection; }(ObjectDetection)); function isWithFaceDetection(obj) { return obj['detection'] instanceof FaceDetection; } function extendWithFaceDetection(sourceObj, detection) { var extension = { detection: detection }; return Object.assign({}, sourceObj, extension); } function drawDetections(canvasArg, detections) { var detectionsArray = Array.isArray(detections) ? detections : [detections]; detectionsArray.forEach(function (det) { var score = det instanceof FaceDetection ? det.score : (isWithFaceDetection(det) ? det.detection.score : undefined); var box = det instanceof FaceDetection ? det.box : (isWithFaceDetection(det) ? det.detection.box : new Box(det)); var label = score ? "" + round(score) : undefined; new DrawBox(box, { label: label }).draw(canvasArg); }); } function depthwiseSeparableConv$1(x, params, stride) { return Fe(function () { var out = iu(x, params.depthwise_filter, params.pointwise_filter, stride, 'same'); out = Yu(out, params.bias); return out; }); } function denseBlock3(x, denseBlockParams, isFirstLayer) { if (isFirstLayer === void 0) { isFirstLayer = false; } return Fe(function () { var out1 = Sl(isFirstLayer ? Yu(nu(x, denseBlockParams.conv0.filters, [2, 2], 'same'), denseBlockParams.conv0.bias) : depthwiseSeparableConv$1(x, denseBlockParams.conv0, [2, 2])); var out2 = depthwiseSeparableConv$1(out1, denseBlockParams.conv1, [1, 1]); var in3 = Sl(Yu(out1, out2)); var out3 = depthwiseSeparableConv$1(in3, denseBlockParams.conv2, [1, 1]); return Sl(Yu(out1, Yu(out2, out3))); }); } function denseBlock4(x, denseBlockParams, isFirstLayer, isScaleDown) { if (isFirstLayer === void 0) { isFirstLayer = false; } if (isScaleDown === void 0) { isScaleDown = true; } return Fe(function () { var out1 = Sl(isFirstLayer ? Yu(nu(x, denseBlockParams.conv0.filters, isScaleDown ? [2, 2] : [1, 1], 'same'), denseBlockParams.conv0.bias) : depthwiseSeparableConv$1(x, denseBlockParams.conv0, isScaleDown ? [2, 2] : [1, 1])); var out2 = depthwiseSeparableConv$1(out1, denseBlockParams.conv1, [1, 1]); var in3 = Sl(Yu(out1, out2)); var out3 = depthwiseSeparableConv$1(in3, denseBlockParams.conv2, [1, 1]); var in4 = Sl(Yu(out1, Yu(out2, out3))); var out4 = depthwiseSeparableConv$1(in4, denseBlockParams.conv3, [1, 1]); return Sl(Yu(out1, Yu(out2, Yu(out3, out4)))); }); } function extractorsFactory$2(extractWeights, paramMappings) { var extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); var extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); function extractDenseBlock3Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer) { if (isFirstLayer === void 0) { isFirstLayer = false; } var conv0 = isFirstLayer ? extractConvParams(channelsIn, channelsOut, 3, mappedPrefix + "/conv0") : extractSeparableConvParams(channelsIn, channelsOut, mappedPrefix + "/conv0"); var conv1 = extractSeparableConvParams(channelsOut, channelsOut, mappedPrefix + "/conv1"); var conv2 = extractSeparableConvParams(channelsOut, channelsOut, mappedPrefix + "/conv2"); return { conv0: conv0, conv1: conv1, conv2: conv2 }; } function extractDenseBlock4Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer) { if (isFirstLayer === void 0) { isFirstLayer = false; } var _a = extractDenseBlock3Params(channelsIn, channelsOut, mappedPrefix, isFirstLayer), conv0 = _a.conv0, conv1 = _a.conv1, conv2 = _a.conv2; var conv3 = extractSeparableConvParams(channelsOut, channelsOut, mappedPrefix + "/conv3"); return { conv0: conv0, conv1: conv1, conv2: conv2, conv3: conv3 }; } return { extractDenseBlock3Params: extractDenseBlock3Params, extractDenseBlock4Params: extractDenseBlock4Params }; } function extractParams$1(weights) { var paramMappings = []; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var extractDenseBlock4Params = extractorsFactory$2(extractWeights, paramMappings).extractDenseBlock4Params; var dense0 = extractDenseBlock4Params(3, 32, 'dense0', true); var dense1 = extractDenseBlock4Params(32, 64, 'dense1'); var dense2 = extractDenseBlock4Params(64, 128, 'dense2'); var dense3 = extractDenseBlock4Params(128, 256, 'dense3'); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { paramMappings: paramMappings, params: { dense0: dense0, dense1: dense1, dense2: dense2, dense3: dense3 } }; } function loadConvParamsFactory(extractWeightEntry) { return function (prefix) { var filters = extractWeightEntry(prefix + "/filters", 4); var bias = extractWeightEntry(prefix + "/bias", 1); return { filters: filters, bias: bias }; }; } function loadParamsFactory(weightMap, paramMappings) { var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); var extractConvParams = loadConvParamsFactory(extractWeightEntry); var extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); function extractDenseBlock3Params(prefix, isFirstLayer) { if (isFirstLayer === void 0) { isFirstLayer = false; } var conv0 = isFirstLayer ? extractConvParams(prefix + "/conv0") : extractSeparableConvParams(prefix + "/conv0"); var conv1 = extractSeparableConvParams(prefix + "/conv1"); var conv2 = extractSeparableConvParams(prefix + "/conv2"); return { conv0: conv0, conv1: conv1, conv2: conv2 }; } function extractDenseBlock4Params(prefix, isFirstLayer) { if (isFirstLayer === void 0) { isFirstLayer = false; } var conv0 = isFirstLayer ? extractConvParams(prefix + "/conv0") : extractSeparableConvParams(prefix + "/conv0"); var conv1 = extractSeparableConvParams(prefix + "/conv1"); var conv2 = extractSeparableConvParams(prefix + "/conv2"); var conv3 = extractSeparableConvParams(prefix + "/conv3"); return { conv0: conv0, conv1: conv1, conv2: conv2, conv3: conv3 }; } return { extractDenseBlock3Params: extractDenseBlock3Params, extractDenseBlock4Params: extractDenseBlock4Params }; } function extractParamsFromWeigthMap$1(weightMap) { var paramMappings = []; var extractDenseBlock4Params = loadParamsFactory(weightMap, paramMappings).extractDenseBlock4Params; var params = { dense0: extractDenseBlock4Params('dense0', true), dense1: extractDenseBlock4Params('dense1'), dense2: extractDenseBlock4Params('dense2'), dense3: extractDenseBlock4Params('dense3') }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } var FaceFeatureExtractor = /** @class */ (function (_super) { __extends(FaceFeatureExtractor, _super); function FaceFeatureExtractor() { return _super.call(this, 'FaceFeatureExtractor') || this; } FaceFeatureExtractor.prototype.forwardInput = function (input) { var params = this.params; if (!params) { throw new Error('FaceFeatureExtractor - load model before inference'); } return Fe(function () { var batchTensor = input.toBatchTensor(112, true); var meanRgb = [122.782, 117.001, 104.298]; var normalized = normalize(batchTensor, meanRgb).div(vn(255)); var out = denseBlock4(normalized, params.dense0, true); out = denseBlock4(out, params.dense1); out = denseBlock4(out, params.dense2); out = denseBlock4(out, params.dense3); out = xu(out, [7, 7], [2, 2], 'valid'); return out; }); }; FaceFeatureExtractor.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; FaceFeatureExtractor.prototype.getDefaultModelName = function () { return 'face_feature_extractor_model'; }; FaceFeatureExtractor.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMap$1(weightMap); }; FaceFeatureExtractor.prototype.extractParams = function (weights) { return extractParams$1(weights); }; return FaceFeatureExtractor; }(NeuralNetwork)); function fullyConnectedLayer(x, params) { return Fe(function () { return Yu(uu(x, params.weights), params.bias); }); } function extractParams$2(weights, channelsIn, channelsOut) { var paramMappings = []; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var extractFCParams = extractFCParamsFactory(extractWeights, paramMappings); var fc = extractFCParams(channelsIn, channelsOut, 'fc'); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { paramMappings: paramMappings, params: { fc: fc } }; } function extractParamsFromWeigthMap$2(weightMap) { var paramMappings = []; var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); function extractFcParams(prefix) { var weights = extractWeightEntry(prefix + "/weights", 2); var bias = extractWeightEntry(prefix + "/bias", 1); return { weights: weights, bias: bias }; } var params = { fc: extractFcParams('fc') }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } function seperateWeightMaps(weightMap) { var featureExtractorMap = {}; var classifierMap = {}; Object.keys(weightMap).forEach(function (key) { var map = key.startsWith('fc') ? classifierMap : featureExtractorMap; map[key] = weightMap[key]; }); return { featureExtractorMap: featureExtractorMap, classifierMap: classifierMap }; } var FaceProcessor = /** @class */ (function (_super) { __extends(FaceProcessor, _super); function FaceProcessor(_name, faceFeatureExtractor) { var _this = _super.call(this, _name) || this; _this._faceFeatureExtractor = faceFeatureExtractor; return _this; } Object.defineProperty(FaceProcessor.prototype, "faceFeatureExtractor", { get: function () { return this._faceFeatureExtractor; }, enumerable: true, configurable: true }); FaceProcessor.prototype.runNet = function (input) { var _this = this; var params = this.params; if (!params) { throw new Error(this._name + " - load model before inference"); } return Fe(function () { var bottleneckFeatures = input instanceof NetInput ? _this.faceFeatureExtractor.forwardInput(input) : input; return fullyConnectedLayer(bottleneckFeatures.as2D(bottleneckFeatures.shape[0], -1), params.fc); }); }; FaceProcessor.prototype.dispose = function (throwOnRedispose) { if (throwOnRedispose === void 0) { throwOnRedispose = true; } this.faceFeatureExtractor.dispose(throwOnRedispose); _super.prototype.dispose.call(this, throwOnRedispose); }; FaceProcessor.prototype.loadClassifierParams = function (weights) { var _a = this.extractClassifierParams(weights), params = _a.params, paramMappings = _a.paramMappings; this._params = params; this._paramMappings = paramMappings; }; FaceProcessor.prototype.extractClassifierParams = function (weights) { return extractParams$2(weights, this.getClassifierChannelsIn(), this.getClassifierChannelsOut()); }; FaceProcessor.prototype.extractParamsFromWeigthMap = function (weightMap) { var _a = seperateWeightMaps(weightMap), featureExtractorMap = _a.featureExtractorMap, classifierMap = _a.classifierMap; this.faceFeatureExtractor.loadFromWeightMap(featureExtractorMap); return extractParamsFromWeigthMap$2(classifierMap); }; FaceProcessor.prototype.extractParams = function (weights) { var cIn = this.getClassifierChannelsIn(); var cOut = this.getClassifierChannelsOut(); var classifierWeightSize = (cOut * cIn) + cOut; var featureExtractorWeights = weights.slice(0, weights.length - classifierWeightSize); var classifierWeights = weights.slice(weights.length - classifierWeightSize); this.faceFeatureExtractor.extractWeights(featureExtractorWeights); return this.extractClassifierParams(classifierWeights); }; return FaceProcessor; }(NeuralNetwork)); var FACE_EXPRESSION_LABELS = ['Neutro', 'Feliz', 'Triste', 'Raiva', 'Medo', 'Nojo', 'Surpreso']; var FaceExpressions = /** @class */ (function () { function FaceExpressions(probabilities) { var _this = this; if (probabilities.length !== 7) { throw new Error("FaceExpressions.constructor - expected probabilities.length to be 7, have: " + probabilities.length); } FACE_EXPRESSION_LABELS.forEach(function (expression, idx) { _this[expression] = probabilities[idx]; }); } FaceExpressions.prototype.asSortedArray = function () { var _this = this; return FACE_EXPRESSION_LABELS .map(function (expression) { return ({ expression: expression, probability: _this[expression] }); }) .sort(function (e0, e1) { return e1.probability - e0.probability; }); }; return FaceExpressions; }()); var FaceExpressionNet = /** @class */ (function (_super) { __extends(FaceExpressionNet, _super); function FaceExpressionNet(faceFeatureExtractor) { if (faceFeatureExtractor === void 0) { faceFeatureExtractor = new FaceFeatureExtractor(); } return _super.call(this, 'FaceExpressionNet', faceFeatureExtractor) || this; } FaceExpressionNet.prototype.forwardInput = function (input) { var _this = this; return Fe(function () { return zr(_this.runNet(input)); }); }; FaceExpressionNet.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; FaceExpressionNet.prototype.predictExpressions = function (input) { return __awaiter(this, void 0, void 0, function () { var netInput, out, probabilitesByBatch, predictionsByBatch; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _a.sent(); return [4 /*yield*/, this.forwardInput(netInput)]; case 2: out = _a.sent(); return [4 /*yield*/, Promise.all(gr(out).map(function (t) { return __awaiter(_this, void 0, void 0, function () { var data; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, t.data()]; case 1: data = _a.sent(); t.dispose(); return [2 /*return*/, data]; } }); }); }))]; case 3: probabilitesByBatch = _a.sent(); out.dispose(); predictionsByBatch = probabilitesByBatch .map(function (probabilites) { return new FaceExpressions(probabilites); }); return [2 /*return*/, netInput.isBatchInput ? predictionsByBatch : predictionsByBatch[0]]; } }); }); }; FaceExpressionNet.prototype.getDefaultModelName = function () { return 'face_expression_model'; }; FaceExpressionNet.prototype.getClassifierChannelsIn = function () { return 256; }; FaceExpressionNet.prototype.getClassifierChannelsOut = function () { return 7; }; return FaceExpressionNet; }(FaceProcessor)); function isWithFaceExpressions(obj) { return obj['expressions'] instanceof FaceExpressions; } function extendWithFaceExpressions(sourceObj, expressions) { var extension = { expressions: expressions }; return Object.assign({}, sourceObj, extension); } function drawFaceExpressions(canvasArg, faceExpressions, minConfidence, textFieldAnchor) { if (minConfidence === void 0) { minConfidence = 0.1; } var faceExpressionsArray = Array.isArray(faceExpressions) ? faceExpressions : [faceExpressions]; faceExpressionsArray.forEach(function (e) { var expr = e instanceof FaceExpressions ? e : (isWithFaceExpressions(e) ? e.expressions : undefined); if (!expr) { throw new Error('drawFaceExpressions - expected faceExpressions to be FaceExpressions | WithFaceExpressions<{}> or array thereof'); } var sorted = expr.asSortedArray(); var resultsToDisplay = sorted.filter(function (expr) { return expr.probability > minConfidence; }); var anchor = isWithFaceDetection(e) ? e.detection.box.bottomLeft : (textFieldAnchor || new Point(0, 0)); var drawTextField = new DrawTextField(resultsToDisplay.map(function (expr) { return expr.expression + " (" + round(expr.probability) + ")"; }), anchor); drawTextField.draw(canvasArg); }); } function minBbox$1(pts) { var xs = pts.map(function (pt) { return pt.x; }); var ys = pts.map(function (pt) { return pt.y; }); var minX = xs.reduce(function (min, x) { return x < min ? x : min; }, Infinity); var minY = ys.reduce(function (min, y) { return y < min ? y : min; }, Infinity); var maxX = xs.reduce(function (max, x) { return max < x ? x : max; }, 0); var maxY = ys.reduce(function (max, y) { return max < y ? y : max; }, 0); return new BoundingBox(minX, minY, maxX, maxY); } // face alignment constants var relX = 0.5; var relY = 0.43; var relScale = 0.45; var FaceLandmarks = /** @class */ (function () { function FaceLandmarks(relativeFaceLandmarkPositions, imgDims, shift) { if (shift === void 0) { shift = new Point(0, 0); } var width = imgDims.width, height = imgDims.height; this._imgDims = new Dimensions(width, height); this._shift = shift; this._positions = relativeFaceLandmarkPositions.map(function (pt) { return pt.mul(new Point(width, height)).add(shift); }); } Object.defineProperty(FaceLandmarks.prototype, "shift", { get: function () { return new Point(this._shift.x, this._shift.y); }, enumerable: true, configurable: true }); Object.defineProperty(FaceLandmarks.prototype, "imageWidth", { get: function () { return this._imgDims.width; }, enumerable: true, configurable: true }); Object.defineProperty(FaceLandmarks.prototype, "imageHeight", { get: function () { return this._imgDims.height; }, enumerable: true, configurable: true }); Object.defineProperty(FaceLandmarks.prototype, "positions", { get: function () { return this._positions; }, enumerable: true, configurable: true }); Object.defineProperty(FaceLandmarks.prototype, "relativePositions", { get: function () { var _this = this; return this._positions.map(function (pt) { return pt.sub(_this._shift).div(new Point(_this.imageWidth, _this.imageHeight)); }); }, enumerable: true, configurable: true }); FaceLandmarks.prototype.forSize = function (width, height) { return new this.constructor(this.relativePositions, { width: width, height: height }); }; FaceLandmarks.prototype.shiftBy = function (x, y) { return new this.constructor(this.relativePositions, this._imgDims, new Point(x, y)); }; FaceLandmarks.prototype.shiftByPoint = function (pt) { return this.shiftBy(pt.x, pt.y); }; /** * Aligns the face landmarks after face detection from the relative positions of the faces * bounding box, or it's current shift. This function should be used to align the face images * after face detection has been performed, before they are passed to the face recognition net. * This will make the computed face descriptor more accurate. * * @param detection (optional) The bounding box of the face or the face detection result. If * no argument was passed the position of the face landmarks are assumed to be relative to * it's current shift. * @returns The bounding box of the aligned face. */ FaceLandmarks.prototype.align = function (detection, options) { if (options === void 0) { options = {}; } if (detection) { var box = detection instanceof FaceDetection ? detection.box.floor() : new Box(detection); return this.shiftBy(box.x, box.y).align(null, options); } var _a = Object.assign({}, { useDlibAlignment: false, minBoxPadding: 0.2 }, options), useDlibAlignment = _a.useDlibAlignment, minBoxPadding = _a.minBoxPadding; if (useDlibAlignment) { return this.alignDlib(); } return this.alignMinBbox(minBoxPadding); }; FaceLandmarks.prototype.alignDlib = function () { var centers = this.getRefPointsForAlignment(); var leftEyeCenter = centers[0], rightEyeCenter = centers[1], mouthCenter = centers[2]; var distToMouth = function (pt) { return mouthCenter.sub(pt).magnitude(); }; var eyeToMouthDist = (distToMouth(leftEyeCenter) + distToMouth(rightEyeCenter)) / 2; var size = Math.floor(eyeToMouthDist / relScale); var refPoint = getCenterPoint(centers); // TODO: pad in case rectangle is out of image bounds var x = Math.floor(Math.max(0, refPoint.x - (relX * size))); var y = Math.floor(Math.max(0, refPoint.y - (relY * size))); return new Rect(x, y, Math.min(size, this.imageWidth + x), Math.min(size, this.imageHeight + y)); }; FaceLandmarks.prototype.alignMinBbox = function (padding) { var box = minBbox$1(this.positions); return box.pad(box.width * padding, box.height * padding); }; FaceLandmarks.prototype.getRefPointsForAlignment = function () { throw new Error('getRefPointsForAlignment not implemented by base class'); }; return FaceLandmarks; }()); var FaceLandmarks68 = /** @class */ (function (_super) { __extends(FaceLandmarks68, _super); function FaceLandmarks68() { return _super !== null && _super.apply(this, arguments) || this; } FaceLandmarks68.prototype.getJawOutline = function () { return this.positions.slice(0, 17); }; FaceLandmarks68.prototype.getLeftEyeBrow = function () { return this.positions.slice(17, 22); }; FaceLandmarks68.prototype.getRightEyeBrow = function () { return this.positions.slice(22, 27); }; FaceLandmarks68.prototype.getNose = function () { return this.positions.slice(27, 36); }; FaceLandmarks68.prototype.getLeftEye = function () { return this.positions.slice(36, 42); }; FaceLandmarks68.prototype.getRightEye = function () { return this.positions.slice(42, 48); }; FaceLandmarks68.prototype.getMouth = function () { return this.positions.slice(48, 68); }; FaceLandmarks68.prototype.getRefPointsForAlignment = function () { return [ this.getLeftEye(), this.getRightEye(), this.getMouth() ].map(getCenterPoint); }; return FaceLandmarks68; }(FaceLandmarks)); function isWithFaceLandmarks(obj) { return isWithFaceDetection(obj) && obj['landmarks'] instanceof FaceLandmarks && obj['unshiftedLandmarks'] instanceof FaceLandmarks && obj['alignedRect'] instanceof FaceDetection; } function extendWithFaceLandmarks(sourceObj, unshiftedLandmarks) { var shift = sourceObj.detection.box; var landmarks = unshiftedLandmarks.shiftBy(shift.x, shift.y); var rect = landmarks.align(); var imageDims = sourceObj.detection.imageDims; var alignedRect = new FaceDetection(sourceObj.detection.score, rect.rescale(imageDims.reverse()), imageDims); var extension = { landmarks: landmarks, unshiftedLandmarks: unshiftedLandmarks, alignedRect: alignedRect }; return Object.assign({}, sourceObj, extension); } var DrawFaceLandmarksOptions = /** @class */ (function () { function DrawFaceLandmarksOptions(options) { if (options === void 0) { options = {}; } var _a = options.drawLines, drawLines = _a === void 0 ? true : _a, _b = options.drawPoints, drawPoints = _b === void 0 ? true : _b, lineWidth = options.lineWidth, lineColor = options.lineColor, pointSize = options.pointSize, pointColor = options.pointColor; this.drawLines = drawLines; this.drawPoints = drawPoints; this.lineWidth = lineWidth || 1; this.pointSize = pointSize || 2; this.lineColor = lineColor || 'rgba(0, 255, 255, 1)'; this.pointColor = pointColor || 'rgba(255, 0, 255, 1)'; } return DrawFaceLandmarksOptions; }()); var DrawFaceLandmarks = /** @class */ (function () { function DrawFaceLandmarks(faceLandmarks, options) { if (options === void 0) { options = {}; } this.faceLandmarks = faceLandmarks; this.options = new DrawFaceLandmarksOptions(options); } DrawFaceLandmarks.prototype.draw = function (canvasArg) { var ctx = getContext2dOrThrow(canvasArg); var _a = this.options, drawLines = _a.drawLines, drawPoints = _a.drawPoints, lineWidth = _a.lineWidth, lineColor = _a.lineColor, pointSize = _a.pointSize, pointColor = _a.pointColor; if (drawLines && this.faceLandmarks instanceof FaceLandmarks68) { ctx.strokeStyle = lineColor; ctx.lineWidth = lineWidth; drawContour(ctx, this.faceLandmarks.getJawOutline()); drawContour(ctx, this.faceLandmarks.getLeftEyeBrow()); drawContour(ctx, this.faceLandmarks.getRightEyeBrow()); drawContour(ctx, this.faceLandmarks.getNose()); drawContour(ctx, this.faceLandmarks.getLeftEye(), true); drawContour(ctx, this.faceLandmarks.getRightEye(), true); drawContour(ctx, this.faceLandmarks.getMouth(), true); } if (drawPoints) { ctx.strokeStyle = pointColor; ctx.fillStyle = pointColor; var drawPoint = function (pt) { ctx.beginPath(); ctx.arc(pt.x, pt.y, pointSize, 0, 2 * Math.PI); ctx.fill(); }; this.faceLandmarks.positions.forEach(drawPoint); } }; return DrawFaceLandmarks; }()); function drawFaceLandmarks(canvasArg, faceLandmarks) { var faceLandmarksArray = Array.isArray(faceLandmarks) ? faceLandmarks : [faceLandmarks]; faceLandmarksArray.forEach(function (f) { var landmarks = f instanceof FaceLandmarks ? f : (isWithFaceLandmarks(f) ? f.landmarks : undefined); if (!landmarks) { throw new Error('drawFaceLandmarks - expected faceExpressions to be FaceLandmarks | WithFaceLandmarks> or array thereof'); } new DrawFaceLandmarks(landmarks).draw(canvasArg); }); } var drawExtended = /*#__PURE__*/Object.freeze({ drawContour: drawContour, drawDetections: drawDetections, drawFaceExpressions: drawFaceExpressions, DrawFaceLandmarksOptions: DrawFaceLandmarksOptions, DrawFaceLandmarks: DrawFaceLandmarks, drawFaceLandmarks: drawFaceLandmarks }); function extractorsFactory$3(extractWeights, paramMappings) { var extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); var extractSeparableConvParams = extractSeparableConvParamsFactory(extractWeights, paramMappings); function extractReductionBlockParams(channelsIn, channelsOut, mappedPrefix) { var separable_conv0 = extractSeparableConvParams(channelsIn, channelsOut, mappedPrefix + "/separable_conv0"); var separable_conv1 = extractSeparableConvParams(channelsOut, channelsOut, mappedPrefix + "/separable_conv1"); var expansion_conv = extractConvParams(channelsIn, channelsOut, 1, mappedPrefix + "/expansion_conv"); return { separable_conv0: separable_conv0, separable_conv1: separable_conv1, expansion_conv: expansion_conv }; } function extractMainBlockParams(channels, mappedPrefix) { var separable_conv0 = extractSeparableConvParams(channels, channels, mappedPrefix + "/separable_conv0"); var separable_conv1 = extractSeparableConvParams(channels, channels, mappedPrefix + "/separable_conv1"); var separable_conv2 = extractSeparableConvParams(channels, channels, mappedPrefix + "/separable_conv2"); return { separable_conv0: separable_conv0, separable_conv1: separable_conv1, separable_conv2: separable_conv2 }; } return { extractConvParams: extractConvParams, extractSeparableConvParams: extractSeparableConvParams, extractReductionBlockParams: extractReductionBlockParams, extractMainBlockParams: extractMainBlockParams }; } function extractParams$3(weights, numMainBlocks) { var paramMappings = []; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var _b = extractorsFactory$3(extractWeights, paramMappings), extractConvParams = _b.extractConvParams, extractSeparableConvParams = _b.extractSeparableConvParams, extractReductionBlockParams = _b.extractReductionBlockParams, extractMainBlockParams = _b.extractMainBlockParams; var entry_flow_conv_in = extractConvParams(3, 32, 3, 'entry_flow/conv_in'); var entry_flow_reduction_block_0 = extractReductionBlockParams(32, 64, 'entry_flow/reduction_block_0'); var entry_flow_reduction_block_1 = extractReductionBlockParams(64, 128, 'entry_flow/reduction_block_1'); var entry_flow = { conv_in: entry_flow_conv_in, reduction_block_0: entry_flow_reduction_block_0, reduction_block_1: entry_flow_reduction_block_1 }; var middle_flow = {}; range(numMainBlocks, 0, 1).forEach(function (idx) { middle_flow["main_block_" + idx] = extractMainBlockParams(128, "middle_flow/main_block_" + idx); }); var exit_flow_reduction_block = extractReductionBlockParams(128, 256, 'exit_flow/reduction_block'); var exit_flow_separable_conv = extractSeparableConvParams(256, 512, 'exit_flow/separable_conv'); var exit_flow = { reduction_block: exit_flow_reduction_block, separable_conv: exit_flow_separable_conv }; if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { paramMappings: paramMappings, params: { entry_flow: entry_flow, middle_flow: middle_flow, exit_flow: exit_flow } }; } function loadParamsFactory$1(weightMap, paramMappings) { var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); var extractConvParams = loadConvParamsFactory(extractWeightEntry); var extractSeparableConvParams = loadSeparableConvParamsFactory(extractWeightEntry); function extractReductionBlockParams(mappedPrefix) { var separable_conv0 = extractSeparableConvParams(mappedPrefix + "/separable_conv0"); var separable_conv1 = extractSeparableConvParams(mappedPrefix + "/separable_conv1"); var expansion_conv = extractConvParams(mappedPrefix + "/expansion_conv"); return { separable_conv0: separable_conv0, separable_conv1: separable_conv1, expansion_conv: expansion_conv }; } function extractMainBlockParams(mappedPrefix) { var separable_conv0 = extractSeparableConvParams(mappedPrefix + "/separable_conv0"); var separable_conv1 = extractSeparableConvParams(mappedPrefix + "/separable_conv1"); var separable_conv2 = extractSeparableConvParams(mappedPrefix + "/separable_conv2"); return { separable_conv0: separable_conv0, separable_conv1: separable_conv1, separable_conv2: separable_conv2 }; } return { extractConvParams: extractConvParams, extractSeparableConvParams: extractSeparableConvParams, extractReductionBlockParams: extractReductionBlockParams, extractMainBlockParams: extractMainBlockParams }; } function extractParamsFromWeigthMap$3(weightMap, numMainBlocks) { var paramMappings = []; var _a = loadParamsFactory$1(weightMap, paramMappings), extractConvParams = _a.extractConvParams, extractSeparableConvParams = _a.extractSeparableConvParams, extractReductionBlockParams = _a.extractReductionBlockParams, extractMainBlockParams = _a.extractMainBlockParams; var entry_flow_conv_in = extractConvParams('entry_flow/conv_in'); var entry_flow_reduction_block_0 = extractReductionBlockParams('entry_flow/reduction_block_0'); var entry_flow_reduction_block_1 = extractReductionBlockParams('entry_flow/reduction_block_1'); var entry_flow = { conv_in: entry_flow_conv_in, reduction_block_0: entry_flow_reduction_block_0, reduction_block_1: entry_flow_reduction_block_1 }; var middle_flow = {}; range(numMainBlocks, 0, 1).forEach(function (idx) { middle_flow["main_block_" + idx] = extractMainBlockParams("middle_flow/main_block_" + idx); }); var exit_flow_reduction_block = extractReductionBlockParams('exit_flow/reduction_block'); var exit_flow_separable_conv = extractSeparableConvParams('exit_flow/separable_conv'); var exit_flow = { reduction_block: exit_flow_reduction_block, separable_conv: exit_flow_separable_conv }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: { entry_flow: entry_flow, middle_flow: middle_flow, exit_flow: exit_flow }, paramMappings: paramMappings }; } function conv(x, params, stride) { return Yu(nu(x, params.filters, stride, 'same'), params.bias); } function reductionBlock(x, params, isActivateInput) { if (isActivateInput === void 0) { isActivateInput = true; } var out = isActivateInput ? Sl(x) : x; out = depthwiseSeparableConv$1(out, params.separable_conv0, [1, 1]); out = depthwiseSeparableConv$1(Sl(out), params.separable_conv1, [1, 1]); out = yu(out, [3, 3], [2, 2], 'same'); out = Yu(out, conv(x, params.expansion_conv, [2, 2])); return out; } function mainBlock(x, params) { var out = depthwiseSeparableConv$1(Sl(x), params.separable_conv0, [1, 1]); out = depthwiseSeparableConv$1(Sl(out), params.separable_conv1, [1, 1]); out = depthwiseSeparableConv$1(Sl(out), params.separable_conv2, [1, 1]); out = Yu(out, x); return out; } var TinyXception = /** @class */ (function (_super) { __extends(TinyXception, _super); function TinyXception(numMainBlocks) { var _this = _super.call(this, 'TinyXception') || this; _this._numMainBlocks = numMainBlocks; return _this; } TinyXception.prototype.forwardInput = function (input) { var _this = this; var params = this.params; if (!params) { throw new Error('TinyXception - load model before inference'); } return Fe(function () { var batchTensor = input.toBatchTensor(112, true); var meanRgb = [122.782, 117.001, 104.298]; var normalized = normalize(batchTensor, meanRgb).div(vn(256)); var out = Sl(conv(normalized, params.entry_flow.conv_in, [2, 2])); out = reductionBlock(out, params.entry_flow.reduction_block_0, false); out = reductionBlock(out, params.entry_flow.reduction_block_1); range(_this._numMainBlocks, 0, 1).forEach(function (idx) { out = mainBlock(out, params.middle_flow["main_block_" + idx]); }); out = reductionBlock(out, params.exit_flow.reduction_block); out = Sl(depthwiseSeparableConv$1(out, params.exit_flow.separable_conv, [1, 1])); return out; }); }; TinyXception.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; TinyXception.prototype.getDefaultModelName = function () { return 'tiny_xception_model'; }; TinyXception.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMap$3(weightMap, this._numMainBlocks); }; TinyXception.prototype.extractParams = function (weights) { return extractParams$3(weights, this._numMainBlocks); }; return TinyXception; }(NeuralNetwork)); function extractParams$4(weights) { var paramMappings = []; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var extractFCParams = extractFCParamsFactory(extractWeights, paramMappings); var age = extractFCParams(512, 1, 'fc/age'); var gender = extractFCParams(512, 2, 'fc/gender'); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { paramMappings: paramMappings, params: { fc: { age: age, gender: gender } } }; } function extractParamsFromWeigthMap$4(weightMap) { var paramMappings = []; var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); function extractFcParams(prefix) { var weights = extractWeightEntry(prefix + "/weights", 2); var bias = extractWeightEntry(prefix + "/bias", 1); return { weights: weights, bias: bias }; } var params = { fc: { age: extractFcParams('fc/age'), gender: extractFcParams('fc/gender') } }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } (function (Gender) { Gender["FEMALE"] = "Feminino"; Gender["MALE"] = "Masculino"; })(exports.Gender || (exports.Gender = {})); var AgeGenderNet = /** @class */ (function (_super) { __extends(AgeGenderNet, _super); function AgeGenderNet(faceFeatureExtractor) { if (faceFeatureExtractor === void 0) { faceFeatureExtractor = new TinyXception(2); } var _this = _super.call(this, 'AgeGenderNet') || this; _this._faceFeatureExtractor = faceFeatureExtractor; return _this; } Object.defineProperty(AgeGenderNet.prototype, "faceFeatureExtractor", { get: function () { return this._faceFeatureExtractor; }, enumerable: true, configurable: true }); AgeGenderNet.prototype.runNet = function (input) { var _this = this; var params = this.params; if (!params) { throw new Error(this._name + " - load model before inference"); } return Fe(function () { var bottleneckFeatures = input instanceof NetInput ? _this.faceFeatureExtractor.forwardInput(input) : input; var pooled = xu(bottleneckFeatures, [7, 7], [2, 2], 'valid').as2D(bottleneckFeatures.shape[0], -1); var age = fullyConnectedLayer(pooled, params.fc.age).as1D(); var gender = fullyConnectedLayer(pooled, params.fc.gender); return { age: age, gender: gender }; }); }; AgeGenderNet.prototype.forwardInput = function (input) { var _this = this; return Fe(function () { var _a = _this.runNet(input), age = _a.age, gender = _a.gender; return { age: age, gender: zr(gender) }; }); }; AgeGenderNet.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; AgeGenderNet.prototype.predictAgeAndGender = function (input) { return __awaiter(this, void 0, void 0, function () { var netInput, out, ages, genders, ageAndGenderTensors, predictionsByBatch; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _a.sent(); return [4 /*yield*/, this.forwardInput(netInput)]; case 2: out = _a.sent(); ages = gr(out.age); genders = gr(out.gender); ageAndGenderTensors = ages.map(function (ageTensor, i) { return ({ ageTensor: ageTensor, genderTensor: genders[i] }); }); return [4 /*yield*/, Promise.all(ageAndGenderTensors.map(function (_a) { var ageTensor = _a.ageTensor, genderTensor = _a.genderTensor; return __awaiter(_this, void 0, void 0, function () { var age, probMale, isMale, gender, genderProbability; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, ageTensor.data()]; case 1: age = (_b.sent())[0]; return [4 /*yield*/, genderTensor.data()]; case 2: probMale = (_b.sent())[0]; isMale = probMale > 0.5; gender = isMale ? exports.Gender.MALE : exports.Gender.FEMALE; genderProbability = isMale ? probMale : (1 - probMale); ageTensor.dispose(); genderTensor.dispose(); return [2 /*return*/, { age: age, gender: gender, genderProbability: genderProbability ,probMale:probMale}]; } }); }); }))]; case 3: predictionsByBatch = _a.sent(); out.age.dispose(); out.gender.dispose(); return [2 /*return*/, netInput.isBatchInput ? predictionsByBatch : predictionsByBatch[0]]; } }); }); }; AgeGenderNet.prototype.getDefaultModelName = function () { return 'age_gender_model'; }; AgeGenderNet.prototype.dispose = function (throwOnRedispose) { if (throwOnRedispose === void 0) { throwOnRedispose = true; } this.faceFeatureExtractor.dispose(throwOnRedispose); _super.prototype.dispose.call(this, throwOnRedispose); }; AgeGenderNet.prototype.loadClassifierParams = function (weights) { var _a = this.extractClassifierParams(weights), params = _a.params, paramMappings = _a.paramMappings; this._params = params; this._paramMappings = paramMappings; }; AgeGenderNet.prototype.extractClassifierParams = function (weights) { return extractParams$4(weights); }; AgeGenderNet.prototype.extractParamsFromWeigthMap = function (weightMap) { var _a = seperateWeightMaps(weightMap), featureExtractorMap = _a.featureExtractorMap, classifierMap = _a.classifierMap; this.faceFeatureExtractor.loadFromWeightMap(featureExtractorMap); return extractParamsFromWeigthMap$4(classifierMap); }; AgeGenderNet.prototype.extractParams = function (weights) { var classifierWeightSize = (512 * 1 + 1) + (512 * 2 + 2); var featureExtractorWeights = weights.slice(0, weights.length - classifierWeightSize); var classifierWeights = weights.slice(weights.length - classifierWeightSize); this.faceFeatureExtractor.extractWeights(featureExtractorWeights); return this.extractClassifierParams(classifierWeights); }; return AgeGenderNet; }(NeuralNetwork)); var FaceLandmarks5 = /** @class */ (function (_super) { __extends(FaceLandmarks5, _super); function FaceLandmarks5() { return _super !== null && _super.apply(this, arguments) || this; } FaceLandmarks5.prototype.getRefPointsForAlignment = function () { var pts = this.positions; return [ pts[0], pts[1], getCenterPoint([pts[3], pts[4]]) ]; }; return FaceLandmarks5; }(FaceLandmarks)); var FaceMatch = /** @class */ (function () { function FaceMatch(label, distance,descriptors) { this._label = label; this._distance = distance; this._descriptors =descriptors } Object.defineProperty(FaceMatch.prototype, "label", { get: function () { return this._label; }, enumerable: true, configurable: true }); Object.defineProperty(FaceMatch.prototype, "distance", { get: function () { return this._distance; }, enumerable: true, configurable: true }); Object.defineProperty(FaceMatch.prototype, "descriptors", { get: function () { return this.descriptors; }, enumerable: true, configurable: true }); FaceMatch.prototype.toString = function (withDistance) { if (withDistance === void 0) { withDistance = true; } return "" + this.label + (withDistance ? " (" + round(this.distance) + ")" : ''); }; return FaceMatch; }()); var LabeledFaceDescriptors = /** @class */ (function () { function LabeledFaceDescriptors(label, descriptors) { if (!(typeof label === 'string')) { throw new Error('LabeledFaceDescriptors - constructor expected label to be a string'); } if (!Array.isArray(descriptors) || descriptors.some(function (desc) { return !(desc instanceof Float32Array); })) { throw new Error('LabeledFaceDescriptors - constructor expected descriptors to be an array of Float32Array'); } this._label = label; this._descriptors = descriptors; } Object.defineProperty(LabeledFaceDescriptors.prototype, "label", { get: function () { return this._label; }, enumerable: true, configurable: true }); Object.defineProperty(LabeledFaceDescriptors.prototype, "descriptors", { get: function () { return this._descriptors; }, enumerable: true, configurable: true }); return LabeledFaceDescriptors; }()); /** * Extracts the image regions containing the detected faces. * * @param input The image that face detection has been performed on. * @param detections The face detection results or face bounding boxes for that image. * @returns The Canvases of the corresponding image region for each detected face. */ function extractFaces(input, detections) { return __awaiter(this, void 0, void 0, function () { var Canvas, canvas, netInput, tensorOrCanvas, _a, ctx, boxes; return __generator(this, function (_b) { switch (_b.label) { case 0: Canvas = env.getEnv().Canvas; canvas = input; if (!!(input instanceof Canvas)) return [3 /*break*/, 5]; return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _b.sent(); if (netInput.batchSize > 1) { throw new Error('extractFaces - batchSize > 1 not supported'); } tensorOrCanvas = netInput.getInput(0); if (!(tensorOrCanvas instanceof Canvas)) return [3 /*break*/, 2]; _a = tensorOrCanvas; return [3 /*break*/, 4]; case 2: return [4 /*yield*/, imageTensorToCanvas(tensorOrCanvas)]; case 3: _a = _b.sent(); _b.label = 4; case 4: canvas = _a; _b.label = 5; case 5: ctx = getContext2dOrThrow(canvas); boxes = detections.map(function (det) { return det instanceof FaceDetection ? det.forSize(canvas.width, canvas.height).box.floor() : det; }) .map(function (box) { return box.clipAtImageBorders(canvas.width, canvas.height); }); return [2 /*return*/, boxes.map(function (_a) { var x = _a.x, y = _a.y, width = _a.width, height = _a.height; var faceImg = createCanvas({ width: width, height: height }); getContext2dOrThrow(faceImg) .putImageData(ctx.getImageData(x, y, width, height), 0, 0); return faceImg; })]; } }); }); } /** * Extracts the tensors of the image regions containing the detected faces. * Useful if you want to compute the face descriptors for the face images. * Using this method is faster then extracting a canvas for each face and * converting them to tensors individually. * * @param imageTensor The image tensor that face detection has been performed on. * @param detections The face detection results or face bounding boxes for that image. * @returns Tensors of the corresponding image region for each detected face. */ function extractFaceTensors(imageTensor, detections) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if (!isTensor3D(imageTensor) && !isTensor4D(imageTensor)) { throw new Error('extractFaceTensors - expected image tensor to be 3D or 4D'); } if (isTensor4D(imageTensor) && imageTensor.shape[0] > 1) { throw new Error('extractFaceTensors - batchSize > 1 not supported'); } return [2 /*return*/, Fe(function () { var _a = imageTensor.shape.slice(isTensor4D(imageTensor) ? 1 : 0), imgHeight = _a[0], imgWidth = _a[1], numChannels = _a[2]; var boxes = detections.map(function (det) { return det instanceof FaceDetection ? det.forSize(imgWidth, imgHeight).box : det; }) .map(function (box) { return box.clipAtImageBorders(imgWidth, imgHeight); }); var faceTensors = boxes.map(function (_a) { var x = _a.x, y = _a.y, width = _a.width, height = _a.height; return Ru(imageTensor.as3D(imgHeight, imgWidth, numChannels), [y, x, 0], [height, width, numChannels]); }); return faceTensors; })]; }); }); } var FaceLandmark68NetBase = /** @class */ (function (_super) { __extends(FaceLandmark68NetBase, _super); function FaceLandmark68NetBase() { return _super !== null && _super.apply(this, arguments) || this; } FaceLandmark68NetBase.prototype.postProcess = function (output, inputSize, originalDimensions) { var inputDimensions = originalDimensions.map(function (_a) { var width = _a.width, height = _a.height; var scale = inputSize / Math.max(height, width); return { width: width * scale, height: height * scale }; }); var batchSize = inputDimensions.length; return Fe(function () { var createInterleavedTensor = function (fillX, fillY) { return dr([ Rn([68], fillX), Rn([68], fillY) ], 1).as2D(1, 136).as1D(); }; var getPadding = function (batchIdx, cond) { var _a = inputDimensions[batchIdx], width = _a.width, height = _a.height; return cond(width, height) ? Math.abs(width - height) / 2 : 0; }; var getPaddingX = function (batchIdx) { return getPadding(batchIdx, function (w, h) { return w < h; }); }; var getPaddingY = function (batchIdx) { return getPadding(batchIdx, function (w, h) { return h < w; }); }; var landmarkTensors = output .mul(Rn([batchSize, 136], inputSize)) .sub(dr(Array.from(Array(batchSize), function (_, batchIdx) { return createInterleavedTensor(getPaddingX(batchIdx), getPaddingY(batchIdx)); }))) .div(dr(Array.from(Array(batchSize), function (_, batchIdx) { return createInterleavedTensor(inputDimensions[batchIdx].width, inputDimensions[batchIdx].height); }))); return landmarkTensors; }); }; FaceLandmark68NetBase.prototype.forwardInput = function (input) { var _this = this; return Fe(function () { var out = _this.runNet(input); return _this.postProcess(out, input.inputSize, input.inputDimensions.map(function (_a) { var height = _a[0], width = _a[1]; return ({ height: height, width: width }); })); }); }; FaceLandmark68NetBase.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; FaceLandmark68NetBase.prototype.detectLandmarks = function (input) { return __awaiter(this, void 0, void 0, function () { var netInput, landmarkTensors, landmarksForBatch; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _a.sent(); landmarkTensors = Fe(function () { return gr(_this.forwardInput(netInput)); }); return [4 /*yield*/, Promise.all(landmarkTensors.map(function (landmarkTensor, batchIdx) { return __awaiter(_this, void 0, void 0, function () { var landmarksArray, _a, _b, xCoords, yCoords; return __generator(this, function (_c) { switch (_c.label) { case 0: _b = (_a = Array).from; return [4 /*yield*/, landmarkTensor.data()]; case 1: landmarksArray = _b.apply(_a, [_c.sent()]); xCoords = landmarksArray.filter(function (_, i) { return isEven(i); }); yCoords = landmarksArray.filter(function (_, i) { return !isEven(i); }); return [2 /*return*/, new FaceLandmarks68(Array(68).fill(0).map(function (_, i) { return new Point(xCoords[i], yCoords[i]); }), { height: netInput.getInputHeight(batchIdx), width: netInput.getInputWidth(batchIdx), })]; } }); }); }))]; case 2: landmarksForBatch = _a.sent(); landmarkTensors.forEach(function (t) { return t.dispose(); }); return [2 /*return*/, netInput.isBatchInput ? landmarksForBatch : landmarksForBatch[0]]; } }); }); }; FaceLandmark68NetBase.prototype.getClassifierChannelsOut = function () { return 136; }; return FaceLandmark68NetBase; }(FaceProcessor)); var FaceLandmark68Net = /** @class */ (function (_super) { __extends(FaceLandmark68Net, _super); function FaceLandmark68Net(faceFeatureExtractor) { if (faceFeatureExtractor === void 0) { faceFeatureExtractor = new FaceFeatureExtractor(); } return _super.call(this, 'FaceLandmark68Net', faceFeatureExtractor) || this; } FaceLandmark68Net.prototype.getDefaultModelName = function () { return 'face_landmark_68_model'; }; FaceLandmark68Net.prototype.getClassifierChannelsIn = function () { return 256; }; return FaceLandmark68Net; }(FaceLandmark68NetBase)); function extractParamsFromWeigthMapTiny(weightMap) { var paramMappings = []; var extractDenseBlock3Params = loadParamsFactory(weightMap, paramMappings).extractDenseBlock3Params; var params = { dense0: extractDenseBlock3Params('dense0', true), dense1: extractDenseBlock3Params('dense1'), dense2: extractDenseBlock3Params('dense2') }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } function extractParamsTiny(weights) { var paramMappings = []; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var extractDenseBlock3Params = extractorsFactory$2(extractWeights, paramMappings).extractDenseBlock3Params; var dense0 = extractDenseBlock3Params(3, 32, 'dense0', true); var dense1 = extractDenseBlock3Params(32, 64, 'dense1'); var dense2 = extractDenseBlock3Params(64, 128, 'dense2'); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { paramMappings: paramMappings, params: { dense0: dense0, dense1: dense1, dense2: dense2 } }; } var TinyFaceFeatureExtractor = /** @class */ (function (_super) { __extends(TinyFaceFeatureExtractor, _super); function TinyFaceFeatureExtractor() { return _super.call(this, 'TinyFaceFeatureExtractor') || this; } TinyFaceFeatureExtractor.prototype.forwardInput = function (input) { var params = this.params; if (!params) { throw new Error('TinyFaceFeatureExtractor - load model before inference'); } return Fe(function () { var batchTensor = input.toBatchTensor(112, true); var meanRgb = [122.782, 117.001, 104.298]; var normalized = normalize(batchTensor, meanRgb).div(vn(255)); var out = denseBlock3(normalized, params.dense0, true); out = denseBlock3(out, params.dense1); out = denseBlock3(out, params.dense2); out = xu(out, [14, 14], [2, 2], 'valid'); return out; }); }; TinyFaceFeatureExtractor.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; TinyFaceFeatureExtractor.prototype.getDefaultModelName = function () { return 'face_feature_extractor_tiny_model'; }; TinyFaceFeatureExtractor.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMapTiny(weightMap); }; TinyFaceFeatureExtractor.prototype.extractParams = function (weights) { return extractParamsTiny(weights); }; return TinyFaceFeatureExtractor; }(NeuralNetwork)); var FaceLandmark68TinyNet = /** @class */ (function (_super) { __extends(FaceLandmark68TinyNet, _super); function FaceLandmark68TinyNet(faceFeatureExtractor) { if (faceFeatureExtractor === void 0) { faceFeatureExtractor = new TinyFaceFeatureExtractor(); } return _super.call(this, 'FaceLandmark68TinyNet', faceFeatureExtractor) || this; } FaceLandmark68TinyNet.prototype.getDefaultModelName = function () { return 'face_landmark_68_tiny_model'; }; FaceLandmark68TinyNet.prototype.getClassifierChannelsIn = function () { return 128; }; return FaceLandmark68TinyNet; }(FaceLandmark68NetBase)); var FaceLandmarkNet = /** @class */ (function (_super) { __extends(FaceLandmarkNet, _super); function FaceLandmarkNet() { return _super !== null && _super.apply(this, arguments) || this; } return FaceLandmarkNet; }(FaceLandmark68Net)); function scale(x, params) { return Yu(ll(x, params.weights), params.biases); } function convLayer$1(x, params, strides, withRelu, padding) { if (padding === void 0) { padding = 'same'; } var _a = params.conv, filters = _a.filters, bias = _a.bias; var out = nu(x, filters, strides, padding); out = Yu(out, bias); out = scale(out, params.scale); return withRelu ? Sl(out) : out; } function conv$1(x, params) { return convLayer$1(x, params, [1, 1], true); } function convNoRelu(x, params) { return convLayer$1(x, params, [1, 1], false); } function convDown(x, params) { return convLayer$1(x, params, [2, 2], true, 'valid'); } function extractorsFactory$4(extractWeights, paramMappings) { function extractFilterValues(numFilterValues, numFilters, filterSize) { var weights = extractWeights(numFilterValues); var depth = weights.length / (numFilters * filterSize * filterSize); if (isFloat(depth)) { throw new Error("depth has to be an integer: " + depth + ", weights.length: " + weights.length + ", numFilters: " + numFilters + ", filterSize: " + filterSize); } return Fe(function () { return kl(xn(weights, [numFilters, depth, filterSize, filterSize]), [2, 3, 1, 0]); }); } function extractConvParams(numFilterValues, numFilters, filterSize, mappedPrefix) { var filters = extractFilterValues(numFilterValues, numFilters, filterSize); var bias = mn(extractWeights(numFilters)); paramMappings.push({ paramPath: mappedPrefix + "/filters" }, { paramPath: mappedPrefix + "/bias" }); return { filters: filters, bias: bias }; } function extractScaleLayerParams(numWeights, mappedPrefix) { var weights = mn(extractWeights(numWeights)); var biases = mn(extractWeights(numWeights)); paramMappings.push({ paramPath: mappedPrefix + "/weights" }, { paramPath: mappedPrefix + "/biases" }); return { weights: weights, biases: biases }; } function extractConvLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix) { var conv = extractConvParams(numFilterValues, numFilters, filterSize, mappedPrefix + "/conv"); var scale = extractScaleLayerParams(numFilters, mappedPrefix + "/scale"); return { conv: conv, scale: scale }; } function extractResidualLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix, isDown) { if (isDown === void 0) { isDown = false; } var conv1 = extractConvLayerParams((isDown ? 0.5 : 1) * numFilterValues, numFilters, filterSize, mappedPrefix + "/conv1"); var conv2 = extractConvLayerParams(numFilterValues, numFilters, filterSize, mappedPrefix + "/conv2"); return { conv1: conv1, conv2: conv2 }; } return { extractConvLayerParams: extractConvLayerParams, extractResidualLayerParams: extractResidualLayerParams }; } function extractParams$5(weights) { var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var paramMappings = []; var _b = extractorsFactory$4(extractWeights, paramMappings), extractConvLayerParams = _b.extractConvLayerParams, extractResidualLayerParams = _b.extractResidualLayerParams; var conv32_down = extractConvLayerParams(4704, 32, 7, 'conv32_down'); var conv32_1 = extractResidualLayerParams(9216, 32, 3, 'conv32_1'); var conv32_2 = extractResidualLayerParams(9216, 32, 3, 'conv32_2'); var conv32_3 = extractResidualLayerParams(9216, 32, 3, 'conv32_3'); var conv64_down = extractResidualLayerParams(36864, 64, 3, 'conv64_down', true); var conv64_1 = extractResidualLayerParams(36864, 64, 3, 'conv64_1'); var conv64_2 = extractResidualLayerParams(36864, 64, 3, 'conv64_2'); var conv64_3 = extractResidualLayerParams(36864, 64, 3, 'conv64_3'); var conv128_down = extractResidualLayerParams(147456, 128, 3, 'conv128_down', true); var conv128_1 = extractResidualLayerParams(147456, 128, 3, 'conv128_1'); var conv128_2 = extractResidualLayerParams(147456, 128, 3, 'conv128_2'); var conv256_down = extractResidualLayerParams(589824, 256, 3, 'conv256_down', true); var conv256_1 = extractResidualLayerParams(589824, 256, 3, 'conv256_1'); var conv256_2 = extractResidualLayerParams(589824, 256, 3, 'conv256_2'); var conv256_down_out = extractResidualLayerParams(589824, 256, 3, 'conv256_down_out'); var fc = Fe(function () { return kl(gn(extractWeights(256 * 128), [128, 256]), [1, 0]); }); paramMappings.push({ paramPath: "fc" }); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } var params = { conv32_down: conv32_down, conv32_1: conv32_1, conv32_2: conv32_2, conv32_3: conv32_3, conv64_down: conv64_down, conv64_1: conv64_1, conv64_2: conv64_2, conv64_3: conv64_3, conv128_down: conv128_down, conv128_1: conv128_1, conv128_2: conv128_2, conv256_down: conv256_down, conv256_1: conv256_1, conv256_2: conv256_2, conv256_down_out: conv256_down_out, fc: fc }; return { params: params, paramMappings: paramMappings }; } function extractorsFactory$5(weightMap, paramMappings) { var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); function extractScaleLayerParams(prefix) { var weights = extractWeightEntry(prefix + "/scale/weights", 1); var biases = extractWeightEntry(prefix + "/scale/biases", 1); return { weights: weights, biases: biases }; } function extractConvLayerParams(prefix) { var filters = extractWeightEntry(prefix + "/conv/filters", 4); var bias = extractWeightEntry(prefix + "/conv/bias", 1); var scale = extractScaleLayerParams(prefix); return { conv: { filters: filters, bias: bias }, scale: scale }; } function extractResidualLayerParams(prefix) { return { conv1: extractConvLayerParams(prefix + "/conv1"), conv2: extractConvLayerParams(prefix + "/conv2") }; } return { extractConvLayerParams: extractConvLayerParams, extractResidualLayerParams: extractResidualLayerParams }; } function extractParamsFromWeigthMap$5(weightMap) { var paramMappings = []; var _a = extractorsFactory$5(weightMap, paramMappings), extractConvLayerParams = _a.extractConvLayerParams, extractResidualLayerParams = _a.extractResidualLayerParams; var conv32_down = extractConvLayerParams('conv32_down'); var conv32_1 = extractResidualLayerParams('conv32_1'); var conv32_2 = extractResidualLayerParams('conv32_2'); var conv32_3 = extractResidualLayerParams('conv32_3'); var conv64_down = extractResidualLayerParams('conv64_down'); var conv64_1 = extractResidualLayerParams('conv64_1'); var conv64_2 = extractResidualLayerParams('conv64_2'); var conv64_3 = extractResidualLayerParams('conv64_3'); var conv128_down = extractResidualLayerParams('conv128_down'); var conv128_1 = extractResidualLayerParams('conv128_1'); var conv128_2 = extractResidualLayerParams('conv128_2'); var conv256_down = extractResidualLayerParams('conv256_down'); var conv256_1 = extractResidualLayerParams('conv256_1'); var conv256_2 = extractResidualLayerParams('conv256_2'); var conv256_down_out = extractResidualLayerParams('conv256_down_out'); var fc = weightMap['fc']; paramMappings.push({ originalPath: 'fc', paramPath: 'fc' }); if (!isTensor2D(fc)) { throw new Error("expected weightMap[fc] to be a Tensor2D, instead have " + fc); } var params = { conv32_down: conv32_down, conv32_1: conv32_1, conv32_2: conv32_2, conv32_3: conv32_3, conv64_down: conv64_down, conv64_1: conv64_1, conv64_2: conv64_2, conv64_3: conv64_3, conv128_down: conv128_down, conv128_1: conv128_1, conv128_2: conv128_2, conv256_down: conv256_down, conv256_1: conv256_1, conv256_2: conv256_2, conv256_down_out: conv256_down_out, fc: fc }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } function residual(x, params) { var out = conv$1(x, params.conv1); out = convNoRelu(out, params.conv2); out = Yu(out, x); out = Sl(out); return out; } function residualDown(x, params) { var out = convDown(x, params.conv1); out = convNoRelu(out, params.conv2); var pooled = xu(x, 2, 2, 'valid'); var zeros = En(pooled.shape); var isPad = pooled.shape[3] !== out.shape[3]; var isAdjustShape = pooled.shape[1] !== out.shape[1] || pooled.shape[2] !== out.shape[2]; if (isAdjustShape) { var padShapeX = out.shape.slice(); padShapeX[1] = 1; var zerosW = En(padShapeX); out = An([out, zerosW], 1); var padShapeY = out.shape.slice(); padShapeY[2] = 1; var zerosH = En(padShapeY); out = An([out, zerosH], 2); } pooled = isPad ? An([pooled, zeros], 3) : pooled; out = Yu(pooled, out); out = Sl(out); return out; } var FaceRecognitionNet = /** @class */ (function (_super) { __extends(FaceRecognitionNet, _super); function FaceRecognitionNet() { return _super.call(this, 'FaceRecognitionNet') || this; } FaceRecognitionNet.prototype.forwardInput = function (input) { var params = this.params; if (!params) { throw new Error('FaceRecognitionNet - load model before inference'); } return Fe(function () { var batchTensor = input.toBatchTensor(150, true).toFloat(); var meanRgb = [122.782, 117.001, 104.298]; var normalized = normalize(batchTensor, meanRgb).div(vn(256)); var out = convDown(normalized, params.conv32_down); out = yu(out, 3, 2, 'valid'); out = residual(out, params.conv32_1); out = residual(out, params.conv32_2); out = residual(out, params.conv32_3); out = residualDown(out, params.conv64_down); out = residual(out, params.conv64_1); out = residual(out, params.conv64_2); out = residual(out, params.conv64_3); out = residualDown(out, params.conv128_down); out = residual(out, params.conv128_1); out = residual(out, params.conv128_2); out = residualDown(out, params.conv256_down); out = residual(out, params.conv256_1); out = residual(out, params.conv256_2); out = residualDown(out, params.conv256_down_out); var globalAvg = out.mean([1, 2]); var fullyConnected = uu(globalAvg, params.fc); return fullyConnected; }); }; FaceRecognitionNet.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; FaceRecognitionNet.prototype.computeFaceDescriptor = function (input) { return __awaiter(this, void 0, void 0, function () { var netInput, faceDescriptorTensors, faceDescriptorsForBatch; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _a.sent(); faceDescriptorTensors = Fe(function () { return gr(_this.forwardInput(netInput)); }); return [4 /*yield*/, Promise.all(faceDescriptorTensors.map(function (t) { return t.data(); }))]; case 2: faceDescriptorsForBatch = _a.sent(); faceDescriptorTensors.forEach(function (t) { return t.dispose(); }); return [2 /*return*/, netInput.isBatchInput ? faceDescriptorsForBatch : faceDescriptorsForBatch[0]]; } }); }); }; FaceRecognitionNet.prototype.getDefaultModelName = function () { return 'face_recognition_model'; }; FaceRecognitionNet.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMap$5(weightMap); }; FaceRecognitionNet.prototype.extractParams = function (weights) { return extractParams$5(weights); }; return FaceRecognitionNet; }(NeuralNetwork)); function createFaceRecognitionNet(weights) { var net = new FaceRecognitionNet(); net.extractWeights(weights); return net; } function extendWithFaceDescriptor(sourceObj, descriptor) { var extension = { descriptor: descriptor }; return Object.assign({}, sourceObj, extension); } function isWithAge(obj) { return typeof obj['age'] === 'number'; } function extendWithAge(sourceObj, age) { var extension = { age: age }; return Object.assign({}, sourceObj, extension); } function isWithGender(obj) { return (obj['gender'] === exports.Gender.MALE || obj['gender'] === exports.Gender.FEMALE) && isValidProbablitiy(obj['genderProbability']); } function extendWithGender(sourceObj, gender, genderProbability) { var extension = { gender: gender, genderProbability: genderProbability }; return Object.assign({}, sourceObj, extension); } var MtcnnOptions = /** @class */ (function () { function MtcnnOptions(_a) { var _b = _a === void 0 ? {} : _a, minFaceSize = _b.minFaceSize, scaleFactor = _b.scaleFactor, maxNumScales = _b.maxNumScales, scoreThresholds = _b.scoreThresholds, scaleSteps = _b.scaleSteps; this._name = 'MtcnnOptions'; this._minFaceSize = minFaceSize || 20; this._scaleFactor = scaleFactor || 0.709; this._maxNumScales = maxNumScales || 10; this._scoreThresholds = scoreThresholds || [0.6, 0.7, 0.7]; this._scaleSteps = scaleSteps; if (typeof this._minFaceSize !== 'number' || this._minFaceSize < 0) { throw new Error(this._name + " - expected minFaceSize to be a number > 0"); } if (typeof this._scaleFactor !== 'number' || this._scaleFactor <= 0 || this._scaleFactor >= 1) { throw new Error(this._name + " - expected scaleFactor to be a number between 0 and 1"); } if (typeof this._maxNumScales !== 'number' || this._maxNumScales < 0) { throw new Error(this._name + " - expected maxNumScales to be a number > 0"); } if (!Array.isArray(this._scoreThresholds) || this._scoreThresholds.length !== 3 || this._scoreThresholds.some(function (th) { return typeof th !== 'number'; })) { throw new Error(this._name + " - expected scoreThresholds to be an array of numbers of length 3"); } if (this._scaleSteps && (!Array.isArray(this._scaleSteps) || this._scaleSteps.some(function (th) { return typeof th !== 'number'; }))) { throw new Error(this._name + " - expected scaleSteps to be an array of numbers"); } } Object.defineProperty(MtcnnOptions.prototype, "minFaceSize", { get: function () { return this._minFaceSize; }, enumerable: true, configurable: true }); Object.defineProperty(MtcnnOptions.prototype, "scaleFactor", { get: function () { return this._scaleFactor; }, enumerable: true, configurable: true }); Object.defineProperty(MtcnnOptions.prototype, "maxNumScales", { get: function () { return this._maxNumScales; }, enumerable: true, configurable: true }); Object.defineProperty(MtcnnOptions.prototype, "scoreThresholds", { get: function () { return this._scoreThresholds; }, enumerable: true, configurable: true }); Object.defineProperty(MtcnnOptions.prototype, "scaleSteps", { get: function () { return this._scaleSteps; }, enumerable: true, configurable: true }); return MtcnnOptions; }()); function extractorsFactory$6(extractWeights, paramMappings) { function extractDepthwiseConvParams(numChannels, mappedPrefix) { var filters = xn(extractWeights(3 * 3 * numChannels), [3, 3, numChannels, 1]); var batch_norm_scale = mn(extractWeights(numChannels)); var batch_norm_offset = mn(extractWeights(numChannels)); var batch_norm_mean = mn(extractWeights(numChannels)); var batch_norm_variance = mn(extractWeights(numChannels)); paramMappings.push({ paramPath: mappedPrefix + "/filters" }, { paramPath: mappedPrefix + "/batch_norm_scale" }, { paramPath: mappedPrefix + "/batch_norm_offset" }, { paramPath: mappedPrefix + "/batch_norm_mean" }, { paramPath: mappedPrefix + "/batch_norm_variance" }); return { filters: filters, batch_norm_scale: batch_norm_scale, batch_norm_offset: batch_norm_offset, batch_norm_mean: batch_norm_mean, batch_norm_variance: batch_norm_variance }; } function extractConvParams(channelsIn, channelsOut, filterSize, mappedPrefix, isPointwiseConv) { var filters = xn(extractWeights(channelsIn * channelsOut * filterSize * filterSize), [filterSize, filterSize, channelsIn, channelsOut]); var bias = mn(extractWeights(channelsOut)); paramMappings.push({ paramPath: mappedPrefix + "/filters" }, { paramPath: mappedPrefix + "/" + (isPointwiseConv ? 'batch_norm_offset' : 'bias') }); return { filters: filters, bias: bias }; } function extractPointwiseConvParams(channelsIn, channelsOut, filterSize, mappedPrefix) { var _a = extractConvParams(channelsIn, channelsOut, filterSize, mappedPrefix, true), filters = _a.filters, bias = _a.bias; return { filters: filters, batch_norm_offset: bias }; } function extractConvPairParams(channelsIn, channelsOut, mappedPrefix) { var depthwise_conv = extractDepthwiseConvParams(channelsIn, mappedPrefix + "/depthwise_conv"); var pointwise_conv = extractPointwiseConvParams(channelsIn, channelsOut, 1, mappedPrefix + "/pointwise_conv"); return { depthwise_conv: depthwise_conv, pointwise_conv: pointwise_conv }; } function extractMobilenetV1Params() { var conv_0 = extractPointwiseConvParams(3, 32, 3, 'mobilenetv1/conv_0'); var conv_1 = extractConvPairParams(32, 64, 'mobilenetv1/conv_1'); var conv_2 = extractConvPairParams(64, 128, 'mobilenetv1/conv_2'); var conv_3 = extractConvPairParams(128, 128, 'mobilenetv1/conv_3'); var conv_4 = extractConvPairParams(128, 256, 'mobilenetv1/conv_4'); var conv_5 = extractConvPairParams(256, 256, 'mobilenetv1/conv_5'); var conv_6 = extractConvPairParams(256, 512, 'mobilenetv1/conv_6'); var conv_7 = extractConvPairParams(512, 512, 'mobilenetv1/conv_7'); var conv_8 = extractConvPairParams(512, 512, 'mobilenetv1/conv_8'); var conv_9 = extractConvPairParams(512, 512, 'mobilenetv1/conv_9'); var conv_10 = extractConvPairParams(512, 512, 'mobilenetv1/conv_10'); var conv_11 = extractConvPairParams(512, 512, 'mobilenetv1/conv_11'); var conv_12 = extractConvPairParams(512, 1024, 'mobilenetv1/conv_12'); var conv_13 = extractConvPairParams(1024, 1024, 'mobilenetv1/conv_13'); return { conv_0: conv_0, conv_1: conv_1, conv_2: conv_2, conv_3: conv_3, conv_4: conv_4, conv_5: conv_5, conv_6: conv_6, conv_7: conv_7, conv_8: conv_8, conv_9: conv_9, conv_10: conv_10, conv_11: conv_11, conv_12: conv_12, conv_13: conv_13 }; } function extractPredictionLayerParams() { var conv_0 = extractPointwiseConvParams(1024, 256, 1, 'prediction_layer/conv_0'); var conv_1 = extractPointwiseConvParams(256, 512, 3, 'prediction_layer/conv_1'); var conv_2 = extractPointwiseConvParams(512, 128, 1, 'prediction_layer/conv_2'); var conv_3 = extractPointwiseConvParams(128, 256, 3, 'prediction_layer/conv_3'); var conv_4 = extractPointwiseConvParams(256, 128, 1, 'prediction_layer/conv_4'); var conv_5 = extractPointwiseConvParams(128, 256, 3, 'prediction_layer/conv_5'); var conv_6 = extractPointwiseConvParams(256, 64, 1, 'prediction_layer/conv_6'); var conv_7 = extractPointwiseConvParams(64, 128, 3, 'prediction_layer/conv_7'); var box_encoding_0_predictor = extractConvParams(512, 12, 1, 'prediction_layer/box_predictor_0/box_encoding_predictor'); var class_predictor_0 = extractConvParams(512, 9, 1, 'prediction_layer/box_predictor_0/class_predictor'); var box_encoding_1_predictor = extractConvParams(1024, 24, 1, 'prediction_layer/box_predictor_1/box_encoding_predictor'); var class_predictor_1 = extractConvParams(1024, 18, 1, 'prediction_layer/box_predictor_1/class_predictor'); var box_encoding_2_predictor = extractConvParams(512, 24, 1, 'prediction_layer/box_predictor_2/box_encoding_predictor'); var class_predictor_2 = extractConvParams(512, 18, 1, 'prediction_layer/box_predictor_2/class_predictor'); var box_encoding_3_predictor = extractConvParams(256, 24, 1, 'prediction_layer/box_predictor_3/box_encoding_predictor'); var class_predictor_3 = extractConvParams(256, 18, 1, 'prediction_layer/box_predictor_3/class_predictor'); var box_encoding_4_predictor = extractConvParams(256, 24, 1, 'prediction_layer/box_predictor_4/box_encoding_predictor'); var class_predictor_4 = extractConvParams(256, 18, 1, 'prediction_layer/box_predictor_4/class_predictor'); var box_encoding_5_predictor = extractConvParams(128, 24, 1, 'prediction_layer/box_predictor_5/box_encoding_predictor'); var class_predictor_5 = extractConvParams(128, 18, 1, 'prediction_layer/box_predictor_5/class_predictor'); var box_predictor_0 = { box_encoding_predictor: box_encoding_0_predictor, class_predictor: class_predictor_0 }; var box_predictor_1 = { box_encoding_predictor: box_encoding_1_predictor, class_predictor: class_predictor_1 }; var box_predictor_2 = { box_encoding_predictor: box_encoding_2_predictor, class_predictor: class_predictor_2 }; var box_predictor_3 = { box_encoding_predictor: box_encoding_3_predictor, class_predictor: class_predictor_3 }; var box_predictor_4 = { box_encoding_predictor: box_encoding_4_predictor, class_predictor: class_predictor_4 }; var box_predictor_5 = { box_encoding_predictor: box_encoding_5_predictor, class_predictor: class_predictor_5 }; return { conv_0: conv_0, conv_1: conv_1, conv_2: conv_2, conv_3: conv_3, conv_4: conv_4, conv_5: conv_5, conv_6: conv_6, conv_7: conv_7, box_predictor_0: box_predictor_0, box_predictor_1: box_predictor_1, box_predictor_2: box_predictor_2, box_predictor_3: box_predictor_3, box_predictor_4: box_predictor_4, box_predictor_5: box_predictor_5 }; } return { extractMobilenetV1Params: extractMobilenetV1Params, extractPredictionLayerParams: extractPredictionLayerParams }; } function extractParams$6(weights) { var paramMappings = []; var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var _b = extractorsFactory$6(extractWeights, paramMappings), extractMobilenetV1Params = _b.extractMobilenetV1Params, extractPredictionLayerParams = _b.extractPredictionLayerParams; var mobilenetv1 = extractMobilenetV1Params(); var prediction_layer = extractPredictionLayerParams(); var extra_dim = yn(extractWeights(5118 * 4), [1, 5118, 4]); var output_layer = { extra_dim: extra_dim }; paramMappings.push({ paramPath: 'output_layer/extra_dim' }); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { params: { mobilenetv1: mobilenetv1, prediction_layer: prediction_layer, output_layer: output_layer }, paramMappings: paramMappings }; } function extractorsFactory$7(weightMap, paramMappings) { var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); function extractPointwiseConvParams(prefix, idx, mappedPrefix) { var filters = extractWeightEntry(prefix + "/Conv2d_" + idx + "_pointwise/weights", 4, mappedPrefix + "/filters"); var batch_norm_offset = extractWeightEntry(prefix + "/Conv2d_" + idx + "_pointwise/convolution_bn_offset", 1, mappedPrefix + "/batch_norm_offset"); return { filters: filters, batch_norm_offset: batch_norm_offset }; } function extractConvPairParams(idx) { var mappedPrefix = "mobilenetv1/conv_" + idx; var prefixDepthwiseConv = "MobilenetV1/Conv2d_" + idx + "_depthwise"; var mappedPrefixDepthwiseConv = mappedPrefix + "/depthwise_conv"; var mappedPrefixPointwiseConv = mappedPrefix + "/pointwise_conv"; var filters = extractWeightEntry(prefixDepthwiseConv + "/depthwise_weights", 4, mappedPrefixDepthwiseConv + "/filters"); var batch_norm_scale = extractWeightEntry(prefixDepthwiseConv + "/BatchNorm/gamma", 1, mappedPrefixDepthwiseConv + "/batch_norm_scale"); var batch_norm_offset = extractWeightEntry(prefixDepthwiseConv + "/BatchNorm/beta", 1, mappedPrefixDepthwiseConv + "/batch_norm_offset"); var batch_norm_mean = extractWeightEntry(prefixDepthwiseConv + "/BatchNorm/moving_mean", 1, mappedPrefixDepthwiseConv + "/batch_norm_mean"); var batch_norm_variance = extractWeightEntry(prefixDepthwiseConv + "/BatchNorm/moving_variance", 1, mappedPrefixDepthwiseConv + "/batch_norm_variance"); return { depthwise_conv: { filters: filters, batch_norm_scale: batch_norm_scale, batch_norm_offset: batch_norm_offset, batch_norm_mean: batch_norm_mean, batch_norm_variance: batch_norm_variance }, pointwise_conv: extractPointwiseConvParams('MobilenetV1', idx, mappedPrefixPointwiseConv) }; } function extractMobilenetV1Params() { return { conv_0: extractPointwiseConvParams('MobilenetV1', 0, 'mobilenetv1/conv_0'), conv_1: extractConvPairParams(1), conv_2: extractConvPairParams(2), conv_3: extractConvPairParams(3), conv_4: extractConvPairParams(4), conv_5: extractConvPairParams(5), conv_6: extractConvPairParams(6), conv_7: extractConvPairParams(7), conv_8: extractConvPairParams(8), conv_9: extractConvPairParams(9), conv_10: extractConvPairParams(10), conv_11: extractConvPairParams(11), conv_12: extractConvPairParams(12), conv_13: extractConvPairParams(13) }; } function extractConvParams(prefix, mappedPrefix) { var filters = extractWeightEntry(prefix + "/weights", 4, mappedPrefix + "/filters"); var bias = extractWeightEntry(prefix + "/biases", 1, mappedPrefix + "/bias"); return { filters: filters, bias: bias }; } function extractBoxPredictorParams(idx) { var box_encoding_predictor = extractConvParams("Prediction/BoxPredictor_" + idx + "/BoxEncodingPredictor", "prediction_layer/box_predictor_" + idx + "/box_encoding_predictor"); var class_predictor = extractConvParams("Prediction/BoxPredictor_" + idx + "/ClassPredictor", "prediction_layer/box_predictor_" + idx + "/class_predictor"); return { box_encoding_predictor: box_encoding_predictor, class_predictor: class_predictor }; } function extractPredictionLayerParams() { return { conv_0: extractPointwiseConvParams('Prediction', 0, 'prediction_layer/conv_0'), conv_1: extractPointwiseConvParams('Prediction', 1, 'prediction_layer/conv_1'), conv_2: extractPointwiseConvParams('Prediction', 2, 'prediction_layer/conv_2'), conv_3: extractPointwiseConvParams('Prediction', 3, 'prediction_layer/conv_3'), conv_4: extractPointwiseConvParams('Prediction', 4, 'prediction_layer/conv_4'), conv_5: extractPointwiseConvParams('Prediction', 5, 'prediction_layer/conv_5'), conv_6: extractPointwiseConvParams('Prediction', 6, 'prediction_layer/conv_6'), conv_7: extractPointwiseConvParams('Prediction', 7, 'prediction_layer/conv_7'), box_predictor_0: extractBoxPredictorParams(0), box_predictor_1: extractBoxPredictorParams(1), box_predictor_2: extractBoxPredictorParams(2), box_predictor_3: extractBoxPredictorParams(3), box_predictor_4: extractBoxPredictorParams(4), box_predictor_5: extractBoxPredictorParams(5) }; } return { extractMobilenetV1Params: extractMobilenetV1Params, extractPredictionLayerParams: extractPredictionLayerParams }; } function extractParamsFromWeigthMap$6(weightMap) { var paramMappings = []; var _a = extractorsFactory$7(weightMap, paramMappings), extractMobilenetV1Params = _a.extractMobilenetV1Params, extractPredictionLayerParams = _a.extractPredictionLayerParams; var extra_dim = weightMap['Output/extra_dim']; paramMappings.push({ originalPath: 'Output/extra_dim', paramPath: 'output_layer/extra_dim' }); if (!isTensor3D(extra_dim)) { throw new Error("expected weightMap['Output/extra_dim'] to be a Tensor3D, instead have " + extra_dim); } var params = { mobilenetv1: extractMobilenetV1Params(), prediction_layer: extractPredictionLayerParams(), output_layer: { extra_dim: extra_dim } }; disposeUnusedWeightTensors(weightMap, paramMappings); return { params: params, paramMappings: paramMappings }; } function pointwiseConvLayer(x, params, strides) { return Fe(function () { var out = nu(x, params.filters, strides, 'same'); out = Yu(out, params.batch_norm_offset); return hs(out, 0, 6); }); } var epsilon = 0.0010000000474974513; function depthwiseConvLayer(x, params, strides) { return Fe(function () { var out = au(x, params.filters, strides, 'same'); out = Ks(out, params.batch_norm_mean, params.batch_norm_variance, params.batch_norm_offset, params.batch_norm_scale, epsilon); return hs(out, 0, 6); }); } function getStridesForLayerIdx(layerIdx) { return [2, 4, 6, 12].some(function (idx) { return idx === layerIdx; }) ? [2, 2] : [1, 1]; } function mobileNetV1(x, params) { return Fe(function () { var conv11 = null; var out = pointwiseConvLayer(x, params.conv_0, [2, 2]); var convPairParams = [ params.conv_1, params.conv_2, params.conv_3, params.conv_4, params.conv_5, params.conv_6, params.conv_7, params.conv_8, params.conv_9, params.conv_10, params.conv_11, params.conv_12, params.conv_13 ]; convPairParams.forEach(function (param, i) { var layerIdx = i + 1; var depthwiseConvStrides = getStridesForLayerIdx(layerIdx); out = depthwiseConvLayer(out, param.depthwise_conv, depthwiseConvStrides); out = pointwiseConvLayer(out, param.pointwise_conv, [1, 1]); if (layerIdx === 11) { conv11 = out; } }); if (conv11 === null) { throw new Error('mobileNetV1 - output of conv layer 11 is null'); } return { out: out, conv11: conv11 }; }); } function nonMaxSuppression$1(boxes, scores, maxOutputSize, iouThreshold, scoreThreshold) { var numBoxes = boxes.shape[0]; var outputSize = Math.min(maxOutputSize, numBoxes); var candidates = scores .map(function (score, boxIndex) { return ({ score: score, boxIndex: boxIndex }); }) .filter(function (c) { return c.score > scoreThreshold; }) .sort(function (c1, c2) { return c2.score - c1.score; }); var suppressFunc = function (x) { return x <= iouThreshold ? 1 : 0; }; var selected = []; candidates.forEach(function (c) { if (selected.length >= outputSize) { return; } var originalScore = c.score; for (var j = selected.length - 1; j >= 0; --j) { var iou = IOU(boxes, c.boxIndex, selected[j]); if (iou === 0.0) { continue; } c.score *= suppressFunc(iou); if (c.score <= scoreThreshold) { break; } } if (originalScore === c.score) { selected.push(c.boxIndex); } }); return selected; } function IOU(boxes, i, j) { var boxesData = boxes.arraySync(); var yminI = Math.min(boxesData[i][0], boxesData[i][2]); var xminI = Math.min(boxesData[i][1], boxesData[i][3]); var ymaxI = Math.max(boxesData[i][0], boxesData[i][2]); var xmaxI = Math.max(boxesData[i][1], boxesData[i][3]); var yminJ = Math.min(boxesData[j][0], boxesData[j][2]); var xminJ = Math.min(boxesData[j][1], boxesData[j][3]); var ymaxJ = Math.max(boxesData[j][0], boxesData[j][2]); var xmaxJ = Math.max(boxesData[j][1], boxesData[j][3]); var areaI = (ymaxI - yminI) * (xmaxI - xminI); var areaJ = (ymaxJ - yminJ) * (xmaxJ - xminJ); if (areaI <= 0 || areaJ <= 0) { return 0.0; } var intersectionYmin = Math.max(yminI, yminJ); var intersectionXmin = Math.max(xminI, xminJ); var intersectionYmax = Math.min(ymaxI, ymaxJ); var intersectionXmax = Math.min(xmaxI, xmaxJ); var intersectionArea = Math.max(intersectionYmax - intersectionYmin, 0.0) * Math.max(intersectionXmax - intersectionXmin, 0.0); return intersectionArea / (areaI + areaJ - intersectionArea); } function getCenterCoordinatesAndSizesLayer(x) { var vec = gr(kl(x, [1, 0])); var sizes = [ vl(vec[2], vec[0]), vl(vec[3], vec[1]) ]; var centers = [ Yu(vec[0], tl(sizes[0], vn(2))), Yu(vec[1], tl(sizes[1], vn(2))) ]; return { sizes: sizes, centers: centers }; } function decodeBoxesLayer(x0, x1) { var _a = getCenterCoordinatesAndSizesLayer(x0), sizes = _a.sizes, centers = _a.centers; var vec = gr(kl(x1, [1, 0])); var div0_out = tl(ll(vs(tl(vec[2], vn(5))), sizes[0]), vn(2)); var add0_out = Yu(ll(tl(vec[0], vn(10)), sizes[0]), centers[0]); var div1_out = tl(ll(vs(tl(vec[3], vn(5))), sizes[1]), vn(2)); var add1_out = Yu(ll(tl(vec[1], vn(10)), sizes[1]), centers[1]); return kl(dr([ vl(add0_out, div0_out), vl(add1_out, div1_out), Yu(add0_out, div0_out), Yu(add1_out, div1_out) ]), [1, 0]); } function outputLayer(boxPredictions, classPredictions, params) { return Fe(function () { var batchSize = boxPredictions.shape[0]; var boxes = decodeBoxesLayer(hr(vr(params.extra_dim, [batchSize, 1, 1]), [-1, 4]), hr(boxPredictions, [-1, 4])); boxes = hr(boxes, [batchSize, (boxes.shape[0] / batchSize), 4]); var scoresAndClasses = Is(wu(classPredictions, [0, 0, 1], [-1, -1, -1])); var scores = wu(scoresAndClasses, [0, 0, 0], [-1, -1, 1]); scores = hr(scores, [batchSize, scores.shape[1]]); var boxesByBatch = gr(boxes); var scoresByBatch = gr(scores); return { boxes: boxesByBatch, scores: scoresByBatch }; }); } function boxPredictionLayer(x, params) { return Fe(function () { var batchSize = x.shape[0]; var boxPredictionEncoding = hr(convLayer(x, params.box_encoding_predictor), [batchSize, -1, 1, 4]); var classPrediction = hr(convLayer(x, params.class_predictor), [batchSize, -1, 3]); return { boxPredictionEncoding: boxPredictionEncoding, classPrediction: classPrediction }; }); } function predictionLayer(x, conv11, params) { return Fe(function () { var conv0 = pointwiseConvLayer(x, params.conv_0, [1, 1]); var conv1 = pointwiseConvLayer(conv0, params.conv_1, [2, 2]); var conv2 = pointwiseConvLayer(conv1, params.conv_2, [1, 1]); var conv3 = pointwiseConvLayer(conv2, params.conv_3, [2, 2]); var conv4 = pointwiseConvLayer(conv3, params.conv_4, [1, 1]); var conv5 = pointwiseConvLayer(conv4, params.conv_5, [2, 2]); var conv6 = pointwiseConvLayer(conv5, params.conv_6, [1, 1]); var conv7 = pointwiseConvLayer(conv6, params.conv_7, [2, 2]); var boxPrediction0 = boxPredictionLayer(conv11, params.box_predictor_0); var boxPrediction1 = boxPredictionLayer(x, params.box_predictor_1); var boxPrediction2 = boxPredictionLayer(conv1, params.box_predictor_2); var boxPrediction3 = boxPredictionLayer(conv3, params.box_predictor_3); var boxPrediction4 = boxPredictionLayer(conv5, params.box_predictor_4); var boxPrediction5 = boxPredictionLayer(conv7, params.box_predictor_5); var boxPredictions = An([ boxPrediction0.boxPredictionEncoding, boxPrediction1.boxPredictionEncoding, boxPrediction2.boxPredictionEncoding, boxPrediction3.boxPredictionEncoding, boxPrediction4.boxPredictionEncoding, boxPrediction5.boxPredictionEncoding ], 1); var classPredictions = An([ boxPrediction0.classPrediction, boxPrediction1.classPrediction, boxPrediction2.classPrediction, boxPrediction3.classPrediction, boxPrediction4.classPrediction, boxPrediction5.classPrediction ], 1); return { boxPredictions: boxPredictions, classPredictions: classPredictions }; }); } var SsdMobilenetv1Options = /** @class */ (function () { function SsdMobilenetv1Options(_a) { var _b = _a === void 0 ? {} : _a, minConfidence = _b.minConfidence, maxResults = _b.maxResults; this._name = 'SsdMobilenetv1Options'; this._minConfidence = minConfidence || 0.5; this._maxResults = maxResults || 100; if (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"); } } Object.defineProperty(SsdMobilenetv1Options.prototype, "minConfidence", { get: function () { return this._minConfidence; }, enumerable: true, configurable: true }); Object.defineProperty(SsdMobilenetv1Options.prototype, "maxResults", { get: function () { return this._maxResults; }, enumerable: true, configurable: true }); return SsdMobilenetv1Options; }()); var SsdMobilenetv1 = /** @class */ (function (_super) { __extends(SsdMobilenetv1, _super); function SsdMobilenetv1() { return _super.call(this, 'SsdMobilenetv1') || this; } SsdMobilenetv1.prototype.forwardInput = function (input) { var params = this.params; if (!params) { throw new Error('SsdMobilenetv1 - load model before inference'); } return Fe(function () { var batchTensor = input.toBatchTensor(512, false).toFloat(); var x = vl(ll(batchTensor, vn(0.007843137718737125)), vn(1)); var features = mobileNetV1(x, params.mobilenetv1); var _a = predictionLayer(features.out, features.conv11, params.prediction_layer), boxPredictions = _a.boxPredictions, classPredictions = _a.classPredictions; return outputLayer(boxPredictions, classPredictions, params.output_layer); }); }; SsdMobilenetv1.prototype.forward = function (input) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; SsdMobilenetv1.prototype.locateFaces = function (input, options) { if (options === void 0) { options = {}; } return __awaiter(this, void 0, void 0, function () { var _a, maxResults, minConfidence, netInput, _b, _boxes, _scores, boxes, scores, i, scoresData, _c, _d, iouThreshold, indices, reshapedDims, inputSize, padX, padY, boxesData, results; return __generator(this, function (_e) { switch (_e.label) { case 0: _a = new SsdMobilenetv1Options(options), maxResults = _a.maxResults, minConfidence = _a.minConfidence; return [4 /*yield*/, toNetInput(input)]; case 1: netInput = _e.sent(); _b = this.forwardInput(netInput), _boxes = _b.boxes, _scores = _b.scores; boxes = _boxes[0]; scores = _scores[0]; for (i = 1; i < _boxes.length; i++) { _boxes[i].dispose(); _scores[i].dispose(); } _d = (_c = Array).from; return [4 /*yield*/, scores.data()]; case 2: scoresData = _d.apply(_c, [_e.sent()]); iouThreshold = 0.5; indices = nonMaxSuppression$1(boxes, scoresData, maxResults, iouThreshold, minConfidence); reshapedDims = netInput.getReshapedInputDimensions(0); inputSize = netInput.inputSize; padX = inputSize / reshapedDims.width; padY = inputSize / reshapedDims.height; boxesData = boxes.arraySync(); results = indices .map(function (idx) { var _a = [ Math.max(0, boxesData[idx][0]), Math.min(1.0, boxesData[idx][2]) ].map(function (val) { return val * padY; }), top = _a[0], bottom = _a[1]; var _b = [ Math.max(0, boxesData[idx][1]), Math.min(1.0, boxesData[idx][3]) ].map(function (val) { return val * padX; }), left = _b[0], right = _b[1]; return new FaceDetection(scoresData[idx], new Rect(left, top, right - left, bottom - top), { height: netInput.getInputHeight(0), width: netInput.getInputWidth(0) }); }); boxes.dispose(); scores.dispose(); return [2 /*return*/, results]; } }); }); }; SsdMobilenetv1.prototype.getDefaultModelName = function () { return 'ssd_mobilenetv1_model'; }; SsdMobilenetv1.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMap$6(weightMap); }; SsdMobilenetv1.prototype.extractParams = function (weights) { return extractParams$6(weights); }; return SsdMobilenetv1; }(NeuralNetwork)); function createSsdMobilenetv1(weights) { var net = new SsdMobilenetv1(); net.extractWeights(weights); return net; } function createFaceDetectionNet(weights) { return createSsdMobilenetv1(weights); } // alias for backward compatibily var FaceDetectionNet = /** @class */ (function (_super) { __extends(FaceDetectionNet, _super); function FaceDetectionNet() { return _super !== null && _super.apply(this, arguments) || this; } return FaceDetectionNet; }(SsdMobilenetv1)); var TinyFaceDetectorOptions = /** @class */ (function (_super) { __extends(TinyFaceDetectorOptions, _super); function TinyFaceDetectorOptions() { var _this = _super !== null && _super.apply(this, arguments) || this; _this._name = 'TinyFaceDetectorOptions'; return _this; } return TinyFaceDetectorOptions; }(TinyYolov2Options)); var ComposableTask = /** @class */ (function () { function ComposableTask() { } ComposableTask.prototype.then = function (onfulfilled) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = onfulfilled; return [4 /*yield*/, this.run()]; case 1: return [2 /*return*/, _a.apply(void 0, [_b.sent()])]; } }); }); }; ComposableTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { throw new Error('ComposableTask - run is not implemented'); }); }); }; return ComposableTask; }()); function extractAllFacesAndComputeResults(parentResults, input, computeResults, extractedFaces, getRectForAlignment) { if (getRectForAlignment === void 0) { getRectForAlignment = function (_a) { var alignedRect = _a.alignedRect; return alignedRect; }; } return __awaiter(this, void 0, void 0, function () { var faceBoxes, faces, _a, _b, results; return __generator(this, function (_c) { switch (_c.label) { case 0: faceBoxes = parentResults.map(function (parentResult) { return isWithFaceLandmarks(parentResult) ? getRectForAlignment(parentResult) : parentResult.detection; }); _a = extractedFaces; if (_a) return [3 /*break*/, 5]; if (!(input instanceof ht)) return [3 /*break*/, 2]; return [4 /*yield*/, extractFaceTensors(input, faceBoxes)]; case 1: _b = _c.sent(); return [3 /*break*/, 4]; case 2: return [4 /*yield*/, extractFaces(input, faceBoxes)]; case 3: _b = _c.sent(); _c.label = 4; case 4: _a = (_b); _c.label = 5; case 5: faces = _a; return [4 /*yield*/, computeResults(faces)]; case 6: results = _c.sent(); faces.forEach(function (f) { return f instanceof ht && f.dispose(); }); return [2 /*return*/, results]; } }); }); } function extractSingleFaceAndComputeResult(parentResult, input, computeResult, extractedFaces, getRectForAlignment) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { return [2 /*return*/, extractAllFacesAndComputeResults([parentResult], input, function (faces) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, computeResult(faces[0])]; }); }); }, extractedFaces, getRectForAlignment)]; }); }); } function bgrToRgbTensor(tensor) { return Fe(function () { return dr(gr(tensor, 3).reverse(), 3); }); } var CELL_STRIDE = 2; var CELL_SIZE = 12; function extractorsFactory$8(extractWeights, paramMappings) { var extractConvParams = extractConvParamsFactory(extractWeights, paramMappings); var extractFCParams = extractFCParamsFactory(extractWeights, paramMappings); function extractPReluParams(size, paramPath) { var alpha = mn(extractWeights(size)); paramMappings.push({ paramPath: paramPath }); return alpha; } function extractSharedParams(numFilters, mappedPrefix, isRnet) { if (isRnet === void 0) { isRnet = false; } var conv1 = extractConvParams(numFilters[0], numFilters[1], 3, mappedPrefix + "/conv1"); var prelu1_alpha = extractPReluParams(numFilters[1], mappedPrefix + "/prelu1_alpha"); var conv2 = extractConvParams(numFilters[1], numFilters[2], 3, mappedPrefix + "/conv2"); var prelu2_alpha = extractPReluParams(numFilters[2], mappedPrefix + "/prelu2_alpha"); var conv3 = extractConvParams(numFilters[2], numFilters[3], isRnet ? 2 : 3, mappedPrefix + "/conv3"); var prelu3_alpha = extractPReluParams(numFilters[3], mappedPrefix + "/prelu3_alpha"); return { conv1: conv1, prelu1_alpha: prelu1_alpha, conv2: conv2, prelu2_alpha: prelu2_alpha, conv3: conv3, prelu3_alpha: prelu3_alpha }; } function extractPNetParams() { var sharedParams = extractSharedParams([3, 10, 16, 32], 'pnet'); var conv4_1 = extractConvParams(32, 2, 1, 'pnet/conv4_1'); var conv4_2 = extractConvParams(32, 4, 1, 'pnet/conv4_2'); return __assign({}, sharedParams, { conv4_1: conv4_1, conv4_2: conv4_2 }); } function extractRNetParams() { var sharedParams = extractSharedParams([3, 28, 48, 64], 'rnet', true); var fc1 = extractFCParams(576, 128, 'rnet/fc1'); var prelu4_alpha = extractPReluParams(128, 'rnet/prelu4_alpha'); var fc2_1 = extractFCParams(128, 2, 'rnet/fc2_1'); var fc2_2 = extractFCParams(128, 4, 'rnet/fc2_2'); return __assign({}, sharedParams, { fc1: fc1, prelu4_alpha: prelu4_alpha, fc2_1: fc2_1, fc2_2: fc2_2 }); } function extractONetParams() { var sharedParams = extractSharedParams([3, 32, 64, 64], 'onet'); var conv4 = extractConvParams(64, 128, 2, 'onet/conv4'); var prelu4_alpha = extractPReluParams(128, 'onet/prelu4_alpha'); var fc1 = extractFCParams(1152, 256, 'onet/fc1'); var prelu5_alpha = extractPReluParams(256, 'onet/prelu5_alpha'); var fc2_1 = extractFCParams(256, 2, 'onet/fc2_1'); var fc2_2 = extractFCParams(256, 4, 'onet/fc2_2'); var fc2_3 = extractFCParams(256, 10, 'onet/fc2_3'); return __assign({}, sharedParams, { conv4: conv4, prelu4_alpha: prelu4_alpha, fc1: fc1, prelu5_alpha: prelu5_alpha, fc2_1: fc2_1, fc2_2: fc2_2, fc2_3: fc2_3 }); } return { extractPNetParams: extractPNetParams, extractRNetParams: extractRNetParams, extractONetParams: extractONetParams }; } function extractParams$7(weights) { var _a = extractWeightsFactory(weights), extractWeights = _a.extractWeights, getRemainingWeights = _a.getRemainingWeights; var paramMappings = []; var _b = extractorsFactory$8(extractWeights, paramMappings), extractPNetParams = _b.extractPNetParams, extractRNetParams = _b.extractRNetParams, extractONetParams = _b.extractONetParams; var pnet = extractPNetParams(); var rnet = extractRNetParams(); var onet = extractONetParams(); if (getRemainingWeights().length !== 0) { throw new Error("weights remaing after extract: " + getRemainingWeights().length); } return { params: { pnet: pnet, rnet: rnet, onet: onet }, paramMappings: paramMappings }; } function extractorsFactory$9(weightMap, paramMappings) { var extractWeightEntry = extractWeightEntryFactory(weightMap, paramMappings); function extractConvParams(prefix) { var filters = extractWeightEntry(prefix + "/weights", 4, prefix + "/filters"); var bias = extractWeightEntry(prefix + "/bias", 1); return { filters: filters, bias: bias }; } function extractFCParams(prefix) { var weights = extractWeightEntry(prefix + "/weights", 2); var bias = extractWeightEntry(prefix + "/bias", 1); return { weights: weights, bias: bias }; } function extractPReluParams(paramPath) { return extractWeightEntry(paramPath, 1); } function extractSharedParams(prefix) { var conv1 = extractConvParams(prefix + "/conv1"); var prelu1_alpha = extractPReluParams(prefix + "/prelu1_alpha"); var conv2 = extractConvParams(prefix + "/conv2"); var prelu2_alpha = extractPReluParams(prefix + "/prelu2_alpha"); var conv3 = extractConvParams(prefix + "/conv3"); var prelu3_alpha = extractPReluParams(prefix + "/prelu3_alpha"); return { conv1: conv1, prelu1_alpha: prelu1_alpha, conv2: conv2, prelu2_alpha: prelu2_alpha, conv3: conv3, prelu3_alpha: prelu3_alpha }; } function extractPNetParams() { var sharedParams = extractSharedParams('pnet'); var conv4_1 = extractConvParams('pnet/conv4_1'); var conv4_2 = extractConvParams('pnet/conv4_2'); return __assign({}, sharedParams, { conv4_1: conv4_1, conv4_2: conv4_2 }); } function extractRNetParams() { var sharedParams = extractSharedParams('rnet'); var fc1 = extractFCParams('rnet/fc1'); var prelu4_alpha = extractPReluParams('rnet/prelu4_alpha'); var fc2_1 = extractFCParams('rnet/fc2_1'); var fc2_2 = extractFCParams('rnet/fc2_2'); return __assign({}, sharedParams, { fc1: fc1, prelu4_alpha: prelu4_alpha, fc2_1: fc2_1, fc2_2: fc2_2 }); } function extractONetParams() { var sharedParams = extractSharedParams('onet'); var conv4 = extractConvParams('onet/conv4'); var prelu4_alpha = extractPReluParams('onet/prelu4_alpha'); var fc1 = extractFCParams('onet/fc1'); var prelu5_alpha = extractPReluParams('onet/prelu5_alpha'); var fc2_1 = extractFCParams('onet/fc2_1'); var fc2_2 = extractFCParams('onet/fc2_2'); var fc2_3 = extractFCParams('onet/fc2_3'); return __assign({}, sharedParams, { conv4: conv4, prelu4_alpha: prelu4_alpha, fc1: fc1, prelu5_alpha: prelu5_alpha, fc2_1: fc2_1, fc2_2: fc2_2, fc2_3: fc2_3 }); } return { extractPNetParams: extractPNetParams, extractRNetParams: extractRNetParams, extractONetParams: extractONetParams }; } function extractParamsFromWeigthMap$7(weightMap) { var paramMappings = []; var _a = extractorsFactory$9(weightMap, paramMappings), extractPNetParams = _a.extractPNetParams, extractRNetParams = _a.extractRNetParams, extractONetParams = _a.extractONetParams; var pnet = extractPNetParams(); var rnet = extractRNetParams(); var onet = extractONetParams(); disposeUnusedWeightTensors(weightMap, paramMappings); return { params: { pnet: pnet, rnet: rnet, onet: onet }, paramMappings: paramMappings }; } function getSizesForScale(scale, _a) { var height = _a[0], width = _a[1]; return { height: Math.floor(height * scale), width: Math.floor(width * scale) }; } function pyramidDown(minFaceSize, scaleFactor, dims) { var height = dims[0], width = dims[1]; var m = CELL_SIZE / minFaceSize; var scales = []; var minLayer = Math.min(height, width) * m; var exp = 0; while (minLayer >= 12) { scales.push(m * Math.pow(scaleFactor, exp)); minLayer = minLayer * scaleFactor; exp += 1; } return scales; } var MtcnnBox = /** @class */ (function (_super) { __extends(MtcnnBox, _super); function MtcnnBox(left, top, right, bottom) { return _super.call(this, { left: left, top: top, right: right, bottom: bottom }, true) || this; } return MtcnnBox; }(Box)); function normalize$1(x) { return Fe(function () { return ll(vl(x, vn(127.5)), vn(0.0078125)); }); } function prelu(x, alpha) { return Fe(function () { return Yu(Sl(x), ll(alpha, ws(Sl(ws(x))))); }); } function sharedLayer(x, params, isPnet) { if (isPnet === void 0) { isPnet = false; } return Fe(function () { var out = convLayer(x, params.conv1, 'valid'); out = prelu(out, params.prelu1_alpha); out = yu(out, isPnet ? [2, 2] : [3, 3], [2, 2], 'same'); out = convLayer(out, params.conv2, 'valid'); out = prelu(out, params.prelu2_alpha); out = isPnet ? out : yu(out, [3, 3], [2, 2], 'valid'); out = convLayer(out, params.conv3, 'valid'); out = prelu(out, params.prelu3_alpha); return out; }); } function PNet(x, params) { return Fe(function () { var out = sharedLayer(x, params, true); var conv = convLayer(out, params.conv4_1, 'valid'); var max = Zn(_u(conv, 3), 3); var prob = zr(vl(conv, max), 3); var regions = convLayer(out, params.conv4_2, 'valid'); return { prob: prob, regions: regions }; }); } function rescaleAndNormalize(x, scale) { return Fe(function () { var _a = getSizesForScale(scale, x.shape.slice(1)), height = _a.height, width = _a.width; var resized = wc.resizeBilinear(x, [height, width]); var normalized = normalize$1(resized); return kl(normalized, [0, 2, 1, 3]); }); } function extractBoundingBoxes(scoresTensor, regionsTensor, scale, scoreThreshold) { // TODO: fix this!, maybe better to use tf.gather here var indices = []; var scoresData = scoresTensor.arraySync(); for (var y = 0; y < scoresTensor.shape[0]; y++) { for (var x = 0; x < scoresTensor.shape[1]; x++) { if (scoresData[y][x] >= scoreThreshold) { indices.push(new Point(x, y)); } } } var boundingBoxes = indices.map(function (idx) { var cell = new BoundingBox(Math.round((idx.y * CELL_STRIDE + 1) / scale), Math.round((idx.x * CELL_STRIDE + 1) / scale), Math.round((idx.y * CELL_STRIDE + CELL_SIZE) / scale), Math.round((idx.x * CELL_STRIDE + CELL_SIZE) / scale)); var score = scoresData[idx.y][idx.x]; var regionsData = regionsTensor.arraySync(); var region = new MtcnnBox(regionsData[idx.y][idx.x][0], regionsData[idx.y][idx.x][1], regionsData[idx.y][idx.x][2], regionsData[idx.y][idx.x][3]); return { cell: cell, score: score, region: region }; }); return boundingBoxes; } function stage1(imgTensor, scales, scoreThreshold, params, stats) { stats.stage1 = []; var pnetOutputs = scales.map(function (scale) { return Fe(function () { var statsForScale = { scale: scale }; var resized = rescaleAndNormalize(imgTensor, scale); var ts = Date.now(); var _a = PNet(resized, params), prob = _a.prob, regions = _a.regions; statsForScale.pnet = Date.now() - ts; var scoresTensor = gr(gr(prob, 3)[1])[0]; var regionsTensor = gr(regions)[0]; return { scoresTensor: scoresTensor, regionsTensor: regionsTensor, scale: scale, statsForScale: statsForScale }; }); }); var boxesForScale = pnetOutputs.map(function (_a) { var scoresTensor = _a.scoresTensor, regionsTensor = _a.regionsTensor, scale = _a.scale, statsForScale = _a.statsForScale; var boundingBoxes = extractBoundingBoxes(scoresTensor, regionsTensor, scale, scoreThreshold); scoresTensor.dispose(); regionsTensor.dispose(); if (!boundingBoxes.length) { stats.stage1.push(statsForScale); return []; } var ts = Date.now(); var indices = nonMaxSuppression(boundingBoxes.map(function (bbox) { return bbox.cell; }), boundingBoxes.map(function (bbox) { return bbox.score; }), 0.5); statsForScale.nms = Date.now() - ts; statsForScale.numBoxes = indices.length; stats.stage1.push(statsForScale); return indices.map(function (boxIdx) { return boundingBoxes[boxIdx]; }); }); var allBoxes = boxesForScale.reduce(function (all, boxes) { return all.concat(boxes); }, []); var finalBoxes = []; var finalScores = []; if (allBoxes.length > 0) { var ts = Date.now(); var indices = nonMaxSuppression(allBoxes.map(function (bbox) { return bbox.cell; }), allBoxes.map(function (bbox) { return bbox.score; }), 0.7); stats.stage1_nms = Date.now() - ts; finalScores = indices.map(function (idx) { return allBoxes[idx].score; }); finalBoxes = indices .map(function (idx) { return allBoxes[idx]; }) .map(function (_a) { var cell = _a.cell, region = _a.region; return new BoundingBox(cell.left + (region.left * cell.width), cell.top + (region.top * cell.height), cell.right + (region.right * cell.width), cell.bottom + (region.bottom * cell.height)).toSquare().round(); }); } return { boxes: finalBoxes, scores: finalScores }; } function extractImagePatches(img, boxes, _a) { var width = _a.width, height = _a.height; return __awaiter(this, void 0, void 0, function () { var imgCtx, bitmaps, imagePatchesDatas; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: imgCtx = getContext2dOrThrow(img); return [4 /*yield*/, Promise.all(boxes.map(function (box) { return __awaiter(_this, void 0, void 0, function () { var _a, y, ey, x, ex, fromX, fromY, imgData; return __generator(this, function (_b) { _a = box.padAtBorders(img.height, img.width), y = _a.y, ey = _a.ey, x = _a.x, ex = _a.ex; fromX = x - 1; fromY = y - 1; imgData = imgCtx.getImageData(fromX, fromY, (ex - fromX), (ey - fromY)); return [2 /*return*/, env.isNodejs() ? createCanvasFromMedia(imgData) : createImageBitmap(imgData)]; }); }); }))]; case 1: bitmaps = _b.sent(); imagePatchesDatas = []; bitmaps.forEach(function (bmp) { var patch = createCanvas({ width: width, height: height }); var patchCtx = getContext2dOrThrow(patch); patchCtx.drawImage(bmp, 0, 0, width, height); var data = patchCtx.getImageData(0, 0, width, height).data; var currData = []; // RGBA -> BGR for (var i = 0; i < data.length; i += 4) { currData.push(data[i + 2]); currData.push(data[i + 1]); currData.push(data[i]); } imagePatchesDatas.push(currData); }); return [2 /*return*/, imagePatchesDatas.map(function (data) { var t = Fe(function () { var imagePatchTensor = kl(xn(data, [1, width, height, 3]), [0, 2, 1, 3]).toFloat(); return normalize$1(imagePatchTensor); }); return t; })]; } }); }); } function RNet(x, params) { return Fe(function () { var convOut = sharedLayer(x, params); var vectorized = hr(convOut, [convOut.shape[0], params.fc1.weights.shape[0]]); var fc1 = fullyConnectedLayer(vectorized, params.fc1); var prelu4 = prelu(fc1, params.prelu4_alpha); var fc2_1 = fullyConnectedLayer(prelu4, params.fc2_1); var max = Zn(_u(fc2_1, 1), 1); var prob = zr(vl(fc2_1, max), 1); var regions = fullyConnectedLayer(prelu4, params.fc2_2); var scores = gr(prob, 1)[1]; return { scores: scores, regions: regions }; }); } function stage2(img, inputBoxes, scoreThreshold, params, stats) { return __awaiter(this, void 0, void 0, function () { var ts, rnetInputs, rnetOuts, scoresTensor, scores, _a, _b, indices, filteredBoxes, filteredScores, finalBoxes, finalScores, indicesNms, regions_1; return __generator(this, function (_c) { switch (_c.label) { case 0: ts = Date.now(); return [4 /*yield*/, extractImagePatches(img, inputBoxes, { width: 24, height: 24 })]; case 1: rnetInputs = _c.sent(); stats.stage2_extractImagePatches = Date.now() - ts; ts = Date.now(); rnetOuts = rnetInputs.map(function (rnetInput) { var out = RNet(rnetInput, params); rnetInput.dispose(); return out; }); stats.stage2_rnet = Date.now() - ts; scoresTensor = rnetOuts.length > 1 ? An(rnetOuts.map(function (out) { return out.scores; })) : rnetOuts[0].scores; _b = (_a = Array).from; return [4 /*yield*/, scoresTensor.data()]; case 2: scores = _b.apply(_a, [_c.sent()]); scoresTensor.dispose(); indices = scores .map(function (score, idx) { return ({ score: score, idx: idx }); }) .filter(function (c) { return c.score > scoreThreshold; }) .map(function (_a) { var idx = _a.idx; return idx; }); filteredBoxes = indices.map(function (idx) { return inputBoxes[idx]; }); filteredScores = indices.map(function (idx) { return scores[idx]; }); finalBoxes = []; finalScores = []; if (filteredBoxes.length > 0) { ts = Date.now(); indicesNms = nonMaxSuppression(filteredBoxes, filteredScores, 0.7); stats.stage2_nms = Date.now() - ts; regions_1 = indicesNms.map(function (idx) { var regionsData = rnetOuts[indices[idx]].regions.arraySync(); return new MtcnnBox(regionsData[0][0], regionsData[0][1], regionsData[0][2], regionsData[0][3]); }); finalScores = indicesNms.map(function (idx) { return filteredScores[idx]; }); finalBoxes = indicesNms.map(function (idx, i) { return filteredBoxes[idx].calibrate(regions_1[i]); }); } rnetOuts.forEach(function (t) { t.regions.dispose(); t.scores.dispose(); }); return [2 /*return*/, { boxes: finalBoxes, scores: finalScores }]; } }); }); } function ONet(x, params) { return Fe(function () { var out = sharedLayer(x, params); out = yu(out, [2, 2], [2, 2], 'same'); out = convLayer(out, params.conv4, 'valid'); out = prelu(out, params.prelu4_alpha); var vectorized = hr(out, [out.shape[0], params.fc1.weights.shape[0]]); var fc1 = fullyConnectedLayer(vectorized, params.fc1); var prelu5 = prelu(fc1, params.prelu5_alpha); var fc2_1 = fullyConnectedLayer(prelu5, params.fc2_1); var max = Zn(_u(fc2_1, 1), 1); var prob = zr(vl(fc2_1, max), 1); var regions = fullyConnectedLayer(prelu5, params.fc2_2); var points = fullyConnectedLayer(prelu5, params.fc2_3); var scores = gr(prob, 1)[1]; return { scores: scores, regions: regions, points: points }; }); } function stage3(img, inputBoxes, scoreThreshold, params, stats) { return __awaiter(this, void 0, void 0, function () { var ts, onetInputs, onetOuts, scoresTensor, scores, _a, _b, indices, filteredRegions, filteredBoxes, filteredScores, finalBoxes, finalScores, points, indicesNms; return __generator(this, function (_c) { switch (_c.label) { case 0: ts = Date.now(); return [4 /*yield*/, extractImagePatches(img, inputBoxes, { width: 48, height: 48 })]; case 1: onetInputs = _c.sent(); stats.stage3_extractImagePatches = Date.now() - ts; ts = Date.now(); onetOuts = onetInputs.map(function (onetInput) { var out = ONet(onetInput, params); onetInput.dispose(); return out; }); stats.stage3_onet = Date.now() - ts; scoresTensor = onetOuts.length > 1 ? An(onetOuts.map(function (out) { return out.scores; })) : onetOuts[0].scores; _b = (_a = Array).from; return [4 /*yield*/, scoresTensor.data()]; case 2: scores = _b.apply(_a, [_c.sent()]); scoresTensor.dispose(); indices = scores .map(function (score, idx) { return ({ score: score, idx: idx }); }) .filter(function (c) { return c.score > scoreThreshold; }) .map(function (_a) { var idx = _a.idx; return idx; }); filteredRegions = indices.map(function (idx) { var regionsData = onetOuts[idx].regions.arraySync(); return new MtcnnBox(regionsData[0][0], regionsData[0][1], regionsData[0][2], regionsData[0][3]); }); filteredBoxes = indices .map(function (idx, i) { return inputBoxes[idx].calibrate(filteredRegions[i]); }); filteredScores = indices.map(function (idx) { return scores[idx]; }); finalBoxes = []; finalScores = []; points = []; if (filteredBoxes.length > 0) { ts = Date.now(); indicesNms = nonMaxSuppression(filteredBoxes, filteredScores, 0.7, false); stats.stage3_nms = Date.now() - ts; finalBoxes = indicesNms.map(function (idx) { return filteredBoxes[idx]; }); finalScores = indicesNms.map(function (idx) { return filteredScores[idx]; }); points = indicesNms.map(function (idx, i) { return Array(5).fill(0).map(function (_, ptIdx) { var pointsData = onetOuts[idx].points.arraySync(); return new Point(((pointsData[0][ptIdx] * (finalBoxes[i].width + 1)) + finalBoxes[i].left), ((pointsData[0][ptIdx + 5] * (finalBoxes[i].height + 1)) + finalBoxes[i].top)); }); }); } onetOuts.forEach(function (t) { t.regions.dispose(); t.scores.dispose(); t.points.dispose(); }); return [2 /*return*/, { boxes: finalBoxes, scores: finalScores, points: points }]; } }); }); } var Mtcnn = /** @class */ (function (_super) { __extends(Mtcnn, _super); function Mtcnn() { return _super.call(this, 'Mtcnn') || this; } Mtcnn.prototype.forwardInput = function (input, forwardParams) { if (forwardParams === void 0) { forwardParams = {}; } return __awaiter(this, void 0, void 0, function () { var params, inputCanvas, stats, tsTotal, imgTensor, onReturn, _a, height, width, _b, minFaceSize, scaleFactor, maxNumScales, scoreThresholds, scaleSteps, scales, ts, out1, out2, out3, results; return __generator(this, function (_c) { switch (_c.label) { case 0: params = this.params; if (!params) { throw new Error('Mtcnn - load model before inference'); } inputCanvas = input.canvases[0]; if (!inputCanvas) { throw new Error('Mtcnn - inputCanvas is not defined, note that passing tensors into Mtcnn.forwardInput is not supported yet.'); } stats = {}; tsTotal = Date.now(); imgTensor = Fe(function () { return bgrToRgbTensor(Zn(kh.fromPixels(inputCanvas)).toFloat()); }); onReturn = function (results) { // dispose tensors on return imgTensor.dispose(); stats.total = Date.now() - tsTotal; return results; }; _a = imgTensor.shape.slice(1), height = _a[0], width = _a[1]; _b = new MtcnnOptions(forwardParams), minFaceSize = _b.minFaceSize, scaleFactor = _b.scaleFactor, maxNumScales = _b.maxNumScales, scoreThresholds = _b.scoreThresholds, scaleSteps = _b.scaleSteps; scales = (scaleSteps || pyramidDown(minFaceSize, scaleFactor, [height, width])) .filter(function (scale) { var sizes = getSizesForScale(scale, [height, width]); return Math.min(sizes.width, sizes.height) > CELL_SIZE; }) .slice(0, maxNumScales); stats.scales = scales; stats.pyramid = scales.map(function (scale) { return getSizesForScale(scale, [height, width]); }); ts = Date.now(); return [4 /*yield*/, stage1(imgTensor, scales, scoreThresholds[0], params.pnet, stats)]; case 1: out1 = _c.sent(); stats.total_stage1 = Date.now() - ts; if (!out1.boxes.length) { return [2 /*return*/, onReturn({ results: [], stats: stats })]; } stats.stage2_numInputBoxes = out1.boxes.length; // using the inputCanvas to extract and resize the image patches, since it is faster // than doing this on the gpu ts = Date.now(); return [4 /*yield*/, stage2(inputCanvas, out1.boxes, scoreThresholds[1], params.rnet, stats)]; case 2: out2 = _c.sent(); stats.total_stage2 = Date.now() - ts; if (!out2.boxes.length) { return [2 /*return*/, onReturn({ results: [], stats: stats })]; } stats.stage3_numInputBoxes = out2.boxes.length; ts = Date.now(); return [4 /*yield*/, stage3(inputCanvas, out2.boxes, scoreThresholds[2], params.onet, stats)]; case 3: out3 = _c.sent(); stats.total_stage3 = Date.now() - ts; results = out3.boxes.map(function (box, idx) { return extendWithFaceLandmarks(extendWithFaceDetection({}, new FaceDetection(out3.scores[idx], new Rect(box.left / width, box.top / height, box.width / width, box.height / height), { height: height, width: width })), new FaceLandmarks5(out3.points[idx].map(function (pt) { return pt.sub(new Point(box.left, box.top)).div(new Point(box.width, box.height)); }), { width: box.width, height: box.height })); }); return [2 /*return*/, onReturn({ results: results, stats: stats })]; } }); }); }; Mtcnn.prototype.forward = function (input, forwardParams) { if (forwardParams === void 0) { forwardParams = {}; } return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [4 /*yield*/, _a.apply(this, [_b.sent(), forwardParams])]; case 2: return [2 /*return*/, (_b.sent()).results]; } }); }); }; Mtcnn.prototype.forwardWithStats = function (input, forwardParams) { if (forwardParams === void 0) { forwardParams = {}; } return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.forwardInput; return [4 /*yield*/, toNetInput(input)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent(), forwardParams])]; } }); }); }; Mtcnn.prototype.getDefaultModelName = function () { return 'mtcnn_model'; }; Mtcnn.prototype.extractParamsFromWeigthMap = function (weightMap) { return extractParamsFromWeigthMap$7(weightMap); }; Mtcnn.prototype.extractParams = function (weights) { return extractParams$7(weights); }; return Mtcnn; }(NeuralNetwork)); var IOU_THRESHOLD = 0.35; var BOX_ANCHORS = [ new Point(1.603231, 2.094468), new Point(6.041143, 7.080126), new Point(2.882459, 3.518061), new Point(4.266906, 5.178857), new Point(9.041765, 10.66308) ]; var MEAN_RGB = [117.001, 114.697, 97.404]; var TinyFaceDetector = /** @class */ (function (_super) { __extends(TinyFaceDetector, _super); function TinyFaceDetector() { var _this = this; var config = { withSeparableConvs: true, iouThreshold: IOU_THRESHOLD, classes: ['face'], anchors: BOX_ANCHORS, meanRgb: MEAN_RGB, isFirstLayerConv2d: true, filterSizes: [3, 16, 32, 64, 128, 256, 512] }; _this = _super.call(this, config) || this; return _this; } Object.defineProperty(TinyFaceDetector.prototype, "anchors", { get: function () { return this.config.anchors; }, enumerable: true, configurable: true }); TinyFaceDetector.prototype.locateFaces = function (input, forwardParams) { return __awaiter(this, void 0, void 0, function () { var objectDetections; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.detect(input, forwardParams)]; case 1: objectDetections = _a.sent(); return [2 /*return*/, objectDetections.map(function (det) { return new FaceDetection(det.score, det.relativeBox, { width: det.imageWidth, height: det.imageHeight }); })]; } }); }); }; TinyFaceDetector.prototype.getDefaultModelName = function () { return 'tiny_face_detector_model'; }; TinyFaceDetector.prototype.extractParamsFromWeigthMap = function (weightMap) { return _super.prototype.extractParamsFromWeigthMap.call(this, weightMap); }; return TinyFaceDetector; }(TinyYolov2)); var IOU_THRESHOLD$1 = 0.35; var BOX_ANCHORS$1 = [ new Point(0.738768, 0.874946), new Point(2.42204, 2.65704), new Point(4.30971, 7.04493), new Point(10.246, 4.59428), new Point(12.6868, 11.8741) ]; var BOX_ANCHORS_SEPARABLE = [ new Point(1.603231, 2.094468), new Point(6.041143, 7.080126), new Point(2.882459, 3.518061), new Point(4.266906, 5.178857), new Point(9.041765, 10.66308) ]; var MEAN_RGB_SEPARABLE = [117.001, 114.697, 97.404]; var DEFAULT_MODEL_NAME = 'tiny_yolov2_model'; var DEFAULT_MODEL_NAME_SEPARABLE_CONV = 'tiny_yolov2_separable_conv_model'; var TinyYolov2$1 = /** @class */ (function (_super) { __extends(TinyYolov2, _super); function TinyYolov2(withSeparableConvs) { if (withSeparableConvs === void 0) { withSeparableConvs = true; } var _this = this; var config = Object.assign({}, { withSeparableConvs: withSeparableConvs, iouThreshold: IOU_THRESHOLD$1, classes: ['face'] }, withSeparableConvs ? { anchors: BOX_ANCHORS_SEPARABLE, meanRgb: MEAN_RGB_SEPARABLE } : { anchors: BOX_ANCHORS$1, withClassScores: true }); _this = _super.call(this, config) || this; return _this; } Object.defineProperty(TinyYolov2.prototype, "withSeparableConvs", { get: function () { return this.config.withSeparableConvs; }, enumerable: true, configurable: true }); Object.defineProperty(TinyYolov2.prototype, "anchors", { get: function () { return this.config.anchors; }, enumerable: true, configurable: true }); TinyYolov2.prototype.locateFaces = function (input, forwardParams) { return __awaiter(this, void 0, void 0, function () { var objectDetections; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.detect(input, forwardParams)]; case 1: objectDetections = _a.sent(); return [2 /*return*/, objectDetections.map(function (det) { return new FaceDetection(det.score, det.relativeBox, { width: det.imageWidth, height: det.imageHeight }); })]; } }); }); }; TinyYolov2.prototype.getDefaultModelName = function () { return this.withSeparableConvs ? DEFAULT_MODEL_NAME_SEPARABLE_CONV : DEFAULT_MODEL_NAME; }; TinyYolov2.prototype.extractParamsFromWeigthMap = function (weightMap) { return _super.prototype.extractParamsFromWeigthMap.call(this, weightMap); }; return TinyYolov2; }(TinyYolov2)); function createTinyYolov2(weights, withSeparableConvs) { if (withSeparableConvs === void 0) { withSeparableConvs = true; } var net = new TinyYolov2$1(withSeparableConvs); net.extractWeights(weights); return net; } var nets = { ssdMobilenetv1: new SsdMobilenetv1(), tinyFaceDetector: new TinyFaceDetector(), tinyYolov2: new TinyYolov2$1(), mtcnn: new Mtcnn(), faceLandmark68Net: new FaceLandmark68Net(), faceLandmark68TinyNet: new FaceLandmark68TinyNet(), faceRecognitionNet: new FaceRecognitionNet(), faceExpressionNet: new FaceExpressionNet(), ageGenderNet: new AgeGenderNet() }; /** * Attempts to detect all faces in an image using SSD Mobilenetv1 Network. * * @param input The input image. * @param options (optional, default: see SsdMobilenetv1Options constructor for default parameters). * @returns Bounding box of each face with score. */ var ssdMobilenetv1 = function (input, options) { return nets.ssdMobilenetv1.locateFaces(input, options); }; /** * Attempts to detect all faces in an image using the Tiny Face Detector. * * @param input The input image. * @param options (optional, default: see TinyFaceDetectorOptions constructor for default parameters). * @returns Bounding box of each face with score. */ var tinyFaceDetector = function (input, options) { return nets.tinyFaceDetector.locateFaces(input, options); }; /** * Attempts to detect all faces in an image using the Tiny Yolov2 Network. * * @param input The input image. * @param options (optional, default: see TinyYolov2Options constructor for default parameters). * @returns Bounding box of each face with score. */ var tinyYolov2 = function (input, options) { return nets.tinyYolov2.locateFaces(input, options); }; /** * Attempts to detect all faces in an image and the 5 point face landmarks * of each detected face using the MTCNN Network. * * @param input The input image. * @param options (optional, default: see MtcnnOptions constructor for default parameters). * @returns Bounding box of each face with score and 5 point face landmarks. */ var mtcnn = function (input, options) { return nets.mtcnn.forward(input, options); }; /** * Detects the 68 point face landmark positions of the face shown in an image. * * @param inputs The face image extracted from the bounding box of a face. Can * also be an array of input images, which will be batch processed. * @returns 68 point face landmarks or array thereof in case of batch input. */ var detectFaceLandmarks = function (input) { return nets.faceLandmark68Net.detectLandmarks(input); }; /** * Detects the 68 point face landmark positions of the face shown in an image * using a tinier version of the 68 point face landmark model, which is slightly * faster at inference, but also slightly less accurate. * * @param inputs The face image extracted from the bounding box of a face. Can * also be an array of input images, which will be batch processed. * @returns 68 point face landmarks or array thereof in case of batch input. */ var detectFaceLandmarksTiny = function (input) { return nets.faceLandmark68TinyNet.detectLandmarks(input); }; /** * Computes a 128 entry vector (face descriptor / face embeddings) from the face shown in an image, * which uniquely represents the features of that persons face. The computed face descriptor can * be used to measure the similarity between faces, by computing the euclidean distance of two * face descriptors. * * @param inputs The face image extracted from the aligned bounding box of a face. Can * also be an array of input images, which will be batch processed. * @returns Face descriptor with 128 entries or array thereof in case of batch input. */ var computeFaceDescriptor = function (input) { return nets.faceRecognitionNet.computeFaceDescriptor(input); }; /** * Recognizes the facial expressions from a face image. * * @param inputs The face image extracted from the bounding box of a face. Can * also be an array of input images, which will be batch processed. * @returns Facial expressions with corresponding probabilities or array thereof in case of batch input. */ var recognizeFaceExpressions = function (input) { return nets.faceExpressionNet.predictExpressions(input); }; /** * Predicts age and gender from a face image. * * @param inputs The face image extracted from the bounding box of a face. Can * also be an array of input images, which will be batch processed. * @returns Predictions with age, gender and gender probability or array thereof in case of batch input. */ var predictAgeAndGender = function (input) { return nets.ageGenderNet.predictAgeAndGender(input); }; var loadSsdMobilenetv1Model = function (url) { return nets.ssdMobilenetv1.load(url); }; var loadTinyFaceDetectorModel = function (url) { return nets.tinyFaceDetector.load(url); }; var loadMtcnnModel = function (url) { return nets.mtcnn.load(url); }; var loadTinyYolov2Model = function (url) { return nets.tinyYolov2.load(url); }; var loadFaceLandmarkModel = function (url) { return nets.faceLandmark68Net.load(url); }; var loadFaceLandmarkTinyModel = function (url) { return nets.faceLandmark68TinyNet.load(url); }; var loadFaceRecognitionModel = function (url) { return nets.faceRecognitionNet.load(url); }; var loadFaceExpressionModel = function (url) { return nets.faceExpressionNet.load(url); }; var loadAgeGenderModel = function (url) { return nets.ageGenderNet.load(url); }; // backward compatibility var loadFaceDetectionModel = loadSsdMobilenetv1Model; var locateFaces = ssdMobilenetv1; var detectLandmarks = detectFaceLandmarks; var PredictFaceExpressionsTaskBase = /** @class */ (function (_super) { __extends(PredictFaceExpressionsTaskBase, _super); function PredictFaceExpressionsTaskBase(parentTask, input, extractedFaces) { var _this = _super.call(this) || this; _this.parentTask = parentTask; _this.input = input; _this.extractedFaces = extractedFaces; return _this; } return PredictFaceExpressionsTaskBase; }(ComposableTask)); var PredictAllFaceExpressionsTask = /** @class */ (function (_super) { __extends(PredictAllFaceExpressionsTask, _super); function PredictAllFaceExpressionsTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictAllFaceExpressionsTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResults, faceExpressionsByFace; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResults = _a.sent(); return [4 /*yield*/, extractAllFacesAndComputeResults(parentResults, this.input, function (faces) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all(faces.map(function (face) { return nets.faceExpressionNet.predictExpressions(face); }))]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }, this.extractedFaces)]; case 2: faceExpressionsByFace = _a.sent(); return [2 /*return*/, parentResults.map(function (parentResult, i) { return extendWithFaceExpressions(parentResult, faceExpressionsByFace[i]); })]; } }); }); }; PredictAllFaceExpressionsTask.prototype.withAgeAndGender = function () { return new PredictAllAgeAndGenderTask(this, this.input); }; return PredictAllFaceExpressionsTask; }(PredictFaceExpressionsTaskBase)); var PredictSingleFaceExpressionsTask = /** @class */ (function (_super) { __extends(PredictSingleFaceExpressionsTask, _super); function PredictSingleFaceExpressionsTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictSingleFaceExpressionsTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResult, faceExpressions; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResult = _a.sent(); if (!parentResult) { return [2 /*return*/]; } return [4 /*yield*/, extractSingleFaceAndComputeResult(parentResult, this.input, function (face) { return nets.faceExpressionNet.predictExpressions(face); }, this.extractedFaces)]; case 2: faceExpressions = _a.sent(); return [2 /*return*/, extendWithFaceExpressions(parentResult, faceExpressions)]; } }); }); }; PredictSingleFaceExpressionsTask.prototype.withAgeAndGender = function () { return new PredictSingleAgeAndGenderTask(this, this.input); }; return PredictSingleFaceExpressionsTask; }(PredictFaceExpressionsTaskBase)); var PredictAllFaceExpressionsWithFaceAlignmentTask = /** @class */ (function (_super) { __extends(PredictAllFaceExpressionsWithFaceAlignmentTask, _super); function PredictAllFaceExpressionsWithFaceAlignmentTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictAllFaceExpressionsWithFaceAlignmentTask.prototype.withAgeAndGender = function () { return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); }; PredictAllFaceExpressionsWithFaceAlignmentTask.prototype.withFaceDescriptors = function () { return new ComputeAllFaceDescriptorsTask(this, this.input); }; return PredictAllFaceExpressionsWithFaceAlignmentTask; }(PredictAllFaceExpressionsTask)); var PredictSingleFaceExpressionsWithFaceAlignmentTask = /** @class */ (function (_super) { __extends(PredictSingleFaceExpressionsWithFaceAlignmentTask, _super); function PredictSingleFaceExpressionsWithFaceAlignmentTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictSingleFaceExpressionsWithFaceAlignmentTask.prototype.withAgeAndGender = function () { return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); }; PredictSingleFaceExpressionsWithFaceAlignmentTask.prototype.withFaceDescriptor = function () { return new ComputeSingleFaceDescriptorTask(this, this.input); }; return PredictSingleFaceExpressionsWithFaceAlignmentTask; }(PredictSingleFaceExpressionsTask)); var PredictAgeAndGenderTaskBase = /** @class */ (function (_super) { __extends(PredictAgeAndGenderTaskBase, _super); function PredictAgeAndGenderTaskBase(parentTask, input, extractedFaces) { var _this = _super.call(this) || this; _this.parentTask = parentTask; _this.input = input; _this.extractedFaces = extractedFaces; return _this; } return PredictAgeAndGenderTaskBase; }(ComposableTask)); var PredictAllAgeAndGenderTask = /** @class */ (function (_super) { __extends(PredictAllAgeAndGenderTask, _super); function PredictAllAgeAndGenderTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictAllAgeAndGenderTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResults, ageAndGenderByFace; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResults = _a.sent(); return [4 /*yield*/, extractAllFacesAndComputeResults(parentResults, this.input, function (faces) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all(faces.map(function (face) { return nets.ageGenderNet.predictAgeAndGender(face); }))]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }, this.extractedFaces)]; case 2: ageAndGenderByFace = _a.sent(); return [2 /*return*/, parentResults.map(function (parentResult, i) { var _a = ageAndGenderByFace[i], age = _a.age, gender = _a.gender, genderProbability = _a.genderProbability; return extendWithAge(extendWithGender(parentResult, gender, genderProbability), age); })]; } }); }); }; PredictAllAgeAndGenderTask.prototype.withFaceExpressions = function () { return new PredictAllFaceExpressionsTask(this, this.input); }; return PredictAllAgeAndGenderTask; }(PredictAgeAndGenderTaskBase)); var PredictSingleAgeAndGenderTask = /** @class */ (function (_super) { __extends(PredictSingleAgeAndGenderTask, _super); function PredictSingleAgeAndGenderTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictSingleAgeAndGenderTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResult, _a, age, gender, genderProbability; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResult = _b.sent(); if (!parentResult) { return [2 /*return*/]; } return [4 /*yield*/, extractSingleFaceAndComputeResult(parentResult, this.input, function (face) { return nets.ageGenderNet.predictAgeAndGender(face); }, this.extractedFaces)]; case 2: _a = _b.sent(), age = _a.age, gender = _a.gender, genderProbability = _a.genderProbability; return [2 /*return*/, extendWithAge(extendWithGender(parentResult, gender, genderProbability), age)]; } }); }); }; PredictSingleAgeAndGenderTask.prototype.withFaceExpressions = function () { return new PredictSingleFaceExpressionsTask(this, this.input); }; return PredictSingleAgeAndGenderTask; }(PredictAgeAndGenderTaskBase)); var PredictAllAgeAndGenderWithFaceAlignmentTask = /** @class */ (function (_super) { __extends(PredictAllAgeAndGenderWithFaceAlignmentTask, _super); function PredictAllAgeAndGenderWithFaceAlignmentTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictAllAgeAndGenderWithFaceAlignmentTask.prototype.withFaceExpressions = function () { return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); }; PredictAllAgeAndGenderWithFaceAlignmentTask.prototype.withFaceDescriptors = function () { return new ComputeAllFaceDescriptorsTask(this, this.input); }; return PredictAllAgeAndGenderWithFaceAlignmentTask; }(PredictAllAgeAndGenderTask)); var PredictSingleAgeAndGenderWithFaceAlignmentTask = /** @class */ (function (_super) { __extends(PredictSingleAgeAndGenderWithFaceAlignmentTask, _super); function PredictSingleAgeAndGenderWithFaceAlignmentTask() { return _super !== null && _super.apply(this, arguments) || this; } PredictSingleAgeAndGenderWithFaceAlignmentTask.prototype.withFaceExpressions = function () { return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); }; PredictSingleAgeAndGenderWithFaceAlignmentTask.prototype.withFaceDescriptor = function () { return new ComputeSingleFaceDescriptorTask(this, this.input); }; return PredictSingleAgeAndGenderWithFaceAlignmentTask; }(PredictSingleAgeAndGenderTask)); var ComputeFaceDescriptorsTaskBase = /** @class */ (function (_super) { __extends(ComputeFaceDescriptorsTaskBase, _super); function ComputeFaceDescriptorsTaskBase(parentTask, input) { var _this = _super.call(this) || this; _this.parentTask = parentTask; _this.input = input; return _this; } return ComputeFaceDescriptorsTaskBase; }(ComposableTask)); var ComputeAllFaceDescriptorsTask = /** @class */ (function (_super) { __extends(ComputeAllFaceDescriptorsTask, _super); function ComputeAllFaceDescriptorsTask() { return _super !== null && _super.apply(this, arguments) || this; } ComputeAllFaceDescriptorsTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResults, descriptors; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResults = _a.sent(); return [4 /*yield*/, extractAllFacesAndComputeResults(parentResults, this.input, function (faces) { return Promise.all(faces.map(function (face) { return nets.faceRecognitionNet.computeFaceDescriptor(face); })); }, null, function (parentResult) { return parentResult.landmarks.align(null, { useDlibAlignment: true }); })]; case 2: descriptors = _a.sent(); return [2 /*return*/, descriptors.map(function (descriptor, i) { return extendWithFaceDescriptor(parentResults[i], descriptor); })]; } }); }); }; ComputeAllFaceDescriptorsTask.prototype.withFaceExpressions = function () { return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); }; ComputeAllFaceDescriptorsTask.prototype.withAgeAndGender = function () { return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); }; return ComputeAllFaceDescriptorsTask; }(ComputeFaceDescriptorsTaskBase)); var ComputeSingleFaceDescriptorTask = /** @class */ (function (_super) { __extends(ComputeSingleFaceDescriptorTask, _super); function ComputeSingleFaceDescriptorTask() { return _super !== null && _super.apply(this, arguments) || this; } ComputeSingleFaceDescriptorTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResult, descriptor; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResult = _a.sent(); if (!parentResult) { return [2 /*return*/]; } return [4 /*yield*/, extractSingleFaceAndComputeResult(parentResult, this.input, function (face) { return nets.faceRecognitionNet.computeFaceDescriptor(face); }, null, function (parentResult) { return parentResult.landmarks.align(null, { useDlibAlignment: true }); })]; case 2: descriptor = _a.sent(); return [2 /*return*/, extendWithFaceDescriptor(parentResult, descriptor)]; } }); }); }; ComputeSingleFaceDescriptorTask.prototype.withFaceExpressions = function () { return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); }; ComputeSingleFaceDescriptorTask.prototype.withAgeAndGender = function () { return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); }; return ComputeSingleFaceDescriptorTask; }(ComputeFaceDescriptorsTaskBase)); var DetectFaceLandmarksTaskBase = /** @class */ (function (_super) { __extends(DetectFaceLandmarksTaskBase, _super); function DetectFaceLandmarksTaskBase(parentTask, input, useTinyLandmarkNet) { var _this = _super.call(this) || this; _this.parentTask = parentTask; _this.input = input; _this.useTinyLandmarkNet = useTinyLandmarkNet; return _this; } Object.defineProperty(DetectFaceLandmarksTaskBase.prototype, "landmarkNet", { get: function () { return this.useTinyLandmarkNet ? nets.faceLandmark68TinyNet : nets.faceLandmark68Net; }, enumerable: true, configurable: true }); return DetectFaceLandmarksTaskBase; }(ComposableTask)); var DetectAllFaceLandmarksTask = /** @class */ (function (_super) { __extends(DetectAllFaceLandmarksTask, _super); function DetectAllFaceLandmarksTask() { return _super !== null && _super.apply(this, arguments) || this; } DetectAllFaceLandmarksTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResults, detections, faces, _a, faceLandmarksByFace; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResults = _b.sent(); detections = parentResults.map(function (res) { return res.detection; }); if (!(this.input instanceof ht)) return [3 /*break*/, 3]; return [4 /*yield*/, extractFaceTensors(this.input, detections)]; case 2: _a = _b.sent(); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, extractFaces(this.input, detections)]; case 4: _a = _b.sent(); _b.label = 5; case 5: faces = _a; return [4 /*yield*/, Promise.all(faces.map(function (face) { return _this.landmarkNet.detectLandmarks(face); }))]; case 6: faceLandmarksByFace = _b.sent(); faces.forEach(function (f) { return f instanceof ht && f.dispose(); }); return [2 /*return*/, parentResults.map(function (parentResult, i) { return extendWithFaceLandmarks(parentResult, faceLandmarksByFace[i]); })]; } }); }); }; DetectAllFaceLandmarksTask.prototype.withFaceExpressions = function () { return new PredictAllFaceExpressionsWithFaceAlignmentTask(this, this.input); }; DetectAllFaceLandmarksTask.prototype.withAgeAndGender = function () { return new PredictAllAgeAndGenderWithFaceAlignmentTask(this, this.input); }; DetectAllFaceLandmarksTask.prototype.withFaceDescriptors = function () { return new ComputeAllFaceDescriptorsTask(this, this.input); }; return DetectAllFaceLandmarksTask; }(DetectFaceLandmarksTaskBase)); var DetectSingleFaceLandmarksTask = /** @class */ (function (_super) { __extends(DetectSingleFaceLandmarksTask, _super); function DetectSingleFaceLandmarksTask() { return _super !== null && _super.apply(this, arguments) || this; } DetectSingleFaceLandmarksTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var parentResult, detection, faces, _a, landmarks; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, this.parentTask]; case 1: parentResult = _b.sent(); if (!parentResult) { return [2 /*return*/]; } detection = parentResult.detection; if (!(this.input instanceof ht)) return [3 /*break*/, 3]; return [4 /*yield*/, extractFaceTensors(this.input, [detection])]; case 2: _a = _b.sent(); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, extractFaces(this.input, [detection])]; case 4: _a = _b.sent(); _b.label = 5; case 5: faces = _a; return [4 /*yield*/, this.landmarkNet.detectLandmarks(faces[0])]; case 6: landmarks = _b.sent(); faces.forEach(function (f) { return f instanceof ht && f.dispose(); }); return [2 /*return*/, extendWithFaceLandmarks(parentResult, landmarks)]; } }); }); }; DetectSingleFaceLandmarksTask.prototype.withFaceExpressions = function () { return new PredictSingleFaceExpressionsWithFaceAlignmentTask(this, this.input); }; DetectSingleFaceLandmarksTask.prototype.withAgeAndGender = function () { return new PredictSingleAgeAndGenderWithFaceAlignmentTask(this, this.input); }; DetectSingleFaceLandmarksTask.prototype.withFaceDescriptor = function () { return new ComputeSingleFaceDescriptorTask(this, this.input); }; return DetectSingleFaceLandmarksTask; }(DetectFaceLandmarksTaskBase)); var DetectFacesTaskBase = /** @class */ (function (_super) { __extends(DetectFacesTaskBase, _super); function DetectFacesTaskBase(input, options) { if (options === void 0) { options = new SsdMobilenetv1Options(); } var _this = _super.call(this) || this; _this.input = input; _this.options = options; return _this; } return DetectFacesTaskBase; }(ComposableTask)); var DetectAllFacesTask = /** @class */ (function (_super) { __extends(DetectAllFacesTask, _super); function DetectAllFacesTask() { return _super !== null && _super.apply(this, arguments) || this; } DetectAllFacesTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var _a, input, options, faceDetectionFunction; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this, input = _a.input, options = _a.options; if (!(options instanceof MtcnnOptions)) return [3 /*break*/, 2]; return [4 /*yield*/, nets.mtcnn.forward(input, options)]; case 1: return [2 /*return*/, (_b.sent()) .map(function (result) { return result.detection; })]; case 2: faceDetectionFunction = options instanceof TinyFaceDetectorOptions ? function (input) { return nets.tinyFaceDetector.locateFaces(input, options); } : (options instanceof SsdMobilenetv1Options ? function (input) { return nets.ssdMobilenetv1.locateFaces(input, options); } : (options instanceof TinyYolov2Options ? function (input) { return nets.tinyYolov2.locateFaces(input, options); } : null)); if (!faceDetectionFunction) { throw new Error('detectFaces - expected options to be instance of TinyFaceDetectorOptions | SsdMobilenetv1Options | MtcnnOptions | TinyYolov2Options'); } return [2 /*return*/, faceDetectionFunction(input)]; } }); }); }; DetectAllFacesTask.prototype.runAndExtendWithFaceDetections = function () { var _this = this; return new Promise(function (res) { return __awaiter(_this, void 0, void 0, function () { var detections; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.run()]; case 1: detections = _a.sent(); return [2 /*return*/, res(detections.map(function (detection) { return extendWithFaceDetection({}, detection); }))]; } }); }); }); }; DetectAllFacesTask.prototype.withFaceLandmarks = function (useTinyLandmarkNet) { if (useTinyLandmarkNet === void 0) { useTinyLandmarkNet = false; } return new DetectAllFaceLandmarksTask(this.runAndExtendWithFaceDetections(), this.input, useTinyLandmarkNet); }; DetectAllFacesTask.prototype.withFaceExpressions = function () { return new PredictAllFaceExpressionsTask(this.runAndExtendWithFaceDetections(), this.input); }; DetectAllFacesTask.prototype.withAgeAndGender = function () { return new PredictAllAgeAndGenderTask(this.runAndExtendWithFaceDetections(), this.input); }; return DetectAllFacesTask; }(DetectFacesTaskBase)); var DetectSingleFaceTask = /** @class */ (function (_super) { __extends(DetectSingleFaceTask, _super); function DetectSingleFaceTask() { return _super !== null && _super.apply(this, arguments) || this; } DetectSingleFaceTask.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { var faceDetections, faceDetectionWithHighestScore; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, new DetectAllFacesTask(this.input, this.options)]; case 1: faceDetections = _a.sent(); faceDetectionWithHighestScore = faceDetections[0]; faceDetections.forEach(function (faceDetection) { if (faceDetection.score > faceDetectionWithHighestScore.score) { faceDetectionWithHighestScore = faceDetection; } }); return [2 /*return*/, faceDetectionWithHighestScore]; } }); }); }; DetectSingleFaceTask.prototype.runAndExtendWithFaceDetection = function () { var _this = this; return new Promise(function (res) { return __awaiter(_this, void 0, void 0, function () { var detection; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.run()]; case 1: detection = _a.sent(); return [2 /*return*/, res(detection ? extendWithFaceDetection({}, detection) : undefined)]; } }); }); }); }; DetectSingleFaceTask.prototype.withFaceLandmarks = function (useTinyLandmarkNet) { if (useTinyLandmarkNet === void 0) { useTinyLandmarkNet = false; } return new DetectSingleFaceLandmarksTask(this.runAndExtendWithFaceDetection(), this.input, useTinyLandmarkNet); }; DetectSingleFaceTask.prototype.withFaceExpressions = function () { return new PredictSingleFaceExpressionsTask(this.runAndExtendWithFaceDetection(), this.input); }; DetectSingleFaceTask.prototype.withAgeAndGender = function () { return new PredictSingleAgeAndGenderTask(this.runAndExtendWithFaceDetection(), this.input); }; return DetectSingleFaceTask; }(DetectFacesTaskBase)); function detectSingleFace(input, options) { if (options === void 0) { options = new SsdMobilenetv1Options(); } return new DetectSingleFaceTask(input, options); } function detectAllFaces(input, options) { if (options === void 0) { options = new SsdMobilenetv1Options(); } return new DetectAllFacesTask(input, options); } // export allFaces API for backward compatibility function allFacesSsdMobilenetv1(input, minConfidence) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, detectAllFaces(input, new SsdMobilenetv1Options(minConfidence ? { minConfidence: minConfidence } : {})) .withFaceLandmarks() .withFaceDescriptors()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); } function allFacesTinyYolov2(input, forwardParams) { if (forwardParams === void 0) { forwardParams = {}; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, detectAllFaces(input, new TinyYolov2Options(forwardParams)) .withFaceLandmarks() .withFaceDescriptors()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); } function allFacesMtcnn(input, forwardParams) { if (forwardParams === void 0) { forwardParams = {}; } return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, detectAllFaces(input, new MtcnnOptions(forwardParams)) .withFaceLandmarks() .withFaceDescriptors()]; case 1: return [2 /*return*/, _a.sent()]; } }); }); } var allFaces = allFacesSsdMobilenetv1; function euclideanDistance(arr1, arr2) { if (arr1.length !== arr2.length) throw new Error('euclideanDistance: arr1.length !== arr2.length'); var desc1 = Array.from(arr1); var desc2 = Array.from(arr2); return Math.sqrt(desc1 .map(function (val, i) { return val - desc2[i]; }) .reduce(function (res, diff) { return res + Math.pow(diff, 2); }, 0)); } var FaceMatcher = /** @class */ (function () { function FaceMatcher(inputs, distanceThreshold) { if (distanceThreshold === void 0) { distanceThreshold = 0.5; } this._distanceThreshold = distanceThreshold; var inputArray = Array.isArray(inputs) ? inputs : [inputs]; if (!inputArray.length) { throw new Error("FaceRecognizer.constructor - expected atleast one input"); } var count = 1; var createUniqueLabel = function () { return "person " + count++; }; this._labeledDescriptors = inputArray.map(function (desc) { if (desc instanceof LabeledFaceDescriptors) { return desc; } if (desc instanceof Float32Array) { return new LabeledFaceDescriptors(createUniqueLabel(), [desc]); } if (desc.descriptor && desc.descriptor instanceof Float32Array) { return new LabeledFaceDescriptors(createUniqueLabel(), [desc.descriptor]); } throw new Error("FaceRecognizer.constructor - expected inputs to be of type LabeledFaceDescriptors | WithFaceDescriptor | Float32Array | Array | Float32Array>"); }); } Object.defineProperty(FaceMatcher.prototype, "labeledDescriptors", { get: function () { return this._labeledDescriptors; }, enumerable: true, configurable: true }); Object.defineProperty(FaceMatcher.prototype, "distanceThreshold", { get: function () { return this._distanceThreshold; }, enumerable: true, configurable: true }); FaceMatcher.prototype.computeMeanDistance = function (queryDescriptor, descriptors) { return descriptors .map(function (d) { return euclideanDistance(d, queryDescriptor); }) .reduce(function (d1, d2) { return d1 + d2; }, 0) / (descriptors.length || 1); }; FaceMatcher.prototype.matchDescriptor = function (queryDescriptor) { var _this = this; return this.labeledDescriptors .map(function (_a) { var descriptors = _a.descriptors, label = _a.label; return new FaceMatch(label, _this.computeMeanDistance(queryDescriptor, descriptors)); }) .reduce(function (best, curr) { return best.distance < curr.distance ? best : curr; }); }; FaceMatcher.prototype.findBestMatch = function (queryDescriptor) { var bestMatch = this.matchDescriptor(queryDescriptor); return bestMatch.distance < this.distanceThreshold ? bestMatch : new FaceMatch('unknown', bestMatch.distance); }; return FaceMatcher; }()); function createMtcnn(weights) { var net = new Mtcnn(); net.extractWeights(weights); return net; } function createTinyFaceDetector(weights) { var net = new TinyFaceDetector(); net.extractWeights(weights); return net; } function resizeResults(results, dimensions) { var _a = new Dimensions(dimensions.width, dimensions.height), width = _a.width, height = _a.height; if (width <= 0 || height <= 0) { throw new Error("resizeResults - invalid dimensions: " + JSON.stringify({ width: width, height: height })); } if (Array.isArray(results)) { return results.map(function (obj) { return resizeResults(obj, { width: width, height: height }); }); } if (isWithFaceLandmarks(results)) { var resizedDetection = results.detection.forSize(width, height); var resizedLandmarks = results.unshiftedLandmarks.forSize(resizedDetection.box.width, resizedDetection.box.height); return extendWithFaceLandmarks(extendWithFaceDetection(results, resizedDetection), resizedLandmarks); } if (isWithFaceDetection(results)) { return extendWithFaceDetection(results, results.detection.forSize(width, height)); } if (results instanceof FaceLandmarks || results instanceof FaceDetection) { return results.forSize(width, height); } return results; } var draw = __assign({}, drawBase, drawExtended); exports.AgeGenderNet = AgeGenderNet; exports.BoundingBox = BoundingBox; exports.Box = Box; exports.ComposableTask = ComposableTask; exports.ComputeAllFaceDescriptorsTask = ComputeAllFaceDescriptorsTask; exports.ComputeFaceDescriptorsTaskBase = ComputeFaceDescriptorsTaskBase; exports.ComputeSingleFaceDescriptorTask = ComputeSingleFaceDescriptorTask; exports.DetectAllFaceLandmarksTask = DetectAllFaceLandmarksTask; exports.DetectAllFacesTask = DetectAllFacesTask; exports.DetectFaceLandmarksTaskBase = DetectFaceLandmarksTaskBase; exports.DetectFacesTaskBase = DetectFacesTaskBase; exports.DetectSingleFaceLandmarksTask = DetectSingleFaceLandmarksTask; exports.DetectSingleFaceTask = DetectSingleFaceTask; exports.Dimensions = Dimensions; exports.FACE_EXPRESSION_LABELS = FACE_EXPRESSION_LABELS; exports.FaceDetection = FaceDetection; exports.FaceDetectionNet = FaceDetectionNet; exports.FaceExpressionNet = FaceExpressionNet; exports.FaceExpressions = FaceExpressions; exports.FaceLandmark68Net = FaceLandmark68Net; exports.FaceLandmark68TinyNet = FaceLandmark68TinyNet; exports.FaceLandmarkNet = FaceLandmarkNet; exports.FaceLandmarks = FaceLandmarks; exports.FaceLandmarks5 = FaceLandmarks5; exports.FaceLandmarks68 = FaceLandmarks68; exports.FaceMatch = FaceMatch; exports.FaceMatcher = FaceMatcher; exports.FaceRecognitionNet = FaceRecognitionNet; exports.LabeledBox = LabeledBox; exports.LabeledFaceDescriptors = LabeledFaceDescriptors; exports.Mtcnn = Mtcnn; exports.MtcnnOptions = MtcnnOptions; exports.NetInput = NetInput; exports.NeuralNetwork = NeuralNetwork; exports.ObjectDetection = ObjectDetection; exports.Point = Point; exports.PredictedBox = PredictedBox; exports.Rect = Rect; exports.SsdMobilenetv1 = SsdMobilenetv1; exports.SsdMobilenetv1Options = SsdMobilenetv1Options; exports.TfjsImageRecognitionBase = tfjsImageRecognitionBase; exports.TinyFaceDetector = TinyFaceDetector; exports.TinyFaceDetectorOptions = TinyFaceDetectorOptions; exports.TinyYolov2 = TinyYolov2$1; exports.allFaces = allFaces; exports.allFacesMtcnn = allFacesMtcnn; exports.allFacesSsdMobilenetv1 = allFacesSsdMobilenetv1; exports.allFacesTinyYolov2 = allFacesTinyYolov2; exports.awaitMediaLoaded = awaitMediaLoaded; exports.bufferToImage = bufferToImage; exports.computeFaceDescriptor = computeFaceDescriptor; exports.computeReshapedDimensions = computeReshapedDimensions; exports.createCanvas = createCanvas; exports.createCanvasFromMedia = createCanvasFromMedia; exports.createFaceDetectionNet = createFaceDetectionNet; exports.createFaceRecognitionNet = createFaceRecognitionNet; exports.createMtcnn = createMtcnn; exports.createSsdMobilenetv1 = createSsdMobilenetv1; exports.createTinyFaceDetector = createTinyFaceDetector; exports.createTinyYolov2 = createTinyYolov2; exports.detectAllFaces = detectAllFaces; exports.detectFaceLandmarks = detectFaceLandmarks; exports.detectFaceLandmarksTiny = detectFaceLandmarksTiny; exports.detectLandmarks = detectLandmarks; exports.detectSingleFace = detectSingleFace; exports.draw = draw; exports.env = env; exports.euclideanDistance = euclideanDistance; exports.extendWithAge = extendWithAge; exports.extendWithFaceDescriptor = extendWithFaceDescriptor; exports.extendWithFaceDetection = extendWithFaceDetection; exports.extendWithFaceExpressions = extendWithFaceExpressions; exports.extendWithFaceLandmarks = extendWithFaceLandmarks; exports.extendWithGender = extendWithGender; exports.extractFaceTensors = extractFaceTensors; exports.extractFaces = extractFaces; exports.fetchImage = fetchImage; exports.fetchJson = fetchJson; exports.fetchNetWeights = fetchNetWeights; exports.fetchOrThrow = fetchOrThrow; exports.getCenterPoint = getCenterPoint; exports.getContext2dOrThrow = getContext2dOrThrow; exports.getMediaDimensions = getMediaDimensions; exports.imageTensorToCanvas = imageTensorToCanvas; exports.imageToSquare = imageToSquare; exports.inverseSigmoid = inverseSigmoid; exports.iou = iou; exports.isDimensions = isDimensions; exports.isEven = isEven; exports.isFloat = isFloat; exports.isMediaElement = isMediaElement; exports.isMediaLoaded = isMediaLoaded; exports.isTensor = isTensor; exports.isTensor1D = isTensor1D; exports.isTensor2D = isTensor2D; exports.isTensor3D = isTensor3D; exports.isTensor4D = isTensor4D; exports.isValidNumber = isValidNumber; exports.isValidProbablitiy = isValidProbablitiy; exports.isWithAge = isWithAge; exports.isWithFaceDetection = isWithFaceDetection; exports.isWithFaceExpressions = isWithFaceExpressions; exports.isWithFaceLandmarks = isWithFaceLandmarks; exports.isWithGender = isWithGender; exports.loadAgeGenderModel = loadAgeGenderModel; exports.loadFaceDetectionModel = loadFaceDetectionModel; exports.loadFaceExpressionModel = loadFaceExpressionModel; exports.loadFaceLandmarkModel = loadFaceLandmarkModel; exports.loadFaceLandmarkTinyModel = loadFaceLandmarkTinyModel; exports.loadFaceRecognitionModel = loadFaceRecognitionModel; exports.loadMtcnnModel = loadMtcnnModel; exports.loadSsdMobilenetv1Model = loadSsdMobilenetv1Model; exports.loadTinyFaceDetectorModel = loadTinyFaceDetectorModel; exports.loadTinyYolov2Model = loadTinyYolov2Model; exports.loadWeightMap = loadWeightMap; exports.locateFaces = locateFaces; exports.matchDimensions = matchDimensions; exports.minBbox = minBbox; exports.mtcnn = mtcnn; exports.nets = nets; exports.nonMaxSuppression = nonMaxSuppression; exports.normalize = normalize; exports.padToSquare = padToSquare; exports.predictAgeAndGender = predictAgeAndGender; exports.range = range; exports.recognizeFaceExpressions = recognizeFaceExpressions; exports.resizeResults = resizeResults; exports.resolveInput = resolveInput; exports.round = round; exports.shuffleArray = shuffleArray; exports.sigmoid = sigmoid; exports.ssdMobilenetv1 = ssdMobilenetv1; exports.tf = tfCore_esm; exports.tinyFaceDetector = tinyFaceDetector; exports.tinyYolov2 = tinyYolov2; exports.toNetInput = toNetInput; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=face-api.js.map