!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@tensorflow/tfjs-core")):"function"==typeof define&&define.amd?define(["exports","@tensorflow/tfjs-core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).tf=e.tf||{},e.tf)}(this,(function(e,t){"use strict";function n(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var a=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,a.get?a:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,t}var a=n(t);const r={},o={alpha:!1,antialias:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,depth:!1,stencil:!1,failIfMajorPerformanceCaveat:!0};function s(e,t){r[e]=t}function i(e,n){if(!(e in r)||null!=n){const a=function(e,n){if(1!==e&&2!==e)throw new Error("Cannot get WebGL rendering context, WebGL is disabled.");const a=null==n?function(e){if(t.env().getBool("IS_SAFARI")||"undefined"==typeof OffscreenCanvas||2!==e){if("undefined"!=typeof document)return document.createElement("canvas");throw new Error("Cannot create a canvas in this context")}return new OffscreenCanvas(300,150)}(e):n;a.addEventListener("webglcontextlost",(t=>{t.preventDefault(),delete r[e]}),!1),t.env().getBool("SOFTWARE_WEBGL_ENABLED")&&(o.failIfMajorPerformanceCaveat=!1);if(1===e)return a.getContext("webgl",o)||a.getContext("experimental-webgl",o);return a.getContext("webgl2",o)}(e,n);if(null===a)return console.log("Could not get context for WebGL version",e),null;r[e]=a}const a=r[e];return null==a||a.isContextLost()?(delete r[e],i(e)):(a.disable(a.DEPTH_TEST),a.disable(a.STENCIL_TEST),a.disable(a.BLEND),a.disable(a.DITHER),a.disable(a.POLYGON_OFFSET_FILL),a.disable(a.SAMPLE_COVERAGE),a.enable(a.SCISSOR_TEST),a.enable(a.CULL_FACE),a.cullFace(a.BACK),r[e])}var l,u,c;function d(e,t){return[t,e]}function p(e){const n=t.util.sizeFromShape(e),a=Math.ceil(n/4);return t.util.sizeToSquarishShape(a)}function h(e,t){return[Math.max(1,Math.ceil(t/2)),Math.max(1,Math.ceil(e/2))]}function f(e,n){const a=e;let r,o,s,i,l,u,c,d,p,h;return 2===t.env().getNumber("WEBGL_VERSION")?(r=a.R32F,o=a.R16F,s=a.RGBA16F,i=a.RGBA32F,l=a.RED,c=4,d=1,p=a.HALF_FLOAT,h=a.FLOAT,u=a.RGBA8):(r=e.RGBA,o=e.RGBA,s=e.RGBA,i=a.RGBA,l=e.RGBA,c=4,d=4,p=null!=n?n.HALF_FLOAT_OES:null,h=e.FLOAT,u=e.RGBA),{internalFormatFloat:r,internalFormatHalfFloat:o,internalFormatPackedHalfFloat:s,internalFormatPackedFloat:i,textureFormatFloat:l,downloadTextureFormat:u,downloadUnpackNumChannels:c,defaultNumChannels:d,textureTypeHalfFloat:p,textureTypeFloat:h}}function x(e,n){const a=n();return t.env().getBool("DEBUG")&&function(e){const t=e.getError();if(t!==e.NO_ERROR)throw new Error("WebGL Error: "+g(e,t))}(e),a}!function(e){e[e.DENSE=0]="DENSE",e[e.SHARED_BATCH=1]="SHARED_BATCH"}(l||(l={})),function(e){e[e.RENDER=0]="RENDER",e[e.UPLOAD=1]="UPLOAD",e[e.PIXELS=2]="PIXELS",e[e.DOWNLOAD=3]="DOWNLOAD"}(u||(u={})),function(e){e[e.UNPACKED_FLOAT16=0]="UNPACKED_FLOAT16",e[e.UNPACKED_FLOAT32=1]="UNPACKED_FLOAT32",e[e.PACKED_4X1_UNSIGNED_BYTE=2]="PACKED_4X1_UNSIGNED_BYTE",e[e.PACKED_2X2_FLOAT32=3]="PACKED_2X2_FLOAT32",e[e.PACKED_2X2_FLOAT16=4]="PACKED_2X2_FLOAT16"}(c||(c={}));function m(e){return!!(t.env().getBool("WEBGL_RENDER_FLOAT32_ENABLED")||0===e||5.96e-8<Math.abs(e)&&Math.abs(e)<65504)}function g(e,t){switch(t){case e.NO_ERROR:return"NO_ERROR";case e.INVALID_ENUM:return"INVALID_ENUM";case e.INVALID_VALUE:return"INVALID_VALUE";case e.INVALID_OPERATION:return"INVALID_OPERATION";case e.INVALID_FRAMEBUFFER_OPERATION:return"INVALID_FRAMEBUFFER_OPERATION";case e.OUT_OF_MEMORY:return"OUT_OF_MEMORY";case e.CONTEXT_LOST_WEBGL:return"CONTEXT_LOST_WEBGL";default:return`Unknown error code ${t}`}}function b(e,t){return W(e,(()=>e.getExtension(t)),'Extension "'+t+'" not supported on this browser.')}function v(e,t){const n=W(e,(()=>e.createShader(e.VERTEX_SHADER)),"Unable to create vertex WebGLShader.");if(x(e,(()=>e.shaderSource(n,t))),x(e,(()=>e.compileShader(n))),!1===e.getShaderParameter(n,e.COMPILE_STATUS))throw console.log(e.getShaderInfoLog(n)),new Error("Failed to compile vertex shader.");return n}function C(e,n){const a=W(e,(()=>e.createShader(e.FRAGMENT_SHADER)),"Unable to create fragment WebGLShader.");if(x(e,(()=>e.shaderSource(a,n))),x(e,(()=>e.compileShader(a))),t.env().get("ENGINE_COMPILE_ONLY"))return a;if(!1===e.getShaderParameter(a,e.COMPILE_STATUS))throw y(n,e.getShaderInfoLog(a)),new Error("Failed to compile fragment shader.");return a}const $=/ERROR: [0-9]+:([0-9]+):/g;function y(e,n){const a=$.exec(n);if(null==a)return console.log(`Couldn't parse line number in error: ${n}`),void console.log(e);const r=+a[1],o=e.split("\n"),s=o.length.toString().length+2,i=o.map(((e,n)=>t.util.rightPad((n+1).toString(),s)+e));let l=0;for(let e=0;e<i.length;e++)l=Math.max(i[e].length,l);const u=i.slice(0,r-1),c=i.slice(r-1,r),d=i.slice(r);console.log(u.join("\n")),console.log(n.split("\n")[0]),console.log(`%c ${t.util.rightPad(c[0],l)}`,"border:1px solid red; background-color:#e3d2d2; color:#a61717"),console.log(d.join("\n"))}function I(e){return W(e,(()=>e.createProgram()),"Unable to create WebGLProgram.")}function w(e,n){if(x(e,(()=>e.linkProgram(n))),!t.env().get("ENGINE_COMPILE_ONLY")&&!1===e.getProgramParameter(n,e.LINK_STATUS))throw console.log(e.getProgramInfoLog(n)),new Error("Failed to link vertex and fragment shaders.")}function S(e,t){if(x(e,(()=>e.validateProgram(t))),!1===e.getProgramParameter(t,e.VALIDATE_STATUS))throw console.log(e.getProgramInfoLog(t)),new Error("Shader program validation failed.")}function k(e,t){const n=W(e,(()=>e.createBuffer()),"Unable to create WebGLBuffer");return x(e,(()=>e.bindBuffer(e.ARRAY_BUFFER,n))),x(e,(()=>e.bufferData(e.ARRAY_BUFFER,t,e.STATIC_DRAW))),n}function R(e,t){const n=W(e,(()=>e.createBuffer()),"Unable to create WebGLBuffer");return x(e,(()=>e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,n))),x(e,(()=>e.bufferData(e.ELEMENT_ARRAY_BUFFER,t,e.STATIC_DRAW))),n}function T(e){return W(e,(()=>e.createTexture()),"Unable to create WebGLTexture.")}function N(e,n){const a=t.env().getNumber("WEBGL_MAX_TEXTURE_SIZE");if(e<=0||n<=0){throw new Error("Requested texture size "+`[${e}x${n}]`+" is invalid.")}if(e>a||n>a){throw new Error("Requested texture size "+`[${e}x${n}]`+" greater than WebGL maximum on this browser / GPU "+`[${a}x${a}]`+".")}}function E(e){return W(e,(()=>e.createFramebuffer()),"Unable to create WebGLFramebuffer.")}function A(e,t,n,a,r,o,s){const i=e.getAttribLocation(t,n);return-1!==i&&(x(e,(()=>e.bindBuffer(e.ARRAY_BUFFER,a))),x(e,(()=>e.vertexAttribPointer(i,r,e.FLOAT,!1,o,s))),x(e,(()=>e.enableVertexAttribArray(i))),!0)}function _(e,t,n){U(e,n),x(e,(()=>e.activeTexture(e.TEXTURE0+n))),x(e,(()=>e.bindTexture(e.TEXTURE_2D,t)))}function O(e,t,n){return W(e,(()=>e.getUniformLocation(t,n)),'uniform "'+n+'" not present in program.')}function F(e,t,n){return e.getUniformLocation(t,n)}function D(e,t,n,a){x(e,(()=>_(e,t,a))),x(e,(()=>e.uniform1i(n,a)))}function P(e,t,n){x(e,(()=>e.bindFramebuffer(e.FRAMEBUFFER,n))),x(e,(()=>e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0)))}function L(e,t){x(e,(()=>e.bindFramebuffer(e.FRAMEBUFFER,t))),x(e,(()=>e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,null,0)))}function B(e){const t=e.checkFramebufferStatus(e.FRAMEBUFFER);if(t!==e.FRAMEBUFFER_COMPLETE)throw new Error("Error binding framebuffer: "+V(e,t))}function V(e,t){switch(t){case e.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_ATTACHMENT";case e.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";case e.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:return"FRAMEBUFFER_INCOMPLETE_DIMENSIONS";case e.FRAMEBUFFER_UNSUPPORTED:return"FRAMEBUFFER_UNSUPPORTED";default:return`unknown error ${t}`}}function W(e,t,n){const a=x(e,(()=>t()));if(null==a)throw new Error(n);return a}function U(e,t){const n=e.MAX_COMBINED_TEXTURE_IMAGE_UNITS-1,a=t+e.TEXTURE0;if(a<e.TEXTURE0||a>n){throw new Error(`textureUnit must be in ${`[gl.TEXTURE0, gl.TEXTURE${n}]`}.`)}}function M(e,n=2){return t.util.sizeFromShape(e.slice(0,e.length-n))}function G(e){if(0===e.length)throw Error("Cannot get rows and columns of an empty shape array.");return[e.length>1?e[e.length-2]:1,e[e.length-1]]}function z(e){let t=[1,1,1];return 0===e.length||1===e.length&&1===e[0]||(t=[M(e),...G(e)]),t}function X(e,n=!1){let a=t.env().getNumber("WEBGL_MAX_TEXTURE_SIZE"),r=t.env().getNumber("WEBGL_MAX_SIZE_FOR_NARROW_TEXTURE");if(r===1/0&&t.env().getBool("WEBGL_AUTO_SQUARIFY_NARROW_TEXTURE_SHAPE")&&(r=a/2),n&&(a*=2,r*=2,1===(e=e.map(((n,a)=>a>=e.length-2?t.util.nearestLargerEven(e[a]):e[a]))).length&&(e=[2,e[0]])),2!==e.length){const n=t.util.squeezeShape(e);e=n.newShape}let o=t.util.sizeFromShape(e),s=null;e.length<=1&&o<=a?s=[1,o]:2===e.length&&e[0]<=a&&e[1]<=a?s=e:3===e.length&&e[0]*e[1]<=a&&e[2]<=a?s=[e[0]*e[1],e[2]]:3===e.length&&e[0]<=a&&e[1]*e[2]<=a?s=[e[0],e[1]*e[2]]:4===e.length&&e[0]*e[1]*e[2]<=a&&e[3]<=a?s=[e[0]*e[1]*e[2],e[3]]:4===e.length&&e[0]<=a&&e[1]*e[2]*e[3]<=a&&(s=[e[0],e[1]*e[2]*e[3]]);const i=null!=s&&Math.max(...s)>r&&Math.min(...s)<=(n?2:1)&&Math.min(...s)>0;if(null==s||i)if(n){const n=M(e);let a=2,r=2;e.length&&([a,r]=G(e)),o=n*(a/2)*(r/2),s=t.util.sizeToSquarishShape(o).map((e=>2*e))}else s=t.util.sizeToSquarishShape(o);return s}function H(e){return e%2==0}function j(e,n){if(e=e.slice(-2),n=n.slice(-2),t.util.arraysEqual(e,n))return!0;if(!e.length||!n.length)return!0;if(0===e[0]||0===e[1]||0===n[0]||0===n[1])return!0;if(e.length!==n.length){const t=e[e.length-1],a=n[n.length-1];if(t===a)return!0;if(H(t)&&H(a)&&(1===e[0]||1===n[0]))return!0}return e[1]===n[1]&&H(e[0])&&H(n[0])}let K,q;function Y(e){if(null==K){const t=i(e);K=t.getParameter(t.MAX_TEXTURE_SIZE)}return K}function Q(e){if(null==q){const t=i(e);q=t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS)}return Math.min(16,q)}function Z(e){if(0===e)return 0;let t;const n=i(e);return t=J(n,"EXT_disjoint_timer_query_webgl2")&&2===e?2:J(n,"EXT_disjoint_timer_query")?1:0,t}function J(e,t){return null!=e.getExtension(t)}function ee(e){try{if(null!=i(e))return!0}catch(e){return console.log("Error when getting WebGL context: ",e),!1}return!1}function te(e){if(0===e)return!1;const t=i(e);if(1===e){if(!J(t,"OES_texture_float"))return!1}else if(!J(t,"EXT_color_buffer_float"))return!1;return ae(t)}function ne(e){if(0===e)return!1;const t=i(e);if(1!==e){if(J(t,"EXT_color_buffer_float"))return ae(t);const e="EXT_color_buffer_half_float";if(J(t,e)){const n=t.getExtension(e);return function(e,t){const n=f(e,t),a=e.createTexture();e.bindTexture(e.TEXTURE_2D,a);const r=1,o=1;e.texImage2D(e.TEXTURE_2D,0,n.internalFormatHalfFloat,r,o,0,n.textureFormatFloat,n.textureTypeHalfFloat,null);const s=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,s),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,a,0);const i=e.checkFramebufferStatus(e.FRAMEBUFFER)===e.FRAMEBUFFER_COMPLETE;return e.bindTexture(e.TEXTURE_2D,null),e.bindFramebuffer(e.FRAMEBUFFER,null),e.deleteTexture(a),e.deleteFramebuffer(s),i}(t,n)}return!1}if(!J(t,"OES_texture_float"))return!1;if(!J(t,"WEBGL_color_buffer_float"))return!1;return ae(t)}function ae(e){const t=f(e),n=e.createTexture();e.bindTexture(e.TEXTURE_2D,n);e.texImage2D(e.TEXTURE_2D,0,t.internalFormatFloat,1,1,0,t.textureFormatFloat,t.textureTypeFloat,null);const a=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,a),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,n,0);const r=e.checkFramebufferStatus(e.FRAMEBUFFER)===e.FRAMEBUFFER_COMPLETE;return e.bindTexture(e.TEXTURE_2D,null),e.bindFramebuffer(e.FRAMEBUFFER,null),e.deleteTexture(n),e.deleteFramebuffer(a),r}function re(e){if(2!==e)return!1;return null!=i(e).fenceSync}function oe(e,n){Array.isArray(e)||(e=[e]),e.forEach((e=>{null!=e&&t.util.assert("complex64"!==e.dtype,(()=>`${n} does not support complex64 tensors in the WebGL backend.`))}))}var se={__proto__:null,assertNotComplex:oe,bindCanvasToFramebuffer:function(e){x(e,(()=>e.bindFramebuffer(e.FRAMEBUFFER,null))),x(e,(()=>e.viewport(0,0,e.canvas.width,e.canvas.height))),x(e,(()=>e.scissor(0,0,e.canvas.width,e.canvas.height)))},bindColorTextureToFramebuffer:P,bindTextureToProgramUniformSampler:D,bindTextureUnit:_,bindVertexBufferToProgramAttribute:A,callAndCheck:x,canBeRepresented:m,createFragmentShader:C,createFramebuffer:E,createProgram:I,createStaticIndexBuffer:R,createStaticVertexBuffer:k,createTexture:T,createVertexShader:v,getBatchDim:M,getExtensionOrThrow:b,getFramebufferErrorMessage:V,getMaxTexturesInShader:Q,getNumChannels:function(){return 2===t.env().getNumber("WEBGL_VERSION")?1:4},getProgramUniformLocation:F,getProgramUniformLocationOrThrow:O,getRowsCols:G,getShapeAs3D:z,getTextureShapeFromLogicalShape:X,getWebGLDisjointQueryTimerVersion:Z,getWebGLErrorMessage:g,getWebGLMaxTextureSize:Y,hasExtension:J,isCapableOfRenderingToFloatTexture:te,isDownloadFloatTextureEnabled:ne,isReshapeFree:j,isWebGLFenceEnabled:re,isWebGLVersionEnabled:ee,linkProgram:w,logShaderSourceAndInfoLog:y,resetMaxTextureSize:function(){K=null},resetMaxTexturesInShader:function(){q=null},unbindColorTextureFromFramebuffer:L,unbindTextureUnit:function(e,t){U(e,t),x(e,(()=>e.activeTexture(e.TEXTURE0+t))),x(e,(()=>e.bindTexture(e.TEXTURE_2D,null)))},validateFramebuffer:B,validateProgram:S,validateTextureSize:N};const ie=t.env();function le(){let e,n,a,r,o,s,i,l,u,c;return 2===t.env().getNumber("WEBGL_VERSION")?(e="#version 300 es",n="in",a="out",r="in",o="texture",s="outputColor",i="out vec4 outputColor;",l=t.env().getBool("WEBGL2_ISNAN_CUSTOM")?"\n bool isnan_custom(float val) {\n uint floatToUint = floatBitsToUint(val);\n return (floatToUint & 0x7fffffffu) > 0x7f800000u;\n }\n\n bvec4 isnan_custom(vec4 val) {\n return bvec4(isnan_custom(val.x),\n isnan_custom(val.y), isnan_custom(val.z), isnan_custom(val.w));\n }\n\n #define isnan(value) isnan_custom(value)\n ":"",u="",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 "):(e="",n="attribute",a="varying",r="varying",o="texture2D",s="gl_FragColor",i="",l="\n #define isnan(value) isnan_custom(value)\n bool isnan_custom(float val) {\n return (val > 0. || val < 1. || val == 0.) ? false : true;\n }\n bvec4 isnan_custom(vec4 val) {\n return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w));\n }\n ",u="\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:e,attribute:n,varyingVs:a,varyingFs:r,texture2D:o,output:s,defineOutput:i,defineSpecialNaN:l,defineSpecialInf:u,defineRound:c}}function ue(e,n,a="index"){const r=t.util.computeStrides(n);return r.map(((t,n)=>`${`int ${e[n]} = ${a} / ${t}`}; ${n===r.length-1?`int ${e[n+1]} = ${a} - ${e[n]} * ${t}`:`index -= ${e[n]} * ${t}`};`)).join("")}function ce(e,n,a="index"){const r=t.util.computeStrides(n);return r.map(((t,n)=>`${`int ${e[n]} = ${a} / outShapeStrides[${n}]`}; ${n===r.length-1?`int ${e[n+1]} = ${a} - ${e[n]} * outShapeStrides[${n}]`:`index -= ${e[n]} * outShapeStrides[${n}]`};`)).join("")}function de(e,t,n="index"){const a=function(e,t){const n=e.length,a=e.map((e=>`${t}[${e}]`)),r=new Array(n-1);r[n-2]=a[n-1];for(let e=n-3;e>=0;--e)r[e]=`(${r[e+1]} * ${a[e+1]})`;return r}(e.map(((e,t)=>t)),t);return a.map(((t,r)=>`${`int ${e[r]} = ${n} / ${a[r]}`}; ${r===a.length-1?`int ${e[r+1]} = ${n} - ${e[r]} * ${a[r]}`:`index -= ${e[r]} * ${a[r]}`};`)).join("")}function pe(e){const n=t.util.computeStrides(e).map((e=>e.toString()));return`\n int getFlatIndex(ivec3 coords) {\n return coords.x * ${n[0]} + coords.y * ${n[1]} + coords.z;\n }\n`}ie.registerFlag("HAS_WEBGL",(()=>ie.getNumber("WEBGL_VERSION")>0)),ie.registerFlag("WEBGL_VERSION",(()=>ee(2)?2:ee(1)?1:0)),ie.registerFlag("WEBGL_CHECK_NUMERICAL_PROBLEMS",(()=>!1)),ie.registerFlag("WEBGL_BUFFER_SUPPORTED",(()=>2===ie.get("WEBGL_VERSION"))),ie.registerFlag("WEBGL_CPU_FORWARD",(()=>!0)),ie.registerFlag("WEBGL_FORCE_F16_TEXTURES",(()=>!1)),ie.registerFlag("WEBGL_PACK",(()=>ie.getBool("HAS_WEBGL"))),ie.registerFlag("WEBGL_PACK_NORMALIZATION",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_CLIP",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_DEPTHWISECONV",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_BINARY_OPERATIONS",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_UNARY_OPERATIONS",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_ARRAY_OPERATIONS",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_IMAGE_OPERATIONS",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_REDUCE",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_LAZILY_UNPACK",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_CONV_IM2COL",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_PACK_CONV2DTRANSPOSE",(()=>ie.getBool("WEBGL_PACK"))),ie.registerFlag("WEBGL_MAX_TEXTURE_SIZE",(()=>Y(ie.getNumber("WEBGL_VERSION")))),ie.registerFlag("WEBGL_MAX_TEXTURES_IN_SHADER",(()=>Q(ie.getNumber("WEBGL_VERSION")))),ie.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION",(()=>{const e=ie.getNumber("WEBGL_VERSION");return 0===e?0:Z(e)})),ie.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE",(()=>ie.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0&&!t.device_util.isMobile())),ie.registerFlag("WEBGL_RENDER_FLOAT32_CAPABLE",(()=>te(ie.getNumber("WEBGL_VERSION")))),ie.registerFlag("WEBGL_RENDER_FLOAT32_ENABLED",(()=>!ie.getBool("WEBGL_FORCE_F16_TEXTURES")&&ie.getBool("WEBGL_RENDER_FLOAT32_CAPABLE"))),ie.registerFlag("WEBGL_DOWNLOAD_FLOAT_ENABLED",(()=>ne(ie.getNumber("WEBGL_VERSION")))),ie.registerFlag("WEBGL_FENCE_API_ENABLED",(()=>re(ie.getNumber("WEBGL_VERSION")))),ie.registerFlag("WEBGL_SIZE_UPLOAD_UNIFORM",(()=>ie.getBool("WEBGL_RENDER_FLOAT32_ENABLED")?4:0)),ie.registerFlag("WEBGL_DELETE_TEXTURE_THRESHOLD",(()=>-1),(e=>{if("number"!=typeof e)throw new Error(`WEBGL_DELETE_TEXTURE_THRESHOLD must be a number but got ${e}.`);if(e<0&&-1!==e)throw new Error(`WEBGL_DELETE_TEXTURE_THRESHOLD must be -1 (indicating never delete) or at least 0, but got ${e}.`)})),ie.registerFlag("WEBGL_FLUSH_THRESHOLD",(()=>t.device_util.isMobile()?1:-1),(e=>{if("number"!=typeof e)throw new Error(`WEBGL_FLUSH_THRESHOLD must be a number but got ${e}.`);if(e<0&&-1!==e)throw new Error(`WEBGL_FLUSH_THRESHOLD must be -1 (indicating never manual flush) or at least 0, but got ${e}.`)})),ie.registerFlag("CPU_HANDOFF_SIZE_THRESHOLD",(()=>128)),ie.registerFlag("WEBGL_USE_SHAPES_UNIFORMS",(()=>!1)),ie.registerFlag("TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD",(()=>1e5)),ie.registerFlag("TOPK_K_CPU_HANDOFF_THRESHOLD",(()=>128)),ie.registerFlag("WEBGL_EXP_CONV",(()=>!1)),ie.registerFlag("SOFTWARE_WEBGL_ENABLED",(()=>ie.getBool("IS_TEST"))),ie.registerFlag("WEBGL_MAX_SIZE_FOR_NARROW_TEXTURE",(()=>1/0)),ie.registerFlag("WEBGL_AUTO_SQUARIFY_NARROW_TEXTURE_SHAPE",(()=>!1)),ie.registerFlag("WEBGL2_ISNAN_CUSTOM",(()=>!1)),ie.registerFlag("ENGINE_COMPILE_ONLY",(()=>!1));const he="\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",{getBroadcastDims:fe}=t.backend_util;function xe(e,n,a){const r=[];if(e.forEach((e=>{const n=t.util.sizeFromShape(e.shapeInfo.logicalShape);if(e.shapeInfo.isUniform?r.push(`uniform float ${e.name}${n>1?`[${n}]`:""};`):(r.push(`uniform sampler2D ${e.name};`),r.push(`uniform int offset${e.name};`)),a.enableShapeUniforms){const{uniformShape:t}=ke(a.packedInputs,e.shapeInfo.logicalShape,e.shapeInfo.texShape);switch(t.length){case 1:r.push(`uniform int ${e.name}Shape;`);break;case 2:r.push(`uniform ivec2 ${e.name}Shape;`);break;case 3:r.push(`uniform ivec3 ${e.name}Shape;`);break;case 4:r.push(`uniform ivec4 ${e.name}Shape;`)}r.push(`uniform ivec2 ${e.name}TexShape;`)}})),a.enableShapeUniforms){switch(n.logicalShape.length){case 1:r.push("uniform int outShape;");break;case 2:r.push("uniform ivec2 outShape;"),r.push("uniform int outShapeStrides;");break;case 3:r.push("uniform ivec3 outShape;"),r.push("uniform ivec2 outShapeStrides;");break;case 4:r.push("uniform ivec4 outShape;"),r.push("uniform ivec3 outShapeStrides;")}r.push("uniform ivec2 outTexShape;")}a.customUniforms&&a.customUniforms.forEach((e=>{r.push(`uniform ${e.type} ${e.name}${e.arrayIndex?`[${e.arrayIndex}]`:""};`)}));const o=r.join("\n"),s=e.map((e=>function(e,n,a=!1,r){let o="";o+=a?ge(e,r):me(e,r);const s=e.shapeInfo.logicalShape,i=n.logicalShape;s.length<=i.length&&(o+=a?function(e,n){const a=e.name,r=a.charAt(0).toUpperCase()+a.slice(1),o="get"+r+"AtOutCoords",s=e.shapeInfo.logicalShape.length,i=n.logicalShape.length,l=fe(e.shapeInfo.logicalShape,n.logicalShape),u=Se(i),c=i-s;let d;const p=["x","y","z","w","u","v"];d=0===s?"":i<2&&l.length>=1?"coords = 0;":l.map((e=>`coords.${p[e+c]} = 0;`)).join("\n");let h="";h=i<2&&s>0?"coords":e.shapeInfo.logicalShape.map(((e,t)=>`coords.${p[t+c]}`)).join(", ");let f="return outputValue;";const x=1===t.util.sizeFromShape(e.shapeInfo.logicalShape),m=1===t.util.sizeFromShape(n.logicalShape);if(1!==s||x||m){if(x&&!m)f=1===i?"\n return vec4(outputValue.x, outputValue.x, 0., 0.);\n ":"\n return vec4(outputValue.x);\n ";else if(l.length){const e=s-2,t=s-1;l.indexOf(e)>-1&&l.indexOf(t)>-1?f="return vec4(outputValue.x);":l.indexOf(e)>-1?f="return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);":l.indexOf(t)>-1&&(f="return vec4(outputValue.xx, outputValue.zz);")}}else f="\n return vec4(outputValue.xy, outputValue.xy);\n ";return`\n vec4 ${o}() {\n ${u} coords = getOutputCoords();\n ${d}\n vec4 outputValue = get${r}(${h});\n ${f}\n }\n `}(e,n):function(e,n){const a=e.name,r=a.charAt(0).toUpperCase()+a.slice(1),o="get"+r+"AtOutCoords",s=n.texShape,i=e.shapeInfo.texShape,l=e.shapeInfo.logicalShape.length,u=n.logicalShape.length;if(!e.shapeInfo.isUniform&&l===u&&null==e.shapeInfo.flatOffset&&t.util.arraysEqual(i,s))return`\n float ${o}() {\n return sampleTexture(${a}, resultUV);\n }\n `;const c=Se(u),d=fe(e.shapeInfo.logicalShape,n.logicalShape),p=u-l;let h;const f=["x","y","z","w","u","v"];h=0===l?"":u<2&&d.length>=1?"coords = 0;":d.map((e=>`coords.${f[e+p]} = 0;`)).join("\n");let x="";x=u<2&&l>0?"coords":e.shapeInfo.logicalShape.map(((e,t)=>`coords.${f[t+p]}`)).join(", ");return`\n float ${o}() {\n ${c} coords = getOutputCoords();\n ${h}\n return get${r}(${x});\n }\n `}(e,n));return o}(e,n,a.packedInputs,a.enableShapeUniforms))).join("\n"),i=n.texShape,l=le(),u=function(e){return`\n float sampleTexture(sampler2D textureSampler, vec2 uv) {\n return ${e.texture2D}(textureSampler, uv).r;\n }\n `}(l);let c,d,p=function(e){return`${e.version}\n precision highp float;\n precision highp int;\n precision highp sampler2D;\n ${e.varyingFs} vec2 resultUV;\n ${e.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 ${e.defineSpecialNaN}\n ${e.defineSpecialInf}\n ${e.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 ${be}\n ${ve}\n ${Ce}\n `}(l);n.isPacked?(c=function(e,n,a){switch(e.length){case 0:return ye();case 1:return function(e,t,n){const a=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)];if(1===a[0])return n?"\n int getOutputCoords() {\n return 2 * int(resultUV.x * ceil(float(outTexShape[1]) / 2.0));\n }\n ":`\n int getOutputCoords() {\n return 2 * int(resultUV.x * ${a[1]}.0);\n }\n `;if(1===a[1])return n?"\n int getOutputCoords() {\n return 2 * int(resultUV.y * ceil(float(outTexShape[0]) / 2.0));\n }\n ":`\n int getOutputCoords() {\n return 2 * int(resultUV.y * ${a[0]}.0);\n }\n `;if(n)return"\n int getOutputCoords() {\n ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(packedTexShape[0], packedTexShape[1]));\n return 2 * (resTexRC.x * packedTexShape[1] + resTexRC.y);\n }\n ";return`\n int getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${a[0]}, ${a[1]}));\n return 2 * (resTexRC.x * ${a[1]} + resTexRC.y);\n }\n `}(0,n,a);case 2:return function(e,n,a){const r=[Math.ceil(n[0]/2),Math.ceil(n[1]/2)];if(t.util.arraysEqual(e,n))return a?"\n ivec2 getOutputCoords() {\n ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n return 2 * ivec2(resultUV.yx * vec2(packedTexShape[0], packedTexShape[1]));\n }\n ":`\n ivec2 getOutputCoords() {\n return 2 * ivec2(resultUV.yx * vec2(${r[0]}, ${r[1]}));\n }\n `;const o=Math.ceil(e[1]/2);if(a)return"\n ivec2 getOutputCoords() {\n ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n int texelsInLogicalRow = int(ceil(float(outShape[1]) / 2.0));\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(packedTexShape[0], packedTexShape[1]));\n\n int index = resTexRC.x * packedTexShape[1] + resTexRC.y;\n int r = 2 * (index / texelsInLogicalRow);\n int c = imod(index, texelsInLogicalRow) * 2;\n\n return ivec2(r, c);\n }\n ";return`\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${r[0]}, ${r[1]}));\n\n int index = resTexRC.x * ${r[1]} + resTexRC.y;\n int r = 2 * (index / ${o});\n int c = imod(index, ${o}) * 2;\n\n return ivec2(r, c);\n }\n `}(e,n,a);case 3:return function(e,t,n){if(n)return"\n ivec3 getOutputCoords() {\n ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n int texelsInLogicalRow = int(ceil(float(outShape[2]) / 2.0));\n int texelsInBatch = texelsInLogicalRow * int(ceil(float(outShape[1]) / 2.0));\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(packedTexShape[0], packedTexShape[1]));\n int index = resTexRC.x * packedTexShape[1] + resTexRC.y;\n\n int b = index / texelsInBatch;\n index -= b * texelsInBatch;\n\n int r = 2 * (index / texelsInLogicalRow);\n int c = imod(index, texelsInLogicalRow) * 2;\n\n return ivec3(b, r, c);\n }\n ";const a=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)],r=Math.ceil(e[2]/2),o=r*Math.ceil(e[1]/2);return`\n ivec3 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${a[0]}, ${a[1]}));\n int index = resTexRC.x * ${a[1]} + resTexRC.y;\n\n int b = index / ${o};\n index -= b * ${o};\n\n int r = 2 * (index / ${r});\n int c = imod(index, ${r}) * 2;\n\n return ivec3(b, r, c);\n }\n `}(e,n,a);default:return function(e,t,n){if(n)return"\n ivec4 getOutputCoords() {\n ivec2 packedTexShape = ivec2(ceil(float(outTexShape[0]) / 2.0), ceil(float(outTexShape[1]) / 2.0));\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(packedTexShape[0], packedTexShape[1]));\n int index = resTexRC.x * packedTexShape[1] + resTexRC.y;\n\n int texelsInLogicalRow = int(ceil(float(outShape[3]) / 2.0));\n int texelsInBatch = texelsInLogicalRow * int(ceil(float(outShape[2]) / 2.0));\n int texelsInBatchN = texelsInBatch * outShape[1];\n\n int b2 = index / texelsInBatchN;\n index -= b2 * texelsInBatchN;\n\n int b = index / texelsInBatch;\n index -= b * texelsInBatch;\n\n int r = 2 * (index / texelsInLogicalRow);\n int c = imod(index, texelsInLogicalRow) * 2;\n\n return ivec4(b2, b, r, c);\n }\n ";const a=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)],r=Math.ceil(e[e.length-1]/2),o=r*Math.ceil(e[e.length-2]/2);let s=o,i="",l="b, r, c";for(let t=2;t<e.length-1;t++)s*=e[e.length-t-1],i=`\n int b${t} = index / ${s};\n index -= b${t} * ${s};\n `+i,l=`b${t}, `+l;return`\n ivec${e.length} getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${a[0]}, ${a[1]}));\n int index = resTexRC.x * ${a[1]} + resTexRC.y;\n\n ${i}\n\n int b = index / ${o};\n index -= b * ${o};\n\n int r = 2 * (index / ${r});\n int c = imod(index, ${r}) * 2;\n\n return ivec${e.length}(${l});\n }\n `}(e,n,a)}}(n.logicalShape,i,a.enableShapeUniforms),d=function(e){return`\n void setOutput(vec4 val) {\n ${e.output} = val;\n }\n `}(l)):(c=function(e,n,a){switch(e.length){case 0:return ye();case 1:return function(e,t,n){if(1===t[0])return n?"\n int getOutputCoords() {\n return int(resultUV.x * float(outTexShape[1]));\n }\n ":`\n int getOutputCoords() {\n return int(resultUV.x * ${t[1]}.0);\n }\n `;if(1===t[1])return n?"\n int getOutputCoords() {\n return int(resultUV.y * float(outTexShape[0]));\n }\n ":`\n int getOutputCoords() {\n return int(resultUV.y * ${t[0]}.0);\n }\n `;if(n)return"\n int getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(outTexShape[0], outTexShape[1]));\n return resTexRC.x * outTexShape[1] + resTexRC.y;\n }\n ";return`\n int getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${t[0]}, ${t[1]}));\n return resTexRC.x * ${t[1]} + resTexRC.y;\n }\n `}(0,n,a);case 2:return function(e,n,a){if(t.util.arraysEqual(e,n))return a?"\n ivec2 getOutputCoords() {\n return ivec2(resultUV.yx * vec2(outTexShape[0], outTexShape[1]));\n }\n ":`\n ivec2 getOutputCoords() {\n return ivec2(resultUV.yx * vec2(${n[0]}, ${n[1]}));\n }\n `;if(1===e[1])return a?"\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(outTexShape[0], outTexShape[1]));\n int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n return ivec2(index, 0);\n }\n ":`\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${n[0]}, ${n[1]}));\n int index = resTexRC.x * ${n[1]} + resTexRC.y;\n return ivec2(index, 0);\n }\n `;if(1===e[0])return a?"\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(outTexShape[0], outTexShape[1]));\n int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n return ivec2(0, index);\n }\n ":`\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${n[0]}, ${n[1]}));\n int index = resTexRC.x * ${n[1]} + resTexRC.y;\n return ivec2(0, index);\n }\n `;if(a)return"\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(outTexShape[0], outTexShape[1]));\n int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n int r = index / outShape[1];\n int c = index - r * outShape[1];\n return ivec2(r, c);\n }\n ";return`\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${n[0]}, ${n[1]}));\n int index = resTexRC.x * ${n[1]} + resTexRC.y;\n int r = index / ${e[1]};\n int c = index - r * ${e[1]};\n return ivec2(r, c);\n }\n `}(e,n,a);case 3:return function(e,t,n){if(n){return`\n ivec3 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(outTexShape[0], outTexShape[1]));\n int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n ${ce(["r","c","d"],e)}\n return ivec3(r, c, d);\n }\n`}const a=ue(["r","c","d"],e);return`\n ivec3 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${t[0]}, ${t[1]}));\n int index = resTexRC.x * ${t[1]} + resTexRC.y;\n ${a}\n return ivec3(r, c, d);\n }\n `}(e,n,a);case 4:return function(e,t,n){if(n){return`\n ivec4 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(outTexShape[0], outTexShape[1]));\n int index = resTexRC.x * outTexShape[1] + resTexRC.y;\n ${ce(["r","c","d","d2"],e)}\n return ivec4(r, c, d, d2);\n }\n `}const a=ue(["r","c","d","d2"],e);return`\n ivec4 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${t[0]}, ${t[1]}));\n int index = resTexRC.x * ${t[1]} + resTexRC.y;\n ${a}\n return ivec4(r, c, d, d2);\n }\n `}(e,n,a);case 5:return function(e,t){const n=ue(["r","c","d","d2","d3"],e);return`\n ivec5 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx * vec2(${t[0]},\n ${t[1]}));\n\n int index = resTexRC.x * ${t[1]} + resTexRC.y;\n\n ${n}\n\n ivec5 outShape = ivec5(r, c, d, d2, d3);\n return outShape;\n }\n `}(e,n);case 6:return function(e,t){const n=ue(["r","c","d","d2","d3","d4"],e);return`\n ivec6 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(${t[0]}, ${t[1]}));\n int index = resTexRC.x * ${t[1]} + resTexRC.y;\n\n ${n}\n\n ivec6 result = ivec6(r, c, d, d2, d3, d4);\n return result;\n }\n `}(e,n);default:throw new Error(`${e.length}-D output sampling is not yet supported`)}}(n.logicalShape,i,a.enableShapeUniforms),d=function(e){return`\n void setOutput(float val) {\n ${e.output} = vec4(val, 0, 0, 0);\n }\n `}(l)),a.packedInputs&&(p+=$e);return[p,u,d,o,c,s,a.userCode].join("\n")}function me(e,n=!1){const a=e.shapeInfo.logicalShape;switch(a.length){case 0:return function(e,t){const n=e.name,a="get"+n.charAt(0).toUpperCase()+n.slice(1);if(e.shapeInfo.isUniform)return`float ${a}() {return ${n};}`;const[r,o]=e.shapeInfo.texShape;if(1===r&&1===o)return`\n float ${a}() {\n return sampleTexture(${n}, halfCR);\n }\n `;const s=Ie(n);if(t)return`\n float ${a}() {\n vec2 uv = uvFromFlat(${n}TexShape[0], ${n}TexShape[1], ${s});\n return sampleTexture(${n}, uv);\n }\n `;const[i,l]=e.shapeInfo.texShape;return`\n float ${a}() {\n vec2 uv = uvFromFlat(${i}, ${l}, ${s});\n return sampleTexture(${n}, uv);\n }\n `}(e,n);case 1:return function(e,t){const n=e.name,a="get"+n.charAt(0).toUpperCase()+n.slice(1);if(e.shapeInfo.isUniform)return`\n float ${a}(int index) {\n ${we(e)}\n }\n `;const r=e.shapeInfo.texShape,o=r[0],s=r[1];if(1===s&&1===o)return`\n float ${a}(int index) {\n return sampleTexture(${n}, halfCR);\n }\n `;const i=Ie(n);if(1===s)return t?`\n float ${a}(int index) {\n vec2 uv = vec2(0.5, (float(index + ${i}) + 0.5) / float(${n}TexShape[0]));\n return sampleTexture(${n}, uv);\n }\n `:`\n float ${a}(int index) {\n vec2 uv = vec2(0.5, (float(index + ${i}) + 0.5) / ${o}.0);\n return sampleTexture(${n}, uv);\n }\n `;if(1===o)return t?`\n float ${a}(int index) {\n vec2 uv = vec2((float(index + ${i}) + 0.5) / float(${n}TexShape[1]), 0.5);\n return sampleTexture(${n}, uv);\n }\n `:`\n float ${a}(int index) {\n vec2 uv = vec2((float(index + ${i}) + 0.5) / ${s}.0, 0.5);\n return sampleTexture(${n}, uv);\n }\n `;if(t)return`\n float ${a}(int index) {\n vec2 uv = uvFromFlat(${n}TexShape[0], ${n}TexShape[1], index + ${i});\n return sampleTexture(${n}, uv);\n }\n `;return`\n float ${a}(int index) {\n vec2 uv = uvFromFlat(${o}, ${s}, index + ${i});\n return sampleTexture(${n}, uv);\n }\n `}(e,n);case 2:return function(e,n){const a=e.shapeInfo.logicalShape,r=e.name,o="get"+r.charAt(0).toUpperCase()+r.slice(1),s=e.shapeInfo.texShape;if(null!=s&&t.util.arraysEqual(a,s)){if(n)return`\n float ${o}(int row, int col) {\n vec2 uv = (vec2(col, row) + halfCR) / vec2(${r}TexShape[1], ${r}TexShape[0]);\n return sampleTexture(${r}, uv);\n }\n `;const e=s[0];return`\n float ${o}(int row, int col) {\n vec2 uv = (vec2(col, row) + halfCR) / vec2(${s[1]}.0, ${e}.0);\n return sampleTexture(${r}, uv);\n }\n `}const{newShape:i,keptDims:l}=t.util.squeezeShape(a),u=i;if(u.length<a.length){const t=["row","col"];return`\n ${me(Re(e,u),n)}\n float ${o}(int row, int col) {\n return ${o}(${Te(t,l)});\n }\n `}if(e.shapeInfo.isUniform)return`\n float ${o}(int row, int col) {\n int index = round(dot(vec2(row, col), vec2(${a[1]}, 1)));\n ${we(e)}\n }\n `;const c=s[0],d=s[1],p=Ie(r);if(1===d)return n?`\n float ${o}(int row, int col) {\n float index = dot(vec3(row, col, ${p}), vec3(${r}Shape[1], 1, 1));\n vec2 uv = vec2(0.5, (index + 0.5) / float(${r}TexShape[0]));\n return sampleTexture(${r}, uv);\n }\n `:`\n float ${o}(int row, int col) {\n float index = dot(vec3(row, col, ${p}), vec3(${a[1]}, 1, 1));\n vec2 uv = vec2(0.5, (index + 0.5) / ${c}.0);\n return sampleTexture(${r}, uv);\n }\n `;if(1===c)return n?`\n float ${o}(int row, int col) {\n float index = dot(vec3(row, col, ${p}), vec3(${r}Shape[1], 1, 1));\n vec2 uv = vec2((index + 0.5) / float(${r}TexShape[1]), 0.5);\n return sampleTexture(${r}, uv);\n }\n `:`\n float ${o}(int row, int col) {\n float index = dot(vec3(row, col, ${p}), vec3(${a[1]}, 1, 1));\n vec2 uv = vec2((index + 0.5) / ${d}.0, 0.5);\n return sampleTexture(${r}, uv);\n }\n `;if(n)return`\n float ${o}(int row, int col) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * ${r}Shape[1] + col + ${p};\n vec2 uv = uvFromFlat(${r}TexShape[0], ${r}TexShape[1], index);\n return sampleTexture(${r}, uv);\n }\n `;return`\n float ${o}(int row, int col) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * ${a[1]} + col + ${p};\n vec2 uv = uvFromFlat(${c}, ${d}, index);\n return sampleTexture(${r}, uv);\n }\n`}(e,n);case 3:return function(e,n){const a=e.shapeInfo.logicalShape,r=e.name,o="get"+r.charAt(0).toUpperCase()+r.slice(1),s=a[1]*a[2],i=a[2],{newShape:l,keptDims:u}=t.util.squeezeShape(a),c=l;if(c.length<a.length){const t=["row","col","depth"];return`\n ${me(Re(e,c),n)}\n float ${o}(int row, int col, int depth) {\n return ${o}(${Te(t,u)});\n }\n `}if(e.shapeInfo.isUniform)return`\n float ${o}(int row, int col, int depth) {\n int index = round(dot(vec3(row, col, depth),\n vec3(${s}, ${i}, 1)));\n ${we(e)}\n }\n `;const d=e.shapeInfo.texShape,p=d[0],h=d[1],f=e.shapeInfo.flatOffset;if(h===s&&null==f)return n?`\n float ${o}(int row, int col, int depth) {\n int stride1 = ${r}Shape[2];\n float texR = float(row);\n float texC = dot(vec2(col, depth), vec2(stride1, 1));\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${r}TexShape[1], ${r}TexShape[0]);\n return sampleTexture(${r}, uv);\n }\n `:`\n float ${o}(int row, int col, int depth) {\n float texR = float(row);\n float texC = dot(vec2(col, depth), vec2(${i}, 1));\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${h}.0, ${p}.0);\n return sampleTexture(${r}, uv);\n }\n `;if(h===i&&null==f)return n?`\n float ${o}(int row, int col, int depth) {\n float texR = dot(vec2(row, col), vec2(${r}Shape[1], 1));\n float texC = float(depth);\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${r}TexShape[1], ${r}TexShape[0]);\n return sampleTexture(${r}, uv);\n }\n `:`\n float ${o}(int row, int col, int depth) {\n float texR = dot(vec2(row, col), vec2(${a[1]}, 1));\n float texC = float(depth);\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${h}.0, ${p}.0);\n return sampleTexture(${r}, uv);\n }\n `;const x=Ie(r);if(n)return`\n float ${o}(int row, int col, int depth) {\n // Explicitly use integer operations as dot() only works on floats.\n int stride0 = ${r}Shape[1] * ${r}Shape[2];\n int stride1 = ${r}Shape[2];\n int index = row * stride0 + col * stride1 + depth + ${x};\n vec2 uv = uvFromFlat(${r}TexShape[0], ${r}TexShape[1], index);\n return sampleTexture(${r}, uv);\n }\n `;return`\n float ${o}(int row, int col, int depth) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * ${s} + col * ${i} + depth + ${x};\n vec2 uv = uvFromFlat(${p}, ${h}, index);\n return sampleTexture(${r}, uv);\n }\n `}(e,n);case 4:return function(e,n){const a=e.shapeInfo.logicalShape,r=e.name,o="get"+r.charAt(0).toUpperCase()+r.slice(1),s=a[3],i=a[2]*s,l=a[1]*i,{newShape:u,keptDims:c}=t.util.squeezeShape(a);if(u.length<a.length){const t=["row","col","depth","depth2"];return`\n ${me(Re(e,u),n)}\n float ${o}(int row, int col, int depth, int depth2) {\n return ${o}(${Te(t,c)});\n }\n `}if(e.shapeInfo.isUniform)return`\n float ${o}(int row, int col, int depth, int depth2) {\n int index = round(dot(vec4(row, col, depth, depth2),\n vec4(${l}, ${i}, ${s}, 1)));\n ${we(e)}\n }\n `;const d=e.shapeInfo.flatOffset,p=e.shapeInfo.texShape,h=p[0],f=p[1],x=`int stride2 = ${r}Shape[3];`,m=`int stride1 = ${r}Shape[2] * stride2;`,g=`int stride0 = ${r}Shape[1] * stride1;`;if(f===l&&null==d)return n?`\n float ${o}(int row, int col, int depth, int depth2) {\n ${x}\n ${m}\n float texR = float(row);\n float texC =\n dot(vec3(col, depth, depth2),\n vec3(stride1, stride2, 1));\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${r}TexShape[1], ${r}TexShape[0]);\n return sampleTexture(${r}, uv);\n }\n `:`\n float ${o}(int row, int col, int depth, int depth2) {\n float texR = float(row);\n float texC =\n dot(vec3(col, depth, depth2),\n vec3(${i}, ${s}, 1));\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${f}.0, ${h}.0);\n return sampleTexture(${r}, uv);\n }\n `;if(f===s&&null==d)return n?`\n float ${o}(int row, int col, int depth, int depth2) {\n float texR = dot(vec3(row, col, depth),\n vec3(${r}Shape[1] * ${r}Shape[2], ${r}Shape[2], 1));\n float texC = float(depth2);\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${r}TexShape[1], ${r}TexShape[0]);\n return sampleTexture(${r}, uv);\n }\n `:`\n float ${o}(int row, int col, int depth, int depth2) {\n float texR = dot(vec3(row, col, depth),\n vec3(${a[1]*a[2]}, ${a[2]}, 1));\n float texC = float(depth2);\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${f}.0, ${h}.0);\n return sampleTexture(${r}, uv);\n }\n `;const b=Ie(r);if(n)return`\n float ${o}(int row, int col, int depth, int depth2) {\n // Explicitly use integer operations as dot() only works on floats.\n ${x}\n ${m}\n ${g}\n int index = row * stride0 + col * stride1 +\n depth * stride2 + depth2;\n vec2 uv = uvFromFlat(${r}TexShape[0], ${r}TexShape[1], index + ${b});\n return sampleTexture(${r}, uv);\n }\n `;return`\n float ${o}(int row, int col, int depth, int depth2) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * ${l} + col * ${i} +\n depth * ${s} + depth2;\n vec2 uv = uvFromFlat(${h}, ${f}, index + ${b});\n return sampleTexture(${r}, uv);\n }\n `}(e,n);case 5:return function(e){const n=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=n[4],s=n[3]*o,i=n[2]*s,l=n[1]*i,{newShape:u,keptDims:c}=t.util.squeezeShape(n);if(u.length<n.length){const t=["row","col","depth","depth2","depth3"];return`\n ${me(Re(e,u))}\n float ${r}(int row, int col, int depth, int depth2, int depth3) {\n return ${r}(${Te(t,c)});\n }\n `}if(e.shapeInfo.isUniform)return`\n float ${r}(int row, int col, int depth, int depth2, int depth3) {\n float index = dot(\n vec4(row, col, depth, depth2),\n vec4(${l}, ${i}, ${s}, ${o})) +\n depth3;\n ${we(e)}\n }\n `;const d=e.shapeInfo.flatOffset,p=e.shapeInfo.texShape,h=p[0],f=p[1];if(f===l&&null==d)return`\n float ${r}(int row, int col, int depth, int depth2, int depth3) {\n int texR = row;\n float texC = dot(vec4(col, depth, depth2, depth3),\n vec4(${i}, ${s}, ${o}, 1));\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${f}.0, ${h}.0);\n return sampleTexture(${a}, uv);\n }\n `;if(f===o&&null==d)return`\n float ${r}(int row, int col, int depth, int depth2, int depth3) {\n float texR = dot(\n vec4(row, col, depth, depth2),\n vec4(${n[1]*n[2]*n[3]},\n ${n[2]*n[3]}, ${n[3]}, 1));\n int texC = depth3;\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${f}.0, ${h}.0);\n return sampleTexture(${a}, uv);\n }\n `;const x=Ie(a);return`\n float ${r}(int row, int col, int depth, int depth2, int depth3) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * ${l} + col * ${i} + depth * ${s} +\n depth2 * ${o} + depth3 + ${x};\n vec2 uv = uvFromFlat(${h}, ${f}, index);\n return sampleTexture(${a}, uv);\n }\n `}(e);case 6:return function(e){const n=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),{newShape:o,keptDims:s}=t.util.squeezeShape(n);if(o.length<n.length){const t=["row","col","depth","depth2","depth3","depth4"];return`\n ${me(Re(e,o))}\n float ${r}(int row, int col, int depth,\n int depth2, int depth3, int depth4) {\n return ${r}(${Te(t,s)});\n }\n `}const i=n[5],l=n[4]*i,u=n[3]*l,c=n[2]*u,d=n[1]*c;if(e.shapeInfo.isUniform)return`\n float ${r}(int row, int col, int depth,\n int depth2, int depth3, int depth4) {\n int index = round(dot(\n vec4(row, col, depth, depth2),\n vec4(${d}, ${c}, ${u}, ${l})) +\n dot(\n vec2(depth3, depth4),\n vec2(${i}, 1)));\n ${we(e)}\n }\n `;const p=e.shapeInfo.flatOffset,h=e.shapeInfo.texShape,f=h[0],x=h[1];if(x===d&&null==p)return`\n float ${r}(int row, int col, int depth,\n int depth2, int depth3, int depth4) {\n int texR = row;\n float texC = dot(vec4(col, depth, depth2, depth3),\n vec4(${c}, ${u}, ${l}, ${i})) +\n float(depth4);\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${x}.0, ${f}.0);\n return sampleTexture(${a}, uv);\n }\n `;if(x===i&&null==p)return`\n float ${r}(int row, int col, int depth,\n int depth2, int depth3, int depth4) {\n float texR = dot(vec4(row, col, depth, depth2),\n vec4(${n[1]*n[2]*n[3]*n[4]},\n ${n[2]*n[3]*n[4]},\n ${n[3]*n[4]},\n ${n[4]})) + float(depth3);\n int texC = depth4;\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(${x}.0, ${f}.0);\n return sampleTexture(${a}, uv);\n }\n `;const m=Ie(a);return`\n float ${r}(int row, int col, int depth,\n int depth2, int depth3, int depth4) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * ${d} + col * ${c} + depth * ${u} +\n depth2 * ${l} + depth3 * ${i} + depth4 + ${m};\n vec2 uv = uvFromFlat(${f}, ${x}, index);\n return sampleTexture(${a}, uv);\n }\n `}(e);default:throw new Error(`${a.length}-D input sampling is not yet supported`)}}function ge(e,n){switch(e.shapeInfo.logicalShape.length){case 0:return function(e){const t=e.name,n="get"+t.charAt(0).toUpperCase()+t.slice(1),a=le();return`\n vec4 ${n}() {\n return ${a.texture2D}(${t}, halfCR);\n }\n `}(e);case 1:return function(e,t){const n=e.name,a="get"+n.charAt(0).toUpperCase()+n.slice(1),r=e.shapeInfo.texShape,o=le();if(t)return`\n vec4 ${a}(int index) {\n ivec2 packedTexShape = ivec2(ceil(float(${n}TexShape[0]) / 2.0), ceil(float(${n}TexShape[1]) / 2.0));\n vec2 uv = packedUVfrom1D(\n packedTexShape[0], packedTexShape[1], index);\n return ${o.texture2D}(${n}, uv);\n }\n `;const s=[Math.ceil(r[0]/2),Math.ceil(r[1]/2)];return`\n vec4 ${a}(int index) {\n vec2 uv = packedUVfrom1D(\n ${s[0]}, ${s[1]}, index);\n return ${o.texture2D}(${n}, uv);\n }\n `}(e,n);case 2:return function(e,n){const a=e.shapeInfo.logicalShape,r=e.name,o="get"+r.charAt(0).toUpperCase()+r.slice(1),s=e.shapeInfo.texShape,i=s[0],l=s[1],u=le();if(null!=s&&t.util.arraysEqual(a,s))return n?`\n vec4 ${o}(int row, int col) {\n vec2 uv = (vec2(col, row) + halfCR) / vec2(${r}TexShape[1], ${r}TexShape[0]);\n\n return ${u.texture2D}(${r}, uv);\n }\n `:`\n vec4 ${o}(int row, int col) {\n vec2 uv = (vec2(col, row) + halfCR) / vec2(${l}.0, ${i}.0);\n\n return ${u.texture2D}(${r}, uv);\n }\n `;if(n)return`\n vec4 ${o}(int row, int col) {\n ivec2 packedTexShape = ivec2(ceil(float(${r}TexShape[0]) / 2.0), ceil(float(${r}TexShape[1]) / 2.0));\n int valuesPerRow = int(ceil(float(${r}Shape[1]) / 2.0));\n vec2 uv = packedUVfrom2D(valuesPerRow, packedTexShape[0], packedTexShape[1], row, col);\n return ${u.texture2D}(${r}, uv);\n }\n `;const c=[Math.ceil(s[0]/2),Math.ceil(s[1]/2)],d=Math.ceil(a[1]/2);return`\n vec4 ${o}(int row, int col) {\n vec2 uv = packedUVfrom2D(${d}, ${c[0]}, ${c[1]}, row, col);\n return ${u.texture2D}(${r}, uv);\n }\n `}(e,n);case 3:return function(e,t){const n=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=e.shapeInfo.texShape,s=[Math.ceil(o[0]/2),Math.ceil(o[1]/2)];if(1===n[0]){const a=[1,2],o=["b","row","col"];return`\n ${ge(Re(e,n.slice(1)),t)}\n vec4 ${r}(int b, int row, int col) {\n return ${r}(${Te(o,a)});\n }\n `}const i=le();if(t)return`\n vec4 ${r}(int b, int row, int col) {\n ivec2 packedTexShape = ivec2(ceil(float(${a}TexShape[0]) / 2.0), ceil(float(${a}TexShape[1]) / 2.0));\n int valuesPerRow = int(ceil(float(${a}Shape[2]) / 2.0));\n int texelsInBatch = valuesPerRow * int(ceil(float(${a}Shape[1]) / 2.0));\n vec2 uv = packedUVfrom3D(\n packedTexShape[0], packedTexShape[1], texelsInBatch, valuesPerRow, b, row, col);\n return ${i.texture2D}(${a}, uv);\n }\n `;const l=s[0],u=s[1],c=Math.ceil(n[2]/2),d=c*Math.ceil(n[1]/2);return`\n vec4 ${r}(int b, int row, int col) {\n vec2 uv = packedUVfrom3D(\n ${l}, ${u}, ${d}, ${c}, b, row, col);\n return ${i.texture2D}(${a}, uv);\n }\n `}(e,n);default:return function(e,t){const n=e.name,a="get"+n.charAt(0).toUpperCase()+n.slice(1),r=le();if(t)return`\n vec4 ${a}(int b2, int b, int row, int col) {\n int valuesPerRow = int(ceil(float(${n}Shape[3]) / 2.0));\n int texelsInBatch = valuesPerRow * int(ceil(float(${n}Shape[2]) / 2.0));\n int index = b * texelsInBatch + (row / 2) * valuesPerRow + (col / 2);\n texelsInBatch *= ${n}Shape[1];\n index = b2 * texelsInBatch + index;\n ivec2 packedTexShape = ivec2(ceil(float(${n}TexShape[0]) / 2.0), ceil(float(${n}TexShape[1]) / 2.0));\n int texR = index / packedTexShape[1];\n int texC = index - texR * packedTexShape[1];\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2(packedTexShape[1], packedTexShape[0]); return ${r.texture2D}(${n}, uv);\n }\n `;const o=e.shapeInfo.logicalShape,s=o.length,i=e.shapeInfo.texShape,l=[Math.ceil(i[0]/2),Math.ceil(i[1]/2)],u=l[0],c=l[1],d=Math.ceil(o[s-1]/2);let p=d*Math.ceil(o[s-2]/2),h="int b, int row, int col",f=`b * ${p} + (row / 2) * ${d} + (col / 2)`;for(let e=2;e<s-1;e++)h=`int b${e}, `+h,p*=o[s-e-1],f=`b${e} * ${p} + `+f;return`\n vec4 ${a}(${h}) {\n int index = ${f};\n int texR = index / ${c};\n int texC = index - texR * ${c};\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${c}, ${u});\n return ${r.texture2D}(${n}, uv);\n }\n `}(e,n)}}const be="\nvec2 uvFromFlat(int texNumR, int texNumC, int index) {\n int texR = index / texNumC;\n int texC = index - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\nvec2 packedUVfrom1D(int texNumR, int texNumC, int index) {\n int texelIndex = index / 2;\n int texR = texelIndex / texNumC;\n int texC = texelIndex - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n",ve="\nvec2 packedUVfrom2D(int texelsInLogicalRow, int texNumR,\n int texNumC, int row, int col) {\n int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2);\n int texR = texelIndex / texNumC;\n int texC = texelIndex - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n",Ce="\nvec2 packedUVfrom3D(int texNumR, int texNumC,\n int texelsInBatch, int texelsInLogicalRow, int b,\n int row, int col) {\n int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2);\n int texR = index / texNumC;\n int texC = index - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n",$e="\n float getChannel(vec4 frag, vec2 innerDims) {\n vec2 modCoord = mod(innerDims, 2.);\n return modCoord.x == 0. ?\n (modCoord.y == 0. ? frag.r : frag.g) :\n (modCoord.y == 0. ? frag.b : frag.a);\n }\n float getChannel(vec4 frag, int dim) {\n float modCoord = mod(float(dim), 2.);\n return modCoord == 0. ? frag.r : frag.g;\n }\n";function ye(){return"\n int getOutputCoords() {\n return 0;\n }\n "}function Ie(e){return`offset${e}`}function we(e){const n=e.name,a=t.util.sizeFromShape(e.shapeInfo.logicalShape);return a<2?`return ${n};`:`\n for (int i = 0; i < ${a}; i++) {\n if (i == index) {\n return ${n}[i];\n }\n }\n `}function Se(e){if(e<=1)return"int";if(2===e)return"ivec2";if(3===e)return"ivec3";if(4===e)return"ivec4";if(5===e)return"ivec5";if(6===e)return"ivec6";throw Error(`GPU for rank ${e} is not yet supported`)}function ke(e,n,a){const{newShape:r,keptDims:o}=t.util.squeezeShape(n),s=n.length,i=e&&3===s&&1===n[0],l=i?n.slice(1):r,u=!e&&s>1&&!t.util.arraysEqual(n,a)&&r.length<s||i;return{useSqueezeShape:u,uniformShape:u?l:n,keptDims:o}}function Re(e,t){const n=JSON.parse(JSON.stringify(e));return n.shapeInfo.logicalShape=t,n}function Te(e,t){return t.map((t=>e[t])).join(", ")}function Ne(e,n,a){const r=[],o=[];let s,i,l,u=null,c=null;c=e.getUniformLocation(a,"NAN",!1),1===t.env().getNumber("WEBGL_VERSION")&&(u=e.getUniformLocation(a,"INFINITY",!1));const d=!1;for(const t of n.variableNames){const o={name:t,uniform:e.getUniformLocation(a,t,d),offset:e.getUniformLocation(a,`offset${t}`,d)};n.enableShapeUniforms&&(o.shape=e.getUniformLocation(a,`${t}Shape`,d),o.texShape=e.getUniformLocation(a,`${t}TexShape`,d)),r.push(o)}if(n.enableShapeUniforms&&(s=e.getUniformLocation(a,"outShape",d),l=e.getUniformLocation(a,"outShapeStrides",d),i=e.getUniformLocation(a,"outTexShape",d)),n.customUniforms)for(const t of n.customUniforms)o.push(e.getUniformLocation(a,t.name,d));return{variablesLocations:r,customUniformLocations:o,infLoc:u,nanLoc:c,outShapeLocation:s,outShapeStridesLocation:l,outTexShapeLocation:i}}function Ee(e,n){if(e.length!==n.length)throw Error(`Binary was compiled with ${e.length} inputs, but was executed with ${n.length} inputs`);e.forEach(((e,a)=>{const r=e.logicalShape,o=n[a],s=o.shape;if(!t.util.arraysEqual(r,s))throw Error(`Binary was compiled with different shapes than the current args. Shapes ${r} and ${s} must match`);if(e.isUniform&&o.isUniform)return;const i=e.texShape,l=o.isUniform?null:o.texData.texShape;if(!t.util.arraysEqual(i,l))throw Error(`Binary was compiled with different texture shapes than the current args. Shape ${i} and ${l} must match`)}))}function Ae(e){return t.env().getBool("WEBGL_USE_SHAPES_UNIFORMS")&&e<=4}class _e{constructor(e){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.outPackingScheme=l.DENSE,this.customUniforms=[{name:"texShape",type:"ivec2"}];const t=le();this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length),this.userCode=`\n ivec3 outCoordsFromFlatIndex(int index) {\n ${this.enableShapeUniforms?ce(["r","c","d"],e):ue(["r","c","d"],e)}\n return ivec3(r, c, d);\n }\n\n void main() {\n ivec2 resTexRC = ivec2(resultUV.yx * vec2(texShape[0], texShape[1]));\n int index = 4 * (resTexRC.x * texShape[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 ${t.output} = result;\n }\n `}}class Oe{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outPackingScheme=l.DENSE,this.customUniforms=[{name:"texShape",type:"ivec2"}];const t=le();this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length),this.userCode=`\n ivec3 outCoordsFromFlatIndex(int index) {\n ${this.enableShapeUniforms?ce(["r","c","d"],e):ue(["r","c","d"],e)}\n return ivec3(r, c, d);\n }\n\n void main() {\n ivec2 resTexRC = ivec2(resultUV.yx * vec2(texShape[0], texShape[1]));\n int index = 4 * (resTexRC.x * texShape[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 ${t.output} = result;\n }\n `}}class Fe{constructor(e){this.variableNames=["A"],this.outTexUsage=u.DOWNLOAD;const t=le();this.outputShape=e,this.userCode=`\n ${he}\n\n void main() {\n float x = getAAtOutCoords();\n ${t.output} = encode_float(x);\n }\n `}}class De{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!1,this.outTexUsage=u.DOWNLOAD;const t=le();this.outputShape=e,this.userCode=`\n ${he}\n\n void main() {\n ivec3 coords = getOutputCoords();\n float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z));\n ${t.output} = encode_float(x);\n }\n `}}const Pe={R:0,G:1,B:2,A:3};class Le{constructor(e,t=!1,n="RGBA"){this.variableNames=["A"],this.customUniforms=[{name:"texShape",type:"ivec2"}];const a=le();this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length);let r="result";t&&(r="floor(result * 255. + 0.5)");let o="";for(let e=0;e<n.length;e++){const t=n[e];o+=`\n if(offset == ${e}) {\n result = values[${Pe[t]}];\n }`}this.userCode=`\n ${this.enableShapeUniforms?"\n int getFlatIndex(ivec3 coords) {\n return coords.x * outShapeStrides[0] + coords.y * outShapeStrides[1] + coords.z;\n }\n":pe(e)}\n\n void main() {\n ivec3 coords = getOutputCoords();\n int flatIndex = getFlatIndex(coords);\n float result = 0.;\n int offset = imod(flatIndex, ${n.length});\n\n flatIndex = idiv(flatIndex, ${n.length}, 1.);\n\n int r = flatIndex / texShape[1];\n if (r < texShape[0]) {\n int c = imod(flatIndex, texShape[1]);\n vec2 uv = (vec2(c, r) + halfCR) / vec2(texShape[1], texShape[0]);\n vec4 values = ${a.texture2D}(A, uv);\n ${o}\n }\n ${a.output} = vec4(${r}, 0., 0., 0.);\n }\n `}}class Be{constructor(e,t=!1){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.customUniforms=[{name:"texShape",type:"ivec2"}];const n=le();this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length);let a="",r="result";t&&(r="floor(result * 255. + 0.5)");for(let t=0;t<=1;t++)for(let r=0;r<=1;r++){const o=2*t+r;a+=`\n localCoords = coords;\n if(localCoords[2] + ${r} < ${this.enableShapeUniforms?"outShape[2]":`${e[2]}`}) {\n localCoords[2] += ${r};\n if (localCoords[1] + ${t} < ${this.enableShapeUniforms?"outShape[1]":`${e[1]}`}) {\n localCoords[1] += ${t};\n\n flatIndex = getFlatIndex(localCoords);\n offset = imod(flatIndex, 4);\n\n flatIndex = idiv(flatIndex, 4, 1.);\n\n int r = flatIndex / texShape[1];\n int c = imod(flatIndex, texShape[1]);\n vec2 uv = (vec2(c, r) + halfCR) / vec2(texShape[1], texShape[0]);\n values = ${n.texture2D}(A, uv);\n\n if (offset == 0) {\n result[${o}] = values[0];\n } else if (offset == 1) {\n result[${o}] = values[1];\n } else if (offset == 2) {\n result[${o}] = values[2];\n } else {\n result[${o}] = values[3];\n }\n }\n }\n `}this.userCode=`\n ${this.enableShapeUniforms?"\n int getFlatIndex(ivec3 coords) {\n return coords.x * outShapeStrides[0] + coords.y * outShapeStrides[1] + coords.z;\n }\n":pe(e)}\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 ${a}\n\n ${n.output} = ${r};\n }\n `}}function Ve(e){const t=le();return v(e,`${t.version}\n precision highp float;\n ${t.attribute} vec3 clipSpacePos;\n ${t.attribute} vec2 uv;\n ${t.varyingVs} vec2 resultUV;\n\n void main() {\n gl_Position = vec4(clipSpacePos, 1);\n resultUV = uv;\n }`)}function We(e){return k(e,new Float32Array([-1,1,0,0,1,-1,-1,0,0,0,1,1,0,1,1,1,-1,0,1,0]))}function Ue(e){return R(e,new Uint16Array([0,1,2,2,1,3]))}function Me(e,n,a,r,o,s){N(n,a);const i=T(e),l=e.TEXTURE_2D;return x(e,(()=>e.bindTexture(l,i))),x(e,(()=>e.texParameteri(l,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE))),x(e,(()=>e.texParameteri(l,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE))),x(e,(()=>e.texParameteri(l,e.TEXTURE_MIN_FILTER,e.NEAREST))),x(e,(()=>e.texParameteri(l,e.TEXTURE_MAG_FILTER,e.NEAREST))),1===t.env().getNumber("WEBGL_VERSION")?x(e,(()=>e.texImage2D(l,0,r,n,a,0,o,s,null))):x(e,(()=>e.texStorage2D(l,1,r,n,a))),x(e,(()=>e.bindTexture(e.TEXTURE_2D,null))),{texture:i,texShape:[a,n]}}function Ge(e){return e.internalFormatFloat}function ze(e,t,n,a){const[r,o]=d(t,n);return Me(e,r,o,Ge(a),a.textureFormatFloat,e.FLOAT)}function Xe(e){return e.internalFormatHalfFloat}function He(e,t,n,a){const[r,o]=d(t,n);return Me(e,r,o,Xe(a),a.textureFormatFloat,a.textureTypeHalfFloat)}function je(e){return e.downloadTextureFormat}function Ke(e,t,n,a){const[r,o]=d(t,n);return Me(e,r,o,je(a),e.RGBA,e.UNSIGNED_BYTE)}function qe(e){return e.internalFormatPackedFloat}function Ye(e,t,n,a){const[r,o]=h(t,n);return Me(e,r,o,qe(a),e.RGBA,e.FLOAT)}function Qe(e){return e.internalFormatPackedHalfFloat}function Ze(e,t,n,a){const[r,o]=h(t,n);return Me(e,r,o,Qe(a),e.RGBA,a.textureTypeHalfFloat)}function Je(e,t,n){x(e,(()=>e.bindBuffer(e.ARRAY_BUFFER,n)));return A(e,t,"clipSpacePos",n,3,20,0)&&A(e,t,"uv",n,2,20,12)}function et(e,n,a,r,o,s){let i,l,u;x(e,(()=>e.bindTexture(e.TEXTURE_2D,n))),o instanceof Uint8Array?(i=new Uint8Array(a*r*4),l=e.UNSIGNED_BYTE,u=e.RGBA):(i=new Float32Array(a*r*4),l=e.FLOAT,u=s.internalFormatPackedFloat),i.set(o),2===t.env().getNumber("WEBGL_VERSION")?x(e,(()=>e.texSubImage2D(e.TEXTURE_2D,0,0,0,a,r,e.RGBA,l,i))):x(e,(()=>e.texImage2D(e.TEXTURE_2D,0,u,a,r,0,e.RGBA,l,i))),x(e,(()=>e.bindTexture(e.TEXTURE_2D,null)))}function tt(e,n,a){x(e,(()=>e.bindTexture(e.TEXTURE_2D,n))),a.data instanceof Uint8Array?2===t.env().getNumber("WEBGL_VERSION")?x(e,(()=>e.texSubImage2D(e.TEXTURE_2D,0,0,0,a.width,a.height,e.RGBA,e.UNSIGNED_BYTE,a.data))):x(e,(()=>e.texImage2D(e.TEXTURE_2D,0,e.RGBA,a.width,a.height,0,e.RGBA,e.UNSIGNED_BYTE,a.data))):2===t.env().getNumber("WEBGL_VERSION")?x(e,(()=>e.texSubImage2D(e.TEXTURE_2D,0,0,0,e.RGBA,e.UNSIGNED_BYTE,a))):x(e,(()=>e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,a))),x(e,(()=>e.bindTexture(e.TEXTURE_2D,null)))}function nt(e,t,n,a){const r=e.createBuffer();x(e,(()=>e.bindBuffer(e.PIXEL_PACK_BUFFER,r)));const o=16*t*n;return x(e,(()=>e.bufferData(e.PIXEL_PACK_BUFFER,o,e.STREAM_READ))),x(e,(()=>e.readPixels(0,0,n,t,e.RGBA,e.FLOAT,0))),x(e,(()=>e.bindBuffer(e.PIXEL_PACK_BUFFER,null))),r}function at(e,t,n){const a=e,r=new Float32Array(n);return a.bindBuffer(a.PIXEL_PACK_BUFFER,t),a.getBufferSubData(a.PIXEL_PACK_BUFFER,0,r),a.bindBuffer(a.PIXEL_PACK_BUFFER,null),r}function rt(e,t,n,a){const[r,o]=d(t,n),s=new Uint8Array(t*n*4);return x(e,(()=>e.readPixels(0,0,r,o,a.downloadTextureFormat,e.UNSIGNED_BYTE,s))),new Float32Array(s.buffer)}function ot(e,t,n,a,r,o,s,i){const l=e,u=new Float32Array(function(e,t){const[n,a]=h(e,t);return n*a*4}(o,s));return l.bindBuffer(l.PIXEL_PACK_BUFFER,t),l.getBufferSubData(l.PIXEL_PACK_BUFFER,0,u),l.bindBuffer(l.PIXEL_PACK_BUFFER,null),u}function st(e,t,n){const a=new Float32Array(t*n*4);return x(e,(()=>e.readPixels(0,0,n,t,e.RGBA,e.FLOAT,a))),a}var it={__proto__:null,bindVertexProgramAttributeStreams:Je,createBufferFromOutputTexture:nt,createFloat16MatrixTexture:He,createFloat16PackedMatrixTexture:Ze,createFloat32MatrixTexture:ze,createIndexBuffer:Ue,createPackedMatrixTexture:Ye,createUnsignedBytesMatrixTexture:Ke,createVertexBuffer:We,createVertexShader:Ve,downloadByteEncodedFloatMatrixFromOutputTexture:rt,downloadFloat32MatrixFromBuffer:at,downloadMatrixFromPackedOutputTexture:st,downloadPackedMatrixFromBuffer:ot,getInternalFormatForFloat16MatrixTexture:Xe,getInternalFormatForFloat16PackedMatrixTexture:Qe,getInternalFormatForFloat32MatrixTexture:Ge,getInternalFormatForPackedMatrixTexture:qe,getInternalFormatForUnsignedBytesMatrixTexture:je,uploadDenseMatrixToTexture:et,uploadPixelDataToTexture:tt};class lt{constructor(e){this.outputTexture=null,this.program=null,this.disposed=!1,this.itemsToPoll=[];const n=t.env().getNumber("WEBGL_VERSION");if(null!=e?(this.gl=e,s(n,e)):this.gl=i(n),e=this.gl,2===t.env().getNumber("WEBGL_VERSION")){const t=e;this.createVertexArray=()=>x(t,(()=>t.createVertexArray())),this.bindVertexArray=e=>x(t,(()=>t.bindVertexArray(e))),this.deleteVertexArray=e=>x(t,(()=>t.deleteVertexArray(e))),this.getVertexArray=()=>x(t,(()=>t.getParameter(t.VERTEX_ARRAY_BINDING)))}else if(null!=e){const t=e.getExtension("OES_vertex_array_object");if(null==t)throw new Error("All WebGL1 implementations are expected to offer OES_vertex_array_object.");this.createVertexArray=()=>x(e,(()=>t.createVertexArrayOES())),this.bindVertexArray=n=>x(e,(()=>t.bindVertexArrayOES(n))),this.deleteVertexArray=n=>x(e,(()=>t.deleteVertexArrayOES(n))),this.getVertexArray=()=>x(e,(()=>e.getParameter(t.VERTEX_ARRAY_BINDING_OES)))}let a="WEBGL_color_buffer_float";const r="EXT_color_buffer_half_float";if(this.parallelCompilationExtension=this.gl.getExtension("KHR_parallel_shader_compile"),1===t.env().getNumber("WEBGL_VERSION")){const e="OES_texture_float",n="OES_texture_half_float";if(this.textureFloatExtension=b(this.gl,e),J(this.gl,n))this.textureHalfFloatExtension=b(this.gl,n);else if(t.env().get("WEBGL_FORCE_F16_TEXTURES"))throw new Error("GL context does not support half float textures, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.");if(this.colorBufferFloatExtension=this.gl.getExtension(a),J(this.gl,r))this.colorBufferHalfFloatExtension=b(this.gl,r);else if(t.env().get("WEBGL_FORCE_F16_TEXTURES"))throw new Error("GL context does not support color renderable half floats, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.")}else if(a="EXT_color_buffer_float",J(this.gl,a))this.colorBufferFloatExtension=this.gl.getExtension(a);else{if(!J(this.gl,r))throw new Error("GL context does not support color renderable floats");this.colorBufferHalfFloatExtension=this.gl.getExtension(r)}this.vertexBuffer=We(this.gl),this.indexBuffer=Ue(this.gl),this.framebuffer=E(this.gl),this.textureConfig=f(this.gl,this.textureHalfFloatExtension)}get debug(){return t.env().getBool("DEBUG")}dispose(){if(this.disposed)return;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.");const e=this.gl;x(e,(()=>e.finish())),x(e,(()=>e.bindFramebuffer(e.FRAMEBUFFER,null))),x(e,(()=>e.deleteFramebuffer(this.framebuffer))),x(e,(()=>e.bindBuffer(e.ARRAY_BUFFER,null))),x(e,(()=>e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null))),x(e,(()=>e.deleteBuffer(this.indexBuffer))),this.disposed=!0}createFloat32MatrixTexture(e,t){return this.throwIfDisposed(),ze(this.gl,e,t,this.textureConfig)}createFloat16MatrixTexture(e,t){return this.throwIfDisposed(),He(this.gl,e,t,this.textureConfig)}createUnsignedBytesMatrixTexture(e,t){return this.throwIfDisposed(),Ke(this.gl,e,t,this.textureConfig)}uploadPixelDataToTexture(e,t){this.throwIfDisposed(),tt(this.gl,e,t)}uploadDenseMatrixToTexture(e,t,n,a){this.throwIfDisposed(),et(this.gl,e,t,n,a,this.textureConfig)}createFloat16PackedMatrixTexture(e,t){return this.throwIfDisposed(),Ze(this.gl,e,t,this.textureConfig)}createPackedMatrixTexture(e,t){return this.throwIfDisposed(),Ye(this.gl,e,t,this.textureConfig)}deleteMatrixTexture(e){this.throwIfDisposed(),this.outputTexture===e&&(L(this.gl,this.framebuffer),this.outputTexture=null),x(this.gl,(()=>this.gl.deleteTexture(e)))}downloadByteEncodedFloatMatrixFromOutputTexture(e,t,n){return this.downloadMatrixDriver(e,(()=>rt(this.gl,t,n,this.textureConfig)))}downloadPackedMatrixFromBuffer(e,t,n,a,r,o){return ot(this.gl,e,0,0,0,r,o,this.textureConfig)}downloadFloat32MatrixFromBuffer(e,t){return at(this.gl,e,t)}createBufferFromTexture(e,t,n){this.bindTextureToFrameBuffer(e);const a=nt(this.gl,t,n,this.textureConfig);return this.unbindTextureToFrameBuffer(),a}createAndWaitForFence(){const e=this.createFence(this.gl);return this.pollFence(e)}createFence(e){let n,a;if(t.env().getBool("WEBGL_FENCE_API_ENABLED")){const t=e,r=t.fenceSync(t.SYNC_GPU_COMMANDS_COMPLETE,0);e.flush(),a=()=>{const e=t.clientWaitSync(r,0,0);return e===t.ALREADY_SIGNALED||e===t.CONDITION_SATISFIED},n=r}else t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?(n=this.beginQuery(),this.endQuery(),a=()=>this.isQueryAvailable(n,t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))):a=()=>!0;return{query:n,isFencePassed:a}}downloadMatrixFromPackedTexture(e,t,n){return this.downloadMatrixDriver(e,(()=>st(this.gl,t,n)))}createProgram(e){this.throwIfDisposed();const t=this.gl;null==this.vertexShader&&(this.vertexShader=Ve(t));const n=I(t);x(t,(()=>t.attachShader(n,this.vertexShader))),x(t,(()=>t.attachShader(n,e))),w(t,n);const a=Object.assign(n,{vao:this.createVertexArray()});return this.debug&&S(t,a),a}buildVao(e){this.setProgram(e),this.bindVertexArray(e.vao);const t=this.gl;x(t,(()=>t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,this.indexBuffer))),Je(t,e,this.vertexBuffer)}deleteProgram(e){this.throwIfDisposed(),e===this.program&&(this.program=null),null!=e&&(x(this.gl,(()=>this.gl.deleteProgram(e))),this.deleteVertexArray(e.vao))}setProgram(e){this.throwIfDisposed(),this.program=e,null!=this.program&&this.debug&&S(this.gl,this.program),x(this.gl,(()=>this.gl.useProgram(e)))}getUniformLocation(e,t,n=!0){return this.throwIfDisposed(),n?O(this.gl,e,t):F(this.gl,e,t)}getAttributeLocation(e,t){return this.throwIfDisposed(),x(this.gl,(()=>this.gl.getAttribLocation(e,t)))}getUniformLocationNoThrow(e,t){return this.throwIfDisposed(),this.gl.getUniformLocation(e,t)}setInputMatrixTexture(e,t,n){this.throwIfDisposed(),this.throwIfNoProgram(),D(this.gl,e,t,n)}setOutputMatrixTexture(e,t,n){this.setOutputMatrixTextureDriver(e,n,t)}setOutputPackedMatrixTexture(e,t,n){this.throwIfDisposed();const[a,r]=h(t,n);this.setOutputMatrixTextureDriver(e,a,r)}setOutputMatrixWriteRegion(e,t,n,a){this.setOutputMatrixWriteRegionDriver(n,e,a,t)}setOutputPackedMatrixWriteRegion(e,t,n,a){throw new Error("setOutputPackedMatrixWriteRegion not implemented.")}debugValidate(){null!=this.program&&S(this.gl,this.program),B(this.gl)}executeProgram(){this.throwIfDisposed(),this.throwIfNoProgram();const e=this.gl;if(this.debug){const e=this.getVertexArray();console.assert(e===this.program.vao,"VAO changed between setProgram and executeProgram!"),this.debugValidate()}x(e,(()=>e.drawElements(e.TRIANGLES,6,e.UNSIGNED_SHORT,0)))}blockUntilAllProgramsCompleted(){this.throwIfDisposed(),x(this.gl,(()=>this.gl.finish()))}getQueryTimerExtension(){return null==this.disjointQueryTimerExtension&&(this.disjointQueryTimerExtension=b(this.gl,2===t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")?"EXT_disjoint_timer_query_webgl2":"EXT_disjoint_timer_query")),this.disjointQueryTimerExtension}getQueryTimerExtensionWebGL2(){return this.getQueryTimerExtension()}getQueryTimerExtensionWebGL1(){return this.getQueryTimerExtension()}beginQuery(){if(2===t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){const e=this.gl,t=this.getQueryTimerExtensionWebGL2(),n=e.createQuery();return e.beginQuery(t.TIME_ELAPSED_EXT,n),n}const e=this.getQueryTimerExtensionWebGL1(),n=e.createQueryEXT();return e.beginQueryEXT(e.TIME_ELAPSED_EXT,n),n}endQuery(){if(2===t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){const e=this.gl,t=this.getQueryTimerExtensionWebGL2();return void e.endQuery(t.TIME_ELAPSED_EXT)}const e=this.getQueryTimerExtensionWebGL1();e.endQueryEXT(e.TIME_ELAPSED_EXT)}async waitForQueryAndGetTime(e){return await t.util.repeatedTry((()=>this.disposed||this.isQueryAvailable(e,t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")))),this.getQueryTime(e,t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))}getQueryTime(e,t){if(0===t)return null;if(2===t){const t=this.gl;return t.getQueryParameter(e,t.QUERY_RESULT)/1e6}{const t=this.getQueryTimerExtensionWebGL1();return t.getQueryObjectEXT(e,t.QUERY_RESULT_EXT)/1e6}}isQueryAvailable(e,t){if(0===t)return!0;if(2===t){const t=this.gl,n=this.getQueryTimerExtensionWebGL2(),a=t.getQueryParameter(e,t.QUERY_RESULT_AVAILABLE);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(n.GPU_DISJOINT_EXT)),a&&!this.disjoint}{const t=this.getQueryTimerExtensionWebGL1(),n=t.getQueryObjectEXT(e,t.QUERY_RESULT_AVAILABLE_EXT);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(t.GPU_DISJOINT_EXT)),n&&!this.disjoint}}pollFence(e){return new Promise((t=>{this.addItemToPoll((()=>e.isFencePassed()),(()=>t()))}))}pollItems(){const e=function(e){let t=0;for(;t<e.length;++t){if(!e[t]())break}return t-1}(this.itemsToPoll.map((e=>e.isDoneFn)));for(let t=0;t<=e;++t){const{resolveFn:e}=this.itemsToPoll[t];e()}this.itemsToPoll=this.itemsToPoll.slice(e+1)}addItemToPoll(e,n){if(this.itemsToPoll.push({isDoneFn:e,resolveFn:n}),this.itemsToPoll.length>1)return;let a;"setTimeoutCustom"in t.env().platform&&(a=t.env().platform.setTimeoutCustom.bind(t.env().platform)),t.util.repeatedTry((()=>(this.pollItems(),0===this.itemsToPoll.length)),(()=>0),null,a)}bindTextureToFrameBuffer(e){this.throwIfDisposed(),P(this.gl,e,this.framebuffer),this.debug&&B(this.gl)}unbindTextureToFrameBuffer(){null!=this.outputTexture?(P(this.gl,this.outputTexture,this.framebuffer),this.debug&&B(this.gl)):L(this.gl,this.framebuffer)}downloadMatrixDriver(e,t){this.bindTextureToFrameBuffer(e);const n=t();return this.unbindTextureToFrameBuffer(),n}setOutputMatrixTextureDriver(e,t,n){this.throwIfDisposed();const a=this.gl;P(a,e,this.framebuffer),this.debug&&B(a),this.outputTexture=e,x(a,(()=>a.viewport(0,0,t,n))),x(a,(()=>a.scissor(0,0,t,n)))}setOutputMatrixWriteRegionDriver(e,t,n,a){this.throwIfDisposed(),x(this.gl,(()=>this.gl.scissor(e,t,n,a)))}throwIfDisposed(){if(this.disposed)throw new Error("Attempted to use disposed GPGPUContext.")}throwIfNoProgram(){if(null==this.program)throw new Error("No GPU program is currently set.")}}function ut(e){return(n,a,r,o,s)=>{const i=t.backend_util.assertAndGetBroadcastShape(n,a),l=i.length,u=t.util.computeStrides(i),c=t.util.sizeFromShape(i),d=t.util.getTypedArrayFromDType(s,c),p=n.length,h=a.length,f=t.util.computeStrides(n),x=t.util.computeStrides(a),m=t.backend_util.getBroadcastDims(n,i),g=t.backend_util.getBroadcastDims(a,i);if(m.length+g.length===0)for(let t=0;t<d.length;++t)d[t]=e(r[t%r.length],o[t%o.length]);else for(let n=0;n<d.length;++n){const a=t.util.indexToLoc(n,l,u),s=a.slice(-p);m.forEach((e=>s[e]=0));const i=t.util.locToIndex(s,p,f),c=a.slice(-h);g.forEach((e=>c[e]=0));const b=t.util.locToIndex(c,h,x);d[n]=e(r[i],o[b])}return[d,i]}}const ct=ut(((e,t)=>e+t));const dt=ut(((e,t)=>e&t));function pt(e){return(n,a,r)=>{const o=t.util.getArrayFromDType(a,n.length);for(let t=0;t<n.length;++t)o[t]=e(n[t],r);return o}}const ht=pt((e=>Math.ceil(e)));const ft=ut(((e,t)=>e===t?1:0)),xt=pt((e=>Math.exp(e))),mt=pt((e=>Math.expm1(e))),gt=pt((e=>Math.floor(e))),bt=ut(((e,t)=>Math.floor(e/t)));const vt=ut(((e,t)=>e>t?1:0)),Ct=ut(((e,t)=>e>=t?1:0)),$t=ut(((e,t)=>e<t?1:0)),yt=ut(((e,t)=>e<=t?1:0));const It=pt((e=>Math.log(e)));const wt=ut(((e,t)=>Math.max(e,t))),St=ut(((e,t)=>Math.min(e,t))),kt=ut(((e,t)=>e*t));const Rt=ut(((e,t)=>e!==t?1:0));function Tt(e,t,n,a){const r=[];let o=0;const s=t.length-1+n.length,i=new Array(s).fill(null).map((()=>[0]));!function(e,t){for(let n=0;n<e.length;++n){const a=e[n],r=n===e.length-1?t:e[n+1].length;if(0===a.length)throw new Error("Ragged splits may not be empty");if(a[0]<0)throw new Error("Ragged splits must be non-negative");if(a[a.length-1]>r)throw new Error("Ragged splits must not point past values");for(let e=1;e<a.length;++e)if(a[e-1]>a[e])throw new Error("Ragged splits must be sorted in ascending order")}}(n,a);let l=1;for(let e=0;e<t.length-1;++e){l*=t[e];const n=t[e+1];for(let t=1;t<l+1;++t)i[e].push(t*n)}for(let a=0;a<e.length;++a){let s=e[a],l=e[a]+1;for(let e=0;e<n.length;++e){const a=n[e],r=e+t.length-1;if(r>=0){const e=i[r],t=e[e.length-1]-a[s];for(let e=s;e<l;++e)i[r].push(a[e+1]+t)}s=a[s],l=a[l]}l!==s&&(r.push([s,l]),o+=l-s)}return{outSplits:i,valueSlices:r,numValues:o}}function Nt(e,t){const n=e.slice(0,t);for(;n.length<t;)n.push(1);for(let a=t;a<e.length;a++)n[t-1]*=e[a];return n}function Et(e,n,a,r,o){const s=n.slice();s[0]=o;const i=t.util.getArrayFromDType(a,t.util.sizeFromShape(s)),l=e.length;return function(e,t,n,a,r,o){const s=Nt(t,2)[1],i=Nt(o,2)[1];let l=0;for(const t of n)for(let n=t[0];n<t[1];++n){for(let t=0;t<a;++t)r[l*i+t]=e[n*s+t];++l}}(e,n,r,0===l?0:l/n[0],i,s),[i,s]}const At=2147483647;var _t=t.backend_util.RowPartitionType;class Ot{constructor(e,n,a,r,o,s,i,l,u,c){this.shape=e,this.shapeShape=n,this.values=a,this.valuesShape=r,this.valuesDType=o,this.defaultValue=s,this.defaultValueShape=i,this.rowPartitionValues=l,this.rowPartitionValuesShapes=u,this.rowPartitionTypes=t.backend_util.getRowPartitionTypesHelper(c),this.raggedRank=t.backend_util.getRaggedRank(this.rowPartitionTypes)}getRowPartitionTypeByDimension(e){return this.rowPartitionTypes[0]===_t.FIRST_DIM_SIZE?this.rowPartitionTypes[e+1]:this.rowPartitionTypes[e]}getRowPartitionTensor(e){return this.rowPartitionTypes[0]===_t.FIRST_DIM_SIZE?this.rowPartitionValues[e+1]:this.rowPartitionValues[e]}getMaxWidth(e){const t=this.getRowPartitionTensor(e-1);switch(this.getRowPartitionTypeByDimension(e-1)){case _t.VALUE_ROWIDS:return Ot.getMaxWidthValueRowID(t);case _t.ROW_SPLITS:return Ot.getMaxWidthRowSplit(t);default:throw new Error(`Cannot handle partition type ${_t[this.getRowPartitionTypeByDimension(e-1)]}`)}}static getMaxWidthRowSplit(e){const t=e.length;if(0===t||1===t)return 0;let n=0;for(let a=0;a<t-1;++a){const t=e[a+1]-e[a];t>n&&(n=t)}return n}static getMaxWidthValueRowID(e){const t=e.length;if(0===t)return 0;let n=0,a=e[0],r=0;for(let o=1;o<t;++o){const t=e[o];t!==a&&(a=t,r=Math.max(o-n,r),n=o)}return Math.max(t-n,r)}tensorShapeFromTensor(e,t,n=!0){if(0===t.length){if(-1===e[0])return[];throw new Error("The only valid scalar shape tensor is the fully unknown shape specified as -1.")}return Dt(e,n)}calculateOutputSize(e){const n=this.valuesShape,a=this.defaultValueShape;t.backend_util.validateDefaultValueShape(a,n);const r=this.tensorShapeFromTensor(this.shape,this.shapeShape),o=t.backend_util.combineRaggedTensorToTensorShapes(this.raggedRank,r,n);o[0]<0&&(o[0]=e);for(let e=1;e<=this.raggedRank;++e)o[e]<0&&(o[e]=this.getMaxWidth(e));return o}calculateFirstParentOutputIndex(e,n,a){const r=Math.min(e,a),o=[];let s=0;for(let e=0;e<r;++e,s+=n)o.push(s);for(let t=r;t<e;++t)o.push(-1);return t.util.assert(o.length===e,(()=>"Final length of result must be equal to firstDimension.")),o}calculateOutputIndexRowSplit(e,t,n,a){const r=e.length,o=[];for(let s=0;s<r-1;++s){const r=e[s+1]-e[s];let i=Math.min(a,r),l=t[s];-1===l&&(i=0);for(let e=0;e<i;++e)o.push(l),l+=n;for(let e=0;e<r-i;++e)o.push(-1)}if(r>0&&o.length!==e[r-1])throw new Error("Invalid row split size.");return o}calculateOutputIndexValueRowID(e,t,n,a){const r=e.length,o=[];if(0===r)return[];let s=0,i=e[0];if(i>=t.length)throw new Error(`Got currentValueRowId=${i}, which is not less than ${t.length}`);let l=t[i];o.push(l);for(let u=1;u<r;++u){const r=e[u];if(r===i)l>=0&&(++s,s<a?l+=n:l=-1);else{if(s=0,i=r,r>=t.length)throw new Error(`Got nextValueRowId=${r} which is not less than ${t.length}`);l=t[r]}o.push(l)}if(o.length!==e.length)throw new Error("Invalid row ids.");return o}calculateOutputIndex(e,t,n,a){const r=this.getRowPartitionTensor(e),o=this.getRowPartitionTypeByDimension(e);switch(o){case _t.VALUE_ROWIDS:return this.calculateOutputIndexValueRowID(r,t,n,a);case _t.ROW_SPLITS:if(r.length-1>t.length)throw new Error(`Row partition size is greater than output size: ${r.length-1} > ${t.length}`);return this.calculateOutputIndexRowSplit(r,t,n,a);default:throw new Error(`Unsupported partition type: ${_t[o]}`)}}getFirstDimensionSize(){const e=this.rowPartitionValues[0];if(0===this.rowPartitionTypes.length)throw new Error("No row_partition_types given.");const t=this.rowPartitionTypes[0];switch(t){case _t.FIRST_DIM_SIZE:return e[0];case _t.VALUE_ROWIDS:throw new Error("Cannot handle VALUE_ROWIDS in first dimension.");case _t.ROW_SPLITS:return this.rowPartitionValuesShapes[0][0]-1;default:throw new Error(`Cannot handle type ${_t[t]}`)}}compute(){if(this.rowPartitionValues[0].length<=0)throw new Error("Invalid first partition input. Tensor requires at least one element.");const e=this.getFirstDimensionSize(),n=this.calculateOutputSize(e),a=new Array(this.raggedRank+1);a[a.length-1]=1;for(let e=a.length-2;e>=0;--e)a[e]=a[e+1]*n[e+1];const r=Dt(n,!1),o=t.util.getArrayFromDType(this.valuesDType,t.util.sizeFromShape(r));if(a[0]*n[0]>0){let t=this.calculateFirstParentOutputIndex(e,a[0],n[0]);for(let e=1;e<=this.raggedRank;++e){t=this.calculateOutputIndex(e-1,t,a[e],n[e])}this.setOutput(this.raggedRank,t,o,r)}return[r,o]}setOutput(e,n,a,r){if(0===a.length)return;const o=this.values,s=a;let i=r.slice();i=i.slice(e+1);const l=t.util.sizeFromShape(i),u=n.length;let c=this.defaultValue;if(c.length!==l&&1!==c.length){const e=this.defaultValueShape;t.tidy((()=>{const n=t.reshape(c,e),a=t.broadcastTo(n,i);c=a.dataSync()}))}let d=0,p=0,h=0;for(let e=0;e<=u;++e){let t=e<u?n[e]:-1;if(t!==h){if(p<h){const e=o.subarray(d*l);Ft(s.subarray(p*l),e,(h-p)*l)}if(e>=u){const e=a.length;t=Math.floor(e/l)}if(t>h)if(1===this.defaultValue.length)s.subarray(h*l,t*l).fill(this.defaultValue[0]),h=t;else for(;t>h;){Ft(s.slice(h*l),c,l),++h}t<0?(d=e+1,p=h):(d=e,p=h,h=p+1)}else++h}}}function Ft(e,t,n){for(let a=0;a<n;a++)e[a]=t[a]}function Dt(e,t){const n=[];for(let a of e){if(a<0){if(!t)throw new Error(`Dimension ${a} must be >= 0`);if(a<-1)throw new Error(`Dimension ${a} must be >= -1`);a=-1}n.push(a)}return n}const Pt=pt((e=>1/Math.sqrt(e)));const Lt=pt((e=>1/(1+Math.exp(-e))));const Bt=pt((e=>Math.sqrt(e))),Vt=ut(((e,t)=>{const n=e-t;return n*n})),Wt=pt(((e,t)=>{const{pattern:n,replaceGlobal:a,rewrite:r}=t;return e.replace(new RegExp(n,a?"g":""),r)}));class Ut{constructor(e,n,a,r,o,s){this.separator=t.util.encodeString(e),this.nGramWidths=n,this.leftPad=t.util.encodeString(a),this.rightPad=t.util.encodeString(r),this.padWidth=o,this.preserveShort=s}getPadWidth(e){return Math.min(this.padWidth<0?e-1:this.padWidth,e-1)}getNumNGrams(e,t){const n=this.getPadWidth(t);return Math.max(0,e+2*n-t+1)}createNGrams(e,t,n,a,r,o){for(let s=0;s<r;++s){const i=this.getPadWidth(o),l=Math.max(0,i-s),u=Math.max(0,i-(r-(s+1))),c=o-(l+u),d=t+(l>0?0:s-i);let p=0;p+=l*this.leftPad.length;for(let t=0;t<c;++t)p+=e[d+t].length;p+=u*this.rightPad.length;p+=(l+u+c-1)*this.separator.length,n[a+s]=new Uint8Array(p);const h=n[a+s];let f=0;const x=e=>e.forEach((e=>h[f++]=e));for(let e=0;e<l;++e)x(this.leftPad),x(this.separator);for(let t=0;t<c-1;++t)x(e[d+t]),x(this.separator);if(c>0){x(e[d+c-1]);for(let e=0;e<u;++e)x(this.separator),x(this.rightPad)}else{for(let e=0;e<u-1;++e)x(this.rightPad),x(this.separator);x(this.rightPad)}}}compute(e,n){const a=e.length,r=n.length;if(r>0){let e=n[0];if(0!==e)throw new Error(`First split value must be 0, got ${e}`);for(let t=1;t<r;++t){let r=n[t]>=e;if(r=r&&n[t]<=a,!r)throw new Error(`Invalid split value ${n[t]}, must be in [${e}, ${a}]`);e=n[t]}if(e!==a)throw new Error(`Last split value must be data size. Expected ${a}, got ${e}`)}const o=r-1,s=t.util.getArrayFromDType("int32",r);if(0===a||0===r){const e=new Array(a);for(let e=0;e<=o;++e)s[e]=0;return[e,s]}s[0]=0;for(let e=1;e<=o;++e){const t=n[e]-n[e-1];let a=0;this.nGramWidths.forEach((e=>{a+=this.getNumNGrams(t,e)})),this.preserveShort&&t>0&&0===a&&(a=1),s[e]=s[e-1]+a}const i=new Array(s[o]);for(let t=0;t<o;++t){const a=n[t];let r=s[t];if(this.nGramWidths.forEach((o=>{const s=n[t+1]-n[t],l=this.getNumNGrams(s,o);this.createNGrams(e,a,i,r,l,o),r+=l})),this.preserveShort&&r===s[t]){const o=n[t+1]-n[t];if(0===o)continue;const s=o+2*this.padWidth,l=1;this.createNGrams(e,a,i,r,l,s)}}return[i,s]}}function Mt(e,t,n,a){if(!e.length)return;if(0===t.length){for(let t=0;t<e.length;++t)a.push(e.subarray(t,t+1));return}if(1===t.length){const r=t[0];let o=e.indexOf(r);for(;-1!==o;){const t=e.subarray(0,o);n&&0===t.length||a.push(t),o=(e=e.subarray(o+1)).indexOf(r)}return void(n&&0===e.length||a.push(e))}let r=0;for(let o=0;o<e.length+1;o++)if(o===e.length||-1!==t.indexOf(e[o])){const t=e.subarray(r,o);n&&0===t.length||a.push(t),r=o+1}}const Gt=ut(((e,t)=>e-t));const zt=(e,t)=>{const n=t.value-e.value;return 0===n?e.index-t.index:n};function Xt(e,n,a=0,r=e.length-1){for(;r>a;){if(r-a>600){const t=r-a+1,o=n-a+1,s=Math.log(t),i=.5*Math.exp(2*s/3),l=.5*Math.sqrt(s*i*(t-i)/t)*Math.sign(o-t/2);Xt(e,n,Math.max(a,Math.floor(n-o*i/t+l)),Math.min(r,Math.floor(n+(t-o)*i/t+l)))}const o=e[n];let s=a,i=r;for(t.util.swap(e,a,n),zt(e[r],o)>0&&t.util.swap(e,a,r);s<i;){for(t.util.swap(e,s,i),s++,i--;zt(e[s],o)<0;)s+=1;for(;zt(e[i],o)>0;)i-=1}0===zt(e[a],o)?t.util.swap(e,a,i):(i+=1,t.util.swap(e,i,r)),i<=n&&(a=i+1),n<=i&&(r=i-1)}}var Ht={__proto__:null,addImpl:ct,bincountImpl:function(e,n,a,r,o){const s=t.util.sizeFromShape(r),i=t.util.makeZerosTypedArray(o,a);for(let t=0;t<e.length;t++){const a=e[t];if(a<0)throw new Error("Input x must be non-negative!");a>=o||(i[a]+=s>0?n[t]:1)}return i},bincountReduceImpl:function(e,n,a,r=!1){const o=e.shape[0],s=e.shape[1],i=t.buffer([o,a],n.dtype);for(let t=0;t<o;t++)for(let o=0;o<s;o++){const s=e.get(t,o);if(s<0)throw new Error("Input x must be non-negative!");s>=a||(r?i.set(1,t,s):n.size>0?i.set(i.get(t,s)+n.get(t,o),t,s):i.set(i.get(t,s)+1,t,s))}return i},bitwiseAndImpl:dt,castImpl:function(e,n,a,r){if("int32"===r){return[n,"int32",Int32Array.from(e)]}if("bool"===r){const r=t.util.toTypedArray([0],a),[o,s]=ut(((e,t)=>e!==t?1:0))(n,[],e,r,"bool");return[s,"bool",o]}throw new Error(`Error in Cast: failed to cast ${a} to ${r}`)},ceilImpl:ht,concatImpl:function(e,n,a,r){const o=t.util.getArrayFromDType(a,t.util.sizeFromShape(n));if(r&&"string"!==a){let n=0;e.forEach((e=>{const a=t.util.sizeFromShape(e.shape);o.set(e.vals,n),n+=a}))}else{let r=0;e.forEach((e=>{const s="string"===a?t.backend_util.fromUint8ToStringArray(e.vals):e.vals;let i=0;for(let t=0;t<e.shape[0];++t){const a=t*n[1]+r;for(let t=0;t<e.shape[1];++t)o[a+t]=s[i++]}r+=e.shape[1]}))}return o},equalImpl:ft,expImpl:xt,expm1Impl:mt,floorDivImpl:bt,floorImpl:gt,gatherNdImpl:function(e,n,a,r,o,s,i,l,u){const c=t.buffer([r,s],a);for(let t=0;t<r;t++){const a=[];let r=0;for(let n=0;n<o;n++){const s=e[t*o+n];r+=s*i[n],a.push(s)}if(r<0||r>=u/s)throw new Error(`Invalid indices: ${a} does not index into ${l}`);for(let e=0;e<s;e++)c.values[t*s+e]=n.get(...n.indexToLoc(r*s+e))}return c},gatherV2Impl:function(e,n,a){const r=t.buffer(a,e.dtype);for(let t=0;t<r.size;++t){const a=r.indexToLoc(t).slice(),o=a[0],s=a[2],i=n.locToIndex([o,s]);a[2]=n.values[i];const l=e.locToIndex(a);0<=l&&l<e.values.length&&(r.values[t]=e.values[l])}return r},greaterEqualImpl:Ct,greaterImpl:vt,lessEqualImpl:yt,lessImpl:$t,linSpaceImpl:function(e,n,a){const r=(n-e)/(a-1),o=t.util.makeZerosTypedArray(a,"float32");o[0]=e;for(let e=1;e<o.length;e++)o[e]=o[e-1]+r;return o},logImpl:It,maxImpl:function(e,n,a,r){const o=t.util.getTypedArrayFromDType(r,t.util.sizeFromShape(a));for(let t=0;t<o.length;++t){const a=t*n;let r=e[a];for(let t=0;t<n;++t){const n=e[a+t];(Number.isNaN(n)||n>r)&&(r=n)}o[t]=r}return o},maximumImpl:wt,minimumImpl:St,multiplyImpl:kt,negImpl:function(e,n,a){const r=t.util.createScalarValue(-1,a);return kt([],n,r,e,a)},notEqualImpl:Rt,prodImpl:function(e,n,a,r){const[o,s]=t.backend_util.computeOutAndReduceShapes(e,r),i=t.upcastType(n,"int32"),l=t.util.makeZerosTypedArray(t.util.sizeFromShape(o),i),u=t.util.sizeFromShape(s);for(let e=0;e<l.length;++e){const t=e*u;let n=1;for(let e=0;e<u;++e)n*=a[t+e];l[e]=n}return{outVals:l,outShape:o,outDtype:i}},raggedGatherImpl:function(e,n,a,r,o,s,i,l){if(0===e.length)throw new Error("paramsNestedSplits must be non empty");if(0===n[0].length)throw new Error("Split tensors must not be scalars");if(function(e,n,a){e.forEach(((e,r)=>{if(e<0||e>=a){const o=t.util.indexToLoc(r,n.length,t.util.computeStrides(n)).join(",");throw new Error(`indices[${o}] = ${e} is not in [0, ${a})`)}}))}(s,i,n[0][0]-1),0===r.length)throw new Error("params.rank must be nonzero");const u=r[0],{outSplits:c,valueSlices:d,numValues:p}=Tt(s,i,e,u),h=function(e){const n=[];for(let a=0;a<e.length;++a){const r=e[a].length,o=t.util.getArrayFromDType("int32",r);n.push(o),e[a].forEach(((e,t)=>o[t]=e))}return n}(c),f=Et(a,r,o,d,p);return[h,f[0],f[1]]},raggedRangeImpl:function(e,n,a,r,o,s,i){if(n.length>1)throw new Error("starts must be a scalar or vector");if(o.length>1)throw new Error("limits must be a scalar or vector");if(i.length>1)throw new Error("deltas must be a scalar or vector");const l=0===n.length,u=0===o.length,c=0===i.length,d=[];l||d.push(n[0]),u||d.push(o[0]),c||d.push(i[0]);for(let e=1;e<d.length;++e)if(d[e]!==d[e-1])throw new Error("starts, limits, and deltas must have the same shape");const p=0===d.length?1:d[0],h=t.util.getArrayFromDType("int32",p+1);h[0]=0;for(let t=0;t<p;++t){const n=l?e[0]:e[t],a=u?r[0]:r[t],o=c?s[0]:s[t];if(0===o)throw new Error("Requires delta != 0");let i;if(o>0&&a<n||o<0&&a>n)i=0;else if(i=Math.ceil(Math.abs((a-n)/o)),i>At)throw new Error("Requires ((limit - start) / delta) <= 2147483647");h[t+1]=h[t]+i}const f=h[p],x=t.util.getArrayFromDType(a,f);let m=0;for(let t=0;t<p;++t){const n=h[t+1]-h[t];let a=l?e[0]:e[t];const r=c?s[0]:s[t];for(let e=0;e<n;++e)x[m++]=a,a+=r}return[h,x]},raggedTensorToTensorImpl:function(e,t,n,a,r,o,s,i,l,u){return new Ot(e,t,n,a,r,o,s,i,l,u).compute()},rangeImpl:function(e,n,a,r){if(e===n||e<n&&a<0||n<e&&a>1)return t.util.makeZerosTypedArray(0,r);const o=Math.abs(Math.ceil((n-e)/a)),s=t.util.makeZerosTypedArray(o,r);n<e&&1===a&&(a=-1),s[0]=e;for(let e=1;e<s.length;e++)s[e]=s[e-1]+a;return s},rsqrtImpl:Pt,scatterImpl:function(e,n,a,r,o,s,i,l,u,c){const d=[r/o,o],p=e.values,h=n.values;if(0===r)return t.buffer(a,n.dtype);const f=u instanceof t.TensorBuffer?u:t.buffer(d,n.dtype);"string"==typeof u||"number"==typeof u?f.values.fill(u):"boolean"==typeof u&&f.values.fill(+u);for(let e=0;e<s;e++){const t=[];let s=0;for(let n=0;n<i;n++){const a=p[e*i+n];t.push(a),s+=a*l[n]}if(s<0||s>=r/o)throw new Error(`Invalid indices: ${t} does not index into ${a}`);for(let t=0;t<o;t++)c?f.values[s*o+t]+=h[e*o+t]:f.values[s*o+t]=0===n.rank?h[0]:h[e*o+t]}return f},sigmoidImpl:Lt,simpleAbsImpl:function(e){const t=new Float32Array(e.length);for(let n=0;n<e.length;++n)t[n]=Math.abs(e[n]);return t},sliceImpl:function(e,n,a,r,o){const s=t.slice_util.isSliceContinous(r,n,a),i=t.util.sizeFromShape(a),l=t.util.computeStrides(r);if(s){const a=t.slice_util.computeFlatOffset(n,l);return"string"===o?e.slice(a,a+i):e.subarray(a,a+i)}const u="string"===o?t.backend_util.fromUint8ToStringArray(e):e,c=t.buffer(r,o,u),d=t.buffer(a,o);for(let e=0;e<d.size;++e){const t=d.indexToLoc(e),a=t.map(((e,t)=>e+n[t]));d.set(c.get(...a),...t)}return"string"===o?t.backend_util.fromStringArrayToUint8(d.values):d.values},sparseFillEmptyRowsImpl:function(e,n,a,r,o,s,i){const l=n[0],u=s[0],c=new Array(u),d=new Array(l),p=n[1];if(0===u){if(0!==l)throw new Error(t.backend_util.getSparseFillEmptyRowsIndicesDenseShapeMismatch(l));return[t.util.getArrayFromDType(a,0),[0,p],t.util.getArrayFromDType(o,0),c,d]}let h=!0,f=0;const x=new Array(u).fill(0);for(let n=0;n<l;++n){const a=e[n*p];if(a<0)throw new Error(t.backend_util.getSparseFillEmptyRowsNegativeIndexErrorMessage(n,a));if(a>=u)throw new Error(t.backend_util.getSparseFillEmptyRowsOutOfRangeIndexErrorMessage(n,a,u));++x[a],h=h&&a>=f,f=a}let m=!0;for(let e=0;e<u;++e){const t=0===x[e];c[e]=t,m=m&&!t,x[e]=Math.max(x[e],1),e>0&&(x[e]+=x[e-1])}if(m&&h){const t=e,n=r;for(let e=0;e<l;++e)d[e]=e;return[t,[l,p],n,c,d]}{const n=x[u-1],s=t.util.getArrayFromDType(a,n*p),h=t.util.getArrayFromDType(o,n),f=new Array(u).fill(0);for(let t=0;t<l;++t){const n=e[t*p],a=f[n],o=(0===n?0:x[n-1])+a;f[n]++;for(let n=0;n<p;++n)s[o*p+n]=e[t*p+n];h[o]=r[t],d[t]=o}for(let e=0;e<u;++e){if(0===f[e]){const t=0===e?0:x[e-1];s[t*p+0]=e;for(let e=1;e<p;++e)s[t*p+e]=0;h[t]=i}}return[s,[n,p],h,c,d]}},sparseReshapeImpl:function(e,n,a,r,o){const s=t.util.sizeFromShape(r),i=n[0],l=o.length,u=[];let c=1,d=-1;for(let e=0;e<l;++e){const n=o[e];if(-1===n){if(-1!==d)throw new Error(t.backend_util.getSparseReshapeMultipleNegativeOneOutputDimErrorMessage(d,e));d=e,u.push(1)}else{if(n<0)throw new Error(t.backend_util.getSparseReshapeNegativeOutputDimErrorMessage(e,n));c*=n,u.push(n)}}if(-1!==d){if(c<=0)throw new Error(t.backend_util.getSparseReshapeEmptyTensorZeroOutputDimErrorMessage());const e=Math.trunc(s/c);if(c*e!==s)throw new Error(t.backend_util.getSparseReshapeInputOutputMultipleErrorMessage(r,u));u[d]=e}if(t.util.sizeFromShape(u)!==s)throw new Error(t.backend_util.getSparseReshapeInputOutputMismatchErrorMessage(r,u));const p=r.length,h=[];if(p>0){h[p-1]=1;for(let e=p-2;e>=0;--e)h[e]=h[e+1]*r[e+1]}const f=[];if(l>0){f[l-1]=1;for(let e=l-2;e>=0;--e)f[e]=f[e+1]*u[e+1]}const x=t.util.getArrayFromDType(a,i*l);for(let t=0;t<i;++t){let n=0;for(let a=0;a<p;++a)n+=e[t*p+a]*h[a];for(let e=0;e<l;++e)x[t*l+e]=Math.trunc(n/f[e]),n%=f[e]}return[x,[i,l],u]},sparseSegmentReductionImpl:function(e,n,a,r,o,s=!1,i=0){const l=r.length,u=[n[0],e.length/n[0]],c=u[1],d=l>0?o[l-1]+1:0;if(d<0)throw new Error(t.backend_util.getSparseSegmentReductionNegativeSegmentIdsErrorMessage());const p=n.slice();p[0]=d;const h=p.reduce(((e,t)=>e*t),1),f=t.util.getArrayFromDType(a,h);if(0===l)return d>0&&f.fill(i),[f,p];if(d<=0)throw new Error(t.backend_util.getSparseSegmentReductionNegativeSegmentIdsErrorMessage());let x=0,m=1,g=0,b=o[x];for(;;){let n=0;if(m<l){if(n=o[m],b===n){++m;continue}if(b>=n)throw new Error(t.backend_util.getSparseSegmentReductionNonIncreasingSegmentIdsErrorMessage())}if(b<0||b>=d)throw new Error(t.backend_util.getSparseSegmentReductionSegmentIdOutOfRangeErrorMessage(b,d));b>g&&f.fill(i,g*c,b*c);for(let n=x;n<m;++n){const a=r[n];if(a<0||a>=u[0])throw new Error(t.backend_util.getSparseSegmentReductionIndicesOutOfRangeErrorMessage(n,r[n],u[0]));for(let t=0;t<c;t++)f[b*c+t]+=e[a*c+t]}if(s)for(let e=0;e<c;e++)f[b*c+e]/=m-x;if(x=m,++m,g=b+1,b=n,m>l)break}return g<d&&f.fill(i,g*c,d*c),[f,p]},sqrtImpl:Bt,squaredDifferenceImpl:Vt,staticRegexReplaceImpl:Wt,stridedSliceImpl:function(e,n,a,r){const o=t.buffer(e,n.dtype);for(let e=0;e<o.size;e++){const t=o.indexToLoc(e),s=new Array(t.length);for(let e=0;e<s.length;e++)s[e]=t[e]*a[e]+r[e];o.set(n.get(...s),...t)}return o},stringNGramsImpl:function(e,t,n,a,r,o,s,i){return new Ut(n,a,r,o,s,i).compute(e,t)},stringSplitImpl:function(e,n,a){const r=e.length,o=[];let s=0,i=0;const l=new Array(r);for(let t=0;t<r;++t){const r=o.length;Mt(e[t],n,a,o);const u=o.length-r;l[t]=u,s+=u,i=Math.max(i,u)}const u=t.util.getArrayFromDType("int32",2*s),c=new Array(s),d=[r,i];let p=0;for(let e=0;e<r;++e)for(let t=0;t<l[e];++t)u[2*p]=e,u[2*p+1]=t,c[p]=o[p],++p;return[u,c,d]},stringToHashBucketFastImpl:function(e,n){const a=t.util.getArrayFromDType("int32",e.length);for(let r=0;r<e.length;++r)a[r]=t.util.fingerPrint64(e[r]).modulo(n).getLowBitsUnsigned();return a},subImpl:Gt,tileImpl:function(e,n){const a=new Array(e.rank);for(let t=0;t<a.length;t++)a[t]=e.shape[t]*n[t];const r=t.buffer(a,e.dtype);for(let t=0;t<r.values.length;++t){const n=r.indexToLoc(t),a=new Array(e.rank);for(let t=0;t<a.length;t++)a[t]=n[t]%e.shape[t];const o=e.locToIndex(a);r.values[t]=e.values[o]}return r},topKImpl:function(e,n,a,r,o){const s=n[n.length-1],[i,l]=[e.length/s,s],u=t.util.getTypedArrayFromDType(a,i*r),c=t.util.getTypedArrayFromDType("int32",i*r);for(let t=0;t<i;t++){const n=t*l,a=e.subarray(n,n+l);let s=new Array(a.length);a.forEach(((e,t)=>s[t]={value:e,index:t})),r<s.length&&(Xt(s,r),s=s.slice(0,r)),o&&s.sort(zt);const i=t*r,d=u.subarray(i,i+r),p=c.subarray(i,i+r);for(let e=0;e<r;e++)d[e]=s[e].value,p[e]=s[e].index}const d=n.slice();return d[d.length-1]=r,[t.buffer(d,a,u),t.buffer(d,"int32",c)]},transposeImpl:function(e,n,a,r,o){const s=n.length,i=t.util.sizeFromShape(n),l=t.util.computeStrides(n),u=t.util.computeStrides(o),c=t.util.getTypedArrayFromDType(a,t.util.sizeFromShape(o));for(let n=0;n<i;++n){const a=t.util.indexToLoc(n,s,l),o=new Array(a.length);for(let e=0;e<o.length;e++)o[e]=a[r[e]];c[t.util.locToIndex(o,s,u)]=e[n]}return c},uniqueImpl:function(e,n,a,r){const o=t.util.parseAxisParam(n,a)[0],s=[1,a[0],1];for(let e=0;e<o;e++)s[0]*=a[e];s[1]=a[o];for(let e=o+1;e<a.length;e++)s[2]*=a[e];const i=new Map,l=new Int32Array(a[o]),u=new t.TensorBuffer(s,r,e),c=[],d=1===s[0]&&1===s[2];for(let t=0;t<a[o];t++){let n;if(d)n=e[t].toString();else{const e=[];for(let n=0;n<s[0];n++)for(let a=0;a<s[2];a++)e.push(u.get(n,t,a));n=e.join(",")}const a=i.get(n);if(null!=a)l[t]=a;else{const e=i.size;i.set(n,e),l[t]=e,c.push(t)}}const p=s.slice();p[1]=i.size;const h=new t.TensorBuffer(p,r);c.forEach(((e,t)=>{for(let n=0;n<s[0];n++)for(let a=0;a<s[2];a++)h.set(u.get(n,e,a),n,t,a)}));const f=a.slice();return f[o]=p[1],{outputValues:h.values,outputShape:f,indices:l}}};const{addImpl:jt,bincountImpl:Kt,bincountReduceImpl:qt,bitwiseAndImpl:Yt,castImpl:Qt,ceilImpl:Zt,concatImpl:Jt,equalImpl:en,expImpl:tn,expm1Impl:nn,floorImpl:an,gatherNdImpl:rn,gatherV2Impl:on,greaterImpl:sn,greaterEqualImpl:ln,lessImpl:un,lessEqualImpl:cn,linSpaceImpl:dn,logImpl:pn,maxImpl:hn,maximumImpl:fn,minimumImpl:xn,multiplyImpl:mn,negImpl:gn,notEqualImpl:bn,prodImpl:vn,raggedGatherImpl:Cn,raggedRangeImpl:$n,raggedTensorToTensorImpl:yn,rangeImpl:In,rsqrtImpl:wn,scatterImpl:Sn,sigmoidImpl:kn,simpleAbsImpl:Rn,sliceImpl:Tn,sparseFillEmptyRowsImpl:Nn,sparseReshapeImpl:En,sparseSegmentReductionImpl:An,sqrtImpl:_n,staticRegexReplaceImpl:On,stridedSliceImpl:Fn,stringNGramsImpl:Dn,stringSplitImpl:Pn,stringToHashBucketFastImpl:Ln,subImpl:Bn,tileImpl:Vn,topKImpl:Wn,transposeImpl:Un,uniqueImpl:Mn}=Ht;function Gn(e,t){return["x","y","z","w","u","v"].slice(0,t).map((t=>`${e}.${t}`))}function zn(e,t){return 1===t?[e]:Gn(e,t)}class Xn{constructor(e){if(this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.outputShape=e,this.rank=e.length,this.enableShapeUniforms=Ae(this.outputShape.length),0===this.rank)this.userCode="\n void main() {\n setOutput(vec4(getA(), 0., 0., 0.));\n }\n ";else{const e=zn("rc",this.rank),t=Se(this.rank),n=this.getOutOfBoundsCondition(e),a=this.getSetup(e),r=this.getOutput(e);this.userCode=`\n void main() {\n ${t} rc = getOutputCoords();\n\n if(${n}) {\n setOutput(vec4(0));\n } else {\n ${a}\n\n setOutput(vec4(${r}));\n }\n }\n `}}getSourceCoordsArr(e){const t=[];for(let n=0;n<=1;n++)for(let a=0;a<=1;a++){let r=`${0===n?"r":"rp1"}, ${0===a?"c":"cp1"}`;for(let t=2;t<this.rank;t++)r=`${e[e.length-1-t]},`+r;t.push(r)}return t}getOutOfBoundsCondition(e){if(1===this.rank)return`rc > ${this.enableShapeUniforms?"outShape":this.outputShape[0]}`;let t="";for(let n=this.rank-2;n<this.rank;n++)t+=`${e[n]} >= ${this.enableShapeUniforms?`outShape[${n}]`:this.outputShape[n]}`,n<this.rank-1&&(t+="||");return t}getSetup(e){if(1===this.rank)return"";const t=e.slice(-2),n=this.enableShapeUniforms?`outShape[${this.rank} - 1]`:this.outputShape[this.rank-1],a=this.enableShapeUniforms?`outShape[${this.rank} - 2]`:this.outputShape[this.rank-2];return`\n int r = ${t[0]};\n int c = ${t[1]};\n int rp1 = r + 1;\n int cp1 = c + 1;\n\n bool cEdge = cp1 >= ${n};\n bool rEdge = rp1 >= ${a};\n `}getOutput(e){const t=this.getSourceCoordsArr(e);if(1===this.rank){return`getA(rc), (rc + 1 >= ${this.enableShapeUniforms?"outShape":this.outputShape[0]} ? 0. : getA(rc + 1)), 0, 0`}return`getA(${t[0]}),\n cEdge ? 0. : getA(${t[1]}),\n rEdge ? 0. : getA(${t[2]}),\n rEdge || cEdge ? 0. : getA(${t[3]})`}}class Hn{constructor(e,t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"inputShape",type:"ivec3"}],this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length);let n="";for(let e=0;e<4;e++){let t="thisRC = rc;";e%2==1&&(t+="thisRC.z += 1;"),e>1&&(t+="thisRC.y += 1;"),n+=`\n ${t}\n ${e>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[${e}] =\n getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims);\n ${e>0?"}":""}\n `}var a,r;this.userCode=`\n ${a=t,r=this.enableShapeUniforms,`\n ivec3 inputCoordsFromReshapedOutCoords(int index) {\n ${r?de(["r","c","d"],"inputShape"):ue(["r","c","d"],a)}\n return ivec3(r, c, d);\n }\n `}\n ${this.enableShapeUniforms?"\n int getFlatIndex(ivec3 coords) {\n return coords.x * outShapeStrides[0] + coords.y * outShapeStrides[1] + coords.z;\n }\n":pe(e)}\n\n void main() {\n ivec3 rc = getOutputCoords();\n\n vec4 result = vec4(0.);\n\n ivec3 thisRC;\n int rows = ${this.enableShapeUniforms?"outShape[1]":e[1]};\n int cols = ${this.enableShapeUniforms?"outShape[2]":e[2]};\n\n ${n}\n\n setOutput(result);\n }\n `}}class jn{constructor(e){this.gpgpu=e,this.numUsedTextures=0,this.numFreeTextures=0,this._numBytesAllocated=0,this._numBytesFree=0,this.freeTextures={},this.usedTextures={},this.logEnabled=!1}acquireTexture(e,t,n){const a=qn(t,n),r=Yn(e,a,n);r in this.freeTextures||(this.freeTextures[r]=[]),r in this.usedTextures||(this.usedTextures[r]=[]);const o=Kn(e,a,this.gpgpu.gl,this.gpgpu.textureConfig,n);if(this.freeTextures[r].length>0){this.numFreeTextures--,this.numUsedTextures++,this._numBytesFree-=o,this.log();const e=this.freeTextures[r].pop();return this.usedTextures[r].push(e),e}let s;return a===c.PACKED_2X2_FLOAT32?s=this.gpgpu.createPackedMatrixTexture(e[0],e[1]):a===c.PACKED_2X2_FLOAT16?s=this.gpgpu.createFloat16PackedMatrixTexture(e[0],e[1]):a===c.UNPACKED_FLOAT32?s=this.gpgpu.createFloat32MatrixTexture(e[0],e[1]):a===c.UNPACKED_FLOAT16?s=this.gpgpu.createFloat16MatrixTexture(e[0],e[1]):a===c.PACKED_4X1_UNSIGNED_BYTE&&(s=this.gpgpu.createUnsignedBytesMatrixTexture(e[0],e[1])),this.usedTextures[r].push(s),this.numUsedTextures++,this._numBytesAllocated+=o,this.log(),s}releaseTexture(e,n,a,r){if(null==this.freeTextures)return;const o=qn(a,r),s=Yn(n,o,r);s in this.freeTextures||(this.freeTextures[s]=[]);const i=Kn(n,o,this.gpgpu.gl,this.gpgpu.textureConfig,r),l=t.env().getNumber("WEBGL_DELETE_TEXTURE_THRESHOLD");-1!==l&&this._numBytesAllocated>l?(this.gpgpu.deleteMatrixTexture(e.texture),this._numBytesAllocated-=i):(this.freeTextures[s].push(e),this.numFreeTextures++,this._numBytesFree+=i),this.numUsedTextures--;const u=this.usedTextures[s],c=u&&u.indexOf(e);if(null==c||c<0)throw new Error("Cannot release a texture that was never provided by this texture manager");u[c]=u[u.length-1],u.pop(),this.log()}log(){if(!this.logEnabled)return;const e=this.numFreeTextures+this.numUsedTextures;console.log("Free/Used",`${this.numFreeTextures} / ${this.numUsedTextures}`,`(${e})`);const t=this._numBytesFree/this._numBytesAllocated;console.log(`Bytes allocated: ${this._numBytesAllocated}`),console.log(`Bytes unused: ${this._numBytesFree} (${Math.round(100*t)}%)`)}get numBytesAllocated(){return this._numBytesAllocated}get numBytesFree(){return this._numBytesFree}getNumUsedTextures(){return this.numUsedTextures}getNumFreeTextures(){return this.numFreeTextures}dispose(){if(null!=this.freeTextures){for(const e in this.freeTextures)this.freeTextures[e].forEach((e=>{this.gpgpu.deleteMatrixTexture(e.texture)}));for(const e in this.usedTextures)this.usedTextures[e].forEach((e=>{this.gpgpu.deleteMatrixTexture(e.texture)}));this.freeTextures=null,this.usedTextures=null,this.numUsedTextures=0,this.numFreeTextures=0,this._numBytesAllocated=0,this._numBytesFree=0}}}function Kn(e,t,n,a,r){const o=function(e,t){switch(e){case c.PACKED_2X2_FLOAT32:return qe(t);case c.PACKED_2X2_FLOAT16:return Qe(t);case c.UNPACKED_FLOAT32:return Ge(t);case c.UNPACKED_FLOAT16:return Xe(t);case c.PACKED_4X1_UNSIGNED_BYTE:return je(t);default:throw new Error(`Unknown physical texture type ${e}`)}}(t,a);let s;if(r){const[t,n]=h(e[0],e[1]);s=t*n}else{const[t,n]=d(e[0],e[1]);s=t*n}const i=function(e,t){const n=e;if(t===n.R32F)return 4;if(t===n.R16F)return 2;if(t===n.RGBA32F)return 16;if(t===e.RGBA)return 16;if(t===n.RGBA16F)return 8;if(t===n.RGBA8)return 4;throw new Error(`Unknown internal format ${t}`)}(n,o);return s*i}function qn(e,n){if(e===u.UPLOAD)return c.PACKED_2X2_FLOAT32;if(e===u.RENDER||null==e)return function(e){return t.env().getBool("WEBGL_RENDER_FLOAT32_ENABLED")?e?c.PACKED_2X2_FLOAT32:c.UNPACKED_FLOAT32:e?c.PACKED_2X2_FLOAT16:c.UNPACKED_FLOAT16}(n);if(e===u.DOWNLOAD||e===u.PIXELS)return c.PACKED_4X1_UNSIGNED_BYTE;throw new Error(`Unknown logical texture type ${e}`)}function Yn(e,t,n){return`${e[0]}_${e[1]}_${t}_${n}`}class Qn{constructor(e,t){this.variableNames=["A"],this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length),this.userCode=`\n float unaryOperation(float x) {\n ${t}\n }\n\n void main() {\n float x = getAAtOutCoords();\n float y = unaryOperation(x);\n\n setOutput(y);\n }\n `}}const Zn="return abs(x);",Jn="return x;";class ea{constructor(e,t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length),this.userCode=`\n vec4 unaryOperation(vec4 x) {\n ${t}\n }\n\n void main() {\n vec4 x = getAAtOutCoords();\n vec4 y = unaryOperation(x);\n\n setOutput(y);\n }\n `}}class ta{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!1,this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length);const t=e.length,n=zn("rc",t),a=Se(t),r=function(e,t){if(1===e)return"rc";let n="";for(let a=0;a<e;a++)n+=t[a],a<e-1&&(n+=",");return n}(t,n),o=n.slice(-2),s=t<=1?"rc":`vec2(${o.join(",")})`;this.userCode=`\n void main() {\n ${a} rc = getOutputCoords();\n vec4 packedInput = getA(${r});\n\n setOutput(getChannel(packedInput, ${s}));\n }\n `}}const na=t.kernel_impls.whereImpl,aa={};const ra=t.env().getNumber("CPU_HANDOFF_SIZE_THRESHOLD");class oa extends t.KernelBackend{nextDataId(){return oa.nextDataId++}constructor(e){if(super(),this.pendingRead=new WeakMap,this.pendingDisposal=new WeakSet,this.dataRefCount=new WeakMap,this.numBytesInGPU=0,this.uploadWaitMs=0,this.downloadWaitMs=0,this.lastGlFlushTime=0,this.warnedAboutMemory=!1,this.pendingDeletes=0,this.disposed=!1,!t.env().getBool("HAS_WEBGL"))throw new Error("WebGL is not supported on this device");let n;if(null!=e){if(e instanceof lt)n=e;else{const a=i(t.env().getNumber("WEBGL_VERSION"),e);n=new lt(a)}this.binaryCache={},this.gpgpuCreatedLocally=!1}else{const e=i(t.env().getNumber("WEBGL_VERSION"));n=new lt(e),this.binaryCache=((a=t.env().getNumber("WEBGL_VERSION"))in aa||(aa[a]={}),aa[a]),this.gpgpuCreatedLocally=!0}var a;this.gpgpu=n,this.canvas=this.gpgpu.gl.canvas,this.textureManager=new jn(this.gpgpu),this.numMBBeforeWarning=null==t.env().global.screen?1024:t.env().global.screen.height*t.env().global.screen.width*window.devicePixelRatio*600/1024/1024,this.texData=new t.DataStorage(this,t.engine())}numDataIds(){return this.texData.numDataIds()-this.pendingDeletes}writeTexture(e,t,n,a,r,o){const s=this.makeTensorInfo(t,n),i=this.texData.get(s.dataId);i.isPacked=!1,i.texture={texture:e,texShape:[a,r]},i.texShape=[a,r];const l=z(t),u=new Le(l,!1,o),c=this.runWebGLProgram(u,[s],n,[[a,r]]);return c.shape=t,i.texture=null,this.disposeIntermediateTensorInfo(s),c.dataId}write(e,n,a){if((t.env().getBool("WEBGL_CHECK_NUMERICAL_PROBLEMS")||t.env().getBool("DEBUG"))&&this.checkNumericalProblems(e),"complex64"===a&&null!=e)throw new Error("Cannot write to a complex64 dtype. Please use tf.complex(real, imag).");const r={id:this.nextDataId()};return this.texData.set(r,{shape:n,dtype:a,values:e,usage:u.UPLOAD,refCount:1}),r}refCount(e){if(this.texData.has(e)){return this.texData.get(e).refCount}return 0}incRef(e){this.texData.get(e).refCount++}decRef(e){if(this.texData.has(e)){this.texData.get(e).refCount--}}move(e,n,a,r,o){if(t.env().getBool("DEBUG")&&this.checkNumericalProblems(n),"complex64"===r)throw new Error("Cannot write to a complex64 dtype. Please use tf.complex(real, imag).");this.texData.set(e,{shape:a,dtype:r,values:n,usage:u.UPLOAD,refCount:o})}disposeIntermediateTensorInfo(e){this.disposeData(e.dataId)}readSync(e){const n=this.texData.get(e),{values:a,dtype:r,complexTensorInfos:o,slice:s,shape:i,isPacked:l}=n;if(null!=s){let t;t=l?new ea(i,Jn):new Qn(i,Jn);const n=this.runWebGLProgram(t,[{dataId:e,shape:i,dtype:r}],r),a=this.readSync(n.dataId);return this.disposeIntermediateTensorInfo(n),a}if(null!=a)return this.convertAndCacheOnCPU(e);if("string"===r)return a;const u=null!=this.activeTimers;let c,d;if(u&&(c=t.util.now()),"complex64"===r){const e=this.readSync(o.real.dataId),n=this.readSync(o.imag.dataId);d=t.backend_util.mergeRealAndImagArrays(e,n)}else d=this.getValuesFromTexture(e);return u&&(this.downloadWaitMs+=t.util.now()-c),this.convertAndCacheOnCPU(e,d)}async read(e){if(this.pendingRead.has(e)){const t=this.pendingRead.get(e);return new Promise((e=>t.push(e)))}const n=this.texData.get(e),{values:a,shape:r,slice:o,dtype:s,complexTensorInfos:i,isPacked:l}=n;if(null!=o){let t;t=l?new ea(r,Jn):new Qn(r,Jn);const n=this.runWebGLProgram(t,[{dataId:e,shape:r,dtype:s}],s),a=this.read(n.dataId);return this.disposeIntermediateTensorInfo(n),a}if(null!=a)return this.convertAndCacheOnCPU(e);if(t.env().getBool("DEBUG")&&!t.env().getBool("WEBGL_DOWNLOAD_FLOAT_ENABLED")&&2===t.env().getNumber("WEBGL_VERSION"))throw new Error("tensor.data() with WEBGL_DOWNLOAD_FLOAT_ENABLED=false and WEBGL_VERSION=2 not yet supported.");let u,c,d=null;if("complex64"!==s&&t.env().get("WEBGL_BUFFER_SUPPORTED")){u=this.decode(e);const t=this.texData.get(u.dataId);d=this.gpgpu.createBufferFromTexture(t.texture.texture,...p(r))}if(this.pendingRead.set(e,[]),"complex64"!==s&&await this.gpgpu.createAndWaitForFence(),"complex64"===s){const e=await Promise.all([this.read(i.real.dataId),this.read(i.imag.dataId)]),n=e[0],a=e[1];c=t.backend_util.mergeRealAndImagArrays(n,a)}else if(null==d)c=this.getValuesFromTexture(e);else{const e=t.util.sizeFromShape(r);c=this.gpgpu.downloadFloat32MatrixFromBuffer(d,e)}if(null!=u&&this.disposeIntermediateTensorInfo(u),null!=d){const e=this.gpgpu.gl;x(e,(()=>e.deleteBuffer(d)))}const h=this.convertAndCacheOnCPU(e,c),f=this.pendingRead.get(e);return this.pendingRead.delete(e),f.forEach((e=>e(h))),this.pendingDisposal.has(e)&&(this.pendingDisposal.delete(e),this.disposeData(e)&&t.engine().removeDataId(e,this),this.pendingDeletes--),h}readToGPU(e,n={}){const a=this.texData.get(e),{values:r,shape:o,slice:s,dtype:i,isPacked:l,texture:u}=a;if("complex64"===i)throw new Error("Does not support reading texture for complex64 dtype.");if(null!=s){let t;t=l?new ea(o,Jn):new Qn(o,Jn);const a=this.runWebGLProgram(t,[{dataId:e,shape:o,dtype:i}],i),r=this.readToGPU(a,n);return this.disposeIntermediateTensorInfo(a),r}if(null==u)throw null!=r?new Error("Data is not on GPU but on CPU."):new Error("There is no data on GPU or CPU.");const c=this.decode(e,n.customTexShape),d=t.engine().makeTensorFromTensorInfo(c),p=this.texData.get(c.dataId);return Object.assign({tensorRef:d},p.texture)}bufferSync(e){const n=this.readSync(e.dataId);if("string"===e.dtype)try{const a=n.map((e=>t.util.decodeString(e)));return t.buffer(e.shape,e.dtype,a)}catch(e){throw new Error("Failed to decode encoded string bytes into utf-8")}return t.buffer(e.shape,e.dtype,n)}checkNumericalProblems(e){if(null!=e)for(let n=0;n<e.length;n++){const a=e[n];if(!m(a)){if(t.env().getBool("WEBGL_RENDER_FLOAT32_CAPABLE"))throw Error(`The value ${a} cannot be represented with your current settings. Consider enabling float32 rendering: 'tf.env().set('WEBGL_RENDER_FLOAT32_ENABLED', true);'`);throw Error(`The value ${a} cannot be represented on this device.`)}}}getValuesFromTexture(e){const{shape:n,dtype:a,isPacked:r}=this.texData.get(e),o=t.util.sizeFromShape(n);if(t.env().getBool("WEBGL_DOWNLOAD_FLOAT_ENABLED")){const t=this.decode(e),a=this.texData.get(t.dataId),r=this.gpgpu.downloadMatrixFromPackedTexture(a.texture.texture,...p(n)).subarray(0,o);return this.disposeIntermediateTensorInfo(t),r}const s=t.env().getBool("WEBGL_PACK")&&!0===r,i=s?z(n):n,l=s?new De(i):new Fe(i),u=this.runWebGLProgram(l,[{shape:i,dtype:a,dataId:e}],"float32"),c=this.texData.get(u.dataId),d=this.gpgpu.downloadByteEncodedFloatMatrixFromOutputTexture(c.texture.texture,c.texShape[0],c.texShape[1]).subarray(0,o);return this.disposeIntermediateTensorInfo(u),d}timerAvailable(){return t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0}time(e){const n=this.activeTimers,a=[];let r=!1;null==this.programTimersStack?(this.programTimersStack=a,r=!0):this.activeTimers.push(a),this.activeTimers=a,e();const o=t.util.flatten(this.activeTimers.map((e=>e.query))).filter((e=>null!=e)),s=t.util.flatten(this.activeTimers.map((e=>e.name))).filter((e=>null!=e));this.activeTimers=n,r&&(this.programTimersStack=null);const i={uploadWaitMs:this.uploadWaitMs,downloadWaitMs:this.downloadWaitMs,kernelMs:null,wallMs:null};return(async()=>{if(t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0){const e=await Promise.all(o);i.kernelMs=t.util.sum(e),i.getExtraProfileInfo=()=>e.map(((e,t)=>({name:s[t],ms:e}))).map((e=>`${e.name}: ${e.ms}`)).join(", ")}else i.kernelMs={error:"WebGL query timers are not supported in this environment."};return this.uploadWaitMs=0,this.downloadWaitMs=0,i})()}memory(){return{unreliable:!1,numBytesInGPU:this.numBytesInGPU,numBytesInGPUAllocated:this.textureManager.numBytesAllocated,numBytesInGPUFree:this.textureManager.numBytesFree}}startTimer(){return t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0?this.gpgpu.beginQuery():{startMs:t.util.now(),endMs:null}}endTimer(e){return t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0?(this.gpgpu.endQuery(),e):(e.endMs=t.util.now(),e)}async getQueryTime(e){if(t.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0)return this.gpgpu.waitForQueryAndGetTime(e);const n=e;return n.endMs-n.startMs}disposeData(e,t=!1){if(this.pendingDisposal.has(e))return!1;if(!this.texData.has(e))return!0;if(t?this.texData.get(e).refCount=0:this.texData.get(e).refCount--,!t&&this.texData.get(e).refCount>0)return!1;if(this.pendingRead.has(e))return this.pendingDisposal.add(e),this.pendingDeletes++,!1;this.releaseGPUData(e);const{complexTensorInfos:n}=this.texData.get(e);return null!=n&&(this.disposeData(n.real.dataId,t),this.disposeData(n.imag.dataId,t)),this.texData.delete(e),!0}releaseGPUData(e){const{texture:t,dtype:n,texShape:a,usage:r,isPacked:o,slice:s}=this.texData.get(e),i=s&&s.origDataId||e,l=this.dataRefCount.get(i);l>1?this.dataRefCount.set(i,l-1):(this.dataRefCount.delete(i),null!=t&&(this.numBytesInGPU-=this.computeBytes(a,n),this.textureManager.releaseTexture(t,a,r,o)));const u=this.texData.get(e);u.texture=null,u.texShape=null,u.isPacked=!1,u.slice=null}getTexture(e){return this.uploadToGPU(e),this.texData.get(e).texture.texture}getDataInfo(e){return this.texData.get(e)}shouldExecuteOnCPU(e,n=ra){return t.env().getBool("WEBGL_CPU_FORWARD")&&e.every((e=>null==this.texData.get(e.dataId).texture&&t.util.sizeFromShape(e.shape)<n))}getGPGPUContext(){return this.gpgpu}where(e){t.backend_util.warn("tf.where() in webgl locks the UI thread. Call tf.whereAsync() instead");const n=e.dataSync();return na(e.shape,n)}packedUnaryOp(e,n,a){const r=new ea(e.shape,n),o=this.compileAndRun(r,[e],a);return t.engine().makeTensorFromTensorInfo(o)}abs(e){if(this.shouldExecuteOnCPU([e])&&"complex64"!==e.dtype){const t=Rn(this.texData.get(e.dataId).values);return this.makeOutput(e.shape,e.dtype,t)}if(t.env().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(e,Zn,e.dtype);const n=new Qn(e.shape,Zn),a=this.compileAndRun(n,[e]);return t.engine().makeTensorFromTensorInfo(a)}makeTensorInfo(e,n,a){let r;if("string"===n&&null!=a&&a.length>0&&t.util.isString(a[0])){const o=a.map((e=>t.util.encodeString(e)));r=this.write(o,e,n)}else r=this.write(a,e,n);return this.texData.get(r).usage=null,{dataId:r,shape:e,dtype:n}}makeOutput(e,n,a){return t.engine().makeTensorFromTensorInfo(this.makeTensorInfo(e,n,a),this)}unpackTensor(e){const t=new ta(e.shape);return this.runWebGLProgram(t,[e],e.dtype)}packTensor(e){const t=new Xn(e.shape);return this.runWebGLProgram(t,[e],e.dtype,null,!0)}packedReshape(e,t){const n=[M(e.shape),...G(e.shape)],a={dtype:e.dtype,shape:n,dataId:e.dataId},r=[M(t),...G(t)],o=new Hn(r,n),s=[n],i=this.runWebGLProgram(o,[a],e.dtype,s,!0);return{dataId:i.dataId,shape:t,dtype:i.dtype}}decode(e,n){const a=this.texData.get(e),{isPacked:r,shape:o,dtype:s}=a;if(null!=n){const e=t.util.sizeFromShape(o),a=n[0]*n[1]*4;t.util.assert(e<=a,(()=>"customTexShape is too small. Row * Column * 4 should be equal or larger than the size of the tensor data."))}const i=z(o);let l;l=r?new Oe(i):new _e(i);const u=[null!=n?n:p(i)];return{dtype:s,shape:o,dataId:this.runWebGLProgram(l,[{shape:i,dtype:s,dataId:e}],s,u,!0,n).dataId}}runWebGLProgram(e,n,a,r,o=!1,s){const i=this.makeTensorInfo(e.outputShape,a),u=this.texData.get(i.dataId);if(e.packedOutput&&(u.isPacked=!0),e.outPackingScheme===l.DENSE){const t=null!=s?s:p(e.outputShape);u.texShape=t.map((e=>2*e))}if(null!=e.outTexUsage&&(u.usage=e.outTexUsage),0===t.util.sizeFromShape(i.shape))return u.values=t.util.getTypedArrayFromDType(i.dtype,0),i;const c=[],d=n.map((n=>{if("complex64"===n.dtype)throw new Error("GPGPUProgram does not support complex64 input. For complex64 dtypes, please separate the program into real and imaginary parts.");let a=this.texData.get(n.dataId);if(null==a.texture){if(!e.packedInputs&&t.util.sizeFromShape(n.shape)<=t.env().getNumber("WEBGL_SIZE_UPLOAD_UNIFORM"))return{shape:n.shape,texData:null,isUniform:!0,uniformValues:a.values};e.packedInputs&&(a.isPacked=!0,a.shape=n.shape)}if(this.uploadToGPU(n.dataId),!!a.isPacked!=!!e.packedInputs)n=a.isPacked?this.unpackTensor(n):this.packTensor(n),c.push(n),a=this.texData.get(n.dataId);else if(a.isPacked&&!j(a.shape,n.shape)){const e=n,t=n.shape;n.shape=a.shape,n=this.packedReshape(n,t),c.push(n),a=this.texData.get(n.dataId),e.shape=t}return{shape:n.shape,texData:a,isUniform:!1}}));this.uploadToGPU(i.dataId);const h={shape:i.shape,texData:u,isUniform:!1},f=function(e,n,a){let r="";n.concat(a).forEach((n=>{const o=null!=n.texData&&null!=n.texData.slice&&n.texData.slice.flatOffset>0;if(e.enableShapeUniforms&&!n.isUniform){const s=n.texData.texShape,{useSqueezeShape:i,uniformShape:l,keptDims:u}=ke(e.packedInputs,n.shape,s);let c="",d="",p="";if(1===l.length&&e.packedInputs){const e=[Math.ceil(s[0]/2),Math.ceil(s[1]/2)];c=`${e[0]>1}_${e[1]>1}`}else if(2!==l.length||e.packedInputs){if(l.length>2&&!e.packedInputs){const e=t.util.computeStrides(l);p=`${e[0]===s[1]}_${e[e.length-1]===s[1]}`}}else d=`${l[0]>1}_${l[1]>1}`;const h=n.shape.length,f=2===l.length&&t.util.arraysEqual(n.shape,s),x=1===t.util.sizeFromShape(n.shape),m=t.backend_util.getBroadcastDims(n.shape,a.shape),g=!e.packedInputs&&h===a.shape.length&&t.util.arraysEqual(s,a.texData.texShape),b=e.packedInputs||l.length>2?"":`${s[0]>1}_${s[1]>1}`;r+=`${h}_${g}_${i?u:""}_${l.length}_${x}_${m}_${f}_${c}_${d}_${p}_${b}_${o}`}else{const e=n.isUniform?"uniform":n.texData.texShape;r+=`${n.shape}_${e}_${o}`}}));const o=e.userCode;let s=e.constructor.name;return s+="_"+r+"_"+o+`${t.env().getNumber("WEBGL_VERSION")}`,s}(e,d,h),x=this.getAndSaveBinary(f,(()=>function(e,n,a,r){const o=a.map(((e,t)=>{const a={logicalShape:e.shape,texShape:e.isUniform?null:e.texData.texShape,isUniform:e.isUniform,isPacked:!e.isUniform&&e.texData.isPacked,flatOffset:null};return null!=e.texData&&null!=e.texData.slice&&e.texData.slice.flatOffset>0&&(a.flatOffset=e.texData.slice.flatOffset),{name:n.variableNames[t],shapeInfo:a}})),s=o.map((e=>e.shapeInfo)),i={logicalShape:r.shape,texShape:r.texData.texShape,isUniform:!1,isPacked:r.texData.isPacked,flatOffset:null},l=xe(o,i,n),u=C(e.gl,l),c=e.createProgram(u);return t.env().get("ENGINE_COMPILE_ONLY")?{program:n,fragmentShader:u,source:l,webGLProgram:c,inShapeInfos:s,outShapeInfo:i,variablesLocations:null,customUniformLocations:null,infLoc:null,nanLoc:null,outShapeLocation:null,outShapeStridesLocation:null,outTexShapeLocation:null}:(e.buildVao(c),Object.assign({program:n,fragmentShader:u,source:l,webGLProgram:c,inShapeInfos:s,outShapeInfo:i},Ne(e,n,c)))}(this.gpgpu,e,d,h))),m=null!=this.activeTimers;let g;m&&(g=this.startTimer()),t.env().get("ENGINE_COMPILE_ONLY")||function(e,n,a,r,o){n.program.enableShapeUniforms||(Ee(n.inShapeInfos,a),Ee([n.outShapeInfo],[r]));const s=r.texData.texture,i=r.texData.texShape;r.texData.isPacked?e.setOutputPackedMatrixTexture(s.texture,i[0],i[1]):e.setOutputMatrixTexture(s.texture,i[0],i[1]),e.setProgram(n.webGLProgram),e.bindVertexArray(n.webGLProgram.vao),1===t.env().getNumber("WEBGL_VERSION")&&null!==n.infLoc&&e.gl.uniform1f(n.infLoc,1/0),null!==n.nanLoc&&e.gl.uniform1f(n.nanLoc,NaN);for(let r=0;r<a.length;++r){const o=a[r],{uniform:s,offset:i,shape:l,texShape:u}=n.variablesLocations[r];if(l){const{uniformShape:t}=ke(n.program.packedInputs,o.shape,o.texData.texShape);switch(t.length){case 1:e.gl.uniform1iv(l,new Int32Array(t));break;case 2:e.gl.uniform2iv(l,new Int32Array(t));break;case 3:e.gl.uniform3iv(l,new Int32Array(t));break;case 4:e.gl.uniform4iv(l,new Int32Array(t))}}if(u&&e.gl.uniform2i(u,o.texData.texShape[0],o.texData.texShape[1]),null!=s)if(o.isUniform)if(t.util.sizeFromShape(o.shape)<2)e.gl.uniform1f(s,o.uniformValues[0]);else{let t=o.uniformValues;t instanceof Float32Array||(t=new Float32Array(t)),e.gl.uniform1fv(s,t)}else null!=o.texData.slice&&null!=i&&e.gl.uniform1i(i,o.texData.slice.flatOffset),e.setInputMatrixTexture(o.texData.texture.texture,s,r)}const l=n.outShapeLocation;if(l)switch(r.shape.length){case 1:e.gl.uniform1iv(l,new Int32Array(r.shape));break;case 2:e.gl.uniform2iv(l,new Int32Array(r.shape));break;case 3:e.gl.uniform3iv(l,new Int32Array(r.shape));break;case 4:e.gl.uniform4iv(l,new Int32Array(r.shape))}if(n.outShapeStridesLocation){const a=t.util.computeStrides(r.shape);switch(r.shape.length){case 2:e.gl.uniform1iv(n.outShapeStridesLocation,new Int32Array(a));break;case 3:e.gl.uniform2iv(n.outShapeStridesLocation,new Int32Array(a));break;case 4:e.gl.uniform3iv(n.outShapeStridesLocation,new Int32Array(a))}}if(n.outTexShapeLocation&&e.gl.uniform2i(n.outTexShapeLocation,r.texData.texShape[0],r.texData.texShape[1]),n.program.customUniforms&&o)for(let t=0;t<n.program.customUniforms.length;++t){const a=n.program.customUniforms[t],r=n.customUniformLocations[t],s=o[t];if("float"===a.type)e.gl.uniform1fv(r,s);else if("vec2"===a.type)e.gl.uniform2fv(r,s);else if("vec3"===a.type)e.gl.uniform3fv(r,s);else if("vec4"===a.type)e.gl.uniform4fv(r,s);else if("int"===a.type)e.gl.uniform1iv(r,s);else if("ivec2"===a.type)e.gl.uniform2iv(r,s);else if("ivec3"===a.type)e.gl.uniform3iv(r,s);else{if("ivec4"!==a.type)throw Error(`uniform type ${a.type} is not supported yet.`);e.gl.uniform4iv(r,s)}}e.executeProgram()}(this.gpgpu,x,d,h,r),c.forEach((e=>this.disposeIntermediateTensorInfo(e))),m&&(g=this.endTimer(g),this.activeTimers.push({name:e.constructor.name,query:this.getQueryTime(g)}));const b=t.env().getNumber("WEBGL_FLUSH_THRESHOLD");if(b>0){const e=t.util.now();e-this.lastGlFlushTime>b&&(this.gpgpu.gl.flush(),this.lastGlFlushTime=e)}if(!t.env().getBool("WEBGL_LAZILY_UNPACK")&&u.isPacked&&!1===o){const e=this.unpackTensor(i);return this.disposeIntermediateTensorInfo(i),e}return i}compileAndRun(e,t,n,a,r=!1){n=n||t[0].dtype;return this.runWebGLProgram(e,t,n,a,r)}getAndSaveBinary(e,t){return e in this.binaryCache||(this.binaryCache[e]=t()),this.binaryCache[e]}getTextureManager(){return this.textureManager}dispose(){if(!this.disposed){if(!t.env().getBool("IS_TEST")){Object.keys(this.binaryCache).forEach((e=>{this.gpgpu.deleteProgram(this.binaryCache[e].webGLProgram),delete this.binaryCache[e]}))}this.textureManager.dispose(),null!=this.canvas&&"undefined"!=typeof HTMLCanvasElement&&this.canvas instanceof HTMLCanvasElement?this.canvas.remove():this.canvas=null,this.gpgpuCreatedLocally&&(this.gpgpu.program=null,this.gpgpu.dispose()),this.disposed=!0}}floatPrecision(){return null==this.floatPrecisionValue&&(this.floatPrecisionValue=t.tidy((()=>{if(!t.env().get("WEBGL_RENDER_FLOAT32_ENABLED")){const e=t.env().getBool("DEBUG");t.env().set("DEBUG",!1);const n=this.abs(t.scalar(1e-8)).dataSync()[0];if(t.env().set("DEBUG",e),n>0)return 32}return 16}))),this.floatPrecisionValue}epsilon(){return 32===this.floatPrecision()?1e-7:1e-4}uploadToGPU(e){const n=this.texData.get(e),{shape:a,dtype:r,values:o,texture:s,usage:i,isPacked:l}=n;if(null!=s)return;const c=null!=this.activeTimers;let d;c&&(d=t.util.now());let p=n.texShape;if(null==p&&(p=X(a,l),n.texShape=p),null!=o){const e=z(a);let s,i=p[1],f=p[0];const x=o instanceof Uint8Array||o instanceof Uint8ClampedArray;!l&&x||([i,f]=h(p[0],p[1])),s=l?new Be(e,x):new Le(e,x);const m=x?[f,i]:p,g=this.makeTensorInfo(m,r),b=this.texData.get(g.dataId);b.usage=x?u.PIXELS:u.UPLOAD,b.texShape=m,this.gpgpu.uploadDenseMatrixToTexture(this.getTexture(g.dataId),i,f,o);const v=[[f,i]],C=!0,$=this.runWebGLProgram(s,[g],r,v,C),y=this.texData.get($.dataId);n.texShape=y.texShape,n.isPacked=y.isPacked,n.usage=y.usage,t.env().get("ENGINE_COMPILE_ONLY")?this.disposeData($.dataId):(n.texture=y.texture,n.values=null,this.texData.delete($.dataId)),this.disposeIntermediateTensorInfo(g),c&&(this.uploadWaitMs+=t.util.now()-d)}else{const e=this.acquireTexture(p,i,r,l);n.texture=e}}convertAndCacheOnCPU(e,t){const n=this.texData.get(e),{dtype:a}=n;return null!=t&&(n.values=function(e,t){if("float32"===t||"complex64"===t)return e;if("int32"===t||"bool"===t){const n="int32"===t?new Int32Array(e.length):new Uint8Array(e.length);for(let t=0;t<n.length;++t)n[t]=Math.round(e[t]);return n}throw new Error(`Unknown dtype ${t}`)}(t,a)),n.values}acquireTexture(e,t,n,a){if(this.numBytesInGPU+=this.computeBytes(e,n),!this.warnedAboutMemory&&this.numBytesInGPU>1024*this.numMBBeforeWarning*1024){const e=(this.numBytesInGPU/1024/1024).toFixed(2);this.warnedAboutMemory=!0,console.warn(`High memory usage in GPU: ${e} MB, most likely due to a memory leak`)}return this.textureManager.acquireTexture(e,t,a)}computeBytes(e,n){return e[0]*e[1]*t.util.bytesPerElement(n)}checkCompileCompletion(){for(const[,e]of Object.entries(this.binaryCache))this.checkCompletion_(e)}async checkCompileCompletionAsync(){const e=[];if(this.gpgpu.parallelCompilationExtension){for(const[,t]of Object.entries(this.binaryCache))e.push(this.checkCompletionAsync_(t));return Promise.all(e)}for(const[,t]of Object.entries(this.binaryCache)){const n=new Promise((e=>{try{this.checkCompletion_(t),e(!0)}catch(e){throw e}}));e.push(n)}return Promise.all(e)}async checkCompletionAsync_(e){return this.gpgpu.gl.getProgramParameter(e.webGLProgram,this.gpgpu.parallelCompilationExtension.COMPLETION_STATUS_KHR)?this.checkCompletion_(e):(await t.nextFrame(),this.checkCompletionAsync_(e))}checkCompletion_(e){if(!1===this.gpgpu.gl.getProgramParameter(e.webGLProgram,this.gpgpu.gl.LINK_STATUS)){if(console.log(this.gpgpu.gl.getProgramInfoLog(e.webGLProgram)),!1===this.gpgpu.gl.getShaderParameter(e.fragmentShader,this.gpgpu.gl.COMPILE_STATUS))throw y(e.source,this.gpgpu.gl.getShaderInfoLog(e.fragmentShader)),new Error("Failed to compile fragment shader.");throw new Error("Failed to link vertex and fragment shaders.")}return!0}getUniformLocations(){for(const e of Object.values(this.binaryCache)){this.gpgpu.buildVao(e.webGLProgram);const{variablesLocations:t,customUniformLocations:n,infLoc:a,nanLoc:r,outShapeLocation:o,outShapeStridesLocation:s,outTexShapeLocation:i}=Ne(this.gpgpu,e.program,e.webGLProgram);e.variablesLocations=t,e.customUniformLocations=n,e.infLoc=a,e.nanLoc=r,e.outShapeLocation=o,e.outShapeStridesLocation=s,e.outTexShapeLocation=i}}createTensorFromGPUData(e,n,a){e.channels=e.channels||"RGBA";const{texture:r,height:o,width:s,channels:i}=e,l=t.engine().backend;if(!l.gpgpu.gl.isTexture(r))throw new Error("The texture is invalid. Also, please make sure the texture and the TFJS WebGL backend are using the same canvas. If you want to use your own custom canvas, you have to create and use the custom TFJS WebGL backend created from the canvas through 'new tf.MathBackendWebGL(customCanvas)'.");const u=l.writeTexture(r,n,a,o,s,i);return t.engine().makeTensorFromDataId(u,n,a,l)}}oa.nextDataId=0;function sa(){t.env().set("WEBGL_FORCE_F16_TEXTURES",!0)}t.device_util.isBrowser()&&t.registerBackend("webgl",(()=>new oa),2);const ia={forceHalfFloat:sa};class la{constructor(e,n,a){this.variableNames=["A","B"],this.outputShape=t.backend_util.assertAndGetBroadcastShape(n,a),this.enableShapeUniforms=Ae(this.outputShape.length),this.userCode=`\n float binaryOperation(float a, float b) {\n ${e}\n }\n\n void main() {\n float a = getAAtOutCoords();\n float b = getBAtOutCoords();\n setOutput(binaryOperation(a, b));\n }\n `}}const ua="\n result.r = isNaN.r ? NAN : result.r;\n result.g = isNaN.g ? NAN : result.g;\n result.b = isNaN.b ? NAN : result.b;\n result.a = isNaN.a ? NAN : result.a;\n";class ca{constructor(e,n,a,r=!1){this.variableNames=["A","B"],this.supportsBroadcasting=!0,this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t.backend_util.assertAndGetBroadcastShape(n,a);const o=this.outputShape.length;this.enableShapeUniforms=Ae(o);let s="";if(r)if(0===o||1===t.util.sizeFromShape(this.outputShape))s="\n result.y = 0.;\n result.z = 0.;\n result.w = 0.;\n ";else{if(s=`\n ${Se(o)} coords = getOutputCoords();\n `,1===o)this.enableShapeUniforms?s+="\n result.y = (coords + 1) >= outShape ? 0. : result.y;\n result.z = 0.;\n result.w = 0.;\n ":s+=`\n result.y = (coords + 1) >= ${this.outputShape[0]} ? 0. : result.y;\n result.z = 0.;\n result.w = 0.;\n `;else{const e=zn("coords",o);this.enableShapeUniforms?s+=`\n bool nextRowOutOfBounds =\n (${e[o-2]} + 1) >= outShape[${o} - 2];\n bool nextColOutOfBounds =\n (${e[o-1]} + 1) >= outShape[${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 `:s+=`\n bool nextRowOutOfBounds =\n (${e[o-2]} + 1) >= ${this.outputShape[o-2]};\n bool nextColOutOfBounds =\n (${e[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 ${e}\n }\n\n void main() {\n vec4 a = getAAtOutCoords();\n vec4 b = getBAtOutCoords();\n\n vec4 result = binaryOperation(a, b);\n ${s}\n\n setOutput(result);\n }\n `}}function da(e){const{inputs:t,backend:n}=e,{x:a}=t;return n.incRef(a.dataId),{dataId:a.dataId,shape:a.shape,dtype:a.dtype}}const pa={kernelName:t.Identity,backendName:"webgl",kernelFunc:da};function ha(e){const{inputs:t,backend:n}=e,{real:a,imag:r}=t,o=n.makeTensorInfo(a.shape,"complex64"),s=n.texData.get(o.dataId),i=da({inputs:{x:a},backend:n}),l=da({inputs:{x:r},backend:n});return s.complexTensorInfos={real:i,imag:l},o}const fa={kernelName:t.Complex,backendName:"webgl",kernelFunc:ha},xa="return (a < 0.) ? b * a : a;",ma="\n vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n";const ga={kernelName:t.LeakyRelu,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{alpha:s}=r,i=a.makeTensorInfo([],"float32",t.util.createScalarValue(s,"float32")),l=t.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ca(ma,o.shape,i.shape):new la(xa,o.shape,i.shape),u=a.runWebGLProgram(l,[o,i],"float32");return a.disposeIntermediateTensorInfo(i),u}},ba="return (a < 0.) ? b * a : a;",va="\n vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n";const Ca={kernelName:t.Prelu,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{x:r,alpha:o}=n,s=t.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ca(va,r.shape,o.shape):new la(ba,r.shape,o.shape);return a.runWebGLProgram(s,[r,o],"float32")}};function $a({opSnippet:e,packedOpSnippet:n,cpuKernelImpl:a,dtype:r}){return({inputs:o,backend:s})=>{const{x:i}=o,l=s,u=r||i.dtype;if(l.shouldExecuteOnCPU([i])&&null!=a){const e=l.texData.get(i.dataId),t=a(e.values,u);return l.makeTensorInfo(i.shape,u,t)}let c;return c=t.env().getBool("WEBGL_PACK_UNARY_OPERATIONS")&&null!=n?new ea(i.shape,n):new Qn(i.shape,e),l.runWebGLProgram(c,[i],u)}}function ya({opSnippet:e,packedOpSnippet:n,checkOutOfBounds:a=!1,supportsComplex:r=!1,cpuKernelImpl:o,dtype:s}){return({inputs:i,backend:l})=>{const{a:u,b:c}=i,d=l;if(r&&"complex64"===u.dtype){const n=d.texData.get(u.dataId),a=d.texData.get(c.dataId),[r,o]=[[n.complexTensorInfos.real,a.complexTensorInfos.real],[n.complexTensorInfos.imag,a.complexTensorInfos.imag]].map((n=>{const[a,r]=n,o={dataId:a.dataId,dtype:a.dtype,shape:u.shape},s={dataId:r.dataId,dtype:r.dtype,shape:c.shape},i=new la(e,u.shape,c.shape);return d.runWebGLProgram(i,[o,s],t.upcastType(a.dtype,r.dtype))})),s=ha({inputs:{real:r,imag:o},backend:d});return d.disposeIntermediateTensorInfo(r),d.disposeIntermediateTensorInfo(o),s}const p=s||t.upcastType(u.dtype,c.dtype);if(("string"===u.dtype||"string"===c.dtype||d.shouldExecuteOnCPU([u,c]))&&null!=o){const e=d.texData.get(u.dataId).values,n=d.texData.get(c.dataId).values,a="string"===u.dtype?t.backend_util.fromUint8ToStringArray(e):e,r="string"===u.dtype?t.backend_util.fromUint8ToStringArray(n):n,[s,i]=o(u.shape,c.shape,a,r,p),l=d.makeTensorInfo(i,p);return d.texData.get(l.dataId).values=s,l}let h;return h=t.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")&&null!=n?new ca(n,u.shape,c.shape,a):new la(e,u.shape,c.shape),d.runWebGLProgram(h,[u,c],p)}}function Ia(e,t=!1){if("linear"===e)return"return x;";if("relu"===e)return t?"\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":"if (isnan(x)) return x;\n return (x < 0.0) ? 0.0 : x;\n";if("elu"===e)return t?"\n vec4 result;\n\n result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n return result;\n":"return (x >= 0.0) ? x : (exp(x) - 1.0);";if("relu6"===e)return t?"\n vec4 result = min(x, vec4(6.)) * 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":"if (isnan(x)) return x;\n return (x < 0.0) ? 0.0 : min(6.0, x);\n";if("prelu"===e)return t?va:ba;if("leakyrelu"===e)return t?ma:xa;if("sigmoid"===e)return"return 1.0 / (1.0 + exp(-1.0 * x));";throw new Error(`Activation ${e} has not been implemented for the WebGL backend.`)}class wa{constructor(e,t,n,a=!1,r=!1,o=!1,s=null,i=!1,l=!1){this.variableNames=["matrixA","matrixB"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=n,this.enableShapeUniforms=Ae(this.outputShape.length);const u=a?e[1]:e[2],c=Math.ceil(u/2),d=a?"i * 2, rc.y":"rc.y, i * 2",p=r?"rc.z, i * 2":"i * 2, rc.z",h=a?["a.xxyy","a.zzww"]:["a.xxzz","a.yyww"],f=r?["b.xzxz","b.ywyw"]:["b.xyxy","b.zwzw"];let x="",m="";s&&(x=i?`vec4 activation(vec4 a) {\n vec4 b = getPreluActivationWeightsAtOutCoords();\n ${s}\n }`:l?`vec4 activation(vec4 a) {\n vec4 b = getLeakyreluAlphaAtOutCoords();\n ${s}\n }`:`vec4 activation(vec4 x) {\n ${s}\n }`,m="result = activation(result);");const g=o?"result += getBiasAtOutCoords();":"";o&&this.variableNames.push("bias"),i&&this.variableNames.push("preluActivationWeights"),l&&this.variableNames.push("leakyreluAlpha");let b="rc.x",v="rc.x";e[0]<t[0]?b=`imod(rc.x, ${e[0]})`:t[0]<e[0]&&(v=`imod(rc.x, ${t[0]})`),this.userCode=`\n ${x}\n // Don't use uniform for sharedDimensionPacked for performance.\n const float sharedDimension = ${c}.0;\n\n vec4 dot2x2ARowBCol(ivec3 rc) {\n vec4 result = vec4(0);\n int batchA = ${b};\n int batchB = ${v};\n for (int i = 0; i < ${c}; i++) {\n vec4 a = getMatrixA(batchA, ${d});\n vec4 b = getMatrixB(batchB, ${p});\n\n // These swizzled products need to be separately added.\n // See: https://github.com/tensorflow/tfjs/issues/1735\n result += (${h[0]} * ${f[0]});\n result += (${h[1]} * ${f[1]});\n }\n return result;\n }\n\n void main() {\n ivec3 rc = getOutputCoords();\n vec4 result = dot2x2ARowBCol(rc);\n\n ${g}\n\n ${m}\n\n setOutput(result);\n }\n `}}const Sa="return areal * breal - aimag * bimag;",ka="return areal * bimag + aimag * breal;";class Ra{constructor(e,n,a){this.variableNames=["AReal","AImag","BReal","BImag"],this.outputShape=t.backend_util.assertAndGetBroadcastShape(n,a),this.userCode=`\n float binaryOpComplex(\n float areal, float aimag, float breal, float bimag) {\n ${e}\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 `}}const Ta="return a * b;";function Na(e){const{inputs:n,backend:a}=e,{a:r,b:o}=n,s=t.backend_util.upcastType(r.dtype,o.dtype);if("complex64"===r.dtype){const e=a.texData.get(r.dataId),t=a.texData.get(o.dataId),n=new Ra(Sa,r.shape,o.shape),s=new Ra(ka,r.shape,o.shape),i=[{dataId:e.complexTensorInfos.real.dataId,dtype:e.complexTensorInfos.real.dtype,shape:r.shape},{dataId:e.complexTensorInfos.imag.dataId,dtype:e.complexTensorInfos.imag.dtype,shape:r.shape},{dataId:t.complexTensorInfos.real.dataId,dtype:t.complexTensorInfos.real.dtype,shape:o.shape},{dataId:t.complexTensorInfos.imag.dataId,dtype:t.complexTensorInfos.imag.dtype,shape:o.shape}],l=a.runWebGLProgram(n,i,"float32"),u=a.runWebGLProgram(s,i,"float32"),c=ha({inputs:{real:l,imag:u},backend:a});return a.disposeIntermediateTensorInfo(l),a.disposeIntermediateTensorInfo(u),c}if(a.shouldExecuteOnCPU([r,o])){const e=a.texData.get(r.dataId),t=a.texData.get(o.dataId),[n,i]=mn(r.shape,o.shape,e.values,t.values,s),l=a.makeTensorInfo(i,s);return a.texData.get(l.dataId).values=n,l}let i;return i=t.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ca(Ta,r.shape,o.shape):new la(Ta,r.shape,o.shape),a.runWebGLProgram(i,[r,o],s)}const Ea={kernelName:t.Multiply,backendName:"webgl",kernelFunc:Na};function Aa(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{shape:s}=r,i=a,l=t.util.sizeFromShape(o.shape),u=t.util.inferFromImplicitShape(s,l),c=t.util.sizeFromShape(u);t.util.assert(l===c,(()=>`The new shape (${u}) has ${c} elements and the old shape (${o.shape}) has ${l} elements. The new shape and old shape must have the same number of elements.`));const d=i.texData.get(o.dataId);return!d.isPacked||j(o.shape,u)||null!==d.texture&&j(d.shape,u)?(i.incRef(o.dataId),{dataId:o.dataId,shape:u,dtype:o.dtype}):function(e,t,n){const a=[M(e.shape),...G(e.shape)],r={dtype:e.dtype,shape:a,dataId:e.dataId},o=[M(t),...G(t)],s=new Hn(o,a),i=[a],l=n.runWebGLProgram(s,[r],e.dtype,i,!0);return{dataId:l.dataId,shape:t,dtype:l.dtype}}(o,u,i)}const _a={kernelName:t.Reshape,backendName:"webgl",kernelFunc:Aa};class Oa{constructor(e,n){this.variableNames=["x"];const{windowSize:a,batchSize:r,inSize:o,outSize:s}=e;this.outputShape=[r,s];const i=4*Math.floor(a/4),l=a%4;let u="sumValue += dot(values, ones);";if(null!=n){const e=1/n;u=`sumValue += dot(values * ${t.util.isInt(e)?e.toPrecision(2):e}, ones);`}let c="";o%a>0&&(c=`\n if (inIdx < 0 || inIdx >= ${o}) {\n return 0.0;\n }\n `),this.userCode=`\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float getValue(int batch, int inIdx) {\n ${c}\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 * ${a};\n\n float sumValue = 0.0;\n\n for (int i = 0; i < ${i}; 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 ${u}\n }\n\n int inIdx = inOffset + ${i};\n if (${1===l}) {\n vec4 values = vec4(getValue(batch, inIdx), 0.0, 0.0, 0.0);\n\n ${u}\n } else if (${2===l}) {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1), 0.0, 0.0);\n\n ${u}\n } else if (${3===l}) {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2), 0.0);\n\n ${u}\n }\n setOutput(sumValue);\n }\n `}}class Fa{constructor(e,t){this.variableNames=["x"];const{windowSize:n,batchSize:a,inSize:r,outSize:o}=e;this.outputShape=[a,o];let s="0.0",i="";"prod"===t?s="1.0":"min"===t?(s="1.0 / 1e-20",i="min"):"max"===t&&(s="-1.0 / 1e-20",i="max");let l=`${t}(${t}(${t}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;"sum"===t?l="sumValue":"prod"===t?l="prodValue":"all"===t?l="allValue":"any"===t&&(l="anyValue");const u=4*Math.floor(n/4),c=n%4;let d=`\n if (${"sum"===t}) {\n sumValue += dot(values, ones);\n } else if (${"prod"===t}) {\n vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]);\n prodValue *= tmp[0] * tmp[1];\n } else {\n minMaxValue = ${i}(values, minMaxValue);\n if (${"min"===t} || ${"max"===t}) {\n minMaxValue = ${i}(values, minMaxValue);\n bvec4 isNaN = isnan(values);\n if (isNaN.r || isNaN.g || isNaN.b || isNaN.a) {\n minMaxValue = vec4(NAN);\n }\n }\n }\n `,p="vec4";"all"===t?(s="1.0",d="\n bool reducedAllValue = all(values);\n float floatedReducedAllValue = float(reducedAllValue);\n allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0);\n ",p="bvec4"):"any"===t&&(s="0.0",d="\n bool reducedAnyValue = any(values);\n float floatedReducedAnyValue = float(reducedAnyValue);\n anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0);\n ",p="bvec4");let h="";r%n>0&&(h=`\n if (inIdx < 0 || inIdx >= ${r}) {\n return initializationValue;\n }\n `),this.userCode=`\n const float initializationValue = ${s};\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float getValue(int batch, int inIdx) {\n ${h}\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(${s});\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 < ${u}; 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 ${d}\n }\n\n int inIdx = inOffset + ${u};\n if (${1===c}) {\n ${p} values = ${p}(\n getValue(batch, inIdx),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n ${d}\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 ${d}\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 ${d}\n }\n setOutput(${l});\n }\n `}}function Da(e,n,a,r){const o=function(e){const n=[];for(;0===n.length||1!==n[n.length-1].outSize;){const a=n.length?n[n.length-1].outSize:e[1],r=t.backend_util.computeOptimalWindowSize(a);n.push({inSize:a,windowSize:r,outSize:Math.ceil(a/r)})}return n}(e.shape);let s=e;for(let t=0;t<o.length;t++){const{inSize:i,windowSize:l,outSize:u}=o[t];let c,d;c="mean"===a?0===t?new Oa({windowSize:l,inSize:i,batchSize:e.shape[0],outSize:u},i):new Oa({windowSize:l,inSize:i,batchSize:e.shape[0],outSize:u}):new Fa({windowSize:l,inSize:i,batchSize:e.shape[0],outSize:u},a),d=s,s=r.runWebGLProgram(c,[s],n),d.dataId!==e.dataId&&r.disposeIntermediateTensorInfo(d)}return s}class Pa{constructor(e,t){this.variableNames=["A"];const n=new Array(e.length);for(let a=0;a<n.length;a++)n[a]=e[t[a]];this.outputShape=n,this.rank=n.length;const a=Se(this.rank),r=function(e){const t=e.length;if(t>6)throw Error(`Transpose for rank ${t} is not yet supported`);const n=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u","resRC.v"],a=new Array(t);for(let t=0;t<e.length;t++)a[e[t]]=n[t];return a.join()}(t);this.userCode=`\n void main() {\n ${a} resRC = getOutputCoords();\n setOutput(getA(${r}));\n }\n `}}class La{constructor(e,t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0;const n=new Array(e.length);for(let a=0;a<n.length;a++)n[a]=e[t[a]];if(this.outputShape=n,this.rank=n.length,this.rank>6)throw Error(`Packed transpose for rank ${this.rank} is not yet supported.`);const a=Se(this.rank),r=Gn("rc",this.rank),o=new Array(this.rank);for(let e=0;e<t.length;e++)o[t[e]]=r[e];const s=`vec2(${o.slice(-2).join()})`,i=`++${r[this.rank-1]} < ${n[this.rank-1]}`,l=`getChannel(getA(${o.join()}), ${s})`;this.userCode=`\n void main() {\n ${a} rc = getOutputCoords();\n vec4 result = vec4(0.);\n result[0] = ${l};\n if(${i}) {\n result[1] = ${l};\n }\n --${r[this.rank-1]};\n if(++${r[this.rank-2]} < ${n[this.rank-2]}) {\n result[2] = ${l};\n if(${i}) {\n result[3] = ${l};\n }\n }\n setOutput(result);\n }\n `}}function Ba(e,n,a){const r=t.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new La(e.shape,n):new Pa(e.shape,n);return a.runWebGLProgram(r,[e],e.dtype)}function Va(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s,keepDims:i}=r;return function(e,n,a,r){const o=n,s=e.shape.length,i=t.util.parseAxisParam(o,e.shape);let l=i;const u=t.backend_util.getAxesPermutation(l,s),c=null!=u;let d=e;c&&(d=Ba(e,u,r),l=t.backend_util.getInnerMostAxes(l.length,s)),t.backend_util.assertAxesAreInnerMostDims("sum",l,s);const[p,h]=t.backend_util.computeOutAndReduceShapes(d.shape,l);let f=p;a&&(f=t.backend_util.expandShapeToKeepDim(p,i));const x=t.util.sizeFromShape(h),m=Aa({inputs:{x:d},attrs:{shape:[t.util.sizeFromShape(e.shape)/x,x]},backend:r}),g=Da(m,t.sumOutType(e.dtype),"sum",r),b=Aa({inputs:{x:g},attrs:{shape:f},backend:r});return r.disposeIntermediateTensorInfo(m),r.disposeIntermediateTensorInfo(g),c&&r.disposeIntermediateTensorInfo(d),b}(o,s,i,a)}const Wa={kernelName:t.Sum,backendName:"webgl",kernelFunc:Va};function Ua(e){const{inputs:t,backend:n,attrs:a}=e,{x:r}=t,{perm:o}=a,s=n,i=r.shape.length,l=new Array(i);for(let e=0;e<l.length;e++)l[e]=r.shape[o[e]];let u;if(s.shouldExecuteOnCPU([r])){const e=s.texData.get(r.dataId).values,t=Un(e,r.shape,r.dtype,o,l);u=s.makeTensorInfo(l,r.dtype);s.texData.get(u.dataId).values=t}else u=Ba(r,o,s);return u}const Ma={kernelName:t.Transpose,backendName:"webgl",kernelFunc:Ua};function Ga({a:e,b:n,transposeA:a,transposeB:r,backend:o,bias:s=null,preluActivationWeights:i=null,leakyreluAlpha:l=0,activation:u=null}){const c=e.shape.length,d=n.shape.length,p=a?e.shape[c-2]:e.shape[c-1],h=r?n.shape[d-1]:n.shape[d-2],f=a?e.shape[c-1]:e.shape[c-2],x=r?n.shape[d-2]:n.shape[d-1],m=e.shape.slice(0,-2),g=n.shape.slice(0,-2),b=t.util.sizeFromShape(m),v=t.util.sizeFromShape(g),C=t.broadcast_util.assertAndGetBroadcastShape(e.shape.slice(0,-2),n.shape.slice(0,-2)).concat([f,x]);t.util.assert(p===h,(()=>`Error in matMul: inner shapes (${p}) and (${h}) of Tensors with shapes ${e.shape} and ${n.shape} and transposeA=${a} and transposeB=${r} must match.`));const $=a?[b,p,f]:[b,f,p],y=r?[v,x,h]:[v,h,x],I=Aa({inputs:{x:e},backend:o,attrs:{shape:$}}),w=Aa({inputs:{x:n},backend:o,attrs:{shape:y}}),S=[I,w],k=Math.max(b,v),R=a?I.shape[1]:I.shape[2],T=null!=s,N=null!=i,E="leakyrelu"===u,A=null!=u?Ia(u,!0):null;let _;if((1===f||1===x)&&R>1e3&&!1===(T||N||E||null!=A)){let e=I,t=w;a&&(e=Ua({inputs:{x:I},backend:o,attrs:{perm:[0,2,1]}}),S.push(e)),r&&(t=Ua({inputs:{x:w},backend:o,attrs:{perm:[0,2,1]}}),S.push(t));const n=1===x;let s=e;1!==x&&(s=Aa({inputs:{x:e},backend:o,attrs:{shape:[k,R,1]}}),S.push(s));const i=1===x?2:1;let l=t;n&&(l=Aa({inputs:{x:t},backend:o,attrs:{shape:[k,1,R]}}),S.push(l));const u=Na({inputs:{a:s,b:l},backend:o});_=Va({inputs:{x:u},backend:o,attrs:{axis:i,keepDims:!0}}),S.push(u)}else{const u=t.upcastType(e.dtype,n.dtype),c=new wa($,y,[k,f,x],a,r,T,A,N,E),d=[I,w];if(null!=s&&d.push(s),N&&d.push(i),E){const e=o.makeTensorInfo([],"float32",t.util.createScalarValue(l,"float32"));d.push(e),S.push(e)}_=o.runWebGLProgram(c,d,u)}const O=Aa({inputs:{x:_},backend:o,attrs:{shape:C}});S.push(_);for(const e of S)o.disposeIntermediateTensorInfo(e);return O}const za={kernelName:t._FusedMatMul,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{a:r,b:o,bias:s,preluActivationWeights:i}=t,{transposeA:l,transposeB:u,activation:c,leakyreluAlpha:d}=a;return Ga({a:r,b:o,transposeA:l,transposeB:u,backend:n,bias:s,preluActivationWeights:i,leakyreluAlpha:d,activation:c})}},Xa="return abs(x);";const Ha={kernelName:t.Abs,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{x:r}=n;if(a.shouldExecuteOnCPU([r])&&"complex64"!==r.dtype){const e=a.texData.get(r.dataId),t=Rn(e.values);return a.makeTensorInfo(r.shape,r.dtype,t)}let o;return o=t.env().getBool("WEBGL_PACK_UNARY_OPERATIONS")?new ea(r.shape,Xa):new Qn(r.shape,Xa),a.runWebGLProgram(o,[r],r.dtype)}},ja=$a({opSnippet:"if (isnan(x)) return x;\n if (abs(x) > 1.) {\n return NAN;\n }\n return acos(x);\n"}),Ka={kernelName:t.Acos,backendName:"webgl",kernelFunc:ja},qa=$a({opSnippet:"if (isnan(x)) return x;\n if (x < 1.0) return NAN;\nreturn log(x + sqrt(x * x - 1.0));"}),Ya={kernelName:t.Acosh,backendName:"webgl",kernelFunc:qa},Qa="return a + b;",Za=ya({opSnippet:Qa,packedOpSnippet:Qa,supportsComplex:!0,cpuKernelImpl:jt}),Ja={kernelName:t.Add,backendName:"webgl",kernelFunc:Za};class er{constructor(e,t){this.outputShape=[],this.outputShape=e,this.variableNames=t.map(((e,t)=>`T${t}`));const n=[];this.variableNames.forEach((e=>{n.push(`float v${e} = get${e}AtOutCoords();`)}));const a=this.variableNames.map((e=>`v${e}`)).join(" + ");this.userCode=`\n void main() {\n ${n.join("\n ")}\n\n float result = ${a};\n setOutput(result);\n }\n `}}class tr{constructor(e,t){this.outputShape=[],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.variableNames=t.map(((e,t)=>`T${t}`));const n=[];this.variableNames.forEach((e=>{n.push(`vec4 v${e} = get${e}AtOutCoords();`)}));const a=this.variableNames.map((e=>`v${e}`)).join(" + ");this.userCode=`\n void main() {\n ${n.join("\n ")}\n\n vec4 result = ${a};\n setOutput(result);\n }\n `}}const nr={kernelName:t.AddN,backendName:"webgl",kernelFunc:function e(n){const{inputs:a,backend:r}=n,o=a;if(1===o.length)return da({inputs:{x:o[0]},backend:r});if(o.length>t.env().getNumber("WEBGL_MAX_TEXTURES_IN_SHADER")){const t=Math.floor(o.length/2),n=e({inputs:o.slice(0,t),backend:r}),a=e({inputs:o.slice(t),backend:r});return e({inputs:[n,a],backend:r})}const s=o.map((e=>e.dtype)).reduce(((e,n)=>t.upcastType(e,n))),i=o.map((e=>e.shape)),l=t.env().getBool("WEBGL_PACK")?new tr(o[0].shape,i):new er(o[0].shape,i);return r.runWebGLProgram(l,o,s)}};const ar={kernelName:t.All,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s,keepDims:i}=r,l=o.shape.length,u=t.util.parseAxisParam(s,o.shape);let c=u;const d=t.backend_util.getAxesPermutation(c,l);let p=o;null!=d&&(p=Ua({inputs:{x:o},backend:a,attrs:{perm:d}}),c=t.backend_util.getInnerMostAxes(c.length,l)),t.backend_util.assertAxesAreInnerMostDims("all",c,l);const[h,f]=t.backend_util.computeOutAndReduceShapes(p.shape,c),x=Aa({inputs:{x:p},backend:a,attrs:{shape:[-1,t.util.sizeFromShape(f)]}}),m=Da(x,x.dtype,"all",a);let g;if(i){g=Aa({inputs:{x:m},backend:a,attrs:{shape:t.backend_util.expandShapeToKeepDim(h,u)}})}else g=Aa({inputs:{x:m},backend:a,attrs:{shape:h}});return a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(m),null!=d&&a.disposeIntermediateTensorInfo(p),g}};const rr={kernelName:t.Any,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s,keepDims:i}=r,l=o.shape.length,u=t.util.parseAxisParam(s,o.shape);let c=u;const d=t.backend_util.getAxesPermutation(c,l);let p=o;null!=d&&(p=Ua({inputs:{x:o},backend:a,attrs:{perm:d}}),c=t.backend_util.getInnerMostAxes(c.length,l)),t.backend_util.assertAxesAreInnerMostDims("any",c,l);const[h,f]=t.backend_util.computeOutAndReduceShapes(p.shape,c),x=Aa({inputs:{x:p},backend:a,attrs:{shape:[-1,t.util.sizeFromShape(f)]}}),m=Da(x,x.dtype,"any",a);let g;if(i){g=Aa({inputs:{x:m},backend:a,attrs:{shape:t.backend_util.expandShapeToKeepDim(h,u)}})}else g=Aa({inputs:{x:m},backend:a,attrs:{shape:h}});return a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(m),null!=d&&a.disposeIntermediateTensorInfo(p),g}};class or{constructor(e,t,n){this.variableNames=["A"];const{windowSize:a,batchSize:r,outSize:o}=e;n||this.variableNames.push("bestIndicesA"),this.outputShape=[r,o];const s="max"===t?">":"<",i=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 * ${a};\n\n int bestIndex = inOffset;\n float bestValue = getA(batch, bestIndex);\n\n for (int i = 0; i < ${a}; i++) {\n int inIdx = ${i};\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 `}}class sr{constructor(e,n,a,r){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,t.util.assert(e.length>2,(()=>`Packed arg${a.charAt(0).toUpperCase()+a.slice(1)} supports only inputs with rank above 2.`));const o=e[e.length-1],s=Math.ceil(o/n);this.outputShape=e.slice(0,-1),s>1&&this.outputShape.push(s),r||this.variableNames.push("bestIndicesA");const i=this.outputShape,l=i.length,u=Se(l),c=zn("coords",l);let d,p;if(1===s){p=l+1;const e=Se(p);d=`\n ${e} sourceLocR = ${e}(${c.join()}, 0);\n ++${c[l-1]};\n ${e} sourceLocG = ${e}(${c.join()}, 0);\n ++${c[l-2]};\n ${e} sourceLocA = ${e}(${c.join()}, 0);\n --${c[l-1]};\n ${e} sourceLocB = ${e}(${c.join()}, 0);\n --${c[l-2]};`}else p=l,d=`\n ${u} sourceLocR = coords;\n ++${c[l-1]};\n ${u} sourceLocG = coords;\n ++${c[l-2]};\n ${u} sourceLocA = coords;\n --${c[l-1]};\n ${u} sourceLocB = coords;\n --${c[l-2]};`;const h=["x","y","z","w","u","v"].slice(0,p),f="."+h[p-1],x=h.map((e=>"int "+e)),m=zn("sourceLocR",p-1).concat("inIdx.r"),g=zn("sourceLocG",p-1).concat("inIdx.g"),b=zn("sourceLocB",p-1).concat("inIdx.b"),v=zn("sourceLocA",p-1).concat("inIdx.a"),C="max"===a?"greaterThan":"lessThan",$=r?"":`\n inIdx = round(vec4(getBestIndicesAChannel(${m.join()}),\n getBestIndicesAChannel(${g.join()}),\n getBestIndicesAChannel(${b.join()}),\n getBestIndicesAChannel(${v.join()})));`,y=`vec4(\n getAChannel(${m.join()}),\n hasNextCol ? getAChannel(${g.join()}) : 0.,\n hasNextRow ? getAChannel(${b.join()}) : 0.,\n hasNextRow && hasNextCol ? getAChannel(${v.join()}) : 0.)`,I=r?"":`\n float getBestIndicesAChannel(${x.join()}) {\n return getChannel(getBestIndicesA(${h.join()}),\n vec2(${h.slice(-2).join()}));\n }`;this.userCode=`\n float getAChannel(${x.join()}) {\n return getChannel(getA(${h.join()}),\n vec2(${h.slice(-2).join()}));\n }\n ${I}\n void main() {\n ${u} coords = getOutputCoords();\n bool hasNextCol = ${c[l-1]} < ${i[l-1]-1};\n bool hasNextRow = ${c[l-2]} < ${i[l-2]-1};\n ${d}\n ivec4 srcIdx = ivec4(sourceLocR${f}, sourceLocG${f},\n sourceLocB${f}, sourceLocA${f}) * ${n};\n ivec4 inIdx = srcIdx;\n vec4 bestIndex = vec4(inIdx);\n vec4 bestValue = ${y};\n\n for (int i = 0; i < ${n}; i++) {\n inIdx = srcIdx;\n ${$}\n vec4 candidate = ${y};\n bvec4 nan = isnan(candidate);\n bvec4 replace = bvec4(\n vec4(${C}(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 `}}function ir(e,n,a,r=null){let o=n.shape[0],s=n.shape[1];null!=r&&(o=r.shape[0],s=r.shape[1]);const i=t.backend_util.computeOptimalWindowSize(s),l={windowSize:i,inSize:s,batchSize:o,outSize:Math.ceil(s/i)},u=new or(l,a,null==r),c=[n];null!=r&&c.push(r);const d=e.runWebGLProgram(u,c,"int32");if(1===d.shape[1])return d;const p=ir(e,n,a,d);return e.disposeIntermediateTensorInfo(d),p}function lr(e,n,a,r=null){const o=null!=r?r.shape:n.shape,s=o[o.length-1],i=t.backend_util.computeOptimalWindowSize(s),l=new sr(o,i,a,null==r),u=null==r?[n]:[n,r],c=e.runWebGLProgram(l,u,"int32");if(c.shape.length===n.shape.length){const t=lr(e,n,a,c);return e.disposeIntermediateTensorInfo(c),t}return c}function ur(e,n,a,r){const o=[a];if(t.backend_util.assertAxesAreInnerMostDims("arg"+r.charAt(0).toUpperCase()+r.slice(1),o,n.shape.length),!t.env().getBool("WEBGL_PACK_REDUCE")||n.shape.length<=2){const a=[],s=e.texData.get(n.dataId);let i=n;null!==s&&s.isPacked&&(i=e.unpackTensor(n),a.push(i));const[l,u]=t.backend_util.computeOutAndReduceShapes(i.shape,o),c=t.util.sizeFromShape(u),d=Aa({inputs:{x:i},backend:e,attrs:{shape:[-1,c]}});a.push(d);const p=ir(e,d,r);a.push(p);const h=Aa({inputs:{x:p},backend:e,attrs:{shape:l}});return a.forEach((t=>e.disposeIntermediateTensorInfo(t))),h}return lr(e,n,r)}const cr={kernelName:t.ArgMax,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s}=r;let i=t.util.parseAxisParam(s,o.shape);const l=t.backend_util.getAxesPermutation(i,o.shape.length);let u=o;const c=[];null!=l&&(u=Ua({inputs:{x:o},backend:a,attrs:{perm:l}}),c.push(u),i=t.backend_util.getInnerMostAxes(i.length,u.shape.length)),t.backend_util.assertAxesAreInnerMostDims("argMax",[i[0]],u.shape.length);const d=ur(a,u,i[0],"max");return c.forEach((e=>a.disposeIntermediateTensorInfo(e))),d}};const dr={kernelName:t.ArgMin,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s}=r;let i=t.util.parseAxisParam(s,o.shape);const l=t.backend_util.getAxesPermutation(i,o.shape.length);let u=o;const c=[];null!=l&&(u=Ua({inputs:{x:o},backend:a,attrs:{perm:l}}),c.push(u),i=t.backend_util.getInnerMostAxes(i.length,u.shape.length)),t.backend_util.assertAxesAreInnerMostDims("argMin",[i[0]],u.shape.length);const d=ur(a,u,i[0],"min");return c.forEach((e=>a.disposeIntermediateTensorInfo(e))),d}},pr=$a({opSnippet:"if (isnan(x)) return x;\n if (abs(x) > 1.) {\n return NAN;\n }\n return asin(x);\n"}),hr={kernelName:t.Asin,backendName:"webgl",kernelFunc:pr},fr=$a({opSnippet:"if (isnan(x)) return x;return log(x + sqrt(x * x + 1.0));"}),xr={kernelName:t.Asinh,backendName:"webgl",kernelFunc:fr},mr=$a({opSnippet:"if (isnan(x)) return x;\n return atan(x);\n"}),gr={kernelName:t.Atan,backendName:"webgl",kernelFunc:mr},br=ya({opSnippet:"\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return atan(a, b);\n",packedOpSnippet:"\n vec4 result = atan(a, b);\n bvec4 isNaNA = isnan(a);\n bvec4 isNaNB = isnan(b);\n bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w);\n \n result.r = isNaN.r ? NAN : result.r;\n result.g = isNaN.g ? NAN : result.g;\n result.b = isNaN.b ? NAN : result.b;\n result.a = isNaN.a ? NAN : result.a;\n\n return result;\n"}),vr={kernelName:t.Atan2,backendName:"webgl",kernelFunc:br},Cr=$a({opSnippet:"if (isnan(x)) return x;\n if ((x < -1.0) || (x > 1.0)) return NAN;\nreturn (log(1.0 + x) - log(1.0 - x)) / 2.0;"}),$r={kernelName:t.Atanh,backendName:"webgl",kernelFunc:Cr};class yr{constructor(e,t,n,a=!1,r=!1){if(this.variableNames=["x"],"avg"===t&&n)throw new Error("Cannot compute positions for average pool.");const o=e.filterWidth,s=e.strideHeight,i=e.strideWidth,l=e.dilationHeight,u=e.dilationWidth,c=e.effectiveFilterHeight,d=e.effectiveFilterWidth,p=e.padInfo.top,h=e.padInfo.left;this.outputShape=e.outShape;const f="avg"===t,x=`((batch * ${e.inHeight} + xR) * ${e.inWidth} + xC) * ${e.inChannels} + d`,m=`(xR * ${e.inWidth} + xC) * ${e.inChannels} + d`;let g="0.0";if(f||(g="-1.0 / 1e-20"),n){const t=">=";return void(this.userCode=`\n const ivec2 strides = ivec2(${s}, ${i});\n const ivec2 pads = ivec2(${p}, ${h});\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 float minMaxValue = 0.0;\n float minMaxValueFound = 0.0;\n int minMaxPosition = 0;\n float avgValue = 0.0;\n\n for (int wR = 0; wR < ${c};\n wR += ${l}) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int wC = 0; wC < ${d};\n wC += ${u}) {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= ${e.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 ${t} currMinMaxValue) {\n minMaxValue = value;\n minMaxValueFound = 1.0;\n minMaxPosition = ${a?r?x:m:`wR * ${d} + wC`};\n }\n }\n }\n setOutput(float(minMaxPosition));\n }\n `)}let b=`${t}(${t}(${t}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;"avg"===t&&(b="avgValue / max(count, 1.0)");const v=4*Math.floor(o/4),C=o%4,$=`\n if (${f}) {\n avgValue += dot(values, ones);\n } else {\n minMaxValue = max(values, minMaxValue);\n }\n `;this.userCode=`\n const ivec2 strides = ivec2(${s}, ${i});\n const ivec2 pads = ivec2(${p}, ${h});\n const float initializationValue = ${g};\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 >= ${e.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(${g});\n float avgValue = 0.0;\n count = 0.0;\n\n for (int wR = 0; wR < ${c};\n wR += ${l}) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int wC = 0; wC < ${v}; wC += 4) {\n int xC = xCCorner + wC * ${u};\n\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + ${u}, d),\n getValue(batch, xR, xC + 2 * ${u}, d),\n getValue(batch, xR, xC + 3 * ${u}, d)\n );\n\n ${$}\n }\n\n int xC = xCCorner + ${v};\n if (${1===C}) {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n ${$}\n } else if (${2===C}) {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + ${u}, d),\n initializationValue,\n initializationValue\n );\n\n ${$}\n } else if (${3===C}) {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + ${u}, d),\n getValue(batch, xR, xC + 2 * ${u}, d),\n initializationValue\n );\n\n ${$}\n }\n }\n setOutput(${b});\n }\n `}}class Ir{constructor(e,t,n,a=!1,r=!1){if(this.variableNames=["x"],"avg"===t&&n)throw new Error("Cannot compute positions for average pool.");const o=e.filterWidth,s=e.strideDepth,i=e.strideHeight,l=e.strideWidth,u=e.dilationDepth,c=e.dilationHeight,d=e.dilationWidth,p=e.effectiveFilterDepth,h=e.effectiveFilterHeight,f=e.effectiveFilterWidth,x=e.padInfo.front,m=e.padInfo.top,g=e.padInfo.left;this.outputShape=e.outShape;const b="avg"===t;let v="0.0";if(b||(v="-1.0 / 1e-20"),n){const t=">=";return void(this.userCode=`\n const ivec3 strides =\n ivec3(${s}, ${i}, ${l});\n const ivec3 pads = ivec3(${x}, ${m}, ${g});\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n int xDCorner = xCorner.x;\n int xRCorner = xCorner.y;\n int xCCorner = xCorner.z;\n\n // max/min x(?, ?, ?, ch) to get y(yD, yR, yC, ch).\n // ? = to be determined\n float minMaxValue = 0.0;\n float minMaxValueFound = 0.0;\n int minMaxPosition = 0;\n\n for (int wD = 0; wD < ${p};\n wD += ${u}) {\n int xD = xDCorner + wD;\n\n if (xD < 0 || xD >= ${e.inDepth}) {\n continue;\n }\n\n for (int wR = 0; wR < ${h};\n wR += ${c}) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int wC = 0; wC < ${f};\n wC += ${d}) {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= ${e.inWidth}) {\n continue;\n }\n\n float value = getX(batch, xD, xR, xC, ch);\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 ${t} currMinMaxValue) {\n minMaxValue = value;\n minMaxValueFound = 1.0;\n minMaxPosition = ${a?r?`(((batch * ${e.inDepth} + xD) * ${e.inHeight} + xR) * ${e.inWidth} + xC) * ${e.inChannels} + ch`:`((xD * ${e.inHeight} + xR) * ${e.inWidth} + xC) * ${e.inChannels} + ch`:`wD * ${h} * ${f} +\n wR * ${f} + wC`};\n }\n }\n }\n }\n setOutput(float(minMaxPosition));\n }\n `)}let C=`${t}(${t}(${t}(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])`;"avg"===t&&(C="avgValue / max(count, 1.0)");const $=4*Math.floor(o/4),y=o%4,I=`\n if (${b}) {\n avgValue += dot(values, ones);\n } else {\n minMaxValue = max(values, minMaxValue);\n }\n `;this.userCode=`\n const ivec3 strides =\n ivec3(${s}, ${i}, ${l});\n const ivec3 pads = ivec3(${x}, ${m}, ${g});\n const float initializationValue = ${v};\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 xD, int xR, int xC, int ch) {\n if (xC < 0 || xC >= ${e.inWidth}) {\n return initializationValue;\n }\n count += 1.0;\n return getX(batch, xD, xR, xC, ch);\n }\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n int xDCorner = xCorner.x;\n int xRCorner = xCorner.y;\n int xCCorner = xCorner.z;\n\n // max/min x(?, ?, ?, d) to get y(yD, yR, yC, ch).\n // ? = to be determined\n vec4 minMaxValue = vec4(${v});\n float avgValue = 0.0;\n count = 0.0;\n\n for (int wD = 0; wD < ${p};\n wD += ${u}) {\n int xD = xDCorner + wD;\n\n if (xD < 0 || xD >= ${e.inDepth}) {\n continue;\n }\n\n for (int wR = 0; wR < ${h};\n wR += ${c}) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int wC = 0; wC < ${$}; wC += 4) {\n int xC = xCCorner + wC * ${d};\n\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n getValue(batch, xD, xR, xC + ${d}, ch),\n getValue(batch, xD, xR, xC + 2 * ${d}, ch),\n getValue(batch, xD, xR, xC + 3 * ${d}, ch)\n );\n\n ${I}\n }\n\n int xC = xCCorner + ${$};\n if (${1===y}) {\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n ${I}\n } else if (${2===y}) {\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n getValue(batch, xD, xR, xC + ${d}, ch),\n initializationValue,\n initializationValue\n );\n\n ${I}\n } else if (${3===y}) {\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n getValue(batch, xD, xR, xC + ${d}, ch),\n getValue(batch, xD, xR, xC + 2 * ${d}, ch),\n initializationValue\n );\n\n ${I}\n }\n }\n }\n setOutput(${C});\n }\n `}}const wr={kernelName:t.AvgPool,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n;oe(o,"avgPool");const{filterSize:s,strides:i,pad:l,dimRoundingMode:u}=r;t.util.assert(t.backend_util.eitherStridesOrDilationsAreOne(i,1),(()=>`Error in avgPool: Either strides or dilations must be 1. Got strides ${i} and dilations '1'`));const c=t.backend_util.computePool2DInfo(o.shape,s,i,1,l,u);if(1===c.filterWidth&&1===c.filterHeight&&t.util.arraysEqual(c.inShape,c.outShape))return da({inputs:{x:o},backend:a});const d=new yr(c,"avg",!1);return a.runWebGLProgram(d,[o],"float32")}};const Sr={kernelName:t.AvgPool3D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{filterSize:s,strides:i,pad:l,dimRoundingMode:u,dataFormat:c}=r,d=t.backend_util.computePool3DInfo(o.shape,s,i,[1,1,1],l,u,c),p=new Ir(d,"avg",!1);return a.runWebGLProgram(p,[o],"float32")}};class kr{constructor(e){this.variableNames=["dy"],this.outputShape=e.inShape;const t=e.filterHeight,n=e.filterWidth,a=e.strideHeight,r=e.strideWidth,o=e.dilationHeight,s=e.dilationWidth,i=e.effectiveFilterHeight,l=e.effectiveFilterWidth,u=i-1-e.padInfo.top,c=l-1-e.padInfo.left,d=1/(t*n);this.userCode=`\n const ivec2 pads = ivec2(${u}, ${c});\n const float avgMultiplier = float(${d});\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 < ${i};\n wR += ${o}) {\n float dyR = float(dyRCorner + wR) / ${a}.0;\n\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < ${l};\n wC+= ${s}) {\n float dyC = float(dyCCorner + wC) / ${r}.0;\n\n if (dyC < 0.0 || dyC >= ${e.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 `}}class Rr{constructor(e){this.variableNames=["dy"],this.outputShape=e.inShape;const t=e.filterDepth,n=e.filterHeight,a=e.filterWidth,r=e.strideDepth,o=e.strideHeight,s=e.strideWidth,i=e.dilationDepth,l=e.dilationHeight,u=e.dilationWidth,c=e.effectiveFilterDepth,d=e.effectiveFilterHeight,p=e.effectiveFilterWidth,h=c-1-e.padInfo.front,f=d-1-e.padInfo.top,x=p-1-e.padInfo.left,m=1/(t*n*a);this.userCode=`\n const ivec3 pads = ivec3(${h}, ${f}, ${x});\n const float avgMultiplier = float(${m});\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n int dyDCorner = dyCorner.x;\n int dyRCorner = dyCorner.y;\n int dyCCorner = dyCorner.z;\n\n // Convolve dy(?, ?, ?, d) with pos mask(:, :, :, ch) to get\n // dx(xD, xR, xC, ch).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int wD = 0; wD < ${c};\n wD += ${i}) {\n float dyD = float(dyDCorner + wD) / ${r}.0;\n\n if (dyD < 0.0 || dyD >= ${e.outDepth}.0 || fract(dyD) > 0.0) {\n continue;\n }\n int idyD = int(dyD);\n\n for (int wR = 0; wR < ${d};\n wR += ${l}) {\n float dyR = float(dyRCorner + wR) / ${o}.0;\n\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 ||\n fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < ${p};\n wC += ${u}) {\n float dyC = float(dyCCorner + wC) / ${s}.0;\n\n if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n\n dotProd += dyValue * avgMultiplier;\n }\n }\n }\n setOutput(dotProd);\n }\n `}}const Tr={kernelName:t.AvgPool3DGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,input:s}=n,i=s,{filterSize:l,strides:u,pad:c,dimRoundingMode:d}=r,p=t.backend_util.computePool3DInfo(i.shape,l,u,[1,1,1],c,d),h=new Rr(p);return a.runWebGLProgram(h,[o],i.dtype)}};const Nr={kernelName:t.AvgPoolGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,input:s}=n,i=s;oe([o,s],"avgPoolGrad");const{filterSize:l,strides:u,pad:c}=r,d=t.backend_util.computePool2DInfo(i.shape,l,u,1,c),p=new kr(d);return a.runWebGLProgram(p,[o],i.dtype)}};const Er={kernelName:t.BatchMatMul,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{a:r,b:o}=t,{transposeA:s,transposeB:i}=a;return Ga({a:r,b:o,transposeA:s,transposeB:i,backend:n})}};class Ar{constructor(e,n,a,r,o,s){this.outputShape=[],this.variableNames=["x","mean","variance"],t.backend_util.assertAndGetBroadcastShape(e,n),t.backend_util.assertAndGetBroadcastShape(e,a);let i="0.0";null!=r&&(t.backend_util.assertAndGetBroadcastShape(e,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");let l="1.0";null!=o&&(t.backend_util.assertAndGetBroadcastShape(e,o),this.variableNames.push("scale"),l="getScaleAtOutCoords()"),this.outputShape=e,this.userCode=`\n void main() {\n float x = getXAtOutCoords();\n float mean = getMeanAtOutCoords();\n float variance = getVarianceAtOutCoords();\n float offset = ${i};\n float scale = ${l};\n float inv = scale * inversesqrt(variance + float(${s}));\n setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1)));\n }\n `}}class _r{constructor(e,n,a,r,o,s){this.packedInputs=!0,this.packedOutput=!0,this.variableNames=["x","mean","variance"],t.backend_util.assertAndGetBroadcastShape(e,n),t.backend_util.assertAndGetBroadcastShape(e,a);let i="vec4(0.0)";null!=r&&(t.backend_util.assertAndGetBroadcastShape(e,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");let l="vec4(1.0)";null!=o&&(t.backend_util.assertAndGetBroadcastShape(e,o),this.variableNames.push("scale"),l="getScaleAtOutCoords()"),this.outputShape=e,this.userCode=`\n void main() {\n vec4 offset = ${i};\n vec4 scale = ${l};\n\n vec4 x = getXAtOutCoords();\n vec4 mean = getMeanAtOutCoords();\n vec4 variance = getVarianceAtOutCoords();\n\n vec4 inv = scale * inversesqrt(variance + vec4(${s}));\n\n setOutput((x - mean) * inv + offset);\n }\n `}}const Or={kernelName:t.FusedBatchNorm,backendName:"webgl",kernelFunc:({inputs:e,backend:n,attrs:a})=>{const{x:r,mean:o,variance:s,offset:i,scale:l}=e;t.util.assert(o.shape.length===s.shape.length,(()=>"Batch normalization gradient requires mean and variance to have equal ranks.")),t.util.assert(null==i||o.shape.length===i.shape.length,(()=>"Batch normalization gradient requires mean and offset to have equal ranks.")),t.util.assert(null==l||o.shape.length===l.shape.length,(()=>"Batch normalization gradient requires mean and scale to have equal ranks."));let{varianceEpsilon:u}=a;null==u&&(u=.001);const c=[r,o,s];let d=null;null!=i&&(d=i.shape,c.push(i));let p=null;null!=l&&(p=l.shape,c.push(l));const h=t.env().getBool("WEBGL_PACK_NORMALIZATION")?new _r(r.shape,o.shape,s.shape,d,p,u):new Ar(r.shape,o.shape,s.shape,d,p,u);return n.runWebGLProgram(h,c,c[0].dtype)}};class Fr{constructor(e){this.variableNames=["source"],this.outputShape=e,this.rank=e.length;const t=Se(this.rank);this.customUniforms=[{name:"start",arrayIndex:this.rank,type:"int"}];const n=function(e){if(1===e)return"sourceLoc";if(e<=6)return Dr.slice(0,e).map((e=>"sourceLoc."+e)).join(",");throw Error(`Slicing for rank ${e} is not yet supported`)}(this.rank);let a;a=`\n ${t} sourceLoc;\n ${t} coords = getOutputCoords();\n ${e.map(((e,t)=>`sourceLoc.${Dr[t]} = start[${t}] + coords.${Dr[t]};`)).join("\n")}\n `,this.userCode=`\n void main() {\n ${a}\n setOutput(getSource(${n}));\n }\n `}}const Dr=["x","y","z","w","u","v"];class Pr{constructor(e){this.variableNames=["source"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.rank=e.length,this.customUniforms=[{name:"start",arrayIndex:this.rank,type:"int"}];const t=Se(this.rank),n=zn("coords",this.rank),a=zn("sourceLoc",this.rank),r=1===this.rank?"sourceLoc":`vec2(${a.slice(-2).join()})`,o=`getChannel(getSource(${a.join()}), ${r})`,s=`\n result.x = ${o};\n if (++${n[this.rank-1]} < ${e[this.rank-1]}) {\n ++${a[this.rank-1]};\n result.y = ${o};\n --${a[this.rank-1]};\n }\n `,i=1===this.rank?"":`\n --${n[this.rank-1]};\n if (++${n[this.rank-2]} < ${e[this.rank-2]}) {\n ++${a[this.rank-2]};\n result.z = ${o};\n if (++${n[this.rank-1]} < ${e[this.rank-1]}) {\n ++${a[this.rank-1]};\n result.w = ${o};\n }\n }\n `,l=this.rank<=4?`sourceLoc = coords +\n ${t}(${e.map(((e,t)=>`start[${t}]`)).join()});`:e.map(((e,t)=>`${a[t]} = ${n[t]} + start[${t}];`)).join("\n");this.userCode=`\n void main() {\n ${t} coords = getOutputCoords();\n ${t} sourceLoc;\n ${l}\n vec4 result = vec4(0.);\n ${s}\n ${i}\n setOutput(result);\n }\n `}}function Lr(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{begin:s,size:i}=r,[l,u]=t.slice_util.parseSliceParams(o,s,i);if(t.slice_util.assertParamsValid(o,l,u),0===t.util.sizeFromShape(u))return a.makeTensorInfo(u,o.dtype,[]);if(a.shouldExecuteOnCPU([o])||"string"===o.dtype){const e=a.texData.get(o.dataId),t=Tn(e.values,l,u,o.shape,o.dtype);return a.makeTensorInfo(u,o.dtype,t)}const{isPacked:c}=a.texData.get(o.dataId),d=t.slice_util.isSliceContinous(o.shape,l,u);if(c||!d){const e=t.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Pr(u):new Fr(u),n=[l];return a.runWebGLProgram(e,[o],o.dtype,n)}return a.uploadToGPU(o.dataId),function(e,n,a,r){const o=r.texData.get(e.dataId),s=r.makeTensorInfo(a,e.dtype),i=r.texData.get(s.dataId);Object.assign(i,o),i.refCount=1,i.shape=a,i.dtype=e.dtype;let l=t.slice_util.computeFlatOffset(n,t.util.computeStrides(e.shape));o.slice&&(l+=o.slice.flatOffset),i.slice={flatOffset:l,origDataId:o.slice&&o.slice.origDataId||e.dataId};const u=r.dataRefCount.get(i.slice.origDataId)||1;return r.dataRefCount.set(i.slice.origDataId,u+1),s}(o,l,u,a)}const Br={kernelName:t.Slice,backendName:"webgl",kernelFunc:Lr},Vr={kernelName:t.BatchToSpaceND,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{blockShape:s,crops:i}=r;t.util.assert(o.shape.length<=4,(()=>"batchToSpaceND for rank > 4 with a WebGL backend not implemented yet"));const l=s.reduce(((e,t)=>e*t)),u=t.backend_util.getReshaped(o.shape,s,l),c=t.backend_util.getPermuted(u.length,s.length),d=t.backend_util.getReshapedPermuted(o.shape,s,l),p=t.backend_util.getSliceBeginCoords(i,s.length),h=t.backend_util.getSliceSize(d,i,s.length),f=[],x=Aa({inputs:{x:o},backend:a,attrs:{shape:u}}),m=Ua({inputs:{x:x},backend:a,attrs:{perm:c}}),g=Aa({inputs:{x:m},backend:a,attrs:{shape:d}}),b=Lr({inputs:{x:g},backend:a,attrs:{begin:p,size:h}});return f.push(x),f.push(m),f.push(g),f.forEach((e=>a.disposeIntermediateTensorInfo(e))),b}};const Wr={kernelName:t.Bincount,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{x:r,weights:o}=t,{size:s}=a,i=n.readSync(r.dataId),l=n.readSync(o.dataId),u=Kt(i,l,o.dtype,o.shape,s);return n.makeTensorInfo([s],o.dtype,u)}};const Ur={kernelName:t.BitwiseAnd,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{a:r,b:o}=n,s=t.env().getBool("WEBGL_PACK_BINARY_OPERATIONS"),i=t.env().getNumber("WEBGL_VERSION");if(a.shouldExecuteOnCPU([r,o])||1===i){const e=a.texData.get(r.dataId).values,t=a.texData.get(o.dataId).values,[n,s]=Yt(r.shape,o.shape,e,t,r.dtype),i=a.makeTensorInfo(s,r.dtype);return a.texData.get(i.dataId).values=n,i}let l;return l=s?new ca("\n int r = int(a.r) & int(b.r);\n int g = int(a.g) & int(b.g);\n int rb = int(a.b) & int(b.b);\n int ra = int(a.a) & int(b.a);\n return vec4(r, g, rb, ra);\n",r.shape,o.shape,!1):new la("\n return float(int(a.r) & int(b.r));\n",r.shape,o.shape),a.runWebGLProgram(l,[r,o],r.dtype)}};const Mr={kernelName:t.BroadcastArgs,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{s0:r,s1:o}=n,s=a.readSync(r.dataId),i=a.readSync(o.dataId),l=t.backend_util.assertAndGetBroadcastShape(Array.from(s),Array.from(i));return a.makeTensorInfo([l.length],"int32",Int32Array.from(l))}},Gr=ya({opSnippet:"return float(a != b);",cpuKernelImpl:bn,dtype:"bool"}),zr={kernelName:t.NotEqual,backendName:"webgl",kernelFunc:Gr};function Xr(e){const{inputs:t,backend:n}=e,{input:a}=t;return da({inputs:{x:n.texData.get(a.dataId).complexTensorInfos.real},backend:n})}const Hr={kernelName:t.Real,backendName:"webgl",kernelFunc:Xr};const jr={kernelName:t.Cast,backendName:"webgl",kernelFunc:function e(n){const{inputs:r,backend:o,attrs:s}=n,{x:i}=r,{dtype:l}=s;if("complex64"===l){if("complex64"===i.dtype)return da({inputs:{x:i},backend:o});const t=a.zeros(i.shape),n=e({inputs:{x:i},backend:o,attrs:{dtype:"float32"}}),r=ha({inputs:{real:n,imag:t},backend:o});return t.dispose(),o.disposeIntermediateTensorInfo(n),r}if("complex64"===i.dtype){const t=Xr({inputs:{input:i},backend:o}),n=e({inputs:{x:t},backend:o,attrs:{dtype:l}});return o.disposeIntermediateTensorInfo(t),n}if(!t.util.hasEncodingLoss(i.dtype,l)){const e=da({inputs:{x:i},backend:o});return{dataId:e.dataId,shape:e.shape,dtype:l}}if(o.shouldExecuteOnCPU([i])){const e=o.texData.get(i.dataId).values,[t,n,a]=Qt(e,i.shape,i.dtype,l);return o.makeTensorInfo(t,n,a)}if("int32"===l)return function(e,t){const n=new Qn(e.shape,"return float(int(x));"),a=t.runWebGLProgram(n,[e],"int32");return{dataId:a.dataId,shape:a.shape,dtype:a.dtype}}(i,o);if("bool"===l){const e=o.makeTensorInfo([],"bool",t.util.getTypedArrayFromDType("bool",1)),n=Gr({inputs:{a:i,b:e},backend:o});return o.disposeIntermediateTensorInfo(e),n}throw new Error(`Error in Cast: failed to cast ${i.dtype} to ${l}`)}},Kr="return ceil(x);",qr=$a({opSnippet:Kr,packedOpSnippet:Kr,cpuKernelImpl:Zt}),Yr={kernelName:t.Ceil,backendName:"webgl",kernelFunc:qr};class Qr{constructor(e){this.variableNames=["A"],this.customUniforms=[{name:"minVal",type:"float"},{name:"maxVal",type:"float"}],this.outputShape=e,this.userCode="\n\n void main() {\n float value = getAAtOutCoords();\n if (isnan(value)) {\n setOutput(value);\n return;\n }\n\n setOutput(clamp(value, minVal, maxVal));\n }\n "}}class Zr{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"minVal",type:"float"},{name:"maxVal",type:"float"}],this.outputShape=e,this.userCode="\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(minVal), vec4(maxVal)));\n }\n "}}const Jr={kernelName:t.ClipByValue,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{clipValueMin:s,clipValueMax:i}=r;let l;l=t.env().getBool("WEBGL_PACK_CLIP")?new Zr(o.shape):new Qr(o.shape);const u=[[s],[i]];return a.runWebGLProgram(l,[o],o.dtype,u)}};class eo{constructor(e){this.variableNames=["real","imag"],this.outputShape=e,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 "}}function to(e,t){return{dataId:t.dataId,dtype:t.dtype,shape:e.shape}}const no={kernelName:t.ComplexAbs,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{x:a}=t,r=n.texData.get(a.dataId),o=new eo(a.shape),s=[to(a,r.complexTensorInfos.real),to(a,r.complexTensorInfos.imag)];return n.runWebGLProgram(o,s,s[0].dtype)}};class ao{constructor(e){this.outputShape=[],this.outputShape=t.backend_util.computeOutShape(e,1),this.variableNames=e.map(((e,t)=>`T${t}`));const n=new Array(e.length-1);n[0]=e[0][1];for(let t=1;t<n.length;t++)n[t]=n[t-1]+e[t][1];const a=[`if (yC < ${n[0]}) setOutput(getT0(yR, yC));`];for(let e=1;e<n.length;e++){const t=n[e-1];a.push(`else if (yC < ${n[e]}) setOutput(getT${e}(yR, yC-${t}));`)}const r=n.length,o=n[n.length-1];a.push(`else setOutput(getT${r}(yR, yC-${o}));`),this.userCode=`\n void main() {\n ivec2 coords = getOutputCoords();\n int yR = coords.x;\n int yC = coords.y;\n\n ${a.join("\n ")}\n }\n `}}class ro{constructor(e,n){this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[],this.outputShape=t.backend_util.computeOutShape(e,n);const a=this.outputShape,r=a.length,o=Se(r),s=zn("coords",r),i=["x","y","z","w","u","v"].slice(0,r);this.variableNames=e.map(((e,t)=>`T${t}`));const l=new Array(e.length-1);l[0]=e[0][n];for(let t=1;t<l.length;t++)l[t]=l[t-1]+e[t][n];const u=i[n],c=i.slice(-2),d=i.join();let p=`if (${u} < ${l[0]}) {\n return getChannel(\n getT0(${d}), vec2(${c.join()}));\n }`;for(let e=1;e<l.length;e++){const t=l[e-1];p+=`\n if (${u} < ${l[e]} && ${u} >= ${l[e-1]}) {\n return getChannel(\n getT${e}(${oo(i,u,t)}),\n vec2(${oo(c,u,t)}));\n }`}const h=l.length,f=l[l.length-1];p+=`\n return getChannel(\n getT${h}(${oo(i,u,f)}),\n vec2(${oo(c,u,f)}));`,this.userCode=`\n float getValue(${i.map((e=>"int "+e))}) {\n ${p}\n }\n\n void main() {\n ${o} coords = getOutputCoords();\n vec4 result = vec4(getValue(${s}), 0., 0., 0.);\n\n ${s[r-1]} = ${s[r-1]} + 1;\n if (${s[r-1]} < ${a[r-1]}) {\n result.g = getValue(${s});\n }\n\n ${s[r-2]} = ${s[r-2]} + 1;\n if (${s[r-2]} < ${a[r-2]}) {\n result.a = getValue(${s});\n }\n\n ${s[r-1]} = ${s[r-1]} - 1;\n if (${s[r-2]} < ${a[r-2]} &&\n ${s[r-1]} < ${a[r-1]}) {\n result.b = getValue(${s});\n }\n setOutput(result);\n }\n `}}function oo(e,t,n){const a=e.indexOf(t);return e.map(((e,t)=>t===a?`${e} - ${n}`:e)).join()}function so(e){const{inputs:t,backend:n}=e,{input:a}=t;return da({inputs:{x:n.texData.get(a.dataId).complexTensorInfos.imag},backend:n})}const io={kernelName:t.Imag,backendName:"webgl",kernelFunc:so};function lo(e,n,a){const r=e[0].dtype;if("complex64"===r){const t=e.map((e=>Xr({inputs:{input:e},backend:a}))),r=e.map((e=>so({inputs:{input:e},backend:a}))),o=lo(t,n,a),s=lo(r,n,a),i=ha({inputs:{real:o,imag:s},backend:a});return t.forEach((e=>a.disposeIntermediateTensorInfo(e))),r.forEach((e=>a.disposeIntermediateTensorInfo(e))),a.disposeIntermediateTensorInfo(o),a.disposeIntermediateTensorInfo(s),i}let o=a.shouldExecuteOnCPU(e);if("string"===r&&(o=!0),o){const o=e.map((e=>{const r=t.util.sizeFromShape(e.shape.slice(n));return Aa({inputs:{x:e},backend:a,attrs:{shape:[-1,r]}})})),s=o.map((e=>({vals:a.readSync(e.dataId),shape:e.shape}))),i=t.backend_util.computeOutShape(o.map((e=>e.shape)),1),l=1===o[0].shape[0],u=Jt(s,i,r,l),c=t.backend_util.computeOutShape(e.map((e=>e.shape)),n),d=a.makeTensorInfo(c,r,u);return o.forEach((e=>a.disposeIntermediateTensorInfo(e))),d}const s=e.filter((e=>t.util.sizeFromShape(e.shape)>0)),i=t.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")&&s[0].shape.length>1;if(1===s.length){const t=i?new Qn(e[0].shape,Jn):new ea(e[0].shape,Jn);return a.runWebGLProgram(t,e,r)}const l=t.env().getNumber("WEBGL_MAX_TEXTURES_IN_SHADER");if(s.length>l){const e=[];for(let t=0;t<s.length;t+=l){const r=s.slice(t,t+l);e.push(lo(r,n,a))}const t=lo(e,n,a);for(const t of e)a.disposeIntermediateTensorInfo(t);return t}if(i){const e=new ro(s.map((e=>e.shape)),n);return a.runWebGLProgram(e,s,r)}const{tensors2D:u,outShape:c}=function(e,n,a){const r=t.backend_util.computeOutShape(e.map((e=>e.shape)),n);return{tensors2D:e.map((e=>Aa({inputs:{x:e},attrs:{shape:[-1,t.util.sizeFromShape(e.shape.slice(n))]},backend:a}))),outShape:r}}(s,n,a),d=new ao(u.map((e=>e.shape))),p=a.runWebGLProgram(d,u,r);u.forEach((e=>a.disposeIntermediateTensorInfo(e)));const h=Aa({inputs:{x:p},attrs:{shape:c},backend:a});return a.disposeIntermediateTensorInfo(p),h}function uo(e){const{inputs:n,backend:a,attrs:r}=e,{axis:o}=r,s=t.util.parseAxisParam(o,n[0].shape)[0],i=n.map((e=>e.shape));t.backend_util.assertParamsConsistent(i,s);const l=t.backend_util.computeOutShape(n.map((e=>e.shape)),s);if(0===t.util.sizeFromShape(l))return a.makeTensorInfo(l,n[0].dtype,[]);const u=n.filter((e=>t.util.sizeFromShape(e.shape)>0));return 1===u.length?da({inputs:{x:u[0]},backend:a}):lo(u,s,a)}const co={kernelName:t.Concat,backendName:"webgl",kernelFunc:uo};class po{constructor(e,t=!1,n=null,a=!1,r=!1){this.variableNames=["x","W"],this.outputShape=e.outShape;const o=e.padInfo.top,s=e.padInfo.left,i=e.strideHeight,l=e.strideWidth,u=e.dilationHeight,c=e.dilationWidth,d=e.filterHeight,p=e.filterWidth,h=4*Math.floor(e.inChannels/4),f=e.inChannels%4,x="channelsLast"===e.dataFormat,m=x?1:2,g=x?2:3,b=x?3:1;let v="",C="";n&&(v=a?`float activation(float a) {\n float b = getPreluActivationWeightsAtOutCoords();\n ${n}\n }`:r?`float activation(float a) {\n float b = getLeakyreluAlphaAtOutCoords();\n ${n}\n }`:`\n float activation(float x) {\n ${n}\n }\n `,C="result = activation(result);");const $=t?"result += getBiasAtOutCoords();":"";t&&this.variableNames.push("bias"),a&&this.variableNames.push("preluActivationWeights"),r&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n ${v}\n\n const ivec2 strides = ivec2(${i}, ${l});\n const ivec2 pads = ivec2(${o}, ${s});\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d2 = coords[${b}];\n\n ivec2 xRCCorner =\n ivec2(coords[${m}], coords[${g}]) * 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 < ${d}; wR++) {\n int xR = xRCorner + wR * ${u};\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int wC = 0; wC < ${p}; wC++) {\n int xC = xCCorner + wC * ${c};\n\n if (xC < 0 || xC >= ${e.inWidth}) {\n continue;\n }\n\n for (int d1 = 0; d1 < ${h}; d1 += 4) {\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 if (${x}) {\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 dotProd += dot(xValues, wValues);\n } else {\n vec4 xValues = vec4(\n getX(batch, d1, xR, xC),\n getX(batch, d1 + 1, xR, xC),\n getX(batch, d1 + 2, xR, xC),\n getX(batch, d1 + 3, xR, xC)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n\n if (${1===f}) {\n\n if (${x}) {\n dotProd +=\n getX(batch, xR, xC, ${h}) *\n getW(wR, wC, ${h}, d2);\n } else {\n dotProd +=\n getX(batch, ${h}, xR, xC) *\n getW(wR, wC, ${h}, d2);\n }\n\n } else if (${2===f}) {\n vec2 wValues = vec2(\n getW(wR, wC, ${h}, d2),\n getW(wR, wC, ${h} + 1, d2)\n );\n\n if (${x}) {\n vec2 xValues = vec2(\n getX(batch, xR, xC, ${h}),\n getX(batch, xR, xC, ${h} + 1)\n );\n dotProd += dot(xValues, wValues);\n } else {\n vec2 xValues = vec2(\n getX(batch, ${h}, xR, xC),\n getX(batch, ${h} + 1, xR, xC)\n );\n dotProd += dot(xValues, wValues);\n }\n\n } else if (${3===f}) {\n vec3 wValues = vec3(\n getW(wR, wC, ${h}, d2),\n getW(wR, wC, ${h} + 1, d2),\n getW(wR, wC, ${h} + 2, d2)\n );\n\n if (${x}) {\n vec3 xValues = vec3(\n getX(batch, xR, xC, ${h}),\n getX(batch, xR, xC, ${h} + 1),\n getX(batch, xR, xC, ${h} + 2)\n );\n dotProd += dot(xValues, wValues);\n } else {\n vec3 xValues = vec3(\n getX(batch, ${h}, xR, xC),\n getX(batch, ${h} + 1, xR, xC),\n getX(batch, ${h} + 2, xR, xC)\n );\n dotProd += dot(xValues, wValues);\n }\n\n }\n }\n }\n\n float result = dotProd;\n ${$}\n ${C}\n setOutput(result);\n }\n `}}class ho{constructor(e){this.variableNames=["x","W"],this.outputShape=e.outShape;const t=e.padInfo.front,n=e.padInfo.top,a=e.padInfo.left,r=e.strideDepth,o=e.strideHeight,s=e.strideWidth,i=e.dilationDepth,l=e.dilationHeight,u=e.dilationWidth,c=e.filterDepth,d=e.filterHeight,p=e.filterWidth,h=4*Math.floor(e.inChannels/4),f=e.inChannels%4;this.userCode=`\n const ivec3 strides = ivec3(${r}, ${o}, ${s});\n const ivec3 pads = ivec3(${t}, ${n}, ${a});\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 * ${i};\n\n if (xF < 0 || xF >= ${e.inDepth}) {\n continue;\n }\n\n for (int wR = 0; wR < ${d}; wR++) {\n int xR = xRCorner + wR * ${l};\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int wC = 0; wC < ${p}; wC++) {\n int xC = xCCorner + wC * ${u};\n\n if (xC < 0 || xC >= ${e.inWidth}) {\n continue;\n }\n\n for (int d1 = 0; d1 < ${h}; 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===f}) {\n dotProd +=\n getX(batch, xF, xR, xC, ${h}) *\n getW(wF, wR, wC, ${h}, d2);\n } else if (${2===f}) {\n vec2 xValues = vec2(\n getX(batch, xF, xR, xC, ${h}),\n getX(batch, xF, xR, xC, ${h} + 1)\n );\n vec2 wValues = vec2(\n getW(wF, wR, wC, ${h}, d2),\n getW(wF, wR, wC, ${h} + 1, d2)\n );\n dotProd += dot(xValues, wValues);\n } else if (${3===f}) {\n vec3 xValues = vec3(\n getX(batch, xF, xR, xC, ${h}),\n getX(batch, xF, xR, xC, ${h} + 1),\n getX(batch, xF, xR, xC, ${h} + 2)\n );\n vec3 wValues = vec3(\n getW(wF, wR, wC, ${h}, d2),\n getW(wF, wR, wC, ${h} + 1, d2),\n getW(wF, wR, wC, ${h} + 2, d2)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n }\n }\n setOutput(dotProd);\n }\n `}}class fo{constructor(e,n=!1,a=null,r=!1,o=!1){this.variableNames=["x","W"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"pads",type:"ivec2"},{name:"strides",type:"ivec2"},{name:"dilations",type:"ivec2"},{name:"inDims",type:"ivec2"}],this.outputShape=e.outShape,this.enableShapeUniforms=Ae(this.outputShape.length);const s=e.padInfo.left,i=e.strideWidth,l=e.dilationWidth,u=e.filterHeight,c=e.filterWidth,d=c;let p="\n int xR; int xC; int xCOffset;\n vec4 wTexel; vec4 previous; vec4 final;";for(let e=0;e<c;e++)p+=`\n vec4 xTexelC${2*e};\n int xTexelC${2*e}Ready;\n vec4 xTexelC${2*e+1};\n int xTexelC${2*e+1}Ready;\n vec4 xC${e};`;p+=`\n for (int r = 0; r < ${u}; r++) {\n for (int d1 = 0; d1 < ${e.inChannels}; d1 += 2) {\n `;for(let e=0;e<c;e++)p+=`\n xTexelC${2*e} = vec4(0.0);\n xTexelC${2*e}Ready = 0;\n xTexelC${2*e+1} = vec4(0.0);\n xTexelC${2*e+1}Ready = 0;\n xC${e} = vec4(0.0);`;p+="\n xR = xRCorner + r * dilations[0];\n if (xR >=0 && xR < inDims[0]) {\n ";for(let n=0;n<(d+1)/2;n++){const a=2*n;if(p+=`\n xC = xCCorner + ${a*l};\n `,1===i){if(a<c&&(s%2==1?(p+=`\n xCOffset = xC + 1;\n if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${a}Ready == 0) {\n xTexelC${a} = getX(batch, xR, xCOffset, d1);\n\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${a}.zw = vec2(0.0);\n }\n xTexelC${a}Ready = 1;\n }\n `,p+=1===l&&a>0?`\n xC${a} = vec4(xTexelC${a-2}.zw, xTexelC${a}.xy);\n `:`\n xCOffset = xC + 1 - 2;\n\n if (xCOffset >= 0 && xCOffset < inDims[1]) {\n previous = getX(batch, xR, xCOffset, d1);\n\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n previous.zw = vec2(0.0);\n }\n\n xC${a} = vec4(previous.zw, xTexelC${a}.xy);\n } else {\n xC${a} = vec4(0.0, 0.0, xTexelC${a}.xy);\n }\n `):p+=`\n if (xC >= 0 && xC < inDims[1] && xTexelC${a}Ready == 0) {\n xTexelC${a} = getX(batch, xR, xC, d1);\n if (xC + 1 >= inDims[1]) {\n xTexelC${a}.zw = vec2(0.0);\n }\n xTexelC${a}Ready = 1;\n }\n\n xC${a} = xTexelC${a};\n `,a+1<c)){const e=s%2==0?t.util.nearestLargerEven(l):l;l%2==0&&s%2==1||l%2!=0&&s%2!=1?(p+=`\n xCOffset = xC + imod(pads[1], 2) + ${e};\n\n if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${a+1}Ready == 0) {\n xTexelC${a+1} = getX(batch, xR, xCOffset, d1);\n\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${a+1}.zw = vec2(0.0);\n }\n xTexelC${a+1}Ready = 1;\n }\n `,p+=l>1?`\n xCOffset -= 2;\n if (xCOffset >= 0 && xCOffset < inDims[1]) {\n previous = getX(batch, xR, xCOffset, d1);\n xC${a+1} = vec4(previous.zw, xTexelC${a+1}.xy);\n } else {\n xC${a+1} = vec4(0.0, 0.0, xTexelC${a+1}.xy);\n }\n `:`\n xC${a+1} = vec4(xTexelC${a}.zw, xTexelC${a+1}.xy);\n `):p+=1===e?`\n xC${a+1} = xTexelC${a};\n `:`\n xCOffset = xC + ${e};\n\n if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${a+1}Ready == 0) {\n xTexelC${a+1} = getX(batch, xR, xCOffset, d1);\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${a+1}.zw = vec2(0.0);\n }\n xTexelC${a+1}Ready = 1;\n }\n\n xC${a+1} = xTexelC${a+1};\n `}}else a<c&&(s%2==1?(p+=`\n xCOffset = xC + 1 - strides[1];\n if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${a}Ready == 0) {\n xTexelC${a} = getX(batch, xR, xCOffset, d1);\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${a}.zw = vec2(0.0);\n }\n xTexelC${a}Ready = 1;\n }\n\n if(xC + 1 >= 0 && xC + 1 < inDims[1] && xTexelC${a+1}Ready == 0) {\n xTexelC${a+1} = getX(batch, xR, xC + 1, d1);\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xC + 2 >= inDims[1]) {\n xTexelC${a+1}.zw = vec2(0.0);\n }\n xTexelC${a+1}Ready = 1;\n }\n\n xC${a} = vec4(xTexelC${a}.zw, xTexelC${a+1}.zw);\n `,a+1<c&&(p+=`\n final = vec4(0.0);\n xCOffset = xC + 1 + strides[1];\n if(xCOffset >= 0 && xCOffset < inDims[1]) {\n final = getX(batch, xR, xCOffset, d1);\n }\n xC${a+1} = vec4(xTexelC${a+1}.xy, final.xy);\n `)):(p+=`\n if(xC >= 0 && xC < inDims[1] && xTexelC${a}Ready == 0) {\n xTexelC${a} = getX(batch, xR, xC, d1);\n if (xC + 1 >= inDims[1]) {\n xTexelC${a}.zw = vec2(0.0);\n }\n xTexelC${a}Ready = 1;\n }\n\n xCOffset = xC + strides[1];\n if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${a+1}Ready == 0) {\n xTexelC${a+1} = getX(batch, xR, xCOffset, d1);\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${a+1}.zw = vec2(0.);\n }\n xTexelC${a+1}Ready = 1;\n }\n\n xC${a} = vec4(\n xTexelC${a}.xy, xTexelC${a+1}.xy);\n `,a+1<c&&(p+=`\n xC${a+1} = vec4(xTexelC${a}.zw, xTexelC${a+1}.zw);\n `)));a<c&&(p+=`\n wTexel = getW(r, ${a}, d1, d2);\n dotProd += xC${a}.xxzz * vec4(wTexel.xy, wTexel.xy);\n if(d1 + 1 < ${e.inChannels}) {\n dotProd += xC${a}.yyww * vec4(wTexel.zw, wTexel.zw);\n }\n `,a+1<c&&(p+=`\n wTexel = getW(r, ${a+1}, d1, d2);\n dotProd += xC${a+1}.xxzz * vec4(wTexel.xy, wTexel.xy);\n if(d1 + 1 < ${e.inChannels}) {\n dotProd += xC${a+1}.yyww * vec4(wTexel.zw, wTexel.zw);\n }\n `))}p+="\n }\n ",p+="\n }\n ",p+="\n }\n ";let h="",f="";a&&(h=r?`vec4 activation(vec4 a) {\n vec4 b = getPreluActivationWeightsAtOutCoords();\n ${a}\n }`:o?`vec4 activation(vec4 a) {\n vec4 b = getLeakyreluAlphaAtOutCoords();\n ${a}\n }`:`vec4 activation(vec4 x) {\n ${a}\n }`,f="result = activation(result);");const x=n?"result += getBiasAtOutCoords();":"";n&&this.variableNames.push("bias"),r&&this.variableNames.push("preluActivationWeights"),o&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n ${h}\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 xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n //intialize dotProd with a small epsilon seems to reduce GPU accuracy loss.\n vec4 dotProd = vec4(0.000000000000001);\n\n ${p}\n\n vec4 result = dotProd - vec4(0.000000000000001);\n ${x}\n ${f}\n setOutput(result);\n }\n `}}class xo{constructor(e,t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"inputShape",type:"ivec4"},{name:"pad",type:"ivec2"},{name:"stride",type:"ivec2"},{name:"dilation",type:"ivec2"},{name:"inChannels",type:"int"},{name:"itemsPerBlockRow",type:"int"},{name:"outWidth",type:"int"}],this.outputShape=e,this.enableShapeUniforms=Ae(this.outputShape.length);const{dataFormat:n}=t,a=le(),r="channelsLast"===n,o=r?1:2,s=r?2:3,i=this.enableShapeUniforms?"if(blockIndex < outShape[2] && pos < outShape[1]) {":`if(blockIndex < ${e[2]} && pos < ${e[1]}) {`;let l="";for(let e=0;e<=1;e++)for(let t=0;t<=1;t++)l+=`\n blockIndex = rc.z + ${t};\n pos = rc.y + ${e};\n\n ${i}\n offsetY = int(blockIndex / outWidth) * stride[0] - pad[0];\n d0 = offsetY + dilation[0] * (pos / itemsPerBlockRow);\n\n if(d0 < inputShape[${o}] && d0 >= 0) {\n // Use custom imod instead mod. On Intel GPU, mod may generate\n // unexpected value.\n // https://github.com/tensorflow/tfjs/issues/5447\n offsetX = imod(blockIndex, outWidth) * stride[1] - pad[1];\n d1 = offsetX + dilation[1] * (imod(pos, itemsPerBlockRow) /\n inChannels);\n\n if(d1 < inputShape[${s}] && d1 >= 0) {\n\n ch = imod(pos, inChannels);\n\n if (${r}) {\n innerDims = vec2(d1, ch);\n result[${2*e+t}] = getChannel(\n getA(rc.x, d0, int(innerDims.x),\n int(innerDims.y)), innerDims);\n } else {\n innerDims = vec2(d0, d1);\n result[${2*e+t}] = getChannel(\n getA(rc.x, ch, int(innerDims.x),\n int(innerDims.y)), innerDims);\n }\n }\n }\n }\n `;this.userCode=`\n void main() {\n ivec3 rc = getOutputCoords();\n\n vec4 result = vec4(0);\n\n int blockIndex, pos, offsetY, d0, offsetX, d1, ch;\n vec2 innerDims;\n\n ${l}\n\n ${a.output} = result;\n }\n `}}function mo(e,t){const n=e.length;return n>=3?t?[...e.slice(0,-3),e[n-3]*e[n-2],e[n-1]]:[...e.slice(0,-3),e[n-3],e[n-2]*e[n-1]]:!t&&1===n&&e[0]>1?[e[0],1]:null}function go({x:e,filter:n,convInfo:a,backend:r,bias:o=null,preluActivationWeights:s=null,leakyreluAlpha:i=0,activation:l=null}){const u=e.shape,c=r.texData.get(e.dataId),d=a.inChannels,p=u[0]*u[1]*u[2],h=a.outChannels,f="channelsLast"===a.dataFormat;let x;const m=[];if(null!=s){const e=mo(s.shape,f);null!=e&&(s=Aa({inputs:{x:s},backend:r,attrs:{shape:e}}),m.push(s))}if(null!=o){const e=mo(o.shape,f);null!=e&&(o=Aa({inputs:{x:o},backend:r,attrs:{shape:e}}),m.push(o))}if(!((1===p||1===h)&&d>1e3)&&c.isPacked&&f&&null!=c.texture&&u[2]%2!=0&&t.util.arraysEqual(c.shape.slice(-3),u.slice(-3))){const d=u[0]*u[1]*(u[2]+1),p={dataId:e.dataId,shape:[1,d,a.inChannels],dtype:e.dtype},h=c.shape;c.shape=c.shape.slice(),c.shape[c.shape.length-2]++,t.util.assert(j(c.shape,p.shape),(()=>`packed reshape ${c.shape} to ${p.shape} isn't free`));const f=Aa({inputs:{x:n},backend:r,attrs:{shape:[1,a.inChannels,a.outChannels]}});m.push(f);const g=Ga({a:p,b:f,backend:r,transposeA:false,transposeB:false,bias:o,activation:l,preluActivationWeights:s,leakyreluAlpha:i}),b=r.texData.get(g.dataId);t.util.assert(b.isPacked,(()=>"batchMatMul result is expected to be packed")),c.shape=h,b.shape=a.outShape,x=da({inputs:{x:g},backend:r}),x.shape=a.outShape,m.push(g)}else{const t=a.outHeight*a.outWidth,u=Aa({inputs:{x:e},backend:r,attrs:{shape:f?[a.batchSize,t,a.inChannels]:[a.batchSize,a.inChannels,t]}}),c=Aa({inputs:{x:n},backend:r,attrs:{shape:[1,a.inChannels,a.outChannels]}}),d=Ga({a:f?u:c,b:f?c:u,transposeA:!f,transposeB:false,backend:r,bias:o,activation:l,preluActivationWeights:s,leakyreluAlpha:i});x=Aa({inputs:{x:d},backend:r,attrs:{shape:a.outShape}}),m.push(u),m.push(c),m.push(d)}for(const e of m)r.disposeIntermediateTensorInfo(e);return x}function bo({x:e,filter:n,convInfo:a,backend:r,bias:o=null,preluActivationWeights:s=null,leakyreluAlpha:i=0,activation:l=null}){const{filterWidth:u,filterHeight:c,inChannels:d,outWidth:p,outHeight:h,dataFormat:f}=a,x="channelsLast"===f,m=u*c*d,g=h*p,b=[a.batchSize,m,g],v=[];if(null!=s){const e=mo(s.shape,x);null!=e&&(s=Aa({inputs:{x:s},backend:r,attrs:{shape:e}}),v.push(s))}if(null!=o){const e=mo(o.shape,x);null!=e&&(o=Aa({inputs:{x:o},backend:r,attrs:{shape:e}}),v.push(o))}const C=Aa({inputs:{x:n},backend:r,attrs:{shape:[1,m,t.util.sizeFromShape(n.shape)/m]}});v.push(C);const $=new xo(b,a),y=[e.shape,[a.padInfo.top,a.padInfo.left],[a.strideHeight,a.strideWidth],[a.dilationHeight,a.dilationWidth],[a.inChannels],[a.filterWidth*a.inChannels],[a.outWidth]],I=r.runWebGLProgram($,[e],"float32",y),w=Aa({inputs:{x:I},backend:r,attrs:{shape:b}});v.push(I),v.push(w);const S=null!=o,k=null!=s,R="leakyrelu"===l,T=l?Ia(l,!0):null,N=new wa(x?w.shape:C.shape,x?C.shape:w.shape,x?[a.batchSize,g,a.outChannels]:[a.batchSize,a.outChannels,g],!0,!1,S,T,k,R),E=x?[w,C]:[C,w];if(o&&E.push(o),k&&E.push(s),R){const e=r.makeTensorInfo([],"float32",t.util.createScalarValue(i,"float32"));E.push(e),v.push(e)}const A=r.runWebGLProgram(N,E,"float32"),_=Aa({inputs:{x:A},backend:r,attrs:{shape:a.outShape}});v.push(A);for(const e of v)r.disposeIntermediateTensorInfo(e);return _}const vo={kernelName:t.Conv2D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,filter:s}=n,{strides:i,pad:l,dataFormat:u,dilations:c,dimRoundingMode:d}=r,p=t.backend_util.convertConv2DDataFormat(u),h=t.backend_util.computeConv2DInfo(o.shape,s.shape,i,c,l,d,!1,p);let f;if(1!==h.filterHeight||1!==h.filterWidth||1!==h.dilationHeight||1!==h.dilationWidth||1!==h.strideHeight||1!==h.strideWidth||"SAME"!==h.padInfo.type&&"VALID"!==h.padInfo.type)if(h.strideWidth<=2&&"channelsLast"===p&&t.env().getBool("WEBGL_EXP_CONV")){const e=new fo(h),t=[[h.padInfo.top,h.padInfo.left],[h.strideHeight,h.strideWidth],[h.dilationHeight,h.dilationWidth],[h.inHeight,h.inWidth]];f=a.runWebGLProgram(e,[o,s],"float32",t)}else if(t.env().getBool("WEBGL_CONV_IM2COL"))f=bo({x:o,filter:s,convInfo:h,backend:a});else{const e=new po(h);f=a.runWebGLProgram(e,[o,s],"float32")}else f=go({x:o,filter:s,convInfo:h,backend:a});const x=Aa({inputs:{x:f},backend:a,attrs:{shape:h.outShape}});return a.disposeIntermediateTensorInfo(f),x}};class Co{constructor(e){this.variableNames=["x","dy"],this.outputShape=e.filterShape;const t=e.strideHeight,n=e.strideWidth,a=e.padInfo.top,r=e.padInfo.left,o="channelsLast"===e.dataFormat;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 d2 = coords.w;\n\n // Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int b = 0; b < ${e.batchSize}; b++) {\n for (int yR = 0; yR < ${e.outHeight}; yR++) {\n int xR = wR + yR * ${t} - ${a};\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int yC = 0; yC < ${e.outWidth}; yC++) {\n int xC = wC + yC * ${n} - ${r};\n\n if (xC < 0 || xC >= ${e.inWidth}) {\n continue;\n }\n\n ${o?"float dyValue = getDy(b, yR, yC, d2);\n float xValue = getX(b, xR, xC, d1);\n dotProd += (xValue * dyValue);":"float dyValue = getDy(b, d2, yR, yC);\n float xValue = getX(b, d1, xR, xC);\n dotProd += (xValue * dyValue);"}\n }\n }\n }\n setOutput(dotProd);\n }\n `}}class $o{constructor(e){this.variableNames=["dy","W"],this.outputShape=e.inShape;const t=e.filterHeight,n=e.filterWidth,a=e.strideHeight,r=e.strideWidth,o="channelsLast"===e.dataFormat,s=t-1-e.padInfo.top,i=n-1-e.padInfo.left,l=o?1:2,u=o?2:3,c=o?3:1;this.userCode=`\n const ivec2 pads = ivec2(${s}, ${i});\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords[${c}];\n\n ivec2 dyCorner = ivec2(coords[${l}], coords[${u}]) - 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 < ${t}; wR++) {\n float dyR = float(dyRCorner + wR) / ${a}.0;\n\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = ${t} - 1 - wR;\n\n for (int wC = 0; wC < ${n}; wC++) {\n float dyC = float(dyCCorner + wC) / ${r}.0;\n\n if (dyC < 0.0 || dyC >= ${e.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 < ${e.outChannels}; d2++) {\n\n if (${o}) {\n float xValue = getDy(batch, idyR, idyC, d2);\n float wValue = getW(wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n } else {\n float xValue = getDy(batch, d2, idyR, idyC);\n float wValue = getW(wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n }\n\n }\n }\n }\n setOutput(dotProd);\n }\n `}}class yo{constructor(e){this.variableNames=["x","dy"],this.outputShape=e.filterShape;const t=e.strideDepth,n=e.strideHeight,a=e.strideWidth,r=e.padInfo.front,o=e.padInfo.top,s=e.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 < ${e.batchSize}; b++) {\n for (int yF = 0; yF < ${e.outDepth}; yF++) {\n int xF = wF + yF * ${t} - ${r};\n\n if (xF < 0 || xF >= ${e.inDepth}) {\n continue;\n }\n\n for (int yR = 0; yR < ${e.outHeight}; yR++) {\n int xR = wR + yR * ${n} - ${o};\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int yC = 0; yC < ${e.outWidth}; yC++) {\n int xC = wC + yC * ${a} - ${s};\n\n if (xC < 0 || xC >= ${e.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 `}}class Io{constructor(e){this.variableNames=["dy","W"],this.outputShape=e.inShape;const t=e.filterDepth,n=e.filterHeight,a=e.filterWidth,r=e.strideDepth,o=e.strideHeight,s=e.strideWidth,i=t-1-e.padInfo.front,l=n-1-e.padInfo.top,u=a-1-e.padInfo.left;this.userCode=`\n const ivec3 pads = ivec3(${i}, ${l}, ${u});\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 < ${t}; wF++) {\n float dyF = float(dyFCorner + wF) / ${r}.0;\n\n if (dyF < 0.0 || dyF >= ${e.outDepth}.0 || fract(dyF) > 0.0) {\n continue;\n }\n int idyF = int(dyF);\n\n int wFPerm = ${t} - 1 - wF;\n\n for (int wR = 0; wR < ${n}; wR++) {\n float dyR = float(dyRCorner + wR) / ${o}.0;\n\n if (dyR < 0.0 || dyR >= ${e.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 < ${a}; wC++) {\n float dyC = float(dyCCorner + wC) / ${s}.0;\n\n if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = ${a} - 1 - wC;\n\n for (int d2 = 0; d2 < ${e.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 `}}const wo={kernelName:t.Conv2DBackpropFilter,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,dy:s}=n,{strides:i,pad:l,dataFormat:u,dimRoundingMode:c,filterShape:d}=r,p=t.backend_util.convertConv2DDataFormat(u),h=t.backend_util.computeConv2DInfo(o.shape,d,i,1,l,c,!1,p),f=new Co(h);return a.runWebGLProgram(f,[o,s],"float32")}};class So{constructor(e){this.variableNames=["dy","W"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"strides",type:"vec2"}],this.outputShape=e.inShape,this.enableShapeUniforms=Ae(this.outputShape.length);const t=e.filterHeight,n=e.filterWidth,a=t-1-e.padInfo.top,r=n-1-e.padInfo.left;this.userCode=`\n const ivec2 pads = ivec2(${a}, ${r});\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords[3];\n\n ivec2 dyCorner = ivec2(coords[1], coords[2]) - pads;\n int dyRCorner = dyCorner.x;\n int dyCCorner = dyCorner.y;\n\n vec4 result = vec4(0.);\n for (int wR = 0; wR < ${t}; wR++) {\n float dyR = float(dyRCorner + wR) / strides[0];\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n int wRPerm = ${t} - 1 - wR;\n\n for (int wC = 0; wC < ${n}; wC++) {\n int wCPerm = ${n} - 1 - wC;\n\n float dyC = float(dyCCorner + wC) / strides[1];\n bool idyCVal = (dyC >= 0.0) && (dyC < ${e.outWidth}.0)\n && (fract(dyC) == 0.0);\n int idyC = int(dyC);\n\n float dyC2 = float(dyCCorner + wC + 1) / strides[1];\n bool idyCVal2 = (dyC2 >= 0.0) && (dyC2 < ${e.outWidth}.0)\n && (fract(dyC2) == 0.0);\n int idyC2 = int(dyC2);\n\n if (idyCVal && idyCVal2) {\n for (int d2 = 0; d2 < ${e.outChannels}; d2 += 2) {\n vec4 wValue = getW(wRPerm, wCPerm, d1, d2);\n vec4 dySample = getDy(batch, idyR, idyC, d2);\n vec4 dySample2 = (idyC / 2 == idyC2 / 2) ?\n dySample : getDy(batch, idyR, idyC2, d2);\n\n vec2 dyValue = mod(float(idyC), 2.) == 0. ?\n dySample.xy : dySample.zw;\n result.xy += vec2(dot(dyValue, wValue.xy),\n dot(dyValue, wValue.zw));\n\n dyValue = mod(float(idyC2), 2.) == 0. ?\n dySample2.xy : dySample2.zw;\n result.zw += vec2(dot(dyValue, wValue.xy),\n dot(dyValue, wValue.zw));\n }\n } else if (idyCVal) {\n for (int d2 = 0; d2 < ${e.outChannels}; d2 += 2) {\n vec4 wValue = getW(wRPerm, wCPerm, d1, d2);\n vec4 dySample = getDy(batch, idyR, idyC, d2);\n vec2 dyValue = mod(float(idyC), 2.) == 0. ?\n dySample.xy : dySample.zw;\n result.xy += vec2(dot(dyValue, wValue.xy),\n dot(dyValue, wValue.zw));\n }\n } else if (idyCVal2) {\n for (int d2 = 0; d2 < ${e.outChannels}; d2 += 2) {\n vec4 wValue = getW(wRPerm, wCPerm, d1, d2);\n vec4 dySample = getDy(batch, idyR, idyC2, d2);\n vec2 dyValue = mod(float(idyC2), 2.) == 0. ?\n dySample.xy : dySample.zw;\n result.zw += vec2(dot(dyValue, wValue.xy),\n dot(dyValue, wValue.zw));\n }\n }\n }\n }\n setOutput(result);\n }\n `}}const ko={kernelName:t.Conv2DBackpropInput,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,filter:s}=n,{inputShape:i,strides:l,pad:u,dataFormat:c,dimRoundingMode:d}=r,p=t.backend_util.convertConv2DDataFormat(c),h=t.backend_util.computeConv2DInfo(i,s.shape,l,1,u,d,!1,p);if(t.env().getBool("WEBGL_PACK_CONV2DTRANSPOSE")&&"channelsLast"===p){const e=[[h.strideHeight,h.strideWidth]],t=new So(h);return a.runWebGLProgram(t,[o,s],"float32",e)}{const e=new $o(h);return a.runWebGLProgram(e,[o,s],"float32")}}};const Ro={kernelName:t.Conv3D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,filter:s}=n,{strides:i,pad:l,dilations:u}=r,c=t.backend_util.computeConv3DInfo(o.shape,s.shape,i,u,l),d=new ho(c);return a.runWebGLProgram(d,[o,s],"float32")}};const To={kernelName:t.Conv3DBackpropFilterV2,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,dy:s}=n,{strides:i,pad:l,filterShape:u}=r,c=t.backend_util.computeConv3DInfo(o.shape,u,i,1,l),d=new yo(c);return a.runWebGLProgram(d,[o,s],"float32")}};const No={kernelName:t.Conv3DBackpropInputV2,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,filter:s}=n,{pad:i,strides:l,inputShape:u}=r,c=t.backend_util.computeConv3DInfo(u,s.shape,l,1,i),d=new Io(c);return a.runWebGLProgram(d,[o,s],"float32")}},Eo=$a({opSnippet:"if (isnan(x)) return x;\n return cos(x);\n",packedOpSnippet:`\n vec4 result = cos(x);\n bvec4 isNaN = isnan(x);\n ${ua}\n return result;\n`}),Ao={kernelName:t.Cos,backendName:"webgl",kernelFunc:Eo},_o=$a({opSnippet:"\n float e2x = exp(-x);\n return (e2x + 1.0 / e2x) / 2.0;\n"}),Oo={kernelName:t.Cosh,backendName:"webgl",kernelFunc:_o};class Fo{constructor(e,t,n,a,r){this.variableNames=["Image","Boxes","BoxInd"],this.outputShape=[];const[o,s,i,l]=e,[u]=t,[c,d]=n;this.outputShape=[u,c,d,l];const p="bilinear"===a?1:0,[h,f]=[s-1+".0",i-1+".0"],[x,m,g]=c>1?[""+(s-1)/(c-1),"(y2-y1) * height_ratio",`y1*${h} + float(y)*(height_scale)`]:["0.0","0.0",`0.5 * (y1+y2) * ${h}`],[b,v,C]=d>1?[""+(i-1)/(d-1),"(x2-x1) * width_ratio",`x1*${f} + float(x)*(width_scale)`]:["0.0","0.0",`0.5 * (x1+x2) * ${f}`];this.userCode=`\n const float height_ratio = float(${x});\n const float width_ratio = float(${b});\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 >= ${o}) {\n return;\n }\n\n float height_scale = ${m};\n float width_scale = ${v};\n\n float in_y = ${g};\n if( in_y < 0.0 || in_y > ${h} ) {\n setOutput(float(${r}));\n return;\n }\n float in_x = ${C};\n if( in_x < 0.0 || in_x > ${f} ) {\n setOutput(float(${r}));\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 `}}const Do={kernelName:t.CropAndResize,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:n,attrs:a}=e,{image:r,boxes:o,boxInd:s}=t,{cropSize:i,method:l,extrapolationValue:u}=a,c=new Fo(r.shape,o.shape,i,l,u);return n.runWebGLProgram(c,[r,o,s],"float32")}};var Po;!function(e){e.Prod="*",e.Sum="+"}(Po||(Po={}));class Lo{constructor(e,t,n,a){this.op=e,this.outputShape=t,this.variableNames=["x"],this.customUniforms=[{name:"index",type:"float"}];const r=this.outputShape.length,o=this.op===Po.Prod?"1.0":"0.0",s=n?o:`getX(${Bo(r,"coords",this.op)})`,i=this.outputShape[this.outputShape.length-1];let l="",u="";n?(l=a?"end != "+(i-1):"end != 0",u=a?"end + 1":"end - 1"):(l=a?`end + pow2 < ${i}`:"end >= pow2",u=a?"end + pow2":"end - pow2"),this.userCode=`\n void main() {\n ${Se(r)} coords = getOutputCoords();\n int end = ${Vo(r,"coords",this.op)};\n float val = ${s};\n int pow2 = int(pow(2.0, index));\n if (${l}) {\n int idx = ${u};\n ${Vo(r,"coords",this.op)} = idx;\n val ${this.op}= getX(${Bo(r,"coords",this.op)});\n }\n setOutput(val);\n }\n `}}function Bo(e,t,n){if(1===e)return`${t}`;if(2===e)return`${t}.x, ${t}.y`;if(3===e)return`${t}.x, ${t}.y, ${t}.z`;if(4===e)return`${t}.x, ${t}.y, ${t}.z, ${t}.w`;throw new Error(`Cumulative ${n} for rank ${e} is not yet supported`)}function Vo(e,t,n){if(1===e)return`${t}`;if(2===e)return`${t}.y`;if(3===e)return`${t}.z`;if(4===e)return`${t}.w`;throw new Error(`Cumulative ${n} for rank ${e} is not yet supported`)}function Wo(e,n,a,r,o,s){const i=n.shape.length,l=t.backend_util.getAxesPermutation([r],i);let u=n;null!=l&&(u=Ua({inputs:{x:n},backend:a,attrs:{perm:l}}));const c=t.backend_util.getInnerMostAxes(1,i)[0];if(c!==i-1)throw new Error(`WebGL cumprod shader expects an inner-most axis=${n.shape.length-1} but got axis=${r}`);const d=u.shape[c];let p=da({inputs:{x:u},backend:a});for(let t=0;t<=Math.ceil(Math.log2(d))-1;t++){const n=new Lo(e,u.shape,!1,s),r=[[t]],o=p;p=a.runWebGLProgram(n,[p],p.dtype,r),a.disposeIntermediateTensorInfo(o)}if(o){const t=new Lo(e,u.shape,o,s),n=p;p=a.runWebGLProgram(t,[p],p.dtype),a.disposeIntermediateTensorInfo(n)}if(null!=l){const e=Ua({inputs:{x:p},backend:a,attrs:{perm:t.backend_util.getUndoAxesPermutation(l)}});return a.disposeIntermediateTensorInfo(p),a.disposeIntermediateTensorInfo(u),e}return p}const Uo={kernelName:t.Cumprod,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{x:r}=t,{axis:o,exclusive:s,reverse:i}=a;return Wo(Po.Prod,r,n,o,s,i)}};const Mo={kernelName:t.Cumsum,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{x:r}=t,{axis:o,exclusive:s,reverse:i}=a;return Wo(Po.Sum,r,n,o,s,i)}};const Go={kernelName:t.DenseBincount,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{x:r,weights:o}=t,{size:s,binaryOutput:i}=a;if(1===r.shape.length){const e=n.readSync(r.dataId),t=n.readSync(o.dataId),a=Kt(e,t,o.dtype,o.shape,s);return n.makeTensorInfo([s],o.dtype,a)}if(2===r.shape.length){const e=n.bufferSync(r),t=n.bufferSync(o),a=qt(e,t,s,i);return n.makeTensorInfo(a.shape,o.dtype,a.values)}throw new Error(`Error in denseBincount: input must be at most rank 2, but got rank${r.shape.length}.`)}};class zo{constructor(e,t,n){this.variableNames=["x"],this.outputShape=[],this.outputShape=e,this.blockSize=t,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 / ${t};\n int offset_h = imod(h, ${t});\n int in_w = w / ${t};\n int offset_w = imod(w, ${t});\n int offset_d = (offset_h * ${t} + offset_w) *\n ${this.getOutputDepthSize()};\n int in_d = d + offset_d;\n\n float result = ${this.getInputSamplingString()};\n setOutput(result);\n }\n `}getHeightCoordString(){return"NHWC"===this.dataFormat?"coords[1]":"coords[2]"}getWidthCoordString(){return"NHWC"===this.dataFormat?"coords[2]":"coords[3]"}getDepthCoordString(){return"NHWC"===this.dataFormat?"coords[3]":"coords[1]"}getOutputDepthSize(){return"NHWC"===this.dataFormat?this.outputShape[3]:this.outputShape[1]}getInputSamplingString(){return"NHWC"===this.dataFormat?"getX(b, in_h, in_w, in_d)":"getX(b, in_d, in_h, in_w)"}}const Xo={kernelName:t.DepthToSpace,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{x:r}=t,{blockSize:o,dataFormat:s}=a,i=r.shape[0],l=("NHWC"===s?r.shape[1]:r.shape[2])*o,u=("NHWC"===s?r.shape[2]:r.shape[3])*o,c=("NHWC"===s?r.shape[3]:r.shape[1])/(o*o),d=new zo("NHWC"===s?[i,l,u,c]:[i,c,l,u],o,s);return n.runWebGLProgram(d,[r],r.dtype)}};class Ho{constructor(e,t=!1,n=null,a=!1,r=!1){this.variableNames=["x","W"],this.customUniforms=[{name:"pads",type:"ivec2"},{name:"strides",type:"ivec2"},{name:"dilations",type:"ivec2"},{name:"inDims",type:"ivec2"}],this.outputShape=e.outShape,this.enableShapeUniforms=Ae(this.outputShape.length);const o=e.filterHeight,s=e.filterWidth,i=e.outChannels/e.inChannels;let l="",u="";n&&(l=a?`float activation(float a) {\n float b = getPreluActivationWeightsAtOutCoords();\n ${n}\n }`:r?`float activation(float a) {\n float b = getLeakyreluAlphaAtOutCoords();\n ${n}\n }`:`\n float activation(float x) {\n ${n}\n }\n `,u="result = activation(result);");const c=t?"result += getBiasAtOutCoords();":"";t&&this.variableNames.push("bias"),a&&this.variableNames.push("preluActivationWeights"),r&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n ${l}\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 / ${i};\n int q = d2 - d1 * ${i};\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 // TO DO(dsmilkov): Flatten the two for loops and vec4 the operations.\n for (int wR = 0; wR < ${o}; wR++) {\n int xR = xRCorner + wR * dilations[0];\n\n if (xR < 0 || xR >= inDims[0]) {\n continue;\n }\n\n for (int wC = 0; wC < ${s}; wC++) {\n int xC = xCCorner + wC * dilations[1];\n\n if (xC < 0 || xC >= inDims[1]) {\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\n float result = dotProd;\n ${c}\n ${u}\n setOutput(result);\n }\n `}}class jo{constructor(e,n=!1,a=null,r=!1,o=!1){this.variableNames=["x","W"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"pads",type:"ivec2"},{name:"strides",type:"ivec2"},{name:"dilations",type:"ivec2"},{name:"inDims",type:"ivec2"}],this.outputShape=e.outShape,this.enableShapeUniforms=Ae(this.outputShape.length);const s=e.outChannels/e.inChannels,i=e.padInfo.left,l=e.strideWidth,u=e.dilationWidth,c=e.filterHeight,d=e.filterWidth,p=d;let h="\n int xR; int xC; int xCOffset;\n vec4 wTexel; vec4 previous; vec4 final;";for(let e=0;e<d;e++)h+=`\n vec4 xTexelC${2*e};\n int xTexelC${2*e}Ready;\n vec4 xTexelC${2*e+1};\n int xTexelC${2*e+1}Ready;\n vec4 xC${e};`;h+=`\n for (int r = 0; r < ${c}; r++) {\n `;for(let e=0;e<d;e++)h+=`\n xTexelC${2*e} = vec4(0.0);\n xTexelC${2*e}Ready = 0;\n xTexelC${2*e+1} = vec4(0.0);\n xTexelC${2*e+1}Ready = 0;\n xC${e} = vec4(0.0);`;h+="\n xR = xRCorner + r * dilations[0];\n if (xR >=0 && xR < inDims[0]) {\n ";for(let e=0;e<(p+1)/2;e++){const n=2*e;if(h+=`\n xC = xCCorner + ${n*u};\n `,1===l){if(n<d&&(i%2==1?(h+=`\n xCOffset = xC + 1;\n if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${n}Ready == 0) {\n xTexelC${n} = getX(batch, xR, xCOffset, d1);\n\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${n}.zw = vec2(0.0);\n }\n xTexelC${n}Ready = 1;\n }\n `,h+=1===u&&n>0?`\n xC${n} = vec4(xTexelC${n-2}.zw, xTexelC${n}.xy);\n `:`\n xCOffset = xC + 1 - 2;\n\n if (xCOffset >= 0 && xCOffset < inDims[1]) {\n previous = getX(batch, xR, xCOffset, d1);\n\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n previous.zw = vec2(0.0);\n }\n\n xC${n} = vec4(previous.zw, xTexelC${n}.xy);\n } else {\n xC${n} = vec4(0.0, 0.0, xTexelC${n}.xy);\n }\n `):h+=`\n if (xC >= 0 && xC < inDims[1] && xTexelC${n}Ready == 0) {\n xTexelC${n} = getX(batch, xR, xC, d1);\n if (xC + 1 >= inDims[1]) {\n xTexelC${n}.zw = vec2(0.0);\n }\n xTexelC${n}Ready = 1;\n }\n\n xC${n} = xTexelC${n};\n `,n+1<d)){const e=i%2==0?t.util.nearestLargerEven(u):u;u%2==0&&i%2==1||u%2!=0&&i%2!=1?(h+=`\n xCOffset = xC + imod(pads[1], 2) + ${e};\n\n if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${n+1}Ready == 0) {\n xTexelC${n+1} = getX(batch, xR, xCOffset, d1);\n\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${n+1}.zw = vec2(0.0);\n }\n xTexelC${n+1}Ready = 1;\n }\n `,h+=u>1?`\n xCOffset -= 2;\n if (xCOffset >= 0 && xCOffset < inDims[1]) {\n previous = getX(batch, xR, xCOffset, d1);\n xC${n+1} = vec4(previous.zw, xTexelC${n+1}.xy);\n } else {\n xC${n+1} = vec4(0.0, 0.0, xTexelC${n+1}.xy);\n }\n `:`\n xC${n+1} = vec4(xTexelC${n}.zw, xTexelC${n+1}.xy);\n `):h+=1===e?`\n xC${n+1} = xTexelC${n};\n `:`\n xCOffset = xC + ${e};\n\n if (xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${n+1}Ready == 0) {\n xTexelC${n+1} = getX(batch, xR, xCOffset, d1);\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${n+1}.zw = vec2(0.0);\n }\n xTexelC${n+1}Ready = 1;\n }\n\n xC${n+1} = xTexelC${n+1};\n `}}else n<d&&(i%2==1?(h+=`\n xCOffset = xC + 1 - strides[1];\n if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${n}Ready == 0) {\n xTexelC${n} = getX(batch, xR, xCOffset, d1);\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${n}.zw = vec2(0.0);\n }\n xTexelC${n}Ready = 1;\n }\n\n if(xC + 1 >= 0 && xC + 1 < inDims[1] && xTexelC${n+1}Ready == 0) {\n xTexelC${n+1} = getX(batch, xR, xC + 1, d1);\n // Need to manually clear unused channels in case\n // we're reading from recycled texture.\n if (xC + 2 >= inDims[1]) {\n xTexelC${n+1}.zw = vec2(0.0);\n }\n xTexelC${n+1}Ready = 1;\n }\n\n xC${n} = vec4(xTexelC${n}.zw, xTexelC${n+1}.zw);\n `,n+1<d&&(h+=`\n final = vec4(0.0);\n xCOffset = xC + 1 + strides[1];\n if(xCOffset >= 0 && xCOffset < inDims[1]) {\n final = getX(batch, xR, xCOffset, d1);\n }\n xC${n+1} = vec4(xTexelC${n+1}.xy, final.xy);\n `)):(h+=`\n if(xC >= 0 && xC < inDims[1] && xTexelC${n}Ready == 0) {\n xTexelC${n} = getX(batch, xR, xC, d1);\n if (xC + 1 >= inDims[1]) {\n xTexelC${n}.zw = vec2(0.0);\n }\n xTexelC${n}Ready = 1;\n }\n\n xCOffset = xC + strides[1];\n if(xCOffset >= 0 && xCOffset < inDims[1] && xTexelC${n+1}Ready == 0) {\n xTexelC${n+1} = getX(batch, xR, xCOffset, d1);\n if (xCOffset + 1 >= inDims[1]) {\n xTexelC${n+1}.zw = vec2(0.);\n }\n xTexelC${n+1}Ready = 1;\n }\n\n xC${n} = vec4(\n xTexelC${n}.xy, xTexelC${n+1}.xy);\n `,n+1<d&&(h+=`\n xC${n+1} = vec4(xTexelC${n}.zw, xTexelC${n+1}.zw);\n `)));n<d&&(h+=`\n wTexel = getW(r, ${n}, d1, q);\n dotProd += xC${n} * vec4(wTexel.xz, wTexel.xz);\n `,n+1<d&&(h+=`\n wTexel = getW(r, ${n+1}, d1, q);\n dotProd += xC${n+1} * vec4(wTexel.xz, wTexel.xz);\n `))}h+="\n }\n ",h+="\n }\n ";let f="",x="";a&&(f=r?`vec4 activation(vec4 a) {\n vec4 b = getPreluActivationWeightsAtOutCoords();\n ${a}\n }`:o?`vec4 activation(vec4 a) {\n vec4 b = getLeakyreluAlphaAtOutCoords();\n ${a}\n }`:`vec4 activation(vec4 x) {\n ${a}\n }`,x="result = activation(result);");const m=n?"result += getBiasAtOutCoords();":"";n&&this.variableNames.push("bias"),r&&this.variableNames.push("preluActivationWeights"),o&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n ${f}\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 / ${s};\n int q = d2 - d1 * ${s};\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n //intialize dotProd with a small epsilon seems to reduce GPU accuracy loss.\n vec4 dotProd = vec4(0.000000000000001);\n\n ${h}\n\n vec4 result = dotProd - vec4(0.000000000000001);\n ${m}\n ${x}\n setOutput(result);\n }\n `}}const Ko={kernelName:t.DepthwiseConv2dNative,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,filter:s}=n,{strides:i,pad:l,dilations:u,dimRoundingMode:c}=r;let d=u;null==d&&(d=[1,1]),t.util.assert(t.backend_util.eitherStridesOrDilationsAreOne(i,d),(()=>`Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${i} and dilations '${d}'`));const p=t.backend_util.computeConv2DInfo(o.shape,s.shape,i,d,l,c,!0);let h;h=t.env().getBool("WEBGL_PACK_DEPTHWISECONV")&&p.strideWidth<=2&&p.outChannels/p.inChannels==1?new jo(p):new Ho(p);const f=[[p.padInfo.top,p.padInfo.left],[p.strideHeight,p.strideWidth],[p.dilationHeight,p.dilationWidth],[p.inHeight,p.inWidth]];return a.runWebGLProgram(h,[o,s],"float32",f)}};class qo{constructor(e){this.variableNames=["x","dy"],this.outputShape=e.filterShape;const t=e.strideHeight,n=e.strideWidth,a=e.padInfo.top,r=e.padInfo.left,o=e.outChannels/e.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 * ${o} + dm;\n\n float dotProd = 0.0;\n\n // TO DO: Vec4 over the batch size\n for (int b = 0; b < ${e.batchSize}; b++) {\n for (int yR = 0; yR < ${e.outHeight}; yR++) {\n int xR = wR + yR * ${t} - ${a};\n\n if (xR < 0 || xR >= ${e.inHeight}) {\n continue;\n }\n\n for (int yC = 0; yC < ${e.outWidth}; yC++) {\n int xC = wC + yC * ${n} - ${r};\n\n if (xC < 0 || xC >= ${e.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 `}}class Yo{constructor(e){this.variableNames=["dy","W"],this.outputShape=e.inShape;const t=e.filterHeight,n=e.filterWidth,a=e.strideHeight,r=e.strideWidth,o=t-1-e.padInfo.top,s=n-1-e.padInfo.left,i=e.outChannels/e.inChannels;this.userCode=`\n const ivec2 pads = ivec2(${o}, ${s});\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 < ${t}; wR++) {\n float dyR = float(dyRCorner + wR) / ${a}.0;\n\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = ${t} - 1 - wR;\n\n for (int wC = 0; wC < ${n}; wC++) {\n float dyC = float(dyCCorner + wC) / ${r}.0;\n\n if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = ${n} - 1 - wC;\n\n // TO DO: Vec4 over the channelMul\n for (int dm = 0; dm < ${i}; dm++) {\n int d2 = d1 * ${i} + 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 `}}const Qo={kernelName:t.DepthwiseConv2dNativeBackpropFilter,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,dy:s}=n,{strides:i,dilations:l,pad:u,dimRoundingMode:c,filterShape:d}=r,p=t.backend_util.computeConv2DInfo(o.shape,d,i,l,u,c,!0),h=new qo(p);return a.runWebGLProgram(h,[o,s],"float32")}};const Zo={kernelName:t.DepthwiseConv2dNativeBackpropInput,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,filter:s}=n,{strides:i,dilations:l,pad:u,dimRoundingMode:c,inputShape:d}=r,p=t.backend_util.computeConv2DInfo(d,s.shape,i,l,u,c,!0),h=new Yo(p);return a.runWebGLProgram(h,[o,s],"float32")}};class Jo{constructor(e){this.variableNames=["X"],this.outputShape=[e,e],this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n float val = coords[0] == coords[1] ? getX(coords[0]) : 0.0;\n setOutput(val);\n }\n "}}const es={kernelName:t.Diag,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{x:r}=n,o=[...r.shape,...r.shape],s=t.util.sizeFromShape(r.shape),i=Aa({inputs:{x:r},backend:a,attrs:{shape:[s]}}),l=new Jo(s),u=a.runWebGLProgram(l,[i],i.dtype),c=Aa({inputs:{x:u},backend:a,attrs:{shape:o}});return a.disposeIntermediateTensorInfo(i),a.disposeIntermediateTensorInfo(u),c}};class ts{constructor(e){this.variableNames=["x","W"],this.outputShape=e.outShape;const{inHeight:t,inWidth:n,padInfo:a,strideHeight:r,strideWidth:o,filterHeight:s,filterWidth:i,dilationHeight:l,dilationWidth:u}=e,{top:c,left:d}=a;this.userCode=`\n const ivec2 strides = ivec2(${r}, ${o});\n const ivec2 pads = ivec2(${c}, ${d});\n const float neg_infinity = -3.4e38;\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords.x;\n int d1 = coords.w;\n ivec2 outTopLeftCorner =\n coords.yz * strides - pads;\n int hBeg = outTopLeftCorner.x;\n int wBeg = outTopLeftCorner.y;\n\n float curVal = neg_infinity;\n for (int h = 0; h < ${s}; h++) {\n int hIn = hBeg + h * ${l};\n\n if (hIn >= 0 && hIn < ${t}) {\n for (int w = 0; w < ${i}; w++) {\n int wIn = wBeg + w * ${u};\n\n if (wIn >= 0 && wIn < ${n}) {\n float xVal = getX(batch, hIn, wIn, d1);\n float wVal = getW(h, w, d1);\n\n float val = xVal + wVal;\n if (val > curVal) {\n curVal = val;\n }\n }\n }\n }\n }\n\n float result = curVal;\n setOutput(result);\n }\n `}}const ns={kernelName:t.Dilation2D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,filter:s}=n,{strides:i,pad:l,dilations:u}=r,c=t.backend_util.computeDilation2DInfo(o.shape,s.shape,i,l,"NHWC",u);let d;const p=new ts(c);d=a.runWebGLProgram(p,[o,s],"float32");const h=Aa({inputs:{x:d},backend:a,attrs:{shape:c.outShape}});return a.disposeIntermediateTensorInfo(d),h}};const as={kernelName:t.Einsum,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{equation:o}=r,s=n,{allDims:i,summedDims:l,idDims:u}=t.backend_util.decodeEinsumEquation(o,s.length);t.backend_util.checkEinsumDimSizes(i.length,u,s);const{path:c,steps:d}=t.backend_util.getEinsumComputePath(l,u),p=d.length;let h=null,f=i.length;const x=[];for(let e=0;e<p;++e){for(const n of d[e]){const{permutationIndices:e,expandDims:r}=t.backend_util.getEinsumPermutation(f,u[n]);let o;t.backend_util.isIdentityPermutation(e)?o=s[n]:(o=Ua({inputs:{x:s[n]},backend:a,attrs:{perm:e}}),x.push(o));const i=o.shape.slice();for(let e=0;e<r.length;++e)i.splice(r[e],0,1);t.util.arraysEqual(o.shape,i)||(o=Aa({inputs:{x:o},backend:a,attrs:{shape:i}}),x.push(o)),null===h?h=o:(h=Na({inputs:{a:o,b:h},backend:a}),x.push(h))}e<p-1&&(c[e]>=0&&(h=Va({inputs:{x:h},backend:a,attrs:{axis:c[e]-(i.length-f),keepDims:!1}}),x.push(h)),f--)}for(const e of x)e!==h&&a.disposeIntermediateTensorInfo(e);return h}},rs=$a({opSnippet:"return (x >= 0.0) ? x : (exp(x) - 1.0);",packedOpSnippet:"\n vec4 result;\n\n result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n return result;\n"}),os={kernelName:t.Elu,backendName:"webgl",kernelFunc:rs},ss={kernelName:t.EluGrad,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:a}=e,{dy:r,y:o}=n,s=t.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ca("\n vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.)));\n return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0))));\n",r.shape,o.shape):new la("return (b >= 0.0) ? a : a * (b + 1.0);",r.shape,o.shape);return a.runWebGLProgram(s,[r,o],r.dtype)}},is=ya({opSnippet:"return float(a == b);",packedOpSnippet:"\n return vec4(equal(a, b));\n",dtype:"bool",cpuKernelImpl:en}),ls={kernelName:t.Equal,backendName:"webgl",kernelFunc:is},us=$a({opSnippet:`\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 = ${t.backend_util.ERF_P};\n float a1 = ${t.backend_util.ERF_A1};\n float a2 = ${t.backend_util.ERF_A2};\n float a3 = ${t.backend_util.ERF_A3};\n float a4 = ${t.backend_util.ERF_A4};\n float a5 = ${t.backend_util.ERF_A5};\n\n float sign = sign(x);\n x = abs(x);\n float t = 1.0 / (1.0 + p * x);\n return sign * (1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x));\n`}),cs={kernelName:t.Erf,backendName:"webgl",kernelFunc:us},ds=$a({opSnippet:"if (isnan(x)) return x;\n return exp(x);\n",packedOpSnippet:"\n vec4 result = exp(x);\n bvec4 isNaN = isnan(x);\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",cpuKernelImpl:tn,dtype:"float32"}),ps={kernelName:t.Exp,backendName:"webgl",kernelFunc:ds};function hs(e){const{inputs:n,attrs:a,backend:r}=e,{dim:o}=a,{input:s}=n,i=s.shape.length,l=s.shape.slice();let u=o;return o<0&&(t.util.assert(-(i+1)<=o,(()=>`Axis must be in the interval [${-(i+1)}, ${i}]`)),u=i+o+1),l.splice(u,0,1),Aa({inputs:{x:s},backend:r,attrs:{shape:l}})}const fs={kernelName:t.ExpandDims,backendName:"webgl",kernelFunc:hs},xs="return exp(x) - 1.0;",ms=$a({opSnippet:xs,packedOpSnippet:xs,cpuKernelImpl:nn}),gs={kernelName:t.Expm1,backendName:"webgl",kernelFunc:ms};class bs{constructor(e,t,n){this.variableNames=["real","imag"];const a=t[1];this.outputShape=t;const r=n?`2.0 * ${Math.PI}`:`-2.0 * ${Math.PI}`,o=n?`${a}.0`:"1.0";let s;if("real"===e)s="return real * expR - imag * expI;";else{if("imag"!==e)throw new Error(`FFT component must be either "real" or "imag", got ${e}.`);s="return real * expI + imag * expR;"}this.userCode=`\n const float exponentMultiplier = ${r};\n\n float unaryOpComplex(float real, float expR, float imag, float expI) {\n ${s}\n }\n\n float mulMatDFT(int batch, int index) {\n float indexRatio = float(index) / float(${a});\n float exponentMultiplierTimesIndexRatio =\n exponentMultiplier * indexRatio;\n\n float result = 0.0;\n\n for (int i = 0; i < ${a}; 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) / ${o};\n }\n\n return result;\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n setOutput(mulMatDFT(coords[0], coords[1]));\n }\n `}}function vs(e,n,a){const r=a.texData.get(e.dataId),o=t.util.sizeFromShape(e.shape),s=e.shape[e.shape.length-1],i=Aa({inputs:{x:e},backend:a,attrs:{shape:[o/s,s]}}),l=i.shape,u=new bs("real",l,n),c=new bs("imag",l,n),d=[{dataId:r.complexTensorInfos.real.dataId,dtype:r.complexTensorInfos.real.dtype,shape:l},{dataId:r.complexTensorInfos.imag.dataId,dtype:r.complexTensorInfos.imag.dtype,shape:l}],p=a.runWebGLProgram(u,d,"float32"),h=a.runWebGLProgram(c,d,"float32"),f=ha({inputs:{real:p,imag:h},backend:a});a.disposeIntermediateTensorInfo(p),a.disposeIntermediateTensorInfo(h);const x=Aa({inputs:{x:f},backend:a,attrs:{shape:e.shape}});return a.disposeIntermediateTensorInfo(i),a.disposeIntermediateTensorInfo(f),x}const Cs={kernelName:t.FFT,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{input:a}=t;return vs(a,!1,n)}};class $s{constructor(e,t){this.outputShape=[],this.customUniforms=[{name:"value",type:"float"}],this.variableNames=["x"],this.outputShape=e,this.userCode="\n void main() {\n // Input can be obtained from uniform value.\n setOutput(value);\n }\n "}}function ys(e){const{backend:n,attrs:a}=e,{shape:r,value:o}=a;let{dtype:s}=a;if(s=s||t.util.inferDtype(o),"string"===s){const e=t.util.getArrayFromDType(s,t.util.sizeFromShape(r));return e.fill(o),n.makeTensorInfo(r,s,e)}{const e=new $s(r,o),t=[[o]];return n.runWebGLProgram(e,[],s,t)}}const Is={kernelName:t.Fill,backendName:"webgl",kernelFunc:ys};class ws{constructor(e){this.variableNames=["Image"],this.outputShape=[];const t=e[2];this.outputShape=e,this.userCode=`\n void main() {\n ivec4 coords = getOutputCoords();\n int x = coords[2];\n\n int coordX = ${t} - x - 1;\n float outputValue;\n if(coordX >= 0 && coordX < ${t}) {\n outputValue = getImage(coords[0], coords[1], coordX, coords[3]);\n } else {\n outputValue = getImage(coords[0], coords[1], coords[2], coords[3]);\n }\n setOutput(outputValue);\n }\n `}}const Ss={kernelName:t.FlipLeftRight,backendName:"webgl",kernelFunc:({inputs:e,backend:t})=>{const{image:n}=e,a=t,r=new ws(n.shape);return a.runWebGLProgram(r,[n],n.dtype)}},ks="return floor(x);",Rs=$a({opSnippet:ks,packedOpSnippet:ks,cpuKernelImpl:an}),Ts={kernelName:t.Floor,backendName:"webgl",kernelFunc:Rs},Ns=ya({opSnippet:"\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",packedOpSnippet:"\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",dtype:"int32"}),Es={kernelName:t.FloorDiv,backendName:"webgl",kernelFunc:Ns};class As{constructor(e){this.variableNames=["A"];const t=le(),[n,a]=e;this.outputShape=e,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(${a}.0, ${n}.0);\n\n vec4 values = ${t.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 `}}class _s{constructor(e){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0;const t=le(),[n,a]=e;this.outputShape=e,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) /\n vec2(${a}.0, ${n}.0);\n vec4 values = ${t.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 ${t.output} = result;\n }\n `}}const Os={kernelName:t.FromPixels,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e;let{pixels:o}=n;const{numChannels:s}=r,i="undefined"!=typeof HTMLVideoElement&&o instanceof HTMLVideoElement,l="undefined"!=typeof HTMLImageElement&&o instanceof HTMLImageElement,[c,d]=i?[o.videoWidth,o.videoHeight]:[o.width,o.height],p=[d,c],h=[d,c,s];if(l||i){const e=t.env().getBool("CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU");null!=Fs&&e===Ds||(Ds=e,Fs=document.createElement("canvas").getContext("2d",{willReadFrequently:Ds})),Fs.canvas.width=c,Fs.canvas.height=d,Fs.drawImage(o,0,0,c,d),o=Fs.canvas}const f=a.makeTensorInfo(p,"int32");a.texData.get(f.dataId).usage=u.PIXELS,a.gpgpu.uploadPixelDataToTexture(a.getTexture(f.dataId),o);const x=t.env().getBool("WEBGL_PACK")?new _s(h):new As(h),m=a.runWebGLProgram(x,[f],"int32");return a.disposeData(f.dataId),m}};let Fs,Ds=t.env().getBool("CANVAS2D_WILL_READ_FREQUENTLY_FOR_GPU");const Ps={kernelName:t.FusedConv2D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,filter:s,bias:i,preluActivationWeights:l}=n,{strides:u,pad:c,dataFormat:d,dilations:p,dimRoundingMode:h,activation:f,leakyreluAlpha:x}=r,m=t.backend_util.convertConv2DDataFormat(d),g=t.backend_util.computeConv2DInfo(o.shape,s.shape,u,p,c,h,!1,m);let b;const v=[],C=null!=i,$=null!=l,y="leakyrelu"===f,I=()=>{const e=[o,s],n=(e,t)=>{if("NCHW"===t&&1===e.shape.length&&1!==e.shape[0]){const t=Aa({inputs:{x:e},backend:a,attrs:{shape:[e.shape[0],1,1]}});return v.push(t),t}return e};if(C&&e.push(n(i,d)),$&&e.push(n(l,d)),y){const n=a.makeTensorInfo([],"float32",t.util.createScalarValue(x,"float32"));e.push(n),v.push(n)}return e};if(1!==g.filterHeight||1!==g.filterWidth||1!==g.dilationHeight||1!==g.dilationWidth||1!==g.strideHeight||1!==g.strideWidth||"SAME"!==g.padInfo.type&&"VALID"!==g.padInfo.type)if(g.strideWidth<=2&&"channelsLast"===m&&t.env().getBool("WEBGL_EXP_CONV")){const e=f?Ia(f,!0):null,t=new fo(g,C,e,$,y),n=[[g.padInfo.top,g.padInfo.left],[g.strideHeight,g.strideWidth],[g.dilationHeight,g.dilationWidth],[g.inHeight,g.inWidth]],r=I();b=a.runWebGLProgram(t,r,"float32",n)}else if(t.env().getBool("WEBGL_CONV_IM2COL"))b=bo({x:o,filter:s,convInfo:g,backend:a,bias:i,activation:f,preluActivationWeights:l,leakyreluAlpha:x});else{const e=f?Ia(f,!1):null,t=new po(g,C,e,$,y),n=I();b=a.runWebGLProgram(t,n,"float32")}else b=go({x:o,filter:s,convInfo:g,backend:a,bias:i,activation:f,preluActivationWeights:l,leakyreluAlpha:x});const w=Aa({inputs:{x:b},backend:a,attrs:{shape:g.outShape}});return v.push(b),v.forEach((e=>a.disposeIntermediateTensorInfo(e))),w}};const Ls={kernelName:t.FusedDepthwiseConv2D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,filter:s,bias:i,preluActivationWeights:l}=n,{strides:u,pad:c,dilations:d,dimRoundingMode:p,activation:h,leakyreluAlpha:f}=r,x=[];let m=d;null==m&&(m=[1,1]),t.util.assert(t.backend_util.eitherStridesOrDilationsAreOne(u,m),(()=>`Error in depthwiseConv2d: Either strides or dilations must be 1. Got strides ${u} and dilations '${m}'`));const g=t.backend_util.computeConv2DInfo(o.shape,s.shape,u,m,c,p,!0),b=t.env().getBool("WEBGL_PACK_DEPTHWISECONV")&&g.strideWidth<=2&&g.outChannels/g.inChannels==1,v=h?Ia(h,b):null,C=[o,s],$=null!=i,y=null!=l,I="leakyrelu"===h;if($&&C.push(i),y&&C.push(l),I){const e=a.makeTensorInfo([],"float32",t.util.createScalarValue(f,"float32"));C.push(e),x.push(e)}let w;w=b?new jo(g,$,v,y,I):new Ho(g,$,v,y,I);const S=[[g.padInfo.top,g.padInfo.left],[g.strideHeight,g.strideWidth],[g.dilationHeight,g.dilationWidth],[g.inHeight,g.inWidth]],k=a.runWebGLProgram(w,C,"float32",S);return x.forEach((e=>a.disposeIntermediateTensorInfo(e))),k}};class Bs{constructor(e,t,n,a){this.sliceDim=e,this.strides=t,this.paramsShape=a,this.variableNames=["x","indices"],this.outputShape=n;const r=Se(n.length);let o="\n int index;";for(let e=0;e<this.sliceDim;e++)o+=`\n index = round(getIndices(coords[0], ${e}));\n out_of_bounds = out_of_bounds || index < 0;\n out_of_bounds = out_of_bounds || index >= ${this.paramsShape[e]};\n flattenIndex += index * ${this.strides[e]};`;this.userCode=`\n void main() {\n ${r} coords = getOutputCoords();\n int flattenIndex = 0;\n bool out_of_bounds = false;\n\n ${o}\n\n setOutput(out_of_bounds ? 0.0 : getX(flattenIndex, coords[1]));\n }\n `}}const Vs={kernelName:t.GatherNd,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{params:r,indices:o}=n,s=o.shape,i=s[s.length-1],l=t.util.sizeFromShape(r.shape),[u,c,d,p]=t.backend_util.prepareAndValidate(r,o),h=Aa({inputs:{x:o},backend:a,attrs:{shape:[c,i]}}),f=Aa({inputs:{x:r},backend:a,attrs:{shape:[t.util.sizeFromShape(r.shape)/d,d]}});if(a.shouldExecuteOnCPU([r,o])||"string"===r.dtype){const e=a.readSync(o.dataId),t=a.bufferSync(r),n=rn(e,t,r.dtype,c,i,d,p,r.shape,l);return a.makeTensorInfo(u,r.dtype,n.values)}const x=new Bs(i,p,[c,d],r.shape),m=a.runWebGLProgram(x,[f,h],f.dtype),g=Aa({inputs:{x:m},backend:a,attrs:{shape:u}});return a.disposeIntermediateTensorInfo(h),a.disposeIntermediateTensorInfo(f),a.disposeIntermediateTensorInfo(m),g}};class Ws{constructor(e,t){this.variableNames=["A","indices"],this.outputShape=t,this.rank=t.length;const n=Se(this.rank),a=function(e,t){const n=["resRC.x","resRC.y","resRC.z","resRC.w"],a=[];for(let t=0;t<e.length;t++)2===t?a.push("index"):a.push(`${n[t]}`);return a.join()}(e);this.userCode=`\n void main() {\n ${n} resRC = getOutputCoords();\n int index = int(getIndices(resRC.x, resRC.z));\n float inBounds = (index >= 0) && (index < ${e[2]}) ? 1.0 : 0.0;\n setOutput(inBounds * getA(${a}));\n }\n `}}function Us(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,indices:s}=n,{axis:i,batchDims:l}=r,u=t.util.parseAxisParam(i,o.shape)[0];if(t.env().get("DEBUG")){const e=a.readSync(s.dataId),n=o.shape[u];for(let a=0;a<e.length;++a){const r=e[a];t.util.assert(r<=n-1&&r>=0,(()=>`GatherV2: the index value ${r} is not in [0, ${n-1}]`))}}const c=t.backend_util.segment_util.collectGatherOpShapeInfo(o,s,u,l),d=t.util.sizeFromShape(s.shape),p=[],h=Aa({inputs:{x:o},backend:a,attrs:{shape:[c.batchSize,c.outerSize,c.dimSize,c.sliceSize]}}),f=Aa({inputs:{x:s},backend:a,attrs:{shape:[c.batchSize,d/c.batchSize]}});p.push(h),p.push(f);const x=[c.batchSize,c.outerSize,d/c.batchSize,c.sliceSize];if(a.shouldExecuteOnCPU([o,s])||"string"===o.dtype){const e=a.bufferSync(f),t=a.bufferSync(h),n=on(t,e,x);return p.forEach((e=>a.disposeIntermediateTensorInfo(e))),a.makeTensorInfo(c.outputShape,n.dtype,n.values)}const m=new Ws(h.shape,x),g=a.runWebGLProgram(m,[h,f],h.dtype);p.push(g);const b=Aa({inputs:{x:g},backend:a,attrs:{shape:c.outputShape}});return p.forEach((e=>a.disposeIntermediateTensorInfo(e))),b}const Ms={kernelName:t.GatherV2,backendName:"webgl",kernelFunc:Us},Gs=ya({opSnippet:"return float(a > b);",packedOpSnippet:"\n return vec4(greaterThan(a, b));\n",cpuKernelImpl:sn,dtype:"bool"}),zs={kernelName:t.Greater,backendName:"webgl",kernelFunc:Gs},Xs=ya({opSnippet:"return float(a >= b);",packedOpSnippet:"\n return vec4(greaterThanEqual(a, b));\n",dtype:"bool",cpuKernelImpl:ln}),Hs={kernelName:t.GreaterEqual,backendName:"webgl",kernelFunc:Xs};const js={kernelName:t.IFFT,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{input:a}=t;return vs(a,!0,n)}},Ks=$a({opSnippet:"return float(!isnan(x) && !isinf(x));",dtype:"bool"}),qs={kernelName:t.IsFinite,backendName:"webgl",kernelFunc:Ks},Ys=$a({opSnippet:"return float(isinf(x));",dtype:"bool"}),Qs={kernelName:t.IsInf,backendName:"webgl",kernelFunc:Ys},Zs=$a({opSnippet:"return float(isnan(x));",dtype:"bool"}),Js={kernelName:t.IsNan,backendName:"webgl",kernelFunc:Zs},ei=ya({opSnippet:"return float(a < b);",packedOpSnippet:"\n return vec4(lessThan(a, b));\n",cpuKernelImpl:un,dtype:"bool"}),ti={kernelName:t.Less,backendName:"webgl",kernelFunc:ei},ni=ya({opSnippet:"return float(a <= b);",packedOpSnippet:"\n return vec4(lessThanEqual(a, b));\n",cpuKernelImpl:cn,dtype:"bool"}),ai={kernelName:t.LessEqual,backendName:"webgl",kernelFunc:ni};const ri={kernelName:t.LinSpace,backendName:"webgl",kernelFunc:function(e){const{backend:t,attrs:n}=e,{start:a,stop:r,num:o}=n,s=dn(a,r,o);return t.makeTensorInfo([s.length],"float32",s)}},oi=$a({opSnippet:"if (isnan(x)) return x;\n return x < 0.0 ? 0./0. : log(x);\n",packedOpSnippet:"\n vec4 result = log(x);\n bvec4 isNaN = isnan(x);\n result.r = isNaN.r ? x.r : (x.r < 0.0 ? 0./0. : result.r);\n result.g = isNaN.g ? x.g : (x.g < 0.0 ? 0./0. : result.g);\n result.b = isNaN.b ? x.b : (x.b < 0.0 ? 0./0. : result.b);\n result.a = isNaN.a ? x.a : (x.a < 0.0 ? 0./0. : result.a);\n return result;\n",cpuKernelImpl:pn}),si={kernelName:t.Log,backendName:"webgl",kernelFunc:oi},ii=$a({opSnippet:"if (isnan(x)) return x;\n return log(1.0 + x);\n"}),li={kernelName:t.Log1p,backendName:"webgl",kernelFunc:ii},ui=ya({opSnippet:"return float(a >= 1.0 && b >= 1.0);",packedOpSnippet:"\n return vec4(\n vec4(greaterThanEqual(a, vec4(1.0))) *\n vec4(greaterThanEqual(b, vec4(1.0))));\n",dtype:"bool"}),ci={kernelName:t.LogicalAnd,backendName:"webgl",kernelFunc:ui},di=$a({opSnippet:"return float(!(x >= 1.0));"}),pi={kernelName:t.LogicalNot,backendName:"webgl",kernelFunc:di},hi=ya({opSnippet:"return float(a >= 1.0 || b >= 1.0);",packedOpSnippet:"\n return min(\n vec4(greaterThanEqual(a, vec4(1.0))) +\n vec4(greaterThanEqual(b, vec4(1.0))),\n vec4(1.0));\n",dtype:"bool"}),fi={kernelName:t.LogicalOr,backendName:"webgl",kernelFunc:hi};class xi{constructor(e,t,n,a,r){this.variableNames=["x"],this.outputShape=[];const o=t,s=e[3]-1;let i;this.outputShape=e;const l=`float(${n}) + float(${a}) * sum`;i=.5===r?`inversesqrt(${l})`:1===r?`1.0/(${l})`:`exp(log(${l}) * float(-${r}));`,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 = -${o}; j <= ${o}; 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 * ${i};\n setOutput(val);\n }\n `}}class mi{constructor(e,t,n,a,r){this.variableNames=["x"],this.outputShape=[],this.packedInputs=!0,this.packedOutput=!0;const o=t,s=e[3]-1;let i;this.outputShape=e;const l=`float(${n}) + float(${a}) * sum`;i=.5===r?`inversesqrt(${l})`:1===r?`1.0/(${l})`:`exp(log(${l}) * float(-${r}));`,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 - ${o};\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 = - ${o}; j <= ${o}; 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 * ${i};\n setOutput(result);\n }\n `}}const gi={kernelName:t.LRN,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{depthRadius:s,bias:i,alpha:l,beta:u}=r,c=t.env().getBool("WEBGL_PACK_NORMALIZATION")?new mi(o.shape,s,i,l,u):new xi(o.shape,s,i,l,u);return a.runWebGLProgram(c,[o],o.dtype)}};class bi{constructor(e,t,n,a,r){this.variableNames=["inputImage","outputImage","dy"],this.outputShape=[],this.outputShape=e,this.depth=e[3],this.depthRadius=t,this.bias=n,this.alpha=a,this.beta=r,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 - ${t})));\n int depthEnd = int(min(float(${this.depth}),\n float(d + ${t} + 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(${a}) * 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(${a})\n * float(${r})\n * getInputImage(b, r, c, k) * getOutputImage(b, r, c, d)\n / norm;\n if (k == d) {\n dyi += pow(norm, -1.0 * ${r});\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 `}}const vi={kernelName:t.LRNGrad,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:n,attrs:a}=e,{x:r,y:o,dy:s}=t,{depthRadius:i,bias:l,alpha:u,beta:c}=a,d=new bi(r.shape,i,l,u,c);return n.runWebGLProgram(d,[r,o,s],r.dtype)}};function Ci(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{reductionIndices:s,keepDims:i}=r,l=o.shape.length,u=t.util.parseAxisParam(s,o.shape);let c=u;const d=t.backend_util.getAxesPermutation(c,l),p=null!=d,h=a.shouldExecuteOnCPU([o]);let f=o;if(p){if(h){const e=a.texData.get(f.dataId).values,t=new Array(l);for(let e=0;e<t.length;e++)t[e]=o.shape[d[e]];const n=Un(e,o.shape,o.dtype,d,t);f=a.makeTensorInfo(t,o.dtype);a.texData.get(f.dataId).values=n}else f=Ba(o,d,a);c=t.backend_util.getInnerMostAxes(c.length,l)}t.backend_util.assertAxesAreInnerMostDims("max",c,l);const[x,m]=t.backend_util.computeOutAndReduceShapes(f.shape,c);let g,b=x;if(i&&(b=t.backend_util.expandShapeToKeepDim(x,u)),h){const e=a.texData.get(f.dataId).values,n=hn(e,t.util.sizeFromShape(m),b,o.dtype);g=a.makeTensorInfo(b,o.dtype);a.texData.get(g.dataId).values=n}else g=function(e,n,a,r){const o=t.util.sizeFromShape(n),s=Aa({inputs:{x:e},attrs:{shape:[t.util.sizeFromShape(e.shape)/o,o]},backend:r}),i=Da(s,e.dtype,"max",r),l=Aa({inputs:{x:i},attrs:{shape:a},backend:r});return r.disposeIntermediateTensorInfo(s),r.disposeIntermediateTensorInfo(i),l}(f,m,b,a);return p&&a.disposeIntermediateTensorInfo(f),g}const $i={kernelName:t.Max,backendName:"webgl",kernelFunc:Ci},yi=ya({opSnippet:"\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return max(a, b);\n",packedOpSnippet:"\n vec4 result = vec4(max(a, b));\n bvec4 isNaNA = isnan(a);\n bvec4 isNaNB = isnan(b);\n bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w);\n \n result.r = isNaN.r ? NAN : result.r;\n result.g = isNaN.g ? NAN : result.g;\n result.b = isNaN.b ? NAN : result.b;\n result.a = isNaN.a ? NAN : result.a;\n\n return result;\n",cpuKernelImpl:fn}),Ii={kernelName:t.Maximum,backendName:"webgl",kernelFunc:yi};const wi={kernelName:t.MaxPool,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n;oe(o,"maxPool");const{filterSize:s,strides:i,pad:l,dimRoundingMode:u}=r;t.util.assert(t.backend_util.eitherStridesOrDilationsAreOne(i,1),(()=>`Error in maxPool: Either strides or dilations must be 1. Got strides ${i} and dilations '1'`));const c=t.backend_util.computePool2DInfo(o.shape,s,i,1,l,u);if(1===c.filterWidth&&1===c.filterHeight&&t.util.arraysEqual(c.inShape,c.outShape))return da({inputs:{x:o},backend:a});const d=new yr(c,"max",!1);return a.runWebGLProgram(d,[o],o.dtype)}};const Si={kernelName:t.MaxPool3D,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{filterSize:s,strides:i,pad:l,dataFormat:u,dimRoundingMode:c}=r,d=t.backend_util.computePool3DInfo(o.shape,s,i,[1,1,1],l,c,u),p=new Ir(d,"max",!1);return a.runWebGLProgram(p,[o],o.dtype)}};class ki{constructor(e){this.variableNames=["dy","maxPos"],this.outputShape=e.inShape;const t=e.strideHeight,n=e.strideWidth,a=e.dilationHeight,r=e.effectiveFilterHeight,o=e.effectiveFilterWidth,s=r-1-e.padInfo.top,i=o-1-e.padInfo.left,l=r*o-1;this.userCode=`\n const ivec2 pads = ivec2(${s}, ${i});\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 < ${r};\n wR += ${a}) {\n float dyR = float(dyRCorner + wR) / ${t}.0;\n\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < ${o}; wC++) {\n float dyC = float(dyCCorner + wC) / ${n}.0;\n\n if (dyC < 0.0 || dyC >= ${e.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 = ${l} - 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 * ${o} + wC;\n float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n dotProd += dyValue * mask;\n }\n }\n setOutput(dotProd);\n }\n `}}class Ri{constructor(e){this.variableNames=["dy","maxPos"],this.outputShape=e.inShape;const t=e.strideDepth,n=e.strideHeight,a=e.strideWidth,r=e.dilationDepth,o=e.dilationHeight,s=e.dilationWidth,i=e.effectiveFilterDepth,l=e.effectiveFilterHeight,u=e.effectiveFilterWidth,c=i-1-e.padInfo.front,d=l-1-e.padInfo.top,p=u-1-e.padInfo.left,h=i*l*u-1;this.userCode=`\n const ivec3 pads = ivec3(${c}, ${d}, ${p});\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n int dyDCorner = dyCorner.x;\n int dyRCorner = dyCorner.y;\n int dyCCorner = dyCorner.z;\n\n // Convolve dy(?, ?, ?, ch) with pos mask(:, :, :, d) to get\n // dx(xD, xR, xC, ch).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int wD = 0; wD < ${i};\n wD += ${r}) {\n float dyD = float(dyDCorner + wD) / ${t}.0;\n\n if (dyD < 0.0 || dyD >= ${e.outDepth}.0 || fract(dyD) > 0.0) {\n continue;\n }\n int idyD = int(dyD);\n\n for (int wR = 0; wR < ${l};\n wR += ${o}) {\n float dyR = float(dyRCorner + wR) / ${n}.0;\n\n if (dyR < 0.0 || dyR >= ${e.outHeight}.0 ||\n fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < ${u};\n wC += ${s}) {\n float dyC = float(dyCCorner + wC) / ${a}.0;\n\n if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n int maxPosValue = ${h} -\n int(getMaxPos(batch, idyD, idyR, idyC, ch));\n\n // Get the current value, check it against the value from the\n // position matrix.\n int curPosValue =\n wD * ${l} * ${u} +\n wR * ${u} + wC;\n float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n dotProd += dyValue * mask;\n }\n }\n }\n setOutput(dotProd);\n }\n `}}const Ti={kernelName:t.MaxPool3DGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,input:s}=n,i=s,{filterSize:l,strides:u,pad:c,dimRoundingMode:d}=r,p=t.backend_util.computePool3DInfo(i.shape,l,u,[1,1,1],c,d),h=new Ir(p,"max",!0),f=a.runWebGLProgram(h,[i],i.dtype),x=new Ri(p),m=a.runWebGLProgram(x,[o,f],i.dtype);return a.disposeIntermediateTensorInfo(f),m}};const Ni={kernelName:t.MaxPoolGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{dy:o,input:s,output:i}=n,l=s;oe([s,i],"maxPoolGrad");const{filterSize:u,strides:c,pad:d,dimRoundingMode:p}=r,h=t.backend_util.computePool2DInfo(l.shape,u,c,1,d,p),f=new yr(h,"max",!0),x=a.runWebGLProgram(f,[l],l.dtype),m=new ki(h),g=a.runWebGLProgram(m,[o,x],l.dtype);return a.disposeIntermediateTensorInfo(x),g}};const Ei={kernelName:t.MaxPoolWithArgmax,backendName:"webgl",kernelFunc:({inputs:e,attrs:n,backend:a})=>{const{x:r}=e,{filterSize:o,strides:s,pad:i,includeBatchInIndex:l}=n,u=a;t.util.assert(4===r.shape.length,(()=>`Error in maxPool: input must be rank 4 but got rank ${r.shape.length}.`));const c=[1,1];t.util.assert(t.backend_util.eitherStridesOrDilationsAreOne(s,c),(()=>`Error in maxPool: Either strides or dilations must be 1. Got strides ${s} and dilations '${c}'`));const d=t.backend_util.computePool2DInfo(r.shape,o,s,c,i),[p,h]=function(e,t,n,a){let r=new yr(n,"max",!1);const o=a.runWebGLProgram(r,[e],"float32");return r=new yr(n,"max",!0,!0,t),[o,a.runWebGLProgram(r,[e],"float32")]}(r,l,d,u);return[p,h]}};const Ai={kernelName:t.Mean,backendName:"webgl",kernelFunc:({inputs:e,attrs:n,backend:a})=>{const{x:r}=e,{keepDims:o,axis:s}=n,i=a,l=r.shape.length,u=t.util.parseAxisParam(s,r.shape);let c=u;const d=t.backend_util.getAxesPermutation(c,l),p=null!=d,h=i.shouldExecuteOnCPU([r]),f=[];let x=r;if(p){if(h){const e=i.texData.get(x.dataId).values,t=new Array(l);for(let e=0;e<t.length;e++)t[e]=r.shape[d[e]];const n=Un(e,r.shape,r.dtype,d,t);x=i.makeTensorInfo(t,r.dtype);i.texData.get(x.dataId).values=n}else x=Ba(r,d,i);f.push(x),c=t.backend_util.getInnerMostAxes(c.length,l)}t.backend_util.assertAxesAreInnerMostDims("sum",c,l);const[m,g]=t.backend_util.computeOutAndReduceShapes(x.shape,c);let b=m;o&&(b=t.backend_util.expandShapeToKeepDim(m,u));const v=function(e,n,a,r){const o=t.util.sizeFromShape(n),s=Aa({inputs:{x:e},attrs:{shape:[t.util.sizeFromShape(e.shape)/o,o]},backend:r}),i=Da(s,"float32","mean",r),l=Aa({inputs:{x:i},attrs:{shape:a},backend:r});return r.disposeIntermediateTensorInfo(s),r.disposeIntermediateTensorInfo(i),l}(x,g,b,i);for(const e of f)i.disposeIntermediateTensorInfo(e);return v}};const _i={kernelName:t.Min,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s,keepDims:i}=r,l=o.shape.length,u=t.util.parseAxisParam(s,o.shape);let c=u;const d=t.backend_util.getAxesPermutation(c,l);let p=o;null!=d&&(p=Ua({inputs:{x:o},backend:a,attrs:{perm:d}}),c=t.backend_util.getInnerMostAxes(c.length,o.shape.length)),t.backend_util.assertAxesAreInnerMostDims("min",c,l);const[h,f]=t.backend_util.computeOutAndReduceShapes(p.shape,c),x=Aa({inputs:{x:p},backend:a,attrs:{shape:[-1,t.util.sizeFromShape(f)]}}),m=Da(x,x.dtype,"min",a);let g;if(i){g=Aa({inputs:{x:m},backend:a,attrs:{shape:t.backend_util.expandShapeToKeepDim(h,u)}})}else g=Aa({inputs:{x:m},backend:a,attrs:{shape:h}});return a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(m),null!=d&&a.disposeIntermediateTensorInfo(p),g}},Oi=ya({opSnippet:"\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return min(a, b);\n",packedOpSnippet:"\n vec4 result = vec4(min(a, b));\n bvec4 isNaNA = isnan(a);\n bvec4 isNaNB = isnan(b);\n bvec4 isNaN = bvec4(isNaNA.x || isNaNB.x, isNaNA.y || isNaNB.y, isNaNA.z || isNaNB.z, isNaNA.w || isNaNB.w);\n \n result.r = isNaN.r ? NAN : result.r;\n result.g = isNaN.g ? NAN : result.g;\n result.b = isNaN.b ? NAN : result.b;\n result.a = isNaN.a ? NAN : result.a;\n\n return result;\n",cpuKernelImpl:xn}),Fi={kernelName:t.Minimum,backendName:"webgl",kernelFunc:Oi};class Di{constructor(e,t,n){this.variableNames=["x"],this.outputShape=t.map(((t,n)=>t[0]+e[n]+t[1]));const a=e.length,r=Se(a),o=t.map((e=>e[0])).join(","),s=t.map(((t,n)=>t[0]+e[n])).join(","),i=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,a),l="reflect"===n?0:1;this.userCode=1!==a?`\n ${r} start = ${r}(${o});\n ${r} end = ${r}(${s});\n\n void main() {\n ${r} outC = getOutputCoords();\n for (int i = 0; i < ${a}; i++) {\n if (outC[i] < start[i]) {\n outC[i] = start[i] * 2 - outC[i] - ${l};\n } else if(outC[i] >= end[i]) {\n outC[i] = (end[i] - 1) * 2 - outC[i] + ${l};\n }\n }\n ${r} coords = outC - start;\n setOutput(getX(${i}));\n }\n `:`\n int start = ${o};\n int end = ${s};\n\n void main() {\n int outC = getOutputCoords();\n if (outC < start) {\n outC = start * 2 - outC - ${l};\n } else if(outC >= end) {\n outC = (end - 1) * 2 - outC + ${l};\n }\n setOutput(getX(outC - start));\n }\n `}}class Pi{constructor(e,t,n){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t.map(((t,n)=>t[0]+e[n]+t[1]));const a=e.length,r=Se(a),o=t.map((e=>e[0])).join(","),s=t.map(((t,n)=>t[0]+e[n])).join(","),i=zn("rc",a),l=zn("source",a),u=`${i[a-1]} < ${this.outputShape[a-1]}`,c=1===a?"source":`vec2(${l.slice(-2).join()})`,d="reflect"===n?0:1;let p="";if(1===a){const e=`\n ${r} source = rc;\n if (source < start) {\n source = start * 2 - source - ${d};\n } else if (source >= end) {\n source = (end - 1) * 2 - source + ${d};\n }\n source -= start;\n `;p=`\n ${r} rc = outputLoc;\n ${e}\n result[0] = getChannel(getX(${l.join()}), ${c});\n ${i[a-1]} += 1;\n if(${u}) {\n ${e}\n result[1] = getChannel(getX(${l.join()}), ${c});\n }\n `}else{const e=`\n ${r} source = rc;\n ${r} lt = ${r}(lessThan(source, start));\n ${r} gte = ${r}(greaterThanEqual(source, end));\n ${r} orig = 1 - (lt + gte);\n source = orig * source +\n lt * (start * 2 - source - ${d}) +\n gte * ((end - 1) * 2 - source + ${d});\n source -= start;\n `;p=`\n ${r} rc = outputLoc;\n ${e}\n result[0] = getChannel(getX(${l.join()}), ${c});\n ${i[a-1]} += 1;\n if(${u}) {\n ${e}\n result[1] = getChannel(getX(${l.join()}), ${c});\n }\n rc = outputLoc;\n ${i[a-2]} += 1;\n if(${i[a-2]} < ${this.outputShape[a-2]}) {\n ${e}\n result[2] = getChannel(getX(${l.join()}), ${c});\n ${i[a-1]} += 1;\n if(${u}) {\n ${e}\n result[3] = getChannel(getX(${l.join()}), ${c});\n }\n }\n `}this.userCode=`\n const ${r} start = ${r}(${o});\n const ${r} end = ${r}(${s});\n\n void main() {\n ${r} outputLoc = getOutputCoords();\n vec4 result = vec4(0.);\n ${p}\n setOutput(result);\n }\n `}}const Li={kernelName:t.MirrorPad,backendName:"webgl",kernelFunc:({inputs:e,backend:n,attrs:a})=>{const{x:r}=e,{paddings:o,mode:s}=a,i=t.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Pi(r.shape,o,s):new Di(r.shape,o,s);return n.runWebGLProgram(i,[r],r.dtype)}},Bi=ya({opSnippet:"if (b == 0.0) return NAN;\n return mod(a, b);",packedOpSnippet:"\n vec4 result = mod(a, b);\n bvec4 isNaN = equal(b, vec4(0.0));\n \n result.r = isNaN.r ? NAN : result.r;\n result.g = isNaN.g ? NAN : result.g;\n result.b = isNaN.b ? NAN : result.b;\n result.a = isNaN.a ? NAN : result.a;\n\n return result;\n"}),Vi={kernelName:t.Mod,backendName:"webgl",kernelFunc:Bi};class Wi{constructor(e,t,n){this.variableNames=["probs"],this.customUniforms=[{name:"seed",type:"float"}],this.outputShape=[e,n],this.userCode=`\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 < ${t-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(${t-1}));\n }\n `}}const Ui=ya({opSnippet:"\nif (a == b) {\n return 1.0;\n};\nreturn a / b;",packedOpSnippet:"\n // vec4 one = vec4(equal(a, b));\n // return one + (vec4(1.0) - one) * a / b;\n vec4 result = a / b;\n if(a.x == b.x) {\n result.x = 1.;\n }\n if(a.y == b.y) {\n result.y = 1.;\n }\n if(a.z == b.z) {\n result.z = 1.;\n }\n if(a.w == b.w) {\n result.w = 1.;\n }\n\n return result;\n",checkOutOfBounds:!0}),Mi={kernelName:t.RealDiv,backendName:"webgl",kernelFunc:Ui},Gi="return a - b;",zi=ya({opSnippet:Gi,packedOpSnippet:Gi,supportsComplex:!0,cpuKernelImpl:Bn}),Xi={kernelName:t.Sub,backendName:"webgl",kernelFunc:zi};function Hi(e){const{inputs:n,backend:a,attrs:r}=e,{logits:o}=n,{dim:s}=r,i=t.util.parseAxisParam([s],o.shape),l=Ci({inputs:{x:o},backend:a,attrs:{reductionIndices:i,keepDims:!1}}),u=t.backend_util.expandShapeToKeepDim(l.shape,i),c=Aa({inputs:{x:l},backend:a,attrs:{shape:u}}),d=zi({inputs:{a:o,b:c},backend:a}),p=ds({inputs:{x:d},backend:a}),h=Va({inputs:{x:p},backend:a,attrs:{axis:i,keepDims:!1}}),f=Aa({inputs:{x:h},backend:a,attrs:{shape:u}}),x=Ui({inputs:{a:p,b:f},backend:a});return a.disposeIntermediateTensorInfo(l),a.disposeIntermediateTensorInfo(c),a.disposeIntermediateTensorInfo(d),a.disposeIntermediateTensorInfo(p),a.disposeIntermediateTensorInfo(h),a.disposeIntermediateTensorInfo(f),x}const ji={kernelName:t.Softmax,backendName:"webgl",kernelFunc:Hi};const Ki={kernelName:t.Multinomial,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{logits:r}=t,{numSamples:o,seed:s,normalized:i}=a,l=i?r:Hi({inputs:{logits:r},backend:n,attrs:{dim:r.shape.length-1}}),u=l.shape[0],c=l.shape[1],d=new Wi(u,c,o),p=[[s]],h=n.runWebGLProgram(d,[l],"int32",p);return i||n.disposeIntermediateTensorInfo(l),h}};const qi={kernelName:t.Neg,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{x:r}=n;if(a.shouldExecuteOnCPU([r])){const e=a.texData.get(r.dataId),[t,n]=gn(e.values,r.shape,r.dtype);return a.makeTensorInfo(n,r.dtype,t)}let o;return o=t.env().getBool("WEBGL_PACK_UNARY_OPERATIONS")?new ea(r.shape,"\n vec4 result = -x;\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"):new Qn(r.shape,"if (isnan(x)) return x;\n return -x;\n"),a.runWebGLProgram(o,[r],r.dtype)}},Yi=t.kernel_impls.nonMaxSuppressionV3Impl;const Qi={kernelName:t.NonMaxSuppressionV3,backendName:"webgl",kernelFunc:function(e){t.backend_util.warn("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");const{inputs:n,backend:a,attrs:r}=e,{boxes:o,scores:s}=n,{maxOutputSize:i,iouThreshold:l,scoreThreshold:u}=r,c=a.readSync(o.dataId),d=a.readSync(s.dataId),{selectedIndices:p}=Yi(c,d,i,l,u);return a.makeTensorInfo([p.length],"int32",new Int32Array(p))}},Zi=t.kernel_impls.nonMaxSuppressionV4Impl;const Ji={kernelName:t.NonMaxSuppressionV4,backendName:"webgl",kernelFunc:function(e){t.backend_util.warn("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");const{inputs:n,backend:a,attrs:r}=e,{boxes:o,scores:s}=n,{maxOutputSize:i,iouThreshold:l,scoreThreshold:u,padToMaxOutputSize:c}=r,d=a.readSync(o.dataId),p=a.readSync(s.dataId),{selectedIndices:h,validOutputs:f}=Zi(d,p,i,l,u,c);return[a.makeTensorInfo([h.length],"int32",new Int32Array(h)),a.makeTensorInfo([],"int32",new Int32Array([f]))]}},el=t.kernel_impls.nonMaxSuppressionV5Impl;const tl={kernelName:t.NonMaxSuppressionV5,backendName:"webgl",kernelFunc:function(e){t.backend_util.warn("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");const{inputs:n,backend:a,attrs:r}=e,{boxes:o,scores:s}=n,{maxOutputSize:i,iouThreshold:l,scoreThreshold:u,softNmsSigma:c}=r,d=a.readSync(o.dataId),p=a.readSync(s.dataId),h=i,f=l,x=u,m=c,{selectedIndices:g,selectedScores:b}=el(d,p,h,f,x,m);return[a.makeTensorInfo([g.length],"int32",new Int32Array(g)),a.makeTensorInfo([b.length],"float32",new Float32Array(b))]}};class nl{constructor(e,t,n,a){this.variableNames=["indices"],this.outputShape=[e,t],this.userCode=`\n void main() {\n ivec2 coords = getOutputCoords();\n int index = round(getIndices(coords.x));\n setOutput(mix(float(${a}), float(${n}),\n float(index == coords.y)));\n }\n `}}const al={kernelName:t.OneHot,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:a,attrs:r}=e,{indices:o}=n,{dtype:s,depth:i,onValue:l,offValue:u}=r,c=t.util.sizeFromShape(o.shape),d=new nl(c,i,l,u),p=Aa({inputs:{x:o},backend:a,attrs:{shape:[c]}}),h=a.runWebGLProgram(d,[p],s);a.disposeIntermediateTensorInfo(p);const f=Aa({inputs:{x:h},backend:a,attrs:{shape:[...o.shape,i]}});return a.disposeIntermediateTensorInfo(h),f}};function rl(e){const{inputs:t,backend:n}=e,{x:a}=t;if("complex64"===a.dtype){const e=Xr({inputs:{input:a},backend:n}),t=rl({inputs:{x:e},backend:n}),r=so({inputs:{input:a},backend:n}),o=rl({inputs:{x:r},backend:n}),s=ha({inputs:{real:t,imag:o},backend:n});return n.disposeIntermediateTensorInfo(e),n.disposeIntermediateTensorInfo(t),n.disposeIntermediateTensorInfo(r),n.disposeIntermediateTensorInfo(o),s}return ys({attrs:{shape:a.shape,dtype:a.dtype,value:"string"===a.dtype?"":0},backend:n})}const ol={kernelName:t.ZerosLike,backendName:"webgl",kernelFunc:rl};const sl={kernelName:t.OnesLike,backendName:"webgl",kernelFunc:function e(t){const{inputs:n,backend:a}=t,{x:r}=n;if("string"===r.dtype)throw new Error("onesLike is not supported under string dtype");if("complex64"===r.dtype){const t=Xr({inputs:{input:r},backend:a}),n=e({inputs:{x:t},backend:a}),o=so({inputs:{input:r},backend:a}),s=rl({inputs:{x:o},backend:a}),i=ha({inputs:{real:n,imag:s},backend:a});return a.disposeIntermediateTensorInfo(t),a.disposeIntermediateTensorInfo(n),a.disposeIntermediateTensorInfo(o),a.disposeIntermediateTensorInfo(s),i}return ys({attrs:{shape:r.shape,dtype:r.dtype,value:1},backend:a})}};const il={kernelName:t.Pack,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{axis:o}=r;if(1===n.length)return hs({inputs:{input:n[0]},backend:a,attrs:{dim:o}});const s=n[0].shape,i=n[0].dtype;n.forEach((e=>{t.util.assertShapesMatch(s,e.shape,"All tensors passed to stack must have matching shapes"),t.util.assert(i===e.dtype,(()=>"All tensors passed to stack must have matching dtypes"))}));const l=[],u=uo({inputs:n.map((e=>{const t=hs({inputs:{input:e},backend:a,attrs:{dim:o}});return l.push(t),t})),backend:a,attrs:{axis:o}});return l.forEach((e=>a.disposeIntermediateTensorInfo(e))),u}};class ll{constructor(e,t,n){this.variableNames=["x"],this.customUniforms=[{name:"value",type:"float"}],this.outputShape=t.map(((t,n)=>t[0]+e[n]+t[1]));const a=e.length,r=Se(a),o=t.map((e=>e[0])).join(","),s=t.map(((t,n)=>t[0]+e[n])).join(","),i=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,a);this.userCode=1!==a?`\n ${r} start = ${r}(${o});\n ${r} end = ${r}(${s});\n\n void main() {\n ${r} outC = getOutputCoords();\n if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) {\n setOutput(value);\n } else {\n ${r} coords = outC - start;\n setOutput(getX(${i}));\n }\n }\n `:`\n int start = ${o};\n int end = ${s};\n\n void main() {\n int outC = getOutputCoords();\n if (outC < start || outC >= end) {\n setOutput(value);\n } else {\n setOutput(getX(outC - start));\n }\n }\n `}}class ul{constructor(e,t,n){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0,this.customUniforms=[{name:"value",type:"float"}],this.outputShape=t.map(((t,n)=>t[0]+e[n]+t[1]));const a=e.length,r=Se(a),o=t.map((e=>e[0])).join(","),s=t.map(((t,n)=>t[0]+e[n])).join(","),i=zn("rc",a),l=zn("source",a),u=`${i[a-1]} < ${this.outputShape[a-1]}`,c=1===a?"source":`vec2(${l.slice(-2).join()})`,d=[`${r} rc = outputLoc;`,`${i[a-1]} += 1;\n if(${u}) {\n `,1===a?"":`}\n rc = outputLoc;\n ${i[a-2]} += 1;\n if(${i[a-2]} < ${this.outputShape[a-2]}) {`,1===a?"":` ${i[a-1]} += 1;\n if(${u}) {`],p=1===a?"rc < start || rc >= end":"any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))";let h="";for(let e=0,t=1===a?2:4;e<t;e++)h+=`\n ${d[e]}\n if (${p}) {\n result[${e}] = float(value);\n } else {\n ${r} source = rc - start;\n result[${e}] = getChannel(getX(${l.join()}), ${c});\n }\n `;h+=1===a?"} ":"}}",this.userCode=`\n const ${r} start = ${r}(${o});\n const ${r} end = ${r}(${s});\n\n void main() {\n ${r} outputLoc = getOutputCoords();\n vec4 result = vec4(0.);\n ${h}\n setOutput(result);\n }\n `}}const cl=e=>{const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{paddings:s,constantValue:i}=r;if(0===t.util.sizeFromShape(o.shape)){return ys({backend:a,attrs:{shape:s.map(((e,t)=>e[0]+o.shape[t]+e[1])),value:i,dtype:o.dtype}})}const l=t.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new ul(o.shape,s,i):new ll(o.shape,s,i),u=[[i]];return a.runWebGLProgram(l,[o],o.dtype,u)},dl={kernelName:t.PadV2,backendName:"webgl",kernelFunc:cl},pl=ya({opSnippet:"\n if(a < 0.0 && floor(b) < b){\n return NAN;\n }\n if (b == 0.0) {\n return 1.0;\n }\n return (round(mod(b, 2.0)) != 1) ?\n pow(abs(a), b) : sign(a) * pow(abs(a), b);\n",packedOpSnippet:"\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 // Ensure that a^0 = 1, including 0^0 = 1 as this correspond to TF and JS\n bvec4 isExpZero = equal(b, vec4(0.0));\n result.r = isExpZero.r ? 1.0 : result.r;\n result.g = isExpZero.g ? 1.0 : result.g;\n result.b = isExpZero.b ? 1.0 : result.b;\n result.a = isExpZero.a ? 1.0 : result.a;\n\n bvec4 isNaN1 = lessThan(a, vec4(0.0));\n bvec4 isNaN2 = lessThan(floor(b), b);\n bvec4 isNaN = bvec4(isNaN1.x && isNaN2.x, isNaN1.y && isNaN2.y, isNaN1.z && isNaN2.z, isNaN1.w && isNaN2.w);\n \n result.r = isNaN.r ? NAN : result.r;\n result.g = isNaN.g ? NAN : result.g;\n result.b = isNaN.b ? NAN : result.b;\n result.a = isNaN.a ? NAN : result.a;\n\n return result;\n"}),hl={kernelName:t.Pow,backendName:"webgl",kernelFunc:pl};const fl={kernelName:t.Prod,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{axis:s,keepDims:i}=r,l=o.shape.length,u=[],c=t.util.parseAxisParam(s,o.shape);let d=c;const p=t.backend_util.getAxesPermutation(d,l);let h,f=o;if(null!=p&&(f=Ua({inputs:{x:o},backend:a,attrs:{perm:p}}),d=t.backend_util.getInnerMostAxes(d.length,l),u.push(f)),t.backend_util.assertAxesAreInnerMostDims("prod",d,l),a.shouldExecuteOnCPU([f])){const e=a.texData.get(f.dataId).values,{outVals:t,outShape:n,outDtype:r}=vn(f.shape,f.dtype,e,d);h=a.makeTensorInfo(n,r,t)}else{const[e,n]=t.backend_util.computeOutAndReduceShapes(f.shape,d),r=t.util.sizeFromShape(n),s=Aa({inputs:{x:f},backend:a,attrs:{shape:[-1,r]}}),i=Da(s,t.sumOutType(o.dtype),"prod",a);h=Aa({inputs:{x:i},backend:a,attrs:{shape:e}}),u.push(s),u.push(i)}if(i){u.push(h);const e=t.backend_util.expandShapeToKeepDim(h.shape,c);h=Aa({inputs:{x:h},backend:a,attrs:{shape:e}})}return u.forEach((e=>a.disposeIntermediateTensorInfo(e))),h}};const xl={kernelName:t.RaggedGather,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{paramsNestedSplits:r,paramsDenseValues:o,indices:s}=t,{outputRaggedRank:i}=a,l=r.map((e=>n.readSync(e.dataId))),u=r.map((e=>e.shape)),c=n.readSync(o.dataId),d=n.readSync(s.dataId),[p,h,f]=Cn(l,u,c,o.shape,o.dtype,d,s.shape,i),x=p.map((e=>n.makeTensorInfo([e.length],"int32",e))),m=n.makeTensorInfo(f,o.dtype,h);return x.concat([m])}};const ml={kernelName:t.RaggedRange,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{starts:a,limits:r,deltas:o}=t,s=n.readSync(a.dataId),i=n.readSync(r.dataId),l=n.readSync(o.dataId),[u,c]=$n(s,a.shape,a.dtype,i,r.shape,l,o.shape);return[n.makeTensorInfo([u.length],"int32",u),n.makeTensorInfo([c.length],a.dtype,c)]}};const gl={kernelName:t.RaggedTensorToTensor,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{shape:r,values:o,defaultValue:s,rowPartitionTensors:i}=t,{rowPartitionTypes:l}=a,u=n.readSync(r.dataId),c=n.readSync(o.dataId),d=n.readSync(s.dataId),p=i.map((e=>n.readSync(e.dataId))),h=i.map((e=>e.shape)),[f,x]=yn(u,r.shape,c,o.shape,o.dtype,d,s.shape,p,h,l);return n.makeTensorInfo(f,o.dtype,x)}},bl=e=>{const{backend:t,attrs:n}=e,{start:a,stop:r,step:o,dtype:s}=n,i=In(a,r,o,s);return t.makeTensorInfo([i.length],s,i)},vl={kernelName:t.Range,backendName:"webgl",kernelFunc:bl},Cl=$a({opSnippet:"return 1.0 / x;"}),$l={kernelName:t.Reciprocal,backendName:"webgl",kernelFunc:Cl},yl=$a({opSnippet:"if (isnan(x)) return x;\n return (x < 0.0) ? 0.0 : x;\n",packedOpSnippet:"\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"}),Il={kernelName:t.Relu,backendName:"webgl",kernelFunc:yl},wl=$a({opSnippet:"if (isnan(x)) return x;\n return (x < 0.0) ? 0.0 : min(6.0, x);\n",packedOpSnippet:"\n vec4 result = min(x, vec4(6.)) * 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"}),Sl={kernelName:t.Relu6,backendName:"webgl",kernelFunc:wl};class kl{constructor(e,t,n,a,r){this.variableNames=["A"],this.outputShape=[];const[o,s,i,l]=e;this.outputShape=[o,t,n,l];const u=[a&&t>1?s-1:s,a&&n>1?i-1:i],c=[a&&t>1?t-1:t,a&&n>1?n-1:n];let d;d=r?"(vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC - vec2(0.5)":"vec2(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n ${u[0]/c[0]},\n ${u[1]/c[1]});\n const vec2 inputShapeRC = vec2(${s}.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 = ${d};\n\n // Compute the four integer indices.\n ivec2 sourceFloorRC = ivec2(max(sourceFracIndexRC, vec2(0.0)));\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 `}}class Rl{constructor(e,t,n,a,r){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[];const[o,s,i,l]=e;this.outputShape=[o,t,n,l];const u=[a&&t>1?s-1:s,a&&n>1?i-1:i],c=[a&&t>1?t-1:t,a&&n>1?n-1:n];let d;d=r?"(vec3(yRC) + vec3(0.5)) * effectiveInputOverOutputRatioRC - vec3(0.5)":"vec3(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n const vec3 effectiveInputOverOutputRatioRC = vec3(\n ${u[0]/c[0]},\n ${u[1]/c[1]},\n ${u[1]/c[1]});\n const vec3 inputShapeRC = vec3(${s}.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 = ${d};\n\n // Compute the four integer indices.\n ivec3 sourceFloorRC = ivec3(max(sourceFracIndexRC, vec3(0.0)));\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 < ${l-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 `}}const Tl={kernelName:t.ResizeBilinear,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{images:o}=n,{alignCorners:s,halfPixelCenters:i,size:l}=r,[u,c]=l,d=t.env().getBool("WEBGL_PACK_IMAGE_OPERATIONS")?new Rl(o.shape,u,c,s,i):new kl(o.shape,u,c,s,i);return a.runWebGLProgram(d,[o],"float32")}};class Nl{constructor(e,t,n){this.variableNames=["dy"],this.outputShape=[],this.outputShape=t;const[,a,r]=t,[,o,s]=e,i=[n&&o>1?a-1:a,n&&s>1?r-1:r],l=[n&&o>1?o-1:o,n&&s>1?s-1:s],u=i[0]/l[0],c=i[1]/l[1],d=1/u,p=1/c,h=2*Math.ceil(d)+2,f=2*Math.ceil(p)+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(${u});\n const float widthScale = float(${c});\n\n const float invHeightScale = float(${d});\n const float invWidthScale = float(${p});\n\n const int winHeight = int(${h});\n const int winWidth = int(${f});\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 >= ${o}) {\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 >= ${s}) {\n continue;\n }\n\n float dxR = float(dyR) * heightScale;\n int topDxRIndex = int(floor(dxR));\n int bottomDxRIndex = int(min(ceil(dxR), ${a-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), ${r-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 `}}const El={kernelName:t.ResizeBilinearGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{images:r,dy:o}=t,{alignCorners:s}=a,i=new Nl(o.shape,r.shape,s);return n.runWebGLProgram(i,[o],o.dtype)}};class Al{constructor(e,t,n,a,r){this.variableNames=["A"],this.outputShape=[];const[o,s,i,l]=e;this.outputShape=[o,t,n,l];const u=[a&&t>1?s-1:s,a&&n>1?i-1:i],c=[a&&t>1?t-1:t,a&&n>1?n-1:n],d=a?"0.5":"0.0";let p;p=r?"max((vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC, vec2(0.0))":"vec2(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n ${u[0]/c[0]},\n ${u[1]/c[1]});\n const vec2 inputShapeRC = vec2(${s}.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 = ${p};\n\n // Compute the coordinators of nearest neighbor point.\n ivec2 sourceNearestRC = ivec2(\n min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${d})));\n float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d);\n\n setOutput(newValue);\n }\n `}}class _l{constructor(e,t,n,a,r){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[];const[o,s,i,l]=e;this.outputShape=[o,t,n,l];const u=[a&&t>1?s-1:s,a&&n>1?i-1:i],c=[a&&t>1?t-1:t,a&&n>1?n-1:n],d=a?"0.5":"0.0";let p;p=r?"max((vec3(yRC) + vec3(0.5)) * effectiveInputOverOutputRatioRC, vec3(0.0))":"vec3(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n const vec3 effectiveInputOverOutputRatioRC = vec3(\n ${u[0]/c[0]},\n ${u[1]/c[1]},\n ${u[1]/c[1]});\n const vec3 inputShapeRC = vec3(${s}.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 = ${p};\n\n // Compute the coordinators of nearest neighbor point.\n ivec3 sourceNearestRC = ivec3(\n min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${d})));\n\n // Should we calculate next column and row elements in 2x2 packed cell.\n bool hasNextCol = d < ${l-1};\n bool hasNextRow = coords.z < ${n-1};\n\n vec4 newValue = vec4(\n getAValue(b, sourceNearestRC.x, sourceNearestRC.y, d),\n hasNextCol ? getAValue(b, sourceNearestRC.x, sourceNearestRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceNearestRC.x, sourceNearestRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceNearestRC.x, sourceNearestRC.z, d + 1) : 0.0);\n\n setOutput(newValue);\n }\n `}}const Ol={kernelName:t.ResizeNearestNeighbor,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{images:o}=n,{alignCorners:s,halfPixelCenters:i,size:l}=r,[u,c]=l,d=t.env().getBool("WEBGL_PACK_IMAGE_OPERATIONS")?new _l(o.shape,u,c,s,i):new Al(o.shape,u,c,s,i);return a.runWebGLProgram(d,[o],o.dtype)}};class Fl{constructor(e,t,n){this.variableNames=["dy"],this.outputShape=[],this.outputShape=t;const[,a,r]=t,[,o,s]=e,i=[n&&o>1?a-1:a,n&&s>1?r-1:r],l=[n&&o>1?o-1:o,n&&s>1?s-1:s],u=i[0]/l[0],c=i[1]/l[1],d=1/u,p=1/c,h=2*Math.ceil(d)+2,f=2*Math.ceil(p)+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(${u});\n const float widthScale = float(${c});\n\n const float invHeightScale = float(${d});\n const float invWidthScale = float(${p});\n\n const int winHeight = int(${h});\n const int winWidth = int(${f});\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 >= ${o}) {\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 >= ${s}) {\n continue;\n }\n\n float sourceFracRow =\n float(${i[0]}) *\n (float(dyR) / float(${l[0]}));\n\n float sourceFracCol =\n float(${i[1]}) *\n (float(dyC) / float(${l[1]}));\n\n int sourceNearestRow = int(min(\n float(int(${a}) - 1),\n ${n} ? float(round(sourceFracRow)) :\n float(floor(sourceFracRow))));\n\n int sourceNearestCol = int(min(\n float(int(${r}) - 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 `}}const Dl={kernelName:t.ResizeNearestNeighborGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{images:r,dy:o}=t,{alignCorners:s}=a,i=new Fl(o.shape,r.shape,s);return n.runWebGLProgram(i,[o],o.dtype)}};class Pl{constructor(e,t){this.variableNames=["x"];const n=e.length;if(n>4)throw new Error(`WebGL backend: Reverse of rank-${n} tensor is not yet supported`);if(this.outputShape=e,1===n)return void(this.userCode=`\n void main() {\n int coord = getOutputCoords();\n setOutput(getX(${e[0]} - coord - 1));\n }\n `);const a=e.map(((n,a)=>(n=>-1!==t.indexOf(n)&&1!==e[n]?`${e[n]} - coords[${n}] - 1`:`coords[${n}]`)(a))).join(","),r=Se(n);this.userCode=`\n void main() {\n ${r} coords = getOutputCoords();\n setOutput(getX(${a}));\n }\n `}}class Ll{constructor(e,t){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0;const n=e.length;if(n>4)throw new Error(`WebGL backend: Reverse of rank-${n} tensor is not yet supported`);this.outputShape=e;const a=zn("rc",n),r=`${a[n-1]} + 1 < ${this.outputShape[n-1]}`,o=`${a[n-2]} + 1 < ${this.outputShape[n-2]}`,s=Se(n);function i(n){const a=e.map(((a,r)=>function(n,a){return-1!==t.indexOf(n)&&1!==e[n]?`${e[n]} - ${a[n]} - 1`:`${a[n]}`}(r,n)));return`getChannel(getX(${a.join(",")}), vec2(${a.slice(-2).join(",")}))`}this.userCode=1===n?`\n void main(){\n int rc = getOutputCoords();\n vec4 result = vec4(0.);\n result.r = getChannel(getX(${e[0]} - rc - 1),\n ${e[0]} - rc - 1);\n if(${r}){\n result.g = getChannel(getX(${e[0]} - (rc + 1) - 1),\n ${e[0]} - (rc + 1) - 1);\n }\n setOutput(result);\n }\n `:`\n void main() {\n ${s} rc = getOutputCoords();\n vec4 result = vec4(0.);\n result.r = ${function(e){return i(e)}(a.slice())};\n if(${r}){\n result.g = ${function(e){return e[n-1]="("+e[n-1]+" + 1)",i(e)}(a.slice())};\n }\n if(${o}) {\n result.b = ${function(e){return e[n-2]="("+e[n-2]+" + 1)",i(e)}(a.slice())};\n if(${r}) {\n result.a = ${function(e){return e[n-1]="("+e[n-1]+" + 1)",e[n-2]="("+e[n-2]+" + 1)",i(e)}(a.slice())};\n }\n }\n setOutput(result);\n }\n `}}const Bl={kernelName:t.Reverse,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{dims:s}=r,i=o.shape.length,l=t.util.parseAxisParam(s,o.shape);if(0===i)return da({inputs:{x:o},backend:a});const u=t.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Ll(o.shape,l):new Pl(o.shape,l);return a.runWebGLProgram(u,[o],o.dtype)}};class Vl{constructor(e,t){this.variableNames=["Image"],this.outputShape=[],this.customUniforms=[{name:"params",type:"vec4"}];const n=e[1],a=e[2];this.outputShape=e;let r="";r="number"==typeof t?`float outputValue = ${t.toFixed(2)};`:`\n vec3 fill = vec3(${t.join(",")});\n float outputValue = fill[coords[3]];`,this.userCode=`\n void main() {\n ivec4 coords = getOutputCoords();\n int x = coords[2];\n int y = coords[1];\n float coordXFloat = (float(x) - params[0]) * params[3] -\n (float(y) - params[1]) * params[2];\n float coordYFloat = (float(x) - params[0]) * params[2] +\n (float(y) - params[1]) * params[3];\n int coordX = int(round(coordXFloat + params[0]));\n int coordY = int(round(coordYFloat + params[1]));\n ${r}\n if(coordX >= 0 && coordX < ${a} && coordY >= 0 && coordY < ${n}) {\n outputValue = getImage(coords[0], coordY, coordX, coords[3]);\n }\n setOutput(outputValue);\n }\n `}}const Wl={kernelName:t.RotateWithOffset,backendName:"webgl",kernelFunc:({inputs:e,attrs:n,backend:a})=>{const{image:r}=e,{radians:o,fillValue:s,center:i}=n,l=a,u=new Vl(r.shape,s),[c,d]=t.backend_util.getImageCenter(i,r.shape[1],r.shape[2]),p=[[c,d,Math.sin(o),Math.cos(o)]];return l.runWebGLProgram(u,[r],r.dtype,p)}},Ul=$a({opSnippet:"\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"}),Ml={kernelName:t.Round,backendName:"webgl",kernelFunc:Ul},Gl=$a({opSnippet:"return inversesqrt(x);",cpuKernelImpl:wn}),zl={kernelName:t.Rsqrt,backendName:"webgl",kernelFunc:Gl};class Xl{constructor(e,t,n,a,r,o,s=!0,i=!1){this.variableNames=["updates","indices","defaultValue"],this.outputShape=o;const l=Se(r.length),u=Se(o.length);let c="";1===n?c="i":2===n&&(c="i, j");const d=`getIndices(${c})`;let p="";1===a?p="i":2===a&&(p="i, coords[1]");const h=`getUpdates(${p})`;let f="";i&&(f="coords[0], coords[1]");const x=`getDefaultValue(${f})`,m=t>1?"strides[j]":"strides";this.userCode=`\n ${l} strides = ${l}(${r});\n\n void main() {\n ${u} coords = getOutputCoords();\n float sum = 0.0;\n bool found = false;\n for (int i = 0; i < ${e}; i++) {\n int flattenedIndex = 0;\n for (int j = 0; j < ${t}; j++) {\n int index = round(${d});\n flattenedIndex += index * ${m};\n }\n if (flattenedIndex == coords[0]) {\n sum += ${h};\n found = true;\n }\n }\n setOutput(mix(${x}, sum, float(found)));\n }\n `}}class Hl{constructor(e,t,n,a,r,o,s=!0,i=!1){this.variableNames=["updates","indices","defaultValue"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=o;const l=Se(r.length),u=Se(o.length);let c="";1===n?c="i":2===n&&(c="i, j");const d=`getIndices(${c})`;let p="";1===a?p="i":2===a&&(p="i, coords[1]");const h=`getUpdates(${p})`;let f="";i&&(f="coords[0], coords[1]");const x=`getDefaultValue(${f})`,m=t>1?"strides[j]":"strides",g=t>1?"strides[j + 1]":"strides";this.userCode=`\n ${l} strides = ${l}(${r});\n\n void main() {\n ${u} coords = getOutputCoords();\n vec4 sum = vec4(0.);\n vec4 found = vec4(0.);\n for (int i = 0; i < ${e}; i+=2) {\n ivec2 flattenedIndex = ivec2(0);\n for (int j = 0; j < ${t}; j+=2) {\n ivec4 index = round(${d});\n flattenedIndex += index.xz * ${m};\n if (j + 1 < ${t}) {\n flattenedIndex += index.yw * ${g};\n }\n }\n if (flattenedIndex[0] == coords[0] || flattenedIndex[1] == coords[0] ||\n flattenedIndex[0] == coords[0] + 1 || flattenedIndex[1] == coords[0] + 1) {\n vec4 updVals = ${h};\n if (flattenedIndex[0] == coords[0]) {\n sum.xy += updVals.xy;\n found.xy = vec2(1.);\n } else if (flattenedIndex[0] == coords[0] + 1) {\n sum.zw += updVals.xy;\n found.zw = vec2(1.);\n }\n if (flattenedIndex[1] == coords[0]) {\n sum.xy += updVals.zw;\n found.xy = vec2(1.);\n } else if (flattenedIndex[1] == coords[0] + 1) {\n sum.zw += updVals.zw;\n found.zw = vec2(1.);\n }\n }\n }\n setOutput(mix(${x}, sum, found));\n }\n `}}const jl={kernelName:t.ScatterNd,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{indices:o,updates:s}=n,{shape:i}=r,{sliceRank:l,numUpdates:u,sliceSize:c,strides:d,outputSize:p}=t.backend_util.calculateShapes(s,o,i),h=[p/c,c];if(0===p)return a.makeTensorInfo(i,o.dtype);const f=Aa({inputs:{x:o},backend:a,attrs:{shape:[u,l]}}),x=Aa({inputs:{x:s},backend:a,attrs:{shape:[u,c]}}),m=a.makeTensorInfo([],"float32",new Float32Array([0]));let g;g=t.env().getBool("WEBGL_PACK")?new Hl(u,l,f.shape.length,x.shape.length,d,h):new Xl(u,l,f.shape.length,x.shape.length,d,h);const b=a.runWebGLProgram(g,[x,f,m],x.dtype),v=Aa({inputs:{x:b},backend:a,attrs:{shape:i}});return a.disposeIntermediateTensorInfo(f),a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(b),a.disposeIntermediateTensorInfo(m),v}};class Kl{constructor(e,n,a,r){this.variableNames=["sortedSequence","values"],this.customUniforms=[{name:"numInputs",type:"int"}],this.outputShape=[e,a];const o=`for (int i = 0; i < ${Math.ceil(Math.log2(n+1))}; ++i) { if (left >= right) break;`,s=2===t.env().getNumber("WEBGL_VERSION")?"while (left < right) {":o,i="left"===r?"<":"<=";this.userCode=`\n int findBound(int batch, float value) {\n int left = 0;\n int right = numInputs;\n int mid;\n ${s}\n mid = (left + right) / 2;\n if (getSortedSequence(batch, mid) ${i} value) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n return right;\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int valueIndex = coords[1];\n\n float value = getValues(batch, valueIndex);\n\n setOutput(float(findBound(batch, value)));\n }\n `}}const ql={kernelName:t.SearchSorted,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{sortedSequence:r,values:o}=t,{side:s}=a,i=new Kl(r.shape[0],r.shape[1],o.shape[1],s),l=[[r.shape[1]]];return n.runWebGLProgram(i,[r,o],"int32",l)}};class Yl{constructor(e,t,n){let a,r;if(this.variableNames=["c","a","b"],this.outputShape=t,n>4)throw Error(`Where for rank ${n} is not yet supported`);if(1===n)r="resRC",a="resRC";else{const n=["resRC.x","resRC.y","resRC.z","resRC.w"],o=[],s=[];for(let a=0;a<t.length;a++)s.push(`${n[a]}`),a<e&&o.push(`${n[a]}`);a=o.join(),r=s.join()}const o=Se(n);this.userCode=`\n void main() {\n ${o} resRC = getOutputCoords();\n float cVal = getC(${a});\n if (cVal >= 1.0) {\n setOutput(getA(${r}));\n } else {\n setOutput(getB(${r}));\n }\n }\n `}}const Ql={kernelName:t.Select,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a}=e,{condition:r,t:o,e:s}=n,i=new Yl(r.shape.length,o.shape,o.shape.length);return a.runWebGLProgram(i,[r,o,s],t.upcastType(o.dtype,s.dtype))}},Zl=$a({opSnippet:`\n // Stable and Attracting Fixed Point (0, 1) for Normalized Weights.\n // see: https://arxiv.org/abs/1706.02515\n float scaleAlpha = ${t.backend_util.SELU_SCALEALPHA};\n float scale = ${t.backend_util.SELU_SCALE};\n return (x >= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);\n`}),Jl={kernelName:t.Selu,backendName:"webgl",kernelFunc:Zl},eu=$a({opSnippet:"if (isnan(x)) return x;\n return 1.0 / (1.0 + exp(-1.0 * x));\n",packedOpSnippet:"\n vec4 result = 1.0 / (1.0 + exp(-1.0 * x));\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",cpuKernelImpl:kn}),tu={kernelName:t.Sigmoid,backendName:"webgl",kernelFunc:eu},nu=$a({opSnippet:"\n if (isnan(x)) { return 0.0; }\n return sign(x);\n"}),au={kernelName:t.Sign,backendName:"webgl",kernelFunc:nu},ru=$a({opSnippet:"if (isnan(x)) return x;\n return sin(x);\n",packedOpSnippet:`\n vec4 result = sin(x);\n bvec4 isNaN = isnan(x);\n ${ua}\n return result;\n`}),ou={kernelName:t.Sin,backendName:"webgl",kernelFunc:ru},su=$a({opSnippet:"\n float e2x = exp(x);\n return (e2x - 1.0 / e2x) / 2.0;\n"}),iu={kernelName:t.Sinh,backendName:"webgl",kernelFunc:su},lu=$a({opSnippet:"\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"}),uu={kernelName:t.Softplus,backendName:"webgl",kernelFunc:lu},cu={kernelName:t.SpaceToBatchND,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{blockShape:s,paddings:i}=r;t.util.assert(o.shape.length<=4,(()=>"spaceToBatchND for rank > 4 with a WebGL backend not implemented yet"));const l=s.reduce(((e,t)=>e*t)),u=[[0,0]];u.push(...i);for(let e=1+s.length;e<o.shape.length;++e)u.push([0,0]);const c=[],d=cl({inputs:{x:o},backend:a,attrs:{paddings:u,constantValue:0}}),p=t.backend_util.getReshaped(d.shape,s,l,!1),h=t.backend_util.getPermuted(p.length,s.length,!1),f=t.backend_util.getReshapedPermuted(d.shape,s,l,!1),x=Aa({inputs:{x:d},backend:a,attrs:{shape:p}}),m=Ua({inputs:{x:x},backend:a,attrs:{perm:h}}),g=Aa({inputs:{x:m},backend:a,attrs:{shape:f}});return c.push(d),c.push(x),c.push(m),c.forEach((e=>a.disposeIntermediateTensorInfo(e))),g}};const du={kernelName:t.SparseFillEmptyRows,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{indices:a,values:r,denseShape:o,defaultValue:s}=t;if(1!==o.shape.length)throw new Error(`Dense shape must be a vector, saw:\n ${o.shape}`);if(2!==a.shape.length)throw new Error(`Indices must be a matrix, saw:\n ${a.shape}`);if(1!==r.shape.length)throw new Error(`Values must be a vector, saw:\n ${r.shape}`);if(0!==s.shape.length)throw new Error(`Default value must be a scalar, saw:\n ${s.shape}`);const i=n.readSync(a.dataId),l=n.readSync(r.dataId),u=n.readSync(o.dataId),c=n.readSync(s.dataId)[0],[d,p,h,f,x]=Nn(i,a.shape,a.dtype,l,r.dtype,u,c);return[n.makeTensorInfo(p,a.dtype,d),n.makeTensorInfo([p[0]],r.dtype,h),n.makeTensorInfo([f.length],"bool",new Uint8Array(f.map((e=>Number(e))))),n.makeTensorInfo([x.length],a.dtype,new Int32Array(x))]}};const pu={kernelName:t.SparseReshape,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{inputIndices:a,inputShape:r,newShape:o}=t;if(2!==a.shape.length)throw new Error(`Input indices should be a matrix but received shape ${a.shape}`);if(1!==r.shape.length)throw new Error(`Input shape should be a vector but received shape ${r.shape}`);if(1!==o.shape.length)throw new Error(`Target shape should be a vector but received shape ${o.shape}`);const s=Array.from(n.readSync(r.dataId)),i=n.readSync(a.dataId),l=Array.from(n.readSync(o.dataId)),[u,c,d]=En(i,a.shape,a.dtype,s,l);return[n.makeTensorInfo(c,a.dtype,u),n.makeTensorInfo([d.length],o.dtype,new Int32Array(d))]}};const hu={kernelName:t.SparseSegmentMean,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{data:a,indices:r,segmentIds:o}=t;if(a.shape.length<1)throw new Error("Data should be at least 1 dimensional but received scalar");if(1!==r.shape.length)throw new Error(`Indices should be a vector but received shape\n ${r.shape}`);if(1!==o.shape.length)throw new Error(`Segment ids should be a vector but received shape\n ${o.shape}`);const s=n.readSync(a.dataId),i=n.readSync(r.dataId),l=n.readSync(o.dataId),[u,c]=An(s,a.shape,a.dtype,i,l,!0);return n.makeTensorInfo(c,a.dtype,u)}};const fu={kernelName:t.SparseSegmentSum,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n}=e,{data:a,indices:r,segmentIds:o}=t;if(a.shape.length<1)throw new Error("Data should be at least 1 dimensional but received scalar");if(1!==r.shape.length)throw new Error(`Indices should be a vector but received shape\n ${r.shape}`);if(1!==o.shape.length)throw new Error(`Segment ids should be a vector but received shape\n ${o.shape}`);const s=n.readSync(a.dataId),i=n.readSync(r.dataId),l=n.readSync(o.dataId),[u,c]=An(s,a.shape,a.dtype,i,l);return n.makeTensorInfo(c,a.dtype,u)}};const xu={kernelName:t.SparseToDense,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{sparseIndices:o,sparseValues:s,defaultValue:i}=n,{outputShape:l}=r,{sliceRank:u,numUpdates:c,sliceSize:d,strides:p,outputSize:h}=t.backend_util.calculateShapes(s,o,l);if("string"===s.dtype){const e=a.bufferSync(o),n=a.bufferSync(s),r=t.util.decodeString(a.readSync(i.dataId)[0]),f=Sn(e,n,l,h,d,c,u,p,r,false);return a.makeTensorInfo(l,f.dtype,f.values)}const f=new Xl(c,u,o.shape.length,s.shape.length,p,[h,1],false),x=a.runWebGLProgram(f,[s,o,i],s.dtype),m=Aa({inputs:{x:x},backend:a,attrs:{shape:l}});return a.disposeIntermediateTensorInfo(x),m}};const mu={kernelName:t.SplitV,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{numOrSizeSplits:s,axis:i}=r,l=t.util.parseAxisParam(i,o.shape)[0],u=t.backend_util.prepareSplitSize(o,s,l),c=o.shape.length,d=new Array(c).fill(0),p=o.shape.slice();return u.map((e=>{const t=[...p];t[l]=e;const n=Lr({inputs:{x:o},backend:a,attrs:{begin:d,size:t}});return d[l]+=e,n}))}},gu="return sqrt(x);",bu=$a({opSnippet:gu,packedOpSnippet:gu,cpuKernelImpl:_n}),vu={kernelName:t.Sqrt,backendName:"webgl",kernelFunc:bu},Cu=$a({opSnippet:"return x * x;"}),$u={kernelName:t.Square,backendName:"webgl",kernelFunc:Cu},yu="return (a - b) * (a - b);",Iu=ya({opSnippet:yu,packedOpSnippet:yu}),wu={kernelName:t.SquaredDifference,backendName:"webgl",kernelFunc:Iu};const Su={kernelName:t.StaticRegexReplace,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n;if("string"!==o.dtype)throw new Error("Input must be of datatype string");const s=a.readSync(o.dataId),i=t.backend_util.fromUint8ToStringArray(s),l=On(i,"string",r);return a.makeTensorInfo(o.shape,"string",l)}};const ku={kernelName:t.Step,backendName:"webgl",kernelFunc:function({inputs:e,attrs:t,backend:n}){const{x:a}=e,r=`if (isnan(x)) return x;\n return x > 0.0 ? 1.0 : float(${t.alpha});\n `,o=new Qn(a.shape,r);return n.runWebGLProgram(o,[a],a.dtype)}};class Ru{constructor(e,t,n){this.variableNames=["x"],this.outputShape=n;const a=n.length,r=Se(n.length),o=Se(n.length);let s="";if(1===a)s="coords * strides + begin";else{let e=0;s=n.map(((t,a)=>(e++,1===n.length?`coords * strides[${a}] + begin[${a}]`:`coords[${e-1}] * strides[${a}] + begin[${a}]`))).join(",")}this.userCode=`\n ${r} begin = ${r}(${e});\n ${r} strides = ${r}(${t});\n\n void main() {\n ${o} coords = getOutputCoords();\n setOutput(getX(${s}));\n }\n `}}const Tu={kernelName:t.StridedSlice,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{begin:s,end:i,strides:l,beginMask:u,endMask:c,ellipsisMask:d,newAxisMask:p,shrinkAxisMask:h}=r,{finalShapeSparse:f,finalShape:x,isIdentity:m,sliceDim0:g,isSimpleSlice:b,begin:v,end:C,strides:$}=t.slice_util.sliceInfo(o.shape,s,i,l,u,c,d,p,h);let y;if(m)y=Aa({inputs:{x:o},backend:a,attrs:{shape:x}});else if(g||b){t.util.assert(o.shape.length>=1,(()=>`Input must have rank at least 1, got: ${o.shape.length}`));const e=t.slice_util.computeOutShape(v,C,$),n=Lr({inputs:{x:o},backend:a,attrs:{begin:v,size:e}});y=Aa({inputs:{x:n},backend:a,attrs:{shape:x}}),a.disposeIntermediateTensorInfo(n)}else{if(a.shouldExecuteOnCPU([o])){const e=a.readSync(o.dataId),n=t.buffer(o.shape,o.dtype,e),r=Fn(f,n,$,v);y=a.makeTensorInfo(x,o.dtype,r.values)}else{const e=new Ru(v,$,f);y=a.runWebGLProgram(e,[o],o.dtype)}}const I=Aa({inputs:{x:y},backend:a,attrs:{shape:x}});return a.disposeIntermediateTensorInfo(y),I}};const Nu={kernelName:t.StringNGrams,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{separator:r,nGramWidths:o,leftPad:s,rightPad:i,padWidth:l,preserveShortSequences:u}=a,{data:c,dataSplits:d}=t,p=n.readSync(c.dataId),h=n.readSync(d.dataId),[f,x]=Dn(p,h,r,o,s,i,l,u);return[n.makeTensorInfo([f.length],"string",f),n.makeTensorInfo(d.shape,"int32",x)]}};const Eu={kernelName:t.StringSplit,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{skipEmpty:r}=a,{input:o,delimiter:s}=t;if("string"!==o.dtype)throw new Error("Input must be of datatype string");if(1!==o.shape.length)throw new Error(`Input must be a vector, got shape: ${o.shape}`);if(0!==s.shape.length)throw new Error(`Delimiter must be a scalar, got shape: ${s.shape}`);const i=n.readSync(o.dataId),l=n.readSync(s.dataId)[0],[u,c,d]=Pn(i,l,r),p=c.length;return[n.makeTensorInfo([p,2],"int32",u),n.makeTensorInfo([p],"string",c),n.makeTensorInfo([2],"int32",new Int32Array(d))]}};const Au={kernelName:t.StringToHashBucketFast,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{numBuckets:r}=a,{input:o}=t;if("string"!==o.dtype)throw new Error("Input must be of datatype string");if(r<=0)throw new Error("Number of buckets must be at least 1");const s=n.readSync(o.dataId),i=Ln(s,r);return n.makeTensorInfo(o.shape,"int32",i)}},_u=$a({opSnippet:"return tan(x);"}),Ou={kernelName:t.Tan,backendName:"webgl",kernelFunc:_u},Fu=$a({opSnippet:"\n float e2x = exp(-2.0 * abs(x));\n return sign(x) * (1.0 - e2x) / (1.0 + e2x);\n"}),Du={kernelName:t.Tanh,backendName:"webgl",kernelFunc:Fu};const Pu={kernelName:t.TensorScatterUpdate,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{tensor:o,indices:s,updates:i}=n,{sliceRank:l,numUpdates:u,sliceSize:c,strides:d,outputSize:p}=t.backend_util.calculateShapes(i,s,o.shape),h=[p/c,c];if(0===p)return a.makeTensorInfo(o.shape,s.dtype);const f=Aa({inputs:{x:s},backend:a,attrs:{shape:[u,l]}}),x=Aa({inputs:{x:i},backend:a,attrs:{shape:[u,c]}}),m=Aa({inputs:{x:o},backend:a,attrs:{shape:h}}),g=new Xl(u,l,f.shape.length,x.shape.length,d,h,!1,!0),b=a.runWebGLProgram(g,[x,f,m],m.dtype),v=Aa({inputs:{x:b},backend:a,attrs:{shape:o.shape}});return a.disposeIntermediateTensorInfo(f),a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(m),a.disposeIntermediateTensorInfo(b),v}};class Lu{constructor(e,t){this.variableNames=["A"];const n=new Array(e.length);for(let a=0;a<n.length;a++)n[a]=e[a]*t[a];this.outputShape=n,this.rank=n.length;const a=Se(this.rank),r=function(e){const t=e.length;if(t>5)throw Error(`Tile for rank ${t} is not yet supported`);if(1===t)return`imod(resRC, ${e[0]})`;const n=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u"],a=[];for(let t=0;t<e.length;t++)a.push(`imod(${n[t]}, ${e[t]})`);return a.join()}(e);this.userCode=`\n void main() {\n ${a} resRC = getOutputCoords();\n setOutput(getA(${r}));\n }\n `}}function Bu(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{reps:s}=r;if("string"===o.dtype||o.shape.length>5){const e=a.readSync(o.dataId),n="string"===o.dtype?e.map((e=>t.util.decodeString(e))):e,r=t.buffer(o.shape,o.dtype,n),i=Vn(r,s);return a.makeTensorInfo(i.shape,i.dtype,i.values)}const i=new Lu(o.shape,s);return a.runWebGLProgram(i,[o],o.dtype)}const Vu={kernelName:t.Tile,backendName:"webgl",kernelFunc:Bu};class Wu{constructor(e){this.variableNames=["x","indices"],this.customUniforms=[{name:"n",type:"int"},{name:"firstPass",type:"int"},{name:"negativeInf",type:"float"},{name:"dir",type:"int"},{name:"inc",type:"int"}],this.outputShape=e,this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int elemIdx = coords[1];\n\n // We compare elements pair-wise within a group of size 2 * inc.\n // The comparing rule for each group alternates between ascending\n // and descending. Within each group, we compare each pair at\n // positions i and i+inc. To decide whether an element at position i\n // is x0 or x1, we mod it by 2 * inc, if the result is smaller than\n // inc, it is in the first half of the group, we denote it as x0,\n // otherwise we denote it as x1.\n // For example, as shown in the Bitonic top K paper referenced above,\n // Figure5(a) shows that element[1] is in the\n // second half of the group when group size is 2, but it is in the\n // first half of the group when group size is 4.\n\n bool isFirstInPair = imod(elemIdx, 2 * inc) < inc;\n int i = isFirstInPair ? elemIdx : elemIdx - inc;\n\n int i0 = firstPass == 1 ? i : int(getIndices(batch, i));\n int i1 = firstPass == 1 ? i + inc : int(getIndices(batch, i + inc));\n float x0 = i0 < n ? getX(batch, i0) : negativeInf;\n float x1 = i1 < n ? getX(batch, i1) : negativeInf;\n\n // Denotes which direction indices are in (ascending or descending).\n bool reverse = imod(elemIdx, 2 * dir) >= dir;\n bool isGreater = x0 > x1 || (x0 == x1 && i1 > i0);\n if (reverse == isGreater) { // Elements in opposite order of direction\n int iTemp = i0;\n i0 = i1;\n i1 = iTemp;\n }\n if (isFirstInPair) {\n setOutput(float(i0));\n } else {\n setOutput(float(i1));\n }\n }\n "}}class Uu{constructor(e){this.variableNames=["x","indices"],this.customUniforms=[{name:"n",type:"int"},{name:"firstPass",type:"int"},{name:"k",type:"int"}],this.outputShape=e,this.userCode="\n void main() {\n // Takes max of indices (0, k), (1, k + 1), (2, k + 2) ...\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int elemIdx = coords[1];\n\n // The output size is half of the previous size.\n // If the previous sequence is | | | | _ _ _ _ | | | | _ _ _ _ (k=4),\n // we only need to output the indices at positions |, the indices at\n // positions _ can be thrown away, see Figure5(b) After Phase 2\n // (Merge phase) in the Bitonic Top K paper referenced above.\n // For example, the paper shows we only need to output the orange bars.\n // The output sequence should look like this | | | | | | | |.\n // Because the sequence is halved, to map the output index back\n // to the previous sequence to find the corresponding value,\n // we need to double the index. When we double the index,\n // we basically interpolate a position, so 2i looks like\n // | _ | _ | _ | _ | _ | _ | _. We move the | to the first k position\n // of each 2k positions by - elemIdx % k. E.g. for output at\n // index 4,5,6,7, we want to get the corresponding element at\n // original index 8,9,10,11, for output at index 8,9,10,11,\n // we want to get the corresponding element at original index\n // 16,17,18,19, so on and so forth.\n\n int i = elemIdx < k ? elemIdx : (elemIdx * 2 - imod(elemIdx, k));\n int i0 = firstPass == 1 ? i : int(getIndices(batch, i));\n int i1 = firstPass == 1 ? i + k : int(getIndices(batch, i + k));\n\n float x0 = getX(batch, i0);\n float x1 = i1 < n ? getX(batch, i1) : x0;\n\n setOutput(x0 >= x1 ? float(i0) : float(i1));\n }\n "}}function Mu(e,t){null!==t&&e.disposeIntermediateTensorInfo(t)}function Gu(e){let t=1;for(;t<e;)t*=2;return t}const zu={kernelName:t.TopK,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o}=n,{k:s,sorted:i}=r,l=t.env().getNumber("TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD"),u=t.env().getNumber("TOPK_K_CPU_HANDOFF_THRESHOLD"),c=o.shape,d=c[c.length-1];if(a.shouldExecuteOnCPU([o])||d<l||s>u){const e=a.readSync(o.dataId),[t,n]=Wn(e,c,o.dtype,s,i);return[a.makeTensorInfo(t.shape,t.dtype,t.values),a.makeTensorInfo(n.shape,n.dtype,n.values)]}if(0===s)return c[c.length-1]=0,[a.makeTensorInfo(c,o.dtype,[]),a.makeTensorInfo(c,"int32",[])];if(1===d)return[o,ys({attrs:{shape:c,dtype:"int32",value:0},backend:a})];const p=a.texData.get(o.dataId),h=null!==p&&p.isPacked,f=h?a.unpackTensor(o):o,x=t.util.sizeFromShape(c)/d,m=Aa({inputs:{x:f},attrs:{shape:[x,d]},backend:a});h&&Mu(a,f);const g=Gu(s),b=Gu(d);let v=null;const C=()=>null===v?[m,m]:[m,v],$=(e,t,n)=>{const r=C(),o=new Wu(n),s=[[d],[null===v?1:0],[Number.NEGATIVE_INFINITY],[e],[t]],i=v;v=a.runWebGLProgram(o,r,"int32",s),Mu(a,i)};for(let e=1;e<g;e*=2){const t=2*e;for(let n=e;n>=1;n/=2)$(t,n,[x,b])}for(let e=b;e>g;e/=2){const t=C(),n=new Uu([x,e/2]),r=[[d],[null===v?1:0],[g]],o=v;v=a.runWebGLProgram(n,t,"int32",r),Mu(a,o);const s=g/2,i=2*s;for(let e=s;e>=1;e/=2)$(i,e,v.shape)}let y=v;v=Lr({inputs:{x:v},backend:a,attrs:{begin:0,size:[x,s]}}),Mu(a,y);let I=Us({inputs:{x:m,indices:v},backend:a,attrs:{axis:1,batchDims:1}});Mu(a,m);const w=c.slice(0,-1);w.push(s),y=v,v=Aa({inputs:{x:v},attrs:{shape:w},backend:a}),Mu(a,y);const S=I;return I=Aa({inputs:{x:I},attrs:{shape:w},backend:a}),Mu(a,S),[I,v]}};class Xu{constructor(e,t,n,a,r,o){this.variableNames=["Image","Transforms"],this.outputShape=o;const s="nearest"===n?1:2;let i;switch(a){case"constant":default:i=1;break;case"reflect":i=2;break;case"wrap":i=3;break;case"nearest":i=4}this.userCode=`\n float mapCoord(float outCoord, float len) {\n float inCoord = outCoord;\n if(${i} == 2) {\n if (inCoord < 0.0) {\n if (len <= 1.0) {\n inCoord = 0.0;\n } else {\n float sz2 = 2.0 * len;\n if (inCoord < sz2) {\n inCoord = sz2 * float(int(float(-inCoord / sz2))) +\n inCoord;\n }\n inCoord = inCoord < -len ? inCoord + sz2 : -inCoord - 1.0;\n }\n } else if (inCoord > len - 1.0) {\n if (len <= 1.0) {\n inCoord = 0.0;\n } else {\n float sz2 = 2.0 * len;\n inCoord -= sz2 * float(int(float(inCoord / sz2)));\n if (inCoord >= len) {\n inCoord = sz2 - inCoord - 1.0;\n }\n }\n }\n return clamp(inCoord, 0.0, len - 1.0);\n } else if (${i} == 3) {\n if (inCoord < 0.0) {\n if (len <= 1.0) {\n inCoord = 0.0;\n } else {\n float sz = len - 1.0;\n inCoord += len * (float(int(float(-inCoord / sz))) + 1.0);\n }\n } else if (inCoord > len - 1.0) {\n if (len <= 1.0) {\n inCoord = 0.0;\n } else {\n float sz = len - 1.0;\n inCoord -= len * float(int(float(inCoord / sz)));\n }\n }\n return clamp(inCoord, 0.0, len - 1.0);\n } else if (${i} == 4) {\n return clamp(outCoord, 0.0, len - 1.0);\n } else {\n return outCoord;\n }\n }\n\n float readWithFillValue(int batch, int coordY, int coordX,\n int channel) {\n float outputValue;\n if (0 <= coordY && coordY < ${e} && 0 <= coordX && coordX < ${t}) {\n outputValue = getImage(batch, coordY, coordX, channel);\n } else {\n outputValue = float(${r});\n }\n return outputValue;\n }\n\n void main() {\n ivec4 coords = getOutputCoords();\n float outputValue;\n int batch = coords[0];\n int x = coords[2];\n int y = coords[1];\n int channel = coords[3];\n float xf = float(x);\n float yf = float(y);\n float a1 = getTransforms(batch, 0);\n float a2 = getTransforms(batch, 1);\n float a3 = getTransforms(batch, 2);\n float b1 = getTransforms(batch, 3);\n float b2 = getTransforms(batch, 4);\n float b3 = getTransforms(batch, 5);\n float c1 = getTransforms(batch, 6);\n float c2 = getTransforms(batch, 7);\n float projection = c1 * xf + c2 * yf + 1.0;\n if (projection == 0.0) {\n outputValue = float(${r});\n } else {\n float inX = (a1 * xf + a2 * yf + a3) / projection;\n float inY = (b1 * xf + b2 * yf + b3) / projection;\n float mapX = mapCoord(inX, float(${t}));\n float mapY = mapCoord(inY, float(${e}));\n\n if (${s} == 1) {\n int coordY = int(round(mapY));\n int coordX = int(round(mapX));\n outputValue = readWithFillValue(batch, coordY, coordX,\n channel);\n } else {\n float yFloor = floor(mapY);\n float xFloor = floor(mapX);\n float yCeil = yFloor + 1.0;\n float xCeil = xFloor + 1.0;\n float valueYFloor = (xCeil - mapX) *\n readWithFillValue(batch, int(yFloor), int(xFloor), channel) +\n (mapX - xFloor) *\n readWithFillValue(batch, int(yFloor), int(xCeil), channel);\n float valueYCeil = (xCeil - mapX) *\n readWithFillValue(batch, int(yCeil), int(xFloor), channel) +\n (mapX - xFloor) *\n readWithFillValue(batch, int(yCeil), int(xCeil), channel);\n outputValue = (yCeil - mapY) * valueYFloor +\n (mapY - yFloor) * valueYCeil;\n }\n }\n setOutput(outputValue);\n }\n `}}const Hu={kernelName:t.Transform,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{image:r,transforms:o}=t,{interpolation:s,fillMode:i,fillValue:l,outputShape:u}=a,[c,d,p,h]=r.shape,[f,x]=null!=u?u:[d,p],m=new Xu(d,p,s,i,l,[c,f,x,h]);return n.runWebGLProgram(m,[r,o],"float32")}};const ju={kernelName:t.Unique,backendName:"webgl",kernelFunc:function(e){const{inputs:t,attrs:n,backend:a}=e,{axis:r}=n,{x:o}=t;oe(o,"unique"),console.warn("WARNING: ","UI might be locked temporarily as data is being downloaded");const s=a.readSync(o.dataId),{outputValues:i,outputShape:l,indices:u}=Mn(s,r,o.shape,o.dtype);return[a.makeTensorInfo(l,o.dtype,i),a.makeTensorInfo([u.length],"int32",u)]}};const Ku={kernelName:t.Unpack,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:n,attrs:a}=e,{value:r}=t;let{axis:o}=a;o<0&&(o+=r.shape.length);const s=r,i=s.shape.length,l=r.shape[o],u=new Array(i-1);let c=0;for(let e=0;e<i;e++)e!==o&&(u[c++]=s.shape[e]);const d=[],p=new Array(i).fill(0),h=s.shape.slice();h[o]=1;const f=new Array(l);for(let e=0;e<f.length;e++){p[o]=e;const t=Lr({inputs:{x:s},backend:n,attrs:{begin:p,size:h}}),a=Aa({inputs:{x:t},backend:n,attrs:{shape:u}});f[e]=a,d.push(t)}return d.forEach((e=>n.disposeIntermediateTensorInfo(e))),f}};class qu{constructor(e,t){this.variableNames=["x","segmentIds"];const n=e.windowSize,a=e.batchSize,r=e.inSize,o=e.numSegments,s=o*Math.ceil(r/n);this.outputShape=[a,s];const i=4*Math.floor(n/4),l=n%4,u="\n sumValue += dot(values, segFilter);\n ";let c="";r%n>0&&(c=`\n if (inIdx < 0 || inIdx >= ${r}) {\n return initializationValue;\n }\n `);let d="";r%n>0&&(d=`\n if (inIdx < 0 || inIdx >= ${r}) {\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 ${d}\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 ${o})) * float(${n}));\n int currentSeg = int(mod(float(outIdx), float(${o})));\n\n float sumValue = 0.0;\n\n for (int i = 0; i < ${i}; 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 ${u}\n }\n\n int inIdx = inOffset + ${i};\n if (${1===l}) {\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 ${u}\n } else if (${2===l}) {\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 ${u}\n } else if (${3===l}) {\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 ${u}\n }\n setOutput(sumValue);\n }\n `}}const Yu=[za,Ha,Ka,Ya,Ja,nr,ar,rr,cr,dr,hr,xr,gr,vr,$r,wr,Sr,Tr,Nr,Er,Or,Vr,Wr,Ur,Mr,jr,Yr,Jr,fa,no,co,vo,wo,ko,Ro,To,No,Ao,Oo,Do,Uo,Mo,Go,Xo,Ko,Qo,Zo,es,ns,as,os,ss,ls,cs,ps,fs,gs,Cs,Is,Ss,Ts,Es,Os,Ps,Ls,Vs,Ms,zs,Hs,pa,js,io,qs,Qs,Js,ga,ti,ai,ri,si,li,ci,pi,fi,gi,vi,$i,Ii,wi,Si,Ti,Ni,Ei,Ai,_i,Fi,Li,Vi,Ki,Ea,qi,Qi,Ji,tl,zr,al,sl,il,dl,hl,Ca,fl,xl,ml,gl,vl,Hr,Mi,$l,Il,Sl,_a,Tl,El,Ol,Dl,Bl,Wl,Ml,zl,jl,ql,Ql,Jl,tu,au,ou,iu,Br,ji,uu,cu,du,pu,hu,fu,xu,mu,vu,$u,wu,Su,ku,Tu,Nu,Eu,Au,Xi,Wa,Ou,Du,Pu,Vu,zu,Hu,Ma,ju,Ku,{kernelName:t.UnsortedSegmentSum,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:a,attrs:r}=e,{x:o,segmentIds:s}=n,{numSegments:i}=r,l=o.shape.length,u=[];let c=0;const d=t.backend_util.getAxesPermutation([c],l);let p=o;null!=d&&(p=Ua({inputs:{x:o},backend:a,attrs:{perm:d}}),u.push(p),c=t.backend_util.getInnerMostAxes(1,l)[0]);const h=t.backend_util.segment_util.computeOutShape(p.shape,c,i),f=t.util.sizeFromShape([p.shape[c]]),x=Aa({inputs:{x:p},backend:a,attrs:{shape:[-1,f]}});u.push(x);const m=t.sumOutType(o.dtype),g=(e,n,r,o,s)=>{const i=e.shape[0],l=e.shape[1],c=t.backend_util.segment_util.segOpComputeOptimalWindowSize(l,s),d=new qu({windowSize:c,inSize:l,batchSize:i,numSegments:s},n),p=a.compileAndRun(d,[e,r],o);if(u.push(p),p.shape[1]===s)return p;const h=bl({backend:a,attrs:{start:0,stop:s,step:1,dtype:"float32"}}),f=Bu({inputs:{x:h},backend:a,attrs:{reps:[l/c]}});u.push(h),u.push(f);return g(p,n,f,o,s)},b=Aa({inputs:{x:g(x,"unsortedSegmentSum",s,m,i)},backend:a,attrs:{shape:h}});let v=b;if(null!=d){u.push(b);const e=t.backend_util.getUndoAxesPermutation(d);v=Ua({inputs:{x:v},backend:a,attrs:{perm:e}})}return u.forEach((e=>a.disposeIntermediateTensorInfo(e))),v}},ol];for(const e of Yu)t.registerKernel(e);e.GPGPUContext=lt,e.MathBackendWebGL=oa,e.forceHalfFloat=sa,e.gpgpu_util=it,e.setWebGLContext=s,e.version_webgl="4.15.0",e.webgl=ia,e.webgl_util=se}));
|