diff --git a/.gitignore b/.gitignore index d5985cad..44856c2d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,8 @@ # NPM /node_modules npm-* + +# Build +/render*.js /dist.js +/playground/render.js diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..e69de29b diff --git a/.travis.yml b/.travis.yml index fc980a70..9832efe1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,32 @@ language: node_js node_js: - - "4.2" - - "stable" +- "4.2" +- "stable" sudo: false cache: directories: - node_modules +after_script: +- | + # RELEASE_BRANCHES and NPM_TOKEN defined in Travis settings panel + declare exitCode + $(npm bin)/travis-after-all + exitCode=$? + if [[ + # Execute after all jobs finish successfully + $exitCode = 0 && + # Only release on release branches + $RELEASE_BRANCHES =~ $TRAVIS_BRANCH && + # Don't release on PR builds + $TRAVIS_PULL_REQUEST = "false" + ]]; then + # Authenticate NPM + echo "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" > .npmrc + # Set version to timestamp + npm --no-git-tag-version version $($(npm bin)/json -f package.json version)-prerelease.$(date +%s) + npm publish + # Publish to gh-pages as most recent committer + git config --global user.email $(git log --pretty=format:"%ce" -n1) + git config --global user.name $(git log --pretty=format:"%cn" -n1) + ./node_modules/.bin/gh-pages -x -r https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git -d playground -m "Build for $(git log --pretty=format:%H)" + fi diff --git a/Makefile b/Makefile index 53cdcc39..20c327f1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,6 @@ ESLINT=./node_modules/.bin/eslint WEBPACK=./node_modules/.bin/webpack --progress --colors WEBPACK_DEV_SERVER=./node_modules/.bin/webpack-dev-server - # ------------------------------------------------------------------------------ build: @@ -11,12 +10,11 @@ watch: $(WEBPACK) --watch --watch-poll serve: - $(WEBPACK_DEV_SERVER) --host 0.0.0.0 --content-base ./ + $(WEBPACK_DEV_SERVER) # ------------------------------------------------------------------------------ lint: - $(ESLINT) ./playground/*.js $(ESLINT) ./src/*.js $(ESLINT) ./src/**/*.js diff --git a/index.html b/index.html deleted file mode 100644 index 42edce43..00000000 --- a/index.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - Redirect to playground - - diff --git a/package.json b/package.json index 4028a558..61e238ed 100644 --- a/package.json +++ b/package.json @@ -4,32 +4,36 @@ "description": "WebGL Renderer for Scratch 3.0", "author": "Massachusetts Institute of Technology", "license": "BSD-3-Clause", - "homepage": "https://github.com/LLK/scratch-render-webgl#readme", + "homepage": "https://github.com/LLK/scratch-render#readme", "repository": { "type": "git", - "url": "git+ssh://git@github.com/LLK/scratch-render-webgl.git" + "url": "git+ssh://git@github.com/LLK/scratch-render.git" }, "main": "./dist.js", "scripts": { - "postinstall": "./node_modules/.bin/webpack", - "test": "make test" + "prepublish": "make build", + "start": "make serve", + "test": "make test", + "version": "./node_modules/.bin/json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\"" }, - "dependencies": { + "devDependencies": { "babel-core": "6.9.1", "babel-eslint": "6.0.4", "babel-loader": "6.2.4", "babel-polyfill": "6.9.1", "babel-preset-es2015": "6.9.0", + "eslint": "2.7.0", + "gh-pages": "0.11.0", + "json": "9.0.4", "json-loader": "0.5.4", + "lodash.defaultsdeep": "4.6.0", "raw-loader": "0.5.1", "svg-to-image": "1.1.3", - "twgl.js": "1.5.2", - "xhr": "2.2.0", - "webpack": "1.13.0" - }, - "devDependencies": { - "eslint": "2.7.0", "tap": "5.7.1", - "webpack-dev-server": "1.14.1" + "travis-after-all": "1.4.4", + "twgl.js": "1.5.2", + "webpack": "1.13.0", + "webpack-dev-server": "1.14.1", + "xhr": "2.2.0" } } diff --git a/playground/index.html b/playground/index.html index 89299fb6..d64ac599 100644 --- a/playground/index.html +++ b/playground/index.html @@ -14,7 +14,7 @@ Min: Max:

- + - // - // Has one line before it which is invalid according to GLSL ES 3.00 - // - var lineOffset = 0; - if (spaceRE.test(shaderSource)) { - lineOffset = 1; - shaderSource = shaderSource.replace(spaceRE, ''); - } - - // Load the shader source - gl.shaderSource(shader, shaderSource); - - // Compile the shader - gl.compileShader(shader); - - // Check the compile status - var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - if (!compiled) { - // Something went wrong during compilation; get the error - var lastError = gl.getShaderInfoLog(shader); - errFn(addLineNumbers(shaderSource, lineOffset) + "\n*** Error compiling shader: " + lastError); - gl.deleteShader(shader); - return null; - } - - return shader; - } - - /** - * Creates a program, attaches shaders, binds attrib locations, links the - * program and calls useProgram. - * @param {WebGLShader[]} shaders The shaders to attach - * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in - * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. - * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console - * on error. If you want something else pass an callback. It's passed an error message. - * @return {WebGLProgram?} the created program or null if error. - * @memberOf module:twgl/programs - */ - function createProgram( - gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { - var errFn = opt_errorCallback || error; - var program = gl.createProgram(); - shaders.forEach(function(shader) { - gl.attachShader(program, shader); - }); - if (opt_attribs) { - opt_attribs.forEach(function(attrib, ndx) { - gl.bindAttribLocation( - program, - opt_locations ? opt_locations[ndx] : ndx, - attrib); - }); - } - gl.linkProgram(program); - - // Check the link status - var linked = gl.getProgramParameter(program, gl.LINK_STATUS); - if (!linked) { - // something went wrong with the link - var lastError = gl.getProgramInfoLog(program); - errFn("Error in program linking:" + lastError); - - gl.deleteProgram(program); - return null; - } - return program; - } - - /** - * Loads a shader from a script tag. - * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. - * @param {string} scriptId The id of the script tag. - * @param {number} [opt_shaderType] The type of shader. If not passed in it will - * be derived from the type of the script tag. - * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. - * @return {WebGLShader?} The created shader or null if error. - */ - function createShaderFromScript( - gl, scriptId, opt_shaderType, opt_errorCallback) { - var shaderSource = ""; - var shaderType; - var shaderScript = document.getElementById(scriptId); - if (!shaderScript) { - throw "*** Error: unknown script element" + scriptId; - } - shaderSource = shaderScript.text; - - if (!opt_shaderType) { - if (shaderScript.type === "x-shader/x-vertex") { - shaderType = gl.VERTEX_SHADER; - } else if (shaderScript.type === "x-shader/x-fragment") { - shaderType = gl.FRAGMENT_SHADER; - } else if (shaderType !== gl.VERTEX_SHADER && shaderType !== gl.FRAGMENT_SHADER) { - throw "*** Error: unknown shader type"; - } - } - - return loadShader( - gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType, - opt_errorCallback); - } - - var defaultShaderType = [ - "VERTEX_SHADER", - "FRAGMENT_SHADER", - ]; - - /** - * Creates a program from 2 script tags. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext - * to use. - * @param {string[]} shaderScriptIds Array of ids of the script - * tags for the shaders. The first is assumed to be the - * vertex shader, the second the fragment shader. - * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in - * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. - * @param {module:twgl.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console - * on error. If you want something else pass an callback. It's passed an error message. - * @return {WebGLProgram} The created program. - * @memberOf module:twgl/programs - */ - function createProgramFromScripts( - gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { - var shaders = []; - for (var ii = 0; ii < shaderScriptIds.length; ++ii) { - var shader = createShaderFromScript( - gl, shaderScriptIds[ii], gl[defaultShaderType[ii]], opt_errorCallback); - if (!shader) { - return null; - } - shaders.push(shader); - } - return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); - } - - /** - * Creates a program from 2 sources. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext - * to use. - * @param {string[]} shaderSourcess Array of sources for the - * shaders. The first is assumed to be the vertex shader, - * the second the fragment shader. - * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in - * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. - * @param {module:twgl.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console - * on error. If you want something else pass an callback. It's passed an error message. - * @return {WebGLProgram} The created program. - * @memberOf module:twgl/programs - */ - function createProgramFromSources( - gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { - var shaders = []; - for (var ii = 0; ii < shaderSources.length; ++ii) { - var shader = loadShader( - gl, shaderSources[ii], gl[defaultShaderType[ii]], opt_errorCallback); - if (!shader) { - return null; - } - shaders.push(shader); - } - return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback); - } - - /** - * Creates setter functions for all uniforms of a shader - * program. - * - * @see {@link module:twgl.setUniforms} - * - * @param {WebGLProgram} program the program to create setters for. - * @returns {Object.} an object with a setter by name for each uniform - * @memberOf module:twgl/programs - */ - function createUniformSetters(gl, program) { - var textureUnit = 0; - - /** - * Creates a setter for a uniform of the given program with it's - * location embedded in the setter. - * @param {WebGLProgram} program - * @param {WebGLUniformInfo} uniformInfo - * @returns {function} the created setter. - */ - function createUniformSetter(program, uniformInfo) { - var location = gl.getUniformLocation(program, uniformInfo.name); - var isArray = (uniformInfo.size > 1 && uniformInfo.name.substr(-3) === "[0]"); - var type = uniformInfo.type; - var typeInfo = typeMap[type]; - if (!typeInfo) { - throw ("unknown type: 0x" + type.toString(16)); // we should never get here. - } - if (typeInfo.bindPoint) { - // it's a sampler - var unit = textureUnit; - textureUnit += uniformInfo.size; - - if (isArray) { - return typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); - } else { - return typeInfo.setter(gl, type, unit, location, uniformInfo.size); - } - } else { - if (typeInfo.arraySetter && isArray) { - return typeInfo.arraySetter(gl, location); - } else { - return typeInfo.setter(gl, location); - } - } - } - - var uniformSetters = { }; - var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - - for (var ii = 0; ii < numUniforms; ++ii) { - var uniformInfo = gl.getActiveUniform(program, ii); - if (!uniformInfo) { - break; - } - var name = uniformInfo.name; - // remove the array suffix. - if (name.substr(-3) === "[0]") { - name = name.substr(0, name.length - 3); - } - var setter = createUniformSetter(program, uniformInfo); - uniformSetters[name] = setter; - } - return uniformSetters; - } - - /** - * @typedef {Object} UniformData - * @property {number} type The WebGL type enum for this uniform - * @property {number} size The number of elements for this uniform - * @property {number} blockNdx The block index this uniform appears in - * @property {number} offset The byte offset in the block for this uniform's value - * @memberOf module:twgl - */ - - /** - * The specification for one UniformBlockObject - * - * @typedef {Object} BlockSpec - * @property {number} index The index of the block. - * @property {number} size The size in bytes needed for the block - * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices - * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. - * @property {bool} usedByVertexShader Self explanitory - * @property {bool} usedByFragmentShader Self explanitory - * @property {bool} used Self explanitory - * @memberOf module:twgl - */ - - /** - * A `UniformBlockSpec` represents the data needed to create and bind - * UniformBlockObjects for a given program - * - * @typedef {Object} UniformBlockSpec - * @property {Object. blockSpecs The BlockSpec for each block by block name - * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. - * @memberOf module:twgl - */ - - /** - * Creates a UniformBlockSpec for the given program. - * - * A UniformBlockSpec represents the data needed to create and bind - * UniformBlockObjects - * - * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context - * @param {WebGLProgram} program A WebGLProgram for a successfully linked program - * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec - * @memberOf module:twgl/programs - */ - function createUniformBlockSpecFromProgram(gl, program) { - var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); - var uniformData = []; - var uniformIndices = []; - - for (var ii = 0; ii < numUniforms; ++ii) { - uniformIndices.push(ii); - uniformData.push({}); - var uniformInfo = gl.getActiveUniform(program, ii); - if (!uniformInfo) { - break; - } - // REMOVE [0]? - uniformData[ii].name = uniformInfo.name; - } - - [ - [ "UNIFORM_TYPE", "type" ], - [ "UNIFORM_SIZE", "size" ], // num elements - [ "UNIFORM_BLOCK_INDEX", "blockNdx" ], - [ "UNIFORM_OFFSET", "offset", ], - ].forEach(function(pair) { - var pname = pair[0]; - var key = pair[1]; - gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) { - uniformData[ndx][key] = value; - }); - }); - - var blockSpecs = {}; - - var numUniformBlocks = gl.getProgramParameter(program, gl.ACTIVE_UNIFORM_BLOCKS); - for (ii = 0; ii < numUniformBlocks; ++ii) { - var name = gl.getActiveUniformBlockName(program, ii); - var blockSpec = { - index: ii, - usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, gl.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), - usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, gl.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), - size: gl.getActiveUniformBlockParameter(program, ii, gl.UNIFORM_BLOCK_DATA_SIZE), - uniformIndices: gl.getActiveUniformBlockParameter(program, ii, gl.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES), - }; - blockSpec.used = blockSpec.usedByVertexSahder || blockSpec.usedByFragmentShader; - blockSpecs[name] = blockSpec; - } - - return { - blockSpecs: blockSpecs, - uniformData: uniformData, - }; - } - - var arraySuffixRE = /\[\d+\]\.$/; // better way to check? - - /** - * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values - * and a corresponding WebGLBuffer to hold those values on the GPU - * - * @typedef {Object} UniformBlockInfo - * @property {string} name The name of the block - * @property {ArrayBuffer} array The array buffer that contains the uniform values - * @property {Float32Array} asFloat A float view on the array buffer. This is useful - * inspecting the contents of the buffer in the debugger. - * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. - * @property {Object.} uniforms A uniform name to ArrayBufferView map. - * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset - * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` - * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an - * `Int32Array` view, etc. - * @memberOf module:twgl - */ - - /** - * Creates a `UniformBlockInfo` for the specified block - * - * Note: **A warning is printed to the console of the blockName makes no existing blocks and a dummy - * `UniformBlockInfo` is returned**. This is because when debugging GLSL - * it is common to comment out large portions of a shader or for example set - * the final output to a constant. When that happens blocks get optimized out. - * If this function did not create dummy blocks your code would crash when debugging. - * - * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext - * @param {WebGLProgram} program A WebGLProgram - * @param {module:twgl.UniformBlockSpec} uinformBlockSpec. A UniformBlockSpec as returned - * from {@link module:twgl.createUniformBlockSpecFromProgram}. - * @param {string} blockName The name of the block. - * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo - * @memberOf module:twgl/programs - */ - function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName) { - var blockSpecs = uniformBlockSpec.blockSpecs; - var uniformData = uniformBlockSpec.uniformData; - var blockSpec = blockSpecs[blockName]; - if (!blockSpec) { - warn("no uniform block object named:", blockName); - return { - name: blockName, - uniforms: {}, - }; - } - var array = new ArrayBuffer(blockSpec.size); - var buffer = gl.createBuffer(); - var uniformBufferIndex = blockSpec.index; - gl.bindBuffer(gl.UNIFORM_BUFFER, buffer); - gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); - - var prefix = blockName + "."; - if (arraySuffixRE.test(prefix)) { - prefix = prefix.replace(arraySuffixRE, "."); - } - var uniforms = {}; - blockSpec.uniformIndices.forEach(function(uniformNdx) { - var data = uniformData[uniformNdx]; - var typeInfo = typeMap[data.type]; - var Type = typeInfo.Type; - var length = data.size * typeInfo.size; - var name = data.name; - if (name.substr(0, prefix.length) === prefix) { - name = name.substr(prefix.length); - } - uniforms[name] = new Type(array, data.offset, length / Type.BYTES_PER_ELEMENT); - }); - return { - name: blockName, - array: array, - asFloat: new Float32Array(array), // for debugging - buffer: buffer, - uniforms: uniforms, - }; - } - - /** - * Creates a `UniformBlockInfo` for the specified block - * - * Note: **A warning is printed to the console of the blockName makes no existing blocks and a dummy - * `UniformBlockInfo` is returned**. This is because when debugging GLSL - * it is common to comment out large portions of a shader or for example set - * the final output to a constant. When that happens blocks get optimized out. - * If this function did not create dummy blocks your code would crash when debugging. - * - * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext - * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` - * as returned from {@link module:twgl.createProgramInfo} - * @param {string} blockName The name of the block. - * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo - * @memberOf module:twgl/programs - */ - function createUniformBlockInfo(gl, programInfo, blockName) { - return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName); - } - - /** - * Binds a unform block to the matching uniform block point. - * Matches by blocks by name so blocks must have the same name not just the same - * structure. - * - * If you have changed any values and you upload the valus into the corresponding WebGLBuffer - * call {@link module:twgl.setUniformBlock} instead. - * - * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. - * @param {{module:twgl.ProgramInfo|module:twgl.UniformBlockSpec} programInfo a `ProgramInfo` - * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as - * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. - * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from - * {@link module:twgl.createUniformBlockInfo}. - * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name - * no buffer is bound. - * @memberOf module:twgl/programs - */ - function bindUniformBlock(gl, programInfo, uniformBlockInfo) { - var uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; - var blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; - if (blockSpec) { - var bufferBindIndex = blockSpec.index; - gl.bindBufferRange(gl.UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, 0, uniformBlockInfo.array.byteLength); - return true; - } - return false; - } - - /** - * Uploads the current uniform values to the corresponding WebGLBuffer - * and binds that buffer to the program's corresponding bind point for the uniform block object. - * - * If you haven't changed any values and you only need to bind the uniform block object - * call {@link module:twgl.bindUniformBlock} instead. - * - * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. - * @param {{module:twgl.ProgramInfo|module:twgl.UniformBlockSpec} programInfo a `ProgramInfo` - * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as - * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. - * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from - * {@link module:twgl.createUniformBlockInfo}. - * @memberOf module:twgl/programs - */ - function setUniformBlock(gl, programInfo, uniformBlockInfo) { - if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { - gl.bufferData(gl.UNIFORM_BUFFER, uniformBlockInfo.array, gl.DYNAMIC_DRAW); - } - } - - /** - * Sets values of a uniform block object - * - * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. - * @param {Object. values A uniform name to value map where the value is correct for the given - * type of uniform. So for example given a block like - * - * uniform SomeBlock { - * float someFloat; - * vec2 someVec2; - * vec3 someVec3Array[2]; - * int someInt; - * } - * - * You can set the values of the uniform block with - * - * twgl.setBlockUniforms(someBlockInfo, { - * someFloat: 12.3, - * someVec2: [1, 2], - * someVec3Array: [1, 2, 3, 4, 5, 6], - * someInt: 5, - * } - * - * Arrays can be JavaScript arrays or typed arrays - * - * Any name that doesn't match will be ignored - * @memberOf module:twgl/programs - */ - function setBlockUniforms(uniformBlockInfo, values) { - var uniforms = uniformBlockInfo.uniforms; - for (var name in values) { - var array = uniforms[name]; - if (array) { - var value = values[name]; - if (value.length) { - array.set(value); - } else { - array[0] = value; - } - } - } - } - - /** - * Set uniforms and binds related textures. - * - * example: - * - * var programInfo = createProgramInfo( - * gl, ["some-vs", "some-fs"]); - * - * var tex1 = gl.createTexture(); - * var tex2 = gl.createTexture(); - * - * ... assume we setup the textures with data ... - * - * var uniforms = { - * u_someSampler: tex1, - * u_someOtherSampler: tex2, - * u_someColor: [1,0,0,1], - * u_somePosition: [0,1,1], - * u_someMatrix: [ - * 1,0,0,0, - * 0,1,0,0, - * 0,0,1,0, - * 0,0,0,0, - * ], - * }; - * - * gl.useProgram(program); - * - * This will automatically bind the textures AND set the - * uniforms. - * - * twgl.setUniforms(programInfo, uniforms); - * - * For the example above it is equivalent to - * - * var texUnit = 0; - * gl.activeTexture(gl.TEXTURE0 + texUnit); - * gl.bindTexture(gl.TEXTURE_2D, tex1); - * gl.uniform1i(u_someSamplerLocation, texUnit++); - * gl.activeTexture(gl.TEXTURE0 + texUnit); - * gl.bindTexture(gl.TEXTURE_2D, tex2); - * gl.uniform1i(u_someSamplerLocation, texUnit++); - * gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]); - * gl.uniform3fv(u_somePositionLocation, [0, 1, 1]); - * gl.uniformMatrix4fv(u_someMatrix, false, [ - * 1,0,0,0, - * 0,1,0,0, - * 0,0,1,0, - * 0,0,0,0, - * ]); - * - * Note it is perfectly reasonable to call `setUniforms` multiple times. For example - * - * var uniforms = { - * u_someSampler: tex1, - * u_someOtherSampler: tex2, - * }; - * - * var moreUniforms { - * u_someColor: [1,0,0,1], - * u_somePosition: [0,1,1], - * u_someMatrix: [ - * 1,0,0,0, - * 0,1,0,0, - * 0,0,1,0, - * 0,0,0,0, - * ], - * }; - * - * twgl.setUniforms(programInfo, uniforms); - * twgl.setUniforms(programInfo, moreUniforms); - * - * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from - * `createUniformSetters`. - * @param {Object.} values an object with values for the - * uniforms. - * You can pass multiple objects by putting them in an array or by calling with more arguments.For example - * - * var sharedUniforms = { - * u_fogNear: 10, - * u_projection: ... - * ... - * }; - * - * var localUniforms = { - * u_world: ... - * u_diffuseColor: ... - * }; - * - * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); - * - * // is the same as - * - * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); - * - * // is the same as - * - * twgl.setUniforms(programInfo, sharedUniforms); - * twgl.setUniforms(programInfo, localUniforms}; - * - * @memberOf module:twgl/programs - */ - function setUniforms(setters, values) { // eslint-disable-line - var actualSetters = setters.uniformSetters || setters; - var numArgs = arguments.length; - for (var andx = 1; andx < numArgs; ++andx) { - var vals = arguments[andx]; - if (Array.isArray(vals)) { - var numValues = vals.length; - for (var ii = 0; ii < numValues; ++ii) { - setUniforms(actualSetters, vals[ii]); - } - } else { - for (var name in vals) { - var setter = actualSetters[name]; - if (setter) { - setter(vals[name]); - } - } - } - } - } - - /** - * Creates setter functions for all attributes of a shader - * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. - * - * @see {@link module:twgl.setAttributes} for example - * @param {WebGLProgram} program the program to create setters for. - * @return {Object.} an object with a setter for each attribute by name. - * @memberOf module:twgl/programs - */ - function createAttributeSetters(gl, program) { - var attribSetters = { - }; - - function createAttribSetter(index) { - return function(b) { - gl.bindBuffer(gl.ARRAY_BUFFER, b.buffer); - gl.enableVertexAttribArray(index); - gl.vertexAttribPointer( - index, b.numComponents || b.size, b.type || gl.FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); - }; - } - - var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); - for (var ii = 0; ii < numAttribs; ++ii) { - var attribInfo = gl.getActiveAttrib(program, ii); - if (!attribInfo) { - break; - } - var index = gl.getAttribLocation(program, attribInfo.name); - attribSetters[attribInfo.name] = createAttribSetter(index); - } - - return attribSetters; - } - - /** - * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) - * - * Example: - * - * var program = createProgramFromScripts( - * gl, ["some-vs", "some-fs"); - * - * var attribSetters = createAttributeSetters(program); - * - * var positionBuffer = gl.createBuffer(); - * var texcoordBuffer = gl.createBuffer(); - * - * var attribs = { - * a_position: {buffer: positionBuffer, numComponents: 3}, - * a_texcoord: {buffer: texcoordBuffer, numComponents: 2}, - * }; - * - * gl.useProgram(program); - * - * This will automatically bind the buffers AND set the - * attributes. - * - * setAttributes(attribSetters, attribs); - * - * Properties of attribs. For each attrib you can add - * properties: - * - * * type: the type of data in the buffer. Default = gl.FLOAT - * * normalize: whether or not to normalize the data. Default = false - * * stride: the stride. Default = 0 - * * offset: offset into the buffer. Default = 0 - * - * For example if you had 3 value float positions, 2 value - * float texcoord and 4 value uint8 colors you'd setup your - * attribs like this - * - * var attribs = { - * a_position: {buffer: positionBuffer, numComponents: 3}, - * a_texcoord: {buffer: texcoordBuffer, numComponents: 2}, - * a_color: { - * buffer: colorBuffer, - * numComponents: 4, - * type: gl.UNSIGNED_BYTE, - * normalize: true, - * }, - * }; - * - * @param {Object.} setters Attribute setters as returned from createAttributeSetters - * @param {Object.} buffers AttribInfos mapped by attribute name. - * @memberOf module:twgl/programs - * @deprecated use {@link module:twgl.setBuffersAndAttributes} - */ - function setAttributes(setters, buffers) { - for (var name in buffers) { - var setter = setters[name]; - if (setter) { - setter(buffers[name]); - } - } - } - - /** - * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate - * - * Example: - * - * var programInfo = createProgramInfo( - * gl, ["some-vs", "some-fs"); - * - * var arrays = { - * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], }, - * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], }, - * }; - * - * var bufferInfo = createBufferInfoFromArrays(gl, arrays); - * - * gl.useProgram(programInfo.program); - * - * This will automatically bind the buffers AND set the - * attributes. - * - * setBuffersAndAttributes(gl, programInfo, bufferInfo); - * - * For the example above it is equivilent to - * - * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); - * gl.enableVertexAttribArray(a_positionLocation); - * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0); - * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); - * gl.enableVertexAttribArray(a_texcoordLocation); - * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0); - * - * @param {WebGLRenderingContext} gl A WebGLRenderingContext. - * @param {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgrmaInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} - * @param {(module:twgl.BufferInfo|module:twgl.vertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. - * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} - * @memberOf module:twgl/programs - */ - function setBuffersAndAttributes(gl, programInfo, buffers) { - if (buffers.vertexArrayObject) { - gl.bindVertexArray(buffers.vertexArrayObject); - } else { - setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); - if (buffers.indices) { - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices); - } - } - } - - /** - * @typedef {Object} ProgramInfo - * @property {WebGLProgram} program A shader program - * @property {Object} uniformSetters object of setters as returned from createUniformSetters, - * @property {Object} attribSetters object of setters as returned from createAttribSetters, - * @memberOf module:twgl - */ - - /** - * Creates a ProgramInfo from an existing program. - * - * A ProgramInfo contains - * - * programInfo = { - * program: WebGLProgram, - * uniformSetters: object of setters as returned from createUniformSetters, - * attribSetters: object of setters as returned from createAttribSetters, - * } - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext - * to use. - * @param {WebGLProgram} program an existing WebGLProgram. - * @return {module:twgl.ProgramInfo} The created ProgramInfo. - * @memberOf module:twgl/programs - */ - function createProgramInfoFromProgram(gl, program) { - var uniformSetters = createUniformSetters(gl, program); - var attribSetters = createAttributeSetters(gl, program); - var programInfo = { - program: program, - uniformSetters: uniformSetters, - attribSetters: attribSetters, - }; - - if (utils.isWebGL2(gl)) { - programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); - } - - return programInfo; - } - - /** - * Creates a ProgramInfo from 2 sources. - * - * A ProgramInfo contains - * - * programInfo = { - * program: WebGLProgram, - * uniformSetters: object of setters as returned from createUniformSetters, - * attribSetters: object of setters as returned from createAttribSetters, - * } - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext - * to use. - * @param {string[]} shaderSourcess Array of sources for the - * shaders or ids. The first is assumed to be the vertex shader, - * the second the fragment shader. - * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in - * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations. - * @param {module:twgl.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console - * on error. If you want something else pass an callback. It's passed an error message. - * @return {module:twgl.ProgramInfo?} The created ProgramInfo. - * @memberOf module:twgl/programs - */ - function createProgramInfo( - gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { - shaderSources = shaderSources.map(function(source) { - var script = document.getElementById(source); - return script ? script.text : source; - }); - var program = createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); - if (!program) { - return null; - } - return createProgramInfoFromProgram(gl, program); - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "createAttributeSetters": createAttributeSetters, - - "createProgram": createProgram, - "createProgramFromScripts": createProgramFromScripts, - "createProgramFromSources": createProgramFromSources, - "createProgramInfo": createProgramInfo, - "createProgramInfoFromProgram": createProgramInfoFromProgram, - "createUniformSetters": createUniformSetters, - "createUniformBlockSpecFromProgram": createUniformBlockSpecFromProgram, - "createUniformBlockInfoFromProgram": createUniformBlockInfoFromProgram, - "createUniformBlockInfo": createUniformBlockInfo, - - "setAttributes": setAttributes, - "setBuffersAndAttributes": setBuffersAndAttributes, - "setUniforms": setUniforms, - "setUniformBlock": setUniformBlock, - "setBlockUniforms": setBlockUniforms, - "bindUniformBlock": bindUniformBlock, - }; - - }); - - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - define('twgl/draw',[ - './programs', - ], function( - programs) { - - - /** - * Drawing related functions - * - * For backward compatibily they are available at both `twgl.draw` and `twgl` - * itself - * - * See {@link module:twgl} for core functions - * - * @module twgl/draw - */ - - /** - * Calls `gl.drawElements` or `gl.drawArrays`, whichever is appropriate - * - * normally you'd call `gl.drawElements` or `gl.drawArrays` yourself - * but calling this means if you switch from indexed data to non-indexed - * data you don't have to remember to update your draw call. - * - * @param {WebGLRenderingContext} gl A WebGLRenderingContext - * @param {enum} type eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...) - * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or - * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} - * @param {number} [count] An optional count. Defaults to bufferInfo.numElements - * @param {number} [offset] An optional offset. Defaults to 0. - * @memberOf module:twgl/draw - */ - function drawBufferInfo(gl, type, bufferInfo, count, offset) { - var indices = bufferInfo.indices; - var elementType = bufferInfo.elementType; - var numElements = count === undefined ? bufferInfo.numElements : count; - offset = offset === undefined ? 0 : offset; - if (elementType || indices) { - gl.drawElements(type, numElements, elementType === undefined ? gl.UNSIGNED_SHORT : bufferInfo.elementType, offset); - } else { - gl.drawArrays(type, offset, numElements); - } - } - - /** - * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. - * - * You need either a `BufferInfo` or a `VertexArrayInfo`. - * - * @typedef {Object} DrawObject - * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In otherwords `undefined` = `true` - * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... - * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} - * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} - * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} - * @property {Object} uniforms The values for the uniforms. - * You can pass multiple objects by putting them in an array. For example - * - * var sharedUniforms = { - * u_fogNear: 10, - * u_projection: ... - * ... - * }; - * - * var localUniforms = { - * u_world: ... - * u_diffuseColor: ... - * }; - * - * var drawObj = { - * ... - * uniforms: [sharedUniforms, localUniforms], - * }; - * - * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. - * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElemnts`. Defaults to bufferInfo.numElements. - * @memberOf module:twgl - */ - - /** - * Draws a list of objects - * @param {DrawObject[]} objectsToDraw an array of objects to draw. - * @memberOf module:twgl/draw - */ - function drawObjectList(gl, objectsToDraw) { - var lastUsedProgramInfo = null; - var lastUsedBufferInfo = null; - - objectsToDraw.forEach(function(object) { - if (object.active === false) { - return; - } - - var programInfo = object.programInfo; - var bufferInfo = object.vertexArrayInfo || object.bufferInfo; - var bindBuffers = false; - - if (programInfo !== lastUsedProgramInfo) { - lastUsedProgramInfo = programInfo; - gl.useProgram(programInfo.program); - - // We have to rebind buffers when changing programs because we - // only bind buffers the program uses. So if 2 programs use the same - // bufferInfo but the 1st one uses only positions the when the - // we switch to the 2nd one some of the attributes will not be on. - bindBuffers = true; - } - - // Setup all the needed attributes. - if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { - if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { - gl.bindVertexArray(null); - } - lastUsedBufferInfo = bufferInfo; - programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); - } - - // Set the uniforms. - programs.setUniforms(programInfo, object.uniforms); - - // Draw - drawBufferInfo(gl, object.type || gl.TRIANGLES, bufferInfo, object.count, object.offset); - }); - - if (lastUsedBufferInfo.vertexArrayObject) { - gl.bindVertexArray(null); - } - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "drawBufferInfo": drawBufferInfo, - "drawObjectList": drawObjectList, - }; - - }); - - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - define('twgl/textures',[ - './typedarrays', - './utils', - ], function( - typedArrays, - utils) { - - - /** - * Low level texture related functions - * - * You should generally not need to use these functions. They are provided - * for those cases where you're doing something out of the ordinary - * and you need lower level access. - * - * For backward compatibily they are available at both `twgl.textures` and `twgl` - * itself - * - * See {@link module:twgl} for core functions - * - * @module twgl/textures - */ - - // make sure we don't see a global gl - var gl = undefined; // eslint-disable-line - var defaults = { - textureColor: new Uint8Array([128, 192, 255, 255]), - textureOptions: {}, - crossOrigin: undefined, - }; - var isArrayBuffer = typedArrays.isArrayBuffer; - - /* PixelFormat */ - var ALPHA = 0x1906; - var RGB = 0x1907; - var RGBA = 0x1908; - var LUMINANCE = 0x1909; - var LUMINANCE_ALPHA = 0x190A; - - /* TextureWrapMode */ - var REPEAT = 0x2901; // eslint-disable-line - var MIRRORED_REPEAT = 0x8370; // eslint-disable-line - - /* TextureMagFilter */ - var NEAREST = 0x2600; // eslint-disable-line - - /* TextureMinFilter */ - var NEAREST_MIPMAP_NEAREST = 0x2700; // eslint-disable-line - var LINEAR_MIPMAP_NEAREST = 0x2701; // eslint-disable-line - var NEAREST_MIPMAP_LINEAR = 0x2702; // eslint-disable-line - var LINEAR_MIPMAP_LINEAR = 0x2703; // eslint-disable-line - - /** - * Sets the default texture color. - * - * The default texture color is used when loading textures from - * urls. Because the URL will be loaded async we'd like to be - * able to use the texture immediately. By putting a 1x1 pixel - * color in the texture we can start using the texture before - * the URL has loaded. - * - * @param {number[]} color Array of 4 values in the range 0 to 1 - * @deprecated see {@link module:twgl.setDefaults} - * @memberOf module:twgl/textures - */ - function setDefaultTextureColor(color) { - defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); - } - - function setDefaults(newDefaults) { - utils.copyExistingProperties(newDefaults, defaults); - if (newDefaults.textureColor) { - setDefaultTextureColor(newDefaults.textureColor); - } - } - - /** - * Gets a string for gl enum - * - * Note: Several enums are the same. Without more - * context (which function) it's impossible to always - * give the correct enum. - * - * @param {WebGLRenderingContext} gl A WebGLRenderingContext - * @param {number} value the value of the enum you want to look up. - */ - var glEnumToString = (function() { - var enums; - - function init(gl) { - if (!enums) { - enums = {}; - Object.keys(gl).forEach(function(key) { - if (typeof gl[key] === 'number') { - enums[gl[key]] = key; - } - }); - } - } - - return function glEnumToString(gl, value) { - init(); - return enums[value] || ("0x" + value.toString(16)); - }; - }()); - - /** - * A function to generate the source for a texture. - * @callback TextureFunc - * @param {WebGLRenderingContext} gl A WebGLRenderingContext - * @param {module:twgl.TextureOptions} options the texture options - * @return {*} Returns any of the things documentented for `src` for {@link module:twgl.TextureOptions}. - * @memberOf module:twgl - */ - - /** - * Texture options passed to most texture functions. Each function will use whatever options - * are appropriate for its needs. This lets you pass the same options to all functions. - * - * @typedef {Object} TextureOptions - * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. - * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. - * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. - * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` - * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. - * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` - * @property {number} [format] format for texture. Defaults to `gl.RGBA`. - * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBuffer. If `src` - * is ArrayBuffer defaults to type that matches ArrayBuffer type. - * @property {number} [wrap] Texture wrapping for both S and T. Defaults to `gl.REPEAT` for 2D and `gl.CLAMP_TO_EDGE` for cube - * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. - * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. - * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. - * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. - * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override - * the current setting for specific textures. - * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. - * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override - * the current setting for specific textures. - * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. - * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override - * the current setting for specific textures. - * @property {(number[]|ArrayBuffer)} color color used as temporary 1x1 pixel color for textures loaded async when src is a string. - * If it's a JavaScript array assumes color is 0 to 1 like most GL colors as in `[1, 0, 0, 1] = red=1, green=0, blue=0, alpha=0`. - * Defaults to `[0.5, 0.75, 1, 1]`. See {@link module:twgl.setDefaultTextureColor}. If `false` texture is set. Can be used to re-load a texture - * @property {boolean} [auto] If not `false` then texture working filtering is set automatically for non-power of 2 images and - * mips are generated for power of 2 images. - * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is - * - * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, - * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, - * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, - * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, - * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, - * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] - * - * @property {(number[]|ArrayBuffer|HTMLCanvasElement|HTMLImageElement|HTMLVideoElement|string|string[]|module:twgl.TextureFunc)} [src] source for texture - * - * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable - * 1x1 pixel texture will be returned immediatley. The texture will be updated once the image has downloaded. - * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. - * The pieces will be uploaded in `cubeFaceOrder` - * - * If `string[]` then it must have 6 entries, one for each face of a cube map. Target must be `gl.TEXTURE_CUBE_MAP`. - * - * If `HTMLElement` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, - * `HTMLCanvasElement`, `HTMLVideoElement`. - * - * If `number[]` or `ArrayBuffer` it's assumed to be data for a texture. If `width` or `height` is - * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponets` - * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided - * by 6. Then - * - * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height - * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. - * - * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. - * - * If `number[]` will be converted to `type`. - * - * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. - * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` - * an array etc... - * - * If `src` is undefined then an empty texture will be created of size `width` by `height`. - * - * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. - * default: undefined. Also see {@link module:twgl.setDefaults}. - * - * @memberOf module:twgl - */ - - // NOTE: While querying GL is considered slow it's not remotely as slow - // as uploading a texture. On top of that you're unlikely to call this in - // a perf critical loop. Even if upload a texture every frame that's unlikely - // to be more than 1 or 2 textures a frame. In other words, the benefits of - // making the API easy to use outweigh any supposed perf benefits - var lastPackState = {}; - - /** - * Saves any packing state that will be set based on the options. - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - */ - function savePackState(gl, options) { - if (options.colorspaceConversion !== undefined) { - lastPackState.colorSpaceConversion = gl.getParameter(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL); - } - if (options.premultiplyAlpha !== undefined) { - lastPackState.premultiplyAlpha = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL); - } - if (options.flipY !== undefined) { - lastPackState.flipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL); - } - } - - /** - * Restores any packing state that was set based on the options. - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - */ - function restorePackState(gl, options) { - if (options.colorspaceConversion !== undefined) { - gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, lastPackState.colorSpaceConversion); - } - if (options.premultiplyAlpha !== undefined) { - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, lastPackState.premultiplyAlpha); - } - if (options.flipY !== undefined) { - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, lastPackState.flipY); - } - } - - /** - * Sets the texture parameters of a texture. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * This is often the same options you passed in when you created the texture. - * @memberOf module:twgl/textures - */ - function setTextureParameters(gl, tex, options) { - var target = options.target || gl.TEXTURE_2D; - gl.bindTexture(target, tex); - if (options.min) { - gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, options.min); - } - if (options.mag) { - gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, options.mag); - } - if (options.wrap) { - gl.texParameteri(target, gl.TEXTURE_WRAP_S, options.wrap); - gl.texParameteri(target, gl.TEXTURE_WRAP_T, options.wrap); - } - if (options.wrapS) { - gl.texParameteri(target, gl.TEXTURE_WRAP_S, options.wrapS); - } - if (options.wrapT) { - gl.texParameteri(target, gl.TEXTURE_WRAP_T, options.wrapT); - } - } - - /** - * Makes a 1x1 pixel - * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. - * @param {(number[]|ArrayBuffer)} [color] The color using 0-1 values - * @return {Uint8Array} Unit8Array with color. - */ - function make1Pixel(color) { - color = color || defaults.textureColor; - if (isArrayBuffer(color)) { - return color; - } - return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); - } - - /** - * Returns true if value is power of 2 - * @param {number} value number to check. - * @return true if value is power of 2 - */ - function isPowerOf2(value) { - return (value & (value - 1)) === 0; - } - - /** - * Sets filtering or generates mips for texture based on width or height - * If width or height is not passed in uses `options.width` and//or `options.height` - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. - * This is often the same options you passed in when you created the texture. - * @param {number} [width] width of texture - * @param {number} [height] height of texture - * @memberOf module:twgl/textures - */ - function setTextureFilteringForSize(gl, tex, options, width, height) { - options = options || defaults.textureOptions; - var target = options.target || gl.TEXTURE_2D; - width = width || options.width; - height = height || options.height; - gl.bindTexture(target, tex); - if (!isPowerOf2(width) || !isPowerOf2(height)) { - gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } else { - gl.generateMipmap(target); - } - } - - /** - * Gets an array of cubemap face enums - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * This is often the same options you passed in when you created the texture. - * @return {number[]} cubemap face enums - */ - function getCubeFaceOrder(gl, options) { - options = options || {}; - return options.cubeFaceOrder || [ - gl.TEXTURE_CUBE_MAP_POSITIVE_X, - gl.TEXTURE_CUBE_MAP_NEGATIVE_X, - gl.TEXTURE_CUBE_MAP_POSITIVE_Y, - gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, - gl.TEXTURE_CUBE_MAP_POSITIVE_Z, - gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, - ]; - } - - /** - * @typedef {Object} FaceInfo - * @property {number} face gl enum for texImage2D - * @property {number} ndx face index (0 - 5) into source data - * @ignore - */ - - /** - * Gets an array of FaceInfos - * There's a bug in some NVidia drivers that will crash the driver if - * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take - * the user's desired order from his faces to WebGL and make sure we - * do the faces in WebGL order - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundent but - * it's needed internally to sort the array of `ndx` properties by `face`. - */ - function getCubeFacesWithNdx(gl, options) { - var faces = getCubeFaceOrder(gl, options); - // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( - var facesWithNdx = faces.map(function(face, ndx) { - return { face: face, ndx: ndx }; - }); - facesWithNdx.sort(function(a, b) { - return a.face - b.face; - }); - return facesWithNdx; - } - - /** - * Set a texture from the contents of an element. Will also set - * texture filtering or generate mips based on the dimensions of the element - * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will - * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {HTMLElement} element a canvas, img, or video element. - * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. - * This is often the same options you passed in when you created the texture. - * @memberOf module:twgl/textures - * @kind function - */ - var setTextureFromElement = function() { - var ctx = document.createElement("canvas").getContext("2d"); - return function setTextureFromElement(gl, tex, element, options) { - options = options || defaults.textureOptions; - var target = options.target || gl.TEXTURE_2D; - var width = element.width; - var height = element.height; - var format = options.format || gl.RGBA; - var type = options.type || gl.UNSIGNED_BYTE; - savePackState(gl, options); - gl.bindTexture(target, tex); - if (target === gl.TEXTURE_CUBE_MAP) { - // guess the parts - var imgWidth = element.width; - var imgHeight = element.height; - var size; - var slices; - if (imgWidth / 6 === imgHeight) { - // It's 6x1 - size = imgHeight; - slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; - } else if (imgHeight / 6 === imgWidth) { - // It's 1x6 - size = imgWidth; - slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; - } else if (imgWidth / 3 === imgHeight / 2) { - // It's 3x2 - size = imgWidth / 3; - slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; - } else if (imgWidth / 2 === imgHeight / 3) { - // It's 2x3 - size = imgWidth / 2; - slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; - } else { - throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); - } - ctx.canvas.width = size; - ctx.canvas.height = size; - width = size; - height = size; - getCubeFacesWithNdx(gl, options).forEach(function(f) { - var xOffset = slices[f.ndx * 2 + 0] * size; - var yOffset = slices[f.ndx * 2 + 1] * size; - ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); - gl.texImage2D(f.face, 0, format, format, type, ctx.canvas); - }); - // Free up the canvas memory - ctx.canvas.width = 1; - ctx.canvas.height = 1; - } else { - gl.texImage2D(target, 0, format, format, type, element); - } - restorePackState(gl, options); - if (options.auto !== false) { - setTextureFilteringForSize(gl, tex, options, width, height); - } - setTextureParameters(gl, tex, options); - }; - }(); - - function noop() { - } - - /** - * Loads an image - * @param {string} url url to image - * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null - * if there was an error - * @return {HTMLImageElement} the image being loaded. - */ - function loadImage(url, crossOrigin, callback) { - callback = callback || noop; - var img = new Image(); - crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin; - if (crossOrigin !== undefined) { - img.crossOrigin = crossOrigin; - } - - function clearEventHandlers() { - img.removeEventListener('error', onError); // eslint-disable-line - img.removeEventListener('load', onLoad); // eslint-disable-line - img = null; - } - - function onError() { - var msg = "couldn't load image: " + url; - utils.error(msg); - callback(msg, img); - clearEventHandlers(); - } - - function onLoad() { - callback(null, img); - clearEventHandlers(); - } - - img.addEventListener('error', onError); - img.addEventListener('load', onLoad); - img.src = url; - return img; - } - - /** - * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set - * the default texture color is used which can be set by calling `setDefaultTextureColor`. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. - * This is often the same options you passed in when you created the texture. - * @memberOf module:twgl/textures - */ - function setTextureTo1PixelColor(gl, tex, options) { - options = options || defaults.textureOptions; - var target = options.target || gl.TEXTURE_2D; - gl.bindTexture(target, tex); - if (options.color === false) { - return; - } - // Assume it's a URL - // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. - var color = make1Pixel(options.color); - if (target === gl.TEXTURE_CUBE_MAP) { - for (var ii = 0; ii < 6; ++ii) { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color); - } - } else { - gl.texImage2D(target, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, color); - } - } - - /** - * The src image(s) used to create a texture. - * - * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} - * you can pass in urls for images to load into the textures. If it's a single url - * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap - * this will be a corresponding array of images for the cubemap. - * - * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc - * @memberOf module:twgl - */ - - /** - * A callback for when an image finished downloading and been uploaded into a texture - * @callback TextureReadyCallback - * @param {*} err If truthy there was an error. - * @param {WebGLTexture} texture the texture. - * @param {module:twgl.TextureSrc} souce image(s) used to as the src for the texture - * @memberOf module:twgl - */ - - /** - * A callback for when all images have finished downloading and been uploaded into their respective textures - * @callback TexturesReadyCallback - * @param {*} err If truthy there was an error. - * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. - * @param {Object.} sources the image(s) used for the texture by name. - * @memberOf module:twgl - */ - - /** - * A callback for when an image finished downloading and been uploaded into a texture - * @callback CubemapReadyCallback - * @param {*} err If truthy there was an error. - * @param {WebGLTexture} tex the texture. - * @param {HTMLImageElement[]} imgs the images for each face. - * @memberOf module:twgl - */ - - /** - * Loads a texture from an image from a Url as specified in `options.src` - * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is - * immediately useable. It will be updated with the contents of the image once the image has finished - * downloading. Filtering options will be set as approriate for image unless `options.auto === false`. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. - * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will - * be non null if there was an error. - * @return {HTMLImageElement} the image being downloaded. - * @memberOf module:twgl/textures - */ - function loadTextureFromUrl(gl, tex, options, callback) { - callback = callback || noop; - options = options || defaults.textureOptions; - setTextureTo1PixelColor(gl, tex, options); - // Because it's async we need to copy the options. - options = utils.shallowCopy(options); - var img = loadImage(options.src, options.crossOrigin, function(err, img) { - if (err) { - callback(err, tex, img); - } else { - setTextureFromElement(gl, tex, img, options); - callback(null, tex, img); - } - }); - return img; - } - - /** - * Loads a cubemap from 6 urls as specified in `options.src`. Will set the cubemap to a 1x1 pixel color - * so that it is usable immediately unless `option.color === false`. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will - * be non null if there was an error. - * @memberOf module:twgl/textures - */ - function loadCubemapFromUrls(gl, tex, options, callback) { - callback = callback || noop; - var urls = options.src; - if (urls.length !== 6) { - throw "there must be 6 urls for a cubemap"; - } - var format = options.format || gl.RGBA; - var type = options.type || gl.UNSIGNED_BYTE; - var target = options.target || gl.TEXTURE_2D; - if (target !== gl.TEXTURE_CUBE_MAP) { - throw "target must be TEXTURE_CUBE_MAP"; - } - setTextureTo1PixelColor(gl, tex, options); - // Because it's async we need to copy the options. - options = utils.shallowCopy(options); - var numToLoad = 6; - var errors = []; - var imgs; - var faces = getCubeFaceOrder(gl, options); - - function uploadImg(faceTarget) { - return function(err, img) { - --numToLoad; - if (err) { - errors.push(err); - } else { - if (img.width !== img.height) { - errors.push("cubemap face img is not a square: " + img.src); - } else { - savePackState(gl, options); - gl.bindTexture(target, tex); - - // So assuming this is the first image we now have one face that's img sized - // and 5 faces that are 1x1 pixel so size the other faces - if (numToLoad === 5) { - // use the default order - getCubeFaceOrder(gl).forEach(function(otherTarget) { - // Should we re-use the same face or a color? - gl.texImage2D(otherTarget, 0, format, format, type, img); - }); - } else { - gl.texImage2D(faceTarget, 0, format, format, type, img); - } - - restorePackState(gl, options); - gl.generateMipmap(target); - } - } - - if (numToLoad === 0) { - callback(errors.length ? errors : undefined, imgs, tex); - } - }; - } - - imgs = urls.map(function(url, ndx) { - return loadImage(url, options.crossOrigin, uploadImg(faces[ndx])); - }); - } - - /** - * Gets the number of compontents for a given image format. - * @param {number} format the format. - * @return {number} the number of components for the format. - * @memberOf module:twgl/textures - */ - function getNumComponentsForFormat(format) { - switch (format) { - case ALPHA: - case LUMINANCE: - return 1; - case LUMINANCE_ALPHA: - return 2; - case RGB: - return 3; - case RGBA: - return 4; - default: - throw "unknown type: " + format; - } - } - - /** - * Gets the texture type for a given array type. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @return {number} the gl texture type - */ - function getTextureTypeForArrayType(gl, src) { - if (isArrayBuffer(src)) { - return typedArrays.getGLTypeForTypedArray(src); - } - return gl.UNSIGNED_BYTE; - } - - /** - * Sets a texture from an array or typed array. If the width or height is not provided will attempt to - * guess the size. See {@link module:twgl.TextureOptions}. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {(number[]|ArrayBuffer)} src An array or typed arry with texture data. - * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. - * This is often the same options you passed in when you created the texture. - * @memberOf module:twgl/textures - */ - function setTextureFromArray(gl, tex, src, options) { - options = options || defaults.textureOptions; - var target = options.target || gl.TEXTURE_2D; - gl.bindTexture(target, tex); - var width = options.width; - var height = options.height; - var format = options.format || gl.RGBA; - var type = options.type || getTextureTypeForArrayType(gl, src); - var numComponents = getNumComponentsForFormat(format); - var numElements = src.length / numComponents; - if (numElements % 1) { - throw "length wrong size for format: " + glEnumToString(gl, format); - } - if (!width && !height) { - var size = Math.sqrt(numElements / (target === gl.TEXTURE_CUBE_MAP ? 6 : 1)); - if (size % 1 === 0) { - width = size; - height = size; - } else { - width = numElements; - height = 1; - } - } else if (!height) { - height = numElements / width; - if (height % 1) { - throw "can't guess height"; - } - } else if (!width) { - width = numElements / height; - if (width % 1) { - throw "can't guess width"; - } - } - if (!isArrayBuffer(src)) { - var Type = typedArrays.getTypedArrayTypeForGLType(type); - src = new Type(src); - } else { - if (src instanceof Uint8ClampedArray) { - src = new Uint8Array(src.buffer); - } - } - gl.pixelStorei(gl.UNPACK_ALIGNMENT, options.unpackAlignment || 1); - savePackState(gl, options); - if (target === gl.TEXTURE_CUBE_MAP) { - var faceSize = numElements / 6 * numComponents; - getCubeFacesWithNdx(gl, options).forEach(function(f) { - var offset = faceSize * f.ndx; - var data = src.subarray(offset, offset + faceSize); - gl.texImage2D(f.face, 0, format, width, height, 0, format, type, data); - }); - } else { - gl.texImage2D(target, 0, format, width, height, 0, format, type, src); - } - restorePackState(gl, options); - return { - width: width, - height: height, - }; - } - - /** - * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. - * You must set `options.width` and `options.height`. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the WebGLTexture to set parameters for - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * @memberOf module:twgl/textures - */ - function setEmptyTexture(gl, tex, options) { - var target = options.target || gl.TEXTURE_2D; - gl.bindTexture(target, tex); - var format = options.format || gl.RGBA; - var type = options.type || gl.UNSIGNED_BYTE; - savePackState(gl, options); - if (target === gl.TEXTURE_CUBE_MAP) { - for (var ii = 0; ii < 6; ++ii) { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, format, options.width, options.height, 0, format, type, null); - } - } else { - gl.texImage2D(target, 0, format, options.width, options.height, 0, format, type, null); - } - } - - /** - * Creates a texture based on the options passed in. - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. - * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. - * @return {WebGLTexture} the created texture. - * @memberOf module:twgl/textures - */ - function createTexture(gl, options, callback) { - callback = callback || noop; - options = options || defaults.textureOptions; - var tex = gl.createTexture(); - var target = options.target || gl.TEXTURE_2D; - var width = options.width || 1; - var height = options.height || 1; - gl.bindTexture(target, tex); - if (target === gl.TEXTURE_CUBE_MAP) { - // this should have been the default for CUBEMAPS :( - gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - var src = options.src; - if (src) { - if (typeof src === "function") { - src = src(gl, options); - } - if (typeof (src) === "string") { - loadTextureFromUrl(gl, tex, options, callback); - } else if (isArrayBuffer(src) || - (Array.isArray(src) && ( - typeof src[0] === 'number' || - Array.isArray(src[0]) || - isArrayBuffer(src[0])) - ) - ) { - var dimensions = setTextureFromArray(gl, tex, src, options); - width = dimensions.width; - height = dimensions.height; - } else if (Array.isArray(src) && typeof (src[0]) === 'string') { - loadCubemapFromUrls(gl, tex, options, callback); - } else if (src instanceof HTMLElement) { - setTextureFromElement(gl, tex, src, options); - width = src.width; - height = src.height; - } else { - throw "unsupported src type"; - } - } else { - setEmptyTexture(gl, tex, options); - } - if (options.auto !== false) { - setTextureFilteringForSize(gl, tex, options, width, height); - } - setTextureParameters(gl, tex, options); - return tex; - } - - /** - * Resizes a texture based on the options passed in. - * - * Note: This is not a generic resize anything function. - * It's mostly used by {@link module:twgl.resizeFramebufferInfo} - * It will use `options.src` if it exists to try to determine a `type` - * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided - * for the texture. Texture parameters will be set accordingly - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {WebGLTexture} tex the texture to resize - * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. - * @param {number} [width] the new width. If not passed in will use `options.width` - * @param {number} [height] the new height. If not passed in will use `options.height` - * @memberOf module:twgl/textures - */ - function resizeTexture(gl, tex, options, width, height) { - width = width || options.width; - height = height || options.height; - var target = options.target || gl.TEXTURE_2D; - gl.bindTexture(target, tex); - var format = options.format || gl.RGBA; - var type; - var src = options.src; - if (!src) { - type = options.type || gl.UNSIGNED_BYTE; - } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) { - type = options.type || getTextureTypeForArrayType(gl, src); - } else { - type = options.type || gl.UNSIGNED_BYTE; - } - if (target === gl.TEXTURE_CUBE_MAP) { - for (var ii = 0; ii < 6; ++ii) { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, format, width, height, 0, format, type, null); - } - } else { - gl.texImage2D(target, 0, format, width, height, 0, format, type, null); - } - } - - /** - * Check if a src is an async request. - * if src is a string we're going to download an image - * if src is an array of strings we're going to download cubemap images - * @param {*} src The src from a TextureOptions - * @returns {bool} true if src is async. - */ - function isAsyncSrc(src) { - return typeof src === 'string' || - (Array.isArray(src) && typeof src[0] === 'string'); - } - - /** - * Creates a bunch of textures based on the passed in options. - * - * Example: - * - * var textures = twgl.createTextures(gl, { - * // a power of 2 image - * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, - * // a non-power of 2 image - * clover: { src: "images/clover.jpg" }, - * // From a canvas - * fromCanvas: { src: ctx.canvas }, - * // A cubemap from 6 images - * yokohama: { - * target: gl.TEXTURE_CUBE_MAP, - * src: [ - * 'images/yokohama/posx.jpg', - * 'images/yokohama/negx.jpg', - * 'images/yokohama/posy.jpg', - * 'images/yokohama/negy.jpg', - * 'images/yokohama/posz.jpg', - * 'images/yokohama/negz.jpg', - * ], - * }, - * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) - * goldengate: { - * target: gl.TEXTURE_CUBE_MAP, - * src: 'images/goldengate.jpg', - * }, - * // A 2x2 pixel texture from a JavaScript array - * checker: { - * mag: gl.NEAREST, - * min: gl.LINEAR, - * src: [ - * 255,255,255,255, - * 192,192,192,255, - * 192,192,192,255, - * 255,255,255,255, - * ], - * }, - * // a 1x2 pixel texture from a typed array. - * stripe: { - * mag: gl.NEAREST, - * min: gl.LINEAR, - * format: gl.LUMINANCE, - * src: new Uint8Array([ - * 255, - * 128, - * 255, - * 128, - * 255, - * 128, - * 255, - * 128, - * ]), - * width: 1, - * }, - * }); - * - * Now - * - * * `textures.hftIcon` will be a 2d texture - * * `textures.clover` will be a 2d texture - * * `textures.fromCanvas` will be a 2d texture - * * `textures.yohohama` will be a cubemap texture - * * `textures.goldengate` will be a cubemap texture - * * `textures.checker` will be a 2d texture - * * `textures.stripe` will be a 2d texture - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {Object.} options A object of TextureOptions one per texture. - * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. - * @return {Object.} the created textures by name - * @memberOf module:twgl/textures - */ - function createTextures(gl, textureOptions, callback) { - callback = callback || noop; - var numDownloading = 0; - var errors = []; - var textures = {}; - var images = {}; - - function callCallbackIfReady() { - if (numDownloading === 0) { - setTimeout(function() { - callback(errors.length ? errors : undefined, textures, images); - }, 0); - } - } - - Object.keys(textureOptions).forEach(function(name) { - var options = textureOptions[name]; - var onLoadFn; - if (isAsyncSrc(options.src)) { - onLoadFn = function(err, tex, img) { - images[name] = img; - --numDownloading; - if (err) { - errors.push(err); - } - callCallbackIfReady(); - }; - ++numDownloading; - } - textures[name] = createTexture(gl, options, onLoadFn); - }); - - // queue the callback if there are no images to download. - // We do this because if your code is structured to wait for - // images to download but then you comment out all the async - // images your code would break. - callCallbackIfReady(); - - return textures; - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "setDefaults_": setDefaults, - - "createTexture": createTexture, - "setEmptyTexture": setEmptyTexture, - "setTextureFromArray": setTextureFromArray, - "loadTextureFromUrl": loadTextureFromUrl, - "setTextureFromElement": setTextureFromElement, - "setTextureFilteringForSize": setTextureFilteringForSize, - "setTextureParameters": setTextureParameters, - "setDefaultTextureColor": setDefaultTextureColor, - "createTextures": createTextures, - "resizeTexture": resizeTexture, - "getNumComponentsForFormat": getNumComponentsForFormat, - }; - }); - - - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - define('twgl/framebuffers',[ - './textures', - './utils', - ], function( - textures, - utils) { - - - /** - * Framebuffer related functions - * - * For backward compatibily they are available at both `twgl.framebuffer` and `twgl` - * itself - * - * See {@link module:twgl} for core functions - * - * @module twgl/framebuffers - */ - - // make sure we don't see a global gl - var gl = undefined; // eslint-disable-line - - var UNSIGNED_BYTE = 0x1401; - - /* PixelFormat */ - var DEPTH_COMPONENT = 0x1902; - var RGBA = 0x1908; - - /* Framebuffer Object. */ - var RGBA4 = 0x8056; - var RGB5_A1 = 0x8057; - var RGB565 = 0x8D62; - var DEPTH_COMPONENT16 = 0x81A5; - var STENCIL_INDEX = 0x1901; - var STENCIL_INDEX8 = 0x8D48; - var DEPTH_STENCIL = 0x84F9; - var COLOR_ATTACHMENT0 = 0x8CE0; - var DEPTH_ATTACHMENT = 0x8D00; - var STENCIL_ATTACHMENT = 0x8D20; - var DEPTH_STENCIL_ATTACHMENT = 0x821A; - - /* TextureWrapMode */ - var REPEAT = 0x2901; // eslint-disable-line - var CLAMP_TO_EDGE = 0x812F; - var MIRRORED_REPEAT = 0x8370; // eslint-disable-line - - /* TextureMagFilter */ - var NEAREST = 0x2600; // eslint-disable-line - var LINEAR = 0x2601; - - /* TextureMinFilter */ - var NEAREST_MIPMAP_NEAREST = 0x2700; // eslint-disable-line - var LINEAR_MIPMAP_NEAREST = 0x2701; // eslint-disable-line - var NEAREST_MIPMAP_LINEAR = 0x2702; // eslint-disable-line - var LINEAR_MIPMAP_LINEAR = 0x2703; // eslint-disable-line - - /** - * The options for a framebuffer attachment. - * - * Note: For a `format` that is a texture include all the texture - * options from {@link module:twgl.TextureOptions} for example - * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} - * `auto` defaults to `false` for attachment textures - * - * @typedef {Object} AttachmentOptions - * @property {number} [attach] The attachment point. Defaults - * to `gl.COLOR_ATTACTMENT0 + ndx` unless type is a depth or stencil type - * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending - * on the format or attachment type. - * @property {number} [format] The format. If one of `gl.RGBA4`, - * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, - * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a - * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` - * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. - * @property {number} [target] The texture target for `gl.framebufferTexture2D`. - * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. - * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. - * @property {WebGLObject} [attachment] An existing renderbuffer or texture. - * If provided will attach this Object. This allows you to share - * attachemnts across framebuffers. - * @memberOf module:twgl - */ - - var defaultAttachments = [ - { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, }, - { format: DEPTH_STENCIL, }, - ]; - - var attachmentsByFormat = {}; - attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; - attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; - attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; - attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; - attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; - - function getAttachmentPointForFormat(format) { - return attachmentsByFormat[format]; - } - - var renderbufferFormats = {}; - renderbufferFormats[RGBA4] = true; - renderbufferFormats[RGB5_A1] = true; - renderbufferFormats[RGB565] = true; - renderbufferFormats[DEPTH_STENCIL] = true; - renderbufferFormats[DEPTH_COMPONENT16] = true; - renderbufferFormats[STENCIL_INDEX] = true; - renderbufferFormats[STENCIL_INDEX8] = true; - - function isRenderbufferFormat(format) { - return renderbufferFormats[format]; - } - - /** - * @typedef {Object} FramebufferInfo - * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo - * @property {WebGLObject[]} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. - * @memberOf module:twgl - */ - - /** - * Creates a framebuffer and attachments. - * - * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. - * - * The simplest usage - * - * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer - * var fbi = twgl.createFramebuffer(gl); - * - * More complex usage - * - * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer - * var attachments = [ - * { format: RGB565, mag: NEAREST }, - * { format: STENCIL_INDEX8 }, - * ] - * var fbi = twgl.createFramebuffer(gl, attachments); - * - * Passing in a specific size - * - * var width = 256; - * var height = 256; - * var fbi = twgl.createFramebuffer(gl, attachments, width, height); - * - * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. - * [WebGL only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an - * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. - * @param {number} [width] the width for the attachments. Default = size of drawingBuffer - * @param {number} [height] the height for the attachments. Defautt = size of drawingBuffer - * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. - * @memberOf module:twgl/framebuffers - */ - function createFramebufferInfo(gl, attachments, width, height) { - var target = gl.FRAMEBUFFER; - var fb = gl.createFramebuffer(); - gl.bindFramebuffer(target, fb); - width = width || gl.drawingBufferWidth; - height = height || gl.drawingBufferHeight; - attachments = attachments || defaultAttachments; - var colorAttachmentCount = 0; - var framebufferInfo = { - framebuffer: fb, - attachments: [], - width: width, - height: height, - }; - attachments.forEach(function(attachmentOptions) { - var attachment = attachmentOptions.attachment; - var format = attachmentOptions.format; - var attachmentPoint = getAttachmentPointForFormat(format); - if (!attachmentPoint) { - attachmentPoint = COLOR_ATTACHMENT0 + colorAttachmentCount++; - } - if (!attachment) { - if (isRenderbufferFormat(format)) { - attachment = gl.createRenderbuffer(); - gl.bindRenderbuffer(gl.RENDERBUFFER, attachment); - gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height); - } else { - var textureOptions = utils.shallowCopy(attachmentOptions); - textureOptions.width = width; - textureOptions.height = height; - textureOptions.auto = attachmentOptions.auto === undefined ? false : attachmentOptions.auto; - attachment = textures.createTexture(gl, textureOptions); - } - } - if (attachment instanceof WebGLRenderbuffer) { - gl.framebufferRenderbuffer(target, attachmentPoint, gl.RENDERBUFFER, attachment); - } else if (attachment instanceof WebGLTexture) { - gl.framebufferTexture2D( - target, - attachmentPoint, - attachmentOptions.texTarget || gl.TEXTURE_2D, - attachment, - attachmentOptions.level || 0); - } else { - throw "unknown attachment type"; - } - framebufferInfo.attachments.push(attachment); - }); - return framebufferInfo; - } - - /** - * Resizes the attachments of a framebuffer. - * - * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebuffer} - * because TWGL has no idea the format/type of each attachment. - * - * The simplest usage - * - * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer - * var fbi = twgl.createFramebuffer(gl); - * - * ... - * - * function render() { - * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { - * // resize the attachments - * twgl.resizeFramebufferInfo(gl, fbi); - * } - * - * More complex usage - * - * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer - * var attachments = [ - * { format: RGB565, mag: NEAREST }, - * { format: STENCIL_INDEX8 }, - * ] - * var fbi = twgl.createFramebuffer(gl, attachments); - * - * ... - * - * function render() { - * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { - * // resize the attachments to match - * twgl.resizeFramebufferInfo(gl, fbi, attachments); - * } - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebuffer}. - * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebuffer}. - * @param {number} [width] the width for the attachments. Default = size of drawingBuffer - * @param {number} [height] the height for the attachments. Defautt = size of drawingBuffer - * @memberOf module:twgl/framebuffers - */ - function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { - width = width || gl.drawingBufferWidth; - height = height || gl.drawingBufferHeight; - framebufferInfo.width = width; - framebufferInfo.height = height; - attachments = attachments || defaultAttachments; - attachments.forEach(function(attachmentOptions, ndx) { - var attachment = framebufferInfo.attachments[ndx]; - var format = attachmentOptions.format; - if (attachment instanceof WebGLRenderbuffer) { - gl.bindRenderbuffer(gl.RENDERBUFFER, attachment); - gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height); - } else if (attachment instanceof WebGLTexture) { - textures.resizeTexture(gl, attachment, attachmentOptions, width, height); - } else { - throw "unknown attachment type"; - } - }); - } - - /** - * Binds a framebuffer - * - * This function pretty much soley exists because I spent hours - * trying to figure out why something I wrote wasn't working only - * to realize I forget to set the viewport dimensions. - * My hope is this function will fix that. - * - * It is effectively the same as - * - * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); - * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); - * - * @param {WebGLRenderingContext} gl the WebGLRenderingContext - * @param {module:twgl.FramebufferInfo} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebuffer}. - * If not passed will bind the canvas. - * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. - * @memberOf module:twgl/framebuffers - */ - - function bindFramebufferInfo(gl, framebufferInfo, target) { - target = target || gl.FRAMEBUFFER; - if (framebufferInfo) { - gl.bindFramebuffer(target, framebufferInfo.framebuffer); - gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); - } else { - gl.bindFramebuffer(target, null); - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "bindFramebufferInfo": bindFramebufferInfo, - "createFramebufferInfo": createFramebufferInfo, - "resizeFramebufferInfo": resizeFramebufferInfo, - }; - }); - - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - define('twgl/twgl',[ - './attributes', - './draw', - './framebuffers', - './programs', - './textures', - './typedarrays', - './utils', - ], function( - attributes, - draw, - framebuffers, - programs, - textures, - typedArrays, - utils) { - - - /** - * The main TWGL module. - * - * For most use cases you shouldn't need anything outside this module. - * Exceptions between the stuff added to twgl-full (v3, m4, primitives) - * - * @module twgl - * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray - * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays - * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo - * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo - * @borrows module:twgl/draw.drawObjectList as drawObjectList - * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo - * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo - * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo - * @borrows module:twgl/programs.createProgramInfo as createProgramInfo - * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo - * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock - * @borrows module:twgl/programs.setUniformBlock as setUniformBlock - * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms - * @borrows module:twgl/programs.setUniforms as setUniforms - * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes - * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray - * @borrows module:twgl/textures.createTexture as createTexture - * @borrows module:twgl/textures.resizeTexture as resizeTexture - * @borrows module:twgl/textures.createTextures as createTextures - */ - - // make sure we don't see a global gl - var gl = undefined; // eslint-disable-line - var defaults = { - enableVertexArrayObjects: true, - }; - - /** - * Various default settings for twgl. - * - * Note: You can call this any number of times. Example: - * - * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); - * twgl.setDefaults({ attribPrefix: 'a_' }); - * - * is equivalent to - * - * twgl.setDefaults({ - * textureColor: [1, 0, 0, 1], - * attribPrefix: 'a_', - * }); - * - * @typedef {Object} Defaults - * @property {string} attribPrefix The prefix to stick on attributes - * - * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` - * as it makes it clear where they came from. But, when building geometry I prefer using unprefixed names. - * - * In otherwords I'll create arrays of geometry like this - * - * var arrays = { - * position: ... - * normal: ... - * texcoord: ... - * }; - * - * But need those mapped to attributes and my attributes start with `a_`. - * - * Default: `""` - * - * @property {number[]} textureColor Array of 4 values in the range 0 to 1 - * - * The default texture color is used when loading textures from - * urls. Because the URL will be loaded async we'd like to be - * able to use the texture immediately. By putting a 1x1 pixel - * color in the texture we can start using the texture before - * the URL has loaded. - * - * Default: `[0.5, 0.75, 1, 1]` - * - * @property {string} crossOrigin - * - * If not undefined sets the crossOrigin attribute on images - * that twgl creates when downloading images for textures. - * - * Also see {@link module:twgl.TextureOptions}. - * - * @property {bool} enableVertexArrayObjects - * - * If true then in WebGL 1.0 will attempt to get the `OES_vertex_array_object` extension. - * If successful it will copy create/bind/delete/isVertexArrayOES from the extension to - * the WebGLRenderingContext removing the OES at the end which is the standard entry point - * for WebGL 2. - * - * Note: According to webglstats.com 90% of devices support `OES_vertex_array_object`. - * If you just want to count on support I suggest using [this polyfill](https://github.com/KhronosGroup/WebGL/blob/master/sdk/demos/google/resources/OESVertexArrayObject.js) - * or ignoring devices that don't support them. - * - * Default: `true` - * - * @memberOf module:twgl - */ - - /** - * Sets various defaults for twgl. - * - * In the interest of terseness which is kind of the point - * of twgl I've integrated a few of the older functions here - * - * @param {module:twgl.Defaults} newDefaults The default settings. - * @memberOf module:twgl - */ - function setDefaults(newDefaults) { - utils.copyExistingProperties(newDefaults, defaults); - attributes.setDefaults_(newDefaults); // eslint-disable-line - textures.setDefaults_(newDefaults); // eslint-disable-line - } - - /** - * Adds Vertex Array Objects to WebGL 1 GL contexts if available - * @param {WebGLRenderingContext} gl A WebGLRenderingContext - */ - function addVertexArrayObjectSupport(gl) { - if (!gl || !defaults.enableVertexArrayObjects) { - return; - } - if (utils.isWebGL1(gl)) { - var ext = gl.getExtension("OES_vertex_array_object"); - if (ext) { - gl.createVertexArray = function() { - return ext.createVertexArrayOES(); - }; - gl.deleteVertexArray = function(v) { - ext.deleteVertexArrayOES(v); - }; - gl.isVertexArray = function(v) { - return ext.isVertexArrayOES(v); - }; - gl.bindVertexArray = function(v) { - ext.bindVertexArrayOES(v); - }; - gl.VERTEX_ARRAY_BINDING = ext.VERTEX_ARRAY_BINDING_OES; - } - } - } - - /** - * Creates a webgl context. - * @param {HTMLCanvasElement} canvas The canvas tag to get - * context from. If one is not passed in one will be - * created. - * @return {WebGLRenderingContext} The created context. - */ - function create3DContext(canvas, opt_attribs) { - var names = ["webgl", "experimental-webgl"]; - var context = null; - for (var ii = 0; ii < names.length; ++ii) { - try { - context = canvas.getContext(names[ii], opt_attribs); - } catch(e) {} // eslint-disable-line - if (context) { - break; - } - } - return context; - } - - /** - * Gets a WebGL context. - * @param {HTMLCanvasElement} canvas a canvas element. - * @param {WebGLContextCreationAttirbutes} [opt_attribs] optional webgl context creation attributes - * @memberOf module:twgl - */ - function getWebGLContext(canvas, opt_attribs) { - var gl = create3DContext(canvas, opt_attribs); - addVertexArrayObjectSupport(gl); - return gl; - } - - /** - * Creates a webgl context. - * - * Will return a WebGL2 context if possible. - * - * You can check if it's WebGL2 with - * - * twgl.isWebGL2(gl); - * - * @param {HTMLCanvasElement} canvas The canvas tag to get - * context from. If one is not passed in one will be - * created. - * @return {WebGLRenderingContext} The created context. - */ - function createContext(canvas, opt_attribs) { - var names = ["webgl2", "experimental-webgl2", "webgl", "experimental-webgl"]; - var context = null; - for (var ii = 0; ii < names.length; ++ii) { - try { - context = canvas.getContext(names[ii], opt_attribs); - } catch(e) {} // eslint-disable-line - if (context) { - break; - } - } - return context; - } - - /** - * Gets a WebGL context. Will create a WebGL2 context if possible. - * - * You can check if it's WebGL2 with - * - * function isWebGL2(gl) { - * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; - * } - * - * @param {HTMLCanvasElement} canvas a canvas element. - * @param {WebGLContextCreationAttirbutes} [opt_attribs] optional webgl context creation attributes - * @return {WebGLRenderingContext} The created context. - * @memberOf module:twgl - */ - function getContext(canvas, opt_attribs) { - var gl = createContext(canvas, opt_attribs); - addVertexArrayObjectSupport(gl); - return gl; - } - - /** - * Resize a canvas to match the size it's displayed. - * @param {HTMLCanvasElement} canvas The canvas to resize. - * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` if you want to. - * @return {boolean} true if the canvas was resized. - * @memberOf module:twgl - */ - function resizeCanvasToDisplaySize(canvas, multiplier) { - multiplier = multiplier || 1; - multiplier = Math.max(1, multiplier); - var width = canvas.clientWidth * multiplier | 0; - var height = canvas.clientHeight * multiplier | 0; - if (canvas.width !== width || - canvas.height !== height) { - canvas.width = width; - canvas.height = height; - return true; - } - return false; - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - var api = { - "getContext": getContext, - "getWebGLContext": getWebGLContext, - "isWebGL1": utils.isWebGL1, - "isWebGL2": utils.isWebGL2, - "resizeCanvasToDisplaySize": resizeCanvasToDisplaySize, - "setDefaults": setDefaults, - }; - - function notPrivate(name) { - return name[name.length - 1] !== '_'; - } - - function copyPublicProperties(src, dst) { - Object.keys(src).filter(notPrivate).forEach(function(key) { - dst[key] = src[key]; - }); - return dst; - } - - var apis = { - attributes: attributes, - draw: draw, - framebuffers: framebuffers, - programs: programs, - textures: textures, - typedArrays: typedArrays, - }; - Object.keys(apis).forEach(function(name) { - var srcApi = apis[name]; - copyPublicProperties(srcApi, api); - api[name] = copyPublicProperties(srcApi, {}); - }); - - return api; - - }); - - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - define('twgl/v3',[], function() { - - - /** - * - * Vec3 math math functions. - * - * Almost all functions take an optional `dst` argument. If it is not passed in the - * functions will create a new Vec3. In other words you can do this - * - * var v = v3.cross(v1, v2); // Creates a new Vec3 with the cross product of v1 x v2. - * - * or - * - * var v3 = v3.create(); - * v3.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v - * - * The first style is often easier but depending on where it's used it generates garbage where - * as there is almost never allocation with the second style. - * - * It is always save to pass any vector as the destination. So for example - * - * v3.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1 - * - * @module twgl/v3 - */ - - var VecType = Float32Array; - - /** - * A JavaScript array with 3 values or a Float32Array with 3 values. - * When created by the library will create the default type which is `Float32Array` - * but can be set by calling {@link module:twgl/v3.setDefaultType}. - * @typedef {(number[]|Float32Array)} Vec3 - * @memberOf module:twgl/v3 - */ - - /** - * Sets the type this library creates for a Vec3 - * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` - * @return {constructor} previous constructor for Vec3 - */ - function setDefaultType(ctor) { - var oldType = VecType; - VecType = ctor; - return oldType; - } - - /** - * Creates a vec3; may be called with x, y, z to set initial values. - * @return {Vec3} the created vector - * @memberOf module:twgl/v3 - */ - function create(x, y, z) { - var dst = new VecType(3); - if (x) { - dst[0] = x; - } - if (y) { - dst[1] = y; - } - if (z) { - dst[2] = z; - } - return dst; - } - - /** - * Adds two vectors; assumes a and b have the same dimension. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @memberOf module:twgl/v3 - */ - function add(a, b, dst) { - dst = dst || new VecType(3); - - dst[0] = a[0] + b[0]; - dst[1] = a[1] + b[1]; - dst[2] = a[2] + b[2]; - - return dst; - } - - /** - * Subtracts two vectors. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @memberOf module:twgl/v3 - */ - function subtract(a, b, dst) { - dst = dst || new VecType(3); - - dst[0] = a[0] - b[0]; - dst[1] = a[1] - b[1]; - dst[2] = a[2] - b[2]; - - return dst; - } - - /** - * Performs linear interpolation on two vectors. - * Given vectors a and b and interpolation coefficient t, returns - * (1 - t) * a + t * b. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @param {number} t Interpolation coefficient. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @memberOf module:twgl/v3 - */ - function lerp(a, b, t, dst) { - dst = dst || new VecType(3); - - dst[0] = (1 - t) * a[0] + t * b[0]; - dst[1] = (1 - t) * a[1] + t * b[1]; - dst[2] = (1 - t) * a[2] + t * b[2]; - - return dst; - } - - /** - * Mutiplies a vector by a scalar. - * @param {module:twgl/v3.Vec3} v The vector. - * @param {number} k The scalar. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} dst. - * @memberOf module:twgl/v3 - */ - function mulScalar(v, k, dst) { - dst = dst || new VecType(3); - - dst[0] = v[0] * k; - dst[1] = v[1] * k; - dst[2] = v[2] * k; - - return dst; - } - - /** - * Divides a vector by a scalar. - * @param {module:twgl/v3.Vec3} v The vector. - * @param {number} k The scalar. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} dst. - * @memberOf module:twgl/v3 - */ - function divScalar(v, k, dst) { - dst = dst || new VecType(3); - - dst[0] = v[0] / k; - dst[1] = v[1] / k; - dst[2] = v[2] / k; - - return dst; - } - - /** - * Computes the cross product of two vectors; assumes both vectors have - * three entries. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} The vector a cross b. - * @memberOf module:twgl/v3 - */ - function cross(a, b, dst) { - dst = dst || new VecType(3); - - dst[0] = a[1] * b[2] - a[2] * b[1]; - dst[1] = a[2] * b[0] - a[0] * b[2]; - dst[2] = a[0] * b[1] - a[1] * b[0]; - - return dst; - } - - /** - * Computes the dot product of two vectors; assumes both vectors have - * three entries. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @return {number} dot product - * @memberOf module:twgl/v3 - */ - function dot(a, b) { - return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); - } - - /** - * Computes the length of vector - * @param {module:twgl/v3.Vec3} v vector. - * @return {number} length of vector. - * @memberOf module:twgl/v3 - */ - function length(v) { - return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - } - - /** - * Computes the square of the length of vector - * @param {module:twgl/v3.Vec3} v vector. - * @return {number} square of the length of vector. - * @memberOf module:twgl/v3 - */ - function lengthSq(v) { - return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; - } - - /** - * Divides a vector by its Euclidean length and returns the quotient. - * @param {module:twgl/v3.Vec3} a The vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} The normalized vector. - * @memberOf module:twgl/v3 - */ - function normalize(a, dst) { - dst = dst || new VecType(3); - - var lenSq = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; - var len = Math.sqrt(lenSq); - if (len > 0.00001) { - dst[0] = a[0] / len; - dst[1] = a[1] / len; - dst[2] = a[2] / len; - } else { - dst[0] = 0; - dst[1] = 0; - dst[2] = 0; - } - - return dst; - } - - /** - * Negates a vector. - * @param {module:twgl/v3.Vec3} v The vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} -v. - * @memberOf module:twgl/v3 - */ - function negate(v, dst) { - dst = dst || new VecType(3); - - dst[0] = -v[0]; - dst[1] = -v[1]; - dst[2] = -v[2]; - - return dst; - } - - /** - * Copies a vector. - * @param {module:twgl/v3.Vec3} v The vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} A copy of v. - * @memberOf module:twgl/v3 - */ - function copy(v, dst) { - dst = dst || new VecType(3); - - dst[0] = v[0]; - dst[1] = v[1]; - dst[2] = v[2]; - - return dst; - } - - /** - * Multiplies a vector by another vector (component-wise); assumes a and - * b have the same length. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} The vector of products of entries of a and - * b. - * @memberOf module:twgl/v3 - */ - function multiply(a, b, dst) { - dst = dst || new VecType(3); - - dst[0] = a[0] * b[0]; - dst[1] = a[1] * b[1]; - dst[2] = a[2] * b[2]; - - return dst; - } - - /** - * Divides a vector by another vector (component-wise); assumes a and - * b have the same length. - * @param {module:twgl/v3.Vec3} a Operand vector. - * @param {module:twgl/v3.Vec3} b Operand vector. - * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.. - * @return {module:twgl/v3.Vec3} The vector of quotients of entries of a and - * b. - * @memberOf module:twgl/v3 - */ - function divide(a, b, dst) { - dst = dst || new VecType(3); - - dst[0] = a[0] / b[0]; - dst[1] = a[1] / b[1]; - dst[2] = a[2] / b[2]; - - return dst; - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "add": add, - "copy": copy, - "create": create, - "cross": cross, - "divide": divide, - "divScalar": divScalar, - "dot": dot, - "lerp": lerp, - "length": length, - "lengthSq": lengthSq, - "mulScalar": mulScalar, - "multiply": multiply, - "negate": negate, - "normalize": normalize, - "setDefaultType": setDefaultType, - "subtract": subtract, - }; - - }); - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - define('twgl/m4',['./v3'], function(v3) { - - - /** - * 4x4 Matrix math math functions. - * - * Almost all functions take an optional `dst` argument. If it is not passed in the - * functions will create a new matrix. In other words you can do this - * - * var mat = m4.translation([1, 2, 3]); // Creates a new translation matrix - * - * or - * - * var mat = m4.create(); - * m4.translation([1, 2, 3], mat); // Puts translation matrix in mat. - * - * The first style is often easier but depending on where it's used it generates garbage where - * as there is almost never allocation with the second style. - * - * It is always save to pass any matrix as the destination. So for example - * - * var mat = m4.identity(); - * var trans = m4.translation([1, 2, 3]); - * m4.multiply(mat, trans, mat); // Multiplies mat * trans and puts result in mat. - * - * @module twgl/m4 - */ - var MatType = Float32Array; - - var tempV3a = v3.create(); - var tempV3b = v3.create(); - var tempV3c = v3.create(); - - /** - * A JavaScript array with 16 values or a Float32Array with 16 values. - * When created by the library will create the default type which is `Float32Array` - * but can be set by calling {@link module:twgl/m4.setDefaultType}. - * @typedef {(number[]|Float32Array)} Mat4 - * @memberOf module:twgl/m4 - */ - - /** - * Sets the type this library creates for a Mat4 - * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` - * @return {constructor} previous constructor for Mat4 - */ - function setDefaultType(ctor) { - var oldType = MatType; - MatType = ctor; - return oldType; - } - - /** - * Negates a matrix. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} -m. - * @memberOf module:twgl/m4 - */ - function negate(m, dst) { - dst = dst || new MatType(16); - - dst[ 0] = -m[ 0]; - dst[ 1] = -m[ 1]; - dst[ 2] = -m[ 2]; - dst[ 3] = -m[ 3]; - dst[ 4] = -m[ 4]; - dst[ 5] = -m[ 5]; - dst[ 6] = -m[ 6]; - dst[ 7] = -m[ 7]; - dst[ 8] = -m[ 8]; - dst[ 9] = -m[ 9]; - dst[10] = -m[10]; - dst[11] = -m[11]; - dst[12] = -m[12]; - dst[13] = -m[13]; - dst[14] = -m[14]; - dst[15] = -m[15]; - - return dst; - } - - /** - * Copies a matrix. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {module:twgl/m4.Mat4} [dst] The matrix. - * @return {module:twgl/m4.Mat4} A copy of m. - * @memberOf module:twgl/m4 - */ - function copy(m, dst) { - dst = dst || new MatType(16); - - dst[ 0] = m[ 0]; - dst[ 1] = m[ 1]; - dst[ 2] = m[ 2]; - dst[ 3] = m[ 3]; - dst[ 4] = m[ 4]; - dst[ 5] = m[ 5]; - dst[ 6] = m[ 6]; - dst[ 7] = m[ 7]; - dst[ 8] = m[ 8]; - dst[ 9] = m[ 9]; - dst[10] = m[10]; - dst[11] = m[11]; - dst[12] = m[12]; - dst[13] = m[13]; - dst[14] = m[14]; - dst[15] = m[15]; - - return dst; - } - - /** - * Creates an n-by-n identity matrix. - * - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} An n-by-n identity matrix. - * @memberOf module:twgl/m4 - */ - function identity(dst) { - dst = dst || new MatType(16); - - dst[ 0] = 1; - dst[ 1] = 0; - dst[ 2] = 0; - dst[ 3] = 0; - dst[ 4] = 0; - dst[ 5] = 1; - dst[ 6] = 0; - dst[ 7] = 0; - dst[ 8] = 0; - dst[ 9] = 0; - dst[10] = 1; - dst[11] = 0; - dst[12] = 0; - dst[13] = 0; - dst[14] = 0; - dst[15] = 1; - - return dst; - } - - /** - * Takes the transpose of a matrix. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The transpose of m. - * @memberOf module:twgl/m4 - */ - function transpose(m, dst) { - dst = dst || new MatType(16); - if (dst === m) { - var t; - - t = m[1]; - m[1] = m[4]; - m[4] = t; - - t = m[2]; - m[2] = m[8]; - m[8] = t; - - t = m[3]; - m[3] = m[12]; - m[12] = t; - - t = m[6]; - m[6] = m[9]; - m[9] = t; - - t = m[7]; - m[7] = m[13]; - m[13] = t; - - t = m[11]; - m[11] = m[14]; - m[14] = t; - return dst; - } - - var m00 = m[0 * 4 + 0]; - var m01 = m[0 * 4 + 1]; - var m02 = m[0 * 4 + 2]; - var m03 = m[0 * 4 + 3]; - var m10 = m[1 * 4 + 0]; - var m11 = m[1 * 4 + 1]; - var m12 = m[1 * 4 + 2]; - var m13 = m[1 * 4 + 3]; - var m20 = m[2 * 4 + 0]; - var m21 = m[2 * 4 + 1]; - var m22 = m[2 * 4 + 2]; - var m23 = m[2 * 4 + 3]; - var m30 = m[3 * 4 + 0]; - var m31 = m[3 * 4 + 1]; - var m32 = m[3 * 4 + 2]; - var m33 = m[3 * 4 + 3]; - - dst[ 0] = m00; - dst[ 1] = m10; - dst[ 2] = m20; - dst[ 3] = m30; - dst[ 4] = m01; - dst[ 5] = m11; - dst[ 6] = m21; - dst[ 7] = m31; - dst[ 8] = m02; - dst[ 9] = m12; - dst[10] = m22; - dst[11] = m32; - dst[12] = m03; - dst[13] = m13; - dst[14] = m23; - dst[15] = m33; - - return dst; - } - - /** - * Computes the inverse of a 4-by-4 matrix. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The inverse of m. - * @memberOf module:twgl/m4 - */ - function inverse(m, dst) { - dst = dst || new MatType(16); - - var m00 = m[0 * 4 + 0]; - var m01 = m[0 * 4 + 1]; - var m02 = m[0 * 4 + 2]; - var m03 = m[0 * 4 + 3]; - var m10 = m[1 * 4 + 0]; - var m11 = m[1 * 4 + 1]; - var m12 = m[1 * 4 + 2]; - var m13 = m[1 * 4 + 3]; - var m20 = m[2 * 4 + 0]; - var m21 = m[2 * 4 + 1]; - var m22 = m[2 * 4 + 2]; - var m23 = m[2 * 4 + 3]; - var m30 = m[3 * 4 + 0]; - var m31 = m[3 * 4 + 1]; - var m32 = m[3 * 4 + 2]; - var m33 = m[3 * 4 + 3]; - var tmp_0 = m22 * m33; - var tmp_1 = m32 * m23; - var tmp_2 = m12 * m33; - var tmp_3 = m32 * m13; - var tmp_4 = m12 * m23; - var tmp_5 = m22 * m13; - var tmp_6 = m02 * m33; - var tmp_7 = m32 * m03; - var tmp_8 = m02 * m23; - var tmp_9 = m22 * m03; - var tmp_10 = m02 * m13; - var tmp_11 = m12 * m03; - var tmp_12 = m20 * m31; - var tmp_13 = m30 * m21; - var tmp_14 = m10 * m31; - var tmp_15 = m30 * m11; - var tmp_16 = m10 * m21; - var tmp_17 = m20 * m11; - var tmp_18 = m00 * m31; - var tmp_19 = m30 * m01; - var tmp_20 = m00 * m21; - var tmp_21 = m20 * m01; - var tmp_22 = m00 * m11; - var tmp_23 = m10 * m01; - - var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); - var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); - var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); - var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); - - var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); - - dst[ 0] = d * t0; - dst[ 1] = d * t1; - dst[ 2] = d * t2; - dst[ 3] = d * t3; - dst[ 4] = d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); - dst[ 5] = d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); - dst[ 6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); - dst[ 7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); - dst[ 8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); - dst[ 9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); - dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); - dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); - dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); - dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); - dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); - dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); - - return dst; - } - - /** - * Multiplies two 4-by-4 matrices; assumes that the given matrices are 4-by-4; - * assumes matrix entries are accessed in [row][column] fashion. - * @param {module:twgl/m4.Mat4} a The matrix on the left. - * @param {module:twgl/m4.Mat4} b The matrix on the right. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The matrix product of a and b. - * @memberOf module:twgl/m4 - */ - function multiply(a, b, dst) { - dst = dst || new MatType(16); - - var a00 = a[0]; - var a01 = a[1]; - var a02 = a[2]; - var a03 = a[3]; - var a10 = a[ 4 + 0]; - var a11 = a[ 4 + 1]; - var a12 = a[ 4 + 2]; - var a13 = a[ 4 + 3]; - var a20 = a[ 8 + 0]; - var a21 = a[ 8 + 1]; - var a22 = a[ 8 + 2]; - var a23 = a[ 8 + 3]; - var a30 = a[12 + 0]; - var a31 = a[12 + 1]; - var a32 = a[12 + 2]; - var a33 = a[12 + 3]; - var b00 = b[0]; - var b01 = b[1]; - var b02 = b[2]; - var b03 = b[3]; - var b10 = b[ 4 + 0]; - var b11 = b[ 4 + 1]; - var b12 = b[ 4 + 2]; - var b13 = b[ 4 + 3]; - var b20 = b[ 8 + 0]; - var b21 = b[ 8 + 1]; - var b22 = b[ 8 + 2]; - var b23 = b[ 8 + 3]; - var b30 = b[12 + 0]; - var b31 = b[12 + 1]; - var b32 = b[12 + 2]; - var b33 = b[12 + 3]; - - dst[ 0] = a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30; - dst[ 1] = a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31; - dst[ 2] = a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32; - dst[ 3] = a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33; - dst[ 4] = a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30; - dst[ 5] = a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31; - dst[ 6] = a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32; - dst[ 7] = a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33; - dst[ 8] = a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30; - dst[ 9] = a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31; - dst[10] = a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32; - dst[11] = a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33; - dst[12] = a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30; - dst[13] = a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31; - dst[14] = a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32; - dst[15] = a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33; - - return dst; - } - - /** - * Sets the translation component of a 4-by-4 matrix to the given - * vector. - * @param {module:twgl/m4.Mat4} a The matrix. - * @param {Vec3} v The vector. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} a once modified. - * @memberOf module:twgl/m4 - */ - function setTranslation(a, v, dst) { - dst = dst || identity(); - if (a !== dst) { - dst[ 0] = a[ 0]; - dst[ 1] = a[ 1]; - dst[ 2] = a[ 2]; - dst[ 3] = a[ 3]; - dst[ 4] = a[ 4]; - dst[ 5] = a[ 5]; - dst[ 6] = a[ 6]; - dst[ 7] = a[ 7]; - dst[ 8] = a[ 8]; - dst[ 9] = a[ 9]; - dst[10] = a[10]; - dst[11] = a[11]; - } - dst[12] = v[0]; - dst[13] = v[1]; - dst[14] = v[2]; - dst[15] = 1; - return dst; - } - - /** - * Returns the translation component of a 4-by-4 matrix as a vector with 3 - * entries. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {Vec3} [dst] vector.. - * @return {Vec3} The translation component of m. - * @memberOf module:twgl/m4 - */ - function getTranslation(m, dst) { - dst = dst || v3.create(); - dst[0] = m[12]; - dst[1] = m[13]; - dst[2] = m[14]; - return dst; - } - - /** - * Returns an axis of a 4x4 matrix as a vector with 3 entries - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {number} axis The axis 0 = x, 1 = y, 2 = z; - * @return {Vec3} [dst] vector. - * @return {Vec3} The axis component of m. - * @memberOf module:twgl/m4 - */ - function getAxis(m, axis, dst) { - dst = dst || v3.create(); - var off = axis * 4; - dst[0] = m[off + 0]; - dst[1] = m[off + 1]; - dst[2] = m[off + 2]; - return dst; - } - - /** - * Sets an axis of a 4x4 matrix as a vector with 3 entries - * @param {Vec3} v the axis vector - * @param {number} axis The axis 0 = x, 1 = y, 2 = z; - * @param {module:twgl/m4.Mat4} [dst] The matrix to set. If none a new one is created - * @return {module:twgl/m4.Mat4} dst - * @memberOf module:twgl/m4 - */ - function setAxis(a, v, axis, dst) { - if (dst !== a) { - dst = copy(a, dst); - } - var off = axis * 4; - dst[off + 0] = v[0]; - dst[off + 1] = v[1]; - dst[off + 2] = v[2]; - return dst; - } - - /** - * Computes a 4-by-4 perspective transformation matrix given the angular height - * of the frustum, the aspect ratio, and the near and far clipping planes. The - * arguments define a frustum extending in the negative z direction. The given - * angle is the vertical angle of the frustum, and the horizontal angle is - * determined to produce the given aspect ratio. The arguments near and far are - * the distances to the near and far clipping planes. Note that near and far - * are not z coordinates, but rather they are distances along the negative - * z-axis. The matrix generated sends the viewing frustum to the unit box. - * We assume a unit box extending from -1 to 1 in the x and y dimensions and - * from 0 to 1 in the z dimension. - * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians). - * @param {number} aspect The aspect ratio width / height. - * @param {number} zNear The depth (negative z coordinate) - * of the near clipping plane. - * @param {number} zFar The depth (negative z coordinate) - * of the far clipping plane. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The perspective matrix. - * @memberOf module:twgl/m4 - */ - function perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) { - dst = dst || new MatType(16); - - var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians); - var rangeInv = 1.0 / (zNear - zFar); - - dst[0] = f / aspect; - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; - - dst[4] = 0; - dst[5] = f; - dst[6] = 0; - dst[7] = 0; - - dst[8] = 0; - dst[9] = 0; - dst[10] = (zNear + zFar) * rangeInv; - dst[11] = -1; - - dst[12] = 0; - dst[13] = 0; - dst[14] = zNear * zFar * rangeInv * 2; - dst[15] = 0; - - return dst; - } - - /** - * Computes a 4-by-4 othogonal transformation matrix given the left, right, - * bottom, and top dimensions of the near clipping plane as well as the - * near and far clipping plane distances. - * @param {number} left Left side of the near clipping plane viewport. - * @param {number} right Right side of the near clipping plane viewport. - * @param {number} top Top of the near clipping plane viewport. - * @param {number} bottom Bottom of the near clipping plane viewport. - * @param {number} near The depth (negative z coordinate) - * of the near clipping plane. - * @param {number} far The depth (negative z coordinate) - * of the far clipping plane. - * @param {module:twgl/m4.Mat4} [dst] Output matrix. - * @return {module:twgl/m4.Mat4} The perspective matrix. - * @memberOf module:twgl/m4 - */ - function ortho(left, right, bottom, top, near, far, dst) { - dst = dst || new MatType(16); - - dst[0] = 2 / (right - left); - dst[1] = 0; - dst[2] = 0; - dst[3] = 0; - - dst[4] = 0; - dst[5] = 2 / (top - bottom); - dst[6] = 0; - dst[7] = 0; - - dst[8] = 0; - dst[9] = 0; - dst[10] = -1 / (far - near); - dst[11] = 0; - - dst[12] = (right + left) / (left - right); - dst[13] = (top + bottom) / (bottom - top); - dst[14] = -near / (near - far); - dst[15] = 1; - - return dst; - } - - /** - * Computes a 4-by-4 perspective transformation matrix given the left, right, - * top, bottom, near and far clipping planes. The arguments define a frustum - * extending in the negative z direction. The arguments near and far are the - * distances to the near and far clipping planes. Note that near and far are not - * z coordinates, but rather they are distances along the negative z-axis. The - * matrix generated sends the viewing frustum to the unit box. We assume a unit - * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z - * dimension. - * @param {number} left The x coordinate of the left plane of the box. - * @param {number} right The x coordinate of the right plane of the box. - * @param {number} bottom The y coordinate of the bottom plane of the box. - * @param {number} top The y coordinate of the right plane of the box. - * @param {number} near The negative z coordinate of the near plane of the box. - * @param {number} far The negative z coordinate of the far plane of the box. - * @param {module:twgl/m4.Mat4} [dst] Output matrix. - * @return {module:twgl/m4.Mat4} The perspective projection matrix. - * @memberOf module:twgl/m4 - */ - function frustum(left, right, bottom, top, near, far, dst) { - dst = dst || new MatType(16); - - var dx = (right - left); - var dy = (top - bottom); - var dz = (near - far); - - dst[ 0] = 2 * near / dx; - dst[ 1] = 0; - dst[ 2] = 0; - dst[ 3] = 0; - dst[ 4] = 0; - dst[ 5] = 2 * near / dy; - dst[ 6] = 0; - dst[ 7] = 0; - dst[ 8] = (left + right) / dx; - dst[ 9] = (top + bottom) / dy; - dst[10] = far / dz; - dst[11] = -1; - dst[12] = 0; - dst[13] = 0; - dst[14] = near * far / dz; - dst[15] = 0; - - return dst; - } - - /** - * Computes a 4-by-4 look-at transformation. - * - * This is a matrix which positions the camera itself. If you want - * a view matrix (a matrix which moves things in front of the camera) - * take the inverse of this. - * - * @param {Vec3} eye The position of the eye. - * @param {Vec3} target The position meant to be viewed. - * @param {Vec3} up A vector pointing up. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The look-at matrix. - * @memberOf module:twgl/m4 - */ - function lookAt(eye, target, up, dst) { - dst = dst || new MatType(16); - - var xAxis = tempV3a; - var yAxis = tempV3b; - var zAxis = tempV3c; - - v3.normalize( - v3.subtract(eye, target, zAxis), zAxis); - v3.normalize(v3.cross(up, zAxis, xAxis), xAxis); - v3.normalize(v3.cross(zAxis, xAxis, yAxis), yAxis); - - dst[ 0] = xAxis[0]; - dst[ 1] = xAxis[1]; - dst[ 2] = xAxis[2]; - dst[ 3] = 0; - dst[ 4] = yAxis[0]; - dst[ 5] = yAxis[1]; - dst[ 6] = yAxis[2]; - dst[ 7] = 0; - dst[ 8] = zAxis[0]; - dst[ 9] = zAxis[1]; - dst[10] = zAxis[2]; - dst[11] = 0; - dst[12] = eye[0]; - dst[13] = eye[1]; - dst[14] = eye[2]; - dst[15] = 1; - - return dst; - } - - /** - * Creates a 4-by-4 matrix which translates by the given vector v. - * @param {Vec3} v The vector by - * which to translate. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The translation matrix. - * @memberOf module:twgl/m4 - */ - function translation(v, dst) { - dst = dst || new MatType(16); - - dst[ 0] = 1; - dst[ 1] = 0; - dst[ 2] = 0; - dst[ 3] = 0; - dst[ 4] = 0; - dst[ 5] = 1; - dst[ 6] = 0; - dst[ 7] = 0; - dst[ 8] = 0; - dst[ 9] = 0; - dst[10] = 1; - dst[11] = 0; - dst[12] = v[0]; - dst[13] = v[1]; - dst[14] = v[2]; - dst[15] = 1; - return dst; - } - - /** - * Modifies the given 4-by-4 matrix by translation by the given vector v. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {Vec3} v The vector by - * which to translate. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} m once modified. - * @memberOf module:twgl/m4 - */ - function translate(m, v, dst) { - dst = dst || new MatType(16); - - var v0 = v[0]; - var v1 = v[1]; - var v2 = v[2]; - var m00 = m[0]; - var m01 = m[1]; - var m02 = m[2]; - var m03 = m[3]; - var m10 = m[1 * 4 + 0]; - var m11 = m[1 * 4 + 1]; - var m12 = m[1 * 4 + 2]; - var m13 = m[1 * 4 + 3]; - var m20 = m[2 * 4 + 0]; - var m21 = m[2 * 4 + 1]; - var m22 = m[2 * 4 + 2]; - var m23 = m[2 * 4 + 3]; - var m30 = m[3 * 4 + 0]; - var m31 = m[3 * 4 + 1]; - var m32 = m[3 * 4 + 2]; - var m33 = m[3 * 4 + 3]; - - if (m !== dst) { - dst[ 0] = m00; - dst[ 1] = m01; - dst[ 2] = m02; - dst[ 3] = m03; - dst[ 4] = m10; - dst[ 5] = m11; - dst[ 6] = m12; - dst[ 7] = m13; - dst[ 8] = m20; - dst[ 9] = m21; - dst[10] = m22; - dst[11] = m23; - } - - dst[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; - dst[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; - dst[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; - dst[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; - - return dst; - } - - /** - * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The rotation matrix. - * @memberOf module:twgl/m4 - */ - function rotationX(angleInRadians, dst) { - dst = dst || new MatType(16); - - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - - dst[ 0] = 1; - dst[ 1] = 0; - dst[ 2] = 0; - dst[ 3] = 0; - dst[ 4] = 0; - dst[ 5] = c; - dst[ 6] = s; - dst[ 7] = 0; - dst[ 8] = 0; - dst[ 9] = -s; - dst[10] = c; - dst[11] = 0; - dst[12] = 0; - dst[13] = 0; - dst[14] = 0; - dst[15] = 1; - - return dst; - } - - /** - * Modifies the given 4-by-4 matrix by a rotation around the x-axis by the given - * angle. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} m once modified. - * @memberOf module:twgl/m4 - */ - function rotateX(m, angleInRadians, dst) { - dst = dst || new MatType(16); - - var m10 = m[4]; - var m11 = m[5]; - var m12 = m[6]; - var m13 = m[7]; - var m20 = m[8]; - var m21 = m[9]; - var m22 = m[10]; - var m23 = m[11]; - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - - dst[4] = c * m10 + s * m20; - dst[5] = c * m11 + s * m21; - dst[6] = c * m12 + s * m22; - dst[7] = c * m13 + s * m23; - dst[8] = c * m20 - s * m10; - dst[9] = c * m21 - s * m11; - dst[10] = c * m22 - s * m12; - dst[11] = c * m23 - s * m13; - - if (m !== dst) { - dst[ 0] = m[ 0]; - dst[ 1] = m[ 1]; - dst[ 2] = m[ 2]; - dst[ 3] = m[ 3]; - dst[12] = m[12]; - dst[13] = m[13]; - dst[14] = m[14]; - dst[15] = m[15]; - } - - return dst; - } - - /** - * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The rotation matrix. - * @memberOf module:twgl/m4 - */ - function rotationY(angleInRadians, dst) { - dst = dst || new MatType(16); - - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - - dst[ 0] = c; - dst[ 1] = 0; - dst[ 2] = -s; - dst[ 3] = 0; - dst[ 4] = 0; - dst[ 5] = 1; - dst[ 6] = 0; - dst[ 7] = 0; - dst[ 8] = s; - dst[ 9] = 0; - dst[10] = c; - dst[11] = 0; - dst[12] = 0; - dst[13] = 0; - dst[14] = 0; - dst[15] = 1; - - return dst; - } - - /** - * Modifies the given 4-by-4 matrix by a rotation around the y-axis by the given - * angle. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} m once modified. - * @memberOf module:twgl/m4 - */ - function rotateY(m, angleInRadians, dst) { - dst = dst || new MatType(16); - - var m00 = m[0 * 4 + 0]; - var m01 = m[0 * 4 + 1]; - var m02 = m[0 * 4 + 2]; - var m03 = m[0 * 4 + 3]; - var m20 = m[2 * 4 + 0]; - var m21 = m[2 * 4 + 1]; - var m22 = m[2 * 4 + 2]; - var m23 = m[2 * 4 + 3]; - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - - dst[ 0] = c * m00 - s * m20; - dst[ 1] = c * m01 - s * m21; - dst[ 2] = c * m02 - s * m22; - dst[ 3] = c * m03 - s * m23; - dst[ 8] = c * m20 + s * m00; - dst[ 9] = c * m21 + s * m01; - dst[10] = c * m22 + s * m02; - dst[11] = c * m23 + s * m03; - - if (m !== dst) { - dst[ 4] = m[ 4]; - dst[ 5] = m[ 5]; - dst[ 6] = m[ 6]; - dst[ 7] = m[ 7]; - dst[12] = m[12]; - dst[13] = m[13]; - dst[14] = m[14]; - dst[15] = m[15]; - } - - return dst; - } - - /** - * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The rotation matrix. - * @memberOf module:twgl/m4 - */ - function rotationZ(angleInRadians, dst) { - dst = dst || new MatType(16); - - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - - dst[ 0] = c; - dst[ 1] = s; - dst[ 2] = 0; - dst[ 3] = 0; - dst[ 4] = -s; - dst[ 5] = c; - dst[ 6] = 0; - dst[ 7] = 0; - dst[ 8] = 0; - dst[ 9] = 0; - dst[10] = 1; - dst[11] = 0; - dst[12] = 0; - dst[13] = 0; - dst[14] = 0; - dst[15] = 1; - - return dst; - } - - /** - * Modifies the given 4-by-4 matrix by a rotation around the z-axis by the given - * angle. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} m once modified. - * @memberOf module:twgl/m4 - */ - function rotateZ(m, angleInRadians, dst) { - dst = dst || new MatType(16); - - var m00 = m[0 * 4 + 0]; - var m01 = m[0 * 4 + 1]; - var m02 = m[0 * 4 + 2]; - var m03 = m[0 * 4 + 3]; - var m10 = m[1 * 4 + 0]; - var m11 = m[1 * 4 + 1]; - var m12 = m[1 * 4 + 2]; - var m13 = m[1 * 4 + 3]; - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - - dst[ 0] = c * m00 + s * m10; - dst[ 1] = c * m01 + s * m11; - dst[ 2] = c * m02 + s * m12; - dst[ 3] = c * m03 + s * m13; - dst[ 4] = c * m10 - s * m00; - dst[ 5] = c * m11 - s * m01; - dst[ 6] = c * m12 - s * m02; - dst[ 7] = c * m13 - s * m03; - - if (m !== dst) { - dst[ 8] = m[ 8]; - dst[ 9] = m[ 9]; - dst[10] = m[10]; - dst[11] = m[11]; - dst[12] = m[12]; - dst[13] = m[13]; - dst[14] = m[14]; - dst[15] = m[15]; - } - - return dst; - } - - /** - * Creates a 4-by-4 matrix which rotates around the given axis by the given - * angle. - * @param {Vec3} axis The axis - * about which to rotate. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} A matrix which rotates angle radians - * around the axis. - * @memberOf module:twgl/m4 - */ - function axisRotation(axis, angleInRadians, dst) { - dst = dst || new MatType(16); - - var x = axis[0]; - var y = axis[1]; - var z = axis[2]; - var n = Math.sqrt(x * x + y * y + z * z); - x /= n; - y /= n; - z /= n; - var xx = x * x; - var yy = y * y; - var zz = z * z; - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - var oneMinusCosine = 1 - c; - - dst[ 0] = xx + (1 - xx) * c; - dst[ 1] = x * y * oneMinusCosine + z * s; - dst[ 2] = x * z * oneMinusCosine - y * s; - dst[ 3] = 0; - dst[ 4] = x * y * oneMinusCosine - z * s; - dst[ 5] = yy + (1 - yy) * c; - dst[ 6] = y * z * oneMinusCosine + x * s; - dst[ 7] = 0; - dst[ 8] = x * z * oneMinusCosine + y * s; - dst[ 9] = y * z * oneMinusCosine - x * s; - dst[10] = zz + (1 - zz) * c; - dst[11] = 0; - dst[12] = 0; - dst[13] = 0; - dst[14] = 0; - dst[15] = 1; - - return dst; - } - - /** - * Modifies the given 4-by-4 matrix by rotation around the given axis by the - * given angle. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {Vec3} axis The axis - * about which to rotate. - * @param {number} angleInRadians The angle by which to rotate (in radians). - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} m once modified. - * @memberOf module:twgl/m4 - */ - function axisRotate(m, axis, angleInRadians, dst) { - dst = dst || new MatType(16); - - var x = axis[0]; - var y = axis[1]; - var z = axis[2]; - var n = Math.sqrt(x * x + y * y + z * z); - x /= n; - y /= n; - z /= n; - var xx = x * x; - var yy = y * y; - var zz = z * z; - var c = Math.cos(angleInRadians); - var s = Math.sin(angleInRadians); - var oneMinusCosine = 1 - c; - - var r00 = xx + (1 - xx) * c; - var r01 = x * y * oneMinusCosine + z * s; - var r02 = x * z * oneMinusCosine - y * s; - var r10 = x * y * oneMinusCosine - z * s; - var r11 = yy + (1 - yy) * c; - var r12 = y * z * oneMinusCosine + x * s; - var r20 = x * z * oneMinusCosine + y * s; - var r21 = y * z * oneMinusCosine - x * s; - var r22 = zz + (1 - zz) * c; - - var m00 = m[0]; - var m01 = m[1]; - var m02 = m[2]; - var m03 = m[3]; - var m10 = m[4]; - var m11 = m[5]; - var m12 = m[6]; - var m13 = m[7]; - var m20 = m[8]; - var m21 = m[9]; - var m22 = m[10]; - var m23 = m[11]; - - dst[ 0] = r00 * m00 + r01 * m10 + r02 * m20; - dst[ 1] = r00 * m01 + r01 * m11 + r02 * m21; - dst[ 2] = r00 * m02 + r01 * m12 + r02 * m22; - dst[ 3] = r00 * m03 + r01 * m13 + r02 * m23; - dst[ 4] = r10 * m00 + r11 * m10 + r12 * m20; - dst[ 5] = r10 * m01 + r11 * m11 + r12 * m21; - dst[ 6] = r10 * m02 + r11 * m12 + r12 * m22; - dst[ 7] = r10 * m03 + r11 * m13 + r12 * m23; - dst[ 8] = r20 * m00 + r21 * m10 + r22 * m20; - dst[ 9] = r20 * m01 + r21 * m11 + r22 * m21; - dst[10] = r20 * m02 + r21 * m12 + r22 * m22; - dst[11] = r20 * m03 + r21 * m13 + r22 * m23; - - if (m !== dst) { - dst[12] = m[12]; - dst[13] = m[13]; - dst[14] = m[14]; - dst[15] = m[15]; - } - - return dst; - } - - /** - * Creates a 4-by-4 matrix which scales in each dimension by an amount given by - * the corresponding entry in the given vector; assumes the vector has three - * entries. - * @param {Vec3} v A vector of - * three entries specifying the factor by which to scale in each dimension. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} The scaling matrix. - * @memberOf module:twgl/m4 - */ - function scaling(v, dst) { - dst = dst || new MatType(16); - - dst[ 0] = v[0]; - dst[ 1] = 0; - dst[ 2] = 0; - dst[ 3] = 0; - dst[ 4] = 0; - dst[ 5] = v[1]; - dst[ 6] = 0; - dst[ 7] = 0; - dst[ 8] = 0; - dst[ 9] = 0; - dst[10] = v[2]; - dst[11] = 0; - dst[12] = 0; - dst[13] = 0; - dst[14] = 0; - dst[15] = 1; - - return dst; - } - - /** - * Modifies the given 4-by-4 matrix, scaling in each dimension by an amount - * given by the corresponding entry in the given vector; assumes the vector has - * three entries. - * @param {module:twgl/m4.Mat4} m The matrix to be modified. - * @param {Vec3} v A vector of three entries specifying the - * factor by which to scale in each dimension. - * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If none new one is created.. - * @return {module:twgl/m4.Mat4} m once modified. - * @memberOf module:twgl/m4 - */ - function scale(m, v, dst) { - dst = dst || new MatType(16); - - var v0 = v[0]; - var v1 = v[1]; - var v2 = v[2]; - - dst[ 0] = v0 * m[0 * 4 + 0]; - dst[ 1] = v0 * m[0 * 4 + 1]; - dst[ 2] = v0 * m[0 * 4 + 2]; - dst[ 3] = v0 * m[0 * 4 + 3]; - dst[ 4] = v1 * m[1 * 4 + 0]; - dst[ 5] = v1 * m[1 * 4 + 1]; - dst[ 6] = v1 * m[1 * 4 + 2]; - dst[ 7] = v1 * m[1 * 4 + 3]; - dst[ 8] = v2 * m[2 * 4 + 0]; - dst[ 9] = v2 * m[2 * 4 + 1]; - dst[10] = v2 * m[2 * 4 + 2]; - dst[11] = v2 * m[2 * 4 + 3]; - - if (m !== dst) { - dst[12] = m[12]; - dst[13] = m[13]; - dst[14] = m[14]; - dst[15] = m[15]; - } - - return dst; - } - - /** - * Takes a 4-by-4 matrix and a vector with 3 entries, - * interprets the vector as a point, transforms that point by the matrix, and - * returns the result as a vector with 3 entries. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {Vec3} v The point. - * @param {Vec3} dst optional vec3 to store result - * @return {Vec3} dst or new vec3 if not provided - * @memberOf module:twgl/m4 - */ - function transformPoint(m, v, dst) { - dst = dst || v3.create(); - var v0 = v[0]; - var v1 = v[1]; - var v2 = v[2]; - var d = v0 * m[0 * 4 + 3] + v1 * m[1 * 4 + 3] + v2 * m[2 * 4 + 3] + m[3 * 4 + 3]; - - dst[0] = (v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0] + m[3 * 4 + 0]) / d; - dst[1] = (v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1] + m[3 * 4 + 1]) / d; - dst[2] = (v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2] + m[3 * 4 + 2]) / d; - - return dst; - } - - /** - * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a - * direction, transforms that direction by the matrix, and returns the result; - * assumes the transformation of 3-dimensional space represented by the matrix - * is parallel-preserving, i.e. any combination of rotation, scaling and - * translation, but not a perspective distortion. Returns a vector with 3 - * entries. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {Vec3} v The direction. - * @param {Vec3} dst optional Vec3 to store result - * @return {Vec3} dst or new Vec3 if not provided - * @memberOf module:twgl/m4 - */ - function transformDirection(m, v, dst) { - dst = dst || v3.create(); - - var v0 = v[0]; - var v1 = v[1]; - var v2 = v[2]; - - dst[0] = v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0]; - dst[1] = v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1]; - dst[2] = v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2]; - - return dst; - } - - /** - * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector - * as a normal to a surface, and computes a vector which is normal upon - * transforming that surface by the matrix. The effect of this function is the - * same as transforming v (as a direction) by the inverse-transpose of m. This - * function assumes the transformation of 3-dimensional space represented by the - * matrix is parallel-preserving, i.e. any combination of rotation, scaling and - * translation, but not a perspective distortion. Returns a vector with 3 - * entries. - * @param {module:twgl/m4.Mat4} m The matrix. - * @param {Vec3} v The normal. - * @param {Vec3} [dst] The direction. - * @return {Vec3} The transformed direction. - * @memberOf module:twgl/m4 - */ - function transformNormal(m, v, dst) { - dst = dst || v3.create(); - var mi = inverse(m); - var v0 = v[0]; - var v1 = v[1]; - var v2 = v[2]; - - dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2]; - dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2]; - dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2]; - - return dst; - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "axisRotate": axisRotate, - "axisRotation": axisRotation, - "create": identity, - "copy": copy, - "frustum": frustum, - "getAxis": getAxis, - "getTranslation": getTranslation, - "identity": identity, - "inverse": inverse, - "lookAt": lookAt, - "multiply": multiply, - "negate": negate, - "ortho": ortho, - "perspective": perspective, - "rotateX": rotateX, - "rotateY": rotateY, - "rotateZ": rotateZ, - "rotateAxis": axisRotate, - "rotationX": rotationX, - "rotationY": rotationY, - "rotationZ": rotationZ, - "scale": scale, - "scaling": scaling, - "setAxis": setAxis, - "setDefaultType": setDefaultType, - "setTranslation": setTranslation, - "transformDirection": transformDirection, - "transformNormal": transformNormal, - "transformPoint": transformPoint, - "translate": translate, - "translation": translation, - "transpose": transpose, - }; - }); - - - /* - * Copyright 2015, Gregg Tavares. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Gregg Tavares. nor the names of his - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - /** - * Various functions to make simple primitives - * - * note: Most primitive functions come in 3 styles - * - * * `createSomeShapeBufferInfo` - * - * These functions are almost always the functions you want to call. They - * create vertices then make WebGLBuffers and create {@link module:twgl.AttribInfo}s - * returing a {@link module:twgl.BufferInfo} you can pass to {@link module:twgl.setBuffersAndAttributes} - * and {@link module:twgl.drawBufferInfo} etc... - * - * * `createSomeShapeBuffers` - * - * These create WebGLBuffers and put your data in them but nothing else. - * It's a shortcut to doing it yourself if you don't want to use - * the higher level functions. - * - * * `createSomeShapeVertices` - * - * These just create vertices, no buffers. This allows you to manipulate the vertices - * or add more data before generating a {@link module:twgl.BufferInfo}. Once you're finished - * manipulating the vertices call {@link module:twgl.createBufferInfoFromArrays}. - * - * example: - * - * var arrays = twgl.primitives.createPlaneArrays(1); - * twgl.primitives.reorientVertices(arrays, m4.rotationX(Math.PI * 0.5)); - * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); - * - * @module twgl/primitives - */ - define('twgl/primitives',[ - './attributes', - './twgl', - './utils', - './m4', - './v3', - ], function( - attributes, - twgl, - utils, - m4, - v3 - ) { - - - var getArray = attributes.getArray_; // eslint-disable-line - var getNumComponents = attributes.getNumComponents_; // eslint-disable-line - - /** - * Add `push` to a typed array. It just keeps a 'cursor' - * and allows use to `push` values into the array so we - * don't have to manually compute offsets - * @param {TypedArray} typedArray TypedArray to augment - * @param {number} numComponents number of components. - */ - function augmentTypedArray(typedArray, numComponents) { - var cursor = 0; - typedArray.push = function() { - for (var ii = 0; ii < arguments.length; ++ii) { - var value = arguments[ii]; - if (value instanceof Array || (value.buffer && value.buffer instanceof ArrayBuffer)) { - for (var jj = 0; jj < value.length; ++jj) { - typedArray[cursor++] = value[jj]; - } - } else { - typedArray[cursor++] = value; - } - } - }; - typedArray.reset = function(opt_index) { - cursor = opt_index || 0; - }; - typedArray.numComponents = numComponents; - Object.defineProperty(typedArray, 'numElements', { - get: function() { - return this.length / this.numComponents | 0; - }, - }); - return typedArray; - } - - /** - * creates a typed array with a `push` function attached - * so that you can easily *push* values. - * - * `push` can take multiple arguments. If an argument is an array each element - * of the array will be added to the typed array. - * - * Example: - * - * var array = createAugmentedTypedArray(3, 2); // creates a Float32Array with 6 values - * array.push(1, 2, 3); - * array.push([4, 5, 6]); - * // array now contains [1, 2, 3, 4, 5, 6] - * - * Also has `numComponents` and `numElements` properties. - * - * @param {number} numComponents number of components - * @param {number} numElements number of elements. The total size of the array will be `numComponents * numElements`. - * @param {constructor} opt_type A constructor for the type. Default = `Float32Array`. - * @return {ArrayBuffer} A typed array. - * @memberOf module:twgl/primitives - */ - function createAugmentedTypedArray(numComponents, numElements, opt_type) { - var Type = opt_type || Float32Array; - return augmentTypedArray(new Type(numComponents * numElements), numComponents); - } - - function allButIndices(name) { - return name !== "indices"; - } - - /** - * Given indexed vertices creates a new set of vertices unindexed by expanding the indexed vertices. - * @param {Object.} vertices The indexed vertices to deindex - * @return {Object.} The deindexed vertices - * @memberOf module:twgl/primitives - */ - function deindexVertices(vertices) { - var indices = vertices.indices; - var newVertices = {}; - var numElements = indices.length; - - function expandToUnindexed(channel) { - var srcBuffer = vertices[channel]; - var numComponents = srcBuffer.numComponents; - var dstBuffer = createAugmentedTypedArray(numComponents, numElements, srcBuffer.constructor); - for (var ii = 0; ii < numElements; ++ii) { - var ndx = indices[ii]; - var offset = ndx * numComponents; - for (var jj = 0; jj < numComponents; ++jj) { - dstBuffer.push(srcBuffer[offset + jj]); - } - } - newVertices[channel] = dstBuffer; - } - - Object.keys(vertices).filter(allButIndices).forEach(expandToUnindexed); - - return newVertices; - } - - /** - * flattens the normals of deindexed vertices in place. - * @param {Object.} vertices The deindexed vertices who's normals to flatten - * @return {Object.} The flattened vertices (same as was passed in) - * @memberOf module:twgl/primitives - */ - function flattenNormals(vertices) { - if (vertices.indices) { - throw "can't flatten normals of indexed vertices. deindex them first"; - } - - var normals = vertices.normal; - var numNormals = normals.length; - for (var ii = 0; ii < numNormals; ii += 9) { - // pull out the 3 normals for this triangle - var nax = normals[ii + 0]; - var nay = normals[ii + 1]; - var naz = normals[ii + 2]; - - var nbx = normals[ii + 3]; - var nby = normals[ii + 4]; - var nbz = normals[ii + 5]; - - var ncx = normals[ii + 6]; - var ncy = normals[ii + 7]; - var ncz = normals[ii + 8]; - - // add them - var nx = nax + nbx + ncx; - var ny = nay + nby + ncy; - var nz = naz + nbz + ncz; - - // normalize them - var length = Math.sqrt(nx * nx + ny * ny + nz * nz); - - nx /= length; - ny /= length; - nz /= length; - - // copy them back in - normals[ii + 0] = nx; - normals[ii + 1] = ny; - normals[ii + 2] = nz; - - normals[ii + 3] = nx; - normals[ii + 4] = ny; - normals[ii + 5] = nz; - - normals[ii + 6] = nx; - normals[ii + 7] = ny; - normals[ii + 8] = nz; - } - - return vertices; - } - - function applyFuncToV3Array(array, matrix, fn) { - var len = array.length; - var tmp = new Float32Array(3); - for (var ii = 0; ii < len; ii += 3) { - fn(matrix, [array[ii], array[ii + 1], array[ii + 2]], tmp); - array[ii ] = tmp[0]; - array[ii + 1] = tmp[1]; - array[ii + 2] = tmp[2]; - } - } - - function transformNormal(mi, v, dst) { - dst = dst || v3.create(); - var v0 = v[0]; - var v1 = v[1]; - var v2 = v[2]; - - dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2]; - dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2]; - dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2]; - - return dst; - } - - /** - * Reorients directions by the given matrix.. - * @param {number[]|TypedArray} array The array. Assumes value floats per element. - * @param {Matrix} matrix A matrix to multiply by. - * @return {number[]|TypedArray} the same array that was passed in - * @memberOf module:twgl/primitives - */ - function reorientDirections(array, matrix) { - applyFuncToV3Array(array, matrix, m4.transformDirection); - return array; - } - - /** - * Reorients normals by the inverse-transpose of the given - * matrix.. - * @param {number[]|TypedArray} array The array. Assumes value floats per element. - * @param {Matrix} matrix A matrix to multiply by. - * @return {number[]|TypedArray} the same array that was passed in - * @memberOf module:twgl/primitives - */ - function reorientNormals(array, matrix) { - applyFuncToV3Array(array, m4.inverse(matrix), transformNormal); - return array; - } - - /** - * Reorients positions by the given matrix. In other words, it - * multiplies each vertex by the given matrix. - * @param {number[]|TypedArray} array The array. Assumes value floats per element. - * @param {Matrix} matrix A matrix to multiply by. - * @return {number[]|TypedArray} the same array that was passed in - * @memberOf module:twgl/primitives - */ - function reorientPositions(array, matrix) { - applyFuncToV3Array(array, matrix, m4.transformPoint); - return array; - } - - /** - * Reorients arrays by the given matrix. Assumes arrays have - * names that contains 'pos' could be reoriented as positions, - * 'binorm' or 'tan' as directions, and 'norm' as normals. - * - * @param {Object.} arrays The vertices to reorient - * @param {Matrix} matrix matrix to reorient by. - * @return {Object.} same arrays that were passed in. - * @memberOf module:twgl/primitives - */ - function reorientVertices(arrays, matrix) { - Object.keys(arrays).forEach(function(name) { - var array = arrays[name]; - if (name.indexOf("pos") >= 0) { - reorientPositions(array, matrix); - } else if (name.indexOf("tan") >= 0 || name.indexOf("binorm") >= 0) { - reorientDirections(array, matrix); - } else if (name.indexOf("norm") >= 0) { - reorientNormals(array, matrix); - } - }); - return arrays; - } - - /** - * Creates XY quad BufferInfo - * - * The default with no parameters will return a 2x2 quad with values from -1 to +1. - * If you want a unit quad with that goes from 0 to 1 you'd call it with - * - * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); - * - * If you want a unit quad centered above 0,0 you'd call it with - * - * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 - * @param {number} [xOffset] the amount to offset the quad in X - * @param {number} [yOffset] the amount to offset the quad in Y - * @return {Object.} the created XY Quad BufferInfo - * @memberOf module:twgl/primitives - * @function createXYQuadBufferInfo - */ - - /** - * Creates XY quad Buffers - * - * The default with no parameters will return a 2x2 quad with values from -1 to +1. - * If you want a unit quad with that goes from 0 to 1 you'd call it with - * - * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); - * - * If you want a unit quad centered above 0,0 you'd call it with - * - * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 - * @param {number} [xOffset] the amount to offset the quad in X - * @param {number} [yOffset] the amount to offset the quad in Y - * @return {module:twgl.BufferInfo} the created XY Quad buffers - * @memberOf module:twgl/primitives - * @function createXYQuadBuffers - */ - - /** - * Creates XY quad vertices - * - * The default with no parameters will return a 2x2 quad with values from -1 to +1. - * If you want a unit quad with that goes from 0 to 1 you'd call it with - * - * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5); - * - * If you want a unit quad centered above 0,0 you'd call it with - * - * twgl.primitives.createXYQuadVertices(1, 0, 0.5); - * - * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 - * @param {number} [xOffset] the amount to offset the quad in X - * @param {number} [yOffset] the amount to offset the quad in Y - * @return {Object. the created XY Quad vertices - * @memberOf module:twgl/primitives - */ - function createXYQuadVertices(size, xOffset, yOffset) { - size = size || 2; - xOffset = xOffset || 0; - yOffset = yOffset || 0; - size *= 0.5; - return { - position: { - numComponents: 2, - data: [ - xOffset + -1 * size, yOffset + -1 * size, - xOffset + 1 * size, yOffset + -1 * size, - xOffset + -1 * size, yOffset + 1 * size, - xOffset + 1 * size, yOffset + 1 * size, - ], - }, - normal: [ - 0, 0, 1, - 0, 0, 1, - 0, 0, 1, - 0, 0, 1, - ], - texcoord: [ - 0, 0, - 1, 0, - 0, 1, - 1, 1, - ], - indices: [ 0, 1, 2, 2, 1, 3 ], - }; - } - - /** - * Creates XZ plane BufferInfo. - * - * The created plane has position, normal, and texcoord data - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} [width] Width of the plane. Default = 1 - * @param {number} [depth] Depth of the plane. Default = 1 - * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 - * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 - * @param {Matrix4} [matrix] A matrix by which to multiply all the vertices. - * @return {@module:twgl.BufferInfo} The created plane BufferInfo. - * @memberOf module:twgl/primitives - * @function createPlaneBufferInfo - */ - - /** - * Creates XZ plane buffers. - * - * The created plane has position, normal, and texcoord data - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} [width] Width of the plane. Default = 1 - * @param {number} [depth] Depth of the plane. Default = 1 - * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 - * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 - * @param {Matrix4} [matrix] A matrix by which to multiply all the vertices. - * @return {Object.} The created plane buffers. - * @memberOf module:twgl/primitives - * @function createPlaneBuffers - */ - - /** - * Creates XZ plane vertices. - * - * The created plane has position, normal, and texcoord data - * - * @param {number} [width] Width of the plane. Default = 1 - * @param {number} [depth] Depth of the plane. Default = 1 - * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 - * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 - * @param {Matrix4} [matrix] A matrix by which to multiply all the vertices. - * @return {Object.} The created plane vertices. - * @memberOf module:twgl/primitives - */ - function createPlaneVertices( - width, - depth, - subdivisionsWidth, - subdivisionsDepth, - matrix) { - width = width || 1; - depth = depth || 1; - subdivisionsWidth = subdivisionsWidth || 1; - subdivisionsDepth = subdivisionsDepth || 1; - matrix = matrix || m4.identity(); - - var numVertices = (subdivisionsWidth + 1) * (subdivisionsDepth + 1); - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2, numVertices); - - for (var z = 0; z <= subdivisionsDepth; z++) { - for (var x = 0; x <= subdivisionsWidth; x++) { - var u = x / subdivisionsWidth; - var v = z / subdivisionsDepth; - positions.push( - width * u - width * 0.5, - 0, - depth * v - depth * 0.5); - normals.push(0, 1, 0); - texcoords.push(u, v); - } - } - - var numVertsAcross = subdivisionsWidth + 1; - var indices = createAugmentedTypedArray( - 3, subdivisionsWidth * subdivisionsDepth * 2, Uint16Array); - - for (var z = 0; z < subdivisionsDepth; z++) { // eslint-disable-line - for (var x = 0; x < subdivisionsWidth; x++) { // eslint-disable-line - // Make triangle 1 of quad. - indices.push( - (z + 0) * numVertsAcross + x, - (z + 1) * numVertsAcross + x, - (z + 0) * numVertsAcross + x + 1); - - // Make triangle 2 of quad. - indices.push( - (z + 1) * numVertsAcross + x, - (z + 1) * numVertsAcross + x + 1, - (z + 0) * numVertsAcross + x + 1); - } - } - - var arrays = reorientVertices({ - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }, matrix); - return arrays; - } - - /** - * Creates sphere BufferInfo. - * - * The created sphere has position, normal, and texcoord data - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius radius of the sphere. - * @param {number} subdivisionsAxis number of steps around the sphere. - * @param {number} subdivisionsHeight number of vertically on the sphere. - * @param {number} [opt_startLatitudeInRadians] where to start the - * top of the sphere. Default = 0. - * @param {number} [opt_endLatitudeInRadians] Where to end the - * bottom of the sphere. Default = Math.PI. - * @param {number} [opt_startLongitudeInRadians] where to start - * wrapping the sphere. Default = 0. - * @param {number} [opt_endLongitudeInRadians] where to end - * wrapping the sphere. Default = 2 * Math.PI. - * @return {module:twgl.BufferInfo} The created sphere BufferInfo. - * @memberOf module:twgl/primitives - * @function createSphereBufferInfo - */ - - /** - * Creates sphere buffers. - * - * The created sphere has position, normal, and texcoord data - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius radius of the sphere. - * @param {number} subdivisionsAxis number of steps around the sphere. - * @param {number} subdivisionsHeight number of vertically on the sphere. - * @param {number} [opt_startLatitudeInRadians] where to start the - * top of the sphere. Default = 0. - * @param {number} [opt_endLatitudeInRadians] Where to end the - * bottom of the sphere. Default = Math.PI. - * @param {number} [opt_startLongitudeInRadians] where to start - * wrapping the sphere. Default = 0. - * @param {number} [opt_endLongitudeInRadians] where to end - * wrapping the sphere. Default = 2 * Math.PI. - * @return {Object.} The created sphere buffers. - * @memberOf module:twgl/primitives - * @function createSphereBuffers - */ - - /** - * Creates sphere vertices. - * - * The created sphere has position, normal, and texcoord data - * - * @param {number} radius radius of the sphere. - * @param {number} subdivisionsAxis number of steps around the sphere. - * @param {number} subdivisionsHeight number of vertically on the sphere. - * @param {number} [opt_startLatitudeInRadians] where to start the - * top of the sphere. Default = 0. - * @param {number} [opt_endLatitudeInRadians] Where to end the - * bottom of the sphere. Default = Math.PI. - * @param {number} [opt_startLongitudeInRadians] where to start - * wrapping the sphere. Default = 0. - * @param {number} [opt_endLongitudeInRadians] where to end - * wrapping the sphere. Default = 2 * Math.PI. - * @return {Object.} The created sphere vertices. - * @memberOf module:twgl/primitives - */ - function createSphereVertices( - radius, - subdivisionsAxis, - subdivisionsHeight, - opt_startLatitudeInRadians, - opt_endLatitudeInRadians, - opt_startLongitudeInRadians, - opt_endLongitudeInRadians) { - if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { - throw Error('subdivisionAxis and subdivisionHeight must be > 0'); - } - - opt_startLatitudeInRadians = opt_startLatitudeInRadians || 0; - opt_endLatitudeInRadians = opt_endLatitudeInRadians || Math.PI; - opt_startLongitudeInRadians = opt_startLongitudeInRadians || 0; - opt_endLongitudeInRadians = opt_endLongitudeInRadians || (Math.PI * 2); - - var latRange = opt_endLatitudeInRadians - opt_startLatitudeInRadians; - var longRange = opt_endLongitudeInRadians - opt_startLongitudeInRadians; - - // We are going to generate our sphere by iterating through its - // spherical coordinates and generating 2 triangles for each quad on a - // ring of the sphere. - var numVertices = (subdivisionsAxis + 1) * (subdivisionsHeight + 1); - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2 , numVertices); - - // Generate the individual vertices in our vertex buffer. - for (var y = 0; y <= subdivisionsHeight; y++) { - for (var x = 0; x <= subdivisionsAxis; x++) { - // Generate a vertex based on its spherical coordinates - var u = x / subdivisionsAxis; - var v = y / subdivisionsHeight; - var theta = longRange * u; - var phi = latRange * v; - var sinTheta = Math.sin(theta); - var cosTheta = Math.cos(theta); - var sinPhi = Math.sin(phi); - var cosPhi = Math.cos(phi); - var ux = cosTheta * sinPhi; - var uy = cosPhi; - var uz = sinTheta * sinPhi; - positions.push(radius * ux, radius * uy, radius * uz); - normals.push(ux, uy, uz); - texcoords.push(1 - u, v); - } - } - - var numVertsAround = subdivisionsAxis + 1; - var indices = createAugmentedTypedArray(3, subdivisionsAxis * subdivisionsHeight * 2, Uint16Array); - for (var x = 0; x < subdivisionsAxis; x++) { // eslint-disable-line - for (var y = 0; y < subdivisionsHeight; y++) { // eslint-disable-line - // Make triangle 1 of quad. - indices.push( - (y + 0) * numVertsAround + x, - (y + 0) * numVertsAround + x + 1, - (y + 1) * numVertsAround + x); - - // Make triangle 2 of quad. - indices.push( - (y + 1) * numVertsAround + x, - (y + 0) * numVertsAround + x + 1, - (y + 1) * numVertsAround + x + 1); - } - } - - return { - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }; - } - - /** - * Array of the indices of corners of each face of a cube. - * @type {Array.} - */ - var CUBE_FACE_INDICES = [ - [3, 7, 5, 1], // right - [6, 2, 0, 4], // left - [6, 7, 3, 2], // ?? - [0, 1, 5, 4], // ?? - [7, 6, 4, 5], // front - [2, 3, 1, 0], // back - ]; - - /** - * Creates a BufferInfo for a cube. - * - * The cube is created around the origin. (-size / 2, size / 2). - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} [size] width, height and depth of the cube. - * @return {module:twgl.BufferInfo} The created BufferInfo. - * @memberOf module:twgl/primitives - * @function createCubeBufferInfo - */ - - /** - * Creates the buffers and indices for a cube. - * - * The cube is created around the origin. (-size / 2, size / 2). - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} [size] width, height and depth of the cube. - * @return {Object.} The created buffers. - * @memberOf module:twgl/primitives - * @function createCubeBuffers - */ - - /** - * Creates the vertices and indices for a cube. - * - * The cube is created around the origin. (-size / 2, size / 2). - * - * @param {number} [size] width, height and depth of the cube. - * @return {Object.} The created vertices. - * @memberOf module:twgl/primitives - */ - function createCubeVertices(size) { - size = size || 1; - var k = size / 2; - - var cornerVertices = [ - [-k, -k, -k], - [+k, -k, -k], - [-k, +k, -k], - [+k, +k, -k], - [-k, -k, +k], - [+k, -k, +k], - [-k, +k, +k], - [+k, +k, +k], - ]; - - var faceNormals = [ - [+1, +0, +0], - [-1, +0, +0], - [+0, +1, +0], - [+0, -1, +0], - [+0, +0, +1], - [+0, +0, -1], - ]; - - var uvCoords = [ - [1, 0], - [0, 0], - [0, 1], - [1, 1], - ]; - - var numVertices = 6 * 4; - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2 , numVertices); - var indices = createAugmentedTypedArray(3, 6 * 2, Uint16Array); - - for (var f = 0; f < 6; ++f) { - var faceIndices = CUBE_FACE_INDICES[f]; - for (var v = 0; v < 4; ++v) { - var position = cornerVertices[faceIndices[v]]; - var normal = faceNormals[f]; - var uv = uvCoords[v]; - - // Each face needs all four vertices because the normals and texture - // coordinates are not all the same. - positions.push(position); - normals.push(normal); - texcoords.push(uv); - - } - // Two triangles make a square face. - var offset = 4 * f; - indices.push(offset + 0, offset + 1, offset + 2); - indices.push(offset + 0, offset + 2, offset + 3); - } - - return { - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }; - } - - /** - * Creates a BufferInfo for a truncated cone, which is like a cylinder - * except that it has different top and bottom radii. A truncated cone - * can also be used to create cylinders and regular cones. The - * truncated cone will be created centered about the origin, with the - * y axis as its vertical axis. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} bottomRadius Bottom radius of truncated cone. - * @param {number} topRadius Top radius of truncated cone. - * @param {number} height Height of truncated cone. - * @param {number} radialSubdivisions The number of subdivisions around the - * truncated cone. - * @param {number} verticalSubdivisions The number of subdivisions down the - * truncated cone. - * @param {boolean} [opt_topCap] Create top cap. Default = true. - * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. - * @return {module:twgl.BufferInfo} The created cone BufferInfo. - * @memberOf module:twgl/primitives - * @function createTruncatedConeBufferInfo - */ - - /** - * Creates buffers for a truncated cone, which is like a cylinder - * except that it has different top and bottom radii. A truncated cone - * can also be used to create cylinders and regular cones. The - * truncated cone will be created centered about the origin, with the - * y axis as its vertical axis. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} bottomRadius Bottom radius of truncated cone. - * @param {number} topRadius Top radius of truncated cone. - * @param {number} height Height of truncated cone. - * @param {number} radialSubdivisions The number of subdivisions around the - * truncated cone. - * @param {number} verticalSubdivisions The number of subdivisions down the - * truncated cone. - * @param {boolean} [opt_topCap] Create top cap. Default = true. - * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. - * @return {Object.} The created cone buffers. - * @memberOf module:twgl/primitives - * @function createTruncatedConeBuffers - */ - - /** - * Creates vertices for a truncated cone, which is like a cylinder - * except that it has different top and bottom radii. A truncated cone - * can also be used to create cylinders and regular cones. The - * truncated cone will be created centered about the origin, with the - * y axis as its vertical axis. . - * - * @param {number} bottomRadius Bottom radius of truncated cone. - * @param {number} topRadius Top radius of truncated cone. - * @param {number} height Height of truncated cone. - * @param {number} radialSubdivisions The number of subdivisions around the - * truncated cone. - * @param {number} verticalSubdivisions The number of subdivisions down the - * truncated cone. - * @param {boolean} [opt_topCap] Create top cap. Default = true. - * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. - * @return {Object.} The created cone vertices. - * @memberOf module:twgl/primitives - */ - function createTruncatedConeVertices( - bottomRadius, - topRadius, - height, - radialSubdivisions, - verticalSubdivisions, - opt_topCap, - opt_bottomCap) { - if (radialSubdivisions < 3) { - throw Error('radialSubdivisions must be 3 or greater'); - } - - if (verticalSubdivisions < 1) { - throw Error('verticalSubdivisions must be 1 or greater'); - } - - var topCap = (opt_topCap === undefined) ? true : opt_topCap; - var bottomCap = (opt_bottomCap === undefined) ? true : opt_bottomCap; - - var extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0); - - var numVertices = (radialSubdivisions + 1) * (verticalSubdivisions + 1 + extra); - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2, numVertices); - var indices = createAugmentedTypedArray(3, radialSubdivisions * (verticalSubdivisions + extra) * 2, Uint16Array); - - var vertsAroundEdge = radialSubdivisions + 1; - - // The slant of the cone is constant across its surface - var slant = Math.atan2(bottomRadius - topRadius, height); - var cosSlant = Math.cos(slant); - var sinSlant = Math.sin(slant); - - var start = topCap ? -2 : 0; - var end = verticalSubdivisions + (bottomCap ? 2 : 0); - - for (var yy = start; yy <= end; ++yy) { - var v = yy / verticalSubdivisions; - var y = height * v; - var ringRadius; - if (yy < 0) { - y = 0; - v = 1; - ringRadius = bottomRadius; - } else if (yy > verticalSubdivisions) { - y = height; - v = 1; - ringRadius = topRadius; - } else { - ringRadius = bottomRadius + - (topRadius - bottomRadius) * (yy / verticalSubdivisions); - } - if (yy === -2 || yy === verticalSubdivisions + 2) { - ringRadius = 0; - v = 0; - } - y -= height / 2; - for (var ii = 0; ii < vertsAroundEdge; ++ii) { - var sin = Math.sin(ii * Math.PI * 2 / radialSubdivisions); - var cos = Math.cos(ii * Math.PI * 2 / radialSubdivisions); - positions.push(sin * ringRadius, y, cos * ringRadius); - normals.push( - (yy < 0 || yy > verticalSubdivisions) ? 0 : (sin * cosSlant), - (yy < 0) ? -1 : (yy > verticalSubdivisions ? 1 : sinSlant), - (yy < 0 || yy > verticalSubdivisions) ? 0 : (cos * cosSlant)); - texcoords.push((ii / radialSubdivisions), 1 - v); - } - } - - for (var yy = 0; yy < verticalSubdivisions + extra; ++yy) { // eslint-disable-line - for (var ii = 0; ii < radialSubdivisions; ++ii) { // eslint-disable-line - indices.push(vertsAroundEdge * (yy + 0) + 0 + ii, - vertsAroundEdge * (yy + 0) + 1 + ii, - vertsAroundEdge * (yy + 1) + 1 + ii); - indices.push(vertsAroundEdge * (yy + 0) + 0 + ii, - vertsAroundEdge * (yy + 1) + 1 + ii, - vertsAroundEdge * (yy + 1) + 0 + ii); - } - } - - return { - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }; - } - - /** - * Expands RLE data - * @param {number[]} rleData data in format of run-length, x, y, z, run-length, x, y, z - * @param {number[]} [padding] value to add each entry with. - * @return {number[]} the expanded rleData - */ - function expandRLEData(rleData, padding) { - padding = padding || []; - var data = []; - for (var ii = 0; ii < rleData.length; ii += 4) { - var runLength = rleData[ii]; - var element = rleData.slice(ii + 1, ii + 4); - element.push.apply(element, padding); - for (var jj = 0; jj < runLength; ++jj) { - data.push.apply(data, element); - } - } - return data; - } - - /** - * Creates 3D 'F' BufferInfo. - * An 'F' is useful because you can easily tell which way it is oriented. - * The created 'F' has position, normal, texcoord, and color buffers. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @return {module:twgl.BufferInfo} The created BufferInfo. - * @memberOf module:twgl/primitives - * @function create3DFBufferInfo - */ - - /** - * Creates 3D 'F' buffers. - * An 'F' is useful because you can easily tell which way it is oriented. - * The created 'F' has position, normal, texcoord, and color buffers. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @return {Object.} The created buffers. - * @memberOf module:twgl/primitives - * @function create3DFBuffers - */ - - /** - * Creates 3D 'F' vertices. - * An 'F' is useful because you can easily tell which way it is oriented. - * The created 'F' has position, normal, texcoord, and color arrays. - * - * @return {Object.} The created vertices. - * @memberOf module:twgl/primitives - */ - function create3DFVertices() { - - var positions = [ - // left column front - 0, 0, 0, - 0, 150, 0, - 30, 0, 0, - 0, 150, 0, - 30, 150, 0, - 30, 0, 0, - - // top rung front - 30, 0, 0, - 30, 30, 0, - 100, 0, 0, - 30, 30, 0, - 100, 30, 0, - 100, 0, 0, - - // middle rung front - 30, 60, 0, - 30, 90, 0, - 67, 60, 0, - 30, 90, 0, - 67, 90, 0, - 67, 60, 0, - - // left column back - 0, 0, 30, - 30, 0, 30, - 0, 150, 30, - 0, 150, 30, - 30, 0, 30, - 30, 150, 30, - - // top rung back - 30, 0, 30, - 100, 0, 30, - 30, 30, 30, - 30, 30, 30, - 100, 0, 30, - 100, 30, 30, - - // middle rung back - 30, 60, 30, - 67, 60, 30, - 30, 90, 30, - 30, 90, 30, - 67, 60, 30, - 67, 90, 30, - - // top - 0, 0, 0, - 100, 0, 0, - 100, 0, 30, - 0, 0, 0, - 100, 0, 30, - 0, 0, 30, - - // top rung front - 100, 0, 0, - 100, 30, 0, - 100, 30, 30, - 100, 0, 0, - 100, 30, 30, - 100, 0, 30, - - // under top rung - 30, 30, 0, - 30, 30, 30, - 100, 30, 30, - 30, 30, 0, - 100, 30, 30, - 100, 30, 0, - - // between top rung and middle - 30, 30, 0, - 30, 60, 30, - 30, 30, 30, - 30, 30, 0, - 30, 60, 0, - 30, 60, 30, - - // top of middle rung - 30, 60, 0, - 67, 60, 30, - 30, 60, 30, - 30, 60, 0, - 67, 60, 0, - 67, 60, 30, - - // front of middle rung - 67, 60, 0, - 67, 90, 30, - 67, 60, 30, - 67, 60, 0, - 67, 90, 0, - 67, 90, 30, - - // bottom of middle rung. - 30, 90, 0, - 30, 90, 30, - 67, 90, 30, - 30, 90, 0, - 67, 90, 30, - 67, 90, 0, - - // front of bottom - 30, 90, 0, - 30, 150, 30, - 30, 90, 30, - 30, 90, 0, - 30, 150, 0, - 30, 150, 30, - - // bottom - 0, 150, 0, - 0, 150, 30, - 30, 150, 30, - 0, 150, 0, - 30, 150, 30, - 30, 150, 0, - - // left side - 0, 0, 0, - 0, 0, 30, - 0, 150, 30, - 0, 0, 0, - 0, 150, 30, - 0, 150, 0, - ]; - - var texcoords = [ - // left column front - 0.22, 0.19, - 0.22, 0.79, - 0.34, 0.19, - 0.22, 0.79, - 0.34, 0.79, - 0.34, 0.19, - - // top rung front - 0.34, 0.19, - 0.34, 0.31, - 0.62, 0.19, - 0.34, 0.31, - 0.62, 0.31, - 0.62, 0.19, - - // middle rung front - 0.34, 0.43, - 0.34, 0.55, - 0.49, 0.43, - 0.34, 0.55, - 0.49, 0.55, - 0.49, 0.43, - - // left column back - 0, 0, - 1, 0, - 0, 1, - 0, 1, - 1, 0, - 1, 1, - - // top rung back - 0, 0, - 1, 0, - 0, 1, - 0, 1, - 1, 0, - 1, 1, - - // middle rung back - 0, 0, - 1, 0, - 0, 1, - 0, 1, - 1, 0, - 1, 1, - - // top - 0, 0, - 1, 0, - 1, 1, - 0, 0, - 1, 1, - 0, 1, - - // top rung front - 0, 0, - 1, 0, - 1, 1, - 0, 0, - 1, 1, - 0, 1, - - // under top rung - 0, 0, - 0, 1, - 1, 1, - 0, 0, - 1, 1, - 1, 0, - - // between top rung and middle - 0, 0, - 1, 1, - 0, 1, - 0, 0, - 1, 0, - 1, 1, - - // top of middle rung - 0, 0, - 1, 1, - 0, 1, - 0, 0, - 1, 0, - 1, 1, - - // front of middle rung - 0, 0, - 1, 1, - 0, 1, - 0, 0, - 1, 0, - 1, 1, - - // bottom of middle rung. - 0, 0, - 0, 1, - 1, 1, - 0, 0, - 1, 1, - 1, 0, - - // front of bottom - 0, 0, - 1, 1, - 0, 1, - 0, 0, - 1, 0, - 1, 1, - - // bottom - 0, 0, - 0, 1, - 1, 1, - 0, 0, - 1, 1, - 1, 0, - - // left side - 0, 0, - 0, 1, - 1, 1, - 0, 0, - 1, 1, - 1, 0, - ]; - - var normals = expandRLEData([ - // left column front - // top rung front - // middle rung front - 18, 0, 0, 1, - - // left column back - // top rung back - // middle rung back - 18, 0, 0, -1, - - // top - 6, 0, 1, 0, - - // top rung front - 6, 1, 0, 0, - - // under top rung - 6, 0, -1, 0, - - // between top rung and middle - 6, 1, 0, 0, - - // top of middle rung - 6, 0, 1, 0, - - // front of middle rung - 6, 1, 0, 0, - - // bottom of middle rung. - 6, 0, -1, 0, - - // front of bottom - 6, 1, 0, 0, - - // bottom - 6, 0, -1, 0, - - // left side - 6, -1, 0, 0, - ]); - - var colors = expandRLEData([ - // left column front - // top rung front - // middle rung front - 18, 200, 70, 120, - - // left column back - // top rung back - // middle rung back - 18, 80, 70, 200, - - // top - 6, 70, 200, 210, - - // top rung front - 6, 200, 200, 70, - - // under top rung - 6, 210, 100, 70, - - // between top rung and middle - 6, 210, 160, 70, - - // top of middle rung - 6, 70, 180, 210, - - // front of middle rung - 6, 100, 70, 210, - - // bottom of middle rung. - 6, 76, 210, 100, - - // front of bottom - 6, 140, 210, 80, - - // bottom - 6, 90, 130, 110, - - // left side - 6, 160, 160, 220, - ], [255]); - - var numVerts = positions.length / 3; - - var arrays = { - position: createAugmentedTypedArray(3, numVerts), - texcoord: createAugmentedTypedArray(2, numVerts), - normal: createAugmentedTypedArray(3, numVerts), - color: createAugmentedTypedArray(4, numVerts, Uint8Array), - indices: createAugmentedTypedArray(3, numVerts / 3, Uint16Array), - }; - - arrays.position.push(positions); - arrays.texcoord.push(texcoords); - arrays.normal.push(normals); - arrays.color.push(colors); - - for (var ii = 0; ii < numVerts; ++ii) { - arrays.indices.push(ii); - } - - return arrays; - } - - /** - * Creates cresent BufferInfo. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} verticalRadius The vertical radius of the cresent. - * @param {number} outerRadius The outer radius of the cresent. - * @param {number} innerRadius The inner radius of the cresent. - * @param {number} thickness The thickness of the cresent. - * @param {number} subdivisionsDown number of steps around the cresent. - * @param {number} subdivisionsThick number of vertically on the cresent. - * @param {number} [startOffset] Where to start arc. Default 0. - * @param {number} [endOffset] Where to end arg. Default 1. - * @return {module:twgl.BufferInfo} The created BufferInfo. - * @memberOf module:twgl/primitives - * @function createCresentBufferInfo - */ - - /** - * Creates cresent buffers. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} verticalRadius The vertical radius of the cresent. - * @param {number} outerRadius The outer radius of the cresent. - * @param {number} innerRadius The inner radius of the cresent. - * @param {number} thickness The thickness of the cresent. - * @param {number} subdivisionsDown number of steps around the cresent. - * @param {number} subdivisionsThick number of vertically on the cresent. - * @param {number} [startOffset] Where to start arc. Default 0. - * @param {number} [endOffset] Where to end arg. Default 1. - * @return {Object.} The created buffers. - * @memberOf module:twgl/primitives - * @function createCresentBuffers - */ - - /** - * Creates cresent vertices. - * - * @param {number} verticalRadius The vertical radius of the cresent. - * @param {number} outerRadius The outer radius of the cresent. - * @param {number} innerRadius The inner radius of the cresent. - * @param {number} thickness The thickness of the cresent. - * @param {number} subdivisionsDown number of steps around the cresent. - * @param {number} subdivisionsThick number of vertically on the cresent. - * @param {number} [startOffset] Where to start arc. Default 0. - * @param {number} [endOffset] Where to end arg. Default 1. - * @return {Object.} The created vertices. - * @memberOf module:twgl/primitives - */ - function createCresentVertices( - verticalRadius, - outerRadius, - innerRadius, - thickness, - subdivisionsDown, - startOffset, - endOffset) { - if (subdivisionsDown <= 0) { - throw Error('subdivisionDown must be > 0'); - } - - startOffset = startOffset || 0; - endOffset = endOffset || 1; - - var subdivisionsThick = 2; - - var offsetRange = endOffset - startOffset; - var numVertices = (subdivisionsDown + 1) * 2 * (2 + subdivisionsThick); - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2, numVertices); - - function lerp(a, b, s) { - return a + (b - a) * s; - } - - function createArc(arcRadius, x, normalMult, normalAdd, uMult, uAdd) { - for (var z = 0; z <= subdivisionsDown; z++) { - var uBack = x / (subdivisionsThick - 1); - var v = z / subdivisionsDown; - var xBack = (uBack - 0.5) * 2; - var angle = (startOffset + (v * offsetRange)) * Math.PI; - var s = Math.sin(angle); - var c = Math.cos(angle); - var radius = lerp(verticalRadius, arcRadius, s); - var px = xBack * thickness; - var py = c * verticalRadius; - var pz = s * radius; - positions.push(px, py, pz); - var n = v3.add(v3.multiply([0, s, c], normalMult), normalAdd); - normals.push(n); - texcoords.push(uBack * uMult + uAdd, v); - } - } - - // Generate the individual vertices in our vertex buffer. - for (var x = 0; x < subdivisionsThick; x++) { - var uBack = (x / (subdivisionsThick - 1) - 0.5) * 2; - createArc(outerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0); - createArc(outerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 0); - createArc(innerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0); - createArc(innerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 1); - } - - // Do outer surface. - var indices = createAugmentedTypedArray(3, (subdivisionsDown * 2) * (2 + subdivisionsThick), Uint16Array); - - function createSurface(leftArcOffset, rightArcOffset) { - for (var z = 0; z < subdivisionsDown; ++z) { - // Make triangle 1 of quad. - indices.push( - leftArcOffset + z + 0, - leftArcOffset + z + 1, - rightArcOffset + z + 0); - - // Make triangle 2 of quad. - indices.push( - leftArcOffset + z + 1, - rightArcOffset + z + 1, - rightArcOffset + z + 0); - } - } - - var numVerticesDown = subdivisionsDown + 1; - // front - createSurface(numVerticesDown * 0, numVerticesDown * 4); - // right - createSurface(numVerticesDown * 5, numVerticesDown * 7); - // back - createSurface(numVerticesDown * 6, numVerticesDown * 2); - // left - createSurface(numVerticesDown * 3, numVerticesDown * 1); - - return { - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }; - } - - /** - * Creates cylinder BufferInfo. The cylinder will be created around the origin - * along the y-axis. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius Radius of cylinder. - * @param {number} height Height of cylinder. - * @param {number} radialSubdivisions The number of subdivisions around the cylinder. - * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. - * @param {boolean} [topCap] Create top cap. Default = true. - * @param {boolean} [bottomCap] Create bottom cap. Default = true. - * @return {module:twgl.BufferInfo} The created BufferInfo. - * @memberOf module:twgl/primitives - * @function createCylinderBufferInfo - */ - - /** - * Creates cylinder buffers. The cylinder will be created around the origin - * along the y-axis. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius Radius of cylinder. - * @param {number} height Height of cylinder. - * @param {number} radialSubdivisions The number of subdivisions around the cylinder. - * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. - * @param {boolean} [topCap] Create top cap. Default = true. - * @param {boolean} [bottomCap] Create bottom cap. Default = true. - * @return {Object.} The created buffers. - * @memberOf module:twgl/primitives - * @function createCylinderBuffers - */ - - /** - * Creates cylinder vertices. The cylinder will be created around the origin - * along the y-axis. - * - * @param {number} radius Radius of cylinder. - * @param {number} height Height of cylinder. - * @param {number} radialSubdivisions The number of subdivisions around the cylinder. - * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. - * @param {boolean} [topCap] Create top cap. Default = true. - * @param {boolean} [bottomCap] Create bottom cap. Default = true. - * @return {Object.} The created vertices. - * @memberOf module:twgl/primitives - */ - function createCylinderVertices( - radius, - height, - radialSubdivisions, - verticalSubdivisions, - topCap, - bottomCap) { - return createTruncatedConeVertices( - radius, - radius, - height, - radialSubdivisions, - verticalSubdivisions, - topCap, - bottomCap); - } - - /** - * Creates BufferInfo for a torus - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius radius of center of torus circle. - * @param {number} thickness radius of torus ring. - * @param {number} radialSubdivisions The number of subdivisions around the torus. - * @param {number} bodySubdivisions The number of subdivisions around the body torus. - * @param {boolean} [startAngle] start angle in radians. Default = 0. - * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. - * @return {module:twgl.BufferInfo} The created BufferInfo. - * @memberOf module:twgl/primitives - * @function createTorusBufferInfo - */ - - /** - * Creates buffers for a torus - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius radius of center of torus circle. - * @param {number} thickness radius of torus ring. - * @param {number} radialSubdivisions The number of subdivisions around the torus. - * @param {number} bodySubdivisions The number of subdivisions around the body torus. - * @param {boolean} [startAngle] start angle in radians. Default = 0. - * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. - * @return {Object.} The created buffers. - * @memberOf module:twgl/primitives - * @function createTorusBuffers - */ - - /** - * Creates vertices for a torus - * - * @param {number} radius radius of center of torus circle. - * @param {number} thickness radius of torus ring. - * @param {number} radialSubdivisions The number of subdivisions around the torus. - * @param {number} bodySubdivisions The number of subdivisions around the body torus. - * @param {boolean} [startAngle] start angle in radians. Default = 0. - * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. - * @return {Object.} The created vertices. - * @memberOf module:twgl/primitives - */ - function createTorusVertices( - radius, - thickness, - radialSubdivisions, - bodySubdivisions, - startAngle, - endAngle) { - if (radialSubdivisions < 3) { - throw Error('radialSubdivisions must be 3 or greater'); - } - - if (bodySubdivisions < 3) { - throw Error('verticalSubdivisions must be 3 or greater'); - } - - startAngle = startAngle || 0; - endAngle = endAngle || Math.PI * 2; - range = endAngle - startAngle; - - var radialParts = radialSubdivisions + 1; - var bodyParts = bodySubdivisions + 1; - var numVertices = radialParts * bodyParts; - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2, numVertices); - var indices = createAugmentedTypedArray(3, (radialSubdivisions) * (bodySubdivisions) * 2, Uint16Array); - - for (var slice = 0; slice < bodyParts; ++slice) { - var v = slice / bodySubdivisions; - var sliceAngle = v * Math.PI * 2; - var sliceSin = Math.sin(sliceAngle); - var ringRadius = radius + sliceSin * thickness; - var ny = Math.cos(sliceAngle); - var y = ny * thickness; - for (var ring = 0; ring < radialParts; ++ring) { - var u = ring / radialSubdivisions; - var ringAngle = startAngle + u * range; - var xSin = Math.sin(ringAngle); - var zCos = Math.cos(ringAngle); - var x = xSin * ringRadius; - var z = zCos * ringRadius; - var nx = xSin * sliceSin; - var nz = zCos * sliceSin; - positions.push(x, y, z); - normals.push(nx, ny, nz); - texcoords.push(u, 1 - v); - } - } - - for (var slice = 0; slice < bodySubdivisions; ++slice) { // eslint-disable-line - for (var ring = 0; ring < radialSubdivisions; ++ring) { // eslint-disable-line - var nextRingIndex = 1 + ring; - var nextSliceIndex = 1 + slice; - indices.push(radialParts * slice + ring, - radialParts * nextSliceIndex + ring, - radialParts * slice + nextRingIndex); - indices.push(radialParts * nextSliceIndex + ring, - radialParts * nextSliceIndex + nextRingIndex, - radialParts * slice + nextRingIndex); - } - } - - return { - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }; - } - - - /** - * Creates a disc BufferInfo. The disc will be in the xz plane, centered at - * the origin. When creating, at least 3 divisions, or pie - * pieces, need to be specified, otherwise the triangles making - * up the disc will be degenerate. You can also specify the - * number of radial pieces `stacks`. A value of 1 for - * stacks will give you a simple disc of pie pieces. If you - * want to create an annulus you can set `innerRadius` to a - * value > 0. Finally, `stackPower` allows you to have the widths - * increase or decrease as you move away from the center. This - * is particularly useful when using the disc as a ground plane - * with a fixed camera such that you don't need the resolution - * of small triangles near the perimeter. For example, a value - * of 2 will produce stacks whose ouside radius increases with - * the square of the stack index. A value of 1 will give uniform - * stacks. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius Radius of the ground plane. - * @param {number} divisions Number of triangles in the ground plane (at least 3). - * @param {number} [stacks] Number of radial divisions (default=1). - * @param {number} [innerRadius] Default 0. - * @param {number} [stackPower] Power to raise stack size to for decreasing width. - * @return {module:twgl.BufferInfo} The created BufferInfo. - * @memberOf module:twgl/primitives - * @function createDiscBufferInfo - */ - - /** - * Creates disc buffers. The disc will be in the xz plane, centered at - * the origin. When creating, at least 3 divisions, or pie - * pieces, need to be specified, otherwise the triangles making - * up the disc will be degenerate. You can also specify the - * number of radial pieces `stacks`. A value of 1 for - * stacks will give you a simple disc of pie pieces. If you - * want to create an annulus you can set `innerRadius` to a - * value > 0. Finally, `stackPower` allows you to have the widths - * increase or decrease as you move away from the center. This - * is particularly useful when using the disc as a ground plane - * with a fixed camera such that you don't need the resolution - * of small triangles near the perimeter. For example, a value - * of 2 will produce stacks whose ouside radius increases with - * the square of the stack index. A value of 1 will give uniform - * stacks. - * - * @param {WebGLRenderingContext} gl The WebGLRenderingContext. - * @param {number} radius Radius of the ground plane. - * @param {number} divisions Number of triangles in the ground plane (at least 3). - * @param {number} [stacks] Number of radial divisions (default=1). - * @param {number} [innerRadius] Default 0. - * @param {number} [stackPower] Power to raise stack size to for decreasing width. - * @return {Object.} The created buffers. - * @memberOf module:twgl/primitives - * @function createDiscBuffers - */ - - /** - * Creates disc vertices. The disc will be in the xz plane, centered at - * the origin. When creating, at least 3 divisions, or pie - * pieces, need to be specified, otherwise the triangles making - * up the disc will be degenerate. You can also specify the - * number of radial pieces `stacks`. A value of 1 for - * stacks will give you a simple disc of pie pieces. If you - * want to create an annulus you can set `innerRadius` to a - * value > 0. Finally, `stackPower` allows you to have the widths - * increase or decrease as you move away from the center. This - * is particularly useful when using the disc as a ground plane - * with a fixed camera such that you don't need the resolution - * of small triangles near the perimeter. For example, a value - * of 2 will produce stacks whose ouside radius increases with - * the square of the stack index. A value of 1 will give uniform - * stacks. - * - * @param {number} radius Radius of the ground plane. - * @param {number} divisions Number of triangles in the ground plane (at least 3). - * @param {number} [stacks] Number of radial divisions (default=1). - * @param {number} [innerRadius] Default 0. - * @param {number} [stackPower] Power to raise stack size to for decreasing width. - * @return {Object.} The created vertices. - * @memberOf module:twgl/primitives - */ - function createDiscVertices( - radius, - divisions, - stacks, - innerRadius, - stackPower) { - if (divisions < 3) { - throw Error('divisions must be at least 3'); - } - - stacks = stacks ? stacks : 1; - stackPower = stackPower ? stackPower : 1; - innerRadius = innerRadius ? innerRadius : 0; - - // Note: We don't share the center vertex because that would - // mess up texture coordinates. - var numVertices = (divisions + 1) * (stacks + 1); - - var positions = createAugmentedTypedArray(3, numVertices); - var normals = createAugmentedTypedArray(3, numVertices); - var texcoords = createAugmentedTypedArray(2, numVertices); - var indices = createAugmentedTypedArray(3, stacks * divisions * 2, Uint16Array); - - var firstIndex = 0; - var radiusSpan = radius - innerRadius; - var pointsPerStack = divisions + 1; - - // Build the disk one stack at a time. - for (var stack = 0; stack <= stacks; ++stack) { - var stackRadius = innerRadius + radiusSpan * Math.pow(stack / stacks, stackPower); - - for (var i = 0; i <= divisions; ++i) { - var theta = 2.0 * Math.PI * i / divisions; - var x = stackRadius * Math.cos(theta); - var z = stackRadius * Math.sin(theta); - - positions.push(x, 0, z); - normals.push(0, 1, 0); - texcoords.push(1 - (i / divisions), stack / stacks); - if (stack > 0 && i !== divisions) { - // a, b, c and d are the indices of the vertices of a quad. unless - // the current stack is the one closest to the center, in which case - // the vertices a and b connect to the center vertex. - var a = firstIndex + (i + 1); - var b = firstIndex + i; - var c = firstIndex + i - pointsPerStack; - var d = firstIndex + (i + 1) - pointsPerStack; - - // Make a quad of the vertices a, b, c, d. - indices.push(a, b, c); - indices.push(a, c, d); - } - } - - firstIndex += divisions + 1; - } - - return { - position: positions, - normal: normals, - texcoord: texcoords, - indices: indices, - }; - } - - /** - * creates a random integer between 0 and range - 1 inclusive. - * @param {number} range - * @return {number} random value between 0 and range - 1 inclusive. - */ - function randInt(range) { - return Math.random() * range | 0; - } - - /** - * Used to supply random colors - * @callback RandomColorFunc - * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed - * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha - * @return {number} a number from 0 to 255 - * @memberOf module:twgl/primitives - */ - - /** - * @typedef {Object} RandomVerticesOptions - * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices - * @property {module:twgl/primitives.RandomColorFunc} [rand] A function to generate random numbers - * @memberOf module:twgl/primitives - */ - - /** - * Creates an augmentedTypedArray of random vertex colors. - * If the vertices are indexed (have an indices array) then will - * just make random colors. Otherwise assumes they are triangles - * and makes one random color for every 3 vertices. - * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions. - * @param {module:twgl/primitives.RandomVerticesOptions} [options] options. - * @return {Object.} same vertices as passed in with `color` added. - * @memberOf module:twgl/primitives - */ - function makeRandomVertexColors(vertices, options) { - options = options || {}; - var numElements = vertices.position.numElements; - var vcolors = createAugmentedTypedArray(4, numElements, Uint8Array); - var rand = options.rand || function(ndx, channel) { - return channel < 3 ? randInt(256) : 255; - }; - vertices.color = vcolors; - if (vertices.indices) { - // just make random colors if index - for (var ii = 0; ii < numElements; ++ii) { - vcolors.push(rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3)); - } - } else { - // make random colors per triangle - var numVertsPerColor = options.vertsPerColor || 3; - var numSets = numElements / numVertsPerColor; - for (var ii = 0; ii < numSets; ++ii) { // eslint-disable-line - var color = [rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3)]; - for (var jj = 0; jj < numVertsPerColor; ++jj) { - vcolors.push(color); - } - } - } - return vertices; - } - - /** - * creates a function that calls fn to create vertices and then - * creates a buffers for them - */ - function createBufferFunc(fn) { - return function(gl) { - var arrays = fn.apply(this, Array.prototype.slice.call(arguments, 1)); - return twgl.createBuffersFromArrays(gl, arrays); - }; - } - - /** - * creates a function that calls fn to create vertices and then - * creates a bufferInfo object for them - */ - function createBufferInfoFunc(fn) { - return function(gl) { - var arrays = fn.apply(null, Array.prototype.slice.call(arguments, 1)); - return twgl.createBufferInfoFromArrays(gl, arrays); - }; - } - - var arraySpecPropertyNames = [ - "numComponents", - "size", - "type", - "normalize", - "stride", - "offset", - "attrib", - "name", - "attribName", - ]; - - /** - * Copy elements from one array to another - * - * @param {Array|TypedArray} src source array - * @param {Array|TypedArray} dst dest array - * @param {number} dstNdx index in dest to copy src - * @param {number} [offset] offset to add to copied values - */ - function copyElements(src, dst, dstNdx, offset) { - offset = offset || 0; - var length = src.length; - for (var ii = 0; ii < length; ++ii) { - dst[dstNdx + ii] = src[ii] + offset; - } - } - - /** - * Creates an array of the same time - * - * @param {(number[]|ArrayBuffer|module:twgl.FullArraySpec)} srcArray array who's type to copy - * @param {number} length size of new array - * @return {(number[]|ArrayBuffer|module:twgl.FullArraySpec)} array with same type as srcArray - */ - function createArrayOfSameType(srcArray, length) { - var arraySrc = getArray(srcArray); - var newArray = new arraySrc.constructor(length); - var newArraySpec = newArray; - // If it appears to have been augmented make new one augemented - if (arraySrc.numComponents && arraySrc.numElements) { - augmentTypedArray(newArray, arraySrc.numComponents); - } - // If it was a fullspec make new one a fullspec - if (srcArray.data) { - newArraySpec = { - data: newArray, - }; - utils.copyNamedProperties(arraySpecPropertyNames, srcArray, newArraySpec); - } - return newArraySpec; - } - - /** - * Concatinates sets of vertices - * - * Assumes the vertices match in composition. For example - * if one set of vertices has positions, normals, and indices - * all sets of vertices must have positions, normals, and indices - * and of the same type. - * - * Example: - * - * var cubeVertices = twgl.primtiives.createCubeVertices(2); - * var sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10); - * // move the sphere 2 units up - * twgl.primitives.reorientVertices( - * sphereVertices, twgl.m4.translation([0, 2, 0])); - * // merge the sphere with the cube - * var cubeSphereVertices = twgl.primitives.concatVertices( - * [cubeVertices, sphereVertices]); - * // turn them into WebGL buffers and attrib data - * var bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices); - * - * @param {module:twgl.Arrays[]} arrays Array of arrays of vertices - * @return {module:twgl.Arrays} The concatinated vertices. - * @memberOf module:twgl/primitives - */ - function concatVertices(arrayOfArrays) { - var names = {}; - var baseName; - // get names of all arrays. - // and numElements for each set of vertices - for (var ii = 0; ii < arrayOfArrays.length; ++ii) { - var arrays = arrayOfArrays[ii]; - Object.keys(arrays).forEach(function(name) { // eslint-disable-line - if (!names[name]) { - names[name] = []; - } - if (!baseName && name !== 'indices') { - baseName = name; - } - var arrayInfo = arrays[name]; - var numComponents = getNumComponents(arrayInfo, name); - var array = getArray(arrayInfo); - var numElements = array.length / numComponents; - names[name].push(numElements); - }); - } - - // compute length of combined array - // and return one for reference - function getLengthOfCombinedArrays(name) { - var length = 0; - var arraySpec; - for (var ii = 0; ii < arrayOfArrays.length; ++ii) { - var arrays = arrayOfArrays[ii]; - var arrayInfo = arrays[name]; - var array = getArray(arrayInfo); - length += array.length; - if (!arraySpec || arrayInfo.data) { - arraySpec = arrayInfo; - } - } - return { - length: length, - spec: arraySpec, - }; - } - - function copyArraysToNewArray(name, base, newArray) { - var baseIndex = 0; - var offset = 0; - for (var ii = 0; ii < arrayOfArrays.length; ++ii) { - var arrays = arrayOfArrays[ii]; - var arrayInfo = arrays[name]; - var array = getArray(arrayInfo); - if (name === 'indices') { - copyElements(array, newArray, offset, baseIndex); - baseIndex += base[ii]; - } else { - copyElements(array, newArray, offset); - } - offset += array.length; - } - } - - var base = names[baseName]; - - var newArrays = {}; - Object.keys(names).forEach(function(name) { - var info = getLengthOfCombinedArrays(name); - var newArraySpec = createArrayOfSameType(info.spec, info.length); - copyArraysToNewArray(name, base, getArray(newArraySpec)); - newArrays[name] = newArraySpec; - }); - return newArrays; - } - - /** - * Creates a duplicate set of vertices - * - * This is useful for calling reorientVertices when you - * also want to keep the original available - * - * @param {module:twgl.Arrays} arrays of vertices - * @return {module:twgl.Arrays} The dupilicated vertices. - * @memberOf module:twgl/primitives - */ - function duplicateVertices(arrays) { - var newArrays = {}; - Object.keys(arrays).forEach(function(name) { - var arraySpec = arrays[name]; - var srcArray = getArray(arraySpec); - var newArraySpec = createArrayOfSameType(arraySpec, srcArray.length); - copyElements(srcArray, getArray(newArraySpec), 0); - newArrays[name] = newArraySpec; - }); - return newArrays; - } - - // Using quotes prevents Uglify from changing the names. - // No speed diff AFAICT. - return { - "create3DFBufferInfo": createBufferInfoFunc(create3DFVertices), - "create3DFBuffers": createBufferFunc(create3DFVertices), - "create3DFVertices": create3DFVertices, - "createAugmentedTypedArray": createAugmentedTypedArray, - "createCubeBufferInfo": createBufferInfoFunc(createCubeVertices), - "createCubeBuffers": createBufferFunc(createCubeVertices), - "createCubeVertices": createCubeVertices, - "createPlaneBufferInfo": createBufferInfoFunc(createPlaneVertices), - "createPlaneBuffers": createBufferFunc(createPlaneVertices), - "createPlaneVertices": createPlaneVertices, - "createSphereBufferInfo": createBufferInfoFunc(createSphereVertices), - "createSphereBuffers": createBufferFunc(createSphereVertices), - "createSphereVertices": createSphereVertices, - "createTruncatedConeBufferInfo": createBufferInfoFunc(createTruncatedConeVertices), - "createTruncatedConeBuffers": createBufferFunc(createTruncatedConeVertices), - "createTruncatedConeVertices": createTruncatedConeVertices, - "createXYQuadBufferInfo": createBufferInfoFunc(createXYQuadVertices), - "createXYQuadBuffers": createBufferFunc(createXYQuadVertices), - "createXYQuadVertices": createXYQuadVertices, - "createCresentBufferInfo": createBufferInfoFunc(createCresentVertices), - "createCresentBuffers": createBufferFunc(createCresentVertices), - "createCresentVertices": createCresentVertices, - "createCylinderBufferInfo": createBufferInfoFunc(createCylinderVertices), - "createCylinderBuffers": createBufferFunc(createCylinderVertices), - "createCylinderVertices": createCylinderVertices, - "createTorusBufferInfo": createBufferInfoFunc(createTorusVertices), - "createTorusBuffers": createBufferFunc(createTorusVertices), - "createTorusVertices": createTorusVertices, - "createDiscBufferInfo": createBufferInfoFunc(createDiscVertices), - "createDiscBuffers": createBufferFunc(createDiscVertices), - "createDiscVertices": createDiscVertices, - "deindexVertices": deindexVertices, - "flattenNormals": flattenNormals, - "makeRandomVertexColors": makeRandomVertexColors, - "reorientDirections": reorientDirections, - "reorientNormals": reorientNormals, - "reorientPositions": reorientPositions, - "reorientVertices": reorientVertices, - "concatVertices": concatVertices, - "duplicateVertices": duplicateVertices, - }; - - }); - - define('main', [ - 'twgl/twgl', - 'twgl/m4', - 'twgl/v3', - 'twgl/primitives', - ], function( - twgl, - m4, - v3, - primitives - ) { - twgl.m4 = m4; - twgl.v3 = v3; - twgl.primitives = primitives; - return twgl; - }) - - notrequirebecasebrowserifymessesup(['main'], function(main) { - return main; - }, undefined, true); // forceSync = true - - - ; - define("build/js/twgl-includer-full", function(){}); - - return notrequirebecasebrowserifymessesup('main'); - })); - - -/***/ }, -/* 304 */ -/***/ function(module, exports, __webpack_require__) { - - 'use strict'; - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - var twgl = __webpack_require__(303); - var svgToImage = __webpack_require__(305); - var xhr = __webpack_require__(307); - - var ShaderManager = __webpack_require__(315); - - var Drawable = - /** - * An object which can be drawn by the renderer. - * TODO: double-buffer all rendering state (position, skin, effects, etc.) - * @param gl The OpenGL context. - * @constructor - */ - function Drawable(gl) { - _classCallCheck(this, Drawable); - - this._id = Drawable._nextDrawable++; - Drawable._allDrawables[this._id] = this; - - this._gl = gl; - - /** - * The uniforms to be used by the vertex and pixel shaders. - * Some of these are used by other parts of the renderer as well. - * @type {Object.} - * @private - */ - this._uniforms = { - /** - * The model matrix, to concat with projection at draw time. - * @type {module:twgl/m4.Mat4} - */ - u_modelMatrix: twgl.m4.identity(), - - /** - * The nominal (not necessarily current) size of the current skin. - * This is scaled by _costumeResolution. - * @type {number[]} - */ - u_skinSize: [0, 0], - - /** - * The actual WebGL texture object for the skin. - * @type {WebGLTexture} - */ - u_skin: null, - - /** - * The color to use in the silhouette draw mode. - * @type {number[]} - */ - u_silhouetteColor: Drawable.color4fFromID(this._id) - }; - - // Effect values are uniforms too - var numEffects = ShaderManager.EFFECTS.length; - for (var index = 0; index < numEffects; ++index) { - var effectName = ShaderManager.EFFECTS[index]; - var converter = ShaderManager.EFFECT_INFO[effectName].converter; - this._uniforms['u_' + effectName] = converter(0); - } - - this._position = twgl.v3.create(0, 0); - this._scale = twgl.v3.create(100, 100); - this._direction = 90; - this._transformDirty = true; - this._visible = true; - this._effectBits = 0; - - // Create a transparent 1x1 texture for temporary use - var tempTexture = twgl.createTexture(gl, { src: [0, 0, 0, 0] }); - this._useSkin(tempTexture, 0, 0, 1, true); - - // Load a real skin - this.setSkin(Drawable._DEFAULT_SKIN); - }; - - module.exports = Drawable; - - /** - * @callback Drawable~idFilterFunc - * @param {int} drawableID The ID to filter. - * @return {bool} True if the ID passes the filter, otherwise false. - */ - - /** - * An invalid Drawable ID which can be used to signify absence, etc. - * @type {int} - */ - Drawable.NONE = -1; - - /** - * The ID to be assigned next time the Drawable constructor is called. - * @type {number} - * @private - */ - Drawable._nextDrawable = 0; - - /** - * All current Drawables, by ID. - * @type {Object.} - * @private - */ - Drawable._allDrawables = {}; - - /** - * Fetch a Drawable by its ID number. - * @param drawableID {int} The ID of the Drawable to fetch. - * @returns {?Drawable} The specified Drawable if found, otherwise null. - */ - Drawable.getDrawableByID = function (drawableID) { - return Drawable._allDrawables[drawableID]; - }; - - // TODO: fall back on a built-in skin to protect against network problems - Drawable._DEFAULT_SKIN = { - squirrel: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/' + '7e24c99c1b853e52f8e7f9004416fa34.png/get/', - bus: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/' + '66895930177178ea01d9e610917f8acf.png/get/', - scratch_cat: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/' + '09dc888b0b7df19f70d81588ae73420e.svg/get/', - gradient: 'https://cdn.assets.scratch.mit.edu/internalapi/asset/' + 'a49ff276b9b8f997a1ae163992c2c145.png/get/' - }.squirrel; - - /** - * Dispose of this Drawable. Do not use it after calling this method. - */ - Drawable.prototype.dispose = function () { - this.setSkin(null); - if (this._id >= 0) { - delete Drawable[this._id]; - } - }; - - /** - * Mark this Drawable's transform as dirty. - * It will be recalculated next time it's needed. - */ - Drawable.prototype.setTransformDirty = function () { - this._transformDirty = true; - }; - - /** - * Retrieve the ID for this Drawable. - * @returns {number} The ID for this Drawable. - */ - Drawable.prototype.getID = function () { - return this._id; - }; - - /** - * Set this Drawable's skin. - * The Drawable will continue using the existing skin until the new one loads. - * If there is no existing skin, the Drawable will use a 1x1 transparent image. - * @param {string} skin_url The URL of the skin. - */ - Drawable.prototype.setSkin = function (skin_url) { - // TODO: cache Skins instead of loading each time. Ref count them? - // TODO: share Skins across Drawables - see also destroy() - if (skin_url) { - var ext = skin_url.substring(skin_url.lastIndexOf('.') + 1); - switch (ext) { - case 'svg': - case 'svg/get/': - case 'svgz': - case 'svgz/get/': - this._setSkinSVG(skin_url); - break; - default: - this._setSkinBitmap(skin_url); - break; - } - } else { - this._useSkin(null, 0, 0, 1, true); - } - }; - - /** - * Use a skin if it is the currently-pending skin, or if skipPendingCheck==true. - * If the passed skin is used (for either reason) _pendingSkin will be cleared. - * @param {WebGLTexture} skin The skin to use. - * @param {int} width The width of the skin. - * @param {int} height The height of the skin. - * @param {int} costumeResolution The resolution to use for this skin. - * @param {Boolean} [skipPendingCheck] If true, don't compare to _pendingSkin. - * @private - */ - Drawable.prototype._useSkin = function (skin, width, height, costumeResolution, skipPendingCheck) { - - if (skipPendingCheck || skin == this._pendingSkin) { - this._pendingSkin = null; - if (this._uniforms.u_skin && this._uniforms.u_skin != skin) { - this._gl.deleteTexture(this._uniforms.u_skin); - } - this._setSkinSize(width, height, costumeResolution); - this._uniforms.u_skin = skin; - } - }; - - /** - * @returns {int} A bitmask identifying which effects are currently in use. - */ - Drawable.prototype.getEnabledEffects = function () { - return this._effectBits; - }; - - /** - * Load a bitmap skin. Supports the same formats as the Image element. - * @param {string} skin_md5ext The MD5 and file extension of the bitmap skin. - * @private - */ - Drawable.prototype._setSkinBitmap = function (skin_md5ext) { - var url = skin_md5ext; - this._setSkinCore(url, 2); - }; - - /** - * Load an SVG-based skin. This still needs quite a bit of work to match the - * level of quality found in Scratch 2.0: - * - We should detect when a skin is being scaled up and render the SVG at a - * higher resolution in those cases. - * - Colors seem a little off. This may be browser-specific. - * - This method works in Chrome, Firefox, Safari, and Edge but causes a - * security error in IE. - * @param {string} skin_md5ext The MD5 and file extension of the SVG skin. - * @private - */ - Drawable.prototype._setSkinSVG = function (skin_md5ext) { - var url = skin_md5ext; - var instance = this; - function gotSVG(err, response, body) { - if (!err) { - svgToImage(body, gotImage); - } - } - function gotImage(err, image) { - if (!err) { - instance._setSkinCore(image, 1); - } - } - xhr.get({ - useXDR: true, - url: url - }, gotSVG); - // TODO: if there's no current u_skin, install *something* before returning - }; - - /** - * Common code for setting all skin types. - * @param {string|Image} source The source of image data for the skin. - * @param {int} costumeResolution The resolution to use for this skin. - * @private - */ - Drawable.prototype._setSkinCore = function (source, costumeResolution) { - var instance = this; - var callback = function callback(err, texture, source) { - if (!err && instance._pendingSkin == texture) { - instance._useSkin(texture, source.width, source.height, costumeResolution); - } - }; - - var gl = this._gl; - var options = { - auto: true, - mag: gl.NEAREST, - min: gl.NEAREST, // TODO: mipmaps, linear (except pixelate) - wrap: gl.CLAMP_TO_EDGE, - src: source - }; - var willCallCallback = typeof source == 'string'; - instance._pendingSkin = twgl.createTexture(gl, options, willCallCallback ? callback : null); - - // If we won't get a callback, start using the skin immediately. - // This will happen if the data is already local. - if (!willCallCallback) { - callback(null, instance._pendingSkin, source); - } - }; - - /** - * Retrieve the shader uniforms to be used when rendering this Drawable. - * @returns {Object.} - */ - Drawable.prototype.getUniforms = function () { - if (this._transformDirty) { - this._calculateTransform(); - } - return this._uniforms; - }; - - /** - * Retrieve whether this Drawable is visible. - * @returns {boolean} - */ - Drawable.prototype.getVisible = function () { - return this._visible; - }; - - /** - * Update the position, direction, scale, or effect properties of this Drawable. - * @param {Object.} properties The new property values to set. - */ - Drawable.prototype.updateProperties = function (properties) { - var dirty = false; - if ('skin' in properties) { - this.setSkin(properties.skin); - } - if ('position' in properties && (this._position[0] != properties.position[0] || this._position[1] != properties.position[1])) { - this._position[0] = properties.position[0]; - this._position[1] = properties.position[1]; - dirty = true; - } - if ('direction' in properties && this._direction != properties.direction) { - this._direction = properties.direction; - dirty = true; - } - if ('scale' in properties && (this._scale[0] != properties.scale[0] || this._scale[1] != properties.scale[1])) { - this._scale[0] = properties.scale[0]; - this._scale[1] = properties.scale[1]; - dirty = true; - } - if ('visible' in properties) { - this._visible = properties.visible; - } - if (dirty) { - this.setTransformDirty(); - } - var numEffects = ShaderManager.EFFECTS.length; - for (var index = 0; index < numEffects; ++index) { - var effectName = ShaderManager.EFFECTS[index]; - if (effectName in properties) { - var rawValue = properties[effectName]; - var effectInfo = ShaderManager.EFFECT_INFO[effectName]; - if (rawValue != 0) { - this._effectBits |= effectInfo.mask; - } else { - this._effectBits &= ~effectInfo.mask; - } - var converter = effectInfo.converter; - this._uniforms['u_' + effectName] = converter(rawValue); - } - } - }; - - /** - * Set the dimensions of this Drawable's skin. - * @param {int} width The width of the new skin. - * @param {int} height The height of the new skin. - * @param {int} [costumeResolution] The resolution to use for this skin. - * @private - */ - Drawable.prototype._setSkinSize = function (width, height, costumeResolution) { - costumeResolution = costumeResolution || 1; - width /= costumeResolution; - height /= costumeResolution; - if (this._uniforms.u_skinSize[0] != width || this._uniforms.u_skinSize[1] != height) { - this._uniforms.u_skinSize[0] = width; - this._uniforms.u_skinSize[1] = height; - this.setTransformDirty(); - } - }; - - /** - * Calculate the transform to use when rendering this Drawable. - * @private - */ - Drawable.prototype._calculateTransform = function () { - var modelMatrix = this._uniforms.u_modelMatrix; - - twgl.m4.identity(modelMatrix); - twgl.m4.translate(modelMatrix, this._position, modelMatrix); - - var rotation = (270 - this._direction) * Math.PI / 180; - twgl.m4.rotateZ(modelMatrix, rotation, modelMatrix); - - var scaledSize = twgl.v3.divScalar(twgl.v3.multiply(this._uniforms.u_skinSize, this._scale), 100); - scaledSize[3] = 0; // was NaN because the vectors have only 2 components. - twgl.m4.scale(modelMatrix, scaledSize, modelMatrix); - - this._transformDirty = false; - }; - - /** - * Calculate a color to represent the given ID number. At least one component of - * the resulting color will be non-zero if the ID is not Drawable.NONE. - * @param {int} id The ID to convert. - * @returns {number[]} An array of [r,g,b,a], each component in the range [0,1]. - */ - Drawable.color4fFromID = function (id) { - id -= Drawable.NONE; - var r = (id >> 0 & 255) / 255.0; - var g = (id >> 8 & 255) / 255.0; - var b = (id >> 16 & 255) / 255.0; - return [r, g, b, 1.0]; - }; - - /** - * Calculate the ID number represented by the given color. If all components of - * the color are zero, the result will be Drawable.NONE; otherwise the result - * will be a valid ID. - * @param {int} r The red value of the color, in the range [0,255]. - * @param {int} g The green value of the color, in the range [0,255]. - * @param {int} b The blue value of the color, in the range [0,255]. - * @param {int} a The alpha value of the color, in the range [0,255]. - * @returns {int} The ID represented by that color. - */ - // eslint-disable-next-line no-unused-vars - Drawable.color4bToID = function (r, g, b, a) { - var id; - id = (r & 255) << 0; - id |= (g & 255) << 8; - id |= (b & 255) << 16; - return id + Drawable.NONE; - }; - -/***/ }, -/* 305 */ -/***/ function(module, exports, __webpack_require__) { - - /* WEBPACK VAR INJECTION */(function(process) {var loadImage = __webpack_require__(306) - var noop = function () {} - - module.exports = svgToImage - function svgToImage (svg, opt, cb) { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - cb = cb || noop - opt = opt || {} - - if (typeof window === 'undefined') { - return bail('window global is undefined; not in a browser') - } - - var DOMURL = getURL() - if (!DOMURL || - typeof DOMURL.createObjectURL !== 'function' || - typeof DOMURL.revokeObjectURL !== 'function') { - return bail('browser does not support URL.createObjectURL') - } - - if (typeof window.Blob === 'undefined') { - return bail('browser does not support Blob constructor') - } - - if (!Array.isArray(svg)) { - svg = [ svg ] - } - - var blob - try { - blob = new window.Blob(svg, { - type: 'image/svg+xml;charset=utf-8' - }) - } catch (e) { - return bail(e) - } - - var url = DOMURL.createObjectURL(blob) - loadImage(url, opt, function (err, img) { - DOMURL.revokeObjectURL(url) - if (err) { - // try again for Safari 8.0, using simple encodeURIComponent - // this will fail with DOM content but at least it works with SVG - var url2 = 'data:image/svg+xml,' + encodeURIComponent(svg.join('')) - return loadImage(url2, opt, cb) - } - - cb(err, img) - }) - - function bail (msg) { - process.nextTick(function () { - cb(new Error(msg)) - }) - } - } - - function getURL () { - return window.URL || - window.webkitURL || - window.mozURL || - window.msURL - } - - /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(294))) - -/***/ }, -/* 306 */ -/***/ function(module, exports) { - - module.exports = loadImage; - function loadImage (src, opt, callback) { - if (typeof opt === 'function') { - callback = opt; - opt = null; - } - - var el = document.createElement('img'); - var locked; - - el.onload = function onLoaded () { - if (locked) return; - locked = true; - - if (callback) callback(undefined, el); - }; - - el.onerror = function onError () { - if (locked) return; - locked = true; - - if (callback) callback(new Error('Unable to load "' + src + '"'), el); - }; - - if (opt && opt.crossOrigin) { - el.crossOrigin = opt.crossOrigin; - } - - el.src = src; - - return el; - } - - -/***/ }, -/* 307 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - var window = __webpack_require__(308) - var once = __webpack_require__(309) - var isFunction = __webpack_require__(310) - var parseHeaders = __webpack_require__(311) - var xtend = __webpack_require__(314) - - module.exports = createXHR - createXHR.XMLHttpRequest = window.XMLHttpRequest || noop - createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest - - forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { - createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { - options = initParams(uri, options, callback) - options.method = method.toUpperCase() - return _createXHR(options) - } - }) - - function forEachArray(array, iterator) { - for (var i = 0; i < array.length; i++) { - iterator(array[i]) - } - } - - function isEmpty(obj){ - for(var i in obj){ - if(obj.hasOwnProperty(i)) return false - } - return true - } - - function initParams(uri, options, callback) { - var params = uri - - if (isFunction(options)) { - callback = options - if (typeof uri === "string") { - params = {uri:uri} - } - } else { - params = xtend(options, {uri: uri}) - } - - params.callback = callback - return params - } - - function createXHR(uri, options, callback) { - options = initParams(uri, options, callback) - return _createXHR(options) - } - - function _createXHR(options) { - var callback = options.callback - if(typeof callback === "undefined"){ - throw new Error("callback argument missing") - } - callback = once(callback) - - function readystatechange() { - if (xhr.readyState === 4) { - loadFunc() - } - } - - function getBody() { - // Chrome with requestType=blob throws errors arround when even testing access to responseText - var body = undefined - - if (xhr.response) { - body = xhr.response - } else if (xhr.responseType === "text" || !xhr.responseType) { - body = xhr.responseText || xhr.responseXML - } - - if (isJson) { - try { - body = JSON.parse(body) - } catch (e) {} - } - - return body - } - - var failureResponse = { - body: undefined, - headers: {}, - statusCode: 0, - method: method, - url: uri, - rawRequest: xhr - } - - function errorFunc(evt) { - clearTimeout(timeoutTimer) - if(!(evt instanceof Error)){ - evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) - } - evt.statusCode = 0 - callback(evt, failureResponse) - } - - // will load the data & process the response in a special response object - function loadFunc() { - if (aborted) return - var status - clearTimeout(timeoutTimer) - if(options.useXDR && xhr.status===undefined) { - //IE8 CORS GET successful response doesn't have a status field, but body is fine - status = 200 - } else { - status = (xhr.status === 1223 ? 204 : xhr.status) - } - var response = failureResponse - var err = null - - if (status !== 0){ - response = { - body: getBody(), - statusCode: status, - method: method, - headers: {}, - url: uri, - rawRequest: xhr - } - if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE - response.headers = parseHeaders(xhr.getAllResponseHeaders()) - } - } else { - err = new Error("Internal XMLHttpRequest Error") - } - callback(err, response, response.body) - - } - - var xhr = options.xhr || null - - if (!xhr) { - if (options.cors || options.useXDR) { - xhr = new createXHR.XDomainRequest() - }else{ - xhr = new createXHR.XMLHttpRequest() - } - } - - var key - var aborted - var uri = xhr.url = options.uri || options.url - var method = xhr.method = options.method || "GET" - var body = options.body || options.data || null - var headers = xhr.headers = options.headers || {} - var sync = !!options.sync - var isJson = false - var timeoutTimer - - if ("json" in options) { - isJson = true - headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user - if (method !== "GET" && method !== "HEAD") { - headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user - body = JSON.stringify(options.json) - } - } - - xhr.onreadystatechange = readystatechange - xhr.onload = loadFunc - xhr.onerror = errorFunc - // IE9 must have onprogress be set to a unique function. - xhr.onprogress = function () { - // IE must die - } - xhr.ontimeout = errorFunc - xhr.open(method, uri, !sync, options.username, options.password) - //has to be after open - if(!sync) { - xhr.withCredentials = !!options.withCredentials - } - // Cannot set timeout with sync request - // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly - // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent - if (!sync && options.timeout > 0 ) { - timeoutTimer = setTimeout(function(){ - aborted=true//IE9 may still call readystatechange - xhr.abort("timeout") - var e = new Error("XMLHttpRequest timeout") - e.code = "ETIMEDOUT" - errorFunc(e) - }, options.timeout ) - } - - if (xhr.setRequestHeader) { - for(key in headers){ - if(headers.hasOwnProperty(key)){ - xhr.setRequestHeader(key, headers[key]) - } - } - } else if (options.headers && !isEmpty(options.headers)) { - throw new Error("Headers cannot be set on an XDomainRequest object") - } - - if ("responseType" in options) { - xhr.responseType = options.responseType - } - - if ("beforeSend" in options && - typeof options.beforeSend === "function" - ) { - options.beforeSend(xhr) - } - - xhr.send(body) - - return xhr - - - } - - function noop() {} - - -/***/ }, -/* 308 */ -/***/ function(module, exports) { - - /* WEBPACK VAR INJECTION */(function(global) {if (typeof window !== "undefined") { - module.exports = window; - } else if (typeof global !== "undefined") { - module.exports = global; - } else if (typeof self !== "undefined"){ - module.exports = self; - } else { - module.exports = {}; - } - - /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) - -/***/ }, -/* 309 */ -/***/ function(module, exports) { - - module.exports = once - - once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) - }) - - function once (fn) { - var called = false - return function () { - if (called) return - called = true - return fn.apply(this, arguments) - } - } - - -/***/ }, -/* 310 */ -/***/ function(module, exports) { - - module.exports = isFunction - - var toString = Object.prototype.toString - - function isFunction (fn) { - var string = toString.call(fn) - return string === '[object Function]' || - (typeof fn === 'function' && string !== '[object RegExp]') || - (typeof window !== 'undefined' && - // IE8 and below - (fn === window.setTimeout || - fn === window.alert || - fn === window.confirm || - fn === window.prompt)) - }; - - -/***/ }, -/* 311 */ -/***/ function(module, exports, __webpack_require__) { - - var trim = __webpack_require__(312) - , forEach = __webpack_require__(313) - , isArray = function(arg) { - return Object.prototype.toString.call(arg) === '[object Array]'; - } - - module.exports = function (headers) { - if (!headers) - return {} - - var result = {} - - forEach( - trim(headers).split('\n') - , function (row) { - var index = row.indexOf(':') - , key = trim(row.slice(0, index)).toLowerCase() - , value = trim(row.slice(index + 1)) - - if (typeof(result[key]) === 'undefined') { - result[key] = value - } else if (isArray(result[key])) { - result[key].push(value) - } else { - result[key] = [ result[key], value ] - } - } - ) - - return result - } - -/***/ }, -/* 312 */ -/***/ function(module, exports) { - - - exports = module.exports = trim; - - function trim(str){ - return str.replace(/^\s*|\s*$/g, ''); - } - - exports.left = function(str){ - return str.replace(/^\s*/, ''); - }; - - exports.right = function(str){ - return str.replace(/\s*$/, ''); - }; - - -/***/ }, -/* 313 */ -/***/ function(module, exports, __webpack_require__) { - - var isFunction = __webpack_require__(310) - - module.exports = forEach - - var toString = Object.prototype.toString - var hasOwnProperty = Object.prototype.hasOwnProperty - - function forEach(list, iterator, context) { - if (!isFunction(iterator)) { - throw new TypeError('iterator must be a function') - } - - if (arguments.length < 3) { - context = this - } - - if (toString.call(list) === '[object Array]') - forEachArray(list, iterator, context) - else if (typeof list === 'string') - forEachString(list, iterator, context) - else - forEachObject(list, iterator, context) - } - - function forEachArray(array, iterator, context) { - for (var i = 0, len = array.length; i < len; i++) { - if (hasOwnProperty.call(array, i)) { - iterator.call(context, array[i], i, array) - } - } - } - - function forEachString(string, iterator, context) { - for (var i = 0, len = string.length; i < len; i++) { - // no such thing as a sparse string. - iterator.call(context, string.charAt(i), i, string) - } - } - - function forEachObject(object, iterator, context) { - for (var k in object) { - if (hasOwnProperty.call(object, k)) { - iterator.call(context, object[k], k, object) - } - } - } - - -/***/ }, -/* 314 */ -/***/ function(module, exports) { - - module.exports = extend - - var hasOwnProperty = Object.prototype.hasOwnProperty; - - function extend() { - var target = {} - - for (var i = 0; i < arguments.length; i++) { - var source = arguments[i] - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - } - - return target - } - - -/***/ }, -/* 315 */ -/***/ function(module, exports, __webpack_require__) { - - 'use strict'; - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - - var twgl = __webpack_require__(303); - - var ShaderManager = function ShaderManager(gl) { - _classCallCheck(this, ShaderManager); - - this._gl = gl; - - /** - * The cache of all shaders compiled so far, filled on demand. - * @type {Object.>} - * @private - */ - this._shaderCache = {}; - for (var modeName in ShaderManager.DRAW_MODE) { - if (ShaderManager.DRAW_MODE.hasOwnProperty(modeName)) { - this._shaderCache[modeName] = []; - } - } - }; - - module.exports = ShaderManager; - - /** - * Mapping of each effect name to info about that effect. - * The info includes: - * - The bit in 'effectBits' representing the effect. - * - A conversion function which takes a Scratch value (generally in the range - * 0..100 or -100..100) and maps it to a value useful to the shader. This - * mapping may not be reversible. - * @type {Object.>} - */ - ShaderManager.EFFECT_INFO = { - color: { - mask: 1 << 0, - converter: function converter(x) { - return x / 200 % 1; - } - }, - fisheye: { - mask: 1 << 1, - converter: function converter(x) { - return Math.max(0, (x + 100) / 100); - } - }, - whirl: { - mask: 1 << 2, - converter: function converter(x) { - return x * Math.PI / 180; - } - }, - pixelate: { - mask: 1 << 3, - converter: function converter(x) { - return Math.abs(x) / 10; - } - }, - mosaic: { - mask: 1 << 4, - converter: function converter(x) { - x = Math.round((Math.abs(x) + 10) / 10); - // TODO: cap by Math.min(srcWidth, srcHeight) - return Math.max(1, Math.min(x, 512)); - } - }, - brightness: { - mask: 1 << 5, - converter: function converter(x) { - return Math.max(-100, Math.min(x, 100)) / 100; - } - }, - ghost: { - mask: 1 << 6, - converter: function converter(x) { - return 1 - Math.max(0, Math.min(x, 100)) / 100; - } - } - }; - - /** - * The name of each supported effect. - * @type {Array} - */ - ShaderManager.EFFECTS = Object.keys(ShaderManager.EFFECT_INFO); - - /** - * The available draw modes. - * @readonly - * @enum {string} - */ - ShaderManager.DRAW_MODE = { - /** - * Draw normally. - */ - default: 'default', - - /** - * Draw a silhouette using a solid color. - */ - silhouette: 'silhouette', - - /** - * Draw only the parts of the drawable which match a particular color. - */ - colorMask: 'colorMask' - }; - - /** - * Fetch the shader for a particular set of active effects. - * Build the shader if necessary. - * @param {ShaderManager.DRAW_MODE} drawMode Draw normally, silhouette, etc. - * @param {int} effectBits Bitmask representing the enabled effects. - * @returns {ProgramInfo} The shader's program info. - */ - ShaderManager.prototype.getShader = function (drawMode, effectBits) { - var cache = this._shaderCache[drawMode]; - if (drawMode == ShaderManager.DRAW_MODE.silhouette) { - // Silhouette mode isn't affected by these effects. - effectBits &= ~(ShaderManager.EFFECT_INFO.color.mask | ShaderManager.EFFECT_INFO.brightness.mask); - } - var shader = cache[effectBits]; - if (!shader) { - shader = cache[effectBits] = this._buildShader(drawMode, effectBits); - } - return shader; - }; - - /** - * Build the shader for a particular set of active effects. - * @param {ShaderManager.DRAW_MODE} drawMode Draw normally, silhouette, etc. - * @param {int} effectBits Bitmask representing the enabled effects. - * @returns {ProgramInfo} The new shader's program info. - * @private - */ - ShaderManager.prototype._buildShader = function (drawMode, effectBits) { - var numEffects = ShaderManager.EFFECTS.length; - - var defines = ['#define DRAW_MODE_' + drawMode]; - for (var index = 0; index < numEffects; ++index) { - if ((effectBits & 1 << index) != 0) { - defines.push('#define ENABLE_' + ShaderManager.EFFECTS[index]); - } - } - - var definesText = defines.join('\n') + '\n'; - var vsFullText = definesText + __webpack_require__(316); - var fsFullText = definesText + __webpack_require__(317); - - return twgl.createProgramInfo(this._gl, [vsFullText, fsFullText]); - }; - -/***/ }, -/* 316 */ -/***/ function(module, exports) { - - module.exports = "uniform mat4 u_projectionMatrix;\nuniform mat4 u_modelMatrix;\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\n\nvarying vec2 v_texCoord;\n\nvoid main() {\n gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1);\n v_texCoord = a_texCoord;\n}\n" - -/***/ }, -/* 317 */ -/***/ function(module, exports) { - - module.exports = "precision mediump float;\n\nuniform float u_fudge;\n\n#ifdef DRAW_MODE_silhouette\nuniform vec4 u_silhouetteColor;\n#else // DRAW_MODE_silhouette\n# ifdef ENABLE_color\nuniform float u_color;\n# endif // ENABLE_color\n# ifdef ENABLE_brightness\nuniform float u_brightness;\n# endif // ENABLE_brightness\n#endif // DRAW_MODE_silhouette\n\n#ifdef DRAW_MODE_colorMask\nuniform vec3 u_colorMask;\nuniform float u_colorMaskTolerance;\n#endif // DRAW_MODE_colorMask\n\n#ifdef ENABLE_fisheye\nuniform float u_fisheye;\n#endif // ENABLE_fisheye\n#ifdef ENABLE_whirl\nuniform float u_whirl;\n#endif // ENABLE_whirl\n#ifdef ENABLE_pixelate\nuniform float u_pixelate;\nuniform vec2 u_skinSize;\n#endif // ENABLE_pixelate\n#ifdef ENABLE_mosaic\nuniform float u_mosaic;\n#endif // ENABLE_mosaic\n#ifdef ENABLE_ghost\nuniform float u_ghost;\n#endif // ENABLE_ghost\n\nuniform sampler2D u_skin;\n\nvarying vec2 v_texCoord;\n\n#if !defined(DRAW_MODE_silhouette) && (defined(ENABLE_color) || defined(ENABLE_brightness))\n// Branchless color conversions based on code from:\n// http://www.chilliant.com/rgb2hsv.html by Ian Taylor\n// Based in part on work by Sam Hocevar and Emil Persson\n\nconst float kEpsilon = 1e-6;\n\nvec3 convertRGB2HCV(vec3 rgb)\n{\n\tvec4 p = (rgb.g < rgb.b) ? vec4(rgb.bg, -1, 2.0/3.0) : vec4(rgb.gb, 0, -1.0/3.0);\n\tvec4 q = (rgb.r < p.x) ? vec4(p.xyw, rgb.r) : vec4(rgb.r, p.yzx);\n\tfloat c = q.x - min(q.w, q.y);\n\tfloat h = abs((q.w - q.y) / (6.0 * c + kEpsilon) + q.z);\n\treturn vec3(h, c, q.x);\n}\n\nvec3 convertRGB2HSL(vec3 rgb)\n{\n\tvec3 hcv = convertRGB2HCV(rgb);\n\tfloat l = hcv.z - hcv.y * 0.5;\n\tfloat s = hcv.y / (1.0 - abs(l * 2.0 - 1.0) + kEpsilon);\n\treturn vec3(hcv.x, s, l);\n}\n\nvec3 convertHue2RGB(float hue)\n{\n\tfloat r = abs(hue * 6.0 - 3.0) - 1.0;\n\tfloat g = 2.0 - abs(hue * 6.0 - 2.0);\n\tfloat b = 2.0 - abs(hue * 6.0 - 4.0);\n\treturn clamp(vec3(r, g, b), 0.0, 1.0);\n}\n\nvec3 convertHSL2RGB(vec3 hsl)\n{\n\tvec3 rgb = convertHue2RGB(hsl.x);\n\tfloat c = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;\n\treturn (rgb - 0.5) * c + hsl.z;\n}\n#endif // !defined(DRAW_MODE_silhouette) && (defined(ENABLE_color) || defined(ENABLE_brightness))\n\nconst vec2 kCenter = vec2(0.5, 0.5);\n\nvoid main()\n{\n\tvec2 texcoord0 = v_texCoord;\n\n\t#ifdef ENABLE_mosaic\n\ttexcoord0 = fract(u_mosaic * texcoord0);\n\t#endif // ENABLE_mosaic\n\n\t#ifdef ENABLE_pixelate\n\t{\n\t\t// TODO: clean up \"pixel\" edges\n\t\tvec2 pixelTexelSize = u_skinSize / u_pixelate;\n\t\ttexcoord0 = (floor(texcoord0 * pixelTexelSize) + kCenter) / pixelTexelSize;\n\t}\n\t#endif // ENABLE_pixelate\n\n\t#ifdef ENABLE_whirl\n\t{\n\t\tconst float kRadius = 0.5;\n\t\tvec2 offset = texcoord0 - kCenter;\n\t\tfloat offsetMagnitude = length(offset);\n\t\tfloat whirlFactor = 1.0 - (offsetMagnitude / kRadius);\n\t\tfloat whirlActual = u_whirl * whirlFactor * whirlFactor;\n\t\tfloat sinWhirl = sin(whirlActual);\n\t\tfloat cosWhirl = cos(whirlActual);\n\t\tmat2 rotationMatrix = mat2(\n\t\t\tcosWhirl, -sinWhirl,\n\t\t\tsinWhirl, cosWhirl\n\t\t);\n\n\t\t// TODO: tweak this algorithm such that texture coordinates don't depend on conditionals.\n\t\t// see: https://www.opengl.org/wiki/Sampler_%28GLSL%29#Non-uniform_flow_control\n\t\tif (offsetMagnitude <= kRadius)\n\t\t{\n\t\t\ttexcoord0 = rotationMatrix * offset + kCenter;\n\t\t}\n\t}\n\t#endif // ENABLE_whirl\n\n\t#ifdef ENABLE_fisheye\n\t{\n\t\tvec2 vec = (texcoord0 - kCenter) / kCenter;\n\t\tfloat r = pow(length(vec), u_fisheye);\n\t\tfloat angle = atan(vec.y, vec.x);\n\t\t// TODO: tweak this algorithm such that texture coordinates don't depend on conditionals.\n\t\t// see: https://www.opengl.org/wiki/Sampler_%28GLSL%29#Non-uniform_flow_control\n\t\tif (r <= 1.0)\n\t\t{\n\t\t\ttexcoord0 = kCenter + r * vec2(cos(angle), sin(angle)) * kCenter;\n\t\t}\n\t}\n\t#endif // ENABLE_fisheye\n\n\tgl_FragColor = texture2D(u_skin, texcoord0);\n\n\t#ifdef ENABLE_ghost\n\tgl_FragColor.a *= u_ghost;\n\t#endif // ENABLE_ghost\n\n\tif (gl_FragColor.a == 0.0)\n\t{\n\t\tdiscard;\n\t}\n\n\t#ifdef DRAW_MODE_silhouette\n\t// switch to u_silhouetteColor only AFTER the alpha test\n\tgl_FragColor = u_silhouetteColor;\n\t#else // DRAW_MODE_silhouette\n\n\t#if defined(ENABLE_color) || defined(ENABLE_brightness)\n\t{\n\t\tvec3 hsl = convertRGB2HSL(gl_FragColor.xyz);\n\n\t\t#ifdef ENABLE_color\n\t\t{\n\t\t\t// this code forces grayscale values to be slightly saturated\n\t\t\t// so that some slight change of hue will be visible\n\t\t\tconst float minLightness = 0.11 / 2.0;\n\t\t\tconst float minSaturation = 0.09;\n\t\t\tif (hsl.z < minLightness) hsl = vec3(0.0, 1.0, minLightness);\n\t\t\telse if (hsl.y < minSaturation) hsl = vec3(0.0, minSaturation, hsl.z);\n\n\t\t\thsl.x = mod(hsl.x + u_color, 1.0);\n\t\t\tif (hsl.x < 0.0) hsl.x += 1.0;\n\t\t}\n\t\t#endif // ENABLE_color\n\n\t\t#ifdef ENABLE_brightness\n\t\thsl.z = clamp(hsl.z + u_brightness, 0.0, 1.0);\n\t\t#endif // ENABLE_brightness\n\n\t\tgl_FragColor.rgb = convertHSL2RGB(hsl);\n\t}\n\t#endif // defined(ENABLE_color) || defined(ENABLE_brightness)\n\n\t#ifdef DRAW_MODE_colorMask\n\tvec3 maskDistance = abs(gl_FragColor.rgb - u_colorMask);\n\tvec3 colorMaskTolerance = vec3(u_colorMaskTolerance, u_colorMaskTolerance, u_colorMaskTolerance);\n\tif (any(greaterThan(maskDistance, colorMaskTolerance)))\n\t{\n\t\tdiscard;\n\t}\n\t#endif // DRAW_MODE_colorMask\n\n\t// WebGL defaults to premultiplied alpha\n\tgl_FragColor.rgb *= gl_FragColor.a;\n\n\t#endif // DRAW_MODE_silhouette\n}\n" - -/***/ } -/******/ ]); \ No newline at end of file diff --git a/render.min.js b/render.min.js deleted file mode 100644 index 7472080c..00000000 --- a/render.min.js +++ /dev/null @@ -1,26 +0,0 @@ -!function(t){function n(e){if(r[e])return r[e].exports;var i=r[e]={exports:{},id:e,loaded:!1};return t[e].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){"use strict";r(1);var e=r(298);window.RenderWebGL=e},function(t,n,r){(function(t){"use strict";function n(t,n,r){t[n]||Object[e](t,n,{writable:!0,configurable:!0,value:r})}if(r(2),r(293),r(295),t._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");t._babelPolyfill=!0;var e="defineProperty";n(String.prototype,"padLeft","".padStart),n(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function(t){[][t]&&n(Array,t,Function.call.bind([][t]))})}).call(n,function(){return this}())},function(t,n,r){r(3),r(52),r(53),r(54),r(55),r(57),r(60),r(61),r(62),r(63),r(64),r(65),r(66),r(67),r(68),r(70),r(72),r(74),r(76),r(79),r(80),r(81),r(85),r(87),r(89),r(92),r(93),r(94),r(95),r(97),r(98),r(99),r(100),r(101),r(102),r(103),r(105),r(106),r(107),r(109),r(110),r(111),r(113),r(114),r(115),r(116),r(117),r(118),r(119),r(120),r(121),r(122),r(123),r(124),r(125),r(126),r(131),r(132),r(136),r(137),r(138),r(139),r(141),r(142),r(143),r(144),r(145),r(146),r(147),r(148),r(149),r(150),r(151),r(152),r(153),r(154),r(155),r(156),r(157),r(159),r(160),r(166),r(167),r(169),r(170),r(171),r(175),r(176),r(177),r(178),r(179),r(181),r(182),r(183),r(184),r(187),r(189),r(190),r(191),r(193),r(195),r(197),r(198),r(199),r(201),r(202),r(203),r(204),r(211),r(214),r(215),r(217),r(218),r(221),r(222),r(224),r(225),r(226),r(227),r(228),r(229),r(230),r(231),r(232),r(233),r(234),r(235),r(236),r(237),r(238),r(239),r(240),r(241),r(242),r(244),r(245),r(246),r(247),r(248),r(249),r(251),r(252),r(253),r(254),r(255),r(256),r(257),r(258),r(260),r(261),r(263),r(264),r(265),r(266),r(269),r(270),r(271),r(272),r(273),r(274),r(275),r(276),r(278),r(279),r(280),r(281),r(282),r(283),r(284),r(285),r(286),r(287),r(288),r(291),r(292),t.exports=r(9)},function(t,n,r){"use strict";var e=r(4),i=r(5),o=r(6),u=r(8),a=r(18),f=r(22).KEY,c=r(7),s=r(23),l=r(24),h=r(19),p=r(25),v=r(26),d=r(27),g=r(29),y=r(42),m=r(45),_=r(12),E=r(32),w=r(16),b=r(17),A=r(46),x=r(49),S=r(51),T=r(11),R=r(30),I=S.f,O=T.f,P=x.f,M=e.Symbol,F=e.JSON,B=F&&F.stringify,U="prototype",L=p("_hidden"),N=p("toPrimitive"),C={}.propertyIsEnumerable,D=s("symbol-registry"),k=s("symbols"),j=s("op-symbols"),z=Object[U],G="function"==typeof M,W=e.QObject,Y=!W||!W[U]||!W[U].findChild,V=o&&c(function(){return 7!=A(O({},"a",{get:function(){return O(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=I(z,n);e&&delete z[n],O(t,n,r),e&&t!==z&&O(z,n,e)}:O,X=function(t){var n=k[t]=A(M[U]);return n._k=t,n},H=G&&"symbol"==typeof M.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof M},q=function(t,n,r){return t===z&&q(j,n,r),_(t),n=w(n,!0),_(r),i(k,n)?(r.enumerable?(i(t,L)&&t[L][n]&&(t[L][n]=!1),r=A(r,{enumerable:b(0,!1)})):(i(t,L)||O(t,L,b(1,{})),t[L][n]=!0),V(t,n,r)):O(t,n,r)},K=function(t,n){_(t);for(var r,e=y(n=E(n)),i=0,o=e.length;o>i;)q(t,r=e[i++],n[r]);return t},Z=function(t,n){return void 0===n?A(t):K(A(t),n)},J=function(t){var n=C.call(this,t=w(t,!0));return!(this===z&&i(k,t)&&!i(j,t))&&(!(n||!i(this,t)||!i(k,t)||i(this,L)&&this[L][t])||n)},Q=function(t,n){if(t=E(t),n=w(n,!0),t!==z||!i(k,n)||i(j,n)){var r=I(t,n);return!r||!i(k,n)||i(t,L)&&t[L][n]||(r.enumerable=!0),r}},$=function(t){for(var n,r=P(E(t)),e=[],o=0;r.length>o;)i(k,n=r[o++])||n==L||n==f||e.push(n);return e},tt=function(t){for(var n,r=t===z,e=P(r?j:E(t)),o=[],u=0;e.length>u;)!i(k,n=e[u++])||r&&!i(z,n)||o.push(k[n]);return o};G||(M=function(){if(this instanceof M)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),n=function(r){this===z&&n.call(j,r),i(this,L)&&i(this[L],t)&&(this[L][t]=!1),V(this,t,b(1,r))};return o&&Y&&V(z,t,{configurable:!0,set:n}),X(t)},a(M[U],"toString",function(){return this._k}),S.f=Q,T.f=q,r(50).f=x.f=$,r(44).f=J,r(43).f=tt,o&&!r(28)&&a(z,"propertyIsEnumerable",J,!0),v.f=function(t){return X(p(t))}),u(u.G+u.W+u.F*!G,{Symbol:M});for(var nt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),rt=0;nt.length>rt;)p(nt[rt++]);for(var nt=R(p.store),rt=0;nt.length>rt;)d(nt[rt++]);u(u.S+u.F*!G,"Symbol",{"for":function(t){return i(D,t+="")?D[t]:D[t]=M(t)},keyFor:function(t){if(H(t))return g(D,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){Y=!0},useSimple:function(){Y=!1}}),u(u.S+u.F*!G,"Object",{create:Z,defineProperty:q,defineProperties:K,getOwnPropertyDescriptor:Q,getOwnPropertyNames:$,getOwnPropertySymbols:tt}),F&&u(u.S+u.F*(!G||c(function(){var t=M();return"[null]"!=B([t])||"{}"!=B({a:t})||"{}"!=B(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!H(t)){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);return n=e[1],"function"==typeof n&&(r=n),!r&&m(n)||(n=function(t,n){if(r&&(n=r.call(this,t,n)),!H(n))return n}),e[1]=n,B.apply(F,e)}}}),M[U][N]||r(10)(M[U],N,M[U].valueOf),l(M,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n,r){t.exports=!r(7)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n){t.exports=function(t){try{return!!t()}catch(n){return!0}}},function(t,n,r){var e=r(4),i=r(9),o=r(10),u=r(18),a=r(20),f="prototype",c=function(t,n,r){var s,l,h,p,v=t&c.F,d=t&c.G,g=t&c.S,y=t&c.P,m=t&c.B,_=d?e:g?e[n]||(e[n]={}):(e[n]||{})[f],E=d?i:i[n]||(i[n]={}),w=E[f]||(E[f]={});d&&(r=n);for(s in r)l=!v&&_&&void 0!==_[s],h=(l?_:r)[s],p=m&&l?a(h,e):y&&"function"==typeof h?a(Function.call,h):h,_&&u(_,s,h,t&c.U),E[s]!=h&&o(E,s,p),y&&w[s]!=h&&(w[s]=h)};e.core=i,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,n){var r=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=r)},function(t,n,r){var e=r(11),i=r(17);t.exports=r(6)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var e=r(12),i=r(14),o=r(16),u=Object.defineProperty;n.f=r(6)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(a){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){var e=r(13);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n,r){t.exports=!r(6)&&!r(7)(function(){return 7!=Object.defineProperty(r(15)("div"),"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(13),i=r(4).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n,r){var e=r(13);t.exports=function(t,n){if(!e(t))return t;var r,i;if(n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;if("function"==typeof(r=t.valueOf)&&!e(i=r.call(t)))return i;if(!n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n,r){var e=r(4),i=r(10),o=r(5),u=r(19)("src"),a="toString",f=Function[a],c=(""+f).split(a);r(9).inspectSource=function(t){return f.call(t)},(t.exports=function(t,n,r,a){var f="function"==typeof r;f&&(o(r,"name")||i(r,"name",n)),t[n]!==r&&(f&&(o(r,u)||i(r,u,t[n]?""+t[n]:c.join(String(n)))),t===e?t[n]=r:a?t[n]?t[n]=r:i(t,n,r):(delete t[n],i(t,n,r)))})(Function.prototype,a,function(){return"function"==typeof this&&this[u]||f.call(this)})},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n,r){var e=r(21);t.exports=function(t,n,r){if(e(t),void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 2:return function(r,e){return t.call(n,r,e)};case 3:return function(r,e,i){return t.call(n,r,e,i)}}return function(){return t.apply(n,arguments)}}},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n,r){var e=r(19)("meta"),i=r(13),o=r(5),u=r(11).f,a=0,f=Object.isExtensible||function(){return!0},c=!r(7)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++a,w:{}}})},l=function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},h=function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},p=function(t){return c&&v.NEED&&f(t)&&!o(t,e)&&s(t),t},v=t.exports={KEY:e,NEED:!1,fastKey:l,getWeak:h,onFreeze:p}},function(t,n,r){var e=r(4),i="__core-js_shared__",o=e[i]||(e[i]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,n,r){var e=r(11).f,i=r(5),o=r(25)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var e=r(23)("wks"),i=r(19),o=r(4).Symbol,u="function"==typeof o,a=t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))};a.store=e},function(t,n,r){n.f=r(25)},function(t,n,r){var e=r(4),i=r(9),o=r(28),u=r(26),a=r(11).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||a(n,t,{value:u.f(t)})}},function(t,n){t.exports=!1},function(t,n,r){var e=r(30),i=r(32);t.exports=function(t,n){for(var r,o=i(t),u=e(o),a=u.length,f=0;a>f;)if(o[r=u[f++]]===n)return r}},function(t,n,r){var e=r(31),i=r(41);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n,r){var e=r(5),i=r(32),o=r(36)(!1),u=r(40)("IE_PROTO");t.exports=function(t,n){var r,a=i(t),f=0,c=[];for(r in a)r!=u&&e(a,r)&&c.push(r);for(;n.length>f;)e(a,r=n[f++])&&(~o(c,r)||c.push(r));return c}},function(t,n,r){var e=r(33),i=r(35);t.exports=function(t){return e(i(t))}},function(t,n,r){var e=r(34);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,n,r){var e=r(32),i=r(37),o=r(39);t.exports=function(t){return function(n,r,u){var a,f=e(n),c=i(f.length),s=o(u,c);if(t&&r!=r){for(;c>s;)if(a=f[s++],a!=a)return!0}else for(;c>s;s++)if((t||s in f)&&f[s]===r)return t||s||0;return!t&&-1}}},function(t,n,r){var e=r(38),i=Math.min;t.exports=function(t){return t>0?i(e(t),9007199254740991):0}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?e:r)(t)}},function(t,n,r){var e=r(38),i=Math.max,o=Math.min;t.exports=function(t,n){return t=e(t),t<0?i(t+n,0):o(t,n)}},function(t,n,r){var e=r(23)("keys"),i=r(19);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n,r){var e=r(30),i=r(43),o=r(44);t.exports=function(t){var n=e(t),r=i.f;if(r)for(var u,a=r(t),f=o.f,c=0;a.length>c;)f.call(t,u=a[c++])&&n.push(u);return n}},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(34);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){var e=r(12),i=r(47),o=r(41),u=r(40)("IE_PROTO"),a=function(){},f="prototype",c=function(){var t,n=r(15)("iframe"),e=o.length,i="<",u=">";for(n.style.display="none",r(48).appendChild(n),n.src="javascript:",t=n.contentWindow.document,t.open(),t.write(i+"script"+u+"document.F=Object"+i+"/script"+u),t.close(),c=t.F;e--;)delete c[f][o[e]];return c()};t.exports=Object.create||function(t,n){var r;return null!==t?(a[f]=e(t),r=new a,a[f]=null,r[u]=t):r=c(),void 0===n?r:i(r,n)}},function(t,n,r){var e=r(11),i=r(12),o=r(30);t.exports=r(6)?Object.defineProperties:function(t,n){i(t);for(var r,u=o(n),a=u.length,f=0;a>f;)e.f(t,r=u[f++],n[r]);return t}},function(t,n,r){t.exports=r(4).document&&document.documentElement},function(t,n,r){var e=r(32),i=r(50).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],a=function(t){try{return i(t)}catch(n){return u.slice()}};t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?a(t):i(e(t))}},function(t,n,r){var e=r(31),i=r(41).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n,r){var e=r(44),i=r(17),o=r(32),u=r(16),a=r(5),f=r(14),c=Object.getOwnPropertyDescriptor;n.f=r(6)?c:function(t,n){if(t=o(t),n=u(n,!0),f)try{return c(t,n)}catch(r){}if(a(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(8);e(e.S,"Object",{create:r(46)})},function(t,n,r){var e=r(8);e(e.S+e.F*!r(6),"Object",{defineProperty:r(11).f})},function(t,n,r){var e=r(8);e(e.S+e.F*!r(6),"Object",{defineProperties:r(47)})},function(t,n,r){var e=r(32),i=r(51).f;r(56)("getOwnPropertyDescriptor",function(){return function(t,n){return i(e(t),n)}})},function(t,n,r){var e=r(8),i=r(9),o=r(7);t.exports=function(t,n){var r=(i.Object||{})[t]||Object[t],u={};u[t]=n(r),e(e.S+e.F*o(function(){r(1)}),"Object",u)}},function(t,n,r){var e=r(58),i=r(59);r(56)("getPrototypeOf",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(35);t.exports=function(t){return Object(e(t))}},function(t,n,r){var e=r(5),i=r(58),o=r(40)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n,r){var e=r(58),i=r(30);r(56)("keys",function(){return function(t){return i(e(t))}})},function(t,n,r){r(56)("getOwnPropertyNames",function(){return r(49).f})},function(t,n,r){var e=r(13),i=r(22).onFreeze;r(56)("freeze",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(13),i=r(22).onFreeze;r(56)("seal",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(13),i=r(22).onFreeze;r(56)("preventExtensions",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(13);r(56)("isFrozen",function(t){return function(n){return!e(n)||!!t&&t(n)}})},function(t,n,r){var e=r(13);r(56)("isSealed",function(t){return function(n){return!e(n)||!!t&&t(n)}})},function(t,n,r){var e=r(13);r(56)("isExtensible",function(t){return function(n){return!!e(n)&&(!t||t(n))}})},function(t,n,r){var e=r(8);e(e.S+e.F,"Object",{assign:r(69)})},function(t,n,r){"use strict";var e=r(30),i=r(43),o=r(44),u=r(58),a=r(33),f=Object.assign;t.exports=!f||r(7)(function(){var t={},n={},r=Symbol(),e="abcdefghijklmnopqrst";return t[r]=7,e.split("").forEach(function(t){n[t]=t}),7!=f({},t)[r]||Object.keys(f({},n)).join("")!=e})?function(t,n){for(var r=u(t),f=arguments.length,c=1,s=i.f,l=o.f;f>c;)for(var h,p=a(arguments[c++]),v=s?e(p).concat(s(p)):e(p),d=v.length,g=0;d>g;)l.call(p,h=v[g++])&&(r[h]=p[h]);return r}:f},function(t,n,r){var e=r(8);e(e.S,"Object",{is:r(71)})},function(t,n){t.exports=Object.is||function(t,n){return t===n?0!==t||1/t===1/n:t!=t&&n!=n}},function(t,n,r){var e=r(8);e(e.S,"Object",{setPrototypeOf:r(73).set})},function(t,n,r){var e=r(13),i=r(12),o=function(t,n){if(i(t),!e(n)&&null!==n)throw TypeError(n+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,n,e){try{e=r(20)(Function.call,r(51).f(Object.prototype,"__proto__").set,2),e(t,[]),n=!(t instanceof Array)}catch(i){n=!0}return function(t,r){return o(t,r),n?t.__proto__=r:e(t,r),t}}({},!1):void 0),check:o}},function(t,n,r){"use strict";var e=r(75),i={};i[r(25)("toStringTag")]="z",i+""!="[object z]"&&r(18)(Object.prototype,"toString",function(){return"[object "+e(this)+"]"},!0)},function(t,n,r){var e=r(34),i=r(25)("toStringTag"),o="Arguments"==e(function(){return arguments}()),u=function(t,n){try{return t[n]}catch(r){}};t.exports=function(t){var n,r,a;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=u(n=Object(t),i))?r:o?e(n):"Object"==(a=e(n))&&"function"==typeof n.callee?"Arguments":a}},function(t,n,r){var e=r(8);e(e.P,"Function",{bind:r(77)})},function(t,n,r){"use strict";var e=r(21),i=r(13),o=r(78),u=[].slice,a={},f=function(t,n,r){if(!(n in a)){for(var e=[],i=0;i>>0||(u.test(r)?16:10))}:e},function(t,n,r){var e=r(8),i=r(35),o=r(7),u=r(84),a="["+u+"]",f="​…",c=RegExp("^"+a+a+"*"),s=RegExp(a+a+"*$"),l=function(t,n,r){var i={},a=o(function(){return!!u[t]()||f[t]()!=f}),c=i[t]=a?n(h):u[t];r&&(i[r]=c),e(e.P+e.F*a,"String",i)},h=l.trim=function(t,n){return t=String(i(t)),1&n&&(t=t.replace(c,"")),2&n&&(t=t.replace(s,"")),t};t.exports=l},function(t,n){t.exports="\t\n\x0B\f\r   ᠎              \u2028\u2029\ufeff"},function(t,n,r){var e=r(8),i=r(86);e(e.G+e.F*(parseFloat!=i),{parseFloat:i})},function(t,n,r){var e=r(4).parseFloat,i=r(83).trim;t.exports=1/e(r(84)+"-0")!==-(1/0)?function(t){var n=i(String(t),3),r=e(n);return 0===r&&"-"==n.charAt(0)?-0:r}:e},function(t,n,r){"use strict";var e=r(4),i=r(5),o=r(34),u=r(88),a=r(16),f=r(7),c=r(50).f,s=r(51).f,l=r(11).f,h=r(83).trim,p="Number",v=e[p],d=v,g=v.prototype,y=o(r(46)(g))==p,m="trim"in String.prototype,_=function(t){var n=a(t,!1);if("string"==typeof n&&n.length>2){n=m?n.trim():h(n,3);var r,e,i,o=n.charCodeAt(0);if(43===o||45===o){if(r=n.charCodeAt(2),88===r||120===r)return NaN}else if(48===o){switch(n.charCodeAt(1)){case 66:case 98:e=2,i=49;break;case 79:case 111:e=8,i=55;break;default:return+n}for(var u,f=n.slice(2),c=0,s=f.length;ci)return NaN;return parseInt(f,e)}}return+n};if(!v(" 0o1")||!v("0b1")||v("+0x1")){v=function(t){var n=arguments.length<1?0:t,r=this;return r instanceof v&&(y?f(function(){g.valueOf.call(r)}):o(r)!=p)?u(new d(_(n)),r,v):_(n)};for(var E,w=r(6)?c(d):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),b=0;w.length>b;b++)i(d,E=w[b])&&!i(v,E)&&l(v,E,s(d,E));v.prototype=g,g.constructor=v,r(18)(e,p,v)}},function(t,n,r){var e=r(13),i=r(73).set;t.exports=function(t,n,r){var o,u=n.constructor;return u!==r&&"function"==typeof u&&(o=u.prototype)!==r.prototype&&e(o)&&i&&i(t,o),t}},function(t,n,r){"use strict";var e=r(8),i=r(38),o=r(90),u=r(91),a=1..toFixed,f=Math.floor,c=[0,0,0,0,0,0],s="Number.toFixed: incorrect invocation!",l="0",h=function(t,n){for(var r=-1,e=n;++r<6;)e+=t*c[r],c[r]=e%1e7,e=f(e/1e7)},p=function(t){for(var n=6,r=0;--n>=0;)r+=c[n],c[n]=f(r/t),r=r%t*1e7},v=function(){for(var t=6,n="";--t>=0;)if(""!==n||0===t||0!==c[t]){var r=String(c[t]);n=""===n?r:n+u.call(l,7-r.length)+r}return n},d=function(t,n,r){return 0===n?r:n%2===1?d(t,n-1,r*t):d(t*t,n/2,r)},g=function(t){for(var n=0,r=t;r>=4096;)n+=12,r/=4096;for(;r>=2;)n+=1,r/=2;return n};e(e.P+e.F*(!!a&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!r(7)(function(){a.call({})})),"Number",{toFixed:function(t){var n,r,e,a,f=o(this,s),c=i(t),y="",m=l;if(c<0||c>20)throw RangeError(s);if(f!=f)return"NaN";if(f<=-1e21||f>=1e21)return String(f);if(f<0&&(y="-",f=-f),f>1e-21)if(n=g(f*d(2,69,1))-69,r=n<0?f*d(2,-n,1):f/d(2,n,1),r*=4503599627370496,n=52-n,n>0){for(h(0,r),e=c;e>=7;)h(1e7,0),e-=7;for(h(d(10,e,1),0),e=n-1;e>=23;)p(1<<23),e-=23;p(1<0?(a=m.length,m=y+(a<=c?"0."+u.call(l,c-a)+m:m.slice(0,a-c)+"."+m.slice(a-c))):m=y+m,m}})},function(t,n,r){var e=r(34);t.exports=function(t,n){if("number"!=typeof t&&"Number"!=e(t))throw TypeError(n);return+t}},function(t,n,r){"use strict";var e=r(38),i=r(35);t.exports=function(t){var n=String(i(this)),r="",o=e(t);if(o<0||o==1/0)throw RangeError("Count can't be negative");for(;o>0;(o>>>=1)&&(n+=n))1&o&&(r+=n);return r}},function(t,n,r){"use strict";var e=r(8),i=r(7),o=r(90),u=1..toPrecision;e(e.P+e.F*(i(function(){return"1"!==u.call(1,void 0)})||!i(function(){u.call({})})),"Number",{toPrecision:function(t){var n=o(this,"Number#toPrecision: incorrect invocation!");return void 0===t?u.call(n):u.call(n,t)}})},function(t,n,r){var e=r(8);e(e.S,"Number",{EPSILON:Math.pow(2,-52)})},function(t,n,r){var e=r(8),i=r(4).isFinite;e(e.S,"Number",{isFinite:function(t){return"number"==typeof t&&i(t)}})},function(t,n,r){var e=r(8);e(e.S,"Number",{isInteger:r(96)})},function(t,n,r){var e=r(13),i=Math.floor;t.exports=function(t){return!e(t)&&isFinite(t)&&i(t)===t}},function(t,n,r){var e=r(8);e(e.S,"Number",{isNaN:function(t){return t!=t}})},function(t,n,r){var e=r(8),i=r(96),o=Math.abs;e(e.S,"Number",{isSafeInteger:function(t){return i(t)&&o(t)<=9007199254740991}})},function(t,n,r){var e=r(8);e(e.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},function(t,n,r){var e=r(8);e(e.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},function(t,n,r){var e=r(8),i=r(86);e(e.S+e.F*(Number.parseFloat!=i),"Number",{parseFloat:i})},function(t,n,r){var e=r(8),i=r(82);e(e.S+e.F*(Number.parseInt!=i),"Number",{parseInt:i})},function(t,n,r){var e=r(8),i=r(104),o=Math.sqrt,u=Math.acosh;e(e.S+e.F*!(u&&710==Math.floor(u(Number.MAX_VALUE))&&u(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:i(t-1+o(t-1)*o(t+1))}})},function(t,n){t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},function(t,n,r){function e(t){return isFinite(t=+t)&&0!=t?t<0?-e(-t):Math.log(t+Math.sqrt(t*t+1)):t}var i=r(8),o=Math.asinh;i(i.S+i.F*!(o&&1/o(0)>0),"Math",{asinh:e})},function(t,n,r){var e=r(8),i=Math.atanh;e(e.S+e.F*!(i&&1/i(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},function(t,n,r){var e=r(8),i=r(108);e(e.S,"Math",{cbrt:function(t){return i(t=+t)*Math.pow(Math.abs(t),1/3)}})},function(t,n){t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},function(t,n,r){var e=r(8);e(e.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},function(t,n,r){var e=r(8),i=Math.exp;e(e.S,"Math",{cosh:function(t){return(i(t=+t)+i(-t))/2}})},function(t,n,r){var e=r(8),i=r(112);e(e.S+e.F*(i!=Math.expm1),"Math",{expm1:i})},function(t,n){var r=Math.expm1;t.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||r(-2e-17)!=-2e-17?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:r},function(t,n,r){var e=r(8),i=r(108),o=Math.pow,u=o(2,-52),a=o(2,-23),f=o(2,127)*(2-a),c=o(2,-126),s=function(t){return t+1/u-1/u};e(e.S,"Math",{fround:function(t){var n,r,e=Math.abs(t),o=i(t);return ef||r!=r?o*(1/0):o*r)}})},function(t,n,r){var e=r(8),i=Math.abs;e(e.S,"Math",{hypot:function(t,n){for(var r,e,o=0,u=0,a=arguments.length,f=0;u0?(e=r/f,o+=e*e):o+=r;return f===1/0?1/0:f*Math.sqrt(o)}})},function(t,n,r){var e=r(8),i=Math.imul;e(e.S+e.F*r(7)(function(){return i(4294967295,5)!=-5||2!=i.length}),"Math",{imul:function(t,n){var r=65535,e=+t,i=+n,o=r&e,u=r&i;return 0|o*u+((r&e>>>16)*u+o*(r&i>>>16)<<16>>>0)}})},function(t,n,r){var e=r(8);e(e.S,"Math",{log10:function(t){return Math.log(t)/Math.LN10}})},function(t,n,r){var e=r(8);e(e.S,"Math",{log1p:r(104)})},function(t,n,r){var e=r(8);e(e.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},function(t,n,r){var e=r(8);e(e.S,"Math",{sign:r(108)})},function(t,n,r){var e=r(8),i=r(112),o=Math.exp;e(e.S+e.F*r(7)(function(){return!Math.sinh(-2e-17)!=-2e-17}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(i(t)-i(-t))/2:(o(t-1)-o(-t-1))*(Math.E/2)}})},function(t,n,r){var e=r(8),i=r(112),o=Math.exp;e(e.S,"Math",{tanh:function(t){var n=i(t=+t),r=i(-t);return n==1/0?1:r==1/0?-1:(n-r)/(o(t)+o(-t))}})},function(t,n,r){var e=r(8);e(e.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},function(t,n,r){var e=r(8),i=r(39),o=String.fromCharCode,u=String.fromCodePoint;e(e.S+e.F*(!!u&&1!=u.length),"String",{fromCodePoint:function(t){for(var n,r=[],e=arguments.length,u=0;e>u;){if(n=+arguments[u++],i(n,1114111)!==n)throw RangeError(n+" is not a valid code point");r.push(n<65536?o(n):o(((n-=65536)>>10)+55296,n%1024+56320))}return r.join("")}})},function(t,n,r){var e=r(8),i=r(32),o=r(37);e(e.S,"String",{raw:function(t){for(var n=i(t.raw),r=o(n.length),e=arguments.length,u=[],a=0;r>a;)u.push(String(n[a++])),a=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){var e=r(38),i=r(35);t.exports=function(t){return function(n,r){var o,u,a=String(i(n)),f=e(r),c=a.length;return f<0||f>=c?t?"":void 0:(o=a.charCodeAt(f),o<55296||o>56319||f+1===c||(u=a.charCodeAt(f+1))<56320||u>57343?t?a.charAt(f):o:t?a.slice(f,f+2):(o-55296<<10)+(u-56320)+65536)}}},function(t,n,r){"use strict";var e=r(28),i=r(8),o=r(18),u=r(10),a=r(5),f=r(129),c=r(130),s=r(24),l=r(59),h=r(25)("iterator"),p=!([].keys&&"next"in[].keys()),v="@@iterator",d="keys",g="values",y=function(){return this};t.exports=function(t,n,r,m,_,E,w){c(r,n,m);var b,A,x,S=function(t){if(!p&&t in O)return O[t];switch(t){case d:return function(){return new r(this,t)};case g:return function(){return new r(this,t)}}return function(){return new r(this,t)}},T=n+" Iterator",R=_==g,I=!1,O=t.prototype,P=O[h]||O[v]||_&&O[_],M=P||S(_),F=_?R?S("entries"):M:void 0,B="Array"==n?O.entries||P:P;if(B&&(x=l(B.call(new t)),x!==Object.prototype&&(s(x,T,!0),e||a(x,h)||u(x,h,y))),R&&P&&P.name!==g&&(I=!0,M=function(){return P.call(this)}),e&&!w||!p&&!I&&O[h]||u(O,h,M),f[n]=M,f[T]=y,_)if(b={values:R?M:S(g),keys:E?M:S(d),entries:F},w)for(A in b)A in O||o(O,A,b[A]);else i(i.P+i.F*(p||I),n,b);return b}},function(t,n){t.exports={}},function(t,n,r){"use strict";var e=r(46),i=r(17),o=r(24),u={};r(10)(u,r(25)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n,r){"use strict";var e=r(8),i=r(127)(!1);e(e.P,"String",{codePointAt:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(8),i=r(37),o=r(133),u="endsWith",a=""[u];e(e.P+e.F*r(135)(u),"String",{endsWith:function(t){var n=o(this,t,u),r=arguments.length>1?arguments[1]:void 0,e=i(n.length),f=void 0===r?e:Math.min(i(r),e),c=String(t);return a?a.call(n,c,f):n.slice(f-c.length,f)===c}})},function(t,n,r){var e=r(134),i=r(35);t.exports=function(t,n,r){if(e(n))throw TypeError("String#"+r+" doesn't accept regex!");return String(i(t))}},function(t,n,r){var e=r(13),i=r(34),o=r(25)("match");t.exports=function(t){var n;return e(t)&&(void 0!==(n=t[o])?!!n:"RegExp"==i(t))}},function(t,n,r){var e=r(25)("match");t.exports=function(t){var n=/./;try{"/./"[t](n)}catch(r){try{return n[e]=!1,!"/./"[t](n)}catch(i){}}return!0}},function(t,n,r){"use strict";var e=r(8),i=r(133),o="includes";e(e.P+e.F*r(135)(o),"String",{includes:function(t){return!!~i(this,t,o).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},function(t,n,r){var e=r(8);e(e.P,"String",{repeat:r(91)})},function(t,n,r){"use strict";var e=r(8),i=r(37),o=r(133),u="startsWith",a=""[u];e(e.P+e.F*r(135)(u),"String",{startsWith:function(t){var n=o(this,t,u),r=i(Math.min(arguments.length>1?arguments[1]:void 0,n.length)),e=String(t);return a?a.call(n,e,r):n.slice(r,r+e.length)===e}})},function(t,n,r){"use strict";r(140)("anchor",function(t){return function(n){return t(this,"a","name",n)}})},function(t,n,r){var e=r(8),i=r(7),o=r(35),u=/"/g,a=function(t,n,r,e){var i=String(o(t)),a="<"+n;return""!==r&&(a+=" "+r+'="'+String(e).replace(u,""")+'"'),a+">"+i+""};t.exports=function(t,n){var r={};r[t]=n(a),e(e.P+e.F*i(function(){var n=""[t]('"');return n!==n.toLowerCase()||n.split('"').length>3}),"String",r)}},function(t,n,r){"use strict";r(140)("big",function(t){return function(){return t(this,"big","","")}})},function(t,n,r){"use strict";r(140)("blink",function(t){return function(){return t(this,"blink","","")}})},function(t,n,r){"use strict";r(140)("bold",function(t){return function(){return t(this,"b","","")}})},function(t,n,r){"use strict";r(140)("fixed",function(t){return function(){return t(this,"tt","","")}})},function(t,n,r){"use strict";r(140)("fontcolor",function(t){return function(n){return t(this,"font","color",n)}})},function(t,n,r){"use strict";r(140)("fontsize",function(t){return function(n){return t(this,"font","size",n)}})},function(t,n,r){"use strict";r(140)("italics",function(t){return function(){return t(this,"i","","")}})},function(t,n,r){"use strict";r(140)("link",function(t){return function(n){return t(this,"a","href",n)}})},function(t,n,r){"use strict";r(140)("small",function(t){return function(){return t(this,"small","","")}})},function(t,n,r){"use strict";r(140)("strike",function(t){return function(){return t(this,"strike","","")}})},function(t,n,r){"use strict";r(140)("sub",function(t){return function(){return t(this,"sub","","")}})},function(t,n,r){"use strict";r(140)("sup",function(t){return function(){return t(this,"sup","","")}})},function(t,n,r){var e=r(8);e(e.S,"Date",{now:function(){return(new Date).getTime()}})},function(t,n,r){"use strict";var e=r(8),i=r(58),o=r(16);e(e.P+e.F*r(7)(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(t){var n=i(this),r=o(n);return"number"!=typeof r||isFinite(r)?n.toISOString():null}})},function(t,n,r){"use strict";var e=r(8),i=r(7),o=Date.prototype.getTime,u=function(t){return t>9?t:"0"+t};e(e.P+e.F*(i(function(){return"0385-07-25T07:06:39.999Z"!=new Date(-5e13-1).toISOString()})||!i(function(){new Date(NaN).toISOString()})),"Date",{toISOString:function(){if(!isFinite(o.call(this)))throw RangeError("Invalid time value");var t=this,n=t.getUTCFullYear(),r=t.getUTCMilliseconds(),e=n<0?"-":n>9999?"+":""; -return e+("00000"+Math.abs(n)).slice(e?-6:-4)+"-"+u(t.getUTCMonth()+1)+"-"+u(t.getUTCDate())+"T"+u(t.getUTCHours())+":"+u(t.getUTCMinutes())+":"+u(t.getUTCSeconds())+"."+(r>99?r:"0"+u(r))+"Z"}})},function(t,n,r){var e=Date.prototype,i="Invalid Date",o="toString",u=e[o],a=e.getTime;new Date(NaN)+""!=i&&r(18)(e,o,function(){var t=a.call(this);return t===t?u.call(this):i})},function(t,n,r){var e=r(25)("toPrimitive"),i=Date.prototype;e in i||r(10)(i,e,r(158))},function(t,n,r){"use strict";var e=r(12),i=r(16),o="number";t.exports=function(t){if("string"!==t&&t!==o&&"default"!==t)throw TypeError("Incorrect hint");return i(e(this),t!=o)}},function(t,n,r){var e=r(8);e(e.S,"Array",{isArray:r(45)})},function(t,n,r){"use strict";var e=r(20),i=r(8),o=r(58),u=r(161),a=r(162),f=r(37),c=r(163),s=r(164);i(i.S+i.F*!r(165)(function(t){Array.from(t)}),"Array",{from:function(t){var n,r,i,l,h=o(t),p="function"==typeof this?this:Array,v=arguments.length,d=v>1?arguments[1]:void 0,g=void 0!==d,y=0,m=s(h);if(g&&(d=e(d,v>2?arguments[2]:void 0,2)),void 0==m||p==Array&&a(m))for(n=f(h.length),r=new p(n);n>y;y++)c(r,y,g?d(h[y],y):h[y]);else for(l=m.call(h),r=new p;!(i=l.next()).done;y++)c(r,y,g?u(l,d,[i.value,y],!0):i.value);return r.length=y,r}})},function(t,n,r){var e=r(12);t.exports=function(t,n,r,i){try{return i?n(e(r)[0],r[1]):n(r)}catch(o){var u=t["return"];throw void 0!==u&&e(u.call(t)),o}}},function(t,n,r){var e=r(129),i=r(25)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(e.Array===t||o[i]===t)}},function(t,n,r){"use strict";var e=r(11),i=r(17);t.exports=function(t,n,r){n in t?e.f(t,n,i(0,r)):t[n]=r}},function(t,n,r){var e=r(75),i=r(25)("iterator"),o=r(129);t.exports=r(9).getIteratorMethod=function(t){if(void 0!=t)return t[i]||t["@@iterator"]||o[e(t)]}},function(t,n,r){var e=r(25)("iterator"),i=!1;try{var o=[7][e]();o["return"]=function(){i=!0},Array.from(o,function(){throw 2})}catch(u){}t.exports=function(t,n){if(!n&&!i)return!1;var r=!1;try{var o=[7],u=o[e]();u.next=function(){return{done:r=!0}},o[e]=function(){return u},t(o)}catch(a){}return r}},function(t,n,r){"use strict";var e=r(8),i=r(163);e(e.S+e.F*r(7)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,n=arguments.length,r=new("function"==typeof this?this:Array)(n);n>t;)i(r,t,arguments[t++]);return r.length=n,r}})},function(t,n,r){"use strict";var e=r(8),i=r(32),o=[].join;e(e.P+e.F*(r(33)!=Object||!r(168)(o)),"Array",{join:function(t){return o.call(i(this),void 0===t?",":t)}})},function(t,n,r){var e=r(7);t.exports=function(t,n){return!!t&&e(function(){n?t.call(null,function(){},1):t.call(null)})}},function(t,n,r){"use strict";var e=r(8),i=r(48),o=r(34),u=r(39),a=r(37),f=[].slice;e(e.P+e.F*r(7)(function(){i&&f.call(i)}),"Array",{slice:function(t,n){var r=a(this.length),e=o(this);if(n=void 0===n?r:n,"Array"==e)return f.call(this,t,n);for(var i=u(t,r),c=u(n,r),s=a(c-i),l=Array(s),h=0;hw;w++)if((h||w in m)&&(d=m[w],g=_(d,w,y),t))if(r)b[w]=g;else if(g)switch(t){case 3:return!0;case 5:return d;case 6:return w;case 2:b.push(d)}else if(s)return!1;return l?-1:c||s?s:b}}},function(t,n,r){var e=r(174);t.exports=function(t,n){return new(e(t))(n)}},function(t,n,r){var e=r(13),i=r(45),o=r(25)("species");t.exports=function(t){var n;return i(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!i(n.prototype)||(n=void 0),e(n)&&(n=n[o],null===n&&(n=void 0))),void 0===n?Array:n}},function(t,n,r){"use strict";var e=r(8),i=r(172)(1);e(e.P+e.F*!r(168)([].map,!0),"Array",{map:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(8),i=r(172)(2);e(e.P+e.F*!r(168)([].filter,!0),"Array",{filter:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(8),i=r(172)(3);e(e.P+e.F*!r(168)([].some,!0),"Array",{some:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(8),i=r(172)(4);e(e.P+e.F*!r(168)([].every,!0),"Array",{every:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(8),i=r(180);e(e.P+e.F*!r(168)([].reduce,!0),"Array",{reduce:function(t){return i(this,t,arguments.length,arguments[1],!1)}})},function(t,n,r){var e=r(21),i=r(58),o=r(33),u=r(37);t.exports=function(t,n,r,a,f){e(n);var c=i(t),s=o(c),l=u(c.length),h=f?l-1:0,p=f?-1:1;if(r<2)for(;;){if(h in s){a=s[h],h+=p;break}if(h+=p,f?h<0:l<=h)throw TypeError("Reduce of empty array with no initial value")}for(;f?h>=0:l>h;h+=p)h in s&&(a=n(a,s[h],h,c));return a}},function(t,n,r){"use strict";var e=r(8),i=r(180);e(e.P+e.F*!r(168)([].reduceRight,!0),"Array",{reduceRight:function(t){return i(this,t,arguments.length,arguments[1],!0)}})},function(t,n,r){"use strict";var e=r(8),i=r(36)(!1),o=[].indexOf,u=!!o&&1/[1].indexOf(1,-0)<0;e(e.P+e.F*(u||!r(168)(o)),"Array",{indexOf:function(t){return u?o.apply(this,arguments)||0:i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(8),i=r(32),o=r(38),u=r(37),a=[].lastIndexOf,f=!!a&&1/[1].lastIndexOf(1,-0)<0;e(e.P+e.F*(f||!r(168)(a)),"Array",{lastIndexOf:function(t){if(f)return a.apply(this,arguments)||0;var n=i(this),r=u(n.length),e=r-1;for(arguments.length>1&&(e=Math.min(e,o(arguments[1]))),e<0&&(e=r+e);e>=0;e--)if(e in n&&n[e]===t)return e||0;return-1}})},function(t,n,r){var e=r(8);e(e.P,"Array",{copyWithin:r(185)}),r(186)("copyWithin")},function(t,n,r){"use strict";var e=r(58),i=r(39),o=r(37);t.exports=[].copyWithin||function(t,n){var r=e(this),u=o(r.length),a=i(t,u),f=i(n,u),c=arguments.length>2?arguments[2]:void 0,s=Math.min((void 0===c?u:i(c,u))-f,u-a),l=1;for(f0;)f in r?r[a]=r[f]:delete r[a],a+=l,f+=l;return r}},function(t,n,r){var e=r(25)("unscopables"),i=Array.prototype;void 0==i[e]&&r(10)(i,e,{}),t.exports=function(t){i[e][t]=!0}},function(t,n,r){var e=r(8);e(e.P,"Array",{fill:r(188)}),r(186)("fill")},function(t,n,r){"use strict";var e=r(58),i=r(39),o=r(37);t.exports=function(t){for(var n=e(this),r=o(n.length),u=arguments.length,a=i(u>1?arguments[1]:void 0,r),f=u>2?arguments[2]:void 0,c=void 0===f?r:i(f,r);c>a;)n[a++]=t;return n}},function(t,n,r){"use strict";var e=r(8),i=r(172)(5),o="find",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{find:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(186)(o)},function(t,n,r){"use strict";var e=r(8),i=r(172)(6),o="findIndex",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{findIndex:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(186)(o)},function(t,n,r){r(192)("Array")},function(t,n,r){"use strict";var e=r(4),i=r(11),o=r(6),u=r(25)("species");t.exports=function(t){var n=e[t];o&&n&&!n[u]&&i.f(n,u,{configurable:!0,get:function(){return this}})}},function(t,n,r){"use strict";var e=r(186),i=r(194),o=r(129),u=r(32);t.exports=r(128)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):"keys"==n?i(0,r):"values"==n?i(0,t[r]):i(0,[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n,r){var e=r(4),i=r(88),o=r(11).f,u=r(50).f,a=r(134),f=r(196),c=e.RegExp,s=c,l=c.prototype,h=/a/g,p=/a/g,v=new c(h)!==h;if(r(6)&&(!v||r(7)(function(){return p[r(25)("match")]=!1,c(h)!=h||c(p)==p||"/a/i"!=c(h,"i")}))){c=function(t,n){var r=this instanceof c,e=a(t),o=void 0===n;return!r&&e&&t.constructor===c&&o?t:i(v?new s(e&&!o?t.source:t,n):s((e=t instanceof c)?t.source:t,e&&o?f.call(t):n),r?this:l,c)};for(var d=(function(t){t in c||o(c,t,{configurable:!0,get:function(){return s[t]},set:function(n){s[t]=n}})}),g=u(s),y=0;g.length>y;)d(g[y++]);l.constructor=c,c.prototype=l,r(18)(e,"RegExp",c)}r(192)("RegExp")},function(t,n,r){"use strict";var e=r(12);t.exports=function(){var t=e(this),n="";return t.global&&(n+="g"),t.ignoreCase&&(n+="i"),t.multiline&&(n+="m"),t.unicode&&(n+="u"),t.sticky&&(n+="y"),n}},function(t,n,r){"use strict";r(198);var e=r(12),i=r(196),o=r(6),u="toString",a=/./[u],f=function(t){r(18)(RegExp.prototype,u,t,!0)};r(7)(function(){return"/a/b"!=a.call({source:"a",flags:"b"})})?f(function(){var t=e(this);return"/".concat(t.source,"/","flags"in t?t.flags:!o&&t instanceof RegExp?i.call(t):void 0)}):a.name!=u&&f(function(){return a.call(this)})},function(t,n,r){r(6)&&"g"!=/./g.flags&&r(11).f(RegExp.prototype,"flags",{configurable:!0,get:r(196)})},function(t,n,r){r(200)("match",1,function(t,n,r){return[function(r){"use strict";var e=t(this),i=void 0==r?void 0:r[n];return void 0!==i?i.call(r,e):new RegExp(r)[n](String(e))},r]})},function(t,n,r){"use strict";var e=r(10),i=r(18),o=r(7),u=r(35),a=r(25);t.exports=function(t,n,r){var f=a(t),c=r(u,f,""[t]),s=c[0],l=c[1];o(function(){var n={};return n[f]=function(){return 7},7!=""[t](n)})&&(i(String.prototype,t,s),e(RegExp.prototype,f,2==n?function(t,n){return l.call(t,this,n)}:function(t){return l.call(t,this)}))}},function(t,n,r){r(200)("replace",2,function(t,n,r){return[function(e,i){"use strict";var o=t(this),u=void 0==e?void 0:e[n];return void 0!==u?u.call(e,o,i):r.call(String(o),e,i)},r]})},function(t,n,r){r(200)("search",1,function(t,n,r){return[function(r){"use strict";var e=t(this),i=void 0==r?void 0:r[n];return void 0!==i?i.call(r,e):new RegExp(r)[n](String(e))},r]})},function(t,n,r){r(200)("split",2,function(t,n,e){"use strict";var i=r(134),o=e,u=[].push,a="split",f="length",c="lastIndex";if("c"=="abbc"[a](/(b)*/)[1]||4!="test"[a](/(?:)/,-1)[f]||2!="ab"[a](/(?:ab)*/)[f]||4!="."[a](/(.?)(.?)/)[f]||"."[a](/()()/)[f]>1||""[a](/.?/)[f]){var s=void 0===/()??/.exec("")[1];e=function(t,n){var r=String(this);if(void 0===t&&0===n)return[];if(!i(t))return o.call(r,t,n);var e,a,l,h,p,v=[],d=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),g=0,y=void 0===n?4294967295:n>>>0,m=new RegExp(t.source,d+"g");for(s||(e=new RegExp("^"+m.source+"$(?!\\s)",d));(a=m.exec(r))&&(l=a.index+a[0][f],!(l>g&&(v.push(r.slice(g,a.index)),!s&&a[f]>1&&a[0].replace(e,function(){for(p=1;p1&&a.index=y)));)m[c]===a.index&&m[c]++;return g===r[f]?!h&&m.test("")||v.push(""):v.push(r.slice(g)),v[f]>y?v.slice(0,y):v}}else"0"[a](void 0,0)[f]&&(e=function(t,n){return void 0===t&&0===n?[]:o.call(this,t,n)});return[function(r,i){var o=t(this),u=void 0==r?void 0:r[n];return void 0!==u?u.call(r,o,i):e.call(String(o),r,i)},e]})},function(t,n,r){"use strict";var e,i,o,u=r(28),a=r(4),f=r(20),c=r(75),s=r(8),l=r(13),h=r(21),p=r(205),v=r(206),d=r(207),g=r(208).set,y=r(209)(),m="Promise",_=a.TypeError,E=a.process,w=a[m],E=a.process,b="process"==c(E),A=function(){},x=!!function(){try{var t=w.resolve(1),n=(t.constructor={})[r(25)("species")]=function(t){t(A,A)};return(b||"function"==typeof PromiseRejectionEvent)&&t.then(A)instanceof n}catch(e){}}(),S=function(t,n){return t===n||t===w&&n===o},T=function(t){var n;return!(!l(t)||"function"!=typeof(n=t.then))&&n},R=function(t){return S(w,t)?new I(t):new i(t)},I=i=function(t){var n,r;this.promise=new t(function(t,e){if(void 0!==n||void 0!==r)throw _("Bad Promise constructor");n=t,r=e}),this.resolve=h(n),this.reject=h(r)},O=function(t){try{t()}catch(n){return{error:n}}},P=function(t,n){if(!t._n){t._n=!0;var r=t._c;y(function(){for(var e=t._v,i=1==t._s,o=0,u=function(n){var r,o,u=i?n.ok:n.fail,a=n.resolve,f=n.reject,c=n.domain;try{u?(i||(2==t._h&&B(t),t._h=1),u===!0?r=e:(c&&c.enter(),r=u(e),c&&c.exit()),r===n.promise?f(_("Promise-chain cycle")):(o=T(r))?o.call(r,a,f):a(r)):f(e)}catch(s){f(s)}};r.length>o;)u(r[o++]);t._c=[],t._n=!1,n&&!t._h&&M(t)})}},M=function(t){g.call(a,function(){var n,r,e,i=t._v;if(F(t)&&(n=O(function(){b?E.emit("unhandledRejection",i,t):(r=a.onunhandledrejection)?r({promise:t,reason:i}):(e=a.console)&&e.error&&e.error("Unhandled promise rejection",i)}),t._h=b||F(t)?2:1),t._a=void 0,n)throw n.error})},F=function(t){if(1==t._h)return!1;for(var n,r=t._a||t._c,e=0;r.length>e;)if(n=r[e++],n.fail||!F(n.promise))return!1;return!0},B=function(t){g.call(a,function(){var n;b?E.emit("rejectionHandled",t):(n=a.onrejectionhandled)&&n({promise:t,reason:t._v})})},U=function(t){var n=this;n._d||(n._d=!0,n=n._w||n,n._v=t,n._s=2,n._a||(n._a=n._c.slice()),P(n,!0))},L=function(t){var n,r=this;if(!r._d){r._d=!0,r=r._w||r;try{if(r===t)throw _("Promise can't be resolved itself");(n=T(t))?y(function(){var e={_w:r,_d:!1};try{n.call(t,f(L,e,1),f(U,e,1))}catch(i){U.call(e,i)}}):(r._v=t,r._s=1,P(r,!1))}catch(e){U.call({_w:r,_d:!1},e)}}};x||(w=function(t){p(this,w,m,"_h"),h(t),e.call(this);try{t(f(L,this,1),f(U,this,1))}catch(n){U.call(this,n)}},e=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},e.prototype=r(210)(w.prototype,{then:function(t,n){var r=R(d(this,w));return r.ok="function"!=typeof t||t,r.fail="function"==typeof n&&n,r.domain=b?E.domain:void 0,this._c.push(r),this._a&&this._a.push(r),this._s&&P(this,!1),r.promise},"catch":function(t){return this.then(void 0,t)}}),I=function(){var t=new e;this.promise=t,this.resolve=f(L,t,1),this.reject=f(U,t,1)}),s(s.G+s.W+s.F*!x,{Promise:w}),r(24)(w,m),r(192)(m),o=r(9)[m],s(s.S+s.F*!x,m,{reject:function(t){var n=R(this),r=n.reject;return r(t),n.promise}}),s(s.S+s.F*(u||!x),m,{resolve:function(t){if(t instanceof w&&S(t.constructor,this))return t;var n=R(this),r=n.resolve;return r(t),n.promise}}),s(s.S+s.F*!(x&&r(165)(function(t){w.all(t)["catch"](A)})),m,{all:function(t){var n=this,r=R(n),e=r.resolve,i=r.reject,o=O(function(){var r=[],o=0,u=1;v(t,!1,function(t){var a=o++,f=!1;r.push(void 0),u++,n.resolve(t).then(function(t){f||(f=!0,r[a]=t,--u||e(r))},i)}),--u||e(r)});return o&&i(o.error),r.promise},race:function(t){var n=this,r=R(n),e=r.reject,i=O(function(){v(t,!1,function(t){n.resolve(t).then(r.resolve,e)})});return i&&e(i.error),r.promise}})},function(t,n){t.exports=function(t,n,r,e){if(!(t instanceof n)||void 0!==e&&e in t)throw TypeError(r+": incorrect invocation!");return t}},function(t,n,r){var e=r(20),i=r(161),o=r(162),u=r(12),a=r(37),f=r(164),c={},s={},n=t.exports=function(t,n,r,l,h){var p,v,d,g,y=h?function(){return t}:f(t),m=e(r,l,n?2:1),_=0;if("function"!=typeof y)throw TypeError(t+" is not iterable!");if(o(y)){for(p=a(t.length);p>_;_++)if(g=n?m(u(v=t[_])[0],v[1]):m(t[_]),g===c||g===s)return g}else for(d=y.call(t);!(v=d.next()).done;)if(g=i(d,m,v.value,n),g===c||g===s)return g};n.BREAK=c,n.RETURN=s},function(t,n,r){var e=r(12),i=r(21),o=r(25)("species");t.exports=function(t,n){var r,u=e(t).constructor;return void 0===u||void 0==(r=e(u)[o])?n:i(r)}},function(t,n,r){var e,i,o,u=r(20),a=r(78),f=r(48),c=r(15),s=r(4),l=s.process,h=s.setImmediate,p=s.clearImmediate,v=s.MessageChannel,d=0,g={},y="onreadystatechange",m=function(){var t=+this;if(g.hasOwnProperty(t)){var n=g[t];delete g[t],n()}},_=function(t){m.call(t.data)};h&&p||(h=function(t){for(var n=[],r=1;arguments.length>r;)n.push(arguments[r++]);return g[++d]=function(){a("function"==typeof t?t:Function(t),n)},e(d),d},p=function(t){delete g[t]},"process"==r(34)(l)?e=function(t){l.nextTick(u(m,t,1))}:v?(i=new v,o=i.port2,i.port1.onmessage=_,e=u(o.postMessage,o,1)):s.addEventListener&&"function"==typeof postMessage&&!s.importScripts?(e=function(t){s.postMessage(t+"","*")},s.addEventListener("message",_,!1)):e=y in c("script")?function(t){f.appendChild(c("script"))[y]=function(){f.removeChild(this),m.call(t)}}:function(t){setTimeout(u(m,t,1),0)}),t.exports={set:h,clear:p}},function(t,n,r){var e=r(4),i=r(208).set,o=e.MutationObserver||e.WebKitMutationObserver,u=e.process,a=e.Promise,f="process"==r(34)(u);t.exports=function(){var t,n,r,c=function(){var e,i;for(f&&(e=u.domain)&&e.exit();t;){i=t.fn,t=t.next;try{i()}catch(o){throw t?r():n=void 0,o}}n=void 0,e&&e.enter()};if(f)r=function(){u.nextTick(c)};else if(o){var s=!0,l=document.createTextNode("");new o(c).observe(l,{characterData:!0}),r=function(){l.data=s=!s}}else if(a&&a.resolve){var h=a.resolve();r=function(){h.then(c)}}else r=function(){i.call(e,c)};return function(e){var i={fn:e,next:void 0};n&&(n.next=i),t||(t=i,r()),n=i}}},function(t,n,r){var e=r(18);t.exports=function(t,n,r){for(var i in n)e(t,i,n[i],r);return t}},function(t,n,r){"use strict";var e=r(212);t.exports=r(213)("Map",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var n=e.getEntry(this,t);return n&&n.v},set:function(t,n){return e.def(this,0===t?0:t,n)}},e,!0)},function(t,n,r){"use strict";var e=r(11).f,i=r(46),o=r(210),u=r(20),a=r(205),f=r(35),c=r(206),s=r(128),l=r(194),h=r(192),p=r(6),v=r(22).fastKey,d=p?"_s":"size",g=function(t,n){var r,e=v(n);if("F"!==e)return t._i[e];for(r=t._f;r;r=r.n)if(r.k==n)return r};t.exports={getConstructor:function(t,n,r,s){var l=t(function(t,e){a(t,l,n,"_i"),t._i=i(null),t._f=void 0,t._l=void 0,t[d]=0,void 0!=e&&c(e,r,t[s],t)});return o(l.prototype,{clear:function(){for(var t=this,n=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];t._f=t._l=void 0,t[d]=0},"delete":function(t){var n=this,r=g(n,t);if(r){var e=r.n,i=r.p;delete n._i[r.i],r.r=!0,i&&(i.n=e),e&&(e.p=i),n._f==r&&(n._f=e),n._l==r&&(n._l=i),n[d]--}return!!r},forEach:function(t){a(this,l,"forEach");for(var n,r=u(t,arguments.length>1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(t){return!!g(this,t)}}),p&&e(l.prototype,"size",{get:function(){return f(this[d])}}),l},def:function(t,n,r){var e,i,o=g(t,n);return o?o.v=r:(t._l=o={i:i=v(n,!0),k:n,v:r,p:e=t._l,n:void 0,r:!1},t._f||(t._f=o),e&&(e.n=o),t[d]++,"F"!==i&&(t._i[i]=o)),t},getEntry:g,setStrong:function(t,n,r){s(t,n,function(t,n){this._t=t,this._k=n,this._l=void 0},function(){for(var t=this,n=t._k,r=t._l;r&&r.r;)r=r.p;return t._t&&(t._l=r=r?r.n:t._t._f)?"keys"==n?l(0,r.k):"values"==n?l(0,r.v):l(0,[r.k,r.v]):(t._t=void 0,l(1))},r?"entries":"values",!r,!0),h(n)}}},function(t,n,r){"use strict";var e=r(4),i=r(8),o=r(18),u=r(210),a=r(22),f=r(206),c=r(205),s=r(13),l=r(7),h=r(165),p=r(24),v=r(88);t.exports=function(t,n,r,d,g,y){var m=e[t],_=m,E=g?"set":"add",w=_&&_.prototype,b={},A=function(t){var n=w[t];o(w,t,"delete"==t?function(t){return!(y&&!s(t))&&n.call(this,0===t?0:t)}:"has"==t?function(t){return!(y&&!s(t))&&n.call(this,0===t?0:t)}:"get"==t?function(t){return y&&!s(t)?void 0:n.call(this,0===t?0:t)}:"add"==t?function(t){return n.call(this,0===t?0:t),this}:function(t,r){return n.call(this,0===t?0:t,r),this})};if("function"==typeof _&&(y||w.forEach&&!l(function(){(new _).entries().next()}))){var x=new _,S=x[E](y?{}:-0,1)!=x,T=l(function(){x.has(1)}),R=h(function(t){new _(t)}),I=!y&&l(function(){for(var t=new _,n=5;n--;)t[E](n,n);return!t.has(-0)});R||(_=n(function(n,r){c(n,_,t);var e=v(new m,n,_);return void 0!=r&&f(r,g,e[E],e),e}),_.prototype=w,w.constructor=_),(T||I)&&(A("delete"),A("has"),g&&A("get")),(I||S)&&A(E),y&&w.clear&&delete w.clear}else _=d.getConstructor(n,t,g,E),u(_.prototype,r),a.NEED=!0;return p(_,t),b[t]=_,i(i.G+i.W+i.F*(_!=m),b),y||d.setStrong(_,t,g),_}},function(t,n,r){"use strict";var e=r(212);t.exports=r(213)("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return e.def(this,t=0===t?0:t,t)}},e)},function(t,n,r){"use strict";var e,i=r(172)(0),o=r(18),u=r(22),a=r(69),f=r(216),c=r(13),s=u.getWeak,l=Object.isExtensible,h=f.ufstore,p={},v=function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},d={get:function(t){if(c(t)){var n=s(t);return n===!0?h(this).get(t):n?n[this._i]:void 0}},set:function(t,n){return f.def(this,t,n)}},g=t.exports=r(213)("WeakMap",v,d,f,!0,!0);7!=(new g).set((Object.freeze||Object)(p),7).get(p)&&(e=f.getConstructor(v),a(e.prototype,d),u.NEED=!0,i(["delete","has","get","set"],function(t){var n=g.prototype,r=n[t];o(n,t,function(n,i){if(c(n)&&!l(n)){this._f||(this._f=new e);var o=this._f[t](n,i);return"set"==t?this:o}return r.call(this,n,i)})}))},function(t,n,r){"use strict";var e=r(210),i=r(22).getWeak,o=r(12),u=r(13),a=r(205),f=r(206),c=r(172),s=r(5),l=c(5),h=c(6),p=0,v=function(t){return t._l||(t._l=new d)},d=function(){this.a=[]},g=function(t,n){return l(t.a,function(t){return t[0]===n})};d.prototype={get:function(t){var n=g(this,t);if(n)return n[1]},has:function(t){return!!g(this,t)},set:function(t,n){var r=g(this,t);r?r[1]=n:this.a.push([t,n])},"delete":function(t){var n=h(this.a,function(n){return n[0]===t});return~n&&this.a.splice(n,1),!!~n}},t.exports={getConstructor:function(t,n,r,o){var c=t(function(t,e){a(t,c,n,"_i"),t._i=p++,t._l=void 0,void 0!=e&&f(e,r,t[o],t)});return e(c.prototype,{"delete":function(t){if(!u(t))return!1;var n=i(t);return n===!0?v(this)["delete"](t):n&&s(n,this._i)&&delete n[this._i]},has:function(t){if(!u(t))return!1;var n=i(t);return n===!0?v(this).has(t):n&&s(n,this._i)}}),c},def:function(t,n,r){var e=i(o(n),!0);return e===!0?v(t).set(n,r):e[t._i]=r,t},ufstore:v}},function(t,n,r){"use strict";var e=r(216);r(213)("WeakSet",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return e.def(this,t,!0)}},e,!1,!0)},function(t,n,r){"use strict";var e=r(8),i=r(219),o=r(220),u=r(12),a=r(39),f=r(37),c=r(13),s=r(4).ArrayBuffer,l=r(207),h=o.ArrayBuffer,p=o.DataView,v=i.ABV&&s.isView,d=h.prototype.slice,g=i.VIEW,y="ArrayBuffer";e(e.G+e.W+e.F*(s!==h),{ArrayBuffer:h}),e(e.S+e.F*!i.CONSTR,y,{isView:function(t){return v&&v(t)||c(t)&&g in t}}),e(e.P+e.U+e.F*r(7)(function(){return!new h(2).slice(1,void 0).byteLength}),y,{slice:function(t,n){if(void 0!==d&&void 0===n)return d.call(u(this),t);for(var r=u(this).byteLength,e=a(t,r),i=a(void 0===n?r:n,r),o=new(l(this,h))(f(i-e)),c=new p(this),s=new p(o),v=0;e>1,s=23===n?O(2,-24)-O(2,-77):0,l=0,h=t<0||0===t&&1/t<0?1:0;for(t=I(t),t!=t||t===T?(i=t!=t?1:0,e=f):(e=P(M(t)/F),t*(o=O(2,-e))<1&&(e--,o*=2),t+=e+c>=1?s/o:s*O(2,1-c),t*o>=2&&(e++,o/=2),e+c>=f?(i=0,e=f):e+c>=1?(i=(t*o-1)*O(2,n),e+=c):(i=t*O(2,c-1)*O(2,n),e=0));n>=8;u[l++]=255&i,i/=256,n-=8);for(e=e<0;u[l++]=255&e,e/=256,a-=8);return u[--l]|=128*h,u},j=function(t,n,r){var e,i=8*r-n-1,o=(1<>1,a=i-7,f=r-1,c=t[f--],s=127&c;for(c>>=7;a>0;s=256*s+t[f],f--,a-=8);for(e=s&(1<<-a)-1,s>>=-a,a+=n;a>0;e=256*e+t[f],f--,a-=8);if(0===s)s=1-u;else{if(s===o)return e?NaN:c?-T:T;e+=O(2,n),s-=u}return(c?-1:1)*e*O(2,s-n)},z=function(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]},G=function(t){return[255&t]},W=function(t){return[255&t,t>>8&255]},Y=function(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]},V=function(t){return k(t,52,8)},X=function(t){return k(t,23,4)},H=function(t,n,r){v(t[_],n,{get:function(){return this[r]}})},q=function(t,n,r,e){var i=+r,o=l(i);if(i!=o||o<0||o+n>t[C])throw S(w);var u=t[N]._b,a=o+t[D],f=u.slice(a,a+n);return e?f:f.reverse()},K=function(t,n,r,e,i,o){var u=+r,a=l(u);if(u!=a||a<0||a+n>t[C])throw S(w);for(var f=t[N]._b,c=a+t[D],s=e(+i),h=0;htt;)(J=$[tt++])in b||a(b,J,R[J]);o||(Q.constructor=b)}var nt=new A(new b(2)),rt=A[_].setInt8;nt.setInt8(0,2147483648),nt.setInt8(1,2147483649),!nt.getInt8(0)&&nt.getInt8(1)||f(A[_],{setInt8:function(t,n){rt.call(this,t,n<<24>>24)},setUint8:function(t,n){rt.call(this,t,n<<24>>24)}},!0)}else b=function(t){var n=Z(this,t);this._b=d.call(Array(n),0),this[C]=n},A=function(t,n,r){s(this,A,m),s(t,b,m);var e=t[C],i=l(n);if(i<0||i>e)throw S("Wrong offset!");if(r=void 0===r?e-i:h(r),i+r>e)throw S(E);this[N]=t,this[D]=i,this[C]=r},i&&(H(b,U,"_l"),H(A,B,"_b"),H(A,U,"_l"),H(A,L,"_o")),f(A[_],{getInt8:function(t){return q(this,1,t)[0]<<24>>24},getUint8:function(t){return q(this,1,t)[0]},getInt16:function(t){var n=q(this,2,t,arguments[1]);return(n[1]<<8|n[0])<<16>>16},getUint16:function(t){var n=q(this,2,t,arguments[1]);return n[1]<<8|n[0]},getInt32:function(t){return z(q(this,4,t,arguments[1]))},getUint32:function(t){return z(q(this,4,t,arguments[1]))>>>0},getFloat32:function(t){return j(q(this,4,t,arguments[1]),23,4)},getFloat64:function(t){return j(q(this,8,t,arguments[1]),52,8)},setInt8:function(t,n){K(this,1,t,G,n)},setUint8:function(t,n){K(this,1,t,G,n)},setInt16:function(t,n){K(this,2,t,W,n,arguments[2])},setUint16:function(t,n){K(this,2,t,W,n,arguments[2])},setInt32:function(t,n){K(this,4,t,Y,n,arguments[2])},setUint32:function(t,n){K(this,4,t,Y,n,arguments[2])},setFloat32:function(t,n){K(this,4,t,X,n,arguments[2])},setFloat64:function(t,n){K(this,8,t,V,n,arguments[2])}});g(b,y),g(A,m),a(A[_],u.VIEW,!0),n[y]=b,n[m]=A},function(t,n,r){var e=r(8);e(e.G+e.W+e.F*!r(219).ABV,{DataView:r(220).DataView})},function(t,n,r){r(223)("Int8",1,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){"use strict";if(r(6)){var e=r(28),i=r(4),o=r(7),u=r(8),a=r(219),f=r(220),c=r(20),s=r(205),l=r(17),h=r(10),p=r(210),v=r(38),d=r(37),g=r(39),y=r(16),m=r(5),_=r(71),E=r(75),w=r(13),b=r(58),A=r(162),x=r(46),S=r(59),T=r(50).f,R=r(164),I=r(19),O=r(25),P=r(172),M=r(36),F=r(207),B=r(193),U=r(129),L=r(165),N=r(192),C=r(188),D=r(185),k=r(11),j=r(51),z=k.f,G=j.f,W=i.RangeError,Y=i.TypeError,V=i.Uint8Array,X="ArrayBuffer",H="Shared"+X,q="BYTES_PER_ELEMENT",K="prototype",Z=Array[K],J=f.ArrayBuffer,Q=f.DataView,$=P(0),tt=P(2),nt=P(3),rt=P(4),et=P(5),it=P(6),ot=M(!0),ut=M(!1),at=B.values,ft=B.keys,ct=B.entries,st=Z.lastIndexOf,lt=Z.reduce,ht=Z.reduceRight,pt=Z.join,vt=Z.sort,dt=Z.slice,gt=Z.toString,yt=Z.toLocaleString,mt=O("iterator"),_t=O("toStringTag"),Et=I("typed_constructor"),wt=I("def_constructor"),bt=a.CONSTR,At=a.TYPED,xt=a.VIEW,St="Wrong length!",Tt=P(1,function(t,n){return Ft(F(t,t[wt]),n)}),Rt=o(function(){return 1===new V(new Uint16Array([1]).buffer)[0]}),It=!!V&&!!V[K].set&&o(function(){new V(1).set({})}),Ot=function(t,n){if(void 0===t)throw Y(St);var r=+t,e=d(t);if(n&&!_(r,e))throw W(St);return e},Pt=function(t,n){var r=v(t);if(r<0||r%n)throw W("Wrong offset!");return r},Mt=function(t){if(w(t)&&At in t)return t;throw Y(t+" is not a typed array!")},Ft=function(t,n){if(!(w(t)&&Et in t))throw Y("It is not a typed array constructor!");return new t(n)},Bt=function(t,n){return Ut(F(t,t[wt]),n)},Ut=function(t,n){for(var r=0,e=n.length,i=Ft(t,e);e>r;)i[r]=n[r++];return i},Lt=function(t,n,r){z(t,n,{get:function(){return this._d[r]}})},Nt=function(t){var n,r,e,i,o,u,a=b(t),f=arguments.length,s=f>1?arguments[1]:void 0,l=void 0!==s,h=R(a);if(void 0!=h&&!A(h)){for(u=h.call(a),e=[],n=0;!(o=u.next()).done;n++)e.push(o.value);a=e}for(l&&f>2&&(s=c(s,arguments[2],2)),n=0,r=d(a.length),i=Ft(this,r);r>n;n++)i[n]=l?s(a[n],n):a[n];return i},Ct=function(){for(var t=0,n=arguments.length,r=Ft(this,n);n>t;)r[t]=arguments[t++];return r},Dt=!!V&&o(function(){yt.call(new V(1))}),kt=function(){return yt.apply(Dt?dt.call(Mt(this)):Mt(this),arguments)},jt={copyWithin:function(t,n){return D.call(Mt(this),t,n,arguments.length>2?arguments[2]:void 0)},every:function(t){return rt(Mt(this),t,arguments.length>1?arguments[1]:void 0)},fill:function(t){return C.apply(Mt(this),arguments)},filter:function(t){return Bt(this,tt(Mt(this),t,arguments.length>1?arguments[1]:void 0))},find:function(t){return et(Mt(this),t,arguments.length>1?arguments[1]:void 0)},findIndex:function(t){return it(Mt(this),t,arguments.length>1?arguments[1]:void 0)},forEach:function(t){$(Mt(this),t,arguments.length>1?arguments[1]:void 0)},indexOf:function(t){return ut(Mt(this),t,arguments.length>1?arguments[1]:void 0)},includes:function(t){return ot(Mt(this),t,arguments.length>1?arguments[1]:void 0)},join:function(t){return pt.apply(Mt(this),arguments)},lastIndexOf:function(t){return st.apply(Mt(this),arguments)},map:function(t){return Tt(Mt(this),t,arguments.length>1?arguments[1]:void 0)},reduce:function(t){return lt.apply(Mt(this),arguments)},reduceRight:function(t){return ht.apply(Mt(this),arguments)},reverse:function(){for(var t,n=this,r=Mt(n).length,e=Math.floor(r/2),i=0;i1?arguments[1]:void 0)},sort:function(t){return vt.call(Mt(this),t)},subarray:function(t,n){var r=Mt(this),e=r.length,i=g(t,e);return new(F(r,r[wt]))(r.buffer,r.byteOffset+i*r.BYTES_PER_ELEMENT,d((void 0===n?e:g(n,e))-i))}},zt=function(t,n){return Bt(this,dt.call(Mt(this),t,n))},Gt=function(t){Mt(this);var n=Pt(arguments[1],1),r=this.length,e=b(t),i=d(e.length),o=0;if(i+n>r)throw W(St);for(;o255?255:255&e),i.v[v](r*n+i.o,e,Rt)},O=function(t,n){z(t,n,{get:function(){return R(this,n)},set:function(t){return I(this,n,t)},enumerable:!0})};_?(g=r(function(t,r,e,i){s(t,g,c,"_d");var o,u,a,f,l=0,p=0;if(w(r)){if(!(r instanceof J||(f=E(r))==X||f==H))return At in r?Ut(g,r):Nt.call(g,r);o=r,p=Pt(e,n);var v=r.byteLength;if(void 0===i){if(v%n)throw W(St);if(u=v-p,u<0)throw W(St)}else if(u=d(i)*n,u+p>v)throw W(St);a=u/n}else a=Ot(r,!0),u=a*n,o=new J(u);for(h(t,"_d",{b:o,o:p,l:u,e:a,v:new Q(o)});l=r.length)return{value:void 0,done:!0};while(!((t=r[n._i++])in n._t));return{value:t,done:!1}}),e(e.S,"Reflect",{enumerate:function(t){return new o(t)}})},function(t,n,r){function e(t,n){var r,a,s=arguments.length<3?t:arguments[2];return c(t)===s?t[n]:(r=i.f(t,n))?u(r,"value")?r.value:void 0!==r.get?r.get.call(s):void 0:f(a=o(t))?e(a,n,s):void 0}var i=r(51),o=r(59),u=r(5),a=r(8),f=r(13),c=r(12);a(a.S,"Reflect",{get:e})},function(t,n,r){var e=r(51),i=r(8),o=r(12);i(i.S,"Reflect",{getOwnPropertyDescriptor:function(t,n){return e.f(o(t),n)}})},function(t,n,r){var e=r(8),i=r(59),o=r(12);e(e.S,"Reflect",{getPrototypeOf:function(t){return i(o(t))}})},function(t,n,r){var e=r(8);e(e.S,"Reflect",{has:function(t,n){return n in t}})},function(t,n,r){var e=r(8),i=r(12),o=Object.isExtensible;e(e.S,"Reflect",{isExtensible:function(t){return i(t),!o||o(t)}})},function(t,n,r){var e=r(8);e(e.S,"Reflect",{ownKeys:r(243)})},function(t,n,r){var e=r(50),i=r(43),o=r(12),u=r(4).Reflect;t.exports=u&&u.ownKeys||function(t){var n=e.f(o(t)),r=i.f;return r?n.concat(r(t)):n}},function(t,n,r){var e=r(8),i=r(12),o=Object.preventExtensions;e(e.S,"Reflect",{preventExtensions:function(t){i(t);try{return o&&o(t),!0}catch(n){return!1}}})},function(t,n,r){function e(t,n,r){var f,h,p=arguments.length<4?t:arguments[3],v=o.f(s(t),n);if(!v){if(l(h=u(t)))return e(h,n,r,p);v=c(0)}return a(v,"value")?!(v.writable===!1||!l(p))&&(f=o.f(p,n)||c(0),f.value=r,i.f(p,n,f),!0):void 0!==v.set&&(v.set.call(p,r),!0)}var i=r(11),o=r(51),u=r(59),a=r(5),f=r(8),c=r(17),s=r(12),l=r(13);f(f.S,"Reflect",{set:e})},function(t,n,r){var e=r(8),i=r(73);i&&e(e.S,"Reflect",{setPrototypeOf:function(t,n){i.check(t,n);try{return i.set(t,n),!0}catch(r){return!1}}})},function(t,n,r){"use strict";var e=r(8),i=r(36)(!0);e(e.P,"Array",{includes:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(186)("includes")},function(t,n,r){"use strict";var e=r(8),i=r(127)(!0);e(e.P,"String",{at:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(8),i=r(250);e(e.P,"String",{padStart:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},function(t,n,r){var e=r(37),i=r(91),o=r(35);t.exports=function(t,n,r,u){var a=String(o(t)),f=a.length,c=void 0===r?" ":String(r),s=e(n);if(s<=f||""==c)return a;var l=s-f,h=i.call(c,Math.ceil(l/c.length));return h.length>l&&(h=h.slice(0,l)),u?h+a:a+h}},function(t,n,r){"use strict";var e=r(8),i=r(250);e(e.P,"String",{padEnd:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},function(t,n,r){"use strict";r(83)("trimLeft",function(t){return function(){return t(this,1)}},"trimStart")},function(t,n,r){"use strict";r(83)("trimRight",function(t){return function(){return t(this,2)}},"trimEnd")},function(t,n,r){"use strict";var e=r(8),i=r(35),o=r(37),u=r(134),a=r(196),f=RegExp.prototype,c=function(t,n){this._r=t,this._s=n};r(130)(c,"RegExp String",function(){var t=this._r.exec(this._s);return{value:t,done:null===t}}),e(e.P,"String",{matchAll:function(t){if(i(this),!u(t))throw TypeError(t+" is not a regexp!");var n=String(this),r="flags"in f?String(t.flags):a.call(t),e=new RegExp(t.source,~r.indexOf("g")?r:"g"+r);return e.lastIndex=o(t.lastIndex),new c(e,n)}})},function(t,n,r){r(27)("asyncIterator")},function(t,n,r){r(27)("observable")},function(t,n,r){var e=r(8),i=r(243),o=r(32),u=r(51),a=r(163);e(e.S,"Object",{getOwnPropertyDescriptors:function(t){for(var n,r=o(t),e=u.f,f=i(r),c={},s=0;f.length>s;)a(c,n=f[s++],e(r,n));return c}})},function(t,n,r){var e=r(8),i=r(259)(!1);e(e.S,"Object",{values:function(t){return i(t)}})},function(t,n,r){var e=r(30),i=r(32),o=r(44).f;t.exports=function(t){return function(n){for(var r,u=i(n),a=e(u),f=a.length,c=0,s=[];f>c;)o.call(u,r=a[c++])&&s.push(t?[r,u[r]]:u[r]);return s}}},function(t,n,r){var e=r(8),i=r(259)(!0);e(e.S,"Object",{entries:function(t){return i(t)}})},function(t,n,r){"use strict";var e=r(8),i=r(58),o=r(21),u=r(11);r(6)&&e(e.P+r(262),"Object",{__defineGetter__:function(t,n){u.f(i(this),t,{get:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){t.exports=r(28)||!r(7)(function(){var t=Math.random();__defineSetter__.call(null,t,function(){}),delete r(4)[t]})},function(t,n,r){"use strict";var e=r(8),i=r(58),o=r(21),u=r(11);r(6)&&e(e.P+r(262),"Object",{__defineSetter__:function(t,n){u.f(i(this),t,{set:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){"use strict";var e=r(8),i=r(58),o=r(16),u=r(59),a=r(51).f;r(6)&&e(e.P+r(262),"Object",{__lookupGetter__:function(t){var n,r=i(this),e=o(t,!0);do if(n=a(r,e))return n.get;while(r=u(r))}})},function(t,n,r){"use strict";var e=r(8),i=r(58),o=r(16),u=r(59),a=r(51).f;r(6)&&e(e.P+r(262),"Object",{__lookupSetter__:function(t){var n,r=i(this),e=o(t,!0);do if(n=a(r,e))return n.set;while(r=u(r))}})},function(t,n,r){var e=r(8);e(e.P+e.R,"Map",{toJSON:r(267)("Map")})},function(t,n,r){var e=r(75),i=r(268);t.exports=function(t){return function(){if(e(this)!=t)throw TypeError(t+"#toJSON isn't generic");return i(this)}}},function(t,n,r){var e=r(206);t.exports=function(t,n){var r=[];return e(t,!1,r.push,r,n),r}},function(t,n,r){var e=r(8);e(e.P+e.R,"Set",{toJSON:r(267)("Set")})},function(t,n,r){var e=r(8);e(e.S,"System",{global:r(4)})},function(t,n,r){var e=r(8),i=r(34);e(e.S,"Error",{isError:function(t){return"Error"===i(t)}})},function(t,n,r){var e=r(8);e(e.S,"Math",{iaddh:function(t,n,r,e){var i=t>>>0,o=n>>>0,u=r>>>0;return o+(e>>>0)+((i&u|(i|u)&~(i+u>>>0))>>>31)|0}})},function(t,n,r){var e=r(8);e(e.S,"Math",{isubh:function(t,n,r,e){var i=t>>>0,o=n>>>0,u=r>>>0;return o-(e>>>0)-((~i&u|~(i^u)&i-u>>>0)>>>31)|0}})},function(t,n,r){var e=r(8);e(e.S,"Math",{imulh:function(t,n){var r=65535,e=+t,i=+n,o=e&r,u=i&r,a=e>>16,f=i>>16,c=(a*u>>>0)+(o*u>>>16);return a*f+(c>>16)+((o*f>>>0)+(c&r)>>16)}})},function(t,n,r){var e=r(8);e(e.S,"Math",{umulh:function(t,n){var r=65535,e=+t,i=+n,o=e&r,u=i&r,a=e>>>16,f=i>>>16,c=(a*u>>>0)+(o*u>>>16);return a*f+(c>>>16)+((o*f>>>0)+(c&r)>>>16)}})},function(t,n,r){var e=r(277),i=r(12),o=e.key,u=e.set;e.exp({defineMetadata:function(t,n,r,e){u(t,n,i(r),o(e))}})},function(t,n,r){var e=r(211),i=r(8),o=r(23)("metadata"),u=o.store||(o.store=new(r(215))),a=function(t,n,r){var i=u.get(t);if(!i){if(!r)return;u.set(t,i=new e)}var o=i.get(n);if(!o){if(!r)return;i.set(n,o=new e)}return o},f=function(t,n,r){var e=a(n,r,!1);return void 0!==e&&e.has(t)},c=function(t,n,r){var e=a(n,r,!1);return void 0===e?void 0:e.get(t)},s=function(t,n,r,e){a(r,e,!0).set(t,n)},l=function(t,n){var r=a(t,n,!1),e=[];return r&&r.forEach(function(t,n){e.push(n)}),e},h=function(t){return void 0===t||"symbol"==typeof t?t:String(t)},p=function(t){i(i.S,"Reflect",t)};t.exports={store:u,map:a,has:f,get:c,set:s,keys:l,key:h,exp:p}},function(t,n,r){var e=r(277),i=r(12),o=e.key,u=e.map,a=e.store;e.exp({deleteMetadata:function(t,n){var r=arguments.length<3?void 0:o(arguments[2]),e=u(i(n),r,!1);if(void 0===e||!e["delete"](t))return!1;if(e.size)return!0;var f=a.get(n);return f["delete"](r),!!f.size||a["delete"](n)}})},function(t,n,r){var e=r(277),i=r(12),o=r(59),u=e.has,a=e.get,f=e.key,c=function(t,n,r){var e=u(t,n,r);if(e)return a(t,n,r);var i=o(n);return null!==i?c(t,i,r):void 0};e.exp({getMetadata:function(t,n){return c(t,i(n),arguments.length<3?void 0:f(arguments[2]))}})},function(t,n,r){var e=r(214),i=r(268),o=r(277),u=r(12),a=r(59),f=o.keys,c=o.key,s=function(t,n){var r=f(t,n),o=a(t);if(null===o)return r;var u=s(o,n);return u.length?r.length?i(new e(r.concat(u))):u:r};o.exp({getMetadataKeys:function(t){return s(u(t),arguments.length<2?void 0:c(arguments[1]))}})},function(t,n,r){var e=r(277),i=r(12),o=e.get,u=e.key;e.exp({getOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(277),i=r(12),o=e.keys,u=e.key;e.exp({getOwnMetadataKeys:function(t){return o(i(t),arguments.length<2?void 0:u(arguments[1]))}})},function(t,n,r){var e=r(277),i=r(12),o=r(59),u=e.has,a=e.key,f=function(t,n,r){var e=u(t,n,r);if(e)return!0;var i=o(n);return null!==i&&f(t,i,r)};e.exp({hasMetadata:function(t,n){return f(t,i(n),arguments.length<3?void 0:a(arguments[2]))}})},function(t,n,r){var e=r(277),i=r(12),o=e.has,u=e.key;e.exp({hasOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(277),i=r(12),o=r(21),u=e.key,a=e.set;e.exp({metadata:function(t,n){return function(r,e){a(t,n,(void 0!==e?i:o)(r),u(e))}}})},function(t,n,r){var e=r(8),i=r(209)(),o=r(4).process,u="process"==r(34)(o);e(e.G,{asap:function(t){var n=u&&o.domain;i(n?n.bind(t):t)}})},function(t,n,r){"use strict";var e=r(8),i=r(4),o=r(9),u=r(209)(),a=r(25)("observable"),f=r(21),c=r(12),s=r(205),l=r(210),h=r(10),p=r(206),v=p.RETURN,d=function(t){return null==t?void 0:f(t)},g=function(t){var n=t._c;n&&(t._c=void 0,n())},y=function(t){return void 0===t._o},m=function(t){y(t)||(t._o=void 0,g(t))},_=function(t,n){c(t),this._c=void 0,this._o=t,t=new E(this);try{var r=n(t),e=r;null!=r&&("function"==typeof r.unsubscribe?r=function(){e.unsubscribe()}:f(r),this._c=r)}catch(i){return void t.error(i)}y(this)&&g(this)};_.prototype=l({},{unsubscribe:function(){m(this)}});var E=function(t){this._s=t};E.prototype=l({},{next:function(t){var n=this._s;if(!y(n)){var r=n._o;try{var e=d(r.next);if(e)return e.call(r,t)}catch(i){try{m(n)}finally{throw i}}}},error:function(t){var n=this._s;if(y(n))throw t;var r=n._o;n._o=void 0;try{var e=d(r.error);if(!e)throw t;t=e.call(r,t)}catch(i){try{g(n)}finally{throw i}}return g(n),t},complete:function(t){var n=this._s;if(!y(n)){var r=n._o;n._o=void 0;try{var e=d(r.complete);t=e?e.call(r,t):void 0}catch(i){try{g(n)}finally{throw i}}return g(n),t}}});var w=function(t){s(this,w,"Observable","_f")._f=f(t)};l(w.prototype,{subscribe:function(t){return new _(t,this._f)},forEach:function(t){var n=this;return new(o.Promise||i.Promise)(function(r,e){f(t);var i=n.subscribe({next:function(n){try{return t(n)}catch(r){e(r),i.unsubscribe()}},error:e,complete:r})})}}),l(w,{from:function(t){var n="function"==typeof this?this:w,r=d(c(t)[a]);if(r){var e=c(r.call(t));return e.constructor===n?e:new n(function(t){return e.subscribe(t)})}return new n(function(n){var r=!1;return u(function(){if(!r){try{if(p(t,!1,function(t){if(n.next(t),r)return v})===v)return}catch(e){if(r)throw e;return void n.error(e)}n.complete()}}),function(){r=!0}})},of:function(){for(var t=0,n=arguments.length,r=Array(n);tu;)(r[u]=arguments[u++])===a&&(f=!0);return function(){var e,o=this,u=arguments.length,c=0,s=0;if(!f&&!u)return i(t,r,o);if(e=r.slice(),f)for(;n>c;c++)e[c]===a&&(e[c]=arguments[s++]);for(;u>s;)e.push(arguments[s++]);return i(t,e,o)}}},function(t,n,r){t.exports=r(4)},function(t,n,r){var e=r(8),i=r(208);e(e.G+e.B,{setImmediate:i.set,clearImmediate:i.clear})},function(t,n,r){for(var e=r(193),i=r(18),o=r(4),u=r(10),a=r(129),f=r(25),c=f("iterator"),s=f("toStringTag"),l=a.Array,h=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],p=0;p<5;p++){var v,d=h[p],g=o[d],y=g&&g.prototype;if(y){y[c]||u(y,c,l),y[s]||u(y,s,d),a[d]=l;for(v in e)y[v]||i(y,v,e[v],!0)}}},function(t,n,r){(function(n,r){!function(n){"use strict";function e(t,n,r,e){var i=Object.create((n||o).prototype),u=new v(e||[]);return i._invoke=l(t,r,u),i}function i(t,n,r){try{return{type:"normal",arg:t.call(n,r)}}catch(e){return{type:"throw",arg:e}}}function o(){}function u(){}function a(){}function f(t){["next","throw","return"].forEach(function(n){t[n]=function(t){return this._invoke(n,t)}})}function c(t){this.arg=t}function s(t){function n(r,e,o,u){var a=i(t[r],t,e);if("throw"!==a.type){var f=a.arg,s=f.value;return s instanceof c?Promise.resolve(s.arg).then(function(t){n("next",t,o,u)},function(t){n("throw",t,o,u)}):Promise.resolve(s).then(function(t){f.value=t,o(f)},u)}u(a.arg)}function e(t,r){function e(){return new Promise(function(e,i){n(t,r,e,i)})}return o=o?o.then(e,e):e()}"object"==typeof r&&r.domain&&(n=r.domain.bind(n));var o;this._invoke=e}function l(t,n,r){var e=x;return function(o,u){if(e===T)throw new Error("Generator is already running");if(e===R){if("throw"===o)throw u;return g()}for(;;){var a=r.delegate;if(a){if("return"===o||"throw"===o&&a.iterator[o]===y){r.delegate=null;var f=a.iterator["return"];if(f){var c=i(f,a.iterator,u);if("throw"===c.type){o="throw",u=c.arg;continue}}if("return"===o)continue}var c=i(a.iterator[o],a.iterator,u);if("throw"===c.type){r.delegate=null,o="throw",u=c.arg;continue}o="next",u=y;var s=c.arg;if(!s.done)return e=S,s;r[a.resultName]=s.value,r.next=a.nextLoc,r.delegate=null}if("next"===o)r.sent=r._sent=u;else if("throw"===o){if(e===x)throw e=R,u;r.dispatchException(u)&&(o="next",u=y)}else"return"===o&&r.abrupt("return",u);e=T;var c=i(t,n,r);if("normal"===c.type){e=r.done?R:S;var s={value:c.arg,done:r.done};if(c.arg!==I)return s;r.delegate&&"next"===o&&(u=y)}else"throw"===c.type&&(e=R,o="throw",u=c.arg)}}}function h(t){var n={tryLoc:t[0]};1 in t&&(n.catchLoc=t[1]),2 in t&&(n.finallyLoc=t[2],n.afterLoc=t[3]),this.tryEntries.push(n)}function p(t){var n=t.completion||{};n.type="normal",delete n.arg,t.completion=n}function v(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(h,this),this.reset(!0)}function d(t){if(t){var n=t[E];if(n)return n.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,e=function i(){for(;++r=0;--e){var i=this.tryEntries[e],o=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var u=m.call(i,"catchLoc"),a=m.call(i,"finallyLoc");if(u&&a){if(this.prev=0;--r){var e=this.tryEntries[r];if(e.tryLoc<=this.prev&&m.call(e,"finallyLoc")&&this.prev=0;--n){var r=this.tryEntries[n];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),p(r),I}},"catch":function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc===t){var e=r.completion;if("throw"===e.type){var i=e.arg;p(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,r){return this.delegate={iterator:d(t),resultName:n,nextLoc:r},I}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(n,function(){return this}(),r(294))},function(t,n){function r(t){if(f===setTimeout)return setTimeout(t,0);try{return f(t,0)}catch(n){try{return f.call(null,t,0)}catch(n){return f.call(this,t,0)}}}function e(t){if(c===clearTimeout)return clearTimeout(t);try{return c(t)}catch(n){try{return c.call(null,t)}catch(n){return c.call(this,t)}}}function i(){p&&l&&(p=!1,l.length?h=l.concat(h):v=-1,h.length&&o())}function o(){if(!p){var t=r(i);p=!0;for(var n=h.length;n;){for(l=h,h=[];++v1)for(var e=1;e=0&&(o.getDrawableByID(t).dispose(),this._drawables.splice(n,1),!0)},a.prototype.draw=function(){var t=this._gl;i.bindFramebufferInfo(t,null),t.viewport(0,0,t.canvas.width,t.canvas.height),t.clearColor.apply(t,this._backgroundColor),t.clear(t.COLOR_BUFFER_BIT),this._drawThese(this._drawables,u.DRAW_MODE["default"],this._projection)},a.prototype.isTouchingColor=function(t,r,e){var o=this._gl;i.bindFramebufferInfo(o,this._queryBufferInfo),o.viewport(0,0,this._nativeSize[0],this._nativeSize[1]),o.clearColor.apply(o,this._backgroundColor),o.clear(o.COLOR_BUFFER_BIT|o.STENCIL_BUFFER_BIT);var f;e&&(f={u_colorMask:[e[0]/255,e[1]/255,e[2]/255],u_colorMaskTolerance:a.TOLERANCE_TOUCHING_COLOR/255});try{o.enable(o.STENCIL_TEST),o.stencilFunc(o.ALWAYS,1,1),o.stencilOp(o.KEEP,o.KEEP,o.REPLACE),o.colorMask(!1,!1,!1,!1),this._drawThese([t],e?u.DRAW_MODE.colorMask:u.DRAW_MODE.silhouette,this._projection,void 0,f),o.stencilFunc(o.EQUAL,1,1),o.stencilOp(o.KEEP,o.KEEP,o.KEEP),o.colorMask(!0,!0,!0,!0),this._drawThese(this._drawables,u.DRAW_MODE["default"],this._projection,function(n){return n!=t})}finally{o.colorMask(!0,!0,!0,!0),o.disable(o.STENCIL_TEST)}var c=new n(this._nativeSize[0]*this._nativeSize[1]*4);if(o.readPixels(0,0,this._nativeSize[0],this._nativeSize[1],o.RGBA,o.UNSIGNED_BYTE,c),this._debugCanvas){this._debugCanvas.width=this._nativeSize[0],this._debugCanvas.height=this._nativeSize[1];for(var s=this._debugCanvas.getContext("2d"),l=s.getImageData(0,0,this._nativeSize[0],this._nativeSize[1]),h=0,p=c.length;hP[B]&&(B=U);return 0|B},a.prototype.updateDrawableProperties=function(t,n){var r=o.getDrawableByID(t);r.updateProperties(n)},a.prototype._createGeometry=function(){var t={a_position:{numComponents:2,data:[-.5,-.5,.5,-.5,-.5,.5,-.5,.5,.5,-.5,.5,.5]},a_texCoord:{numComponents:2,data:[1,0,0,0,1,1,1,1,0,0,0,1]}};this._bufferInfo=i.createBufferInfoFromArrays(this._gl,t)},a.prototype._createQueryBuffers=function(){var t=this._gl,n=[{format:t.RGBA},{format:t.DEPTH_STENCIL}];this._pickBufferInfo=i.createFramebufferInfo(t,n,a.MAX_TOUCH_SIZE[0],a.MAX_TOUCH_SIZE[1]),this._queryBufferInfo=i.createFramebufferInfo(t,n,this._nativeSize[0],this._nativeSize[1])},a.prototype._drawThese=function(t,n,r,e,u){for(var a=this._gl,f=null,c=t.length,s=0;s - * @license MIT - */ -"use strict";function i(){function t(){}try{var n=new Uint8Array(1);return n.foo=function(){return 42},n.constructor=t,42===n.foo()&&n.constructor===t&&"function"==typeof n.subarray&&0===n.subarray(1,1).byteLength}catch(r){return!1}}function o(){return t.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function t(n){return this instanceof t?(t.TYPED_ARRAY_SUPPORT||(this.length=0,this.parent=void 0),"number"==typeof n?u(this,n):"string"==typeof n?a(this,n,arguments.length>1?arguments[1]:"utf8"):f(this,n)):arguments.length>1?new t(n,arguments[1]):new t(n)}function u(n,r){if(n=d(n,r<0?0:0|g(r)),!t.TYPED_ARRAY_SUPPORT)for(var e=0;e>>1;return e&&(n.parent=J),n}function g(t){if(t>=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|t}function y(n,r){if(!(this instanceof y))return new y(n,r);var e=new t(n,r);return delete e.parent,e}function m(t,n){"string"!=typeof t&&(t=""+t);var r=t.length;if(0===r)return 0;for(var e=!1;;)switch(n){case"ascii":case"binary":case"raw":case"raws":return r;case"utf8":case"utf-8":return W(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*r;case"hex":return r>>>1;case"base64":return X(t).length;default:if(e)return W(t).length;n=(""+n).toLowerCase(),e=!0}}function _(t,n,r){var e=!1;if(n=0|n,r=void 0===r||r===1/0?this.length:0|r,t||(t="utf8"),n<0&&(n=0),r>this.length&&(r=this.length),r<=n)return"";for(;;)switch(t){case"hex":return M(this,n,r);case"utf8":case"utf-8":return R(this,n,r);case"ascii":return O(this,n,r);case"binary":return P(this,n,r);case"base64":return T(this,n,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return F(this,n,r);default:if(e)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),e=!0}}function E(t,n,r,e){r=Number(r)||0;var i=t.length-r;e?(e=Number(e),e>i&&(e=i)):e=i;var o=n.length;if(o%2!==0)throw new Error("Invalid hex string");e>o/2&&(e=o/2);for(var u=0;u239?4:o>223?3:o>191?2:1;if(i+a<=r){var f,c,s,l;switch(a){case 1:o<128&&(u=o);break;case 2:f=t[i+1],128===(192&f)&&(l=(31&o)<<6|63&f,l>127&&(u=l));break;case 3:f=t[i+1],c=t[i+2],128===(192&f)&&128===(192&c)&&(l=(15&o)<<12|(63&f)<<6|63&c,l>2047&&(l<55296||l>57343)&&(u=l));break;case 4:f=t[i+1],c=t[i+2],s=t[i+3],128===(192&f)&&128===(192&c)&&128===(192&s)&&(l=(15&o)<<18|(63&f)<<12|(63&c)<<6|63&s,l>65535&&l<1114112&&(u=l))}}null===u?(u=65533,a=1):u>65535&&(u-=65536,e.push(u>>>10&1023|55296),u=56320|1023&u),e.push(u),i+=a}return I(e)}function I(t){var n=t.length;if(n<=Q)return String.fromCharCode.apply(String,t);for(var r="",e=0;ee)&&(r=e);for(var i="",o=n;or)throw new RangeError("Trying to access beyond buffer length")}function U(n,r,e,i,o,u){if(!t.isBuffer(n))throw new TypeError("buffer must be a Buffer instance");if(r>o||rn.length)throw new RangeError("index out of range")}function L(t,n,r,e){n<0&&(n=65535+n+1);for(var i=0,o=Math.min(t.length-r,2);i>>8*(e?i:1-i)}function N(t,n,r,e){n<0&&(n=4294967295+n+1);for(var i=0,o=Math.min(t.length-r,4);i>>8*(e?i:3-i)&255}function C(t,n,r,e,i,o){if(n>i||nt.length)throw new RangeError("index out of range");if(r<0)throw new RangeError("index out of range")}function D(t,n,r,e,i){return i||C(t,n,r,4,3.4028234663852886e38,-3.4028234663852886e38),K.write(t,n,r,e,23,4),r+4}function k(t,n,r,e,i){return i||C(t,n,r,8,1.7976931348623157e308,-1.7976931348623157e308),K.write(t,n,r,e,52,8),r+8}function j(t){if(t=z(t).replace(tt,""),t.length<2)return"";for(;t.length%4!==0;)t+="=";return t}function z(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function G(t){return t<16?"0"+t.toString(16):t.toString(16)}function W(t,n){n=n||1/0;for(var r,e=t.length,i=null,o=[],u=0;u55295&&r<57344){if(!i){if(r>56319){(n-=3)>-1&&o.push(239,191,189);continue}if(u+1===e){(n-=3)>-1&&o.push(239,191,189);continue}i=r;continue}if(r<56320){(n-=3)>-1&&o.push(239,191,189),i=r;continue}r=(i-55296<<10|r-56320)+65536}else i&&(n-=3)>-1&&o.push(239,191,189);if(i=null,r<128){if((n-=1)<0)break;o.push(r)}else if(r<2048){if((n-=2)<0)break;o.push(r>>6|192,63&r|128)}else if(r<65536){if((n-=3)<0)break;o.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((n-=4)<0)break;o.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return o}function Y(t){for(var n=[],r=0;r>8,i=r%256,o.push(i),o.push(e);return o}function X(t){return q.toByteArray(j(t))}function H(t,n,r,e){for(var i=0;i=n.length||i>=t.length);i++)n[i+r]=t[i];return i}var q=r(300),K=r(301),Z=r(302);n.Buffer=t,n.SlowBuffer=y,n.INSPECT_MAX_BYTES=50,t.poolSize=8192;var J={};t.TYPED_ARRAY_SUPPORT=void 0!==e.TYPED_ARRAY_SUPPORT?e.TYPED_ARRAY_SUPPORT:i(),t.TYPED_ARRAY_SUPPORT?(t.prototype.__proto__=Uint8Array.prototype,t.__proto__=Uint8Array):(t.prototype.length=void 0,t.prototype.parent=void 0),t.isBuffer=function(t){return!(null==t||!t._isBuffer)},t.compare=function(n,r){if(!t.isBuffer(n)||!t.isBuffer(r))throw new TypeError("Arguments must be Buffers");if(n===r)return 0;for(var e=n.length,i=r.length,o=0,u=Math.min(e,i);o0&&(t=this.toString("hex",0,r).match(/.{2}/g).join(" "),this.length>r&&(t+=" ... ")),""},t.prototype.compare=function(n){if(!t.isBuffer(n))throw new TypeError("Argument must be a Buffer");return this===n?0:t.compare(this,n)},t.prototype.indexOf=function(n,r){function e(t,n,r){for(var e=-1,i=0;r+i2147483647?r=2147483647:r<-2147483648&&(r=-2147483648),r>>=0,0===this.length)return-1;if(r>=this.length)return-1;if(r<0&&(r=Math.max(this.length+r,0)),"string"==typeof n)return 0===n.length?-1:String.prototype.indexOf.call(this,n,r);if(t.isBuffer(n))return e(this,n,r);if("number"==typeof n)return t.TYPED_ARRAY_SUPPORT&&"function"===Uint8Array.prototype.indexOf?Uint8Array.prototype.indexOf.call(this,n,r):e(this,[n],r);throw new TypeError("val must be string, number or Buffer")},t.prototype.get=function(t){return console.log(".get() is deprecated. Access using array indexes instead."),this.readUInt8(t)},t.prototype.set=function(t,n){return console.log(".set() is deprecated. Access using array indexes instead."),this.writeUInt8(t,n)},t.prototype.write=function(t,n,r,e){if(void 0===n)e="utf8",r=this.length,n=0;else if(void 0===r&&"string"==typeof n)e=n,r=this.length,n=0;else if(isFinite(n))n=0|n,isFinite(r)?(r=0|r,void 0===e&&(e="utf8")):(e=r,r=void 0);else{var i=e;e=n,n=0|r,r=i}var o=this.length-n;if((void 0===r||r>o)&&(r=o),t.length>0&&(r<0||n<0)||n>this.length)throw new RangeError("attempt to write outside buffer bounds");e||(e="utf8");for(var u=!1;;)switch(e){case"hex":return E(this,t,n,r);case"utf8":case"utf-8":return w(this,t,n,r);case"ascii":return b(this,t,n,r);case"binary":return A(this,t,n,r);case"base64":return x(this,t,n,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,t,n,r);default:if(u)throw new TypeError("Unknown encoding: "+e);e=(""+e).toLowerCase(),u=!0}},t.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var Q=4096;t.prototype.slice=function(n,r){var e=this.length;n=~~n,r=void 0===r?e:~~r,n<0?(n+=e,n<0&&(n=0)):n>e&&(n=e),r<0?(r+=e,r<0&&(r=0)):r>e&&(r=e),r0&&(i*=256);)e+=this[t+--n]*i;return e},t.prototype.readUInt8=function(t,n){return n||B(t,1,this.length),this[t]},t.prototype.readUInt16LE=function(t,n){return n||B(t,2,this.length),this[t]|this[t+1]<<8},t.prototype.readUInt16BE=function(t,n){return n||B(t,2,this.length),this[t]<<8|this[t+1]},t.prototype.readUInt32LE=function(t,n){return n||B(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},t.prototype.readUInt32BE=function(t,n){return n||B(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},t.prototype.readIntLE=function(t,n,r){t=0|t,n=0|n,r||B(t,n,this.length);for(var e=this[t],i=1,o=0;++o=i&&(e-=Math.pow(2,8*n)),e},t.prototype.readIntBE=function(t,n,r){t=0|t,n=0|n,r||B(t,n,this.length);for(var e=n,i=1,o=this[t+--e];e>0&&(i*=256);)o+=this[t+--e]*i;return i*=128,o>=i&&(o-=Math.pow(2,8*n)),o},t.prototype.readInt8=function(t,n){return n||B(t,1,this.length),128&this[t]?(255-this[t]+1)*-1:this[t]},t.prototype.readInt16LE=function(t,n){n||B(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},t.prototype.readInt16BE=function(t,n){n||B(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},t.prototype.readInt32LE=function(t,n){return n||B(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},t.prototype.readInt32BE=function(t,n){return n||B(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},t.prototype.readFloatLE=function(t,n){return n||B(t,4,this.length),K.read(this,t,!0,23,4)},t.prototype.readFloatBE=function(t,n){return n||B(t,4,this.length),K.read(this,t,!1,23,4)},t.prototype.readDoubleLE=function(t,n){return n||B(t,8,this.length),K.read(this,t,!0,52,8)},t.prototype.readDoubleBE=function(t,n){return n||B(t,8,this.length),K.read(this,t,!1,52,8)},t.prototype.writeUIntLE=function(t,n,r,e){t=+t,n=0|n,r=0|r,e||U(this,t,n,r,Math.pow(2,8*r),0);var i=1,o=0;for(this[n]=255&t;++o=0&&(o*=256);)this[n+i]=t/o&255;return n+r},t.prototype.writeUInt8=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,1,255,0),t.TYPED_ARRAY_SUPPORT||(n=Math.floor(n)),this[r]=255&n,r+1},t.prototype.writeUInt16LE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,2,65535,0),t.TYPED_ARRAY_SUPPORT?(this[r]=255&n,this[r+1]=n>>>8):L(this,n,r,!0),r+2},t.prototype.writeUInt16BE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,2,65535,0),t.TYPED_ARRAY_SUPPORT?(this[r]=n>>>8,this[r+1]=255&n):L(this,n,r,!1),r+2},t.prototype.writeUInt32LE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,4,4294967295,0),t.TYPED_ARRAY_SUPPORT?(this[r+3]=n>>>24,this[r+2]=n>>>16,this[r+1]=n>>>8,this[r]=255&n):N(this,n,r,!0),r+4},t.prototype.writeUInt32BE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,4,4294967295,0),t.TYPED_ARRAY_SUPPORT?(this[r]=n>>>24,this[r+1]=n>>>16,this[r+2]=n>>>8,this[r+3]=255&n):N(this,n,r,!1),r+4},t.prototype.writeIntLE=function(t,n,r,e){if(t=+t,n=0|n,!e){var i=Math.pow(2,8*r-1);U(this,t,n,r,i-1,-i)}var o=0,u=1,a=t<0?1:0;for(this[n]=255&t;++o>0)-a&255;return n+r},t.prototype.writeIntBE=function(t,n,r,e){if(t=+t,n=0|n,!e){var i=Math.pow(2,8*r-1);U(this,t,n,r,i-1,-i)}var o=r-1,u=1,a=t<0?1:0;for(this[n+o]=255&t;--o>=0&&(u*=256);)this[n+o]=(t/u>>0)-a&255;return n+r},t.prototype.writeInt8=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,1,127,-128),t.TYPED_ARRAY_SUPPORT||(n=Math.floor(n)),n<0&&(n=255+n+1),this[r]=255&n,r+1},t.prototype.writeInt16LE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,2,32767,-32768),t.TYPED_ARRAY_SUPPORT?(this[r]=255&n,this[r+1]=n>>>8):L(this,n,r,!0),r+2},t.prototype.writeInt16BE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,2,32767,-32768),t.TYPED_ARRAY_SUPPORT?(this[r]=n>>>8,this[r+1]=255&n):L(this,n,r,!1),r+2},t.prototype.writeInt32LE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,4,2147483647,-2147483648),t.TYPED_ARRAY_SUPPORT?(this[r]=255&n,this[r+1]=n>>>8,this[r+2]=n>>>16,this[r+3]=n>>>24):N(this,n,r,!0),r+4},t.prototype.writeInt32BE=function(n,r,e){return n=+n,r=0|r,e||U(this,n,r,4,2147483647,-2147483648),n<0&&(n=4294967295+n+1),t.TYPED_ARRAY_SUPPORT?(this[r]=n>>>24,this[r+1]=n>>>16,this[r+2]=n>>>8,this[r+3]=255&n):N(this,n,r,!1),r+4},t.prototype.writeFloatLE=function(t,n,r){return D(this,t,n,!0,r)},t.prototype.writeFloatBE=function(t,n,r){return D(this,t,n,!1,r)},t.prototype.writeDoubleLE=function(t,n,r){return k(this,t,n,!0,r)},t.prototype.writeDoubleBE=function(t,n,r){return k(this,t,n,!1,r)},t.prototype.copy=function(n,r,e,i){if(e||(e=0),i||0===i||(i=this.length),r>=n.length&&(r=n.length),r||(r=0),i>0&&i=this.length)throw new RangeError("sourceStart out of bounds");if(i<0)throw new RangeError("sourceEnd out of bounds");i>this.length&&(i=this.length),n.length-r=0;o--)n[o+r]=this[o+e];else if(u<1e3||!t.TYPED_ARRAY_SUPPORT)for(o=0;o=this.length)throw new RangeError("start out of bounds");if(r<0||r>this.length)throw new RangeError("end out of bounds");var e;if("number"==typeof t)for(e=n;e0)throw new Error("Invalid string. Length must be a multiple of 4");var s=t.length;f="="===t.charAt(s-2)?2:"="===t.charAt(s-1)?1:0,c=new o(3*t.length/4-f),u=f>0?t.length-4:t.length;var l=0;for(e=0,i=0;e>16),r((65280&a)>>8),r(255&a);return 2===f?(a=n(t.charAt(e))<<2|n(t.charAt(e+1))>>4,r(255&a)):1===f&&(a=n(t.charAt(e))<<10|n(t.charAt(e+1))<<4|n(t.charAt(e+2))>>2,r(a>>8&255),r(255&a)),c}function i(t){function n(t){return e.charAt(t)}function r(t){return n(t>>18&63)+n(t>>12&63)+n(t>>6&63)+n(63&t)}var i,o,u,a=t.length%3,f="";for(i=0,u=t.length-a;i>2),f+=n(o<<4&63),f+="==";break;case 2:o=(t[t.length-2]<<8)+t[t.length-1],f+=n(o>>10),f+=n(o>>4&63),f+=n(o<<2&63),f+="="}return f}var o="undefined"!=typeof Uint8Array?Uint8Array:Array,u="+".charCodeAt(0),a="/".charCodeAt(0),f="0".charCodeAt(0),c="a".charCodeAt(0),s="A".charCodeAt(0),l="-".charCodeAt(0),h="_".charCodeAt(0);t.toByteArray=r,t.fromByteArray=i}(n)},function(t,n){n.read=function(t,n,r,e,i){var o,u,a=8*i-e-1,f=(1<>1,s=-7,l=r?i-1:0,h=r?-1:1,p=t[n+l];for(l+=h,o=p&(1<<-s)-1,p>>=-s,s+=a;s>0;o=256*o+t[n+l],l+=h,s-=8);for(u=o&(1<<-s)-1,o>>=-s,s+=e;s>0;u=256*u+t[n+l],l+=h,s-=8);if(0===o)o=1-c;else{if(o===f)return u?NaN:(p?-1:1)*(1/0);u+=Math.pow(2,e),o-=c}return(p?-1:1)*u*Math.pow(2,o-e)},n.write=function(t,n,r,e,i,o){var u,a,f,c=8*o-i-1,s=(1<>1,h=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=e?0:o-1,v=e?1:-1,d=n<0||0===n&&1/n<0?1:0;for(n=Math.abs(n),isNaN(n)||n===1/0?(a=isNaN(n)?1:0,u=s):(u=Math.floor(Math.log(n)/Math.LN2),n*(f=Math.pow(2,-u))<1&&(u--,f*=2),n+=u+l>=1?h/f:h*Math.pow(2,1-l),n*f>=2&&(u++,f/=2),u+l>=s?(a=0,u=s):u+l>=1?(a=(n*f-1)*Math.pow(2,i),u+=l):(a=n*Math.pow(2,l-1)*Math.pow(2,i),u=0));i>=8;t[r+p]=255&a,p+=v,a/=256,i-=8);for(u=u<0;t[r+p]=255&u,p+=v,u/=256,c-=8);t[r+p-v]|=128*d}},function(t,n){var r={}.toString;t.exports=Array.isArray||function(t){return"[object Array]"==r.call(t)}},function(t,n,r){var e,i,o;/** - * @license twgl.js 1.5.2 Copyright (c) 2015, Gregg Tavares All Rights Reserved. - * Available via the MIT license. - * see: http://github.com/greggman/twgl.js for details - */ -/** - * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/almond for details - */ -!function(r,u){i=[],e=u,o="function"==typeof e?e.apply(n,i):e,!(void 0!==o&&(t.exports=o)),"undefined"!=typeof t&&t.exports?t.exports=u():r.twgl=u()}(this,function(){/** - * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/almond for details - */ -var t,n,r;return function(e){function i(t,n){return E.call(t,n)}function o(t,n){var r,e,i,o,u,a,f,c,s,l,h,p=n&&n.split("/"),v=m.map,d=v&&v["*"]||{};if(t&&"."===t.charAt(0))if(n){for(t=t.split("/"),u=t.length-1,m.nodeIdCompat&&b.test(t[u])&&(t[u]=t[u].replace(b,"")),t=p.slice(0,p.length-1).concat(t),s=0;s0&&(t.splice(s-1,2),s-=2)}t=t.join("/")}else 0===t.indexOf("./")&&(t=t.substring(2));if((p||d)&&v){for(r=t.split("/"),s=r.length;s>0;s-=1){if(e=r.slice(0,s).join("/"),p)for(l=p.length;l>0;l-=1)if(i=v[p.slice(0,l).join("/")],i&&(i=i[e])){o=i,a=s;break}if(o)break;!f&&d&&d[e]&&(f=d[e],c=s)}!o&&f&&(o=f,a=c),o&&(r.splice(0,a,o),t=r.join("/"))}return t}function u(t,n){return function(){var r=w.call(arguments,0);return"string"!=typeof r[0]&&1===r.length&&r.push(null),p.apply(e,r.concat([t,n]))}}function a(t){return function(n){return o(n,t)}}function f(t){return function(n){g[t]=n}}function c(t){if(i(y,t)){var n=y[t];delete y[t],_[t]=!0,h.apply(e,n)}if(!i(g,t)&&!i(_,t))throw new Error("No "+t);return g[t]}function s(t){var n,r=t?t.indexOf("!"):-1;return r>-1&&(n=t.substring(0,r),t=t.substring(r+1,t.length)),[n,t]}function l(t){return function(){return m&&m.config&&m.config[t]||{}}}var h,p,v,d,g={},y={},m={},_={},E=Object.prototype.hasOwnProperty,w=[].slice,b=/\.js$/;v=function(t,n){var r,e=s(t),i=e[0];return t=e[1],i&&(i=o(i,n),r=c(i)),i?t=r&&r.normalize?r.normalize(t,a(n)):o(t,n):(t=o(t,n),e=s(t),i=e[0],t=e[1],i&&(r=c(i))),{f:i?i+"!"+t:t,n:t,pr:i,p:r}},d={notrequirebecasebrowserifymessesup:function(t){return u(t)},exports:function(t){var n=g[t];return"undefined"!=typeof n?n:g[t]={}},module:function(t){return{id:t,uri:"",exports:g[t],config:l(t)}}},h=function(t,n,r,o){var a,s,l,h,p,m,E=[],w=typeof r;if(o=o||t,"undefined"===w||"function"===w){for(n=!n.length&&r.length?["notrequirebecasebrowserifymessesup","exports","module"]:n,p=0;p=0?2:t.indexOf("color")>=0?4:3,n%r>0)throw"can not guess numComponents. You should specify it.";return r}function s(t,n){return t.numComponents||t.size||c(n,f(t).length)}function l(n,r){if(t.isArrayBuffer(n))return n;if(t.isArrayBuffer(n.data))return n.data;Array.isArray(n)&&(n={data:n});var e=n.type;return e||(e="indices"===r?Uint16Array:Float32Array),new e(n.data)}function h(n,r){var e={};return Object.keys(r).forEach(function(i){if(!u(i)){var f=r[i],c=f.attrib||f.name||f.attribName||m.attribPrefix+i,h=l(f,i);e[c]={buffer:o(n,h,void 0,f.drawType),numComponents:s(f,i),type:t.getGLTypeForTypedArray(h),normalize:void 0!==f.normalize?f.normalize:a(h),stride:f.stride||0,offset:f.offset||0,drawType:f.drawType}}}),e}function p(t,n,r,e){r=l(r),e?(t.bindBuffer(t.ARRAY_BUFFER,n.buffer),t.bufferSubData(t.ARRAY_BUFFER,e,r)):i(t,t.ARRAY_BUFFER,n.buffer,r,n.drawType)}function v(n,r){var e={attribs:h(n,r)},i=r.indices;return i?(i=l(i,"indices"),e.indices=o(n,i,n.ELEMENT_ARRAY_BUFFER),e.numElements=i.length,e.elementType=t.getGLTypeForTypedArray(i)):e.numElements=_(r),e}function d(t,n,r){var e="indices"===r?t.ELEMENT_ARRAY_BUFFER:t.ARRAY_BUFFER,i=l(n,r);return o(t,i,e)}function g(t,n){var r={};return Object.keys(n).forEach(function(e){r[e]=d(t,n[e],e)}),r}function y(t,n,r){var e=t.createVertexArray();return t.bindVertexArray(e),n.length||(n=[n]),n.forEach(function(n){twgl.setBuffersAndAttributes(t,n,r)}),t.bindVertexArray(null),{numElements:r.numElements,elementType:r.elementType,vertexArrayObject:e}}var m={attribPrefix:""},_=function(){var t=["position","positions","a_position"];return function(n){for(var r,e=0;e0)throw"numComponents "+u+" not correct for length "+o;return a}}();return{createAttribsFromArrays:h,createBuffersFromArrays:g,createBufferFromArray:d,createBufferFromTypedArray:o,createBufferInfoFromArrays:v,setAttribInfoBufferFromArray:p,createVertexArrayInfo:y,setAttributePrefix:r,setDefaults_:e,getNumComponents_:s,getArray_:f}}),r("twgl/programs",["./utils"],function(t){function n(t,n){return kt[n].bindPoint}function r(t,n){return function(r){t.uniform1f(n,r)}}function e(t,n){return function(r){t.uniform1fv(n,r)}}function i(t,n){return function(r){t.uniform2fv(n,r)}}function o(t,n){return function(r){t.uniform3fv(n,r)}}function u(t,n){return function(r){t.uniform4fv(n,r)}}function a(t,n){return function(r){t.uniform1i(n,r)}}function f(t,n){return function(r){t.uniform1iv(n,r)}}function c(t,n){return function(r){t.uniform2iv(n,r)}}function s(t,n){return function(r){t.uniform3iv(n,r)}}function l(t,n){return function(r){t.uniform4iv(n,r)}}function h(t,n){return function(r){t.uniform1ui(n,r)}}function p(t,n){return function(r){t.uniform1uiv(n,r)}}function v(t,n){return function(r){t.uniform2uiv(n,r)}}function d(t,n){return function(r){t.uniform3uiv(n,r)}}function g(t,n){return function(r){t.uniform4uiv(n,r)}}function y(t,n){return function(r){t.uniformMatrix2fv(n,!1,r)}}function m(t,n){return function(r){t.uniformMatrix3fv(n,!1,r)}}function _(t,n){return function(r){t.uniformMatrix4fv(n,!1,r)}}function E(t,n){return function(r){t.uniformMatrix2x3fv(n,!1,r)}}function w(t,n){return function(r){t.uniformMatrix3x2fv(n,!1,r)}}function b(t,n){return function(r){t.uniformMatrix2x4fv(n,!1,r)}}function A(t,n){return function(r){t.uniformMatrix4x2fv(n,!1,r)}}function x(t,n){return function(r){t.uniformMatrix3x4fv(n,!1,r)}}function S(t,n){return function(r){t.uniformMatrix4x3fv(n,!1,r)}}function T(t,r,e,i){var o=n(t,r);return function(n){t.uniform1i(i,e),t.activeTexture(t.TEXTURE0+e),t.bindTexture(o,n)}}function R(t,r,e,i,o){for(var u=n(t,r),a=new Int32Array(o),f=0;f1&&"[0]"===r.name.substr(-3),u=r.type,a=kt[u];if(!a)throw"unknown type: 0x"+u.toString(16);if(a.bindPoint){var f=e;return e+=r.size,o?a.arraySetter(t,u,f,i,r.size):a.setter(t,u,f,i,r.size)}return a.arraySetter&&o?a.arraySetter(t,i):a.setter(t,i)}for(var e=0,i={},o=t.getProgramParameter(n,t.ACTIVE_UNIFORMS),u=0;u1e-5?(n[0]=t[0]/e,n[1]=t[1]/e,n[2]=t[2]/e):(n[0]=0,n[1]=0,n[2]=0),n}function h(t,n){return n=n||new g(3),n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n}function p(t,n){return n=n||new g(3),n[0]=t[0],n[1]=t[1],n[2]=t[2],n}function v(t,n,r){return r=r||new g(3),r[0]=t[0]*n[0],r[1]=t[1]*n[1],r[2]=t[2]*n[2],r}function d(t,n,r){return r=r||new g(3),r[0]=t[0]/n[0],r[1]=t[1]/n[1],r[2]=t[2]/n[2],r}var g=Float32Array;return{add:r,copy:p,create:n,cross:a,divide:d,divScalar:u,dot:f,lerp:i,length:c,lengthSq:s,mulScalar:o,multiply:v,negate:h,normalize:l,setDefaultType:t,subtract:e}}),r("twgl/m4",["./v3"],function(t){function n(t){var n=M;return M=t,n}function r(t,n){return n=n||new M(16),n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n[3]=-t[3],n[4]=-t[4],n[5]=-t[5],n[6]=-t[6],n[7]=-t[7],n[8]=-t[8],n[9]=-t[9],n[10]=-t[10],n[11]=-t[11],n[12]=-t[12],n[13]=-t[13],n[14]=-t[14],n[15]=-t[15],n}function e(t,n){return n=n||new M(16),n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n}function i(t){return t=t||new M(16),t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function o(t,n){if(n=n||new M(16),n===t){var r;return r=t[1],t[1]=t[4],t[4]=r,r=t[2],t[2]=t[8],t[8]=r,r=t[3],t[3]=t[12],t[12]=r,r=t[6],t[6]=t[9],t[9]=r,r=t[7],t[7]=t[13],t[13]=r,r=t[11],t[11]=t[14],t[14]=r,n}var e=t[0],i=t[1],o=t[2],u=t[3],a=t[4],f=t[5],c=t[6],s=t[7],l=t[8],h=t[9],p=t[10],v=t[11],d=t[12],g=t[13],y=t[14],m=t[15];return n[0]=e,n[1]=a,n[2]=l,n[3]=d,n[4]=i,n[5]=f,n[6]=h,n[7]=g,n[8]=o,n[9]=c,n[10]=p,n[11]=y,n[12]=u,n[13]=s,n[14]=v,n[15]=m,n}function u(t,n){n=n||new M(16);var r=t[0],e=t[1],i=t[2],o=t[3],u=t[4],a=t[5],f=t[6],c=t[7],s=t[8],l=t[9],h=t[10],p=t[11],v=t[12],d=t[13],g=t[14],y=t[15],m=h*y,_=g*p,E=f*y,w=g*c,b=f*p,A=h*c,x=i*y,S=g*o,T=i*p,R=h*o,I=i*c,O=f*o,P=s*d,F=v*l,B=u*d,U=v*a,L=u*l,N=s*a,C=r*d,D=v*e,k=r*l,j=s*e,z=r*a,G=u*e,W=m*a+w*l+b*d-(_*a+E*l+A*d),Y=_*e+x*l+R*d-(m*e+S*l+T*d),V=E*e+S*a+I*d-(w*e+x*a+O*d),X=A*e+T*a+O*l-(b*e+R*a+I*l),H=1/(r*W+u*Y+s*V+v*X);return n[0]=H*W,n[1]=H*Y,n[2]=H*V,n[3]=H*X,n[4]=H*(_*u+E*s+A*v-(m*u+w*s+b*v)),n[5]=H*(m*r+S*s+T*v-(_*r+x*s+R*v)),n[6]=H*(w*r+x*u+O*v-(E*r+S*u+I*v)),n[7]=H*(b*r+R*u+I*s-(A*r+T*u+O*s)),n[8]=H*(P*c+U*p+L*y-(F*c+B*p+N*y)),n[9]=H*(F*o+C*p+j*y-(P*o+D*p+k*y)),n[10]=H*(B*o+D*c+z*y-(U*o+C*c+G*y)),n[11]=H*(N*o+k*c+G*p-(L*o+j*c+z*p)),n[12]=H*(B*h+N*g+F*f-(L*g+P*f+U*h)),n[13]=H*(k*g+P*i+D*h-(C*h+j*g+F*i)), -n[14]=H*(C*f+G*g+U*i-(z*g+B*i+D*f)),n[15]=H*(z*h+L*i+j*f-(k*f+G*h+N*i)),n}function a(t,n,r){r=r||new M(16);var e=t[0],i=t[1],o=t[2],u=t[3],a=t[4],f=t[5],c=t[6],s=t[7],l=t[8],h=t[9],p=t[10],v=t[11],d=t[12],g=t[13],y=t[14],m=t[15],_=n[0],E=n[1],w=n[2],b=n[3],A=n[4],x=n[5],S=n[6],T=n[7],R=n[8],I=n[9],O=n[10],P=n[11],F=n[12],B=n[13],U=n[14],L=n[15];return r[0]=e*_+i*A+o*R+u*F,r[1]=e*E+i*x+o*I+u*B,r[2]=e*w+i*S+o*O+u*U,r[3]=e*b+i*T+o*P+u*L,r[4]=a*_+f*A+c*R+s*F,r[5]=a*E+f*x+c*I+s*B,r[6]=a*w+f*S+c*O+s*U,r[7]=a*b+f*T+c*P+s*L,r[8]=l*_+h*A+p*R+v*F,r[9]=l*E+h*x+p*I+v*B,r[10]=l*w+h*S+p*O+v*U,r[11]=l*b+h*T+p*P+v*L,r[12]=d*_+g*A+y*R+m*F,r[13]=d*E+g*x+y*I+m*B,r[14]=d*w+g*S+y*O+m*U,r[15]=d*b+g*T+y*P+m*L,r}function f(t,n,r){return r=r||i(),t!==r&&(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11]),r[12]=n[0],r[13]=n[1],r[14]=n[2],r[15]=1,r}function c(n,r){return r=r||t.create(),r[0]=n[12],r[1]=n[13],r[2]=n[14],r}function s(n,r,e){e=e||t.create();var i=4*r;return e[0]=n[i+0],e[1]=n[i+1],e[2]=n[i+2],e}function l(t,n,r,i){i!==t&&(i=e(t,i));var o=4*r;return i[o+0]=n[0],i[o+1]=n[1],i[o+2]=n[2],i}function h(t,n,r,e,i){i=i||new M(16);var o=Math.tan(.5*Math.PI-.5*t),u=1/(r-e);return i[0]=o/n,i[1]=0,i[2]=0,i[3]=0,i[4]=0,i[5]=o,i[6]=0,i[7]=0,i[8]=0,i[9]=0,i[10]=(r+e)*u,i[11]=-1,i[12]=0,i[13]=0,i[14]=r*e*u*2,i[15]=0,i}function p(t,n,r,e,i,o,u){return u=u||new M(16),u[0]=2/(n-t),u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=2/(e-r),u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[10]=-1/(o-i),u[11]=0,u[12]=(n+t)/(t-n),u[13]=(e+r)/(r-e),u[14]=-i/(i-o),u[15]=1,u}function v(t,n,r,e,i,o,u){u=u||new M(16);var a=n-t,f=e-r,c=i-o;return u[0]=2*i/a,u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=2*i/f,u[6]=0,u[7]=0,u[8]=(t+n)/a,u[9]=(e+r)/f,u[10]=o/c,u[11]=-1,u[12]=0,u[13]=0,u[14]=i*o/c,u[15]=0,u}function d(n,r,e,i){i=i||new M(16);var o=F,u=B,a=U;return t.normalize(t.subtract(n,r,a),a),t.normalize(t.cross(e,a,o),o),t.normalize(t.cross(a,o,u),u),i[0]=o[0],i[1]=o[1],i[2]=o[2],i[3]=0,i[4]=u[0],i[5]=u[1],i[6]=u[2],i[7]=0,i[8]=a[0],i[9]=a[1],i[10]=a[2],i[11]=0,i[12]=n[0],i[13]=n[1],i[14]=n[2],i[15]=1,i}function g(t,n){return n=n||new M(16),n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=t[0],n[13]=t[1],n[14]=t[2],n[15]=1,n}function y(t,n,r){r=r||new M(16);var e=n[0],i=n[1],o=n[2],u=t[0],a=t[1],f=t[2],c=t[3],s=t[4],l=t[5],h=t[6],p=t[7],v=t[8],d=t[9],g=t[10],y=t[11],m=t[12],_=t[13],E=t[14],w=t[15];return t!==r&&(r[0]=u,r[1]=a,r[2]=f,r[3]=c,r[4]=s,r[5]=l,r[6]=h,r[7]=p,r[8]=v,r[9]=d,r[10]=g,r[11]=y),r[12]=u*e+s*i+v*o+m,r[13]=a*e+l*i+d*o+_,r[14]=f*e+h*i+g*o+E,r[15]=c*e+p*i+y*o+w,r}function m(t,n){n=n||new M(16);var r=Math.cos(t),e=Math.sin(t);return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=r,n[6]=e,n[7]=0,n[8]=0,n[9]=-e,n[10]=r,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function _(t,n,r){r=r||new M(16);var e=t[4],i=t[5],o=t[6],u=t[7],a=t[8],f=t[9],c=t[10],s=t[11],l=Math.cos(n),h=Math.sin(n);return r[4]=l*e+h*a,r[5]=l*i+h*f,r[6]=l*o+h*c,r[7]=l*u+h*s,r[8]=l*a-h*e,r[9]=l*f-h*i,r[10]=l*c-h*o,r[11]=l*s-h*u,t!==r&&(r[0]=t[0],r[1]=t[1],r[2]=t[2],r[3]=t[3],r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15]),r}function E(t,n){n=n||new M(16);var r=Math.cos(t),e=Math.sin(t);return n[0]=r,n[1]=0,n[2]=-e,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=e,n[9]=0,n[10]=r,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function w(t,n,r){r=r||new M(16);var e=t[0],i=t[1],o=t[2],u=t[3],a=t[8],f=t[9],c=t[10],s=t[11],l=Math.cos(n),h=Math.sin(n);return r[0]=l*e-h*a,r[1]=l*i-h*f,r[2]=l*o-h*c,r[3]=l*u-h*s,r[8]=l*a+h*e,r[9]=l*f+h*i,r[10]=l*c+h*o,r[11]=l*s+h*u,t!==r&&(r[4]=t[4],r[5]=t[5],r[6]=t[6],r[7]=t[7],r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15]),r}function b(t,n){n=n||new M(16);var r=Math.cos(t),e=Math.sin(t);return n[0]=r,n[1]=e,n[2]=0,n[3]=0,n[4]=-e,n[5]=r,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function A(t,n,r){r=r||new M(16);var e=t[0],i=t[1],o=t[2],u=t[3],a=t[4],f=t[5],c=t[6],s=t[7],l=Math.cos(n),h=Math.sin(n);return r[0]=l*e+h*a,r[1]=l*i+h*f,r[2]=l*o+h*c,r[3]=l*u+h*s,r[4]=l*a-h*e,r[5]=l*f-h*i,r[6]=l*c-h*o,r[7]=l*s-h*u,t!==r&&(r[8]=t[8],r[9]=t[9],r[10]=t[10],r[11]=t[11],r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15]),r}function x(t,n,r){r=r||new M(16);var e=t[0],i=t[1],o=t[2],u=Math.sqrt(e*e+i*i+o*o);e/=u,i/=u,o/=u;var a=e*e,f=i*i,c=o*o,s=Math.cos(n),l=Math.sin(n),h=1-s;return r[0]=a+(1-a)*s,r[1]=e*i*h+o*l,r[2]=e*o*h-i*l,r[3]=0,r[4]=e*i*h-o*l,r[5]=f+(1-f)*s,r[6]=i*o*h+e*l,r[7]=0,r[8]=e*o*h+i*l,r[9]=i*o*h-e*l,r[10]=c+(1-c)*s,r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r}function S(t,n,r,e){e=e||new M(16);var i=n[0],o=n[1],u=n[2],a=Math.sqrt(i*i+o*o+u*u);i/=a,o/=a,u/=a;var f=i*i,c=o*o,s=u*u,l=Math.cos(r),h=Math.sin(r),p=1-l,v=f+(1-f)*l,d=i*o*p+u*h,g=i*u*p-o*h,y=i*o*p-u*h,m=c+(1-c)*l,_=o*u*p+i*h,E=i*u*p+o*h,w=o*u*p-i*h,b=s+(1-s)*l,A=t[0],x=t[1],S=t[2],T=t[3],R=t[4],I=t[5],O=t[6],P=t[7],F=t[8],B=t[9],U=t[10],L=t[11];return e[0]=v*A+d*R+g*F,e[1]=v*x+d*I+g*B,e[2]=v*S+d*O+g*U,e[3]=v*T+d*P+g*L,e[4]=y*A+m*R+_*F,e[5]=y*x+m*I+_*B,e[6]=y*S+m*O+_*U,e[7]=y*T+m*P+_*L,e[8]=E*A+w*R+b*F,e[9]=E*x+w*I+b*B,e[10]=E*S+w*O+b*U,e[11]=E*T+w*P+b*L,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e}function T(t,n){return n=n||new M(16),n[0]=t[0],n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=t[1],n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=t[2],n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function R(t,n,r){r=r||new M(16);var e=n[0],i=n[1],o=n[2];return r[0]=e*t[0],r[1]=e*t[1],r[2]=e*t[2],r[3]=e*t[3],r[4]=i*t[4],r[5]=i*t[5],r[6]=i*t[6],r[7]=i*t[7],r[8]=o*t[8],r[9]=o*t[9],r[10]=o*t[10],r[11]=o*t[11],t!==r&&(r[12]=t[12],r[13]=t[13],r[14]=t[14],r[15]=t[15]),r}function I(n,r,e){e=e||t.create();var i=r[0],o=r[1],u=r[2],a=i*n[3]+o*n[7]+u*n[11]+n[15];return e[0]=(i*n[0]+o*n[4]+u*n[8]+n[12])/a,e[1]=(i*n[1]+o*n[5]+u*n[9]+n[13])/a,e[2]=(i*n[2]+o*n[6]+u*n[10]+n[14])/a,e}function O(n,r,e){e=e||t.create();var i=r[0],o=r[1],u=r[2];return e[0]=i*n[0]+o*n[4]+u*n[8],e[1]=i*n[1]+o*n[5]+u*n[9],e[2]=i*n[2]+o*n[6]+u*n[10],e}function P(n,r,e){e=e||t.create();var i=u(n),o=r[0],a=r[1],f=r[2];return e[0]=o*i[0]+a*i[1]+f*i[2],e[1]=o*i[4]+a*i[5]+f*i[6],e[2]=o*i[8]+a*i[9]+f*i[10],e}var M=Float32Array,F=t.create(),B=t.create(),U=t.create();return{axisRotate:S,axisRotation:x,create:i,copy:e,frustum:v,getAxis:s,getTranslation:c,identity:i,inverse:u,lookAt:d,multiply:a,negate:r,ortho:p,perspective:h,rotateX:_,rotateY:w,rotateZ:A,rotateAxis:S,rotationX:m,rotationY:E,rotationZ:b,scale:R,scaling:T,setAxis:l,setDefaultType:n,setTranslation:f,transformDirection:O,transformNormal:P,transformPoint:I,translate:y,translation:g,transpose:o}}),r("twgl/primitives",["./attributes","./twgl","./utils","./m4","./v3"],function(t,n,r,e,i){function o(t,n){var r=0;return t.push=function(){for(var n=0;n=0?v(e,n):r.indexOf("tan")>=0||r.indexOf("binorm")>=0?h(e,n):r.indexOf("norm")>=0&&p(e,n)}),t}function g(t,n,r){return t=t||2,n=n||0,r=r||0,t*=.5,{position:{numComponents:2,data:[n+-1*t,r+-1*t,n+1*t,r+-1*t,n+-1*t,r+1*t,n+1*t,r+1*t]},normal:[0,0,1,0,0,1,0,0,1,0,0,1],texcoord:[0,0,1,0,0,1,1,1],indices:[0,1,2,2,1,3]}}function y(t,n,r,i,o){t=t||1,n=n||1,r=r||1,i=i||1,o=o||e.identity();for(var a=(r+1)*(i+1),f=u(3,a),c=u(3,a),s=u(2,a),l=0;l<=i;l++)for(var h=0;h<=r;h++){var p=h/r,v=l/i;f.push(t*p-.5*t,0,n*v-.5*n),c.push(0,1,0),s.push(p,v)}for(var g=r+1,y=u(3,r*i*2,Uint16Array),l=0;l 0");e=e||0,i=i||Math.PI,o=o||0,a=a||2*Math.PI;for(var f=i-e,c=a-o,s=(n+1)*(r+1),l=u(3,s),h=u(3,s),p=u(2,s),v=0;v<=r;v++)for(var d=0;d<=n;d++){var g=d/n,y=v/r,m=c*g,_=f*y,E=Math.sin(m),w=Math.cos(m),b=Math.sin(_),A=Math.cos(_),x=w*b,S=A,T=E*b;l.push(t*x,t*S,t*T),h.push(x,S,T),p.push(1-g,y)}for(var R=n+1,I=u(3,n*r*2,Uint16Array),d=0;di?(S=r,x=1,A=n):A=t+(n-t)*(b/i),b!==-2&&b!==i+2||(A=0,x=0),S-=r/2;for(var T=0;Ti?0:R*m,b<0?-1:b>i?1:_,b<0||b>i?0:I*m),v.push(T/e,1-x)}}for(var b=0;b 0");a=a||0,f=f||1;for(var h=2,p=f-a,v=2*(o+1)*(2+h),d=u(3,v),g=u(3,v),y=u(2,v),m=0;m0&&g!==n){var E=l+(g+1),w=l+g,b=l+g-p,A=l+(g+1)-p;s.push(E,w,b),s.push(E,b,A)}}l+=n+1}return{position:a,normal:f,texcoord:c,indices:s}}function R(t){return Math.random()*t|0}function I(t,n){n=n||{};var r=t.position.numElements,e=u(4,r,Uint8Array),i=n.rand||function(t,n){return n<3?R(256):255};if(t.color=e,t.indices)for(var o=0;o=0&&delete f[this._id]},f.prototype.setTransformDirty=function(){this._transformDirty=!0},f.prototype.getID=function(){return this._id},f.prototype.setSkin=function(t){if(t){var n=t.substring(t.lastIndexOf(".")+1);switch(n){case"svg":case"svg/get/":case"svgz":case"svgz/get/":this._setSkinSVG(t);break;default:this._setSkinBitmap(t)}}else this._useSkin(null,0,0,1,!0)},f.prototype._useSkin=function(t,n,r,e,i){(i||t==this._pendingSkin)&&(this._pendingSkin=null,this._uniforms.u_skin&&this._uniforms.u_skin!=t&&this._gl.deleteTexture(this._uniforms.u_skin),this._setSkinSize(n,r,e),this._uniforms.u_skin=t)},f.prototype.getEnabledEffects=function(){return this._effectBits},f.prototype._setSkinBitmap=function(t){var n=t;this._setSkinCore(n,2)},f.prototype._setSkinSVG=function(t){function n(t,n,e){t||o(e,r)}function r(t,n){t||i._setSkinCore(n,1)}var e=t,i=this;u.get({useXDR:!0,url:e},n)},f.prototype._setSkinCore=function(t,n){var r=this,e=function(t,e,i){t||r._pendingSkin!=e||r._useSkin(e,i.width,i.height,n)},o=this._gl,u={auto:!0,mag:o.NEAREST,min:o.NEAREST,wrap:o.CLAMP_TO_EDGE,src:t},a="string"==typeof t;r._pendingSkin=i.createTexture(o,u,a?e:null),a||e(null,r._pendingSkin,t)},f.prototype.getUniforms=function(){return this._transformDirty&&this._calculateTransform(),this._uniforms},f.prototype.getVisible=function(){return this._visible},f.prototype.updateProperties=function(t){var n=!1;"skin"in t&&this.setSkin(t.skin),"position"in t&&(this._position[0]!=t.position[0]||this._position[1]!=t.position[1])&&(this._position[0]=t.position[0],this._position[1]=t.position[1],n=!0),"direction"in t&&this._direction!=t.direction&&(this._direction=t.direction,n=!0),"scale"in t&&(this._scale[0]!=t.scale[0]||this._scale[1]!=t.scale[1])&&(this._scale[0]=t.scale[0],this._scale[1]=t.scale[1],n=!0),"visible"in t&&(this._visible=t.visible),n&&this.setTransformDirty();for(var r=a.EFFECTS.length,e=0;e>0&255)/255,r=(t>>8&255)/255,e=(t>>16&255)/255;return[n,r,e,1]},f.color4bToID=function(t,n,r,e){var i;return i=(255&t)<<0,i|=(255&n)<<8,i|=(255&r)<<16,i+f.NONE}},function(t,n,r){(function(n){function e(t,r,e){function a(t){n.nextTick(function(){e(new Error(t))})}if("function"==typeof r&&(e=r,r={}),e=e||u,r=r||{},"undefined"==typeof window)return a("window global is undefined; not in a browser");var f=i();if(!f||"function"!=typeof f.createObjectURL||"function"!=typeof f.revokeObjectURL)return a("browser does not support URL.createObjectURL");if("undefined"==typeof window.Blob)return a("browser does not support Blob constructor");Array.isArray(t)||(t=[t]);var c;try{c=new window.Blob(t,{type:"image/svg+xml;charset=utf-8"})}catch(s){return a(s)}var l=f.createObjectURL(c);o(l,r,function(n,i){if(f.revokeObjectURL(l),n){var u="data:image/svg+xml,"+encodeURIComponent(t.join(""));return o(u,r,e)}e(n,i)})}function i(){return window.URL||window.webkitURL||window.mozURL||window.msURL}var o=r(306),u=function(){};t.exports=e}).call(n,r(294))},function(t,n){function r(t,n,r){"function"==typeof n&&(r=n,n=null);var e,i=document.createElement("img");return i.onload=function(){e||(e=!0,r&&r(void 0,i))},i.onerror=function(){e||(e=!0,r&&r(new Error('Unable to load "'+t+'"'),i))},n&&n.crossOrigin&&(i.crossOrigin=n.crossOrigin),i.src=t,i}t.exports=r},function(t,n,r){"use strict";function e(t,n){for(var r=0;r0&&(v=setTimeout(function(){p=!0,c.abort("timeout");var t=new Error("XMLHttpRequest timeout");t.code="ETIMEDOUT",e(t)},t.timeout)),c.setRequestHeader)for(l in m)m.hasOwnProperty(l)&&c.setRequestHeader(l,m[l]);else if(t.headers&&!i(t.headers))throw new Error("Headers cannot be set on an XDomainRequest object");return"responseType"in t&&(c.responseType=t.responseType),"beforeSend"in t&&"function"==typeof t.beforeSend&&t.beforeSend(c),c.send(y),c}function f(){}var c=r(308),s=r(309),l=r(310),h=r(311),p=r(314);t.exports=u,u.XMLHttpRequest=c.XMLHttpRequest||f,u.XDomainRequest="withCredentials"in new u.XMLHttpRequest?u.XMLHttpRequest:c.XDomainRequest,e(["get","put","post","patch","head","delete"],function(t){u["delete"===t?"del":t]=function(n,r,e){return r=o(n,r,e),r.method=t.toUpperCase(),a(r)}})},function(t,n){(function(n){"undefined"!=typeof window?t.exports=window:"undefined"!=typeof n?t.exports=n:"undefined"!=typeof self?t.exports=self:t.exports={}}).call(n,function(){return this}())},function(t,n){function r(t){var n=!1;return function(){if(!n)return n=!0,t.apply(this,arguments)}}t.exports=r,r.proto=r(function(){Object.defineProperty(Function.prototype,"once",{value:function(){return r(this)},configurable:!0})})},function(t,n){function r(t){var n=e.call(t);return"[object Function]"===n||"function"==typeof t&&"[object RegExp]"!==n||"undefined"!=typeof window&&(t===window.setTimeout||t===window.alert||t===window.confirm||t===window.prompt)}t.exports=r;var e=Object.prototype.toString},function(t,n,r){var e=r(312),i=r(313),o=function(t){return"[object Array]"===Object.prototype.toString.call(t)};t.exports=function(t){if(!t)return{};var n={};return i(e(t).split("\n"),function(t){var r=t.indexOf(":"),i=e(t.slice(0,r)).toLowerCase(),u=e(t.slice(r+1));"undefined"==typeof n[i]?n[i]=u:o(n[i])?n[i].push(u):n[i]=[n[i],u]}),n}},function(t,n){function r(t){return t.replace(/^\s*|\s*$/g,"")}n=t.exports=r,n.left=function(t){return t.replace(/^\s*/,"")},n.right=function(t){return t.replace(/\s*$/,"")}},function(t,n,r){function e(t,n,r){if(!a(n))throw new TypeError("iterator must be a function");arguments.length<3&&(r=this),"[object Array]"===f.call(t)?i(t,n,r):"string"==typeof t?o(t,n,r):u(t,n,r)}function i(t,n,r){for(var e=0,i=t.length;e