text: var wglUtils=wglUtils||{};
  wglUtils.glUtils=function(p){function r(a,c,d,e,g,b){var h=a.createTexture();a.bindTexture(c,h);"undefined"===d&&(d=!0);e=e||a.LINEAR;g=g||a.LINEAR;b=b||a.REPEAT;a.texParameteri(c,a.TEXTURE_MIN_FILTER,e);a.texParameteri(c,a.TEXTURE_MAG_FILTER,g);a.texParameteri(c,a.TEXTURE_WRAP_S,b);a.texParameteri(c,a.TEXTURE_WRAP_T,b);return{glTexture:h,imageFromSrc:function(b,e,l,f,t){var q=new Image;q.onload=function(){a.bindTexture(c,h);a.texImage2D(b,0,l,l,f,q);d&&(a.generateMipmap(c),a.texParameteri(c,a.TEXTURE_MIN_FILTER,
  a.LINEAR_MIPMAP_LINEAR));t()};q.src=e;return this},imageFromRaw:function(c,b,e,f){a.bindTexture(c,h);a.texImage2D(c,0,e,e,f,b);d&&(a.generateMipmap(c),a.texParameteri(c,a.TEXTURE_MIN_FILTER,a.LINEAR_MIPMAP_LINEAR));return this},bind:function(b,d){var e=b.uniforms.get(d).cachedSamplerValue;a.activeTexture(a.TEXTURE0+e);a.bindTexture(c,h);return this}}}function u(a){var c;return{glShader:c,fromSource:function(d,e){c=a.createShader(e);a.shaderSource(c,d);a.compileShader(c);return a.getShaderParameter(c,
  a.COMPILE_STATUS)?c:(console.log("error compiling the shader:"+a.getShaderInfoLog(c)),a.deleteShader(c),null)},fromDOM:function(c,e){var g,b;b=document.getElementById(c);if(!b)return console.log("cannot find document element with id "+c),null;g=b.textContent;if(!e)if("x-shader/x-vertex"===b.type)e=a.VERTEX_SHADER;else if("x-shader/x-fragment"===b.type)e=a.FRAGMENT_SHADER;else return console.log("invalid shader type "+b.type),null;return this.fromSource(g,e)}}}function v(a,c){for(var d=a.createProgram(),
  e={},g={},b=0;b<c.length;b++)a.attachShader(d,c[b]);a.linkProgram(d);if(!a.getProgramParameter(d,a.LINK_STATUS))return console.log("failed at program linking: "+a.getProgramInfoLog(d)),a.deleteProgram(d),null;for(var h=a.getProgramParameter(d,a.ACTIVE_UNIFORMS),k=null,n="",l,b=0;b<h;b++)k=a.getActiveUniform(d,b),n=k.name,l=a.getUniformLocation(d,n),e[n]={location:l,type:k.type};for(var k=0,f,h=a.getProgramParameter(d,a.ACTIVE_ATTRIBUTES),b=0;b<h;b++)k=a.getActiveAttrib(d,b),n=k.name,l=a.getAttribLocation(d,
  n),f=k.type,k=f===a.FLOAT||f===a.INT?1:f===a.FLOAT_VEC2||f===a.INT_VEC2?2:f===a.FLOAT_VEC3||f===a.INT_VEC3?3:4,g[n]={location:l,type:f,size:k};return{glProgram:d,uniforms:{get:function(a){var c=e[a];c||console.log("uniform "+a+" does not active or exist");return c},set:function(c,b){var d=e[c];if(d){var k=d.type,f=d.location;switch(k){case a.FLOAT_MAT4:a.uniformMatrix4fv(f,!1,b);break;case a.FLOAT_VEC3:a.uniform3f(f,b[0],b[1],b[2]);break;case a.FLOAT_VEC2:a.uniform2f(f,b[0],b[1]);break;case a.FLOAT_VEC4:a.uniform4f(f,
  b[0],b[1],b[2],b[3]);break;case a.FLOAT:a.uniform1f(f,b);break;case a.INT:a.uniform1i(f,b);break;case a.SAMPLER_2D:case a.SAMPLER_CUBE:a.uniform1i(f,b);d.cachedSamplerValue=b;break;case a.INT_VEC3:a.uniform3i(f,b[0],b[1],b[2]);break;case a.INT_VEC4:a.uniform3i(f,b[0],b[1],b[2]);break;case a.FLOAT_MAT3:a.uniformMatrix3fv(f,!1,b);break;case a.FLOAT_MAT2:a.uniformMatrix2fv(f,!1,b);break;case a.INT_VEC2:a.uniform2i(f,b[0],b[1]);break;default:console.log("unknown uniform type "+k)}}else console.log("uniform "+
  c+" does not active or exist");return this}},attributes:{get:function(a){var b=g[a];b||console.log("attribute "+a+" does not active or exist");return b}},use:function(){a.useProgram(d)}}}function w(a,c,d,e,g){var b=a.createBuffer(),h=e.BYTES_PER_ELEMENT;a.bindBuffer(c,b);a.bufferData(c,new e(d),g);return{glBuffer:b,bytesPerElement:h,length:d.length,update:function(d,g){a.bindBuffer(c,b);a.bufferSubData(c,d,new e(g));return this},attribPointer:function(d,e,g,f,h){d=d.attributes.get(e);if(!d)return this;
  g=g||d.size;g*=this.bytesPerElement;f=(f||0)*this.bytesPerElement;h=h||a.FLOAT;a.bindBuffer(c,b);a.enableVertexAttribArray(d.location);a.vertexAttribPointer(d.location,d.size,h,a.FALSE,g,f);return this},bind:function(){a.bindBuffer(c,b);return this}}}var m=p.getContext("webgl",{stencil:!0})||p.getContext("experimental-webgl");if(!m)return alert("error initialising webgl"),null;m.viewport(0,0,p.width,p.height);return{glContext:m,buffer:function(a,c,d,e){return w(m,a,c,d,e)},shader:function(){return u(m)},
  program:function(a){return v(m,a)},texture:function(a,c,d,e,g){return r(m,a,c,d,e,g)}}};
  