glsl-lut/example/static/bundle.js
2024-06-12 10:49:54 +01:00

10621 lines
291 KiB
JavaScript

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var canvas = document.body.appendChild(document.createElement('canvas'))
var triangle = require('a-big-triangle')
var createContext = require('gl-context')
var createTex2d = require('gl-texture2d')
var createShell = require('gl-now')
canvas.width = 512
canvas.height = 512
document.body.style.margin = "0";
var gl = createContext(canvas, render)
var baboonTex = getTex2D("baboon.png")
var lookupTex1 = getTex2D("lookup_selective_color.png");
var lookupTex2 = getTex2D("lookup_miss_etikate.png");
var lookupTex = lookupTex1;
//could also use ndarray get-pixels
var lookupImage = new Image();
var shader = require('gl-shader')(gl,
"precision mediump float;\n#define GLSLIFY 1\n\nattribute vec2 position;\nvarying vec2 vUv;\n\nvoid main() {\n vUv = (position + vec2(1.0)) / 2.0;\n vUv.y = 1.0 - vUv.y;\n gl_Position = vec4(position, 1.0, 1.0);\n}",
"precision mediump float;\n#define GLSLIFY 1\n\nuniform sampler2D uTexture;\nuniform sampler2D uLookup;\nuniform float stop;\nvarying vec2 vUv;\n\nvec4 lookup_1_0(in vec4 textureColor, in sampler2D lookupTable) {\n #ifndef LUT_NO_CLAMP\n textureColor = clamp(textureColor, 0.0, 1.0);\n #endif\n\n mediump float blueColor = textureColor.b * 63.0;\n\n mediump vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n\n mediump vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n\n highp vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n\n #ifdef LUT_FLIP_Y\n texPos1.y = 1.0-texPos1.y;\n #endif\n\n highp vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);\n\n #ifdef LUT_FLIP_Y\n texPos2.y = 1.0-texPos2.y;\n #endif\n\n lowp vec4 newColor1 = texture2D(lookupTable, texPos1);\n lowp vec4 newColor2 = texture2D(lookupTable, texPos2);\n\n lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor;\n}\n\n\n\nvoid main() {\n\tvec4 color = texture2D(uTexture, vUv);\n\n\tif (vUv.x > stop)\n\t\tgl_FragColor = lookup_1_0(color, uLookup);\n\telse \n\t\tgl_FragColor = color;\n}\n"
)
//handle mouse move
var mouseX = 0;
window.addEventListener("mousemove", function(ev) {
mouseX = Math.max(0, Math.min(1, ev.pageX/canvas.width));
});
canvas.addEventListener("mousedown", function(ev) {
ev.preventDefault();
lookupTex = lookupTex===lookupTex1 ? lookupTex2 : lookupTex1;
})
function render() {
if (!lookupTex.texture || !baboonTex.texture)
return;
shader.bind()
shader.uniforms.stop = mouseX;
shader.uniforms.uTexture = baboonTex.texture.bind(0)
shader.uniforms.uLookup = lookupTex.texture.bind(1);
triangle(gl)
}
//add some info text
document.body.appendChild(info());
function getTex2D(path) {
var obj = {
image: new Image(),
texture: null
};
obj.image.onload = function() {
obj.texture = createTex2d(gl, obj.image)
obj.texture.minFilter = obj.texture.magFilter = gl.LINEAR;
};
obj.image.src = path;
return obj;
}
function info() {
var lbl = document.createElement("div")
lbl.style.font = "14px 'Helvetica', 'Arial', sans-serif";
lbl.style.margin = "10px";
lbl.innerHTML = "move your mouse to see the color transform<br>click to swap lookup tables";
return lbl;
}
},{"a-big-triangle":2,"gl-context":20,"gl-now":22,"gl-shader":23,"gl-texture2d":33}],2:[function(require,module,exports){
"use strict"
var createBuffer = require("gl-buffer")
var createVAO = require("gl-vao")
function createABigTriangle(gl) {
if(gl.__BIG_TRIANGLE) {
gl.__BIG_TRIANGLE.bind()
gl.drawArrays(gl.TRIANGLES, 0, 3)
gl.__BIG_TRIANGLE.unbind()
return
}
var buf = createBuffer(gl, new Float32Array([-1, -1, -1, 4, 4, -1]))
var vao = createVAO(gl, null, [
{ buffer: buf,
type: gl.FLOAT,
size: 2,
offset: 0,
stride: 0,
normalized: false
}
])
gl.__BIG_TRIANGLE = vao
vao.bind()
gl.drawArrays(gl.TRIANGLES, 0, 3)
vao.unbind()
}
module.exports = createABigTriangle
},{"gl-buffer":17,"gl-vao":38}],3:[function(require,module,exports){
var padLeft = require('pad-left')
module.exports = addLineNumbers
function addLineNumbers (string, start, delim) {
start = typeof start === 'number' ? start : 1
delim = delim || ': '
var lines = string.split(/\r?\n/)
var totalDigits = String(lines.length + start - 1).length
return lines.map(function (line, i) {
var c = i + start
var digits = String(c).length
var prefix = padLeft(c, totalDigits - digits)
return prefix + delim + line
}).join('\n')
}
},{"pad-left":56}],4:[function(require,module,exports){
module.exports = function _atob(str) {
return atob(str)
}
},{}],5:[function(require,module,exports){
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
;(function (exports) {
'use strict';
var Arr = (typeof Uint8Array !== 'undefined')
? Uint8Array
: Array
var PLUS = '+'.charCodeAt(0)
var SLASH = '/'.charCodeAt(0)
var NUMBER = '0'.charCodeAt(0)
var LOWER = 'a'.charCodeAt(0)
var UPPER = 'A'.charCodeAt(0)
var PLUS_URL_SAFE = '-'.charCodeAt(0)
var SLASH_URL_SAFE = '_'.charCodeAt(0)
function decode (elt) {
var code = elt.charCodeAt(0)
if (code === PLUS ||
code === PLUS_URL_SAFE)
return 62 // '+'
if (code === SLASH ||
code === SLASH_URL_SAFE)
return 63 // '/'
if (code < NUMBER)
return -1 //no match
if (code < NUMBER + 10)
return code - NUMBER + 26 + 26
if (code < UPPER + 26)
return code - UPPER
if (code < LOWER + 26)
return code - LOWER + 26
}
function b64ToByteArray (b64) {
var i, j, l, tmp, placeHolders, arr
if (b64.length % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}
// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
var len = b64.length
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
// base64 is 4/3 + up to two characters of the original data
arr = new Arr(b64.length * 3 / 4 - placeHolders)
// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? b64.length - 4 : b64.length
var L = 0
function push (v) {
arr[L++] = v
}
for (i = 0, j = 0; i < l; i += 4, j += 3) {
tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
push((tmp & 0xFF0000) >> 16)
push((tmp & 0xFF00) >> 8)
push(tmp & 0xFF)
}
if (placeHolders === 2) {
tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
push(tmp & 0xFF)
} else if (placeHolders === 1) {
tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
push((tmp >> 8) & 0xFF)
push(tmp & 0xFF)
}
return arr
}
function uint8ToBase64 (uint8) {
var i,
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
output = "",
temp, length
function encode (num) {
return lookup.charAt(num)
}
function tripletToBase64 (num) {
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
}
// go through the array every three bytes, we'll deal with trailing stuff later
for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
output += tripletToBase64(temp)
}
// pad the end with zeros, but make sure to not forget the extra bytes
switch (extraBytes) {
case 1:
temp = uint8[uint8.length - 1]
output += encode(temp >> 2)
output += encode((temp << 4) & 0x3F)
output += '=='
break
case 2:
temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
output += encode(temp >> 10)
output += encode((temp >> 4) & 0x3F)
output += encode((temp << 2) & 0x3F)
output += '='
break
}
return output
}
exports.toByteArray = b64ToByteArray
exports.fromByteArray = uint8ToBase64
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports))
},{}],6:[function(require,module,exports){
"use strict"
function compileSearch(funcName, predicate, reversed, extraArgs, useNdarray, earlyOut) {
var code = [
"function ", funcName, "(a,l,h,", extraArgs.join(","), "){",
earlyOut ? "" : "var i=", (reversed ? "l-1" : "h+1"),
";while(l<=h){\
var m=(l+h)>>>1,x=a", useNdarray ? ".get(m)" : "[m]"]
if(earlyOut) {
if(predicate.indexOf("c") < 0) {
code.push(";if(x===y){return m}else if(x<=y){")
} else {
code.push(";var p=c(x,y);if(p===0){return m}else if(p<=0){")
}
} else {
code.push(";if(", predicate, "){i=m;")
}
if(reversed) {
code.push("l=m+1}else{h=m-1}")
} else {
code.push("h=m-1}else{l=m+1}")
}
code.push("}")
if(earlyOut) {
code.push("return -1};")
} else {
code.push("return i};")
}
return code.join("")
}
function compileBoundsSearch(predicate, reversed, suffix, earlyOut) {
var result = new Function([
compileSearch("A", "x" + predicate + "y", reversed, ["y"], false, earlyOut),
compileSearch("B", "x" + predicate + "y", reversed, ["y"], true, earlyOut),
compileSearch("P", "c(x,y)" + predicate + "0", reversed, ["y", "c"], false, earlyOut),
compileSearch("Q", "c(x,y)" + predicate + "0", reversed, ["y", "c"], true, earlyOut),
"function dispatchBsearch", suffix, "(a,y,c,l,h){\
if(a.shape){\
if(typeof(c)==='function'){\
return Q(a,(l===undefined)?0:l|0,(h===undefined)?a.shape[0]-1:h|0,y,c)\
}else{\
return B(a,(c===undefined)?0:c|0,(l===undefined)?a.shape[0]-1:l|0,y)\
}}else{\
if(typeof(c)==='function'){\
return P(a,(l===undefined)?0:l|0,(h===undefined)?a.length-1:h|0,y,c)\
}else{\
return A(a,(c===undefined)?0:c|0,(l===undefined)?a.length-1:l|0,y)\
}}}\
return dispatchBsearch", suffix].join(""))
return result()
}
module.exports = {
ge: compileBoundsSearch(">=", false, "GE"),
gt: compileBoundsSearch(">", false, "GT"),
lt: compileBoundsSearch("<", true, "LT"),
le: compileBoundsSearch("<=", true, "LE"),
eq: compileBoundsSearch("-", true, "EQ", true)
}
},{}],7:[function(require,module,exports){
/**
* Bit twiddling hacks for JavaScript.
*
* Author: Mikola Lysenko
*
* Ported from Stanford bit twiddling hack library:
* http://graphics.stanford.edu/~seander/bithacks.html
*/
"use strict"; "use restrict";
//Number of bits in an integer
var INT_BITS = 32;
//Constants
exports.INT_BITS = INT_BITS;
exports.INT_MAX = 0x7fffffff;
exports.INT_MIN = -1<<(INT_BITS-1);
//Returns -1, 0, +1 depending on sign of x
exports.sign = function(v) {
return (v > 0) - (v < 0);
}
//Computes absolute value of integer
exports.abs = function(v) {
var mask = v >> (INT_BITS-1);
return (v ^ mask) - mask;
}
//Computes minimum of integers x and y
exports.min = function(x, y) {
return y ^ ((x ^ y) & -(x < y));
}
//Computes maximum of integers x and y
exports.max = function(x, y) {
return x ^ ((x ^ y) & -(x < y));
}
//Checks if a number is a power of two
exports.isPow2 = function(v) {
return !(v & (v-1)) && (!!v);
}
//Computes log base 2 of v
exports.log2 = function(v) {
var r, shift;
r = (v > 0xFFFF) << 4; v >>>= r;
shift = (v > 0xFF ) << 3; v >>>= shift; r |= shift;
shift = (v > 0xF ) << 2; v >>>= shift; r |= shift;
shift = (v > 0x3 ) << 1; v >>>= shift; r |= shift;
return r | (v >> 1);
}
//Computes log base 10 of v
exports.log10 = function(v) {
return (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 :
(v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 :
(v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0;
}
//Counts number of bits
exports.popCount = function(v) {
v = v - ((v >>> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}
//Counts number of trailing zeros
function countTrailingZeros(v) {
var c = 32;
v &= -v;
if (v) c--;
if (v & 0x0000FFFF) c -= 16;
if (v & 0x00FF00FF) c -= 8;
if (v & 0x0F0F0F0F) c -= 4;
if (v & 0x33333333) c -= 2;
if (v & 0x55555555) c -= 1;
return c;
}
exports.countTrailingZeros = countTrailingZeros;
//Rounds to next power of 2
exports.nextPow2 = function(v) {
v += v === 0;
--v;
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
return v + 1;
}
//Rounds down to previous power of 2
exports.prevPow2 = function(v) {
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
return v - (v>>>1);
}
//Computes parity of word
exports.parity = function(v) {
v ^= v >>> 16;
v ^= v >>> 8;
v ^= v >>> 4;
v &= 0xf;
return (0x6996 >>> v) & 1;
}
var REVERSE_TABLE = new Array(256);
(function(tab) {
for(var i=0; i<256; ++i) {
var v = i, r = i, s = 7;
for (v >>>= 1; v; v >>>= 1) {
r <<= 1;
r |= v & 1;
--s;
}
tab[i] = (r << s) & 0xff;
}
})(REVERSE_TABLE);
//Reverse bits in a 32 bit word
exports.reverse = function(v) {
return (REVERSE_TABLE[ v & 0xff] << 24) |
(REVERSE_TABLE[(v >>> 8) & 0xff] << 16) |
(REVERSE_TABLE[(v >>> 16) & 0xff] << 8) |
REVERSE_TABLE[(v >>> 24) & 0xff];
}
//Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes
exports.interleave2 = function(x, y) {
x &= 0xFFFF;
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y &= 0xFFFF;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
//Extracts the nth interleaved component
exports.deinterleave2 = function(v, n) {
v = (v >>> n) & 0x55555555;
v = (v | (v >>> 1)) & 0x33333333;
v = (v | (v >>> 2)) & 0x0F0F0F0F;
v = (v | (v >>> 4)) & 0x00FF00FF;
v = (v | (v >>> 16)) & 0x000FFFF;
return (v << 16) >> 16;
}
//Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes
exports.interleave3 = function(x, y, z) {
x &= 0x3FF;
x = (x | (x<<16)) & 4278190335;
x = (x | (x<<8)) & 251719695;
x = (x | (x<<4)) & 3272356035;
x = (x | (x<<2)) & 1227133513;
y &= 0x3FF;
y = (y | (y<<16)) & 4278190335;
y = (y | (y<<8)) & 251719695;
y = (y | (y<<4)) & 3272356035;
y = (y | (y<<2)) & 1227133513;
x |= (y << 1);
z &= 0x3FF;
z = (z | (z<<16)) & 4278190335;
z = (z | (z<<8)) & 251719695;
z = (z | (z<<4)) & 3272356035;
z = (z | (z<<2)) & 1227133513;
return x | (z << 2);
}
//Extracts nth interleaved component of a 3-tuple
exports.deinterleave3 = function(v, n) {
v = (v >>> n) & 1227133513;
v = (v | (v>>>2)) & 3272356035;
v = (v | (v>>>4)) & 251719695;
v = (v | (v>>>8)) & 4278190335;
v = (v | (v>>>16)) & 0x3FF;
return (v<<22)>>22;
}
//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page)
exports.nextCombination = function(v) {
var t = v | (v - 1);
return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1));
}
},{}],8:[function(require,module,exports){
(function (global){
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <http://feross.org>
* @license MIT
*/
/* eslint-disable no-proto */
'use strict'
var base64 = require('base64-js')
var ieee754 = require('ieee754')
var isArray = require('isarray')
exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50
Buffer.poolSize = 8192 // not used by this implementation
var rootParent = {}
/**
* If `Buffer.TYPED_ARRAY_SUPPORT`:
* === true Use Uint8Array implementation (fastest)
* === false Use Object implementation (most compatible, even IE6)
*
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
* Opera 11.6+, iOS 4.2+.
*
* Due to various browser bugs, sometimes the Object implementation will be used even
* when the browser supports typed arrays.
*
* Note:
*
* - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
*
* - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
* on objects.
*
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
*
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
* incorrect length in some situations.
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
* get the Object implementation, which is slower but behaves correctly.
*/
Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
? global.TYPED_ARRAY_SUPPORT
: typedArraySupport()
function typedArraySupport () {
function Bar () {}
try {
var arr = new Uint8Array(1)
arr.foo = function () { return 42 }
arr.constructor = Bar
return arr.foo() === 42 && // typed array instances can be augmented
arr.constructor === Bar && // constructor can be set
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
} catch (e) {
return false
}
}
function kMaxLength () {
return Buffer.TYPED_ARRAY_SUPPORT
? 0x7fffffff
: 0x3fffffff
}
/**
* Class: Buffer
* =============
*
* The Buffer constructor returns instances of `Uint8Array` that are augmented
* with function properties for all the node `Buffer` API functions. We use
* `Uint8Array` so that square bracket notation works as expected -- it returns
* a single octet.
*
* By augmenting the instances, we can avoid modifying the `Uint8Array`
* prototype.
*/
function Buffer (arg) {
if (!(this instanceof Buffer)) {
// Avoid going through an ArgumentsAdaptorTrampoline in the common case.
if (arguments.length > 1) return new Buffer(arg, arguments[1])
return new Buffer(arg)
}
if (!Buffer.TYPED_ARRAY_SUPPORT) {
this.length = 0
this.parent = undefined
}
// Common case.
if (typeof arg === 'number') {
return fromNumber(this, arg)
}
// Slightly less common case.
if (typeof arg === 'string') {
return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
}
// Unusual.
return fromObject(this, arg)
}
function fromNumber (that, length) {
that = allocate(that, length < 0 ? 0 : checked(length) | 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) {
for (var i = 0; i < length; i++) {
that[i] = 0
}
}
return that
}
function fromString (that, string, encoding) {
if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
// Assumption: byteLength() return value is always < kMaxLength.
var length = byteLength(string, encoding) | 0
that = allocate(that, length)
that.write(string, encoding)
return that
}
function fromObject (that, object) {
if (Buffer.isBuffer(object)) return fromBuffer(that, object)
if (isArray(object)) return fromArray(that, object)
if (object == null) {
throw new TypeError('must start with number, buffer, array or string')
}
if (typeof ArrayBuffer !== 'undefined') {
if (object.buffer instanceof ArrayBuffer) {
return fromTypedArray(that, object)
}
if (object instanceof ArrayBuffer) {
return fromArrayBuffer(that, object)
}
}
if (object.length) return fromArrayLike(that, object)
return fromJsonObject(that, object)
}
function fromBuffer (that, buffer) {
var length = checked(buffer.length) | 0
that = allocate(that, length)
buffer.copy(that, 0, 0, length)
return that
}
function fromArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Duplicate of fromArray() to keep fromArray() monomorphic.
function fromTypedArray (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
// Truncating the elements is probably not what people expect from typed
// arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
// of the old Buffer constructor.
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
function fromArrayBuffer (that, array) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
array.byteLength
that = Buffer._augment(new Uint8Array(array))
} else {
// Fallback: Return an object instance of the Buffer class
that = fromTypedArray(that, new Uint8Array(array))
}
return that
}
function fromArrayLike (that, array) {
var length = checked(array.length) | 0
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
// Returns a zero-length buffer for inputs that don't conform to the spec.
function fromJsonObject (that, object) {
var array
var length = 0
if (object.type === 'Buffer' && isArray(object.data)) {
array = object.data
length = checked(array.length) | 0
}
that = allocate(that, length)
for (var i = 0; i < length; i += 1) {
that[i] = array[i] & 255
}
return that
}
if (Buffer.TYPED_ARRAY_SUPPORT) {
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array
} else {
// pre-set for values that may exist in the future
Buffer.prototype.length = undefined
Buffer.prototype.parent = undefined
}
function allocate (that, length) {
if (Buffer.TYPED_ARRAY_SUPPORT) {
// Return an augmented `Uint8Array` instance, for best performance
that = Buffer._augment(new Uint8Array(length))
that.__proto__ = Buffer.prototype
} else {
// Fallback: Return an object instance of the Buffer class
that.length = length
that._isBuffer = true
}
var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
if (fromPool) that.parent = rootParent
return that
}
function checked (length) {
// Note: cannot use `length < kMaxLength` here because that fails when
// length is NaN (which is otherwise coerced to zero.)
if (length >= kMaxLength()) {
throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
'size: 0x' + kMaxLength().toString(16) + ' bytes')
}
return length | 0
}
function SlowBuffer (subject, encoding) {
if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
var buf = new Buffer(subject, encoding)
delete buf.parent
return buf
}
Buffer.isBuffer = function isBuffer (b) {
return !!(b != null && b._isBuffer)
}
Buffer.compare = function compare (a, b) {
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
throw new TypeError('Arguments must be Buffers')
}
if (a === b) return 0
var x = a.length
var y = b.length
var i = 0
var len = Math.min(x, y)
while (i < len) {
if (a[i] !== b[i]) break
++i
}
if (i !== len) {
x = a[i]
y = b[i]
}
if (x < y) return -1
if (y < x) return 1
return 0
}
Buffer.isEncoding = function isEncoding (encoding) {
switch (String(encoding).toLowerCase()) {
case 'hex':
case 'utf8':
case 'utf-8':
case 'ascii':
case 'binary':
case 'base64':
case 'raw':
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return true
default:
return false
}
}
Buffer.concat = function concat (list, length) {
if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
if (list.length === 0) {
return new Buffer(0)
}
var i
if (length === undefined) {
length = 0
for (i = 0; i < list.length; i++) {
length += list[i].length
}
}
var buf = new Buffer(length)
var pos = 0
for (i = 0; i < list.length; i++) {
var item = list[i]
item.copy(buf, pos)
pos += item.length
}
return buf
}
function byteLength (string, encoding) {
if (typeof string !== 'string') string = '' + string
var len = string.length
if (len === 0) return 0
// Use a for loop to avoid recursion
var loweredCase = false
for (;;) {
switch (encoding) {
case 'ascii':
case 'binary':
// Deprecated
case 'raw':
case 'raws':
return len
case 'utf8':
case 'utf-8':
return utf8ToBytes(string).length
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return len * 2
case 'hex':
return len >>> 1
case 'base64':
return base64ToBytes(string).length
default:
if (loweredCase) return utf8ToBytes(string).length // assume utf8
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.byteLength = byteLength
function slowToString (encoding, start, end) {
var loweredCase = false
start = start | 0
end = end === undefined || end === Infinity ? this.length : end | 0
if (!encoding) encoding = 'utf8'
if (start < 0) start = 0
if (end > this.length) end = this.length
if (end <= start) return ''
while (true) {
switch (encoding) {
case 'hex':
return hexSlice(this, start, end)
case 'utf8':
case 'utf-8':
return utf8Slice(this, start, end)
case 'ascii':
return asciiSlice(this, start, end)
case 'binary':
return binarySlice(this, start, end)
case 'base64':
return base64Slice(this, start, end)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return utf16leSlice(this, start, end)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = (encoding + '').toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toString = function toString () {
var length = this.length | 0
if (length === 0) return ''
if (arguments.length === 0) return utf8Slice(this, 0, length)
return slowToString.apply(this, arguments)
}
Buffer.prototype.equals = function equals (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return true
return Buffer.compare(this, b) === 0
}
Buffer.prototype.inspect = function inspect () {
var str = ''
var max = exports.INSPECT_MAX_BYTES
if (this.length > 0) {
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
if (this.length > max) str += ' ... '
}
return '<Buffer ' + str + '>'
}
Buffer.prototype.compare = function compare (b) {
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
if (this === b) return 0
return Buffer.compare(this, b)
}
Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
else if (byteOffset < -0x80000000) byteOffset = -0x80000000
byteOffset >>= 0
if (this.length === 0) return -1
if (byteOffset >= this.length) return -1
// Negative offsets start from the end of the buffer
if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
if (typeof val === 'string') {
if (val.length === 0) return -1 // special case: looking for empty string always fails
return String.prototype.indexOf.call(this, val, byteOffset)
}
if (Buffer.isBuffer(val)) {
return arrayIndexOf(this, val, byteOffset)
}
if (typeof val === 'number') {
if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
}
return arrayIndexOf(this, [ val ], byteOffset)
}
function arrayIndexOf (arr, val, byteOffset) {
var foundIndex = -1
for (var i = 0; byteOffset + i < arr.length; i++) {
if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
if (foundIndex === -1) foundIndex = i
if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
} else {
foundIndex = -1
}
}
return -1
}
throw new TypeError('val must be string, number or Buffer')
}
// `get` is deprecated
Buffer.prototype.get = function get (offset) {
console.log('.get() is deprecated. Access using array indexes instead.')
return this.readUInt8(offset)
}
// `set` is deprecated
Buffer.prototype.set = function set (v, offset) {
console.log('.set() is deprecated. Access using array indexes instead.')
return this.writeUInt8(v, offset)
}
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new Error('Invalid hex string')
if (length > strLen / 2) {
length = strLen / 2
}
for (var i = 0; i < length; i++) {
var parsed = parseInt(string.substr(i * 2, 2), 16)
if (isNaN(parsed)) throw new Error('Invalid hex string')
buf[offset + i] = parsed
}
return i
}
function utf8Write (buf, string, offset, length) {
return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}
function asciiWrite (buf, string, offset, length) {
return blitBuffer(asciiToBytes(string), buf, offset, length)
}
function binaryWrite (buf, string, offset, length) {
return asciiWrite(buf, string, offset, length)
}
function base64Write (buf, string, offset, length) {
return blitBuffer(base64ToBytes(string), buf, offset, length)
}
function ucs2Write (buf, string, offset, length) {
return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}
Buffer.prototype.write = function write (string, offset, length, encoding) {
// Buffer#write(string)
if (offset === undefined) {
encoding = 'utf8'
length = this.length
offset = 0
// Buffer#write(string, encoding)
} else if (length === undefined && typeof offset === 'string') {
encoding = offset
length = this.length
offset = 0
// Buffer#write(string, offset[, length][, encoding])
} else if (isFinite(offset)) {
offset = offset | 0
if (isFinite(length)) {
length = length | 0
if (encoding === undefined) encoding = 'utf8'
} else {
encoding = length
length = undefined
}
// legacy write(string, encoding, offset, length) - remove in v0.13
} else {
var swap = encoding
encoding = offset
offset = length | 0
length = swap
}
var remaining = this.length - offset
if (length === undefined || length > remaining) length = remaining
if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
throw new RangeError('attempt to write outside buffer bounds')
}
if (!encoding) encoding = 'utf8'
var loweredCase = false
for (;;) {
switch (encoding) {
case 'hex':
return hexWrite(this, string, offset, length)
case 'utf8':
case 'utf-8':
return utf8Write(this, string, offset, length)
case 'ascii':
return asciiWrite(this, string, offset, length)
case 'binary':
return binaryWrite(this, string, offset, length)
case 'base64':
// Warning: maxLength not taken into account in base64Write
return base64Write(this, string, offset, length)
case 'ucs2':
case 'ucs-2':
case 'utf16le':
case 'utf-16le':
return ucs2Write(this, string, offset, length)
default:
if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
encoding = ('' + encoding).toLowerCase()
loweredCase = true
}
}
}
Buffer.prototype.toJSON = function toJSON () {
return {
type: 'Buffer',
data: Array.prototype.slice.call(this._arr || this, 0)
}
}
function base64Slice (buf, start, end) {
if (start === 0 && end === buf.length) {
return base64.fromByteArray(buf)
} else {
return base64.fromByteArray(buf.slice(start, end))
}
}
function utf8Slice (buf, start, end) {
end = Math.min(buf.length, end)
var res = []
var i = start
while (i < end) {
var firstByte = buf[i]
var codePoint = null
var bytesPerSequence = (firstByte > 0xEF) ? 4
: (firstByte > 0xDF) ? 3
: (firstByte > 0xBF) ? 2
: 1
if (i + bytesPerSequence <= end) {
var secondByte, thirdByte, fourthByte, tempCodePoint
switch (bytesPerSequence) {
case 1:
if (firstByte < 0x80) {
codePoint = firstByte
}
break
case 2:
secondByte = buf[i + 1]
if ((secondByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
if (tempCodePoint > 0x7F) {
codePoint = tempCodePoint
}
}
break
case 3:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
codePoint = tempCodePoint
}
}
break
case 4:
secondByte = buf[i + 1]
thirdByte = buf[i + 2]
fourthByte = buf[i + 3]
if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
codePoint = tempCodePoint
}
}
}
}
if (codePoint === null) {
// we did not generate a valid codePoint so insert a
// replacement char (U+FFFD) and advance only 1 byte
codePoint = 0xFFFD
bytesPerSequence = 1
} else if (codePoint > 0xFFFF) {
// encode to utf16 (surrogate pair dance)
codePoint -= 0x10000
res.push(codePoint >>> 10 & 0x3FF | 0xD800)
codePoint = 0xDC00 | codePoint & 0x3FF
}
res.push(codePoint)
i += bytesPerSequence
}
return decodeCodePointsArray(res)
}
// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000
function decodeCodePointsArray (codePoints) {
var len = codePoints.length
if (len <= MAX_ARGUMENTS_LENGTH) {
return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
}
// Decode in chunks to avoid "call stack size exceeded".
var res = ''
var i = 0
while (i < len) {
res += String.fromCharCode.apply(
String,
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
)
}
return res
}
function asciiSlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
ret += String.fromCharCode(buf[i] & 0x7F)
}
return ret
}
function binarySlice (buf, start, end) {
var ret = ''
end = Math.min(buf.length, end)
for (var i = start; i < end; i++) {
ret += String.fromCharCode(buf[i])
}
return ret
}
function hexSlice (buf, start, end) {
var len = buf.length
if (!start || start < 0) start = 0
if (!end || end < 0 || end > len) end = len
var out = ''
for (var i = start; i < end; i++) {
out += toHex(buf[i])
}
return out
}
function utf16leSlice (buf, start, end) {
var bytes = buf.slice(start, end)
var res = ''
for (var i = 0; i < bytes.length; i += 2) {
res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
}
return res
}
Buffer.prototype.slice = function slice (start, end) {
var len = this.length
start = ~~start
end = end === undefined ? len : ~~end
if (start < 0) {
start += len
if (start < 0) start = 0
} else if (start > len) {
start = len
}
if (end < 0) {
end += len
if (end < 0) end = 0
} else if (end > len) {
end = len
}
if (end < start) end = start
var newBuf
if (Buffer.TYPED_ARRAY_SUPPORT) {
newBuf = Buffer._augment(this.subarray(start, end))
} else {
var sliceLen = end - start
newBuf = new Buffer(sliceLen, undefined)
for (var i = 0; i < sliceLen; i++) {
newBuf[i] = this[i + start]
}
}
if (newBuf.length) newBuf.parent = this.parent || this
return newBuf
}
/*
* Need to make sure that buffer isn't trying to write out of bounds.
*/
function checkOffset (offset, ext, length) {
if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}
Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
return val
}
Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) {
checkOffset(offset, byteLength, this.length)
}
var val = this[offset + --byteLength]
var mul = 1
while (byteLength > 0 && (mul *= 0x100)) {
val += this[offset + --byteLength] * mul
}
return val
}
Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
return this[offset]
}
Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return this[offset] | (this[offset + 1] << 8)
}
Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
return (this[offset] << 8) | this[offset + 1]
}
Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ((this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16)) +
(this[offset + 3] * 0x1000000)
}
Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] * 0x1000000) +
((this[offset + 1] << 16) |
(this[offset + 2] << 8) |
this[offset + 3])
}
Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var val = this[offset]
var mul = 1
var i = 0
while (++i < byteLength && (mul *= 0x100)) {
val += this[offset + i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkOffset(offset, byteLength, this.length)
var i = byteLength
var mul = 1
var val = this[offset + --i]
while (i > 0 && (mul *= 0x100)) {
val += this[offset + --i] * mul
}
mul *= 0x80
if (val >= mul) val -= Math.pow(2, 8 * byteLength)
return val
}
Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
if (!noAssert) checkOffset(offset, 1, this.length)
if (!(this[offset] & 0x80)) return (this[offset])
return ((0xff - this[offset] + 1) * -1)
}
Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset] | (this[offset + 1] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 2, this.length)
var val = this[offset + 1] | (this[offset] << 8)
return (val & 0x8000) ? val | 0xFFFF0000 : val
}
Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset]) |
(this[offset + 1] << 8) |
(this[offset + 2] << 16) |
(this[offset + 3] << 24)
}
Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return (this[offset] << 24) |
(this[offset + 1] << 16) |
(this[offset + 2] << 8) |
(this[offset + 3])
}
Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, true, 23, 4)
}
Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 4, this.length)
return ieee754.read(this, offset, false, 23, 4)
}
Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, true, 52, 8)
}
Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
if (!noAssert) checkOffset(offset, 8, this.length)
return ieee754.read(this, offset, false, 52, 8)
}
function checkInt (buf, value, offset, ext, max, min) {
if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
if (value > max || value < min) throw new RangeError('value is out of bounds')
if (offset + ext > buf.length) throw new RangeError('index out of range')
}
Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var mul = 1
var i = 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
byteLength = byteLength | 0
if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
var i = byteLength - 1
var mul = 1
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = (value / mul) & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
this[offset] = (value & 0xff)
return offset + 1
}
function objectWriteUInt16 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
(littleEndian ? i : 1 - i) * 8
}
}
Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
function objectWriteUInt32 (buf, value, offset, littleEndian) {
if (value < 0) value = 0xffffffff + value + 1
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
}
}
Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset + 3] = (value >>> 24)
this[offset + 2] = (value >>> 16)
this[offset + 1] = (value >>> 8)
this[offset] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = 0
var mul = 1
var sub = value < 0 ? 1 : 0
this[offset] = value & 0xFF
while (++i < byteLength && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) {
var limit = Math.pow(2, 8 * byteLength - 1)
checkInt(this, value, offset, byteLength, limit - 1, -limit)
}
var i = byteLength - 1
var mul = 1
var sub = value < 0 ? 1 : 0
this[offset + i] = value & 0xFF
while (--i >= 0 && (mul *= 0x100)) {
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
}
return offset + byteLength
}
Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
if (value < 0) value = 0xff + value + 1
this[offset] = (value & 0xff)
return offset + 1
}
Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
} else {
objectWriteUInt16(this, value, offset, true)
}
return offset + 2
}
Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 8)
this[offset + 1] = (value & 0xff)
} else {
objectWriteUInt16(this, value, offset, false)
}
return offset + 2
}
Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value & 0xff)
this[offset + 1] = (value >>> 8)
this[offset + 2] = (value >>> 16)
this[offset + 3] = (value >>> 24)
} else {
objectWriteUInt32(this, value, offset, true)
}
return offset + 4
}
Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
value = +value
offset = offset | 0
if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
if (value < 0) value = 0xffffffff + value + 1
if (Buffer.TYPED_ARRAY_SUPPORT) {
this[offset] = (value >>> 24)
this[offset + 1] = (value >>> 16)
this[offset + 2] = (value >>> 8)
this[offset + 3] = (value & 0xff)
} else {
objectWriteUInt32(this, value, offset, false)
}
return offset + 4
}
function checkIEEE754 (buf, value, offset, ext, max, min) {
if (value > max || value < min) throw new RangeError('value is out of bounds')
if (offset + ext > buf.length) throw new RangeError('index out of range')
if (offset < 0) throw new RangeError('index out of range')
}
function writeFloat (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
}
ieee754.write(buf, value, offset, littleEndian, 23, 4)
return offset + 4
}
Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
return writeFloat(this, value, offset, true, noAssert)
}
Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
return writeFloat(this, value, offset, false, noAssert)
}
function writeDouble (buf, value, offset, littleEndian, noAssert) {
if (!noAssert) {
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
}
ieee754.write(buf, value, offset, littleEndian, 52, 8)
return offset + 8
}
Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
return writeDouble(this, value, offset, true, noAssert)
}
Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
return writeDouble(this, value, offset, false, noAssert)
}
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
if (!start) start = 0
if (!end && end !== 0) end = this.length
if (targetStart >= target.length) targetStart = target.length
if (!targetStart) targetStart = 0
if (end > 0 && end < start) end = start
// Copy 0 bytes; we're done
if (end === start) return 0
if (target.length === 0 || this.length === 0) return 0
// Fatal error conditions
if (targetStart < 0) {
throw new RangeError('targetStart out of bounds')
}
if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
if (end < 0) throw new RangeError('sourceEnd out of bounds')
// Are we oob?
if (end > this.length) end = this.length
if (target.length - targetStart < end - start) {
end = target.length - targetStart + start
}
var len = end - start
var i
if (this === target && start < targetStart && targetStart < end) {
// descending copy from end
for (i = len - 1; i >= 0; i--) {
target[i + targetStart] = this[i + start]
}
} else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
// ascending copy from start
for (i = 0; i < len; i++) {
target[i + targetStart] = this[i + start]
}
} else {
target._set(this.subarray(start, start + len), targetStart)
}
return len
}
// fill(value, start=0, end=buffer.length)
Buffer.prototype.fill = function fill (value, start, end) {
if (!value) value = 0
if (!start) start = 0
if (!end) end = this.length
if (end < start) throw new RangeError('end < start')
// Fill 0 bytes; we're done
if (end === start) return
if (this.length === 0) return
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
var i
if (typeof value === 'number') {
for (i = start; i < end; i++) {
this[i] = value
}
} else {
var bytes = utf8ToBytes(value.toString())
var len = bytes.length
for (i = start; i < end; i++) {
this[i] = bytes[i % len]
}
}
return this
}
/**
* Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
* Added in Node 0.12. Only available in browsers that support ArrayBuffer.
*/
Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
if (typeof Uint8Array !== 'undefined') {
if (Buffer.TYPED_ARRAY_SUPPORT) {
return (new Buffer(this)).buffer
} else {
var buf = new Uint8Array(this.length)
for (var i = 0, len = buf.length; i < len; i += 1) {
buf[i] = this[i]
}
return buf.buffer
}
} else {
throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
}
}
// HELPER FUNCTIONS
// ================
var BP = Buffer.prototype
/**
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
*/
Buffer._augment = function _augment (arr) {
arr.constructor = Buffer
arr._isBuffer = true
// save reference to original Uint8Array set method before overwriting
arr._set = arr.set
// deprecated
arr.get = BP.get
arr.set = BP.set
arr.write = BP.write
arr.toString = BP.toString
arr.toLocaleString = BP.toString
arr.toJSON = BP.toJSON
arr.equals = BP.equals
arr.compare = BP.compare
arr.indexOf = BP.indexOf
arr.copy = BP.copy
arr.slice = BP.slice
arr.readUIntLE = BP.readUIntLE
arr.readUIntBE = BP.readUIntBE
arr.readUInt8 = BP.readUInt8
arr.readUInt16LE = BP.readUInt16LE
arr.readUInt16BE = BP.readUInt16BE
arr.readUInt32LE = BP.readUInt32LE
arr.readUInt32BE = BP.readUInt32BE
arr.readIntLE = BP.readIntLE
arr.readIntBE = BP.readIntBE
arr.readInt8 = BP.readInt8
arr.readInt16LE = BP.readInt16LE
arr.readInt16BE = BP.readInt16BE
arr.readInt32LE = BP.readInt32LE
arr.readInt32BE = BP.readInt32BE
arr.readFloatLE = BP.readFloatLE
arr.readFloatBE = BP.readFloatBE
arr.readDoubleLE = BP.readDoubleLE
arr.readDoubleBE = BP.readDoubleBE
arr.writeUInt8 = BP.writeUInt8
arr.writeUIntLE = BP.writeUIntLE
arr.writeUIntBE = BP.writeUIntBE
arr.writeUInt16LE = BP.writeUInt16LE
arr.writeUInt16BE = BP.writeUInt16BE
arr.writeUInt32LE = BP.writeUInt32LE
arr.writeUInt32BE = BP.writeUInt32BE
arr.writeIntLE = BP.writeIntLE
arr.writeIntBE = BP.writeIntBE
arr.writeInt8 = BP.writeInt8
arr.writeInt16LE = BP.writeInt16LE
arr.writeInt16BE = BP.writeInt16BE
arr.writeInt32LE = BP.writeInt32LE
arr.writeInt32BE = BP.writeInt32BE
arr.writeFloatLE = BP.writeFloatLE
arr.writeFloatBE = BP.writeFloatBE
arr.writeDoubleLE = BP.writeDoubleLE
arr.writeDoubleBE = BP.writeDoubleBE
arr.fill = BP.fill
arr.inspect = BP.inspect
arr.toArrayBuffer = BP.toArrayBuffer
return arr
}
var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
function base64clean (str) {
// Node strips out invalid characters like \n and \t from the string, base64-js does not
str = stringtrim(str).replace(INVALID_BASE64_RE, '')
// Node converts strings with length < 2 to ''
if (str.length < 2) return ''
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
while (str.length % 4 !== 0) {
str = str + '='
}
return str
}
function stringtrim (str) {
if (str.trim) return str.trim()
return str.replace(/^\s+|\s+$/g, '')
}
function toHex (n) {
if (n < 16) return '0' + n.toString(16)
return n.toString(16)
}
function utf8ToBytes (string, units) {
units = units || Infinity
var codePoint
var length = string.length
var leadSurrogate = null
var bytes = []
for (var i = 0; i < length; i++) {
codePoint = string.charCodeAt(i)
// is surrogate component
if (codePoint > 0xD7FF && codePoint < 0xE000) {
// last char was a lead
if (!leadSurrogate) {
// no lead yet
if (codePoint > 0xDBFF) {
// unexpected trail
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
} else if (i + 1 === length) {
// unpaired lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
continue
}
// valid lead
leadSurrogate = codePoint
continue
}
// 2 leads in a row
if (codePoint < 0xDC00) {
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
leadSurrogate = codePoint
continue
}
// valid surrogate pair
codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
} else if (leadSurrogate) {
// valid bmp char, but last char was a lead
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
}
leadSurrogate = null
// encode utf8
if (codePoint < 0x80) {
if ((units -= 1) < 0) break
bytes.push(codePoint)
} else if (codePoint < 0x800) {
if ((units -= 2) < 0) break
bytes.push(
codePoint >> 0x6 | 0xC0,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x10000) {
if ((units -= 3) < 0) break
bytes.push(
codePoint >> 0xC | 0xE0,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else if (codePoint < 0x110000) {
if ((units -= 4) < 0) break
bytes.push(
codePoint >> 0x12 | 0xF0,
codePoint >> 0xC & 0x3F | 0x80,
codePoint >> 0x6 & 0x3F | 0x80,
codePoint & 0x3F | 0x80
)
} else {
throw new Error('Invalid code point')
}
}
return bytes
}
function asciiToBytes (str) {
var byteArray = []
for (var i = 0; i < str.length; i++) {
// Node's code seems to be doing this and not & 0x7F..
byteArray.push(str.charCodeAt(i) & 0xFF)
}
return byteArray
}
function utf16leToBytes (str, units) {
var c, hi, lo
var byteArray = []
for (var i = 0; i < str.length; i++) {
if ((units -= 2) < 0) break
c = str.charCodeAt(i)
hi = c >> 8
lo = c % 256
byteArray.push(lo)
byteArray.push(hi)
}
return byteArray
}
function base64ToBytes (str) {
return base64.toByteArray(base64clean(str))
}
function blitBuffer (src, dst, offset, length) {
for (var i = 0; i < length; i++) {
if ((i + offset >= dst.length) || (i >= src.length)) break
dst[i + offset] = src[i]
}
return i
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"base64-js":5,"ieee754":47,"isarray":9}],9:[function(require,module,exports){
var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
},{}],10:[function(require,module,exports){
/*!
* domready (c) Dustin Diaz 2014 - License MIT
*/
!function (name, definition) {
if (typeof module != 'undefined') module.exports = definition()
else if (typeof define == 'function' && typeof define.amd == 'object') define(definition)
else this[name] = definition()
}('domready', function () {
var fns = [], listener
, doc = document
, hack = doc.documentElement.doScroll
, domContentLoaded = 'DOMContentLoaded'
, loaded = (hack ? /^loaded|^c/ : /^loaded|^i|^c/).test(doc.readyState)
if (!loaded)
doc.addEventListener(domContentLoaded, listener = function () {
doc.removeEventListener(domContentLoaded, listener)
loaded = 1
while (listener = fns.shift()) listener()
})
return function (fn) {
loaded ? setTimeout(fn, 0) : fns.push(fn)
}
});
},{}],11:[function(require,module,exports){
"use strict"
function dupe_array(count, value, i) {
var c = count[i]|0
if(c <= 0) {
return []
}
var result = new Array(c), j
if(i === count.length-1) {
for(j=0; j<c; ++j) {
result[j] = value
}
} else {
for(j=0; j<c; ++j) {
result[j] = dupe_array(count, value, i+1)
}
}
return result
}
function dupe_number(count, value) {
var result, i
result = new Array(count)
for(i=0; i<count; ++i) {
result[i] = value
}
return result
}
function dupe(count, value) {
if(typeof value === "undefined") {
value = 0
}
switch(typeof count) {
case "number":
if(count > 0) {
return dupe_number(count|0, value)
}
break
case "object":
if(typeof (count.length) === "number") {
return dupe_array(count, value, 0)
}
break
}
return []
}
module.exports = dupe
},{}],12:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
function EventEmitter() {
this._events = this._events || {};
this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
EventEmitter.defaultMaxListeners = 10;
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function(n) {
if (!isNumber(n) || n < 0 || isNaN(n))
throw TypeError('n must be a positive number');
this._maxListeners = n;
return this;
};
EventEmitter.prototype.emit = function(type) {
var er, handler, len, args, i, listeners;
if (!this._events)
this._events = {};
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events.error ||
(isObject(this._events.error) && !this._events.error.length)) {
er = arguments[1];
if (er instanceof Error) {
throw er; // Unhandled 'error' event
}
throw TypeError('Uncaught, unspecified "error" event.');
}
}
handler = this._events[type];
if (isUndefined(handler))
return false;
if (isFunction(handler)) {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
handler.apply(this, args);
}
} else if (isObject(handler)) {
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
listeners = handler.slice();
len = listeners.length;
for (i = 0; i < len; i++)
listeners[i].apply(this, args);
}
return true;
};
EventEmitter.prototype.addListener = function(type, listener) {
var m;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events)
this._events = {};
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (this._events.newListener)
this.emit('newListener', type,
isFunction(listener.listener) ?
listener.listener : listener);
if (!this._events[type])
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
else if (isObject(this._events[type]))
// If we've already got an array, just append.
this._events[type].push(listener);
else
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
// Check for listener leak
if (isObject(this._events[type]) && !this._events[type].warned) {
var m;
if (!isUndefined(this._maxListeners)) {
m = this._maxListeners;
} else {
m = EventEmitter.defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
if (typeof console.trace === 'function') {
// not supported in IE 10
console.trace();
}
}
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
if (!isFunction(listener))
throw TypeError('listener must be a function');
var fired = false;
function g() {
this.removeListener(type, g);
if (!fired) {
fired = true;
listener.apply(this, arguments);
}
}
g.listener = listener;
this.on(type, g);
return this;
};
// emits a 'removeListener' event iff the listener was removed
EventEmitter.prototype.removeListener = function(type, listener) {
var list, position, length, i;
if (!isFunction(listener))
throw TypeError('listener must be a function');
if (!this._events || !this._events[type])
return this;
list = this._events[type];
length = list.length;
position = -1;
if (list === listener ||
(isFunction(list.listener) && list.listener === listener)) {
delete this._events[type];
if (this._events.removeListener)
this.emit('removeListener', type, listener);
} else if (isObject(list)) {
for (i = length; i-- > 0;) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener)) {
position = i;
break;
}
}
if (position < 0)
return this;
if (list.length === 1) {
list.length = 0;
delete this._events[type];
} else {
list.splice(position, 1);
}
if (this._events.removeListener)
this.emit('removeListener', type, listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
var key, listeners;
if (!this._events)
return this;
// not listening for removeListener, no need to emit
if (!this._events.removeListener) {
if (arguments.length === 0)
this._events = {};
else if (this._events[type])
delete this._events[type];
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (key in this._events) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = {};
return this;
}
listeners = this._events[type];
if (isFunction(listeners)) {
this.removeListener(type, listeners);
} else {
// LIFO order
while (listeners.length)
this.removeListener(type, listeners[listeners.length - 1]);
}
delete this._events[type];
return this;
};
EventEmitter.prototype.listeners = function(type) {
var ret;
if (!this._events || !this._events[type])
ret = [];
else if (isFunction(this._events[type]))
ret = [this._events[type]];
else
ret = this._events[type].slice();
return ret;
};
EventEmitter.listenerCount = function(emitter, type) {
var ret;
if (!emitter._events || !emitter._events[type])
ret = 0;
else if (isFunction(emitter._events[type]))
ret = 1;
else
ret = emitter._events[type].length;
return ret;
};
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isUndefined(arg) {
return arg === void 0;
}
},{}],13:[function(require,module,exports){
if(typeof window.performance === "object") {
if(window.performance.now) {
module.exports = function() { return window.performance.now() }
} else if(window.performance.webkitNow) {
module.exports = function() { return window.performance.webkitNow() }
}
} else if(Date.now) {
module.exports = Date.now
} else {
module.exports = function() { return (new Date()).getTime() }
}
},{}],14:[function(require,module,exports){
//Adapted from here: https://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel?redirectlocale=en-US&redirectslug=DOM%2FMozilla_event_reference%2Fwheel
var prefix = "", _addEventListener, onwheel, support;
// detect event model
if ( window.addEventListener ) {
_addEventListener = "addEventListener";
} else {
_addEventListener = "attachEvent";
prefix = "on";
}
// detect available wheel event
support = "onwheel" in document.createElement("div") ? "wheel" : // Modern browsers support "wheel"
document.onmousewheel !== undefined ? "mousewheel" : // Webkit and IE support at least "mousewheel"
"DOMMouseScroll"; // let's assume that remaining browsers are older Firefox
function _addWheelListener( elem, eventName, callback, useCapture ) {
elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) {
!originalEvent && ( originalEvent = window.event );
// create a normalized event object
var event = {
// keep a ref to the original event object
originalEvent: originalEvent,
target: originalEvent.target || originalEvent.srcElement,
type: "wheel",
deltaMode: originalEvent.type == "MozMousePixelScroll" ? 0 : 1,
deltaX: 0,
delatZ: 0,
preventDefault: function() {
originalEvent.preventDefault ?
originalEvent.preventDefault() :
originalEvent.returnValue = false;
}
};
// calculate deltaY (and deltaX) according to the event
if ( support == "mousewheel" ) {
event.deltaY = - 1/40 * originalEvent.wheelDelta;
// Webkit also support wheelDeltaX
originalEvent.wheelDeltaX && ( event.deltaX = - 1/40 * originalEvent.wheelDeltaX );
} else {
event.deltaY = originalEvent.detail;
}
// it's time to fire the callback
return callback( event );
}, useCapture || false );
}
module.exports = function( elem, callback, useCapture ) {
_addWheelListener( elem, support, callback, useCapture );
// handle MozMousePixelScroll in older Firefox
if( support == "DOMMouseScroll" ) {
_addWheelListener( elem, "MozMousePixelScroll", callback, useCapture );
}
};
},{}],15:[function(require,module,exports){
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// MIT license
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
},{}],16:[function(require,module,exports){
"use strict"
var EventEmitter = require("events").EventEmitter
, util = require("util")
, domready = require("domready")
, vkey = require("vkey")
, invert = require("invert-hash")
, uniq = require("uniq")
, bsearch = require("binary-search-bounds")
, iota = require("iota-array")
, min = Math.min
//Browser compatibility hacks
require("./lib/raf-polyfill.js")
var addMouseWheel = require("./lib/mousewheel-polyfill.js")
var hrtime = require("./lib/hrtime-polyfill.js")
//Remove angle braces and other useless crap
var filtered_vkey = (function() {
var result = new Array(256)
, i, j, k
for(i=0; i<256; ++i) {
result[i] = "UNK"
}
for(i in vkey) {
k = vkey[i]
if(k.charAt(0) === '<' && k.charAt(k.length-1) === '>') {
k = k.substring(1, k.length-1)
}
k = k.replace(/\s/g, "-")
result[parseInt(i)] = k
}
return result
})()
//Compute minimal common set of keyboard functions
var keyNames = uniq(Object.keys(invert(filtered_vkey)))
//Translates a virtual keycode to a normalized keycode
function virtualKeyCode(key) {
return bsearch.eq(keyNames, key)
}
//Maps a physical keycode to a normalized keycode
function physicalKeyCode(key) {
return virtualKeyCode(filtered_vkey[key])
}
//Game shell
function GameShell() {
EventEmitter.call(this)
this._curKeyState = new Array(keyNames.length)
this._pressCount = new Array(keyNames.length)
this._releaseCount = new Array(keyNames.length)
this._tickInterval = null
this._rafHandle = null
this._tickRate = 0
this._lastTick = hrtime()
this._frameTime = 0.0
this._paused = true
this._width = 0
this._height = 0
this._wantFullscreen = false
this._wantPointerLock = false
this._fullscreenActive = false
this._pointerLockActive = false
this._render = render.bind(undefined, this)
this.preventDefaults = true
this.stopPropagation = false
for(var i=0; i<keyNames.length; ++i) {
this._curKeyState[i] = false
this._pressCount[i] = this._releaseCount[i] = 0
}
//Public members
this.element = null
this.bindings = {}
this.frameSkip = 100.0
this.tickCount = 0
this.frameCount = 0
this.startTime = hrtime()
this.tickTime = this._tickRate
this.frameTime = 10.0
this.stickyFullscreen = false
this.stickyPointerLock = false
//Scroll stuff
this.scroll = [0,0,0]
//Mouse state
this.mouseX = 0
this.mouseY = 0
this.prevMouseX = 0
this.prevMouseY = 0
}
util.inherits(GameShell, EventEmitter)
var proto = GameShell.prototype
//Bind keynames
proto.keyNames = keyNames
//Binds a virtual keyboard event to a physical key
proto.bind = function(virtual_key) {
//Look up previous key bindings
var arr
if(virtual_key in this.bindings) {
arr = this.bindings[virtual_key]
} else {
arr = []
}
//Add keys to list
var physical_key
for(var i=1, n=arguments.length; i<n; ++i) {
physical_key = arguments[i]
if(virtualKeyCode(physical_key) >= 0) {
arr.push(physical_key)
} else if(physical_key in this.bindings) {
var keybinds = this.bindings[physical_key]
for(var j=0; j<keybinds.length; ++j) {
arr.push(keybinds[j])
}
}
}
//Remove any duplicate keys
arr = uniq(arr)
if(arr.length > 0) {
this.bindings[virtual_key] = arr
}
this.emit('bind', virtual_key, arr)
}
//Unbinds a virtual keyboard event
proto.unbind = function(virtual_key) {
if(virtual_key in this.bindings) {
delete this.bindings[virtual_key]
}
this.emit('unbind', virtual_key)
}
//Checks if a key is set in a given state
function lookupKey(state, bindings, key) {
if(key in bindings) {
var arr = bindings[key]
for(var i=0, n=arr.length; i<n; ++i) {
if(state[virtualKeyCode(arr[i])]) {
return true
}
}
return false
}
var kc = virtualKeyCode(key)
if(kc >= 0) {
return state[kc]
}
return false
}
//Checks if a key is set in a given state
function lookupCount(state, bindings, key) {
if(key in bindings) {
var arr = bindings[key], r = 0
for(var i=0, n=arr.length; i<n; ++i) {
r += state[virtualKeyCode(arr[i])]
}
return r
}
var kc = virtualKeyCode(key)
if(kc >= 0) {
return state[kc]
}
return 0
}
//Checks if a key (either physical or virtual) is currently held down
proto.down = function(key) {
return lookupKey(this._curKeyState, this.bindings, key)
}
//Checks if a key was ever down
proto.wasDown = function(key) {
return this.down(key) || !!this.press(key)
}
//Opposite of down
proto.up = function(key) {
return !this.down(key)
}
//Checks if a key was released during previous frame
proto.wasUp = function(key) {
return this.up(key) || !!this.release(key)
}
//Returns the number of times a key was pressed since last tick
proto.press = function(key) {
return lookupCount(this._pressCount, this.bindings, key)
}
//Returns the number of times a key was released since last tick
proto.release = function(key) {
return lookupCount(this._releaseCount, this.bindings, key)
}
//Pause/unpause the game loop
Object.defineProperty(proto, "paused", {
get: function() {
return this._paused
},
set: function(state) {
var ns = !!state
if(ns !== this._paused) {
if(!this._paused) {
this._paused = true
this._frameTime = min(1.0, (hrtime() - this._lastTick) / this._tickRate)
clearInterval(this._tickInterval)
//cancelAnimationFrame(this._rafHandle)
} else {
this._paused = false
this._lastTick = hrtime() - Math.floor(this._frameTime * this._tickRate)
this._tickInterval = setInterval(tick, this._tickRate, this)
this._rafHandle = requestAnimationFrame(this._render)
}
}
}
})
//Fullscreen state toggle
function tryFullscreen(shell) {
//Request full screen
var elem = shell.element
if(shell._wantFullscreen && !shell._fullscreenActive) {
var fs = elem.requestFullscreen ||
elem.requestFullScreen ||
elem.webkitRequestFullscreen ||
elem.webkitRequestFullScreen ||
elem.mozRequestFullscreen ||
elem.mozRequestFullScreen ||
function() {}
fs.call(elem)
}
if(shell._wantPointerLock && !shell._pointerLockActive) {
var pl = elem.requestPointerLock ||
elem.webkitRequestPointerLock ||
elem.mozRequestPointerLock ||
elem.msRequestPointerLock ||
elem.oRequestPointerLock ||
function() {}
pl.call(elem)
}
}
var cancelFullscreen = document.exitFullscreen ||
document.cancelFullscreen || //Why can no one agree on this?
document.cancelFullScreen ||
document.webkitCancelFullscreen ||
document.webkitCancelFullScreen ||
document.mozCancelFullscreen ||
document.mozCancelFullScreen ||
function(){}
Object.defineProperty(proto, "fullscreen", {
get: function() {
return this._fullscreenActive
},
set: function(state) {
var ns = !!state
if(!ns) {
this._wantFullscreen = false
cancelFullscreen.call(document)
} else {
this._wantFullscreen = true
tryFullscreen(this)
}
return this._fullscreenActive
}
})
function handleFullscreen(shell) {
shell._fullscreenActive = document.fullscreen ||
document.mozFullScreen ||
document.webkitIsFullScreen ||
false
if(!shell.stickyFullscreen && shell._fullscreenActive) {
shell._wantFullscreen = false
}
}
//Pointer lock state toggle
var exitPointerLock = document.exitPointerLock ||
document.webkitExitPointerLock ||
document.mozExitPointerLock ||
function() {}
Object.defineProperty(proto, "pointerLock", {
get: function() {
return this._pointerLockActive
},
set: function(state) {
var ns = !!state
if(!ns) {
this._wantPointerLock = false
exitPointerLock.call(document)
} else {
this._wantPointerLock = true
tryFullscreen(this)
}
return this._pointerLockActive
}
})
function handlePointerLockChange(shell, event) {
shell._pointerLockActive = shell.element === (
document.pointerLockElement ||
document.mozPointerLockElement ||
document.webkitPointerLockElement ||
null)
if(!shell.stickyPointerLock && shell._pointerLockActive) {
shell._wantPointerLock = false
}
}
//Width and height
Object.defineProperty(proto, "width", {
get: function() {
return this.element.clientWidth
}
})
Object.defineProperty(proto, "height", {
get: function() {
return this.element.clientHeight
}
})
//Set key state
function setKeyState(shell, key, state) {
var ps = shell._curKeyState[key]
if(ps !== state) {
if(state) {
shell._pressCount[key]++
} else {
shell._releaseCount[key]++
}
shell._curKeyState[key] = state
}
}
//Ticks the game state one update
function tick(shell) {
var skip = hrtime() + shell.frameSkip
, pCount = shell._pressCount
, rCount = shell._releaseCount
, i, s, t
, tr = shell._tickRate
, n = keyNames.length
while(!shell._paused &&
hrtime() >= shell._lastTick + tr) {
//Skip frames if we are over budget
if(hrtime() > skip) {
shell._lastTick = hrtime() + tr
return
}
//Tick the game
s = hrtime()
shell.emit("tick")
t = hrtime()
shell.tickTime = t - s
//Update counters and time
++shell.tickCount
shell._lastTick += tr
//Shift input state
for(i=0; i<n; ++i) {
pCount[i] = rCount[i] = 0
}
if(shell._pointerLockActive) {
shell.prevMouseX = shell.mouseX = shell.width>>1
shell.prevMouseY = shell.mouseY = shell.height>>1
} else {
shell.prevMouseX = shell.mouseX
shell.prevMouseY = shell.mouseY
}
shell.scroll[0] = shell.scroll[1] = shell.scroll[2] = 0
}
}
//Render stuff
function render(shell) {
//Request next frame
shell._rafHandle = requestAnimationFrame(shell._render)
//Tick the shell
tick(shell)
//Compute frame time
var dt
if(shell._paused) {
dt = shell._frameTime
} else {
dt = min(1.0, (hrtime() - shell._lastTick) / shell._tickRate)
}
//Draw a frame
++shell.frameCount
var s = hrtime()
shell.emit("render", dt)
var t = hrtime()
shell.frameTime = t - s
}
function isFocused(shell) {
return (document.activeElement === document.body) ||
(document.activeElement === shell.element)
}
function handleEvent(shell, ev) {
if(shell.preventDefaults) {
ev.preventDefault()
}
if(shell.stopPropagation) {
ev.stopPropagation()
}
}
//Set key up
function handleKeyUp(shell, ev) {
handleEvent(shell, ev)
var kc = physicalKeyCode(ev.keyCode || ev.char || ev.which || ev.charCode)
if(kc >= 0) {
setKeyState(shell, kc, false)
}
}
//Set key down
function handleKeyDown(shell, ev) {
if(!isFocused(shell)) {
return
}
handleEvent(shell, ev)
if(ev.metaKey) {
//Hack: Clear key state when meta gets pressed to prevent keys sticking
handleBlur(shell, ev)
} else {
var kc = physicalKeyCode(ev.keyCode || ev.char || ev.which || ev.charCode)
if(kc >= 0) {
setKeyState(shell, kc, true)
}
}
}
//Mouse events are really annoying
var mouseCodes = iota(32).map(function(n) {
return virtualKeyCode("mouse-" + (n+1))
})
function setMouseButtons(shell, buttons) {
for(var i=0; i<32; ++i) {
setKeyState(shell, mouseCodes[i], !!(buttons & (1<<i)))
}
}
function handleMouseMove(shell, ev) {
handleEvent(shell, ev)
if(shell._pointerLockActive) {
var movementX = ev.movementX ||
ev.mozMovementX ||
ev.webkitMovementX ||
0,
movementY = ev.movementY ||
ev.mozMovementY ||
ev.webkitMovementY ||
0
shell.mouseX += movementX
shell.mouseY += movementY
} else {
shell.mouseX = ev.clientX - shell.element.offsetLeft
shell.mouseY = ev.clientY - shell.element.offsetTop
}
return false
}
function handleMouseDown(shell, ev) {
handleEvent(shell, ev)
setKeyState(shell, mouseCodes[ev.button], true)
return false
}
function handleMouseUp(shell, ev) {
handleEvent(shell, ev)
setKeyState(shell, mouseCodes[ev.button], false)
return false
}
function handleMouseEnter(shell, ev) {
handleEvent(shell, ev)
if(shell._pointerLockActive) {
shell.prevMouseX = shell.mouseX = shell.width>>1
shell.prevMouseY = shell.mouseY = shell.height>>1
} else {
shell.prevMouseX = shell.mouseX = ev.clientX - shell.element.offsetLeft
shell.prevMouseY = shell.mouseY = ev.clientY - shell.element.offsetTop
}
return false
}
function handleMouseLeave(shell, ev) {
handleEvent(shell, ev)
setMouseButtons(shell, 0)
return false
}
//Handle mouse wheel events
function handleMouseWheel(shell, ev) {
handleEvent(shell, ev)
var scale = 1
switch(ev.deltaMode) {
case 0: //Pixel
scale = 1
break
case 1: //Line
scale = 12
break
case 2: //Page
scale = shell.height
break
}
//Add scroll
shell.scroll[0] += ev.deltaX * scale
shell.scroll[1] += ev.deltaY * scale
shell.scroll[2] += (ev.deltaZ * scale)||0.0
return false
}
function handleContexMenu(shell, ev) {
handleEvent(shell, ev)
return false
}
function handleBlur(shell, ev) {
var n = keyNames.length
, c = shell._curKeyState
, r = shell._releaseCount
, i
for(i=0; i<n; ++i) {
if(c[i]) {
++r[i]
}
c[i] = false
}
return false
}
function handleResizeElement(shell, ev) {
var w = shell.element.clientWidth|0
var h = shell.element.clientHeight|0
if((w !== shell._width) || (h !== shell._height)) {
shell._width = w
shell._height = h
shell.emit("resize", w, h)
}
}
function makeDefaultContainer() {
var container = document.createElement("div")
container.tabindex = 1
container.style.position = "absolute"
container.style.left = "0px"
container.style.right = "0px"
container.style.top = "0px"
container.style.bottom = "0px"
container.style.height = "100%"
container.style.overflow = "hidden"
document.body.appendChild(container)
document.body.style.overflow = "hidden" //Prevent bounce
document.body.style.height = "100%"
return container
}
function createShell(options) {
options = options || {}
//Check fullscreen and pointer lock flags
var useFullscreen = !!options.fullscreen
var usePointerLock = useFullscreen
if(typeof options.pointerLock !== undefined) {
usePointerLock = !!options.pointerLock
}
//Create initial shell
var shell = new GameShell()
shell._tickRate = options.tickRate || 30
shell.frameSkip = options.frameSkip || (shell._tickRate+5) * 5
shell.stickyFullscreen = !!options.stickyFullscreen || !!options.sticky
shell.stickyPointerLock = !!options.stickyPointerLock || !!options.sticky
//Set bindings
if(options.bindings) {
shell.bindings = options.bindings
}
//Wait for dom to intiailize
setTimeout(function() { domready(function initGameShell() {
//Retrieve element
var element = options.element
if(typeof element === "string") {
var e = document.querySelector(element)
if(!e) {
e = document.getElementById(element)
}
if(!e) {
e = document.getElementByClass(element)[0]
}
if(!e) {
e = makeDefaultContainer()
}
shell.element = e
} else if(typeof element === "object" && !!element) {
shell.element = element
} else if(typeof element === "function") {
shell.element = element()
} else {
shell.element = makeDefaultContainer()
}
//Disable user-select
if(shell.element.style) {
shell.element.style["-webkit-touch-callout"] = "none"
shell.element.style["-webkit-user-select"] = "none"
shell.element.style["-khtml-user-select"] = "none"
shell.element.style["-moz-user-select"] = "none"
shell.element.style["-ms-user-select"] = "none"
shell.element.style["user-select"] = "none"
}
//Hook resize handler
shell._width = shell.element.clientWidth
shell._height = shell.element.clientHeight
var handleResize = handleResizeElement.bind(undefined, shell)
if(typeof MutationObserver !== "undefined") {
var observer = new MutationObserver(handleResize)
observer.observe(shell.element, {
attributes: true,
subtree: true
})
} else {
shell.element.addEventListener("DOMSubtreeModified", handleResize, false)
}
window.addEventListener("resize", handleResize, false)
//Hook keyboard listener
window.addEventListener("keydown", handleKeyDown.bind(undefined, shell), false)
window.addEventListener("keyup", handleKeyUp.bind(undefined, shell), false)
//Disable right click
shell.element.oncontextmenu = handleContexMenu.bind(undefined, shell)
//Hook mouse listeners
shell.element.addEventListener("mousedown", handleMouseDown.bind(undefined, shell), false)
shell.element.addEventListener("mouseup", handleMouseUp.bind(undefined, shell), false)
shell.element.addEventListener("mousemove", handleMouseMove.bind(undefined, shell), false)
shell.element.addEventListener("mouseenter", handleMouseEnter.bind(undefined, shell), false)
//Mouse leave
var leave = handleMouseLeave.bind(undefined, shell)
shell.element.addEventListener("mouseleave", leave, false)
shell.element.addEventListener("mouseout", leave, false)
window.addEventListener("mouseleave", leave, false)
window.addEventListener("mouseout", leave, false)
//Blur event
var blur = handleBlur.bind(undefined, shell)
shell.element.addEventListener("blur", blur, false)
shell.element.addEventListener("focusout", blur, false)
shell.element.addEventListener("focus", blur, false)
window.addEventListener("blur", blur, false)
window.addEventListener("focusout", blur, false)
window.addEventListener("focus", blur, false)
//Mouse wheel handler
addMouseWheel(shell.element, handleMouseWheel.bind(undefined, shell), false)
//Fullscreen handler
var fullscreenChange = handleFullscreen.bind(undefined, shell)
document.addEventListener("fullscreenchange", fullscreenChange, false)
document.addEventListener("mozfullscreenchange", fullscreenChange, false)
document.addEventListener("webkitfullscreenchange", fullscreenChange, false)
//Stupid fullscreen hack
shell.element.addEventListener("click", tryFullscreen.bind(undefined, shell), false)
//Pointer lock change handler
var pointerLockChange = handlePointerLockChange.bind(undefined, shell)
document.addEventListener("pointerlockchange", pointerLockChange, false)
document.addEventListener("mozpointerlockchange", pointerLockChange, false)
document.addEventListener("webkitpointerlockchange", pointerLockChange, false)
document.addEventListener("pointerlocklost", pointerLockChange, false)
document.addEventListener("webkitpointerlocklost", pointerLockChange, false)
document.addEventListener("mozpointerlocklost", pointerLockChange, false)
//Update flags
shell.fullscreen = useFullscreen
shell.pointerLock = usePointerLock
//Default mouse button aliases
shell.bind("mouse-left", "mouse-1")
shell.bind("mouse-right", "mouse-3")
shell.bind("mouse-middle", "mouse-2")
//Initialize tick counter
shell._lastTick = hrtime()
shell.startTime = hrtime()
//Unpause shell
shell.paused = false
//Emit initialize event
shell.emit("init")
})}, 0)
return shell
}
module.exports = createShell
},{"./lib/hrtime-polyfill.js":13,"./lib/mousewheel-polyfill.js":14,"./lib/raf-polyfill.js":15,"binary-search-bounds":6,"domready":10,"events":12,"invert-hash":48,"iota-array":49,"uniq":62,"util":65,"vkey":66}],17:[function(require,module,exports){
"use strict"
var pool = require("typedarray-pool")
var ops = require("ndarray-ops")
var ndarray = require("ndarray")
function GLBuffer(gl, type, handle, length, usage) {
this.gl = gl
this.type = type
this.handle = handle
this.length = length
this.usage = usage
}
GLBuffer.prototype.bind = function() {
this.gl.bindBuffer(this.type, this.handle)
}
GLBuffer.prototype.dispose = function() {
this.gl.deleteBuffer(this.handle)
}
function updateTypeArray(gl, type, len, usage, data, offset) {
if(offset <= 0 && data.length > len) {
gl.bufferData(type, data, usage)
return data.length
}
if(data.length + offset > len) {
throw new Error("gl-buffer: If resizing buffer, offset must be 0")
}
gl.bufferSubData(type, offset, data)
return len
}
function makeScratchTypeArray(array, dtype) {
var res = pool.malloc(array.length, dtype)
var n = array.length
for(var i=0; i<n; ++i) {
res[i] = array[i]
}
return res
}
GLBuffer.prototype.update = function(array, offset) {
if(!offset) {
offset = 0
}
this.bind()
if(typeof array === "number") {
if(offset > 0) {
throw new Error("gl-buffer: Cannot specify offset when resizing buffer")
}
this.gl.bufferData(this.type, array, this.usage)
this.length = array
} else if(array.shape) {
var dtype = array.dtype
if(dtype === "float64" || dtype === "array" || dtype === "generic") {
dtype = "float32"
}
if(this.type === this.gl.ELEMENT_ARRAY_BUFFER) {
dtype = "uint16"
}
if(array.shape.length !== 1) {
throw new Error("gl-buffer: Array length must be 1")
}
if(dtype === array.dtype && array.stride[0] === 1) {
if(array.offset === 0 && array.data.length === array.shape[0]) {
this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array.data, offset)
} else {
this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array.data.subarray(array.offset, array.shape[0]), offset)
}
} else {
var tmp = pool.malloc(array.shape[0], dtype)
var ndt = ndarray(tmp)
ops.assign(ndt, array)
this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, tmp, offset)
pool.free(tmp)
}
} else if(Array.isArray(array)) {
if(this.type === this.gl.ELEMENT_ARRAY_BUFFER) {
var t = makeScratchTypeArray(array, "uint16")
this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, t.subarray(0, array.length), offset)
pool.freeUint16(t)
} else {
var t = makeScratchTypeArray(array, "float32")
this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, t.subarray(0, array.length), offset)
pool.freeFloat32(t)
}
} else {
this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array, offset)
}
}
GLBuffer.prototype.draw = function(mode, count, offset) {
offset = offset || 0
var gl = this.gl
if(this.type === gl.ARRAY_BUFFER) {
gl.drawArrays(mode, offset, count)
} else if(this.type === gl.ELEMENT_ARRAY_BUFFER) {
this.bind()
gl.drawElements(mode, count, gl.UNSIGNED_SHORT, offset)
} else {
throw new Error("Invalid type for WebGL buffer")
}
}
function createBuffer(gl, type, data, usage) {
if(data === undefined) {
data = type
type = gl.ARRAY_BUFFER
}
if(!usage) {
usage = gl.DYNAMIC_DRAW
}
var len = 0
var handle = gl.createBuffer()
gl.bindBuffer(type, handle)
if(typeof data === "number") {
gl.bufferData(type, data, usage)
len = data
} else if(data instanceof Array) {
if(type === gl.ELEMENT_ARRAY_BUFFER) {
gl.bufferData(type, new Uint16Array(data), usage)
} else {
gl.bufferData(type, new Float32Array(data), usage)
}
len = data.length
} else if(data.length) {
gl.bufferData(type, data, usage)
len = data.length
} else if(data.shape) {
var dtype = data.dtype
if(dtype === "float64" || dtype === "array" || dtype === "generic") {
dtype = "float32"
}
if(type === gl.ELEMENT_ARRAY_BUFFER) {
dtype = "uint16"
}
if(data.shape.length !== 1) {
throw new Error("gl-buffer: Array shape must be 1D")
}
var len = data.shape[0]
if(dtype === data.type && data.stride[0] === 1) {
gl.bufferData(type, data.data.subarray(data.offset, data.offset+len), usage)
} else {
var tmp = pool.malloc(data.shape[0], dtype)
var ndt = ndarray(tmp)
ops.assign(ndt, data)
gl.bufferData(type, tmp, usage)
pool.free(tmp)
}
} else {
throw new Error("gl-buffer: Invalid format for buffer data")
}
if(type !== gl.ARRAY_BUFFER && type !== gl.ELEMENT_ARRAY_BUFFER) {
throw new Error("gl-buffer: Invalid type for webgl buffer")
}
if(usage !== gl.DYNAMIC_DRAW && usage !== gl.STATIC_DRAW && usage !== gl.STREAM_DRAW) {
throw new Error("gl-buffer: Invalid usage for buffer")
}
return new GLBuffer(gl, type, handle, len, usage)
}
module.exports = createBuffer
},{"ndarray":55,"ndarray-ops":51,"typedarray-pool":61}],18:[function(require,module,exports){
module.exports = {
0: 'NONE',
1: 'ONE',
2: 'LINE_LOOP',
3: 'LINE_STRIP',
4: 'TRIANGLES',
5: 'TRIANGLE_STRIP',
6: 'TRIANGLE_FAN',
256: 'DEPTH_BUFFER_BIT',
512: 'NEVER',
513: 'LESS',
514: 'EQUAL',
515: 'LEQUAL',
516: 'GREATER',
517: 'NOTEQUAL',
518: 'GEQUAL',
519: 'ALWAYS',
768: 'SRC_COLOR',
769: 'ONE_MINUS_SRC_COLOR',
770: 'SRC_ALPHA',
771: 'ONE_MINUS_SRC_ALPHA',
772: 'DST_ALPHA',
773: 'ONE_MINUS_DST_ALPHA',
774: 'DST_COLOR',
775: 'ONE_MINUS_DST_COLOR',
776: 'SRC_ALPHA_SATURATE',
1024: 'STENCIL_BUFFER_BIT',
1028: 'FRONT',
1029: 'BACK',
1032: 'FRONT_AND_BACK',
1280: 'INVALID_ENUM',
1281: 'INVALID_VALUE',
1282: 'INVALID_OPERATION',
1285: 'OUT_OF_MEMORY',
1286: 'INVALID_FRAMEBUFFER_OPERATION',
2304: 'CW',
2305: 'CCW',
2849: 'LINE_WIDTH',
2884: 'CULL_FACE',
2885: 'CULL_FACE_MODE',
2886: 'FRONT_FACE',
2928: 'DEPTH_RANGE',
2929: 'DEPTH_TEST',
2930: 'DEPTH_WRITEMASK',
2931: 'DEPTH_CLEAR_VALUE',
2932: 'DEPTH_FUNC',
2960: 'STENCIL_TEST',
2961: 'STENCIL_CLEAR_VALUE',
2962: 'STENCIL_FUNC',
2963: 'STENCIL_VALUE_MASK',
2964: 'STENCIL_FAIL',
2965: 'STENCIL_PASS_DEPTH_FAIL',
2966: 'STENCIL_PASS_DEPTH_PASS',
2967: 'STENCIL_REF',
2968: 'STENCIL_WRITEMASK',
2978: 'VIEWPORT',
3024: 'DITHER',
3042: 'BLEND',
3088: 'SCISSOR_BOX',
3089: 'SCISSOR_TEST',
3106: 'COLOR_CLEAR_VALUE',
3107: 'COLOR_WRITEMASK',
3317: 'UNPACK_ALIGNMENT',
3333: 'PACK_ALIGNMENT',
3379: 'MAX_TEXTURE_SIZE',
3386: 'MAX_VIEWPORT_DIMS',
3408: 'SUBPIXEL_BITS',
3410: 'RED_BITS',
3411: 'GREEN_BITS',
3412: 'BLUE_BITS',
3413: 'ALPHA_BITS',
3414: 'DEPTH_BITS',
3415: 'STENCIL_BITS',
3553: 'TEXTURE_2D',
4352: 'DONT_CARE',
4353: 'FASTEST',
4354: 'NICEST',
5120: 'BYTE',
5121: 'UNSIGNED_BYTE',
5122: 'SHORT',
5123: 'UNSIGNED_SHORT',
5124: 'INT',
5125: 'UNSIGNED_INT',
5126: 'FLOAT',
5386: 'INVERT',
5890: 'TEXTURE',
6401: 'STENCIL_INDEX',
6402: 'DEPTH_COMPONENT',
6406: 'ALPHA',
6407: 'RGB',
6408: 'RGBA',
6409: 'LUMINANCE',
6410: 'LUMINANCE_ALPHA',
7680: 'KEEP',
7681: 'REPLACE',
7682: 'INCR',
7683: 'DECR',
7936: 'VENDOR',
7937: 'RENDERER',
7938: 'VERSION',
9728: 'NEAREST',
9729: 'LINEAR',
9984: 'NEAREST_MIPMAP_NEAREST',
9985: 'LINEAR_MIPMAP_NEAREST',
9986: 'NEAREST_MIPMAP_LINEAR',
9987: 'LINEAR_MIPMAP_LINEAR',
10240: 'TEXTURE_MAG_FILTER',
10241: 'TEXTURE_MIN_FILTER',
10242: 'TEXTURE_WRAP_S',
10243: 'TEXTURE_WRAP_T',
10497: 'REPEAT',
10752: 'POLYGON_OFFSET_UNITS',
16384: 'COLOR_BUFFER_BIT',
32769: 'CONSTANT_COLOR',
32770: 'ONE_MINUS_CONSTANT_COLOR',
32771: 'CONSTANT_ALPHA',
32772: 'ONE_MINUS_CONSTANT_ALPHA',
32773: 'BLEND_COLOR',
32774: 'FUNC_ADD',
32777: 'BLEND_EQUATION_RGB',
32778: 'FUNC_SUBTRACT',
32779: 'FUNC_REVERSE_SUBTRACT',
32819: 'UNSIGNED_SHORT_4_4_4_4',
32820: 'UNSIGNED_SHORT_5_5_5_1',
32823: 'POLYGON_OFFSET_FILL',
32824: 'POLYGON_OFFSET_FACTOR',
32854: 'RGBA4',
32855: 'RGB5_A1',
32873: 'TEXTURE_BINDING_2D',
32926: 'SAMPLE_ALPHA_TO_COVERAGE',
32928: 'SAMPLE_COVERAGE',
32936: 'SAMPLE_BUFFERS',
32937: 'SAMPLES',
32938: 'SAMPLE_COVERAGE_VALUE',
32939: 'SAMPLE_COVERAGE_INVERT',
32968: 'BLEND_DST_RGB',
32969: 'BLEND_SRC_RGB',
32970: 'BLEND_DST_ALPHA',
32971: 'BLEND_SRC_ALPHA',
33071: 'CLAMP_TO_EDGE',
33170: 'GENERATE_MIPMAP_HINT',
33189: 'DEPTH_COMPONENT16',
33306: 'DEPTH_STENCIL_ATTACHMENT',
33635: 'UNSIGNED_SHORT_5_6_5',
33648: 'MIRRORED_REPEAT',
33901: 'ALIASED_POINT_SIZE_RANGE',
33902: 'ALIASED_LINE_WIDTH_RANGE',
33984: 'TEXTURE0',
33985: 'TEXTURE1',
33986: 'TEXTURE2',
33987: 'TEXTURE3',
33988: 'TEXTURE4',
33989: 'TEXTURE5',
33990: 'TEXTURE6',
33991: 'TEXTURE7',
33992: 'TEXTURE8',
33993: 'TEXTURE9',
33994: 'TEXTURE10',
33995: 'TEXTURE11',
33996: 'TEXTURE12',
33997: 'TEXTURE13',
33998: 'TEXTURE14',
33999: 'TEXTURE15',
34000: 'TEXTURE16',
34001: 'TEXTURE17',
34002: 'TEXTURE18',
34003: 'TEXTURE19',
34004: 'TEXTURE20',
34005: 'TEXTURE21',
34006: 'TEXTURE22',
34007: 'TEXTURE23',
34008: 'TEXTURE24',
34009: 'TEXTURE25',
34010: 'TEXTURE26',
34011: 'TEXTURE27',
34012: 'TEXTURE28',
34013: 'TEXTURE29',
34014: 'TEXTURE30',
34015: 'TEXTURE31',
34016: 'ACTIVE_TEXTURE',
34024: 'MAX_RENDERBUFFER_SIZE',
34041: 'DEPTH_STENCIL',
34055: 'INCR_WRAP',
34056: 'DECR_WRAP',
34067: 'TEXTURE_CUBE_MAP',
34068: 'TEXTURE_BINDING_CUBE_MAP',
34069: 'TEXTURE_CUBE_MAP_POSITIVE_X',
34070: 'TEXTURE_CUBE_MAP_NEGATIVE_X',
34071: 'TEXTURE_CUBE_MAP_POSITIVE_Y',
34072: 'TEXTURE_CUBE_MAP_NEGATIVE_Y',
34073: 'TEXTURE_CUBE_MAP_POSITIVE_Z',
34074: 'TEXTURE_CUBE_MAP_NEGATIVE_Z',
34076: 'MAX_CUBE_MAP_TEXTURE_SIZE',
34338: 'VERTEX_ATTRIB_ARRAY_ENABLED',
34339: 'VERTEX_ATTRIB_ARRAY_SIZE',
34340: 'VERTEX_ATTRIB_ARRAY_STRIDE',
34341: 'VERTEX_ATTRIB_ARRAY_TYPE',
34342: 'CURRENT_VERTEX_ATTRIB',
34373: 'VERTEX_ATTRIB_ARRAY_POINTER',
34466: 'NUM_COMPRESSED_TEXTURE_FORMATS',
34467: 'COMPRESSED_TEXTURE_FORMATS',
34660: 'BUFFER_SIZE',
34661: 'BUFFER_USAGE',
34816: 'STENCIL_BACK_FUNC',
34817: 'STENCIL_BACK_FAIL',
34818: 'STENCIL_BACK_PASS_DEPTH_FAIL',
34819: 'STENCIL_BACK_PASS_DEPTH_PASS',
34877: 'BLEND_EQUATION_ALPHA',
34921: 'MAX_VERTEX_ATTRIBS',
34922: 'VERTEX_ATTRIB_ARRAY_NORMALIZED',
34930: 'MAX_TEXTURE_IMAGE_UNITS',
34962: 'ARRAY_BUFFER',
34963: 'ELEMENT_ARRAY_BUFFER',
34964: 'ARRAY_BUFFER_BINDING',
34965: 'ELEMENT_ARRAY_BUFFER_BINDING',
34975: 'VERTEX_ATTRIB_ARRAY_BUFFER_BINDING',
35040: 'STREAM_DRAW',
35044: 'STATIC_DRAW',
35048: 'DYNAMIC_DRAW',
35632: 'FRAGMENT_SHADER',
35633: 'VERTEX_SHADER',
35660: 'MAX_VERTEX_TEXTURE_IMAGE_UNITS',
35661: 'MAX_COMBINED_TEXTURE_IMAGE_UNITS',
35663: 'SHADER_TYPE',
35664: 'FLOAT_VEC2',
35665: 'FLOAT_VEC3',
35666: 'FLOAT_VEC4',
35667: 'INT_VEC2',
35668: 'INT_VEC3',
35669: 'INT_VEC4',
35670: 'BOOL',
35671: 'BOOL_VEC2',
35672: 'BOOL_VEC3',
35673: 'BOOL_VEC4',
35674: 'FLOAT_MAT2',
35675: 'FLOAT_MAT3',
35676: 'FLOAT_MAT4',
35678: 'SAMPLER_2D',
35680: 'SAMPLER_CUBE',
35712: 'DELETE_STATUS',
35713: 'COMPILE_STATUS',
35714: 'LINK_STATUS',
35715: 'VALIDATE_STATUS',
35716: 'INFO_LOG_LENGTH',
35717: 'ATTACHED_SHADERS',
35718: 'ACTIVE_UNIFORMS',
35719: 'ACTIVE_UNIFORM_MAX_LENGTH',
35720: 'SHADER_SOURCE_LENGTH',
35721: 'ACTIVE_ATTRIBUTES',
35722: 'ACTIVE_ATTRIBUTE_MAX_LENGTH',
35724: 'SHADING_LANGUAGE_VERSION',
35725: 'CURRENT_PROGRAM',
36003: 'STENCIL_BACK_REF',
36004: 'STENCIL_BACK_VALUE_MASK',
36005: 'STENCIL_BACK_WRITEMASK',
36006: 'FRAMEBUFFER_BINDING',
36007: 'RENDERBUFFER_BINDING',
36048: 'FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE',
36049: 'FRAMEBUFFER_ATTACHMENT_OBJECT_NAME',
36050: 'FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL',
36051: 'FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE',
36053: 'FRAMEBUFFER_COMPLETE',
36054: 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT',
36055: 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT',
36057: 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS',
36061: 'FRAMEBUFFER_UNSUPPORTED',
36064: 'COLOR_ATTACHMENT0',
36096: 'DEPTH_ATTACHMENT',
36128: 'STENCIL_ATTACHMENT',
36160: 'FRAMEBUFFER',
36161: 'RENDERBUFFER',
36162: 'RENDERBUFFER_WIDTH',
36163: 'RENDERBUFFER_HEIGHT',
36164: 'RENDERBUFFER_INTERNAL_FORMAT',
36168: 'STENCIL_INDEX8',
36176: 'RENDERBUFFER_RED_SIZE',
36177: 'RENDERBUFFER_GREEN_SIZE',
36178: 'RENDERBUFFER_BLUE_SIZE',
36179: 'RENDERBUFFER_ALPHA_SIZE',
36180: 'RENDERBUFFER_DEPTH_SIZE',
36181: 'RENDERBUFFER_STENCIL_SIZE',
36194: 'RGB565',
36336: 'LOW_FLOAT',
36337: 'MEDIUM_FLOAT',
36338: 'HIGH_FLOAT',
36339: 'LOW_INT',
36340: 'MEDIUM_INT',
36341: 'HIGH_INT',
36346: 'SHADER_COMPILER',
36347: 'MAX_VERTEX_UNIFORM_VECTORS',
36348: 'MAX_VARYING_VECTORS',
36349: 'MAX_FRAGMENT_UNIFORM_VECTORS',
37440: 'UNPACK_FLIP_Y_WEBGL',
37441: 'UNPACK_PREMULTIPLY_ALPHA_WEBGL',
37442: 'CONTEXT_LOST_WEBGL',
37443: 'UNPACK_COLORSPACE_CONVERSION_WEBGL',
37444: 'BROWSER_DEFAULT_WEBGL'
}
},{}],19:[function(require,module,exports){
var gl10 = require('./1.0/numbers')
module.exports = function lookupConstant (number) {
return gl10[number]
}
},{"./1.0/numbers":18}],20:[function(require,module,exports){
var raf = require('raf-component')
module.exports = createContext
function createContext(canvas, opts, render) {
if (typeof opts === 'function') {
render = opts
opts = {}
} else {
opts = opts || {}
}
var gl = (
canvas.getContext('webgl', opts) ||
canvas.getContext('webgl-experimental', opts) ||
canvas.getContext('experimental-webgl', opts)
)
if (!gl) {
throw new Error('Unable to initialize WebGL')
}
if (render) raf(tick)
return gl
function tick() {
render(gl)
raf(tick)
}
}
},{"raf-component":58}],21:[function(require,module,exports){
var sprintf = require('sprintf-js').sprintf;
var glConstants = require('gl-constants/lookup');
var shaderName = require('glsl-shader-name');
var addLineNumbers = require('add-line-numbers');
module.exports = formatCompilerError;
function formatCompilerError(errLog, src, type) {
"use strict";
var name = shaderName(src) || 'of unknown name (see npm glsl-shader-name)';
var typeName = 'unknown type';
if (type !== undefined) {
typeName = type === glConstants.FRAGMENT_SHADER ? 'fragment' : 'vertex'
}
var longForm = sprintf('Error compiling %s shader %s:\n', typeName, name);
var shortForm = sprintf("%s%s", longForm, errLog);
var errorStrings = errLog.split('\n');
var errors = {};
for (var i = 0; i < errorStrings.length; i++) {
var errorString = errorStrings[i];
if (errorString === '' || errorString === "\0") continue;
var lineNo = parseInt(errorString.split(':')[2]);
if (isNaN(lineNo)) {
throw new Error(sprintf('Could not parse error: %s', errorString));
}
errors[lineNo] = errorString;
}
var lines = addLineNumbers(src).split('\n');
for (var i = 0; i < lines.length; i++) {
if (!errors[i+3] && !errors[i+2] && !errors[i+1]) continue;
var line = lines[i];
longForm += line + '\n';
if (errors[i+1]) {
var e = errors[i+1];
e = e.substr(e.split(':', 3).join(':').length + 1).trim();
longForm += sprintf('^^^ %s\n\n', e);
}
}
return {
long: longForm.trim(),
short: shortForm.trim()
};
}
},{"add-line-numbers":3,"gl-constants/lookup":19,"glsl-shader-name":39,"sprintf-js":60}],22:[function(require,module,exports){
"use strict"
var makeGameShell = require("game-shell")
var webglew = require("webglew")
function createGLShell(options) {
options = options || {}
var extensions = options.extensions || []
//First create shell
var shell = makeGameShell(options)
var scale = shell.scale || 1
shell.on("init", function initGLNow() {
//Create canvas
var canvas = document.createElement("canvas")
//Try initializing WebGL
var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl")
if(!gl) {
shell.emit("gl-error", new Error("Unable to initialize WebGL"))
return
}
//Check extensions
var ext = webglew(gl)
for(var i=0; i<extensions.length; ++i) {
if(!(extensions[i] in ext)) {
shell.emit("gl-error", new Error("Missing extension: " + extensions[i]))
return
}
}
//Set canvas style
canvas.style.position = "absolute"
canvas.style.left = "0px"
canvas.style.top = "0px"
shell.element.appendChild(canvas)
//Add variables to game-shell
shell.canvas = canvas
shell.gl = gl
//Load width/height
resize()
//Load default parameters
shell.clearFlags = options.clearFlags === undefined ? (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) : options.clearFlags
shell.clearColor = options.clearColor || [0,0,0,0]
shell.clearDepth = options.clearDepth || 1.0
shell.clearStencil = options.clearStencil || 0
shell.on("resize", resize)
//Hook render event
shell.on("render", function renderGLNow(t) {
//Bind default framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
//Set viewport
gl.viewport(0, 0, (shell._width / scale)|0, (shell._height / scale)|0)
//Clear buffers
if(shell.clearFlags & gl.STENCIL_BUFFER_BIT) {
gl.clearStencil(shell.clearStencil)
}
if(shell.clearFlags & gl.COLOR_BUFFER_BIT) {
gl.clearColor(shell.clearColor[0], shell.clearColor[1], shell.clearColor[2], shell.clearColor[3])
}
if(shell.clearFlags & gl.DEPTH_BUFFER_BIT) {
gl.clearDepth(shell.clearDepth)
}
if(shell.clearFlags) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
}
//Render frame
shell.emit("gl-render", t)
})
//WebGL initialized
shell.emit("gl-init")
})
function resize() {
var nw = (shell._width/scale)|0
var nh = (shell._height/scale)|0
shell.canvas.width = nw
shell.canvas.height = nh
shell.canvas.style.width = shell._width + 'px'
shell.canvas.style.height = shell._height + 'px'
shell.emit("gl-resize", nw, nh)
}
Object.defineProperty(shell, 'scale', {
get: function() {
return scale
},
set: function(_scale) {
_scale = +_scale
if((_scale <= 0) || isNaN(_scale) || (scale === _scale)) {
return scale
}
scale = _scale
resize()
return scale
}
})
Object.defineProperty(shell, "width", {
get: function() {
return (shell._width / scale)|0
}
})
Object.defineProperty(shell, "height", {
get: function() {
return (shell._height / scale)|0
}
})
Object.defineProperty(shell, "mouse", {
get: function() {
return [shell.mouseX/scale, shell.mouseY/scale]
}
})
Object.defineProperty(shell, "prevMouse", {
get: function() {
return [shell.prevMouseX/scale, shell.prevMouseY/scale]
}
})
return shell
}
module.exports = createGLShell
},{"game-shell":16,"webglew":71}],23:[function(require,module,exports){
'use strict'
var createUniformWrapper = require('./lib/create-uniforms')
var createAttributeWrapper = require('./lib/create-attributes')
var makeReflect = require('./lib/reflect')
var shaderCache = require('./lib/shader-cache')
var runtime = require('./lib/runtime-reflect')
var GLError = require("./lib/GLError")
//Shader object
function Shader(gl) {
this.gl = gl
this.gl.lastAttribCount = 0 // fixme where else should we store info, safe but not nice on the gl object
//Default initialize these to null
this._vref =
this._fref =
this._relink =
this.vertShader =
this.fragShader =
this.program =
this.attributes =
this.uniforms =
this.types = null
}
var proto = Shader.prototype
proto.bind = function() {
if(!this.program) {
this._relink()
}
// ensuring that we have the right number of enabled vertex attributes
var i
var newAttribCount = this.gl.getProgramParameter(this.program, this.gl.ACTIVE_ATTRIBUTES) // more robust approach
//var newAttribCount = Object.keys(this.attributes).length // avoids the probably immaterial introspection slowdown
var oldAttribCount = this.gl.lastAttribCount
if(newAttribCount > oldAttribCount) {
for(i = oldAttribCount; i < newAttribCount; i++) {
this.gl.enableVertexAttribArray(i)
}
} else if(oldAttribCount > newAttribCount) {
for(i = newAttribCount; i < oldAttribCount; i++) {
this.gl.disableVertexAttribArray(i)
}
}
this.gl.lastAttribCount = newAttribCount
this.gl.useProgram(this.program)
}
proto.dispose = function() {
// disabling vertex attributes so new shader starts with zero
// and it's also useful if all shaders are disposed but the
// gl context is reused for subsequent replotting
var oldAttribCount = this.gl.lastAttribCount
for (var i = 0; i < oldAttribCount; i++) {
this.gl.disableVertexAttribArray(i)
}
this.gl.lastAttribCount = 0
if(this._fref) {
this._fref.dispose()
}
if(this._vref) {
this._vref.dispose()
}
this.attributes =
this.types =
this.vertShader =
this.fragShader =
this.program =
this._relink =
this._fref =
this._vref = null
}
function compareAttributes(a, b) {
if(a.name < b.name) {
return -1
}
return 1
}
//Update export hook for glslify-live
proto.update = function(
vertSource
, fragSource
, uniforms
, attributes) {
//If only one object passed, assume glslify style output
if(!fragSource || arguments.length === 1) {
var obj = vertSource
vertSource = obj.vertex
fragSource = obj.fragment
uniforms = obj.uniforms
attributes = obj.attributes
}
var wrapper = this
var gl = wrapper.gl
//Compile vertex and fragment shaders
var pvref = wrapper._vref
wrapper._vref = shaderCache.shader(gl, gl.VERTEX_SHADER, vertSource)
if(pvref) {
pvref.dispose()
}
wrapper.vertShader = wrapper._vref.shader
var pfref = this._fref
wrapper._fref = shaderCache.shader(gl, gl.FRAGMENT_SHADER, fragSource)
if(pfref) {
pfref.dispose()
}
wrapper.fragShader = wrapper._fref.shader
//If uniforms/attributes is not specified, use RT reflection
if(!uniforms || !attributes) {
//Create initial test program
var testProgram = gl.createProgram()
gl.attachShader(testProgram, wrapper.fragShader)
gl.attachShader(testProgram, wrapper.vertShader)
gl.linkProgram(testProgram)
if(!gl.getProgramParameter(testProgram, gl.LINK_STATUS)) {
var errLog = gl.getProgramInfoLog(testProgram)
throw new GLError(errLog, 'Error linking program:' + errLog)
}
//Load data from runtime
uniforms = uniforms || runtime.uniforms(gl, testProgram)
attributes = attributes || runtime.attributes(gl, testProgram)
//Release test program
gl.deleteProgram(testProgram)
}
//Sort attributes lexicographically
// overrides undefined WebGL behavior for attribute locations
attributes = attributes.slice()
attributes.sort(compareAttributes)
//Convert attribute types, read out locations
var attributeUnpacked = []
var attributeNames = []
var attributeLocations = []
var i
for(i=0; i<attributes.length; ++i) {
var attr = attributes[i]
if(attr.type.indexOf('mat') >= 0) {
var size = attr.type.charAt(attr.type.length-1)|0
var locVector = new Array(size)
for(var j=0; j<size; ++j) {
locVector[j] = attributeLocations.length
attributeNames.push(attr.name + '[' + j + ']')
if(typeof attr.location === 'number') {
attributeLocations.push(attr.location + j)
} else if(Array.isArray(attr.location) &&
attr.location.length === size &&
typeof attr.location[j] === 'number') {
attributeLocations.push(attr.location[j]|0)
} else {
attributeLocations.push(-1)
}
}
attributeUnpacked.push({
name: attr.name,
type: attr.type,
locations: locVector
})
} else {
attributeUnpacked.push({
name: attr.name,
type: attr.type,
locations: [ attributeLocations.length ]
})
attributeNames.push(attr.name)
if(typeof attr.location === 'number') {
attributeLocations.push(attr.location|0)
} else {
attributeLocations.push(-1)
}
}
}
//For all unspecified attributes, assign them lexicographically min attribute
var curLocation = 0
for(i=0; i<attributeLocations.length; ++i) {
if(attributeLocations[i] < 0) {
while(attributeLocations.indexOf(curLocation) >= 0) {
curLocation += 1
}
attributeLocations[i] = curLocation
}
}
//Rebuild program and recompute all uniform locations
var uniformLocations = new Array(uniforms.length)
function relink() {
wrapper.program = shaderCache.program(
gl
, wrapper._vref
, wrapper._fref
, attributeNames
, attributeLocations)
for(var i=0; i<uniforms.length; ++i) {
uniformLocations[i] = gl.getUniformLocation(
wrapper.program
, uniforms[i].name)
}
}
//Perform initial linking, reuse program used for reflection
relink()
//Save relinking procedure, defer until runtime
wrapper._relink = relink
//Generate type info
wrapper.types = {
uniforms: makeReflect(uniforms),
attributes: makeReflect(attributes)
}
//Generate attribute wrappers
wrapper.attributes = createAttributeWrapper(
gl
, wrapper
, attributeUnpacked
, attributeLocations)
//Generate uniform wrappers
Object.defineProperty(wrapper, 'uniforms', createUniformWrapper(
gl
, wrapper
, uniforms
, uniformLocations))
}
//Compiles and links a shader program with the given attribute and vertex list
function createShader(
gl
, vertSource
, fragSource
, uniforms
, attributes) {
var shader = new Shader(gl)
shader.update(
vertSource
, fragSource
, uniforms
, attributes)
return shader
}
module.exports = createShader
},{"./lib/GLError":24,"./lib/create-attributes":25,"./lib/create-uniforms":26,"./lib/reflect":27,"./lib/runtime-reflect":28,"./lib/shader-cache":29}],24:[function(require,module,exports){
function GLError (rawError, shortMessage, longMessage) {
this.shortMessage = shortMessage || ''
this.longMessage = longMessage || ''
this.rawError = rawError || ''
this.message =
'gl-shader: ' + (shortMessage || rawError || '') +
(longMessage ? '\n'+longMessage : '')
this.stack = (new Error()).stack
}
GLError.prototype = new Error
GLError.prototype.name = 'GLError'
GLError.prototype.constructor = GLError
module.exports = GLError
},{}],25:[function(require,module,exports){
'use strict'
module.exports = createAttributeWrapper
var GLError = require("./GLError")
function ShaderAttribute(
gl
, wrapper
, index
, locations
, dimension
, constFunc) {
this._gl = gl
this._wrapper = wrapper
this._index = index
this._locations = locations
this._dimension = dimension
this._constFunc = constFunc
}
var proto = ShaderAttribute.prototype
proto.pointer = function setAttribPointer(
type
, normalized
, stride
, offset) {
var self = this
var gl = self._gl
var location = self._locations[self._index]
gl.vertexAttribPointer(
location
, self._dimension
, type || gl.FLOAT
, !!normalized
, stride || 0
, offset || 0)
gl.enableVertexAttribArray(location)
}
proto.set = function(x0, x1, x2, x3) {
return this._constFunc(this._locations[this._index], x0, x1, x2, x3)
}
Object.defineProperty(proto, 'location', {
get: function() {
return this._locations[this._index]
}
, set: function(v) {
if(v !== this._locations[this._index]) {
this._locations[this._index] = v|0
this._wrapper.program = null
}
return v|0
}
})
var allFns = [
function (gl, v, x0) {
if (x0.length === undefined) {
return gl.vertexAttrib1f(v, x0)
} else {
return gl.vertexAttrib1fv(v, x0)
}
},
function (gl, v, x0, x1) {
if (x0.length === undefined) {
return gl.vertexAttrib2f(v, x0, x1)
} else {
return gl.vertexAttrib2fv(v, x0)
}
},
function (gl, v, x0, x1, x2) {
if (x0.length === undefined) {
return gl.vertexAttrib3f(v, x0, x1, x2)
} else {
return gl.vertexAttrib3fv(v, x0)
}
},
function (gl, v, x0, x1, x2, x3) {
if (x0.length === undefined) {
return gl.vertexAttrib4f(v, x0, x1, x2, x3)
} else {
return gl.vertexAttrib4fv(v, x0)
}
}
]
//Adds a vector attribute to obj
function addVectorAttribute(
gl
, wrapper
, index
, locations
, dimension
, obj
, name) {
var constFunc = allFns[dimension]
//Create attribute wrapper
var attr = new ShaderAttribute(
gl
, wrapper
, index
, locations
, dimension
, constFunc)
//Create accessor
Object.defineProperty(obj, name, {
set: function(x) {
gl.disableVertexAttribArray(locations[index])
constFunc(gl, locations[index], x)
return x
}
, get: function() {
return attr
}
, enumerable: true
})
}
function addMatrixAttribute(
gl
, wrapper
, index
, locations
, dimension
, obj
, name) {
var parts = new Array(dimension)
var attrs = new Array(dimension)
for(var i=0; i<dimension; ++i) {
addVectorAttribute(
gl
, wrapper
, index[i]
, locations
, dimension
, parts
, i)
attrs[i] = parts[i]
}
Object.defineProperty(parts, 'location', {
set: function(v) {
if(Array.isArray(v)) {
for(var i=0; i<dimension; ++i) {
attrs[i].location = v[i]
}
} else {
for(var i=0; i<dimension; ++i) {
attrs[i].location = v + i
}
}
return v
}
, get: function() {
var result = new Array(dimension)
for(var i=0; i<dimension; ++i) {
result[i] = locations[index[i]]
}
return result
}
, enumerable: true
})
parts.pointer = function(type, normalized, stride, offset) {
type = type || gl.FLOAT
normalized = !!normalized
stride = stride || (dimension * dimension)
offset = offset || 0
for(var i=0; i<dimension; ++i) {
var location = locations[index[i]]
gl.vertexAttribPointer(
location
, dimension
, type
, normalized
, stride
, offset + i * dimension)
gl.enableVertexAttribArray(location)
}
}
var scratch = new Array(dimension)
var vertexAttrib = gl['vertexAttrib' + dimension + 'fv']
Object.defineProperty(obj, name, {
set: function(x) {
for(var i=0; i<dimension; ++i) {
var loc = locations[index[i]]
gl.disableVertexAttribArray(loc)
if(Array.isArray(x[0])) {
vertexAttrib.call(gl, loc, x[i])
} else {
for(var j=0; j<dimension; ++j) {
scratch[j] = x[dimension*i + j]
}
vertexAttrib.call(gl, loc, scratch)
}
}
return x
}
, get: function() {
return parts
}
, enumerable: true
})
}
//Create shims for attributes
function createAttributeWrapper(
gl
, wrapper
, attributes
, locations) {
var obj = {}
for(var i=0, n=attributes.length; i<n; ++i) {
var a = attributes[i]
var name = a.name
var type = a.type
var locs = a.locations
switch(type) {
case 'bool':
case 'int':
case 'float':
addVectorAttribute(
gl
, wrapper
, locs[0]
, locations
, 1
, obj
, name)
break
default:
if(type.indexOf('vec') >= 0) {
var d = type.charCodeAt(type.length-1) - 48
if(d < 2 || d > 4) {
throw new GLError('', 'Invalid data type for attribute ' + name + ': ' + type)
}
addVectorAttribute(
gl
, wrapper
, locs[0]
, locations
, d
, obj
, name)
} else if(type.indexOf('mat') >= 0) {
var d = type.charCodeAt(type.length-1) - 48
if(d < 2 || d > 4) {
throw new GLError('', 'Invalid data type for attribute ' + name + ': ' + type)
}
addMatrixAttribute(
gl
, wrapper
, locs
, locations
, d
, obj
, name)
} else {
throw new GLError('', 'Unknown data type for attribute ' + name + ': ' + type)
}
break
}
}
return obj
}
},{"./GLError":24}],26:[function(require,module,exports){
'use strict'
var coallesceUniforms = require('./reflect')
var GLError = require("./GLError")
module.exports = createUniformWrapper
//Binds a function and returns a value
function identity(x) {
return function() {
return x
}
}
function makeVector(length, fill) {
var result = new Array(length)
for(var i=0; i<length; ++i) {
result[i] = fill
}
return result
}
//Create shims for uniforms
function createUniformWrapper(gl, wrapper, uniforms, locations) {
function makeGetter(idx) {
return function(gl, wrapper, locations) {
return gl.getUniform(wrapper.program, locations[idx])
}
}
function makeSetter(type) {
return function updateProperty(obj){
var indices = enumerateIndices('', type)
for(var i=0; i<indices.length; ++i) {
var item = indices[i]
var path = item[0]
var idx = item[1]
if(locations[idx]) {
var objPath = obj
if(typeof path === 'string' && (
path.indexOf('.') === 0 ||
path.indexOf('[') === 0
)) {
var key = path
if(path.indexOf('.') === 0) {
key = path.slice(1)
}
if(key.indexOf(']') === key.length - 1) {
var j = key.indexOf('[')
var k1 = key.slice(0, j)
var k2 = key.slice(j + 1, key.length - 1)
objPath = k1? obj[k1][k2] : obj[k2]
} else {
objPath = obj[key]
}
}
var t = uniforms[idx].type
var d
switch(t) {
case 'bool':
case 'int':
case 'sampler2D':
case 'samplerCube':
gl.uniform1i(locations[idx], objPath)
break
case 'float':
gl.uniform1f(locations[idx], objPath)
break
default:
var vidx = t.indexOf('vec')
if(0 <= vidx && vidx <= 1 && t.length === 4 + vidx) {
d = t.charCodeAt(t.length-1) - 48
if(d < 2 || d > 4) {
throw new GLError('', 'Invalid data type')
}
switch(t.charAt(0)) {
case 'b':
case 'i':
gl['uniform' + d + 'iv'](locations[idx], objPath)
break
case 'v':
gl['uniform' + d + 'fv'](locations[idx], objPath)
break
default:
throw new GLError('', 'Unrecognized data type for vector ' + name + ': ' + t)
}
} else if(t.indexOf('mat') === 0 && t.length === 4) {
d = t.charCodeAt(t.length-1) - 48
if(d < 2 || d > 4) {
throw new GLError('', 'Invalid uniform dimension type for matrix ' + name + ': ' + t)
}
gl['uniformMatrix' + d + 'fv'](locations[idx], false, objPath)
break
} else {
throw new GLError('', 'Unknown uniform data type for ' + name + ': ' + t)
}
}
}
}
}
}
function enumerateIndices(prefix, type) {
if(typeof type !== 'object') {
return [ [prefix, type] ]
}
var indices = []
for(var id in type) {
var prop = type[id]
var tprefix = prefix
if(parseInt(id) + '' === id) {
tprefix += '[' + id + ']'
} else {
tprefix += '.' + id
}
if(typeof prop === 'object') {
indices.push.apply(indices, enumerateIndices(tprefix, prop))
} else {
indices.push([tprefix, prop])
}
}
return indices
}
function defaultValue(type) {
switch(type) {
case 'bool':
return false
case 'int':
case 'sampler2D':
case 'samplerCube':
return 0
case 'float':
return 0.0
default:
var vidx = type.indexOf('vec')
if(0 <= vidx && vidx <= 1 && type.length === 4 + vidx) {
var d = type.charCodeAt(type.length-1) - 48
if(d < 2 || d > 4) {
throw new GLError('', 'Invalid data type')
}
if(type.charAt(0) === 'b') {
return makeVector(d, false)
}
return makeVector(d, 0)
} else if(type.indexOf('mat') === 0 && type.length === 4) {
var d = type.charCodeAt(type.length-1) - 48
if(d < 2 || d > 4) {
throw new GLError('', 'Invalid uniform dimension type for matrix ' + name + ': ' + type)
}
return makeVector(d*d, 0)
} else {
throw new GLError('', 'Unknown uniform data type for ' + name + ': ' + type)
}
}
}
function storeProperty(obj, prop, type) {
if(typeof type === 'object') {
var child = processObject(type)
Object.defineProperty(obj, prop, {
get: identity(child),
set: makeSetter(type),
enumerable: true,
configurable: false
})
} else {
if(locations[type]) {
Object.defineProperty(obj, prop, {
get: makeGetter(type),
set: makeSetter(type),
enumerable: true,
configurable: false
})
} else {
obj[prop] = defaultValue(uniforms[type].type)
}
}
}
function processObject(obj) {
var result
if(Array.isArray(obj)) {
result = new Array(obj.length)
for(var i=0; i<obj.length; ++i) {
storeProperty(result, i, obj[i])
}
} else {
result = {}
for(var id in obj) {
storeProperty(result, id, obj[id])
}
}
return result
}
//Return data
var coallesced = coallesceUniforms(uniforms, true)
return {
get: identity(processObject(coallesced)),
set: makeSetter(coallesced),
enumerable: true,
configurable: true
}
}
},{"./GLError":24,"./reflect":27}],27:[function(require,module,exports){
'use strict'
module.exports = makeReflectTypes
//Construct type info for reflection.
//
// This iterates over the flattened list of uniform type values and smashes them into a JSON object.
//
// The leaves of the resulting object are either indices or type strings representing primitive glslify types
function makeReflectTypes(uniforms, useIndex) {
var obj = {}
for(var i=0; i<uniforms.length; ++i) {
var n = uniforms[i].name
var parts = n.split(".")
var o = obj
for(var j=0; j<parts.length; ++j) {
var x = parts[j].split("[")
if(x.length > 1) {
if(!(x[0] in o)) {
o[x[0]] = []
}
o = o[x[0]]
for(var k=1; k<x.length; ++k) {
var y = parseInt(x[k])
if(k<x.length-1 || j<parts.length-1) {
if(!(y in o)) {
if(k < x.length-1) {
o[y] = []
} else {
o[y] = {}
}
}
o = o[y]
} else {
if(useIndex) {
o[y] = i
} else {
o[y] = uniforms[i].type
}
}
}
} else if(j < parts.length-1) {
if(!(x[0] in o)) {
o[x[0]] = {}
}
o = o[x[0]]
} else {
if(useIndex) {
o[x[0]] = i
} else {
o[x[0]] = uniforms[i].type
}
}
}
}
return obj
}
},{}],28:[function(require,module,exports){
'use strict'
exports.uniforms = runtimeUniforms
exports.attributes = runtimeAttributes
var GL_TO_GLSL_TYPES = {
'FLOAT': 'float',
'FLOAT_VEC2': 'vec2',
'FLOAT_VEC3': 'vec3',
'FLOAT_VEC4': 'vec4',
'INT': 'int',
'INT_VEC2': 'ivec2',
'INT_VEC3': 'ivec3',
'INT_VEC4': 'ivec4',
'BOOL': 'bool',
'BOOL_VEC2': 'bvec2',
'BOOL_VEC3': 'bvec3',
'BOOL_VEC4': 'bvec4',
'FLOAT_MAT2': 'mat2',
'FLOAT_MAT3': 'mat3',
'FLOAT_MAT4': 'mat4',
'SAMPLER_2D': 'sampler2D',
'SAMPLER_CUBE':'samplerCube'
}
var GL_TABLE = null
function getType(gl, type) {
if(!GL_TABLE) {
var typeNames = Object.keys(GL_TO_GLSL_TYPES)
GL_TABLE = {}
for(var i=0; i<typeNames.length; ++i) {
var tn = typeNames[i]
GL_TABLE[gl[tn]] = GL_TO_GLSL_TYPES[tn]
}
}
return GL_TABLE[type]
}
function runtimeUniforms(gl, program) {
var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)
var result = []
for(var i=0; i<numUniforms; ++i) {
var info = gl.getActiveUniform(program, i)
if(info) {
var type = getType(gl, info.type)
if(info.size > 1) {
for(var j=0; j<info.size; ++j) {
result.push({
name: info.name.replace('[0]', '[' + j + ']'),
type: type
})
}
} else {
result.push({
name: info.name,
type: type
})
}
}
}
return result
}
function runtimeAttributes(gl, program) {
var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES)
var result = []
for(var i=0; i<numAttributes; ++i) {
var info = gl.getActiveAttrib(program, i)
if(info) {
result.push({
name: info.name,
type: getType(gl, info.type)
})
}
}
return result
}
},{}],29:[function(require,module,exports){
'use strict'
exports.shader = getShaderReference
exports.program = createProgram
var GLError = require("./GLError")
var formatCompilerError = require('gl-format-compiler-error');
var weakMap = typeof WeakMap === 'undefined' ? require('weakmap-shim') : WeakMap
var CACHE = new weakMap()
var SHADER_COUNTER = 0
function ShaderReference(id, src, type, shader, programs, count, cache) {
this.id = id
this.src = src
this.type = type
this.shader = shader
this.count = count
this.programs = []
this.cache = cache
}
ShaderReference.prototype.dispose = function() {
if(--this.count === 0) {
var cache = this.cache
var gl = cache.gl
//Remove program references
var programs = this.programs
for(var i=0, n=programs.length; i<n; ++i) {
var p = cache.programs[programs[i]]
if(p) {
delete cache.programs[i]
gl.deleteProgram(p)
}
}
//Remove shader reference
gl.deleteShader(this.shader)
delete cache.shaders[(this.type === gl.FRAGMENT_SHADER)|0][this.src]
}
}
function ContextCache(gl) {
this.gl = gl
this.shaders = [{}, {}]
this.programs = {}
}
var proto = ContextCache.prototype
function compileShader(gl, type, src) {
var shader = gl.createShader(type)
gl.shaderSource(shader, src)
gl.compileShader(shader)
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
var errLog = gl.getShaderInfoLog(shader)
try {
var fmt = formatCompilerError(errLog, src, type);
} catch (e){
console.warn('Failed to format compiler error: ' + e);
throw new GLError(errLog, 'Error compiling shader:\n' + errLog)
}
throw new GLError(errLog, fmt.short, fmt.long)
}
return shader
}
proto.getShaderReference = function(type, src) {
var gl = this.gl
var shaders = this.shaders[(type === gl.FRAGMENT_SHADER)|0]
var shader = shaders[src]
if(!shader || !gl.isShader(shader.shader)) {
var shaderObj = compileShader(gl, type, src)
shader = shaders[src] = new ShaderReference(
SHADER_COUNTER++,
src,
type,
shaderObj,
[],
1,
this)
} else {
shader.count += 1
}
return shader
}
function linkProgram(gl, vshader, fshader, attribs, locations) {
var program = gl.createProgram()
gl.attachShader(program, vshader)
gl.attachShader(program, fshader)
for(var i=0; i<attribs.length; ++i) {
gl.bindAttribLocation(program, locations[i], attribs[i])
}
gl.linkProgram(program)
if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {
var errLog = gl.getProgramInfoLog(program)
throw new GLError(errLog, 'Error linking program: ' + errLog)
}
return program
}
proto.getProgram = function(vref, fref, attribs, locations) {
var token = [vref.id, fref.id, attribs.join(':'), locations.join(':')].join('@')
var prog = this.programs[token]
if(!prog || !this.gl.isProgram(prog)) {
this.programs[token] = prog = linkProgram(
this.gl,
vref.shader,
fref.shader,
attribs,
locations)
vref.programs.push(token)
fref.programs.push(token)
}
return prog
}
function getCache(gl) {
var ctxCache = CACHE.get(gl)
if(!ctxCache) {
ctxCache = new ContextCache(gl)
CACHE.set(gl, ctxCache)
}
return ctxCache
}
function getShaderReference(gl, type, src) {
return getCache(gl).getShaderReference(type, src)
}
function createProgram(gl, vref, fref, attribs, locations) {
return getCache(gl).getProgram(vref, fref, attribs, locations)
}
},{"./GLError":24,"gl-format-compiler-error":21,"weakmap-shim":70}],30:[function(require,module,exports){
arguments[4][11][0].apply(exports,arguments)
},{"dup":11}],31:[function(require,module,exports){
arguments[4][7][0].apply(exports,arguments)
},{"dup":7}],32:[function(require,module,exports){
(function (global){
'use strict'
var bits = require('bit-twiddle')
var dup = require('dup')
var Buffer = require('buffer').Buffer
//Legacy pool support
if(!global.__TYPEDARRAY_POOL) {
global.__TYPEDARRAY_POOL = {
UINT8 : dup([32, 0])
, UINT16 : dup([32, 0])
, UINT32 : dup([32, 0])
, BIGUINT64 : dup([32, 0])
, INT8 : dup([32, 0])
, INT16 : dup([32, 0])
, INT32 : dup([32, 0])
, BIGINT64 : dup([32, 0])
, FLOAT : dup([32, 0])
, DOUBLE : dup([32, 0])
, DATA : dup([32, 0])
, UINT8C : dup([32, 0])
, BUFFER : dup([32, 0])
}
}
var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined'
var hasBigUint64 = (typeof BigUint64Array) !== 'undefined'
var hasBigInt64 = (typeof BigInt64Array) !== 'undefined'
var POOL = global.__TYPEDARRAY_POOL
//Upgrade pool
if(!POOL.UINT8C) {
POOL.UINT8C = dup([32, 0])
}
if(!POOL.BIGUINT64) {
POOL.BIGUINT64 = dup([32, 0])
}
if(!POOL.BIGINT64) {
POOL.BIGINT64 = dup([32, 0])
}
if(!POOL.BUFFER) {
POOL.BUFFER = dup([32, 0])
}
//New technique: Only allocate from ArrayBufferView and Buffer
var DATA = POOL.DATA
, BUFFER = POOL.BUFFER
exports.free = function free(array) {
if(Buffer.isBuffer(array)) {
BUFFER[bits.log2(array.length)].push(array)
} else {
if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') {
array = array.buffer
}
if(!array) {
return
}
var n = array.length || array.byteLength
var log_n = bits.log2(n)|0
DATA[log_n].push(array)
}
}
function freeArrayBuffer(buffer) {
if(!buffer) {
return
}
var n = buffer.length || buffer.byteLength
var log_n = bits.log2(n)
DATA[log_n].push(buffer)
}
function freeTypedArray(array) {
freeArrayBuffer(array.buffer)
}
exports.freeUint8 =
exports.freeUint16 =
exports.freeUint32 =
exports.freeBigUint64 =
exports.freeInt8 =
exports.freeInt16 =
exports.freeInt32 =
exports.freeBigInt64 =
exports.freeFloat32 =
exports.freeFloat =
exports.freeFloat64 =
exports.freeDouble =
exports.freeUint8Clamped =
exports.freeDataView = freeTypedArray
exports.freeArrayBuffer = freeArrayBuffer
exports.freeBuffer = function freeBuffer(array) {
BUFFER[bits.log2(array.length)].push(array)
}
exports.malloc = function malloc(n, dtype) {
if(dtype === undefined || dtype === 'arraybuffer') {
return mallocArrayBuffer(n)
} else {
switch(dtype) {
case 'uint8':
return mallocUint8(n)
case 'uint16':
return mallocUint16(n)
case 'uint32':
return mallocUint32(n)
case 'int8':
return mallocInt8(n)
case 'int16':
return mallocInt16(n)
case 'int32':
return mallocInt32(n)
case 'float':
case 'float32':
return mallocFloat(n)
case 'double':
case 'float64':
return mallocDouble(n)
case 'uint8_clamped':
return mallocUint8Clamped(n)
case 'bigint64':
return mallocBigInt64(n)
case 'biguint64':
return mallocBigUint64(n)
case 'buffer':
return mallocBuffer(n)
case 'data':
case 'dataview':
return mallocDataView(n)
default:
return null
}
}
return null
}
function mallocArrayBuffer(n) {
var n = bits.nextPow2(n)
var log_n = bits.log2(n)
var d = DATA[log_n]
if(d.length > 0) {
return d.pop()
}
return new ArrayBuffer(n)
}
exports.mallocArrayBuffer = mallocArrayBuffer
function mallocUint8(n) {
return new Uint8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocUint8 = mallocUint8
function mallocUint16(n) {
return new Uint16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocUint16 = mallocUint16
function mallocUint32(n) {
return new Uint32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocUint32 = mallocUint32
function mallocInt8(n) {
return new Int8Array(mallocArrayBuffer(n), 0, n)
}
exports.mallocInt8 = mallocInt8
function mallocInt16(n) {
return new Int16Array(mallocArrayBuffer(2*n), 0, n)
}
exports.mallocInt16 = mallocInt16
function mallocInt32(n) {
return new Int32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocInt32 = mallocInt32
function mallocFloat(n) {
return new Float32Array(mallocArrayBuffer(4*n), 0, n)
}
exports.mallocFloat32 = exports.mallocFloat = mallocFloat
function mallocDouble(n) {
return new Float64Array(mallocArrayBuffer(8*n), 0, n)
}
exports.mallocFloat64 = exports.mallocDouble = mallocDouble
function mallocUint8Clamped(n) {
if(hasUint8C) {
return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n)
} else {
return mallocUint8(n)
}
}
exports.mallocUint8Clamped = mallocUint8Clamped
function mallocBigUint64(n) {
if(hasBigUint64) {
return new BigUint64Array(mallocArrayBuffer(8*n), 0, n)
} else {
return null;
}
}
exports.mallocBigUint64 = mallocBigUint64
function mallocBigInt64(n) {
if (hasBigInt64) {
return new BigInt64Array(mallocArrayBuffer(8*n), 0, n)
} else {
return null;
}
}
exports.mallocBigInt64 = mallocBigInt64
function mallocDataView(n) {
return new DataView(mallocArrayBuffer(n), 0, n)
}
exports.mallocDataView = mallocDataView
function mallocBuffer(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = BUFFER[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Buffer(n)
}
exports.mallocBuffer = mallocBuffer
exports.clearCache = function clearCache() {
for(var i=0; i<32; ++i) {
POOL.UINT8[i].length = 0
POOL.UINT16[i].length = 0
POOL.UINT32[i].length = 0
POOL.INT8[i].length = 0
POOL.INT16[i].length = 0
POOL.INT32[i].length = 0
POOL.FLOAT[i].length = 0
POOL.DOUBLE[i].length = 0
POOL.BIGUINT64[i].length = 0
POOL.BIGINT64[i].length = 0
POOL.UINT8C[i].length = 0
DATA[i].length = 0
BUFFER[i].length = 0
}
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"bit-twiddle":31,"buffer":8,"dup":30}],33:[function(require,module,exports){
"use strict"
var ndarray = require("ndarray")
var ops = require("ndarray-ops")
var pool = require("typedarray-pool")
var webglew = require("webglew")
var linearTypes = null
var filterTypes = null
var wrapTypes = null
function lazyInitLinearTypes(gl) {
linearTypes = [
gl.LINEAR,
gl.NEAREST_MIPMAP_LINEAR,
gl.LINEAR_MIPMAP_NEAREST,
gl.LINEAR_MIPMAP_NEAREST
]
filterTypes = [
gl.NEAREST,
gl.LINEAR,
gl.NEAREST_MIPMAP_NEAREST,
gl.NEAREST_MIPMAP_LINEAR,
gl.LINEAR_MIPMAP_NEAREST,
gl.LINEAR_MIPMAP_LINEAR
]
wrapTypes = [
gl.REPEAT,
gl.CLAMP_TO_EDGE,
gl.MIRRORED_REPEAT
]
}
var convertFloatToUint8 = function(out, inp) {
ops.muls(out, inp, 255.0)
}
function Texture2D(gl, handle, width, height, format, type) {
this.gl = gl
this.handle = handle
this.shape = [ height, width ]
this.format = format
this.type = type
this._mipLevels = [0]
this._magFilter = gl.NEAREST
this._minFilter = gl.NEAREST
this._wrapS = gl.CLAMP_TO_EDGE
this._wrapT = gl.CLAMP_TO_EDGE
this._anisoSamples = 1
}
Object.defineProperty(Texture2D.prototype, "minFilter", {
get: function() {
return this._minFilter
},
set: function(v) {
this.bind()
var gl = this.gl
if(this.type === gl.FLOAT && linearTypes.indexOf(v) >= 0) {
if(!webglew(gl).OES_texture_float_linear) {
v = gl.NEAREST
}
}
if(filterTypes.indexOf(v) < 0) {
throw new Error("gl-texture2d: Unknown filter mode " + v)
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, v)
return this._minFilter = v
}
})
var proto = Texture2D.prototype
Object.defineProperty(proto, "magFilter", {
get: function() {
return this._magFilter
},
set: function(v) {
this.bind()
var gl = this.gl
if(this.type === gl.FLOAT && linearTypes.indexOf(v) >= 0) {
if(!webglew(gl).OES_texture_float_linear) {
v = gl.NEAREST
}
}
if(filterTypes.indexOf(v) < 0) {
throw new Error("gl-texture2d: Unknown filter mode " + v)
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, v)
return this._magFilter = v
}
})
Object.defineProperty(proto, "wrapS", {
get: function() {
return this._wrapS
},
set: function(v) {
this.bind()
if(wrapTypes.indexOf(v) < 0) {
throw new Error("gl-texture2d: Unknown wrap mode " + v)
}
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, v)
return this._wrapS = v
}
})
Object.defineProperty(proto, "wrapT", {
get: function() {
return this._wrapT
},
set: function(v) {
this.bind()
if(wrapTypes.indexOf(v) < 0) {
throw new Error("gl-texture2d: Unknown wrap mode " + v)
}
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, v)
return this._wrapT = v
}
})
Object.defineProperty(proto, "mipSamples", {
get: function() {
return this._anisoSamples
},
set: function(i) {
var psamples = this._anisoSamples
this._anisoSamples = Math.max(i, 1)|0
if(psamples !== this._anisoSamples) {
var ext = webglew(this.gl).EXT_texture_filter_anisotropic
if(ext) {
this.gl.texParameterf(this.gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, this._anisoSamples)
}
}
return this._anisoSamples
}
})
proto.bind = function bindTexture2D(unit) {
var gl = this.gl
if(unit !== undefined) {
gl.activeTexture(gl.TEXTURE0 + (unit|0))
}
gl.bindTexture(gl.TEXTURE_2D, this.handle)
if(unit !== undefined) {
return unit
}
return gl.getParameter(gl.ACTIVE_TEXTURE) - gl.TEXTURE0
}
proto.dispose = function disposeTexture2D() {
this.gl.deleteTexture(this.handle)
}
proto.generateMipmap = function() {
this.bind()
this.gl.generateMipmap(this.gl.TEXTURE_2D)
//Update mip levels
var l = Math.min(this.shape[0], this.shape[1])
for(var i=0; l>0; ++i, l>>>=1) {
if(this._mipLevels.indexOf(i) < 0) {
this._mipLevels.push(i)
}
}
}
proto.setPixels = function(data, x_off, y_off, mip_level) {
var gl = this.gl
this.bind()
x_off = x_off || 0
y_off = y_off || 0
mip_level = mip_level || 0
if(data instanceof HTMLCanvasElement ||
data instanceof ImageData ||
data instanceof HTMLImageElement ||
data instanceof HTMLVideoElement) {
var needsMip = this._mipLevels.indexOf(mip_level) < 0
if(needsMip) {
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, data)
this._mipLevels.push(mip_level)
} else {
gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, this.format, this.type, data)
}
} else if(data.shape && data.stride && data.data) {
if(data.shape.length < 2 ||
x_off + data.shape[1] > this.shape[1]>>>mip_level ||
y_off + data.shape[0] > this.shape[0]>>>mip_level ||
x_off < 0 ||
y_off < 0) {
throw new Error("Texture dimensions are out of bounds")
}
texSubImageArray(gl, x_off, y_off, mip_level, this.format, this.type, this._mipLevels, data)
} else {
throw new Error("Unsupported data type")
}
}
function texSubImageArray(gl, x_off, y_off, mip_level, cformat, ctype, mipLevels, array) {
var dtype = array.dtype || ndarray.dtype(array)
var shape = array.shape
var packed = isPacked(array)
var type = 0, format = 0
if(dtype === "float32") {
type = gl.FLOAT
} else if(dtype === "float64") {
type = gl.FLOAT
packed = false
dtype = "float32"
} else if(dtype === "uint8") {
type = gl.UNSIGNED_BYTE
} else {
type = gl.UNSIGNED_BYTE
packed = false
}
if(shape.length === 2) {
format = gl.LUMINANCE
} else if(shape.length === 3) {
if(shape[2] === 1) {
format = gl.ALPHA
} else if(shape[2] === 2) {
format = gl.LUMINANCE_ALPHA
} else if(shape[2] === 3) {
format = gl.RGB
} else if(shape[2] === 4) {
format = gl.RGBA
} else {
throw new Error("Invalid shape for pixel coords")
}
} else {
throw new Error("Invalid shape for texture")
}
//For 1-channel textures allow conversion between formats
if((format === gl.LUMINANCE || format === gl.ALPHA) &&
(cformat === gl.LUMINANCE || cformat === gl.ALPHA)) {
format = cformat
}
if(format !== cformat) {
throw new Error("Incompatible texture format for setPixels")
}
var size = array.size
if(typeof size !== "number") {
size = ndarray.size(array)
}
var needsMip = mipLevels.indexOf(mip_level) < 0
if(needsMip) {
mipLevels.push(mip_level)
}
if(type === ctype && packed) {
//Array data types are compatible, can directly copy into texture
if(array.offset === 0 && array.data.length === size) {
if(needsMip) {
gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[1], shape[0], 0, cformat, ctype, array.data)
} else {
gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[1], shape[0], cformat, ctype, array.data)
}
} else {
if(needsMip) {
gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[1], shape[0], 0, cformat, ctype, array.data.subarray(array.offset, array.offset+size))
} else {
gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[1], shape[0], cformat, ctype, array.data.subarray(array.offset, array.offset+size))
}
}
} else {
//Need to do type conversion to pack data into buffer
var pack_buffer
if(ctype === gl.FLOAT) {
pack_buffer = pool.mallocFloat32(size)
} else {
pack_buffer = pool.mallocUint8(size)
}
var pack_view = ndarray(pack_buffer, shape)
if(type === gl.FLOAT && ctype === gl.UNSIGNED_BYTE) {
convertFloatToUint8(pack_view, array)
} else {
ops.assign(pack_view, array)
}
if(needsMip) {
gl.texImage2D(gl.TEXTURE_2D, mip_level, cformat, shape[1], shape[0], 0, cformat, ctype, pack_buffer.subarray(0, size))
} else {
gl.texSubImage2D(gl.TEXTURE_2D, mip_level, x_off, y_off, shape[1], shape[0], cformat, ctype, pack_buffer.subarray(0, size))
}
if(ctype === gl.FLOAT) {
pool.freeFloat32(pack_buffer)
} else {
pool.freeUint8(pack_buffer)
}
}
}
function initTexture(gl) {
var tex = gl.createTexture()
gl.bindTexture(gl.TEXTURE_2D, tex)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
return tex
}
function createTextureShape(gl, width, height, format, type) {
var tex = initTexture(gl)
gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, format, type, null)
return new Texture2D(gl, tex, width, height, format, type)
}
function createTextureDOM(gl, element, format, type) {
var tex = initTexture(gl)
gl.texImage2D(gl.TEXTURE_2D, 0, format, format, type, element)
return new Texture2D(gl, tex, element.width|0, element.height|0, format, type)
}
function isPacked(array) {
var shape = array.shape
var stride = array.stride
var s = 1
for(var i=shape.length-1; i>=0; --i) {
if(stride[i] !== s) {
return false
}
s *= shape[i]
}
return true
}
//Creates a texture from an ndarray
function createTextureArray(gl, array) {
var dtype = array.dtype || ndarray.dtype(array)
var shape = array.shape
var packed = isPacked(array)
var type = 0
if(dtype === "float32") {
type = gl.FLOAT
} else if(dtype === "float64") {
type = gl.FLOAT
packed = false
dtype = "float32"
} else if(dtype === "uint8") {
type = gl.UNSIGNED_BYTE
} else {
type = gl.UNSIGNED_BYTE
packed = false
}
var format = 0
if(shape.length === 2) {
format = gl.LUMINANCE
} else if(shape.length === 3) {
if(shape[2] === 1) {
format = gl.ALPHA
} else if(shape[2] === 2) {
format = gl.LUMINANCE_ALPHA
} else if(shape[2] === 3) {
format = gl.RGB
} else if(shape[2] === 4) {
format = gl.RGBA
} else {
throw new Error("Invalid shape for pixel coords")
}
} else {
throw new Error("Invalid shape for texture")
}
if(type === gl.FLOAT && !!webglew(gl).texture_float) {
type = gl.UNSIGNED_BYTE
packed = false
}
var buffer, buf_store
if(!packed) {
var sz = 1
var stride = new Array(shape.length)
for(var i=shape.length-1; i>=0; --i) {
stride[i] = sz
sz *= shape[i]
}
buf_store = pool.malloc(sz, dtype)
var buf_array = ndarray(buf_store, array.shape, stride, 0)
if((dtype === "float32" || dtype === "float64") && type === gl.UNSIGNED_BYTE) {
convertFloatToUint8(buf_array, array)
} else {
ops.assign(buf_array, array)
}
buffer = buf_store.subarray(0, sz)
} else {
var array_size = array.size
if(typeof array_size !== "number") {
array_size = ndarray.size(array)
}
buffer = array.data.subarray(array.offset, array.offset + array_size)
}
var tex = initTexture(gl)
gl.texImage2D(gl.TEXTURE_2D, 0, format, shape[1], shape[0], 0, format, type, buffer)
if(!packed) {
pool.free(buf_store)
}
return new Texture2D(gl, tex, shape[1], shape[0], format, type)
}
function createTexture2D(gl) {
if(arguments.length <= 1) {
throw new Error("Missing arguments for texture2d constructor")
}
if(!linearTypes) {
lazyInitLinearTypes(gl)
}
if(typeof arguments[1] === "number") {
return createTextureShape(gl, arguments[1], arguments[2], arguments[3]||gl.RGBA, arguments[4]||gl.UNSIGNED_BYTE)
}
if(typeof arguments[1] === "object") {
var obj = arguments[1]
if(obj instanceof HTMLCanvasElement ||
obj instanceof HTMLImageElement ||
obj instanceof HTMLVideoElement ||
obj instanceof ImageData) {
return createTextureDOM(gl, obj, arguments[2]||gl.RGBA, arguments[3]||gl.UNSIGNED_BYTE)
} else if(obj.shape && obj.data && obj.stride) {
return createTextureArray(gl, obj)
}
}
throw new Error("Invalid arguments for texture2d constructor")
}
module.exports = createTexture2D
},{"ndarray":55,"ndarray-ops":51,"typedarray-pool":32,"webglew":71}],34:[function(require,module,exports){
"use strict"
function doBind(gl, elements, attributes) {
if(elements) {
elements.bind()
} else {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null)
}
var nattribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS)|0
if(attributes) {
if(attributes.length > nattribs) {
throw new Error("Too many vertex attributes")
}
for(var i=0; i<attributes.length; ++i) {
var attrib = attributes[i]
if(attrib.buffer) {
var buffer = attrib.buffer
var size = attrib.size || 4
var type = attrib.type || gl.FLOAT
var normalized = !!attrib.normalized
var stride = attrib.stride || 0
var offset = attrib.offset || 0
buffer.bind()
gl.vertexAttribPointer(i, size, type, normalized, stride, offset)
gl.enableVertexAttribArray(i)
} else {
if(typeof attrib === "number") {
gl.vertexAttrib1f(i, attrib)
} else if(attrib.length === 1) {
gl.vertexAttrib1f(i, attrib[0])
} else if(attrib.length === 2) {
gl.vertexAttrib2f(i, attrib[0], attrib[1])
} else if(attrib.length === 3) {
gl.vertexAttrib3f(i, attrib[0], attrib[1], attrib[2])
} else if(attrib.length === 4) {
gl.vertexAttrib4f(i, attrib[0], attrib[1], attrib[2], attrib[3])
} else {
throw new Error("Invalid vertex attribute")
}
gl.disableVertexAttribArray(i)
}
}
for(; i<nattribs; ++i) {
gl.disableVertexAttribArray(i)
}
} else {
gl.bindBuffer(gl.ARRAY_BUFFER, null)
for(var i=0; i<nattribs; ++i) {
gl.disableVertexAttribArray(i)
}
}
}
module.exports = doBind
},{}],35:[function(require,module,exports){
"use strict"
var bindAttribs = require("./do-bind.js")
function VAOEmulated(gl) {
this.gl = gl
this.elements = null
this.attributes = null
}
VAOEmulated.prototype.bind = function() {
bindAttribs(this.gl, this.elements, this.attributes)
}
VAOEmulated.prototype.update = function(elements, attributes) {
this.elements = elements
this.attributes = attributes
}
VAOEmulated.prototype.dispose = function() { }
VAOEmulated.prototype.unbind = function() { }
function createVAOEmulated(gl) {
return new VAOEmulated(gl)
}
module.exports = createVAOEmulated
},{"./do-bind.js":34}],36:[function(require,module,exports){
"use strict"
var bindAttribs = require("./do-bind.js")
function VAONative(gl, ext, handle) {
this.gl = gl
this.ext = ext
this.handle = handle
}
VAONative.prototype.bind = function() {
this.ext.bindVertexArrayOES(this.handle)
}
VAONative.prototype.unbind = function() {
this.ext.bindVertexArrayOES(null)
}
VAONative.prototype.dispose = function() {
this.ext.deleteVertexArrayOES(this.handle)
}
VAONative.prototype.update = function(elements, attributes) {
this.bind()
bindAttribs(this.gl, elements, attributes)
this.unbind()
}
function createVAONative(gl, ext) {
return new VAONative(gl, ext, ext.createVertexArrayOES())
}
module.exports = createVAONative
},{"./do-bind.js":34}],37:[function(require,module,exports){
"use strict";
var VENDOR_PREFIX = [
"WEBKIT_",
"MOZ_"
];
function baseName(ext_name) {
for(var i=0; i<VENDOR_PREFIX.length; ++i) {
var prefix = VENDOR_PREFIX[i];
if(ext_name.indexOf(prefix) === 0) {
return ext_name.slice(prefix.length);
}
}
return ext_name;
}
function initWebGLEW(gl) {
if(gl._webglew_struct) {
return gl._webglew_struct;
}
var extensions = {};
var supported = gl.getSupportedExtensions();
for(var i=0; i<supported.length; ++i) {
var ext = gl.getExtension(supported[i]);
if(!ext) {
continue;
}
extensions[supported[i]] = ext;
extensions[baseName(supported[i])] = ext; //Add version without VENDOR
}
gl._webglew_struct = extensions;
return extensions;
}
module.exports = initWebGLEW;
},{}],38:[function(require,module,exports){
"use strict"
var webglew = require("webglew")
var createVAONative = require("./lib/vao-native.js")
var createVAOEmulated = require("./lib/vao-emulated.js")
function createVAO(gl, elements, attributes) {
var ext = webglew(gl).OES_vertex_array_object
var vao
if(ext) {
vao = createVAONative(gl, ext)
} else {
vao = createVAOEmulated(gl)
}
vao.update(elements, attributes)
return vao
}
module.exports = createVAO
},{"./lib/vao-emulated.js":35,"./lib/vao-native.js":36,"webglew":37}],39:[function(require,module,exports){
var tokenize = require('glsl-tokenizer')
var atob = require('atob-lite')
module.exports = getName
function getName(src) {
var tokens = Array.isArray(src)
? src
: tokenize(src)
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i]
if (token.type !== 'preprocessor') continue
var match = token.data.match(/\#define\s+SHADER_NAME(_B64)?\s+(.+)$/)
if (!match) continue
if (!match[2]) continue
var b64 = match[1]
var name = match[2]
return (b64 ? atob(name) : name).trim()
}
}
},{"atob-lite":4,"glsl-tokenizer":46}],40:[function(require,module,exports){
module.exports = tokenize
var literals100 = require('./lib/literals')
, operators = require('./lib/operators')
, builtins100 = require('./lib/builtins')
, literals300es = require('./lib/literals-300es')
, builtins300es = require('./lib/builtins-300es')
var NORMAL = 999 // <-- never emitted
, TOKEN = 9999 // <-- never emitted
, BLOCK_COMMENT = 0
, LINE_COMMENT = 1
, PREPROCESSOR = 2
, OPERATOR = 3
, INTEGER = 4
, FLOAT = 5
, IDENT = 6
, BUILTIN = 7
, KEYWORD = 8
, WHITESPACE = 9
, EOF = 10
, HEX = 11
var map = [
'block-comment'
, 'line-comment'
, 'preprocessor'
, 'operator'
, 'integer'
, 'float'
, 'ident'
, 'builtin'
, 'keyword'
, 'whitespace'
, 'eof'
, 'integer'
]
function tokenize(opt) {
var i = 0
, total = 0
, mode = NORMAL
, c
, last
, content = []
, tokens = []
, token_idx = 0
, token_offs = 0
, line = 1
, col = 0
, start = 0
, isnum = false
, isoperator = false
, input = ''
, len
opt = opt || {}
var allBuiltins = builtins100
var allLiterals = literals100
if (opt.version === '300 es') {
allBuiltins = builtins300es
allLiterals = literals300es
}
// cache by name
var builtinsDict = {}, literalsDict = {}
for (var i = 0; i < allBuiltins.length; i++) {
builtinsDict[allBuiltins[i]] = true
}
for (var i = 0; i < allLiterals.length; i++) {
literalsDict[allLiterals[i]] = true
}
return function(data) {
tokens = []
if (data !== null) return write(data)
return end()
}
function token(data) {
if (data.length) {
tokens.push({
type: map[mode]
, data: data
, position: start
, line: line
, column: col
})
}
}
function write(chunk) {
i = 0
if (chunk.toString) chunk = chunk.toString()
input += chunk.replace(/\r\n/g, '\n')
len = input.length
var last
while(c = input[i], i < len) {
last = i
switch(mode) {
case BLOCK_COMMENT: i = block_comment(); break
case LINE_COMMENT: i = line_comment(); break
case PREPROCESSOR: i = preprocessor(); break
case OPERATOR: i = operator(); break
case INTEGER: i = integer(); break
case HEX: i = hex(); break
case FLOAT: i = decimal(); break
case TOKEN: i = readtoken(); break
case WHITESPACE: i = whitespace(); break
case NORMAL: i = normal(); break
}
if(last !== i) {
switch(input[last]) {
case '\n': col = 0; ++line; break
default: ++col; break
}
}
}
total += i
input = input.slice(i)
return tokens
}
function end(chunk) {
if(content.length) {
token(content.join(''))
}
mode = EOF
token('(eof)')
return tokens
}
function normal() {
content = content.length ? [] : content
if(last === '/' && c === '*') {
start = total + i - 1
mode = BLOCK_COMMENT
last = c
return i + 1
}
if(last === '/' && c === '/') {
start = total + i - 1
mode = LINE_COMMENT
last = c
return i + 1
}
if(c === '#') {
mode = PREPROCESSOR
start = total + i
return i
}
if(/\s/.test(c)) {
mode = WHITESPACE
start = total + i
return i
}
isnum = /\d/.test(c)
isoperator = /[^\w_]/.test(c)
start = total + i
mode = isnum ? INTEGER : isoperator ? OPERATOR : TOKEN
return i
}
function whitespace() {
if(/[^\s]/g.test(c)) {
token(content.join(''))
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
function preprocessor() {
if((c === '\r' || c === '\n') && last !== '\\') {
token(content.join(''))
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
function line_comment() {
return preprocessor()
}
function block_comment() {
if(c === '/' && last === '*') {
content.push(c)
token(content.join(''))
mode = NORMAL
return i + 1
}
content.push(c)
last = c
return i + 1
}
function operator() {
if(last === '.' && /\d/.test(c)) {
mode = FLOAT
return i
}
if(last === '/' && c === '*') {
mode = BLOCK_COMMENT
return i
}
if(last === '/' && c === '/') {
mode = LINE_COMMENT
return i
}
if(c === '.' && content.length) {
while(determine_operator(content));
mode = FLOAT
return i
}
if(c === ';' || c === ')' || c === '(') {
if(content.length) while(determine_operator(content));
token(c)
mode = NORMAL
return i + 1
}
var is_composite_operator = content.length === 2 && c !== '='
if(/[\w_\d\s]/.test(c) || is_composite_operator) {
while(determine_operator(content));
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
function determine_operator(buf) {
var j = 0
, idx
, res
do {
idx = operators.indexOf(buf.slice(0, buf.length + j).join(''))
res = operators[idx]
if(idx === -1) {
if(j-- + buf.length > 0) continue
res = buf.slice(0, 1).join('')
}
token(res)
start += res.length
content = content.slice(res.length)
return content.length
} while(1)
}
function hex() {
if(/[^a-fA-F0-9]/.test(c)) {
token(content.join(''))
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
function integer() {
if(c === '.') {
content.push(c)
mode = FLOAT
last = c
return i + 1
}
if(/[eE]/.test(c)) {
content.push(c)
mode = FLOAT
last = c
return i + 1
}
if(c === 'x' && content.length === 1 && content[0] === '0') {
mode = HEX
content.push(c)
last = c
return i + 1
}
if(/[^\d]/.test(c)) {
token(content.join(''))
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
function decimal() {
if(c === 'f') {
content.push(c)
last = c
i += 1
}
if(/[eE]/.test(c)) {
content.push(c)
last = c
return i + 1
}
if ((c === '-' || c === '+') && /[eE]/.test(last)) {
content.push(c)
last = c
return i + 1
}
if(/[^\d]/.test(c)) {
token(content.join(''))
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
function readtoken() {
if(/[^\d\w_]/.test(c)) {
var contentstr = content.join('')
if(literalsDict[contentstr]) {
mode = KEYWORD
} else if(builtinsDict[contentstr]) {
mode = BUILTIN
} else {
mode = IDENT
}
token(content.join(''))
mode = NORMAL
return i
}
content.push(c)
last = c
return i + 1
}
}
},{"./lib/builtins":42,"./lib/builtins-300es":41,"./lib/literals":44,"./lib/literals-300es":43,"./lib/operators":45}],41:[function(require,module,exports){
// 300es builtins/reserved words that were previously valid in v100
var v100 = require('./builtins')
// The texture2D|Cube functions have been removed
// And the gl_ features are updated
v100 = v100.slice().filter(function (b) {
return !/^(gl\_|texture)/.test(b)
})
module.exports = v100.concat([
// the updated gl_ constants
'gl_VertexID'
, 'gl_InstanceID'
, 'gl_Position'
, 'gl_PointSize'
, 'gl_FragCoord'
, 'gl_FrontFacing'
, 'gl_FragDepth'
, 'gl_PointCoord'
, 'gl_MaxVertexAttribs'
, 'gl_MaxVertexUniformVectors'
, 'gl_MaxVertexOutputVectors'
, 'gl_MaxFragmentInputVectors'
, 'gl_MaxVertexTextureImageUnits'
, 'gl_MaxCombinedTextureImageUnits'
, 'gl_MaxTextureImageUnits'
, 'gl_MaxFragmentUniformVectors'
, 'gl_MaxDrawBuffers'
, 'gl_MinProgramTexelOffset'
, 'gl_MaxProgramTexelOffset'
, 'gl_DepthRangeParameters'
, 'gl_DepthRange'
// other builtins
, 'trunc'
, 'round'
, 'roundEven'
, 'isnan'
, 'isinf'
, 'floatBitsToInt'
, 'floatBitsToUint'
, 'intBitsToFloat'
, 'uintBitsToFloat'
, 'packSnorm2x16'
, 'unpackSnorm2x16'
, 'packUnorm2x16'
, 'unpackUnorm2x16'
, 'packHalf2x16'
, 'unpackHalf2x16'
, 'outerProduct'
, 'transpose'
, 'determinant'
, 'inverse'
, 'texture'
, 'textureSize'
, 'textureProj'
, 'textureLod'
, 'textureOffset'
, 'texelFetch'
, 'texelFetchOffset'
, 'textureProjOffset'
, 'textureLodOffset'
, 'textureProjLod'
, 'textureProjLodOffset'
, 'textureGrad'
, 'textureGradOffset'
, 'textureProjGrad'
, 'textureProjGradOffset'
])
},{"./builtins":42}],42:[function(require,module,exports){
module.exports = [
// Keep this list sorted
'abs'
, 'acos'
, 'all'
, 'any'
, 'asin'
, 'atan'
, 'ceil'
, 'clamp'
, 'cos'
, 'cross'
, 'dFdx'
, 'dFdy'
, 'degrees'
, 'distance'
, 'dot'
, 'equal'
, 'exp'
, 'exp2'
, 'faceforward'
, 'floor'
, 'fract'
, 'gl_BackColor'
, 'gl_BackLightModelProduct'
, 'gl_BackLightProduct'
, 'gl_BackMaterial'
, 'gl_BackSecondaryColor'
, 'gl_ClipPlane'
, 'gl_ClipVertex'
, 'gl_Color'
, 'gl_DepthRange'
, 'gl_DepthRangeParameters'
, 'gl_EyePlaneQ'
, 'gl_EyePlaneR'
, 'gl_EyePlaneS'
, 'gl_EyePlaneT'
, 'gl_Fog'
, 'gl_FogCoord'
, 'gl_FogFragCoord'
, 'gl_FogParameters'
, 'gl_FragColor'
, 'gl_FragCoord'
, 'gl_FragData'
, 'gl_FragDepth'
, 'gl_FragDepthEXT'
, 'gl_FrontColor'
, 'gl_FrontFacing'
, 'gl_FrontLightModelProduct'
, 'gl_FrontLightProduct'
, 'gl_FrontMaterial'
, 'gl_FrontSecondaryColor'
, 'gl_LightModel'
, 'gl_LightModelParameters'
, 'gl_LightModelProducts'
, 'gl_LightProducts'
, 'gl_LightSource'
, 'gl_LightSourceParameters'
, 'gl_MaterialParameters'
, 'gl_MaxClipPlanes'
, 'gl_MaxCombinedTextureImageUnits'
, 'gl_MaxDrawBuffers'
, 'gl_MaxFragmentUniformComponents'
, 'gl_MaxLights'
, 'gl_MaxTextureCoords'
, 'gl_MaxTextureImageUnits'
, 'gl_MaxTextureUnits'
, 'gl_MaxVaryingFloats'
, 'gl_MaxVertexAttribs'
, 'gl_MaxVertexTextureImageUnits'
, 'gl_MaxVertexUniformComponents'
, 'gl_ModelViewMatrix'
, 'gl_ModelViewMatrixInverse'
, 'gl_ModelViewMatrixInverseTranspose'
, 'gl_ModelViewMatrixTranspose'
, 'gl_ModelViewProjectionMatrix'
, 'gl_ModelViewProjectionMatrixInverse'
, 'gl_ModelViewProjectionMatrixInverseTranspose'
, 'gl_ModelViewProjectionMatrixTranspose'
, 'gl_MultiTexCoord0'
, 'gl_MultiTexCoord1'
, 'gl_MultiTexCoord2'
, 'gl_MultiTexCoord3'
, 'gl_MultiTexCoord4'
, 'gl_MultiTexCoord5'
, 'gl_MultiTexCoord6'
, 'gl_MultiTexCoord7'
, 'gl_Normal'
, 'gl_NormalMatrix'
, 'gl_NormalScale'
, 'gl_ObjectPlaneQ'
, 'gl_ObjectPlaneR'
, 'gl_ObjectPlaneS'
, 'gl_ObjectPlaneT'
, 'gl_Point'
, 'gl_PointCoord'
, 'gl_PointParameters'
, 'gl_PointSize'
, 'gl_Position'
, 'gl_ProjectionMatrix'
, 'gl_ProjectionMatrixInverse'
, 'gl_ProjectionMatrixInverseTranspose'
, 'gl_ProjectionMatrixTranspose'
, 'gl_SecondaryColor'
, 'gl_TexCoord'
, 'gl_TextureEnvColor'
, 'gl_TextureMatrix'
, 'gl_TextureMatrixInverse'
, 'gl_TextureMatrixInverseTranspose'
, 'gl_TextureMatrixTranspose'
, 'gl_Vertex'
, 'greaterThan'
, 'greaterThanEqual'
, 'inversesqrt'
, 'length'
, 'lessThan'
, 'lessThanEqual'
, 'log'
, 'log2'
, 'matrixCompMult'
, 'max'
, 'min'
, 'mix'
, 'mod'
, 'normalize'
, 'not'
, 'notEqual'
, 'pow'
, 'radians'
, 'reflect'
, 'refract'
, 'sign'
, 'sin'
, 'smoothstep'
, 'sqrt'
, 'step'
, 'tan'
, 'texture2D'
, 'texture2DLod'
, 'texture2DProj'
, 'texture2DProjLod'
, 'textureCube'
, 'textureCubeLod'
, 'texture2DLodEXT'
, 'texture2DProjLodEXT'
, 'textureCubeLodEXT'
, 'texture2DGradEXT'
, 'texture2DProjGradEXT'
, 'textureCubeGradEXT'
]
},{}],43:[function(require,module,exports){
var v100 = require('./literals')
module.exports = v100.slice().concat([
'layout'
, 'centroid'
, 'smooth'
, 'case'
, 'mat2x2'
, 'mat2x3'
, 'mat2x4'
, 'mat3x2'
, 'mat3x3'
, 'mat3x4'
, 'mat4x2'
, 'mat4x3'
, 'mat4x4'
, 'uvec2'
, 'uvec3'
, 'uvec4'
, 'samplerCubeShadow'
, 'sampler2DArray'
, 'sampler2DArrayShadow'
, 'isampler2D'
, 'isampler3D'
, 'isamplerCube'
, 'isampler2DArray'
, 'usampler2D'
, 'usampler3D'
, 'usamplerCube'
, 'usampler2DArray'
, 'coherent'
, 'restrict'
, 'readonly'
, 'writeonly'
, 'resource'
, 'atomic_uint'
, 'noperspective'
, 'patch'
, 'sample'
, 'subroutine'
, 'common'
, 'partition'
, 'active'
, 'filter'
, 'image1D'
, 'image2D'
, 'image3D'
, 'imageCube'
, 'iimage1D'
, 'iimage2D'
, 'iimage3D'
, 'iimageCube'
, 'uimage1D'
, 'uimage2D'
, 'uimage3D'
, 'uimageCube'
, 'image1DArray'
, 'image2DArray'
, 'iimage1DArray'
, 'iimage2DArray'
, 'uimage1DArray'
, 'uimage2DArray'
, 'image1DShadow'
, 'image2DShadow'
, 'image1DArrayShadow'
, 'image2DArrayShadow'
, 'imageBuffer'
, 'iimageBuffer'
, 'uimageBuffer'
, 'sampler1DArray'
, 'sampler1DArrayShadow'
, 'isampler1D'
, 'isampler1DArray'
, 'usampler1D'
, 'usampler1DArray'
, 'isampler2DRect'
, 'usampler2DRect'
, 'samplerBuffer'
, 'isamplerBuffer'
, 'usamplerBuffer'
, 'sampler2DMS'
, 'isampler2DMS'
, 'usampler2DMS'
, 'sampler2DMSArray'
, 'isampler2DMSArray'
, 'usampler2DMSArray'
])
},{"./literals":44}],44:[function(require,module,exports){
module.exports = [
// current
'precision'
, 'highp'
, 'mediump'
, 'lowp'
, 'attribute'
, 'const'
, 'uniform'
, 'varying'
, 'break'
, 'continue'
, 'do'
, 'for'
, 'while'
, 'if'
, 'else'
, 'in'
, 'out'
, 'inout'
, 'float'
, 'int'
, 'uint'
, 'void'
, 'bool'
, 'true'
, 'false'
, 'discard'
, 'return'
, 'mat2'
, 'mat3'
, 'mat4'
, 'vec2'
, 'vec3'
, 'vec4'
, 'ivec2'
, 'ivec3'
, 'ivec4'
, 'bvec2'
, 'bvec3'
, 'bvec4'
, 'sampler1D'
, 'sampler2D'
, 'sampler3D'
, 'samplerCube'
, 'sampler1DShadow'
, 'sampler2DShadow'
, 'struct'
// future
, 'asm'
, 'class'
, 'union'
, 'enum'
, 'typedef'
, 'template'
, 'this'
, 'packed'
, 'goto'
, 'switch'
, 'default'
, 'inline'
, 'noinline'
, 'volatile'
, 'public'
, 'static'
, 'extern'
, 'external'
, 'interface'
, 'long'
, 'short'
, 'double'
, 'half'
, 'fixed'
, 'unsigned'
, 'input'
, 'output'
, 'hvec2'
, 'hvec3'
, 'hvec4'
, 'dvec2'
, 'dvec3'
, 'dvec4'
, 'fvec2'
, 'fvec3'
, 'fvec4'
, 'sampler2DRect'
, 'sampler3DRect'
, 'sampler2DRectShadow'
, 'sizeof'
, 'cast'
, 'namespace'
, 'using'
]
},{}],45:[function(require,module,exports){
module.exports = [
'<<='
, '>>='
, '++'
, '--'
, '<<'
, '>>'
, '<='
, '>='
, '=='
, '!='
, '&&'
, '||'
, '+='
, '-='
, '*='
, '/='
, '%='
, '&='
, '^^'
, '^='
, '|='
, '('
, ')'
, '['
, ']'
, '.'
, '!'
, '~'
, '*'
, '/'
, '%'
, '+'
, '-'
, '<'
, '>'
, '&'
, '^'
, '|'
, '?'
, ':'
, '='
, ','
, ';'
, '{'
, '}'
]
},{}],46:[function(require,module,exports){
var tokenize = require('./index')
module.exports = tokenizeString
function tokenizeString(str, opt) {
var generator = tokenize(opt)
var tokens = []
tokens = tokens.concat(generator(str))
tokens = tokens.concat(generator(null))
return tokens
}
},{"./index":40}],47:[function(require,module,exports){
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
var i = isLE ? (nBytes - 1) : 0
var d = isLE ? -1 : 1
var s = buffer[offset + i]
i += d
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}
if (e === 0) {
e = 1 - eBias
} else if (e === eMax) {
return m ? NaN : ((s ? -1 : 1) * Infinity)
} else {
m = m + Math.pow(2, mLen)
e = e - eBias
}
return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
var i = isLE ? 0 : (nBytes - 1)
var d = isLE ? 1 : -1
var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
value = Math.abs(value)
if (isNaN(value) || value === Infinity) {
m = isNaN(value) ? 1 : 0
e = eMax
} else {
e = Math.floor(Math.log(value) / Math.LN2)
if (value * (c = Math.pow(2, -e)) < 1) {
e--
c *= 2
}
if (e + eBias >= 1) {
value += rt / c
} else {
value += rt * Math.pow(2, 1 - eBias)
}
if (value * c >= 2) {
e++
c /= 2
}
if (e + eBias >= eMax) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = ((value * c) - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
e = 0
}
}
for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
e = (e << mLen) | m
eLen += mLen
for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
buffer[offset + i - d] |= s * 128
}
},{}],48:[function(require,module,exports){
"use strict"
function invert(hash) {
var result = {}
for(var i in hash) {
if(hash.hasOwnProperty(i)) {
result[hash[i]] = i
}
}
return result
}
module.exports = invert
},{}],49:[function(require,module,exports){
"use strict"
function iota(n) {
var result = new Array(n)
for(var i=0; i<n; ++i) {
result[i] = i
}
return result
}
module.exports = iota
},{}],50:[function(require,module,exports){
/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
// The _isBuffer check is for Safari 5-7 support, because it's missing
// Object.prototype.constructor. Remove this eventually
module.exports = function (obj) {
return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
}
function isBuffer (obj) {
return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
}
// For Node v0.10 support. Remove this eventually.
function isSlowBuffer (obj) {
return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
}
},{}],51:[function(require,module,exports){
"use strict"
var compile = require("cwise-compiler")
var EmptyProc = {
body: "",
args: [],
thisVars: [],
localVars: []
}
function fixup(x) {
if(!x) {
return EmptyProc
}
for(var i=0; i<x.args.length; ++i) {
var a = x.args[i]
if(i === 0) {
x.args[i] = {name: a, lvalue:true, rvalue: !!x.rvalue, count:x.count||1 }
} else {
x.args[i] = {name: a, lvalue:false, rvalue:true, count: 1}
}
}
if(!x.thisVars) {
x.thisVars = []
}
if(!x.localVars) {
x.localVars = []
}
return x
}
function pcompile(user_args) {
return compile({
args: user_args.args,
pre: fixup(user_args.pre),
body: fixup(user_args.body),
post: fixup(user_args.proc),
funcName: user_args.funcName
})
}
function makeOp(user_args) {
var args = []
for(var i=0; i<user_args.args.length; ++i) {
args.push("a"+i)
}
var wrapper = new Function("P", [
"return function ", user_args.funcName, "_ndarrayops(", args.join(","), ") {P(", args.join(","), ");return a0}"
].join(""))
return wrapper(pcompile(user_args))
}
var assign_ops = {
add: "+",
sub: "-",
mul: "*",
div: "/",
mod: "%",
band: "&",
bor: "|",
bxor: "^",
lshift: "<<",
rshift: ">>",
rrshift: ">>>"
}
;(function(){
for(var id in assign_ops) {
var op = assign_ops[id]
exports[id] = makeOp({
args: ["array","array","array"],
body: {args:["a","b","c"],
body: "a=b"+op+"c"},
funcName: id
})
exports[id+"eq"] = makeOp({
args: ["array","array"],
body: {args:["a","b"],
body:"a"+op+"=b"},
rvalue: true,
funcName: id+"eq"
})
exports[id+"s"] = makeOp({
args: ["array", "array", "scalar"],
body: {args:["a","b","s"],
body:"a=b"+op+"s"},
funcName: id+"s"
})
exports[id+"seq"] = makeOp({
args: ["array","scalar"],
body: {args:["a","s"],
body:"a"+op+"=s"},
rvalue: true,
funcName: id+"seq"
})
}
})();
var unary_ops = {
not: "!",
bnot: "~",
neg: "-",
recip: "1.0/"
}
;(function(){
for(var id in unary_ops) {
var op = unary_ops[id]
exports[id] = makeOp({
args: ["array", "array"],
body: {args:["a","b"],
body:"a="+op+"b"},
funcName: id
})
exports[id+"eq"] = makeOp({
args: ["array"],
body: {args:["a"],
body:"a="+op+"a"},
rvalue: true,
count: 2,
funcName: id+"eq"
})
}
})();
var binary_ops = {
and: "&&",
or: "||",
eq: "===",
neq: "!==",
lt: "<",
gt: ">",
leq: "<=",
geq: ">="
}
;(function() {
for(var id in binary_ops) {
var op = binary_ops[id]
exports[id] = makeOp({
args: ["array","array","array"],
body: {args:["a", "b", "c"],
body:"a=b"+op+"c"},
funcName: id
})
exports[id+"s"] = makeOp({
args: ["array","array","scalar"],
body: {args:["a", "b", "s"],
body:"a=b"+op+"s"},
funcName: id+"s"
})
exports[id+"eq"] = makeOp({
args: ["array", "array"],
body: {args:["a", "b"],
body:"a=a"+op+"b"},
rvalue:true,
count:2,
funcName: id+"eq"
})
exports[id+"seq"] = makeOp({
args: ["array", "scalar"],
body: {args:["a","s"],
body:"a=a"+op+"s"},
rvalue:true,
count:2,
funcName: id+"seq"
})
}
})();
var math_unary = [
"abs",
"acos",
"asin",
"atan",
"ceil",
"cos",
"exp",
"floor",
"log",
"round",
"sin",
"sqrt",
"tan"
]
;(function() {
for(var i=0; i<math_unary.length; ++i) {
var f = math_unary[i]
exports[f] = makeOp({
args: ["array", "array"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b"], body:"a=this_f(b)", thisVars:["this_f"]},
funcName: f
})
exports[f+"eq"] = makeOp({
args: ["array"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args: ["a"], body:"a=this_f(a)", thisVars:["this_f"]},
rvalue: true,
count: 2,
funcName: f+"eq"
})
}
})();
var math_comm = [
"max",
"min",
"atan2",
"pow"
]
;(function(){
for(var i=0; i<math_comm.length; ++i) {
var f= math_comm[i]
exports[f] = makeOp({
args:["array", "array", "array"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b","c"], body:"a=this_f(b,c)", thisVars:["this_f"]},
funcName: f
})
exports[f+"s"] = makeOp({
args:["array", "array", "scalar"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b","c"], body:"a=this_f(b,c)", thisVars:["this_f"]},
funcName: f+"s"
})
exports[f+"eq"] = makeOp({ args:["array", "array"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b"], body:"a=this_f(a,b)", thisVars:["this_f"]},
rvalue: true,
count: 2,
funcName: f+"eq"
})
exports[f+"seq"] = makeOp({ args:["array", "scalar"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b"], body:"a=this_f(a,b)", thisVars:["this_f"]},
rvalue:true,
count:2,
funcName: f+"seq"
})
}
})();
var math_noncomm = [
"atan2",
"pow"
]
;(function(){
for(var i=0; i<math_noncomm.length; ++i) {
var f= math_noncomm[i]
exports[f+"op"] = makeOp({
args:["array", "array", "array"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b","c"], body:"a=this_f(c,b)", thisVars:["this_f"]},
funcName: f+"op"
})
exports[f+"ops"] = makeOp({
args:["array", "array", "scalar"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b","c"], body:"a=this_f(c,b)", thisVars:["this_f"]},
funcName: f+"ops"
})
exports[f+"opeq"] = makeOp({ args:["array", "array"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b"], body:"a=this_f(b,a)", thisVars:["this_f"]},
rvalue: true,
count: 2,
funcName: f+"opeq"
})
exports[f+"opseq"] = makeOp({ args:["array", "scalar"],
pre: {args:[], body:"this_f=Math."+f, thisVars:["this_f"]},
body: {args:["a","b"], body:"a=this_f(b,a)", thisVars:["this_f"]},
rvalue:true,
count:2,
funcName: f+"opseq"
})
}
})();
exports.any = compile({
args:["array"],
pre: EmptyProc,
body: {args:[{name:"a", lvalue:false, rvalue:true, count:1}], body: "if(a){return true}", localVars: [], thisVars: []},
post: {args:[], localVars:[], thisVars:[], body:"return false"},
funcName: "any"
})
exports.all = compile({
args:["array"],
pre: EmptyProc,
body: {args:[{name:"x", lvalue:false, rvalue:true, count:1}], body: "if(!x){return false}", localVars: [], thisVars: []},
post: {args:[], localVars:[], thisVars:[], body:"return true"},
funcName: "all"
})
exports.sum = compile({
args:["array"],
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"},
body: {args:[{name:"a", lvalue:false, rvalue:true, count:1}], body: "this_s+=a", localVars: [], thisVars: ["this_s"]},
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
funcName: "sum"
})
exports.prod = compile({
args:["array"],
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=1"},
body: {args:[{name:"a", lvalue:false, rvalue:true, count:1}], body: "this_s*=a", localVars: [], thisVars: ["this_s"]},
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
funcName: "prod"
})
exports.norm2squared = compile({
args:["array"],
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"},
body: {args:[{name:"a", lvalue:false, rvalue:true, count:2}], body: "this_s+=a*a", localVars: [], thisVars: ["this_s"]},
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
funcName: "norm2squared"
})
exports.norm2 = compile({
args:["array"],
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"},
body: {args:[{name:"a", lvalue:false, rvalue:true, count:2}], body: "this_s+=a*a", localVars: [], thisVars: ["this_s"]},
post: {args:[], localVars:[], thisVars:["this_s"], body:"return Math.sqrt(this_s)"},
funcName: "norm2"
})
exports.norminf = compile({
args:["array"],
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"},
body: {args:[{name:"a", lvalue:false, rvalue:true, count:4}], body:"if(-a>this_s){this_s=-a}else if(a>this_s){this_s=a}", localVars: [], thisVars: ["this_s"]},
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
funcName: "norminf"
})
exports.norm1 = compile({
args:["array"],
pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"},
body: {args:[{name:"a", lvalue:false, rvalue:true, count:3}], body: "this_s+=a<0?-a:a", localVars: [], thisVars: ["this_s"]},
post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"},
funcName: "norm1"
})
exports.sup = compile({
args: [ "array" ],
pre:
{ body: "this_h=-Infinity",
args: [],
thisVars: [ "this_h" ],
localVars: [] },
body:
{ body: "if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_",
args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ],
thisVars: [ "this_h" ],
localVars: [] },
post:
{ body: "return this_h",
args: [],
thisVars: [ "this_h" ],
localVars: [] }
})
exports.inf = compile({
args: [ "array" ],
pre:
{ body: "this_h=Infinity",
args: [],
thisVars: [ "this_h" ],
localVars: [] },
body:
{ body: "if(_inline_1_arg0_<this_h)this_h=_inline_1_arg0_",
args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ],
thisVars: [ "this_h" ],
localVars: [] },
post:
{ body: "return this_h",
args: [],
thisVars: [ "this_h" ],
localVars: [] }
})
exports.argmin = compile({
args:["index","array","shape"],
pre:{
body:"{this_v=Infinity;this_i=_inline_0_arg2_.slice(0)}",
args:[
{name:"_inline_0_arg0_",lvalue:false,rvalue:false,count:0},
{name:"_inline_0_arg1_",lvalue:false,rvalue:false,count:0},
{name:"_inline_0_arg2_",lvalue:false,rvalue:true,count:1}
],
thisVars:["this_i","this_v"],
localVars:[]},
body:{
body:"{if(_inline_1_arg1_<this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}",
args:[
{name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2},
{name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}],
thisVars:["this_i","this_v"],
localVars:["_inline_1_k"]},
post:{
body:"{return this_i}",
args:[],
thisVars:["this_i"],
localVars:[]}
})
exports.argmax = compile({
args:["index","array","shape"],
pre:{
body:"{this_v=-Infinity;this_i=_inline_0_arg2_.slice(0)}",
args:[
{name:"_inline_0_arg0_",lvalue:false,rvalue:false,count:0},
{name:"_inline_0_arg1_",lvalue:false,rvalue:false,count:0},
{name:"_inline_0_arg2_",lvalue:false,rvalue:true,count:1}
],
thisVars:["this_i","this_v"],
localVars:[]},
body:{
body:"{if(_inline_1_arg1_>this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}",
args:[
{name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2},
{name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}],
thisVars:["this_i","this_v"],
localVars:["_inline_1_k"]},
post:{
body:"{return this_i}",
args:[],
thisVars:["this_i"],
localVars:[]}
})
exports.random = makeOp({
args: ["array"],
pre: {args:[], body:"this_f=Math.random", thisVars:["this_f"]},
body: {args: ["a"], body:"a=this_f()", thisVars:["this_f"]},
funcName: "random"
})
exports.assign = makeOp({
args:["array", "array"],
body: {args:["a", "b"], body:"a=b"},
funcName: "assign" })
exports.assigns = makeOp({
args:["array", "scalar"],
body: {args:["a", "b"], body:"a=b"},
funcName: "assigns" })
exports.equals = compile({
args:["array", "array"],
pre: EmptyProc,
body: {args:[{name:"x", lvalue:false, rvalue:true, count:1},
{name:"y", lvalue:false, rvalue:true, count:1}],
body: "if(x!==y){return false}",
localVars: [],
thisVars: []},
post: {args:[], localVars:[], thisVars:[], body:"return true"},
funcName: "equals"
})
},{"cwise-compiler":52}],52:[function(require,module,exports){
"use strict"
var createThunk = require("./lib/thunk.js")
function Procedure() {
this.argTypes = []
this.shimArgs = []
this.arrayArgs = []
this.arrayBlockIndices = []
this.scalarArgs = []
this.offsetArgs = []
this.offsetArgIndex = []
this.indexArgs = []
this.shapeArgs = []
this.funcName = ""
this.pre = null
this.body = null
this.post = null
this.debug = false
}
function compileCwise(user_args) {
//Create procedure
var proc = new Procedure()
//Parse blocks
proc.pre = user_args.pre
proc.body = user_args.body
proc.post = user_args.post
//Parse arguments
var proc_args = user_args.args.slice(0)
proc.argTypes = proc_args
for(var i=0; i<proc_args.length; ++i) {
var arg_type = proc_args[i]
if(arg_type === "array" || (typeof arg_type === "object" && arg_type.blockIndices)) {
proc.argTypes[i] = "array"
proc.arrayArgs.push(i)
proc.arrayBlockIndices.push(arg_type.blockIndices ? arg_type.blockIndices : 0)
proc.shimArgs.push("array" + i)
if(i < proc.pre.args.length && proc.pre.args[i].count>0) {
throw new Error("cwise: pre() block may not reference array args")
}
if(i < proc.post.args.length && proc.post.args[i].count>0) {
throw new Error("cwise: post() block may not reference array args")
}
} else if(arg_type === "scalar") {
proc.scalarArgs.push(i)
proc.shimArgs.push("scalar" + i)
} else if(arg_type === "index") {
proc.indexArgs.push(i)
if(i < proc.pre.args.length && proc.pre.args[i].count > 0) {
throw new Error("cwise: pre() block may not reference array index")
}
if(i < proc.body.args.length && proc.body.args[i].lvalue) {
throw new Error("cwise: body() block may not write to array index")
}
if(i < proc.post.args.length && proc.post.args[i].count > 0) {
throw new Error("cwise: post() block may not reference array index")
}
} else if(arg_type === "shape") {
proc.shapeArgs.push(i)
if(i < proc.pre.args.length && proc.pre.args[i].lvalue) {
throw new Error("cwise: pre() block may not write to array shape")
}
if(i < proc.body.args.length && proc.body.args[i].lvalue) {
throw new Error("cwise: body() block may not write to array shape")
}
if(i < proc.post.args.length && proc.post.args[i].lvalue) {
throw new Error("cwise: post() block may not write to array shape")
}
} else if(typeof arg_type === "object" && arg_type.offset) {
proc.argTypes[i] = "offset"
proc.offsetArgs.push({ array: arg_type.array, offset:arg_type.offset })
proc.offsetArgIndex.push(i)
} else {
throw new Error("cwise: Unknown argument type " + proc_args[i])
}
}
//Make sure at least one array argument was specified
if(proc.arrayArgs.length <= 0) {
throw new Error("cwise: No array arguments specified")
}
//Make sure arguments are correct
if(proc.pre.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in pre() block")
}
if(proc.body.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in body() block")
}
if(proc.post.args.length > proc_args.length) {
throw new Error("cwise: Too many arguments in post() block")
}
//Check debug flag
proc.debug = !!user_args.printCode || !!user_args.debug
//Retrieve name
proc.funcName = user_args.funcName || "cwise"
//Read in block size
proc.blockSize = user_args.blockSize || 64
return createThunk(proc)
}
module.exports = compileCwise
},{"./lib/thunk.js":54}],53:[function(require,module,exports){
"use strict"
var uniq = require("uniq")
// This function generates very simple loops analogous to how you typically traverse arrays (the outermost loop corresponds to the slowest changing index, the innermost loop to the fastest changing index)
// TODO: If two arrays have the same strides (and offsets) there is potential for decreasing the number of "pointers" and related variables. The drawback is that the type signature would become more specific and that there would thus be less potential for caching, but it might still be worth it, especially when dealing with large numbers of arguments.
function innerFill(order, proc, body) {
var dimension = order.length
, nargs = proc.arrayArgs.length
, has_index = proc.indexArgs.length>0
, code = []
, vars = []
, idx=0, pidx=0, i, j
for(i=0; i<dimension; ++i) { // Iteration variables
vars.push(["i",i,"=0"].join(""))
}
//Compute scan deltas
for(j=0; j<nargs; ++j) {
for(i=0; i<dimension; ++i) {
pidx = idx
idx = order[i]
if(i === 0) { // The innermost/fastest dimension's delta is simply its stride
vars.push(["d",j,"s",i,"=t",j,"p",idx].join(""))
} else { // For other dimensions the delta is basically the stride minus something which essentially "rewinds" the previous (more inner) dimension
vars.push(["d",j,"s",i,"=(t",j,"p",idx,"-s",pidx,"*t",j,"p",pidx,")"].join(""))
}
}
}
if (vars.length > 0) {
code.push("var " + vars.join(","))
}
//Scan loop
for(i=dimension-1; i>=0; --i) { // Start at largest stride and work your way inwards
idx = order[i]
code.push(["for(i",i,"=0;i",i,"<s",idx,";++i",i,"){"].join(""))
}
//Push body of inner loop
code.push(body)
//Advance scan pointers
for(i=0; i<dimension; ++i) {
pidx = idx
idx = order[i]
for(j=0; j<nargs; ++j) {
code.push(["p",j,"+=d",j,"s",i].join(""))
}
if(has_index) {
if(i > 0) {
code.push(["index[",pidx,"]-=s",pidx].join(""))
}
code.push(["++index[",idx,"]"].join(""))
}
code.push("}")
}
return code.join("\n")
}
// Generate "outer" loops that loop over blocks of data, applying "inner" loops to the blocks by manipulating the local variables in such a way that the inner loop only "sees" the current block.
// TODO: If this is used, then the previous declaration (done by generateCwiseOp) of s* is essentially unnecessary.
// I believe the s* are not used elsewhere (in particular, I don't think they're used in the pre/post parts and "shape" is defined independently), so it would be possible to make defining the s* dependent on what loop method is being used.
function outerFill(matched, order, proc, body) {
var dimension = order.length
, nargs = proc.arrayArgs.length
, blockSize = proc.blockSize
, has_index = proc.indexArgs.length > 0
, code = []
for(var i=0; i<nargs; ++i) {
code.push(["var offset",i,"=p",i].join(""))
}
//Generate loops for unmatched dimensions
// The order in which these dimensions are traversed is fairly arbitrary (from small stride to large stride, for the first argument)
// TODO: It would be nice if the order in which these loops are placed would also be somehow "optimal" (at the very least we should check that it really doesn't hurt us if they're not).
for(var i=matched; i<dimension; ++i) {
code.push(["for(var j"+i+"=SS[", order[i], "]|0;j", i, ">0;){"].join("")) // Iterate back to front
code.push(["if(j",i,"<",blockSize,"){"].join("")) // Either decrease j by blockSize (s = blockSize), or set it to zero (after setting s = j).
code.push(["s",order[i],"=j",i].join(""))
code.push(["j",i,"=0"].join(""))
code.push(["}else{s",order[i],"=",blockSize].join(""))
code.push(["j",i,"-=",blockSize,"}"].join(""))
if(has_index) {
code.push(["index[",order[i],"]=j",i].join(""))
}
}
for(var i=0; i<nargs; ++i) {
var indexStr = ["offset"+i]
for(var j=matched; j<dimension; ++j) {
indexStr.push(["j",j,"*t",i,"p",order[j]].join(""))
}
code.push(["p",i,"=(",indexStr.join("+"),")"].join(""))
}
code.push(innerFill(order, proc, body))
for(var i=matched; i<dimension; ++i) {
code.push("}")
}
return code.join("\n")
}
//Count the number of compatible inner orders
// This is the length of the longest common prefix of the arrays in orders.
// Each array in orders lists the dimensions of the correspond ndarray in order of increasing stride.
// This is thus the maximum number of dimensions that can be efficiently traversed by simple nested loops for all arrays.
function countMatches(orders) {
var matched = 0, dimension = orders[0].length
while(matched < dimension) {
for(var j=1; j<orders.length; ++j) {
if(orders[j][matched] !== orders[0][matched]) {
return matched
}
}
++matched
}
return matched
}
//Processes a block according to the given data types
// Replaces variable names by different ones, either "local" ones (that are then ferried in and out of the given array) or ones matching the arguments that the function performing the ultimate loop will accept.
function processBlock(block, proc, dtypes) {
var code = block.body
var pre = []
var post = []
for(var i=0; i<block.args.length; ++i) {
var carg = block.args[i]
if(carg.count <= 0) {
continue
}
var re = new RegExp(carg.name, "g")
var ptrStr = ""
var arrNum = proc.arrayArgs.indexOf(i)
switch(proc.argTypes[i]) {
case "offset":
var offArgIndex = proc.offsetArgIndex.indexOf(i)
var offArg = proc.offsetArgs[offArgIndex]
arrNum = offArg.array
ptrStr = "+q" + offArgIndex // Adds offset to the "pointer" in the array
case "array":
ptrStr = "p" + arrNum + ptrStr
var localStr = "l" + i
var arrStr = "a" + arrNum
if (proc.arrayBlockIndices[arrNum] === 0) { // Argument to body is just a single value from this array
if(carg.count === 1) { // Argument/array used only once(?)
if(dtypes[arrNum] === "generic") {
if(carg.lvalue) {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue)
code = code.replace(re, localStr)
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
} else {
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join(""))
}
} else {
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join(""))
}
} else if(dtypes[arrNum] === "generic") {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // TODO: Could we optimize by checking for carg.rvalue?
code = code.replace(re, localStr)
if(carg.lvalue) {
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
}
} else {
pre.push(["var ", localStr, "=", arrStr, "[", ptrStr, "]"].join("")) // TODO: Could we optimize by checking for carg.rvalue?
code = code.replace(re, localStr)
if(carg.lvalue) {
post.push([arrStr, "[", ptrStr, "]=", localStr].join(""))
}
}
} else { // Argument to body is a "block"
var reStrArr = [carg.name], ptrStrArr = [ptrStr]
for(var j=0; j<Math.abs(proc.arrayBlockIndices[arrNum]); j++) {
reStrArr.push("\\s*\\[([^\\]]+)\\]")
ptrStrArr.push("$" + (j+1) + "*t" + arrNum + "b" + j) // Matched index times stride
}
re = new RegExp(reStrArr.join(""), "g")
ptrStr = ptrStrArr.join("+")
if(dtypes[arrNum] === "generic") {
/*if(carg.lvalue) {
pre.push(["var ", localStr, "=", arrStr, ".get(", ptrStr, ")"].join("")) // Is this necessary if the argument is ONLY used as an lvalue? (keep in mind that we can have a += something, so we would actually need to check carg.rvalue)
code = code.replace(re, localStr)
post.push([arrStr, ".set(", ptrStr, ",", localStr,")"].join(""))
} else {
code = code.replace(re, [arrStr, ".get(", ptrStr, ")"].join(""))
}*/
throw new Error("cwise: Generic arrays not supported in combination with blocks!")
} else {
// This does not produce any local variables, even if variables are used multiple times. It would be possible to do so, but it would complicate things quite a bit.
code = code.replace(re, [arrStr, "[", ptrStr, "]"].join(""))
}
}
break
case "scalar":
code = code.replace(re, "Y" + proc.scalarArgs.indexOf(i))
break
case "index":
code = code.replace(re, "index")
break
case "shape":
code = code.replace(re, "shape")
break
}
}
return [pre.join("\n"), code, post.join("\n")].join("\n").trim()
}
function typeSummary(dtypes) {
var summary = new Array(dtypes.length)
var allEqual = true
for(var i=0; i<dtypes.length; ++i) {
var t = dtypes[i]
var digits = t.match(/\d+/)
if(!digits) {
digits = ""
} else {
digits = digits[0]
}
if(t.charAt(0) === 0) {
summary[i] = "u" + t.charAt(1) + digits
} else {
summary[i] = t.charAt(0) + digits
}
if(i > 0) {
allEqual = allEqual && summary[i] === summary[i-1]
}
}
if(allEqual) {
return summary[0]
}
return summary.join("")
}
//Generates a cwise operator
function generateCWiseOp(proc, typesig) {
//Compute dimension
// Arrays get put first in typesig, and there are two entries per array (dtype and order), so this gets the number of dimensions in the first array arg.
var dimension = (typesig[1].length - Math.abs(proc.arrayBlockIndices[0]))|0
var orders = new Array(proc.arrayArgs.length)
var dtypes = new Array(proc.arrayArgs.length)
for(var i=0; i<proc.arrayArgs.length; ++i) {
dtypes[i] = typesig[2*i]
orders[i] = typesig[2*i+1]
}
//Determine where block and loop indices start and end
var blockBegin = [], blockEnd = [] // These indices are exposed as blocks
var loopBegin = [], loopEnd = [] // These indices are iterated over
var loopOrders = [] // orders restricted to the loop indices
for(var i=0; i<proc.arrayArgs.length; ++i) {
if (proc.arrayBlockIndices[i]<0) {
loopBegin.push(0)
loopEnd.push(dimension)
blockBegin.push(dimension)
blockEnd.push(dimension+proc.arrayBlockIndices[i])
} else {
loopBegin.push(proc.arrayBlockIndices[i]) // Non-negative
loopEnd.push(proc.arrayBlockIndices[i]+dimension)
blockBegin.push(0)
blockEnd.push(proc.arrayBlockIndices[i])
}
var newOrder = []
for(var j=0; j<orders[i].length; j++) {
if (loopBegin[i]<=orders[i][j] && orders[i][j]<loopEnd[i]) {
newOrder.push(orders[i][j]-loopBegin[i]) // If this is a loop index, put it in newOrder, subtracting loopBegin, to make sure that all loopOrders are using a common set of indices.
}
}
loopOrders.push(newOrder)
}
//First create arguments for procedure
var arglist = ["SS"] // SS is the overall shape over which we iterate
var code = ["'use strict'"]
var vars = []
for(var j=0; j<dimension; ++j) {
vars.push(["s", j, "=SS[", j, "]"].join("")) // The limits for each dimension.
}
for(var i=0; i<proc.arrayArgs.length; ++i) {
arglist.push("a"+i) // Actual data array
arglist.push("t"+i) // Strides
arglist.push("p"+i) // Offset in the array at which the data starts (also used for iterating over the data)
for(var j=0; j<dimension; ++j) { // Unpack the strides into vars for looping
vars.push(["t",i,"p",j,"=t",i,"[",loopBegin[i]+j,"]"].join(""))
}
for(var j=0; j<Math.abs(proc.arrayBlockIndices[i]); ++j) { // Unpack the strides into vars for block iteration
vars.push(["t",i,"b",j,"=t",i,"[",blockBegin[i]+j,"]"].join(""))
}
}
for(var i=0; i<proc.scalarArgs.length; ++i) {
arglist.push("Y" + i)
}
if(proc.shapeArgs.length > 0) {
vars.push("shape=SS.slice(0)") // Makes the shape over which we iterate available to the user defined functions (so you can use width/height for example)
}
if(proc.indexArgs.length > 0) {
// Prepare an array to keep track of the (logical) indices, initialized to dimension zeroes.
var zeros = new Array(dimension)
for(var i=0; i<dimension; ++i) {
zeros[i] = "0"
}
vars.push(["index=[", zeros.join(","), "]"].join(""))
}
for(var i=0; i<proc.offsetArgs.length; ++i) { // Offset arguments used for stencil operations
var off_arg = proc.offsetArgs[i]
var init_string = []
for(var j=0; j<off_arg.offset.length; ++j) {
if(off_arg.offset[j] === 0) {
continue
} else if(off_arg.offset[j] === 1) {
init_string.push(["t", off_arg.array, "p", j].join(""))
} else {
init_string.push([off_arg.offset[j], "*t", off_arg.array, "p", j].join(""))
}
}
if(init_string.length === 0) {
vars.push("q" + i + "=0")
} else {
vars.push(["q", i, "=", init_string.join("+")].join(""))
}
}
//Prepare this variables
var thisVars = uniq([].concat(proc.pre.thisVars)
.concat(proc.body.thisVars)
.concat(proc.post.thisVars))
vars = vars.concat(thisVars)
if (vars.length > 0) {
code.push("var " + vars.join(","))
}
for(var i=0; i<proc.arrayArgs.length; ++i) {
code.push("p"+i+"|=0")
}
//Inline prelude
if(proc.pre.body.length > 3) {
code.push(processBlock(proc.pre, proc, dtypes))
}
//Process body
var body = processBlock(proc.body, proc, dtypes)
var matched = countMatches(loopOrders)
if(matched < dimension) {
code.push(outerFill(matched, loopOrders[0], proc, body)) // TODO: Rather than passing loopOrders[0], it might be interesting to look at passing an order that represents the majority of the arguments for example.
} else {
code.push(innerFill(loopOrders[0], proc, body))
}
//Inline epilog
if(proc.post.body.length > 3) {
code.push(processBlock(proc.post, proc, dtypes))
}
if(proc.debug) {
console.log("-----Generated cwise routine for ", typesig, ":\n" + code.join("\n") + "\n----------")
}
var loopName = [(proc.funcName||"unnamed"), "_cwise_loop_", orders[0].join("s"),"m",matched,typeSummary(dtypes)].join("")
var f = new Function(["function ",loopName,"(", arglist.join(","),"){", code.join("\n"),"} return ", loopName].join(""))
return f()
}
module.exports = generateCWiseOp
},{"uniq":62}],54:[function(require,module,exports){
"use strict"
// The function below is called when constructing a cwise function object, and does the following:
// A function object is constructed which accepts as argument a compilation function and returns another function.
// It is this other function that is eventually returned by createThunk, and this function is the one that actually
// checks whether a certain pattern of arguments has already been used before and compiles new loops as needed.
// The compilation passed to the first function object is used for compiling new functions.
// Once this function object is created, it is called with compile as argument, where the first argument of compile
// is bound to "proc" (essentially containing a preprocessed version of the user arguments to cwise).
// So createThunk roughly works like this:
// function createThunk(proc) {
// var thunk = function(compileBound) {
// var CACHED = {}
// return function(arrays and scalars) {
// if (dtype and order of arrays in CACHED) {
// var func = CACHED[dtype and order of arrays]
// } else {
// var func = CACHED[dtype and order of arrays] = compileBound(dtype and order of arrays)
// }
// return func(arrays and scalars)
// }
// }
// return thunk(compile.bind1(proc))
// }
var compile = require("./compile.js")
function createThunk(proc) {
var code = ["'use strict'", "var CACHED={}"]
var vars = []
var thunkName = proc.funcName + "_cwise_thunk"
//Build thunk
code.push(["return function ", thunkName, "(", proc.shimArgs.join(","), "){"].join(""))
var typesig = []
var string_typesig = []
var proc_args = [["array",proc.arrayArgs[0],".shape.slice(", // Slice shape so that we only retain the shape over which we iterate (which gets passed to the cwise operator as SS).
Math.max(0,proc.arrayBlockIndices[0]),proc.arrayBlockIndices[0]<0?(","+proc.arrayBlockIndices[0]+")"):")"].join("")]
var shapeLengthConditions = [], shapeConditions = []
// Process array arguments
for(var i=0; i<proc.arrayArgs.length; ++i) {
var j = proc.arrayArgs[i]
vars.push(["t", j, "=array", j, ".dtype,",
"r", j, "=array", j, ".order"].join(""))
typesig.push("t" + j)
typesig.push("r" + j)
string_typesig.push("t"+j)
string_typesig.push("r"+j+".join()")
proc_args.push("array" + j + ".data")
proc_args.push("array" + j + ".stride")
proc_args.push("array" + j + ".offset|0")
if (i>0) { // Gather conditions to check for shape equality (ignoring block indices)
shapeLengthConditions.push("array" + proc.arrayArgs[0] + ".shape.length===array" + j + ".shape.length+" + (Math.abs(proc.arrayBlockIndices[0])-Math.abs(proc.arrayBlockIndices[i])))
shapeConditions.push("array" + proc.arrayArgs[0] + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[0]) + "]===array" + j + ".shape[shapeIndex+" + Math.max(0,proc.arrayBlockIndices[i]) + "]")
}
}
// Check for shape equality
if (proc.arrayArgs.length > 1) {
code.push("if (!(" + shapeLengthConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same dimensionality!')")
code.push("for(var shapeIndex=array" + proc.arrayArgs[0] + ".shape.length-" + Math.abs(proc.arrayBlockIndices[0]) + "; shapeIndex-->0;) {")
code.push("if (!(" + shapeConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same shape!')")
code.push("}")
}
// Process scalar arguments
for(var i=0; i<proc.scalarArgs.length; ++i) {
proc_args.push("scalar" + proc.scalarArgs[i])
}
// Check for cached function (and if not present, generate it)
vars.push(["type=[", string_typesig.join(","), "].join()"].join(""))
vars.push("proc=CACHED[type]")
code.push("var " + vars.join(","))
code.push(["if(!proc){",
"CACHED[type]=proc=compile([", typesig.join(","), "])}",
"return proc(", proc_args.join(","), ")}"].join(""))
if(proc.debug) {
console.log("-----Generated thunk:\n" + code.join("\n") + "\n----------")
}
//Compile thunk
var thunk = new Function("compile", code.join("\n"))
return thunk(compile.bind(undefined, proc))
}
module.exports = createThunk
},{"./compile.js":53}],55:[function(require,module,exports){
var iota = require("iota-array")
var isBuffer = require("is-buffer")
var hasTypedArrays = ((typeof Float64Array) !== "undefined")
function compare1st(a, b) {
return a[0] - b[0]
}
function order() {
var stride = this.stride
var terms = new Array(stride.length)
var i
for(i=0; i<terms.length; ++i) {
terms[i] = [Math.abs(stride[i]), i]
}
terms.sort(compare1st)
var result = new Array(terms.length)
for(i=0; i<result.length; ++i) {
result[i] = terms[i][1]
}
return result
}
function compileConstructor(dtype, dimension) {
var className = ["View", dimension, "d", dtype].join("")
if(dimension < 0) {
className = "View_Nil" + dtype
}
var useGetters = (dtype === "generic")
if(dimension === -1) {
//Special case for trivial arrays
var code =
"function "+className+"(a){this.data=a;};\
var proto="+className+".prototype;\
proto.dtype='"+dtype+"';\
proto.index=function(){return -1};\
proto.size=0;\
proto.dimension=-1;\
proto.shape=proto.stride=proto.order=[];\
proto.lo=proto.hi=proto.transpose=proto.step=\
function(){return new "+className+"(this.data);};\
proto.get=proto.set=function(){};\
proto.pick=function(){return null};\
return function construct_"+className+"(a){return new "+className+"(a);}"
var procedure = new Function(code)
return procedure()
} else if(dimension === 0) {
//Special case for 0d arrays
var code =
"function "+className+"(a,d) {\
this.data = a;\
this.offset = d\
};\
var proto="+className+".prototype;\
proto.dtype='"+dtype+"';\
proto.index=function(){return this.offset};\
proto.dimension=0;\
proto.size=1;\
proto.shape=\
proto.stride=\
proto.order=[];\
proto.lo=\
proto.hi=\
proto.transpose=\
proto.step=function "+className+"_copy() {\
return new "+className+"(this.data,this.offset)\
};\
proto.pick=function "+className+"_pick(){\
return TrivialArray(this.data);\
};\
proto.valueOf=proto.get=function "+className+"_get(){\
return "+(useGetters ? "this.data.get(this.offset)" : "this.data[this.offset]")+
"};\
proto.set=function "+className+"_set(v){\
return "+(useGetters ? "this.data.set(this.offset,v)" : "this.data[this.offset]=v")+"\
};\
return function construct_"+className+"(a,b,c,d){return new "+className+"(a,d)}"
var procedure = new Function("TrivialArray", code)
return procedure(CACHED_CONSTRUCTORS[dtype][0])
}
var code = ["'use strict'"]
//Create constructor for view
var indices = iota(dimension)
var args = indices.map(function(i) { return "i"+i })
var index_str = "this.offset+" + indices.map(function(i) {
return "this.stride[" + i + "]*i" + i
}).join("+")
var shapeArg = indices.map(function(i) {
return "b"+i
}).join(",")
var strideArg = indices.map(function(i) {
return "c"+i
}).join(",")
code.push(
"function "+className+"(a," + shapeArg + "," + strideArg + ",d){this.data=a",
"this.shape=[" + shapeArg + "]",
"this.stride=[" + strideArg + "]",
"this.offset=d|0}",
"var proto="+className+".prototype",
"proto.dtype='"+dtype+"'",
"proto.dimension="+dimension)
//view.size:
code.push("Object.defineProperty(proto,'size',{get:function "+className+"_size(){\
return "+indices.map(function(i) { return "this.shape["+i+"]" }).join("*"),
"}})")
//view.order:
if(dimension === 1) {
code.push("proto.order=[0]")
} else {
code.push("Object.defineProperty(proto,'order',{get:")
if(dimension < 4) {
code.push("function "+className+"_order(){")
if(dimension === 2) {
code.push("return (Math.abs(this.stride[0])>Math.abs(this.stride[1]))?[1,0]:[0,1]}})")
} else if(dimension === 3) {
code.push(
"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\
if(s0>s1){\
if(s1>s2){\
return [2,1,0];\
}else if(s0>s2){\
return [1,2,0];\
}else{\
return [1,0,2];\
}\
}else if(s0>s2){\
return [2,0,1];\
}else if(s2>s1){\
return [0,1,2];\
}else{\
return [0,2,1];\
}}})")
}
} else {
code.push("ORDER})")
}
}
//view.set(i0, ..., v):
code.push(
"proto.set=function "+className+"_set("+args.join(",")+",v){")
if(useGetters) {
code.push("return this.data.set("+index_str+",v)}")
} else {
code.push("return this.data["+index_str+"]=v}")
}
//view.get(i0, ...):
code.push("proto.get=function "+className+"_get("+args.join(",")+"){")
if(useGetters) {
code.push("return this.data.get("+index_str+")}")
} else {
code.push("return this.data["+index_str+"]}")
}
//view.index:
code.push(
"proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}")
//view.hi():
code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+
indices.map(function(i) {
return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("")
}).join(",")+","+
indices.map(function(i) {
return "this.stride["+i + "]"
}).join(",")+",this.offset)}")
//view.lo():
var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" })
var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" })
code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(","))
for(var i=0; i<dimension; ++i) {
code.push(
"if(typeof i"+i+"==='number'&&i"+i+">=0){\
d=i"+i+"|0;\
b+=c"+i+"*d;\
a"+i+"-=d}")
}
code.push("return new "+className+"(this.data,"+
indices.map(function(i) {
return "a"+i
}).join(",")+","+
indices.map(function(i) {
return "c"+i
}).join(",")+",b)}")
//view.step():
code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+
indices.map(function(i) {
return "a"+i+"=this.shape["+i+"]"
}).join(",")+","+
indices.map(function(i) {
return "b"+i+"=this.stride["+i+"]"
}).join(",")+",c=this.offset,d=0,ceil=Math.ceil")
for(var i=0; i<dimension; ++i) {
code.push(
"if(typeof i"+i+"==='number'){\
d=i"+i+"|0;\
if(d<0){\
c+=b"+i+"*(a"+i+"-1);\
a"+i+"=ceil(-a"+i+"/d)\
}else{\
a"+i+"=ceil(a"+i+"/d)\
}\
b"+i+"*=d\
}")
}
code.push("return new "+className+"(this.data,"+
indices.map(function(i) {
return "a" + i
}).join(",")+","+
indices.map(function(i) {
return "b" + i
}).join(",")+",c)}")
//view.transpose():
var tShape = new Array(dimension)
var tStride = new Array(dimension)
for(var i=0; i<dimension; ++i) {
tShape[i] = "a[i"+i+"]"
tStride[i] = "b[i"+i+"]"
}
code.push("proto.transpose=function "+className+"_transpose("+args+"){"+
args.map(function(n,idx) { return n + "=(" + n + "===undefined?" + idx + ":" + n + "|0)"}).join(";"),
"var a=this.shape,b=this.stride;return new "+className+"(this.data,"+tShape.join(",")+","+tStride.join(",")+",this.offset)}")
//view.pick():
code.push("proto.pick=function "+className+"_pick("+args+"){var a=[],b=[],c=this.offset")
for(var i=0; i<dimension; ++i) {
code.push("if(typeof i"+i+"==='number'&&i"+i+">=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}")
}
code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}")
//Add return statement
code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+
indices.map(function(i) {
return "shape["+i+"]"
}).join(",")+","+
indices.map(function(i) {
return "stride["+i+"]"
}).join(",")+",offset)}")
//Compile procedure
var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n"))
return procedure(CACHED_CONSTRUCTORS[dtype], order)
}
function arrayDType(data) {
if(isBuffer(data)) {
return "buffer"
}
if(hasTypedArrays) {
switch(Object.prototype.toString.call(data)) {
case "[object Float64Array]":
return "float64"
case "[object Float32Array]":
return "float32"
case "[object Int8Array]":
return "int8"
case "[object Int16Array]":
return "int16"
case "[object Int32Array]":
return "int32"
case "[object Uint8Array]":
return "uint8"
case "[object Uint16Array]":
return "uint16"
case "[object Uint32Array]":
return "uint32"
case "[object Uint8ClampedArray]":
return "uint8_clamped"
case "[object BigInt64Array]":
return "bigint64"
case "[object BigUint64Array]":
return "biguint64"
}
}
if(Array.isArray(data)) {
return "array"
}
return "generic"
}
var CACHED_CONSTRUCTORS = {
"float32":[],
"float64":[],
"int8":[],
"int16":[],
"int32":[],
"uint8":[],
"uint16":[],
"uint32":[],
"array":[],
"uint8_clamped":[],
"bigint64": [],
"biguint64": [],
"buffer":[],
"generic":[]
}
;(function() {
for(var id in CACHED_CONSTRUCTORS) {
CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1))
}
});
function wrappedNDArrayCtor(data, shape, stride, offset) {
if(data === undefined) {
var ctor = CACHED_CONSTRUCTORS.array[0]
return ctor([])
} else if(typeof data === "number") {
data = [data]
}
if(shape === undefined) {
shape = [ data.length ]
}
var d = shape.length
if(stride === undefined) {
stride = new Array(d)
for(var i=d-1, sz=1; i>=0; --i) {
stride[i] = sz
sz *= shape[i]
}
}
if(offset === undefined) {
offset = 0
for(var i=0; i<d; ++i) {
if(stride[i] < 0) {
offset -= (shape[i]-1)*stride[i]
}
}
}
var dtype = arrayDType(data)
var ctor_list = CACHED_CONSTRUCTORS[dtype]
while(ctor_list.length <= d+1) {
ctor_list.push(compileConstructor(dtype, ctor_list.length-1))
}
var ctor = ctor_list[d+1]
return ctor(data, shape, stride, offset)
}
module.exports = wrappedNDArrayCtor
},{"iota-array":49,"is-buffer":50}],56:[function(require,module,exports){
/*!
* pad-left <https://github.com/jonschlinkert/pad-left>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
var repeat = require('repeat-string');
module.exports = function padLeft(str, num, ch) {
ch = typeof ch !== 'undefined' ? (ch + '') : ' ';
return repeat(ch, num) + str;
};
},{"repeat-string":59}],57:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
function drainQueue() {
if (draining) {
return;
}
draining = true;
var currentQueue;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
var i = -1;
while (++i < len) {
currentQueue[i]();
}
len = queue.length;
}
draining = false;
}
process.nextTick = function (fun) {
queue.push(fun);
if (!draining) {
setTimeout(drainQueue, 0);
}
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],58:[function(require,module,exports){
/**
* Expose `requestAnimationFrame()`.
*/
exports = module.exports = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| fallback;
/**
* Fallback implementation.
*/
var prev = new Date().getTime();
function fallback(fn) {
var curr = new Date().getTime();
var ms = Math.max(0, 16 - (curr - prev));
var req = setTimeout(fn, ms);
prev = curr;
return req;
}
/**
* Cancel.
*/
var cancel = window.cancelAnimationFrame
|| window.webkitCancelAnimationFrame
|| window.mozCancelAnimationFrame
|| window.oCancelAnimationFrame
|| window.msCancelAnimationFrame
|| window.clearTimeout;
exports.cancel = function(id){
cancel.call(window, id);
};
},{}],59:[function(require,module,exports){
/*!
* repeat-string <https://github.com/jonschlinkert/repeat-string>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
/**
* Results cache
*/
var res = '';
var cache;
/**
* Expose `repeat`
*/
module.exports = repeat;
/**
* Repeat the given `string` the specified `number`
* of times.
*
* **Example:**
*
* ```js
* var repeat = require('repeat-string');
* repeat('A', 5);
* //=> AAAAA
* ```
*
* @param {String} `string` The string to repeat
* @param {Number} `number` The number of times to repeat the string
* @return {String} Repeated string
* @api public
*/
function repeat(str, num) {
if (typeof str !== 'string') {
throw new TypeError('expected a string');
}
// cover common, quick use cases
if (num === 1) return str;
if (num === 2) return str + str;
var max = str.length * num;
if (cache !== str || typeof cache === 'undefined') {
cache = str;
res = '';
} else if (res.length >= max) {
return res.substr(0, max);
}
while (max > res.length && num > 1) {
if (num & 1) {
res += str;
}
num >>= 1;
str += str;
}
res += str;
res = res.substr(0, max);
return res;
}
},{}],60:[function(require,module,exports){
/* global window, exports, define */
!function() {
'use strict'
var re = {
not_string: /[^s]/,
not_bool: /[^t]/,
not_type: /[^T]/,
not_primitive: /[^v]/,
number: /[diefg]/,
numeric_arg: /[bcdiefguxX]/,
json: /[j]/,
not_json: /[^j]/,
text: /^[^\x25]+/,
modulo: /^\x25{2}/,
placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
key: /^([a-z_][a-z_\d]*)/i,
key_access: /^\.([a-z_][a-z_\d]*)/i,
index_access: /^\[(\d+)\]/,
sign: /^[+-]/
}
function sprintf(key) {
// `arguments` is not an array, but should be fine for this call
return sprintf_format(sprintf_parse(key), arguments)
}
function vsprintf(fmt, argv) {
return sprintf.apply(null, [fmt].concat(argv || []))
}
function sprintf_format(parse_tree, argv) {
var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
for (i = 0; i < tree_length; i++) {
if (typeof parse_tree[i] === 'string') {
output += parse_tree[i]
}
else if (typeof parse_tree[i] === 'object') {
ph = parse_tree[i] // convenience purposes only
if (ph.keys) { // keyword argument
arg = argv[cursor]
for (k = 0; k < ph.keys.length; k++) {
if (arg == undefined) {
throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
}
arg = arg[ph.keys[k]]
}
}
else if (ph.param_no) { // positional argument (explicit)
arg = argv[ph.param_no]
}
else { // positional argument (implicit)
arg = argv[cursor++]
}
if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
arg = arg()
}
if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
}
if (re.number.test(ph.type)) {
is_positive = arg >= 0
}
switch (ph.type) {
case 'b':
arg = parseInt(arg, 10).toString(2)
break
case 'c':
arg = String.fromCharCode(parseInt(arg, 10))
break
case 'd':
case 'i':
arg = parseInt(arg, 10)
break
case 'j':
arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
break
case 'e':
arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
break
case 'f':
arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
break
case 'g':
arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
break
case 'o':
arg = (parseInt(arg, 10) >>> 0).toString(8)
break
case 's':
arg = String(arg)
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 't':
arg = String(!!arg)
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 'T':
arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 'u':
arg = parseInt(arg, 10) >>> 0
break
case 'v':
arg = arg.valueOf()
arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
break
case 'x':
arg = (parseInt(arg, 10) >>> 0).toString(16)
break
case 'X':
arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
break
}
if (re.json.test(ph.type)) {
output += arg
}
else {
if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
sign = is_positive ? '+' : '-'
arg = arg.toString().replace(re.sign, '')
}
else {
sign = ''
}
pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
pad_length = ph.width - (sign + arg).length
pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
}
}
}
return output
}
var sprintf_cache = Object.create(null)
function sprintf_parse(fmt) {
if (sprintf_cache[fmt]) {
return sprintf_cache[fmt]
}
var _fmt = fmt, match, parse_tree = [], arg_names = 0
while (_fmt) {
if ((match = re.text.exec(_fmt)) !== null) {
parse_tree.push(match[0])
}
else if ((match = re.modulo.exec(_fmt)) !== null) {
parse_tree.push('%')
}
else if ((match = re.placeholder.exec(_fmt)) !== null) {
if (match[2]) {
arg_names |= 1
var field_list = [], replacement_field = match[2], field_match = []
if ((field_match = re.key.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
if ((field_match = re.key_access.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
}
else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
field_list.push(field_match[1])
}
else {
throw new SyntaxError('[sprintf] failed to parse named argument key')
}
}
}
else {
throw new SyntaxError('[sprintf] failed to parse named argument key')
}
match[2] = field_list
}
else {
arg_names |= 2
}
if (arg_names === 3) {
throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
}
parse_tree.push(
{
placeholder: match[0],
param_no: match[1],
keys: match[2],
sign: match[3],
pad_char: match[4],
align: match[5],
width: match[6],
precision: match[7],
type: match[8]
}
)
}
else {
throw new SyntaxError('[sprintf] unexpected placeholder')
}
_fmt = _fmt.substring(match[0].length)
}
return sprintf_cache[fmt] = parse_tree
}
/**
* export to either browser or node.js
*/
/* eslint-disable quote-props */
if (typeof exports !== 'undefined') {
exports['sprintf'] = sprintf
exports['vsprintf'] = vsprintf
}
if (typeof window !== 'undefined') {
window['sprintf'] = sprintf
window['vsprintf'] = vsprintf
if (typeof define === 'function' && define['amd']) {
define(function() {
return {
'sprintf': sprintf,
'vsprintf': vsprintf
}
})
}
}
/* eslint-enable quote-props */
}(); // eslint-disable-line
},{}],61:[function(require,module,exports){
(function (global){
"use strict"
var bits = require("bit-twiddle")
var dup = require("dup")
if(!global.__TYPEDARRAY_POOL) {
global.__TYPEDARRAY_POOL = {
UINT8 : dup([32, 0])
, UINT16 : dup([32, 0])
, UINT32 : dup([32, 0])
, INT8 : dup([32, 0])
, INT16 : dup([32, 0])
, INT32 : dup([32, 0])
, FLOAT : dup([32, 0])
, DOUBLE : dup([32, 0])
, DATA : dup([32, 0])
}
}
var POOL = global.__TYPEDARRAY_POOL
var UINT8 = POOL.UINT8
, UINT16 = POOL.UINT16
, UINT32 = POOL.UINT32
, INT8 = POOL.INT8
, INT16 = POOL.INT16
, INT32 = POOL.INT32
, FLOAT = POOL.FLOAT
, DOUBLE = POOL.DOUBLE
, DATA = POOL.DATA
exports.free = function free(array) {
if(array instanceof ArrayBuffer) {
var n = array.byteLength|0
, log_n = bits.log2(n)
DATA[log_n].push(array)
} else {
var n = array.length|0
, log_n = bits.log2(n)
if(array instanceof Uint8Array) {
UINT8[log_n].push(array)
} else if(array instanceof Uint16Array) {
UINT16[log_n].push(array)
} else if(array instanceof Uint32Array) {
UINT32[log_n].push(array)
} else if(array instanceof Int8Array) {
INT8[log_n].push(array)
} else if(array instanceof Int16Array) {
INT16[log_n].push(array)
} else if(array instanceof Int32Array) {
INT32[log_n].push(array)
} else if(array instanceof Float32Array) {
FLOAT[log_n].push(array)
} else if(array instanceof Float64Array) {
DOUBLE[log_n].push(array)
}
}
}
exports.freeUint8 = function freeUint8(array) {
UINT8[bits.log2(array.length)].push(array)
}
exports.freeUint16 = function freeUint16(array) {
UINT16[bits.log2(array.length)].push(array)
}
exports.freeUint32 = function freeUint32(array) {
UINT32[bits.log2(array.length)].push(array)
}
exports.freeInt8 = function freeInt8(array) {
INT8[bits.log2(array.length)].push(array)
}
exports.freeInt16 = function freeInt16(array) {
INT16[bits.log2(array.length)].push(array)
}
exports.freeInt32 = function freeInt32(array) {
INT32[bits.log2(array.length)].push(array)
}
exports.freeFloat32 = exports.freeFloat = function freeFloat(array) {
FLOAT[bits.log2(array.length)].push(array)
}
exports.freeFloat64 = exports.freeDouble = function freeDouble(array) {
DOUBLE[bits.log2(array.length)].push(array)
}
exports.freeArrayBuffer = function freeArrayBuffer(array) {
DATA[bits.log2(array.length)].push(array)
}
exports.malloc = function malloc(n, dtype) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
if(dtype === undefined) {
var d = DATA[log_n]
if(d.length > 0) {
var r = d[d.length-1]
d.pop()
return r
}
return new ArrayBuffer(n)
} else {
switch(dtype) {
case "uint8":
var u8 = UINT8[log_n]
if(u8.length > 0) {
return u8.pop()
}
return new Uint8Array(n)
break
case "uint16":
var u16 = UINT16[log_n]
if(u16.length > 0) {
return u16.pop()
}
return new Uint16Array(n)
break
case "uint32":
var u32 = UINT32[log_n]
if(u32.length > 0) {
return u32.pop()
}
return new Uint32Array(n)
break
case "int8":
var i8 = INT8[log_n]
if(i8.length > 0) {
return i8.pop()
}
return new Int8Array(n)
break
case "int16":
var i16 = INT16[log_n]
if(i16.length > 0) {
return i16.pop()
}
return new Int16Array(n)
break
case "int32":
var i32 = INT32[log_n]
if(i32.length > 0) {
return i32.pop()
}
return new Int32Array(n)
break
case "float":
case "float32":
var f = FLOAT[log_n]
if(f.length > 0) {
return f.pop()
}
return new Float32Array(n)
break
case "double":
case "float64":
var dd = DOUBLE[log_n]
if(dd.length > 0) {
return dd.pop()
}
return new Float64Array(n)
break
default:
return null
}
}
return null
}
exports.mallocUint8 = function mallocUint8(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = UINT8[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Uint8Array(n)
}
exports.mallocUint16 = function mallocUint16(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = UINT16[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Uint16Array(n)
}
exports.mallocUint32 = function mallocUint32(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = UINT32[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Uint32Array(n)
}
exports.mallocInt8 = function mallocInt8(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = INT8[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Int8Array(n)
}
exports.mallocInt16 = function mallocInt16(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = INT16[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Int16Array(n)
}
exports.mallocInt32 = function mallocInt32(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = INT32[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Int32Array(n)
}
exports.mallocFloat32 = exports.mallocFloat = function mallocFloat(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = FLOAT[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Float32Array(n)
}
exports.mallocFloat64 = exports.mallocDouble = function mallocDouble(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = DOUBLE[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new Float64Array(n)
}
exports.mallocArrayBuffer = function mallocArrayBuffer(n) {
n = bits.nextPow2(n)
var log_n = bits.log2(n)
var cache = DATA[log_n]
if(cache.length > 0) {
return cache.pop()
}
return new ArrayBuffer(n)
}
exports.clearCache = function clearCache() {
for(var i=0; i<32; ++i) {
UINT8[i].length = 0
UINT16[i].length = 0
UINT32[i].length = 0
INT8[i].length = 0
INT16[i].length = 0
INT32[i].length = 0
FLOAT[i].length = 0
DOUBLE[i].length = 0
DATA[i].length = 0
}
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"bit-twiddle":7,"dup":11}],62:[function(require,module,exports){
"use strict"
function unique_pred(list, compare) {
var ptr = 1
, len = list.length
, a=list[0], b=list[0]
for(var i=1; i<len; ++i) {
b = a
a = list[i]
if(compare(a, b)) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique_eq(list) {
var ptr = 1
, len = list.length
, a=list[0], b = list[0]
for(var i=1; i<len; ++i, b=a) {
b = a
a = list[i]
if(a !== b) {
if(i === ptr) {
ptr++
continue
}
list[ptr++] = a
}
}
list.length = ptr
return list
}
function unique(list, compare, sorted) {
if(list.length === 0) {
return list
}
if(compare) {
if(!sorted) {
list.sort(compare)
}
return unique_pred(list, compare)
}
if(!sorted) {
list.sort()
}
return unique_eq(list)
}
module.exports = unique
},{}],63:[function(require,module,exports){
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
},{}],64:[function(require,module,exports){
module.exports = function isBuffer(arg) {
return arg && typeof arg === 'object'
&& typeof arg.copy === 'function'
&& typeof arg.fill === 'function'
&& typeof arg.readUInt8 === 'function';
}
},{}],65:[function(require,module,exports){
(function (process,global){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (!isString(f)) {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(inspect(arguments[i]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j':
try {
return JSON.stringify(args[i++]);
} catch (_) {
return '[Circular]';
}
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (isNull(x) || !isObject(x)) {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
// Allow for deprecating things in the process of starting up.
if (isUndefined(global.process)) {
return function() {
return exports.deprecate(fn, msg).apply(this, arguments);
};
}
if (process.noDeprecation === true) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (process.throwDeprecation) {
throw new Error(msg);
} else if (process.traceDeprecation) {
console.trace(msg);
} else {
console.error(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
};
var debugs = {};
var debugEnviron;
exports.debuglog = function(set) {
if (isUndefined(debugEnviron))
debugEnviron = process.env.NODE_DEBUG || '';
set = set.toUpperCase();
if (!debugs[set]) {
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
var pid = process.pid;
debugs[set] = function() {
var msg = exports.format.apply(exports, arguments);
console.error('%s %d: %s', set, pid, msg);
};
} else {
debugs[set] = function() {};
}
}
return debugs[set];
};
/**
* Echos the value of a value. Trys to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
* @param {Object} opts Optional options object that alters the output.
*/
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
}
function stylizeNoColor(str, styleType) {
return str;
}
function arrayToHash(array) {
var hash = {};
array.forEach(function(val, idx) {
hash[val] = true;
});
return hash;
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect &&
value &&
isFunction(value.inspect) &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
// IE doesn't make error fields non-enumerable
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
if (isError(value)
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
return formatError(value);
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
}
var base = '', array = false, braces = ['{', '}'];
// Make Array say that they are Array
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(value);
}
if (keys.length === 0 && (!array || value.length == 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function formatPrimitive(ctx, value) {
if (isUndefined(value))
return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value))
return ctx.stylize('' + value, 'number');
if (isBoolean(value))
return ctx.stylize('' + value, 'boolean');
// For some reason typeof null is "object", so special case here.
if (isNull(value))
return ctx.stylize('null', 'null');
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function(key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar);
}
exports.isArray = isArray;
function isBoolean(arg) {
return typeof arg === 'boolean';
}
exports.isBoolean = isBoolean;
function isNull(arg) {
return arg === null;
}
exports.isNull = isNull;
function isNullOrUndefined(arg) {
return arg == null;
}
exports.isNullOrUndefined = isNullOrUndefined;
function isNumber(arg) {
return typeof arg === 'number';
}
exports.isNumber = isNumber;
function isString(arg) {
return typeof arg === 'string';
}
exports.isString = isString;
function isSymbol(arg) {
return typeof arg === 'symbol';
}
exports.isSymbol = isSymbol;
function isUndefined(arg) {
return arg === void 0;
}
exports.isUndefined = isUndefined;
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
exports.isObject = isObject;
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
exports.isError = isError;
function isFunction(arg) {
return typeof arg === 'function';
}
exports.isFunction = isFunction;
function isPrimitive(arg) {
return arg === null ||
typeof arg === 'boolean' ||
typeof arg === 'number' ||
typeof arg === 'string' ||
typeof arg === 'symbol' || // ES6 symbol
typeof arg === 'undefined';
}
exports.isPrimitive = isPrimitive;
exports.isBuffer = require('./support/isBuffer');
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
// 26 Feb 16:19:34
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}
// log is just a thin wrapper to console.log that prepends a timestamp
exports.log = function() {
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
};
/**
* Inherit the prototype methods from one constructor into another.
*
* The Function.prototype.inherits from lang.js rewritten as a standalone
* function (not on Function.prototype). NOTE: If this file is to be loaded
* during bootstrapping this function needs to be rewritten using some native
* functions as prototype setup using normal JavaScript does not work as
* expected during bootstrapping (see mirror.js in r114903).
*
* @param {function} ctor Constructor function which needs to inherit the
* prototype.
* @param {function} superCtor Constructor function to inherit prototype from.
*/
exports.inherits = require('inherits');
exports._extend = function(origin, add) {
// Don't do anything if add isn't an object
if (!add || !isObject(add)) return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./support/isBuffer":64,"_process":57,"inherits":63}],66:[function(require,module,exports){
var ua = typeof window !== 'undefined' ? window.navigator.userAgent : ''
, isOSX = /OS X/.test(ua)
, isOpera = /Opera/.test(ua)
, maybeFirefox = !/like Gecko/.test(ua) && !isOpera
var i, output = module.exports = {
0: isOSX ? '<menu>' : '<UNK>'
, 1: '<mouse 1>'
, 2: '<mouse 2>'
, 3: '<break>'
, 4: '<mouse 3>'
, 5: '<mouse 4>'
, 6: '<mouse 5>'
, 8: '<backspace>'
, 9: '<tab>'
, 12: '<clear>'
, 13: '<enter>'
, 16: '<shift>'
, 17: '<control>'
, 18: '<alt>'
, 19: '<pause>'
, 20: '<caps-lock>'
, 21: '<ime-hangul>'
, 23: '<ime-junja>'
, 24: '<ime-final>'
, 25: '<ime-kanji>'
, 27: '<escape>'
, 28: '<ime-convert>'
, 29: '<ime-nonconvert>'
, 30: '<ime-accept>'
, 31: '<ime-mode-change>'
, 27: '<escape>'
, 32: '<space>'
, 33: '<page-up>'
, 34: '<page-down>'
, 35: '<end>'
, 36: '<home>'
, 37: '<left>'
, 38: '<up>'
, 39: '<right>'
, 40: '<down>'
, 41: '<select>'
, 42: '<print>'
, 43: '<execute>'
, 44: '<snapshot>'
, 45: '<insert>'
, 46: '<delete>'
, 47: '<help>'
, 91: '<meta>' // meta-left -- no one handles left and right properly, so we coerce into one.
, 92: '<meta>' // meta-right
, 93: isOSX ? '<meta>' : '<menu>' // chrome,opera,safari all report this for meta-right (osx mbp).
, 95: '<sleep>'
, 106: '<num-*>'
, 107: '<num-+>'
, 108: '<num-enter>'
, 109: '<num-->'
, 110: '<num-.>'
, 111: '<num-/>'
, 144: '<num-lock>'
, 145: '<scroll-lock>'
, 160: '<shift-left>'
, 161: '<shift-right>'
, 162: '<control-left>'
, 163: '<control-right>'
, 164: '<alt-left>'
, 165: '<alt-right>'
, 166: '<browser-back>'
, 167: '<browser-forward>'
, 168: '<browser-refresh>'
, 169: '<browser-stop>'
, 170: '<browser-search>'
, 171: '<browser-favorites>'
, 172: '<browser-home>'
// ff/osx reports '<volume-mute>' for '-'
, 173: isOSX && maybeFirefox ? '-' : '<volume-mute>'
, 174: '<volume-down>'
, 175: '<volume-up>'
, 176: '<next-track>'
, 177: '<prev-track>'
, 178: '<stop>'
, 179: '<play-pause>'
, 180: '<launch-mail>'
, 181: '<launch-media-select>'
, 182: '<launch-app 1>'
, 183: '<launch-app 2>'
, 186: ';'
, 187: '='
, 188: ','
, 189: '-'
, 190: '.'
, 191: '/'
, 192: '`'
, 219: '['
, 220: '\\'
, 221: ']'
, 222: "'"
, 223: '<meta>'
, 224: '<meta>' // firefox reports meta here.
, 226: '<alt-gr>'
, 229: '<ime-process>'
, 231: isOpera ? '`' : '<unicode>'
, 246: '<attention>'
, 247: '<crsel>'
, 248: '<exsel>'
, 249: '<erase-eof>'
, 250: '<play>'
, 251: '<zoom>'
, 252: '<no-name>'
, 253: '<pa-1>'
, 254: '<clear>'
}
for(i = 58; i < 65; ++i) {
output[i] = String.fromCharCode(i)
}
// 0-9
for(i = 48; i < 58; ++i) {
output[i] = (i - 48)+''
}
// A-Z
for(i = 65; i < 91; ++i) {
output[i] = String.fromCharCode(i)
}
// num0-9
for(i = 96; i < 106; ++i) {
output[i] = '<num-'+(i - 96)+'>'
}
// F1-F24
for(i = 112; i < 136; ++i) {
output[i] = 'F'+(i-111)
}
},{}],67:[function(require,module,exports){
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Install a leaky WeakMap emulation on platforms that
* don't provide a built-in one.
*
* <p>Assumes that an ES5 platform where, if {@code WeakMap} is
* already present, then it conforms to the anticipated ES6
* specification. To run this file on an ES5 or almost ES5
* implementation where the {@code WeakMap} specification does not
* quite conform, run <code>repairES5.js</code> first.
*
* <p>Even though WeakMapModule is not global, the linter thinks it
* is, which is why it is in the overrides list below.
*
* <p>NOTE: Before using this WeakMap emulation in a non-SES
* environment, see the note below about hiddenRecord.
*
* @author Mark S. Miller
* @requires crypto, ArrayBuffer, Uint8Array, navigator, console
* @overrides WeakMap, ses, Proxy
* @overrides WeakMapModule
*/
/**
* This {@code WeakMap} emulation is observably equivalent to the
* ES-Harmony WeakMap, but with leakier garbage collection properties.
*
* <p>As with true WeakMaps, in this emulation, a key does not
* retain maps indexed by that key and (crucially) a map does not
* retain the keys it indexes. A map by itself also does not retain
* the values associated with that map.
*
* <p>However, the values associated with a key in some map are
* retained so long as that key is retained and those associations are
* not overridden. For example, when used to support membranes, all
* values exported from a given membrane will live for the lifetime
* they would have had in the absence of an interposed membrane. Even
* when the membrane is revoked, all objects that would have been
* reachable in the absence of revocation will still be reachable, as
* far as the GC can tell, even though they will no longer be relevant
* to ongoing computation.
*
* <p>The API implemented here is approximately the API as implemented
* in FF6.0a1 and agreed to by MarkM, Andreas Gal, and Dave Herman,
* rather than the offially approved proposal page. TODO(erights):
* upgrade the ecmascript WeakMap proposal page to explain this API
* change and present to EcmaScript committee for their approval.
*
* <p>The first difference between the emulation here and that in
* FF6.0a1 is the presence of non enumerable {@code get___, has___,
* set___, and delete___} methods on WeakMap instances to represent
* what would be the hidden internal properties of a primitive
* implementation. Whereas the FF6.0a1 WeakMap.prototype methods
* require their {@code this} to be a genuine WeakMap instance (i.e.,
* an object of {@code [[Class]]} "WeakMap}), since there is nothing
* unforgeable about the pseudo-internal method names used here,
* nothing prevents these emulated prototype methods from being
* applied to non-WeakMaps with pseudo-internal methods of the same
* names.
*
* <p>Another difference is that our emulated {@code
* WeakMap.prototype} is not itself a WeakMap. A problem with the
* current FF6.0a1 API is that WeakMap.prototype is itself a WeakMap
* providing ambient mutability and an ambient communications
* channel. Thus, if a WeakMap is already present and has this
* problem, repairES5.js wraps it in a safe wrappper in order to
* prevent access to this channel. (See
* PATCH_MUTABLE_FROZEN_WEAKMAP_PROTO in repairES5.js).
*/
/**
* If this is a full <a href=
* "http://code.google.com/p/es-lab/wiki/SecureableES5"
* >secureable ES5</a> platform and the ES-Harmony {@code WeakMap} is
* absent, install an approximate emulation.
*
* <p>If WeakMap is present but cannot store some objects, use our approximate
* emulation as a wrapper.
*
* <p>If this is almost a secureable ES5 platform, then WeakMap.js
* should be run after repairES5.js.
*
* <p>See {@code WeakMap} for documentation of the garbage collection
* properties of this WeakMap emulation.
*/
(function WeakMapModule() {
"use strict";
if (typeof ses !== 'undefined' && ses.ok && !ses.ok()) {
// already too broken, so give up
return;
}
/**
* In some cases (current Firefox), we must make a choice betweeen a
* WeakMap which is capable of using all varieties of host objects as
* keys and one which is capable of safely using proxies as keys. See
* comments below about HostWeakMap and DoubleWeakMap for details.
*
* This function (which is a global, not exposed to guests) marks a
* WeakMap as permitted to do what is necessary to index all host
* objects, at the cost of making it unsafe for proxies.
*
* Do not apply this function to anything which is not a genuine
* fresh WeakMap.
*/
function weakMapPermitHostObjects(map) {
// identity of function used as a secret -- good enough and cheap
if (map.permitHostObjects___) {
map.permitHostObjects___(weakMapPermitHostObjects);
}
}
if (typeof ses !== 'undefined') {
ses.weakMapPermitHostObjects = weakMapPermitHostObjects;
}
// IE 11 has no Proxy but has a broken WeakMap such that we need to patch
// it using DoubleWeakMap; this flag tells DoubleWeakMap so.
var doubleWeakMapCheckSilentFailure = false;
// Check if there is already a good-enough WeakMap implementation, and if so
// exit without replacing it.
if (typeof WeakMap === 'function') {
var HostWeakMap = WeakMap;
// There is a WeakMap -- is it good enough?
if (typeof navigator !== 'undefined' &&
/Firefox/.test(navigator.userAgent)) {
// We're now *assuming not*, because as of this writing (2013-05-06)
// Firefox's WeakMaps have a miscellany of objects they won't accept, and
// we don't want to make an exhaustive list, and testing for just one
// will be a problem if that one is fixed alone (as they did for Event).
// If there is a platform that we *can* reliably test on, here's how to
// do it:
// var problematic = ... ;
// var testHostMap = new HostWeakMap();
// try {
// testHostMap.set(problematic, 1); // Firefox 20 will throw here
// if (testHostMap.get(problematic) === 1) {
// return;
// }
// } catch (e) {}
} else {
// IE 11 bug: WeakMaps silently fail to store frozen objects.
var testMap = new HostWeakMap();
var testObject = Object.freeze({});
testMap.set(testObject, 1);
if (testMap.get(testObject) !== 1) {
doubleWeakMapCheckSilentFailure = true;
// Fall through to installing our WeakMap.
} else {
module.exports = WeakMap;
return;
}
}
}
var hop = Object.prototype.hasOwnProperty;
var gopn = Object.getOwnPropertyNames;
var defProp = Object.defineProperty;
var isExtensible = Object.isExtensible;
/**
* Security depends on HIDDEN_NAME being both <i>unguessable</i> and
* <i>undiscoverable</i> by untrusted code.
*
* <p>Given the known weaknesses of Math.random() on existing
* browsers, it does not generate unguessability we can be confident
* of.
*
* <p>It is the monkey patching logic in this file that is intended
* to ensure undiscoverability. The basic idea is that there are
* three fundamental means of discovering properties of an object:
* The for/in loop, Object.keys(), and Object.getOwnPropertyNames(),
* as well as some proposed ES6 extensions that appear on our
* whitelist. The first two only discover enumerable properties, and
* we only use HIDDEN_NAME to name a non-enumerable property, so the
* only remaining threat should be getOwnPropertyNames and some
* proposed ES6 extensions that appear on our whitelist. We monkey
* patch them to remove HIDDEN_NAME from the list of properties they
* returns.
*
* <p>TODO(erights): On a platform with built-in Proxies, proxies
* could be used to trap and thereby discover the HIDDEN_NAME, so we
* need to monkey patch Proxy.create, Proxy.createFunction, etc, in
* order to wrap the provided handler with the real handler which
* filters out all traps using HIDDEN_NAME.
*
* <p>TODO(erights): Revisit Mike Stay's suggestion that we use an
* encapsulated function at a not-necessarily-secret name, which
* uses the Stiegler shared-state rights amplification pattern to
* reveal the associated value only to the WeakMap in which this key
* is associated with that value. Since only the key retains the
* function, the function can also remember the key without causing
* leakage of the key, so this doesn't violate our general gc
* goals. In addition, because the name need not be a guarded
* secret, we could efficiently handle cross-frame frozen keys.
*/
var HIDDEN_NAME_PREFIX = 'weakmap:';
var HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'ident:' + Math.random() + '___';
if (typeof crypto !== 'undefined' &&
typeof crypto.getRandomValues === 'function' &&
typeof ArrayBuffer === 'function' &&
typeof Uint8Array === 'function') {
var ab = new ArrayBuffer(25);
var u8s = new Uint8Array(ab);
crypto.getRandomValues(u8s);
HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'rand:' +
Array.prototype.map.call(u8s, function(u8) {
return (u8 % 36).toString(36);
}).join('') + '___';
}
function isNotHiddenName(name) {
return !(
name.substr(0, HIDDEN_NAME_PREFIX.length) == HIDDEN_NAME_PREFIX &&
name.substr(name.length - 3) === '___');
}
/**
* Monkey patch getOwnPropertyNames to avoid revealing the
* HIDDEN_NAME.
*
* <p>The ES5.1 spec requires each name to appear only once, but as
* of this writing, this requirement is controversial for ES6, so we
* made this code robust against this case. If the resulting extra
* search turns out to be expensive, we can probably relax this once
* ES6 is adequately supported on all major browsers, iff no browser
* versions we support at that time have relaxed this constraint
* without providing built-in ES6 WeakMaps.
*/
defProp(Object, 'getOwnPropertyNames', {
value: function fakeGetOwnPropertyNames(obj) {
return gopn(obj).filter(isNotHiddenName);
}
});
/**
* getPropertyNames is not in ES5 but it is proposed for ES6 and
* does appear in our whitelist, so we need to clean it too.
*/
if ('getPropertyNames' in Object) {
var originalGetPropertyNames = Object.getPropertyNames;
defProp(Object, 'getPropertyNames', {
value: function fakeGetPropertyNames(obj) {
return originalGetPropertyNames(obj).filter(isNotHiddenName);
}
});
}
/**
* <p>To treat objects as identity-keys with reasonable efficiency
* on ES5 by itself (i.e., without any object-keyed collections), we
* need to add a hidden property to such key objects when we
* can. This raises several issues:
* <ul>
* <li>Arranging to add this property to objects before we lose the
* chance, and
* <li>Hiding the existence of this new property from most
* JavaScript code.
* <li>Preventing <i>certification theft</i>, where one object is
* created falsely claiming to be the key of an association
* actually keyed by another object.
* <li>Preventing <i>value theft</i>, where untrusted code with
* access to a key object but not a weak map nevertheless
* obtains access to the value associated with that key in that
* weak map.
* </ul>
* We do so by
* <ul>
* <li>Making the name of the hidden property unguessable, so "[]"
* indexing, which we cannot intercept, cannot be used to access
* a property without knowing the name.
* <li>Making the hidden property non-enumerable, so we need not
* worry about for-in loops or {@code Object.keys},
* <li>monkey patching those reflective methods that would
* prevent extensions, to add this hidden property first,
* <li>monkey patching those methods that would reveal this
* hidden property.
* </ul>
* Unfortunately, because of same-origin iframes, we cannot reliably
* add this hidden property before an object becomes
* non-extensible. Instead, if we encounter a non-extensible object
* without a hidden record that we can detect (whether or not it has
* a hidden record stored under a name secret to us), then we just
* use the key object itself to represent its identity in a brute
* force leaky map stored in the weak map, losing all the advantages
* of weakness for these.
*/
function getHiddenRecord(key) {
if (key !== Object(key)) {
throw new TypeError('Not an object: ' + key);
}
var hiddenRecord = key[HIDDEN_NAME];
if (hiddenRecord && hiddenRecord.key === key) { return hiddenRecord; }
if (!isExtensible(key)) {
// Weak map must brute force, as explained in doc-comment above.
return void 0;
}
// The hiddenRecord and the key point directly at each other, via
// the "key" and HIDDEN_NAME properties respectively. The key
// field is for quickly verifying that this hidden record is an
// own property, not a hidden record from up the prototype chain.
//
// NOTE: Because this WeakMap emulation is meant only for systems like
// SES where Object.prototype is frozen without any numeric
// properties, it is ok to use an object literal for the hiddenRecord.
// This has two advantages:
// * It is much faster in a performance critical place
// * It avoids relying on Object.create(null), which had been
// problematic on Chrome 28.0.1480.0. See
// https://code.google.com/p/google-caja/issues/detail?id=1687
hiddenRecord = { key: key };
// When using this WeakMap emulation on platforms where
// Object.prototype might not be frozen and Object.create(null) is
// reliable, use the following two commented out lines instead.
// hiddenRecord = Object.create(null);
// hiddenRecord.key = key;
// Please contact us if you need this to work on platforms where
// Object.prototype might not be frozen and
// Object.create(null) might not be reliable.
try {
defProp(key, HIDDEN_NAME, {
value: hiddenRecord,
writable: false,
enumerable: false,
configurable: false
});
return hiddenRecord;
} catch (error) {
// Under some circumstances, isExtensible seems to misreport whether
// the HIDDEN_NAME can be defined.
// The circumstances have not been isolated, but at least affect
// Node.js v0.10.26 on TravisCI / Linux, but not the same version of
// Node.js on OS X.
return void 0;
}
}
/**
* Monkey patch operations that would make their argument
* non-extensible.
*
* <p>The monkey patched versions throw a TypeError if their
* argument is not an object, so it should only be done to functions
* that should throw a TypeError anyway if their argument is not an
* object.
*/
(function(){
var oldFreeze = Object.freeze;
defProp(Object, 'freeze', {
value: function identifyingFreeze(obj) {
getHiddenRecord(obj);
return oldFreeze(obj);
}
});
var oldSeal = Object.seal;
defProp(Object, 'seal', {
value: function identifyingSeal(obj) {
getHiddenRecord(obj);
return oldSeal(obj);
}
});
var oldPreventExtensions = Object.preventExtensions;
defProp(Object, 'preventExtensions', {
value: function identifyingPreventExtensions(obj) {
getHiddenRecord(obj);
return oldPreventExtensions(obj);
}
});
})();
function constFunc(func) {
func.prototype = null;
return Object.freeze(func);
}
var calledAsFunctionWarningDone = false;
function calledAsFunctionWarning() {
// Future ES6 WeakMap is currently (2013-09-10) expected to reject WeakMap()
// but we used to permit it and do it ourselves, so warn only.
if (!calledAsFunctionWarningDone && typeof console !== 'undefined') {
calledAsFunctionWarningDone = true;
console.warn('WeakMap should be invoked as new WeakMap(), not ' +
'WeakMap(). This will be an error in the future.');
}
}
var nextId = 0;
var OurWeakMap = function() {
if (!(this instanceof OurWeakMap)) { // approximate test for new ...()
calledAsFunctionWarning();
}
// We are currently (12/25/2012) never encountering any prematurely
// non-extensible keys.
var keys = []; // brute force for prematurely non-extensible keys.
var values = []; // brute force for corresponding values.
var id = nextId++;
function get___(key, opt_default) {
var index;
var hiddenRecord = getHiddenRecord(key);
if (hiddenRecord) {
return id in hiddenRecord ? hiddenRecord[id] : opt_default;
} else {
index = keys.indexOf(key);
return index >= 0 ? values[index] : opt_default;
}
}
function has___(key) {
var hiddenRecord = getHiddenRecord(key);
if (hiddenRecord) {
return id in hiddenRecord;
} else {
return keys.indexOf(key) >= 0;
}
}
function set___(key, value) {
var index;
var hiddenRecord = getHiddenRecord(key);
if (hiddenRecord) {
hiddenRecord[id] = value;
} else {
index = keys.indexOf(key);
if (index >= 0) {
values[index] = value;
} else {
// Since some browsers preemptively terminate slow turns but
// then continue computing with presumably corrupted heap
// state, we here defensively get keys.length first and then
// use it to update both the values and keys arrays, keeping
// them in sync.
index = keys.length;
values[index] = value;
// If we crash here, values will be one longer than keys.
keys[index] = key;
}
}
return this;
}
function delete___(key) {
var hiddenRecord = getHiddenRecord(key);
var index, lastIndex;
if (hiddenRecord) {
return id in hiddenRecord && delete hiddenRecord[id];
} else {
index = keys.indexOf(key);
if (index < 0) {
return false;
}
// Since some browsers preemptively terminate slow turns but
// then continue computing with potentially corrupted heap
// state, we here defensively get keys.length first and then use
// it to update both the keys and the values array, keeping
// them in sync. We update the two with an order of assignments,
// such that any prefix of these assignments will preserve the
// key/value correspondence, either before or after the delete.
// Note that this needs to work correctly when index === lastIndex.
lastIndex = keys.length - 1;
keys[index] = void 0;
// If we crash here, there's a void 0 in the keys array, but
// no operation will cause a "keys.indexOf(void 0)", since
// getHiddenRecord(void 0) will always throw an error first.
values[index] = values[lastIndex];
// If we crash here, values[index] cannot be found here,
// because keys[index] is void 0.
keys[index] = keys[lastIndex];
// If index === lastIndex and we crash here, then keys[index]
// is still void 0, since the aliasing killed the previous key.
keys.length = lastIndex;
// If we crash here, keys will be one shorter than values.
values.length = lastIndex;
return true;
}
}
return Object.create(OurWeakMap.prototype, {
get___: { value: constFunc(get___) },
has___: { value: constFunc(has___) },
set___: { value: constFunc(set___) },
delete___: { value: constFunc(delete___) }
});
};
OurWeakMap.prototype = Object.create(Object.prototype, {
get: {
/**
* Return the value most recently associated with key, or
* opt_default if none.
*/
value: function get(key, opt_default) {
return this.get___(key, opt_default);
},
writable: true,
configurable: true
},
has: {
/**
* Is there a value associated with key in this WeakMap?
*/
value: function has(key) {
return this.has___(key);
},
writable: true,
configurable: true
},
set: {
/**
* Associate value with key in this WeakMap, overwriting any
* previous association if present.
*/
value: function set(key, value) {
return this.set___(key, value);
},
writable: true,
configurable: true
},
'delete': {
/**
* Remove any association for key in this WeakMap, returning
* whether there was one.
*
* <p>Note that the boolean return here does not work like the
* {@code delete} operator. The {@code delete} operator returns
* whether the deletion succeeds at bringing about a state in
* which the deleted property is absent. The {@code delete}
* operator therefore returns true if the property was already
* absent, whereas this {@code delete} method returns false if
* the association was already absent.
*/
value: function remove(key) {
return this.delete___(key);
},
writable: true,
configurable: true
}
});
if (typeof HostWeakMap === 'function') {
(function() {
// If we got here, then the platform has a WeakMap but we are concerned
// that it may refuse to store some key types. Therefore, make a map
// implementation which makes use of both as possible.
// In this mode we are always using double maps, so we are not proxy-safe.
// This combination does not occur in any known browser, but we had best
// be safe.
if (doubleWeakMapCheckSilentFailure && typeof Proxy !== 'undefined') {
Proxy = undefined;
}
function DoubleWeakMap() {
if (!(this instanceof OurWeakMap)) { // approximate test for new ...()
calledAsFunctionWarning();
}
// Preferable, truly weak map.
var hmap = new HostWeakMap();
// Our hidden-property-based pseudo-weak-map. Lazily initialized in the
// 'set' implementation; thus we can avoid performing extra lookups if
// we know all entries actually stored are entered in 'hmap'.
var omap = undefined;
// Hidden-property maps are not compatible with proxies because proxies
// can observe the hidden name and either accidentally expose it or fail
// to allow the hidden property to be set. Therefore, we do not allow
// arbitrary WeakMaps to switch to using hidden properties, but only
// those which need the ability, and unprivileged code is not allowed
// to set the flag.
//
// (Except in doubleWeakMapCheckSilentFailure mode in which case we
// disable proxies.)
var enableSwitching = false;
function dget(key, opt_default) {
if (omap) {
return hmap.has(key) ? hmap.get(key)
: omap.get___(key, opt_default);
} else {
return hmap.get(key, opt_default);
}
}
function dhas(key) {
return hmap.has(key) || (omap ? omap.has___(key) : false);
}
var dset;
if (doubleWeakMapCheckSilentFailure) {
dset = function(key, value) {
hmap.set(key, value);
if (!hmap.has(key)) {
if (!omap) { omap = new OurWeakMap(); }
omap.set(key, value);
}
return this;
};
} else {
dset = function(key, value) {
if (enableSwitching) {
try {
hmap.set(key, value);
} catch (e) {
if (!omap) { omap = new OurWeakMap(); }
omap.set___(key, value);
}
} else {
hmap.set(key, value);
}
return this;
};
}
function ddelete(key) {
var result = !!hmap['delete'](key);
if (omap) { return omap.delete___(key) || result; }
return result;
}
return Object.create(OurWeakMap.prototype, {
get___: { value: constFunc(dget) },
has___: { value: constFunc(dhas) },
set___: { value: constFunc(dset) },
delete___: { value: constFunc(ddelete) },
permitHostObjects___: { value: constFunc(function(token) {
if (token === weakMapPermitHostObjects) {
enableSwitching = true;
} else {
throw new Error('bogus call to permitHostObjects___');
}
})}
});
}
DoubleWeakMap.prototype = OurWeakMap.prototype;
module.exports = DoubleWeakMap;
// define .constructor to hide OurWeakMap ctor
Object.defineProperty(WeakMap.prototype, 'constructor', {
value: WeakMap,
enumerable: false, // as default .constructor is
configurable: true,
writable: true
});
})();
} else {
// There is no host WeakMap, so we must use the emulation.
// Emulated WeakMaps are incompatible with native proxies (because proxies
// can observe the hidden name), so we must disable Proxy usage (in
// ArrayLike and Domado, currently).
if (typeof Proxy !== 'undefined') {
Proxy = undefined;
}
module.exports = OurWeakMap;
}
})();
},{}],68:[function(require,module,exports){
var hiddenStore = require('./hidden-store.js');
module.exports = createStore;
function createStore() {
var key = {};
return function (obj) {
if ((typeof obj !== 'object' || obj === null) &&
typeof obj !== 'function'
) {
throw new Error('Weakmap-shim: Key must be object')
}
var store = obj.valueOf(key);
return store && store.identity === key ?
store : hiddenStore(obj, key);
};
}
},{"./hidden-store.js":69}],69:[function(require,module,exports){
module.exports = hiddenStore;
function hiddenStore(obj, key) {
var store = { identity: key };
var valueOf = obj.valueOf;
Object.defineProperty(obj, "valueOf", {
value: function (value) {
return value !== key ?
valueOf.apply(this, arguments) : store;
},
writable: true
});
return store;
}
},{}],70:[function(require,module,exports){
// Original - @Gozola.
// https://gist.github.com/Gozala/1269991
// This is a reimplemented version (with a few bug fixes).
var createStore = require('./create-store.js');
module.exports = weakMap;
function weakMap() {
var privates = createStore();
return {
'get': function (key, fallback) {
var store = privates(key)
return store.hasOwnProperty('value') ?
store.value : fallback
},
'set': function (key, value) {
privates(key).value = value;
return this;
},
'has': function(key) {
return 'value' in privates(key);
},
'delete': function (key) {
return delete privates(key).value;
}
}
}
},{"./create-store.js":68}],71:[function(require,module,exports){
'use strict'
var weakMap = typeof WeakMap === 'undefined' ? require('weak-map') : WeakMap
var WebGLEWStruct = new weakMap()
function baseName(ext_name) {
return ext_name.replace(/^[A-Z]+_/, '')
}
function initWebGLEW(gl) {
var struct = WebGLEWStruct.get(gl)
if(struct) {
return struct
}
var extensions = {}
var supported = gl.getSupportedExtensions()
for(var i=0; i<supported.length; ++i) {
var extName = supported[i]
//Skip MOZ_ extensions
if(extName.indexOf('MOZ_') === 0) {
continue
}
var ext = gl.getExtension(supported[i])
if(!ext) {
continue
}
while(true) {
extensions[extName] = ext
var base = baseName(extName)
if(base === extName) {
break
}
extName = base
}
}
WebGLEWStruct.set(gl, extensions)
return extensions
}
module.exports = initWebGLEW
},{"weak-map":67}]},{},[1]);