class Portal{constructor(t="/",i=!0,e=!1){const n=[`${"/"!==t?t:""}/sky.png`,`${"/"!==t?t:""}/portal.png`];return this.version="1.3",this.notice(),this.animate=i,this.randomize=e,this.canvas=this.createCanvas(),this.gl=this.canvas.getContext("webgl2"),this.gl?(this.speed=1,this.initialSpeed=this.speed,this.currentTime=Date.now(),this.pauseTime=null,this.tick=(this.animate&&e)*this.randomRange(0,10),this.prog=this.build("#version 300 es\n\n\t\tlayout (location = 0) in vec3 Position;\n\n\t\tuniform mat4 modelViewMatrix;\n\t\tuniform mat4 projectionMatrix;\n\t\t\n\t\tuniform vec2 canvasResolution;\n\n\t\tvec4 projection_from_position(vec4 position) {\n\t\t\tvec4 projection = position * 0.5;\n\t\t\tprojection.xy = vec2(projection.x + projection.w, projection.y + projection.w);\n\t\t\tprojection.zw = position.zw;\n\t\t\treturn projection;\n\t\t}\n\n\t\tout vec4 texProj0;\n\n\t\tvoid main() {\n\t\t\tgl_Position = projectionMatrix * modelViewMatrix * vec4(Position, 1.0);\n\n\t\t\ttexProj0 = projection_from_position(gl_Position);\n\t\t\ttexProj0 = vec4(texProj0.xy * canvasResolution / max(canvasResolution.x, canvasResolution.y), texProj0.zw);\n\t\t}","#version 300 es\n\n\t\tprecision highp float;\n\n\t\tuniform sampler2D sky;\n\t\tuniform sampler2D particles;\n\t\tuniform float dt;\n\n\t\tin vec4 texProj0;\n\n\t\tconst int LAYERS = 15;\n\t\tconst vec3 COLORS[] = vec3[](\n\t\t\tvec3(0.022087, 0.098399, 0.110818),\n\t\t\tvec3(0.011892, 0.095924, 0.089485),\n\t\t\tvec3(0.027636, 0.101689, 0.100326),\n\t\t\tvec3(0.046564, 0.109883, 0.114838),\n\t\t\tvec3(0.064901, 0.117696, 0.097189),\n\t\t\tvec3(0.063761, 0.086895, 0.123646),\n\t\t\tvec3(0.084817, 0.111994, 0.166380),\n\t\t\tvec3(0.097489, 0.154120, 0.091064),\n\t\t\tvec3(0.106152, 0.131144, 0.195191),\n\t\t\tvec3(0.097721, 0.110188, 0.187229),\n\t\t\tvec3(0.133516, 0.138278, 0.148582),\n\t\t\tvec3(0.070006, 0.243332, 0.235792),\n\t\t\tvec3(0.196766, 0.142899, 0.214696),\n\t\t\tvec3(0.047281, 0.315338, 0.321970),\n\t\t\tvec3(0.204675, 0.390010, 0.302066),\n\t\t\tvec3(0.080955, 0.314821, 0.661491)\n\t\t);\n\n\t\tconst mat4 SCALE_TRANSLATE = mat4(\n\t\t\t0.5, 0.0, 0.0, 0.25,\n\t\t\t0.0, 0.5, 0.0, 0.25,\n\t\t\t0.0, 0.0, 1.0, 0.0,\n\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t);\n\n\t\tmat2 mat2_rotate_z(float radians) {\n\t\t\treturn mat2(\n\t\t\t\tcos(radians), -sin(radians),\n\t\t\t\tsin(radians), cos(radians)\n\t\t\t);\n\t\t}\n\n\t\tmat4 portal_layer(float layer) {\n\t\t\tmat4 translate = mat4(\n\t\t\t\t1.0, 0.0, 0.0, 17.0 / layer,\n\t\t\t\t0.0, 1.0, 0.0, (2.0 + layer / 1.5) * (dt * 1.5),\n\t\t\t\t0.0, 0.0, 1.0, 0.0,\n\t\t\t\t0.0, 0.0, 0.0, 1.0\n\t\t\t);\n\n\t\t\tmat2 rotate = mat2_rotate_z(radians((layer * layer * 4321.0 + layer * 9.0) * 2.0));\n\n\t\t\tmat2 scale = mat2((4.5 - layer / 4.0) * 2.0);\n\n\t\t\treturn mat4(scale * rotate) * translate * SCALE_TRANSLATE;\n\t\t}\n\n\t\tout vec4 fragColor;\n\n\t\tvoid main() {\n\t\t\tvec3 color = textureProj(sky, texProj0).rgb * COLORS[0];\n\t\t\t\n\t\t\tfor (int i = 0; i < LAYERS; i++) {\n\t\t\t\tcolor += textureProj(particles, texProj0 * portal_layer(float(i + 1))).rgb * COLORS[i];\n\t\t\t}\n\t\t\t\n\t\t\tfragColor = vec4(color, 1.0);\n\t\t}"),this.prog?(window.addEventListener("resize",this.resize.bind(this)),this.clickTime=null,this.promises=n.map((t=>this.loadImage(t))),this.initialize(),void Promise.all(this.promises).then((t=>{t.forEach(((t,i)=>this.loadResource(t,i))),this.gl.useProgram(this.prog),this.render()}))):(alert("Failed to compile WebGL 2 shaders.\nOpen the developer console for debug output."),this.destroyCanvas())):(alert("Unable to initialize WebGL 2.\nThe website will lack parallax animation."),console.error("Unable to initialize WebGL 2. Your browser or machine may not support it."),this.destroyCanvas())}createCanvas(){let t=document.createElement("canvas");return t.width=window.innerWidth,t.height=window.innerHeight,t.style.display="block",t.style.position="fixed",t.style.bottom="0",t.style.left="0",t.style.zIndex="-1",t.innerHTML="Your browser does not support the canvas element, which is required for animation.",t.classList.add("ecmaportal"),t.id="ecmaportal",this.animate&&(t.onclick=()=>this.clickTime=Date.now()),document.body.appendChild(t),t}destroyCanvas(){document.body.removeChild(this.canvas)}notice(){console.log(`%c \u2587%c\u2587%c\u2587 %c\u2587%c\u2587%c\u2587 %c // ECMAPortal v${this.version} by Endermanch & WiPet\n\n\thttps://enderman.ch\n\thttps://go.enderman.ch/wipet`,"color: #E58EFF","color: #D52DFF","color: #E58EFF","color: #E58EFF","color: #D52DFF","color: #E58EFF","color: #008000"),console.log("If any errors occur below, please send a screenshot of them my way!\n\t%ccontact@enderman.ch","color: #87CEFA")}randomRange(t,i){return Math.random()*(i-t)+t}build(t,i){let e=this.gl.createShader(this.gl.VERTEX_SHADER);if(this.gl.shaderSource(e,t),this.gl.compileShader(e),!this.gl.getShaderParameter(e,this.gl.COMPILE_STATUS))return console.error(this.gl.getShaderInfoLog(e)),!1;let n=this.gl.createShader(this.gl.FRAGMENT_SHADER);if(this.gl.shaderSource(n,i),this.gl.compileShader(n),!this.gl.getShaderParameter(n,this.gl.COMPILE_STATUS))return console.error(this.gl.getShaderInfoLog(n)),!1;let r=this.gl.createProgram();return this.gl.attachShader(r,e),this.gl.attachShader(r,n),this.gl.linkProgram(r),this.gl.getProgramParameter(r,this.gl.LINK_STATUS)?r:(console.error(this.gl.getProgramInfoLog(r)),!1)}loadImage(t){return new Promise(((i,e)=>{let n=new Image;n.onload=()=>i(n),n.onerror=e,n.src=t}))}loadResource(t,i){const e=[this.gl.CLAMP_TO_EDGE,this.gl.MIRRORED_REPEAT];let n=this.gl.createSampler();this.gl.samplerParameteri(n,this.gl.TEXTURE_WRAP_S,e[i]),this.gl.samplerParameteri(n,this.gl.TEXTURE_WRAP_T,e[i]),this.gl.samplerParameteri(n,this.gl.TEXTURE_WRAP_R,e[i]),this.gl.samplerParameteri(n,this.gl.TEXTURE_MIN_FILTER,this.gl.NEAREST_MIPMAP_LINEAR),this.gl.samplerParameteri(n,this.gl.TEXTURE_MAG_FILTER,this.gl.NEAREST),this.gl.bindSampler(i,n);let r=this.gl.createTexture();this.gl.activeTexture(this.gl.TEXTURE0+i),this.gl.bindTexture(this.gl.TEXTURE_2D,r),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.gl.RGBA,this.gl.UNSIGNED_BYTE,t),this.gl.generateMipmap(this.gl.TEXTURE_2D)}initialize(){this.uniforms={modelViewMatrix:this.gl.getUniformLocation(this.prog,"modelViewMatrix"),projectionMatrix:this.gl.getUniformLocation(this.prog,"projectionMatrix"),dt:this.gl.getUniformLocation(this.prog,"dt"),resolution:this.gl.getUniformLocation(this.prog,"canvasResolution"),sky:this.gl.getUniformLocation(this.prog,"sky"),particles:this.gl.getUniformLocation(this.prog,"particles")};let t=this.gl.createBuffer(),i=new Float32Array([-1,-1,1,-1,1,1,1,1,-1,1,-1,-1]);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,t),this.gl.bufferData(this.gl.ARRAY_BUFFER,i,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);let e=this.gl.createBuffer(),n=new Float32Array([0,1,1,1,1,0,1,0,0,0,0,1]);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,e),this.gl.bufferData(this.gl.ARRAY_BUFFER,n,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,t),this.gl.vertexAttribPointer(0,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(0),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null);this.gl.bindBuffer(this.gl.ARRAY_BUFFER,e),this.gl.vertexAttribPointer(4,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(4),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,null)}scene(){let t=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);this.animate&&(null!==this.clickTime&&(this.speed=20-Math.min((Date.now()-this.clickTime)/100,20-this.initialSpeed),this.speed===this.initialSpeed&&(this.clickTime=null)),this.tick+=this.dt,this.tick%=20),this.gl.uniformMatrix4fv(this.uniforms.modelViewMatrix,!1,t),this.gl.uniformMatrix4fv(this.uniforms.projectionMatrix,!1,t),this.gl.uniform2f(this.uniforms.resolution,this.canvas.clientWidth,this.canvas.clientHeight),this.gl.uniform1f(this.uniforms.dt,this.tick),this.gl.uniform1i(this.uniforms.sky,0),this.gl.uniform1i(this.uniforms.particles,1),this.gl.drawArraysInstanced(this.gl.TRIANGLES,0,6,1)}render(){this.gl.viewport(0,0,this.gl.drawingBufferWidth,this.gl.drawingBufferHeight),this.dt=(Date.now()-this.currentTime)*this.speed/1e6,this.currentTime=Date.now(),this.scene(),this.animate&&requestAnimationFrame(this.render.bind(this))}resize(){let t=window.innerWidth,i=window.innerHeight;this.canvas.width===t&&this.canvas.height===i||(this.canvas.width=t,this.canvas.height=i),this.animate||requestAnimationFrame(this.render.bind(this))}continue(){null!==this.pauseTime&&(this.currentTime+=Date.now()-this.pauseTime,this.pauseTime=null,this.animate=!0,this.render())}pause(){null===this.pauseTime&&(this.pauseTime=Date.now(),this.animate=!1)}destruct(){this.gl.deleteProgram(this.prog)}}const portal=new Portal("/images/portal",!0,!0);