├── .gitignore ├── .npmignore ├── LICENSE.md ├── README.md ├── bundle.js ├── demo.frag ├── demo.js ├── demo.vert ├── index.glsl ├── index.html └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | bundle.js 5 | test 6 | test.js 7 | demo 8 | demo.* 9 | index.html 10 | example 11 | .npmignore 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright (c) 2014 [stackgl](http://github.com/stackgl/) contributors 5 | 6 | *stackgl contributors listed at * 7 | 8 | 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: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 11 | 12 | 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. 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # glsl-camera-ray 2 | 3 | [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 4 | 5 | Generates a ray for [Shadertoy](http://shadertoy.com)-style raycasting in GLSL. 6 | Accepts either either a camera origin/target or an arbitrary `mat3` matrix. 7 | 8 | ## Usage 9 | 10 | [![NPM](https://nodei.co/npm/glsl-camera-ray.png)](https://nodei.co/npm/glsl-camera-ray/) 11 | 12 | ### `vec3 cameraRay(vec3 ro, vec3 ta, vec2 screen, float lens)` 13 | 14 | * `vec3 ro` is the position of the camera. 15 | * `vec3 ta` is the position the camera is pointing towards. 16 | * `vec2 screen` is the position of the fragment on the screen, generally between -1 and 1. For non-square frames you'll want to normalize this using something like [glsl-square-frame](http://github.com/hughsk/glsl-square-frame) 17 | * `lens` is the lens length of the camera. This works 18 | similarly to FOV, where `0.0` is horribly wide and `2.0` 19 | is a decent default. 20 | 21 | ``` glsl 22 | #pragma glslify: square = require('glsl-square-frame') 23 | #pragma glslify: camera = require('glsl-camera-ray') 24 | 25 | uniform vec2 iResolution; 26 | uniform float iGlobalTime; 27 | 28 | void main() { 29 | // Bootstrap a Shadertoy-style raytracing scene: 30 | float cameraAngle = 0.8 * iGlobalTime; 31 | vec3 rayOrigin = vec3(3.5 * sin(cameraAngle), 3.0, 3.5 * cos(cameraAngle)); 32 | vec3 rayTarget = vec3(0, 0, 0); 33 | vec2 screenPos = square(iResolution.xy); 34 | float lensLength = 2.0; 35 | 36 | vec3 rayDirection = camera(rayOrigin, rayTarget, screenPos, lensLength); 37 | // ... 38 | } 39 | ``` 40 | 41 | ### `vec3 cameraRay(mat3 camera, vec2 screen, float lens)` 42 | 43 | For more flexibility, you can supply `mat3 camera` in place 44 | of `vec3 ro, vec3 ta`. This way, you can use your own camera 45 | modules alongside `glsl-camera-ray`. 46 | 47 | ## Contributing 48 | 49 | See [stackgl/contributing](https://github.com/stackgl/contributing) for details. 50 | 51 | ## License 52 | 53 | MIT. See [LICENSE.md](http://github.com/stackgl/glsl-camera-ray/blob/master/LICENSE.md) for details. 54 | -------------------------------------------------------------------------------- /bundle.js: -------------------------------------------------------------------------------- 1 | (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 maxd) break;\n h = doModel(ro+rd*t);\n t += h;\n }\n\n if (t < maxd) res = t;\n return res;\n}\n\nvec3 calcNormal(vec3 pos) {\n const float eps = 0.002;\n\n const vec3 v1 = vec3( 1.0,-1.0,-1.0);\n const vec3 v2 = vec3(-1.0,-1.0, 1.0);\n const vec3 v3 = vec3(-1.0, 1.0,-1.0);\n const vec3 v4 = vec3( 1.0, 1.0, 1.0);\n\n return normalize( v1*doModel( pos + v1*eps ) +\n v2*doModel( pos + v2*eps ) +\n v3*doModel( pos + v3*eps ) +\n v4*doModel( pos + v4*eps ) );\n}\n\nvoid main() {\n float cameraAngle = 0.8 * iGlobalTime;\n vec3 rayOrigin = vec3(3.5 * sin(cameraAngle), 3.0, 3.5 * cos(cameraAngle));\n vec3 rayTarget = vec3(0, 0, 0);\n vec2 screenPos = squareFrame_1_0(iResolution);\n vec3 rayDirection = getRay_3_3(rayOrigin, rayTarget, screenPos, 2.0);\n\n vec3 col = vec3(0.0);\n float t = calcIntersection(rayOrigin, rayDirection);\n\n if (t > -0.5) {\n vec3 pos = rayOrigin + t*rayDirection;\n vec3 nor = calcNormal(pos);\n vec3 mal = doMaterial(pos, nor);\n\n col = doLighting(pos, nor, rayDirection, t, mal);\n }\n\n col = pow(clamp(col,0.0,1.0), vec3(0.4545));\n\n gl_FragColor = vec4( col, 1.0 );\n}\n" 17 | ) 18 | }, function(gl, shader) { 19 | shader.uniforms.iResolution = [gl.drawingBufferWidth, gl.drawingBufferHeight] 20 | shader.uniforms.iGlobalTime = (Date.now() - start) / 1000 21 | }) 22 | 23 | // Extracted for gl-toy, need to do manual 24 | // downsampling here :) 25 | function Toy(shader, cb) { 26 | var gl = context(canvas, render) 27 | shader = shader(gl) 28 | 29 | function render() { 30 | var width = gl.drawingBufferWidth 31 | var height = gl.drawingBufferHeight 32 | gl.viewport(0, 0, width, height) 33 | 34 | shader.bind() 35 | cb(gl, shader) 36 | triangle(gl) 37 | } 38 | } 39 | 40 | },{"a-big-triangle":22,"canvas-fit":27,"gl-context":29,"gl-shader":31}],2:[function(require,module,exports){ 41 | "use strict" 42 | 43 | var pool = require("typedarray-pool") 44 | var ops = require("ndarray-ops") 45 | var ndarray = require("ndarray") 46 | var webglew = require("webglew") 47 | 48 | var SUPPORTED_TYPES = [ 49 | "uint8", 50 | "uint8_clamped", 51 | "uint16", 52 | "uint32", 53 | "int8", 54 | "int16", 55 | "int32", 56 | "float32" ] 57 | 58 | function GLBuffer(gl, type, handle, length, usage) { 59 | this.gl = gl 60 | this.type = type 61 | this.handle = handle 62 | this.length = length 63 | this.usage = usage 64 | } 65 | 66 | var proto = GLBuffer.prototype 67 | 68 | proto.bind = function() { 69 | this.gl.bindBuffer(this.type, this.handle) 70 | } 71 | 72 | proto.unbind = function() { 73 | this.gl.bindBuffer(this.type, null) 74 | } 75 | 76 | proto.dispose = function() { 77 | this.gl.deleteBuffer(this.handle) 78 | } 79 | 80 | function updateTypeArray(gl, type, len, usage, data, offset) { 81 | var dataLen = data.length * data.BYTES_PER_ELEMENT 82 | if(offset < 0) { 83 | gl.bufferData(type, data, usage) 84 | return dataLen 85 | } 86 | if(dataLen + offset > len) { 87 | throw new Error("gl-buffer: If resizing buffer, must not specify offset") 88 | } 89 | gl.bufferSubData(type, offset, data) 90 | return len 91 | } 92 | 93 | function makeScratchTypeArray(array, dtype) { 94 | var res = pool.malloc(array.length, dtype) 95 | var n = array.length 96 | for(var i=0; i=0; --i) { 105 | if(stride[i] !== n) { 106 | return false 107 | } 108 | n *= shape[i] 109 | } 110 | return true 111 | } 112 | 113 | proto.update = function(array, offset) { 114 | if(typeof offset !== "number") { 115 | offset = -1 116 | } 117 | this.bind() 118 | if(typeof array === "object" && typeof array.shape !== "undefined") { //ndarray 119 | var dtype = array.dtype 120 | if(SUPPORTED_TYPES.indexOf(dtype) < 0) { 121 | dtype = "float32" 122 | } 123 | if(this.type === this.gl.ELEMENT_ARRAY_BUFFER) { 124 | var wgl = webglew(this.gl) 125 | var ext = wgl.OES_element_index_uint 126 | if(ext && dtype !== "uint16") { 127 | dtype = "uint32" 128 | } else { 129 | dtype = "uint16" 130 | } 131 | } 132 | if(dtype === array.dtype && isPacked(array.shape, array.stride)) { 133 | if(array.offset === 0 && array.data.length === array.shape[0]) { 134 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array.data, offset) 135 | } else { 136 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array.data.subarray(array.offset, array.shape[0]), offset) 137 | } 138 | } else { 139 | var tmp = pool.malloc(array.size, dtype) 140 | var ndt = ndarray(tmp, array.shape) 141 | ops.assign(ndt, array) 142 | if(offset < 0) { 143 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, tmp, offset) 144 | } else { 145 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, tmp.subarray(0, array.size), offset) 146 | } 147 | pool.free(tmp) 148 | } 149 | } else if(Array.isArray(array)) { //Vanilla array 150 | var t 151 | if(this.type === this.gl.ELEMENT_ARRAY_BUFFER) { 152 | t = makeScratchTypeArray(array, "uint16") 153 | } else { 154 | t = makeScratchTypeArray(array, "float32") 155 | } 156 | if(offset < 0) { 157 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, t, offset) 158 | } else { 159 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, t.subarray(0, array.length), offset) 160 | } 161 | pool.free(t) 162 | } else if(typeof array === "object" && typeof array.length === "number") { //Typed array 163 | this.length = updateTypeArray(this.gl, this.type, this.length, this.usage, array, offset) 164 | } else if(typeof array === "number" || array === undefined) { //Number/default 165 | if(offset >= 0) { 166 | throw new Error("gl-buffer: Cannot specify offset when resizing buffer") 167 | } 168 | array = array | 0 169 | if(array <= 0) { 170 | array = 1 171 | } 172 | this.gl.bufferData(this.type, array|0, this.usage) 173 | this.length = array 174 | } else { //Error, case should not happen 175 | throw new Error("gl-buffer: Invalid data type") 176 | } 177 | } 178 | 179 | function createBuffer(gl, data, type, usage) { 180 | webglew(gl) 181 | type = type || gl.ARRAY_BUFFER 182 | usage = usage || gl.DYNAMIC_DRAW 183 | if(type !== gl.ARRAY_BUFFER && type !== gl.ELEMENT_ARRAY_BUFFER) { 184 | throw new Error("gl-buffer: Invalid type for webgl buffer, must be either gl.ARRAY_BUFFER or gl.ELEMENT_ARRAY_BUFFER") 185 | } 186 | if(usage !== gl.DYNAMIC_DRAW && usage !== gl.STATIC_DRAW && usage !== gl.STREAM_DRAW) { 187 | throw new Error("gl-buffer: Invalid usage for buffer, must be either gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW") 188 | } 189 | var handle = gl.createBuffer() 190 | var result = new GLBuffer(gl, type, handle, 0, usage) 191 | result.update(data) 192 | return result 193 | } 194 | 195 | module.exports = createBuffer 196 | },{"ndarray":8,"ndarray-ops":3,"typedarray-pool":12,"webglew":14}],3:[function(require,module,exports){ 197 | "use strict" 198 | 199 | var compile = require("cwise-compiler") 200 | 201 | var EmptyProc = { 202 | body: "", 203 | args: [], 204 | thisVars: [], 205 | localVars: [] 206 | } 207 | 208 | function fixup(x) { 209 | if(!x) { 210 | return EmptyProc 211 | } 212 | for(var i=0; i>", 261 | rrshift: ">>>" 262 | } 263 | ;(function(){ 264 | for(var id in assign_ops) { 265 | var op = assign_ops[id] 266 | exports[id] = makeOp({ 267 | args: ["array","array","array"], 268 | body: {args:["a","b","c"], 269 | body: "a=b"+op+"c"}, 270 | funcName: id 271 | }) 272 | exports[id+"eq"] = makeOp({ 273 | args: ["array","array"], 274 | body: {args:["a","b"], 275 | body:"a"+op+"=b"}, 276 | rvalue: true, 277 | funcName: id+"eq" 278 | }) 279 | exports[id+"s"] = makeOp({ 280 | args: ["array", "array", "scalar"], 281 | body: {args:["a","b","s"], 282 | body:"a=b"+op+"s"}, 283 | funcName: id+"s" 284 | }) 285 | exports[id+"seq"] = makeOp({ 286 | args: ["array","scalar"], 287 | body: {args:["a","s"], 288 | body:"a"+op+"=s"}, 289 | rvalue: true, 290 | funcName: id+"seq" 291 | }) 292 | } 293 | })(); 294 | 295 | var unary_ops = { 296 | not: "!", 297 | bnot: "~", 298 | neg: "-", 299 | recip: "1.0/" 300 | } 301 | ;(function(){ 302 | for(var id in unary_ops) { 303 | var op = unary_ops[id] 304 | exports[id] = makeOp({ 305 | args: ["array", "array"], 306 | body: {args:["a","b"], 307 | body:"a="+op+"b"}, 308 | funcName: id 309 | }) 310 | exports[id+"eq"] = makeOp({ 311 | args: ["array"], 312 | body: {args:["a"], 313 | body:"a="+op+"a"}, 314 | rvalue: true, 315 | count: 2, 316 | funcName: id+"eq" 317 | }) 318 | } 319 | })(); 320 | 321 | var binary_ops = { 322 | and: "&&", 323 | or: "||", 324 | eq: "===", 325 | neq: "!==", 326 | lt: "<", 327 | gt: ">", 328 | leq: "<=", 329 | geq: ">=" 330 | } 331 | ;(function() { 332 | for(var id in binary_ops) { 333 | var op = binary_ops[id] 334 | exports[id] = makeOp({ 335 | args: ["array","array","array"], 336 | body: {args:["a", "b", "c"], 337 | body:"a=b"+op+"c"}, 338 | funcName: id 339 | }) 340 | exports[id+"s"] = makeOp({ 341 | args: ["array","array","scalar"], 342 | body: {args:["a", "b", "s"], 343 | body:"a=b"+op+"s"}, 344 | funcName: id+"s" 345 | }) 346 | exports[id+"eq"] = makeOp({ 347 | args: ["array", "array"], 348 | body: {args:["a", "b"], 349 | body:"a=a"+op+"b"}, 350 | rvalue:true, 351 | count:2, 352 | funcName: id+"eq" 353 | }) 354 | exports[id+"seq"] = makeOp({ 355 | args: ["array", "scalar"], 356 | body: {args:["a","s"], 357 | body:"a=a"+op+"s"}, 358 | rvalue:true, 359 | count:2, 360 | funcName: id+"seq" 361 | }) 362 | } 363 | })(); 364 | 365 | var math_unary = [ 366 | "abs", 367 | "acos", 368 | "asin", 369 | "atan", 370 | "ceil", 371 | "cos", 372 | "exp", 373 | "floor", 374 | "log", 375 | "round", 376 | "sin", 377 | "sqrt", 378 | "tan" 379 | ] 380 | ;(function() { 381 | for(var i=0; ithis_s){this_s=-a}else if(a>this_s){this_s=a}", localVars: [], thisVars: ["this_s"]}, 527 | post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, 528 | funcName: "norminf" 529 | }) 530 | 531 | exports.norm1 = compile({ 532 | args:["array"], 533 | pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, 534 | body: {args:[{name:"a", lvalue:false, rvalue:true, count:3}], body: "this_s+=a<0?-a:a", localVars: [], thisVars: ["this_s"]}, 535 | post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, 536 | funcName: "norm1" 537 | }) 538 | 539 | exports.sup = compile({ 540 | args: [ "array" ], 541 | pre: 542 | { body: "this_h=-Infinity", 543 | args: [], 544 | thisVars: [ "this_h" ], 545 | localVars: [] }, 546 | body: 547 | { body: "if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_", 548 | args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ], 549 | thisVars: [ "this_h" ], 550 | localVars: [] }, 551 | post: 552 | { body: "return this_h", 553 | args: [], 554 | thisVars: [ "this_h" ], 555 | localVars: [] } 556 | }) 557 | 558 | exports.inf = compile({ 559 | args: [ "array" ], 560 | pre: 561 | { body: "this_h=Infinity", 562 | args: [], 563 | thisVars: [ "this_h" ], 564 | localVars: [] }, 565 | body: 566 | { body: "if(_inline_1_arg0_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]}}}", 615 | args:[ 616 | {name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2}, 617 | {name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}], 618 | thisVars:["this_i","this_v"], 619 | localVars:["_inline_1_k"]}, 620 | post:{ 621 | body:"{return this_i}", 622 | args:[], 623 | thisVars:["this_i"], 624 | localVars:[]} 625 | }) 626 | 627 | exports.random = makeOp({ 628 | args: ["array"], 629 | pre: {args:[], body:"this_f=Math.random", thisVars:["this_f"]}, 630 | body: {args: ["a"], body:"a=this_f()", thisVars:["this_f"]}, 631 | funcName: "random" 632 | }) 633 | 634 | exports.assign = makeOp({ 635 | args:["array", "array"], 636 | body: {args:["a", "b"], body:"a=b"}, 637 | funcName: "assign" }) 638 | 639 | exports.assigns = makeOp({ 640 | args:["array", "scalar"], 641 | body: {args:["a", "b"], body:"a=b"}, 642 | funcName: "assigns" }) 643 | 644 | 645 | exports.equals = compile({ 646 | args:["array", "array"], 647 | pre: EmptyProc, 648 | body: {args:[{name:"x", lvalue:false, rvalue:true, count:1}, 649 | {name:"y", lvalue:false, rvalue:true, count:1}], 650 | body: "if(x!==y){return false}", 651 | localVars: [], 652 | thisVars: []}, 653 | post: {args:[], localVars:[], thisVars:[], body:"return true"}, 654 | funcName: "equals" 655 | }) 656 | 657 | 658 | 659 | },{"cwise-compiler":4}],4:[function(require,module,exports){ 660 | "use strict" 661 | 662 | var createThunk = require("./lib/thunk.js") 663 | 664 | function Procedure() { 665 | this.argTypes = [] 666 | this.shimArgs = [] 667 | this.arrayArgs = [] 668 | this.scalarArgs = [] 669 | this.offsetArgs = [] 670 | this.offsetArgIndex = [] 671 | this.indexArgs = [] 672 | this.shapeArgs = [] 673 | this.funcName = "" 674 | this.pre = null 675 | this.body = null 676 | this.post = null 677 | this.debug = false 678 | } 679 | 680 | function compileCwise(user_args) { 681 | //Create procedure 682 | var proc = new Procedure() 683 | 684 | //Parse blocks 685 | proc.pre = user_args.pre 686 | proc.body = user_args.body 687 | proc.post = user_args.post 688 | 689 | //Parse arguments 690 | var proc_args = user_args.args.slice(0) 691 | proc.argTypes = proc_args 692 | for(var i=0; i0) { 698 | throw new Error("cwise: pre() block may not reference array args") 699 | } 700 | if(i < proc.post.args.length && proc.post.args[i].count>0) { 701 | throw new Error("cwise: post() block may not reference array args") 702 | } 703 | } else if(arg_type === "scalar") { 704 | proc.scalarArgs.push(i) 705 | proc.shimArgs.push("scalar" + i) 706 | } else if(arg_type === "index") { 707 | proc.indexArgs.push(i) 708 | if(i < proc.pre.args.length && proc.pre.args[i].count > 0) { 709 | throw new Error("cwise: pre() block may not reference array index") 710 | } 711 | if(i < proc.body.args.length && proc.body.args[i].lvalue) { 712 | throw new Error("cwise: body() block may not write to array index") 713 | } 714 | if(i < proc.post.args.length && proc.post.args[i].count > 0) { 715 | throw new Error("cwise: post() block may not reference array index") 716 | } 717 | } else if(arg_type === "shape") { 718 | proc.shapeArgs.push(i) 719 | if(i < proc.pre.args.length && proc.pre.args[i].lvalue) { 720 | throw new Error("cwise: pre() block may not write to array shape") 721 | } 722 | if(i < proc.body.args.length && proc.body.args[i].lvalue) { 723 | throw new Error("cwise: body() block may not write to array shape") 724 | } 725 | if(i < proc.post.args.length && proc.post.args[i].lvalue) { 726 | throw new Error("cwise: post() block may not write to array shape") 727 | } 728 | } else if(typeof arg_type === "object" && arg_type.offset) { 729 | proc.argTypes[i] = "offset" 730 | proc.offsetArgs.push({ array: arg_type.array, offset:arg_type.offset }) 731 | proc.offsetArgIndex.push(i) 732 | } else { 733 | throw new Error("cwise: Unknown argument type " + proc_args[i]) 734 | } 735 | } 736 | 737 | //Make sure at least one array argument was specified 738 | if(proc.arrayArgs.length <= 0) { 739 | throw new Error("cwise: No array arguments specified") 740 | } 741 | 742 | //Make sure arguments are correct 743 | if(proc.pre.args.length > proc_args.length) { 744 | throw new Error("cwise: Too many arguments in pre() block") 745 | } 746 | if(proc.body.args.length > proc_args.length) { 747 | throw new Error("cwise: Too many arguments in body() block") 748 | } 749 | if(proc.post.args.length > proc_args.length) { 750 | throw new Error("cwise: Too many arguments in post() block") 751 | } 752 | 753 | //Check debug flag 754 | proc.debug = !!user_args.printCode || !!user_args.debug 755 | 756 | //Retrieve name 757 | proc.funcName = user_args.funcName || "cwise" 758 | 759 | //Read in block size 760 | proc.blockSize = user_args.blockSize || 64 761 | 762 | return createThunk(proc) 763 | } 764 | 765 | module.exports = compileCwise 766 | 767 | },{"./lib/thunk.js":6}],5:[function(require,module,exports){ 768 | "use strict" 769 | 770 | var uniq = require("uniq") 771 | 772 | function innerFill(order, proc, body) { 773 | var dimension = order.length 774 | , nargs = proc.arrayArgs.length 775 | , has_index = proc.indexArgs.length>0 776 | , code = [] 777 | , vars = [] 778 | , idx=0, pidx=0, i, j 779 | for(i=0; i=0; --i) { 797 | idx = order[i] 798 | code.push(["for(i",i,"=0;i",i," 0) { 811 | code.push(["index[",pidx,"]-=s",pidx].join("")) 812 | } 813 | code.push(["++index[",idx,"]"].join("")) 814 | } 815 | code.push("}") 816 | } 817 | return code.join("\n") 818 | } 819 | 820 | function outerFill(matched, order, proc, body) { 821 | var dimension = order.length 822 | , nargs = proc.arrayArgs.length 823 | , blockSize = proc.blockSize 824 | , has_index = proc.indexArgs.length > 0 825 | , code = [] 826 | for(var i=0; i0;){"].join("")) 832 | code.push(["if(j",i,"<",blockSize,"){"].join("")) 833 | code.push(["s",order[i],"=j",i].join("")) 834 | code.push(["j",i,"=0"].join("")) 835 | code.push(["}else{s",order[i],"=",blockSize].join("")) 836 | code.push(["j",i,"-=",blockSize,"}"].join("")) 837 | if(has_index) { 838 | code.push(["index[",order[i],"]=j",i].join("")) 839 | } 840 | } 841 | for(var i=0; i 0) { 949 | allEqual = allEqual && summary[i] === summary[i-1] 950 | } 951 | } 952 | if(allEqual) { 953 | return summary[0] 954 | } 955 | return summary.join("") 956 | } 957 | 958 | //Generates a cwise operator 959 | function generateCWiseOp(proc, typesig) { 960 | 961 | //Compute dimension 962 | var dimension = typesig[1].length|0 963 | var orders = new Array(proc.arrayArgs.length) 964 | var dtypes = new Array(proc.arrayArgs.length) 965 | 966 | //First create arguments for procedure 967 | var arglist = ["SS"] 968 | var code = ["'use strict'"] 969 | var vars = [] 970 | 971 | for(var j=0; j 0) { 989 | vars.push("shape=SS.slice(0)") 990 | } 991 | if(proc.indexArgs.length > 0) { 992 | var zeros = new Array(dimension) 993 | for(var i=0; i 3) { 1029 | code.push(processBlock(proc.pre, proc, dtypes)) 1030 | } 1031 | 1032 | //Process body 1033 | var body = processBlock(proc.body, proc, dtypes) 1034 | var matched = countMatches(orders) 1035 | if(matched < dimension) { 1036 | code.push(outerFill(matched, orders[0], proc, body)) 1037 | } else { 1038 | code.push(innerFill(orders[0], proc, body)) 1039 | } 1040 | 1041 | //Inline epilog 1042 | if(proc.post.body.length > 3) { 1043 | code.push(processBlock(proc.post, proc, dtypes)) 1044 | } 1045 | 1046 | if(proc.debug) { 1047 | console.log("Generated cwise routine for ", typesig, ":\n\n", code.join("\n")) 1048 | } 1049 | 1050 | var loopName = [(proc.funcName||"unnamed"), "_cwise_loop_", orders[0].join("s"),"m",matched,typeSummary(dtypes)].join("") 1051 | var f = new Function(["function ",loopName,"(", arglist.join(","),"){", code.join("\n"),"} return ", loopName].join("")) 1052 | return f() 1053 | } 1054 | module.exports = generateCWiseOp 1055 | },{"uniq":7}],6:[function(require,module,exports){ 1056 | "use strict" 1057 | 1058 | var compile = require("./compile.js") 1059 | 1060 | function createThunk(proc) { 1061 | var code = ["'use strict'", "var CACHED={}"] 1062 | var vars = [] 1063 | var thunkName = proc.funcName + "_cwise_thunk" 1064 | 1065 | //Build thunk 1066 | code.push(["return function ", thunkName, "(", proc.shimArgs.join(","), "){"].join("")) 1067 | var typesig = [] 1068 | var string_typesig = [] 1069 | var proc_args = [["array",proc.arrayArgs[0],".shape"].join("")] 1070 | for(var i=0; iMath.abs(this.stride[1]))?[1,0]:[0,1]}})") 1285 | } else if(dimension === 3) { 1286 | code.push( 1287 | "var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\ 1288 | if(s0>s1){\ 1289 | if(s1>s2){\ 1290 | return [2,1,0];\ 1291 | }else if(s0>s2){\ 1292 | return [1,2,0];\ 1293 | }else{\ 1294 | return [1,0,2];\ 1295 | }\ 1296 | }else if(s0>s2){\ 1297 | return [2,0,1];\ 1298 | }else if(s2>s1){\ 1299 | return [0,1,2];\ 1300 | }else{\ 1301 | return [0,2,1];\ 1302 | }}})") 1303 | } 1304 | } else { 1305 | code.push("ORDER})") 1306 | } 1307 | } 1308 | 1309 | //view.set(i0, ..., v): 1310 | code.push( 1311 | "proto.set=function "+className+"_set("+args.join(",")+",v){") 1312 | if(useGetters) { 1313 | code.push("return this.data.set("+index_str+",v)}") 1314 | } else { 1315 | code.push("return this.data["+index_str+"]=v}") 1316 | } 1317 | 1318 | //view.get(i0, ...): 1319 | code.push("proto.get=function "+className+"_get("+args.join(",")+"){") 1320 | if(useGetters) { 1321 | code.push("return this.data.get("+index_str+")}") 1322 | } else { 1323 | code.push("return this.data["+index_str+"]}") 1324 | } 1325 | 1326 | //view.index: 1327 | code.push( 1328 | "proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}") 1329 | 1330 | //view.hi(): 1331 | code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+ 1332 | indices.map(function(i) { 1333 | return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("") 1334 | }).join(",")+","+ 1335 | indices.map(function(i) { 1336 | return "this.stride["+i + "]" 1337 | }).join(",")+",this.offset)}") 1338 | 1339 | //view.lo(): 1340 | var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" }) 1341 | var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" }) 1342 | code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(",")) 1343 | for(var i=0; i=0){\ 1346 | d=i"+i+"|0;\ 1347 | b+=c"+i+"*d;\ 1348 | a"+i+"-=d}") 1349 | } 1350 | code.push("return new "+className+"(this.data,"+ 1351 | indices.map(function(i) { 1352 | return "a"+i 1353 | }).join(",")+","+ 1354 | indices.map(function(i) { 1355 | return "c"+i 1356 | }).join(",")+",b)}") 1357 | 1358 | //view.step(): 1359 | code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+ 1360 | indices.map(function(i) { 1361 | return "a"+i+"=this.shape["+i+"]" 1362 | }).join(",")+","+ 1363 | indices.map(function(i) { 1364 | return "b"+i+"=this.stride["+i+"]" 1365 | }).join(",")+",c=this.offset,d=0,ceil=Math.ceil") 1366 | for(var i=0; i=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}") 1402 | } 1403 | code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}") 1404 | 1405 | //Add return statement 1406 | code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+ 1407 | indices.map(function(i) { 1408 | return "shape["+i+"]" 1409 | }).join(",")+","+ 1410 | indices.map(function(i) { 1411 | return "stride["+i+"]" 1412 | }).join(",")+",offset)}") 1413 | 1414 | //Compile procedure 1415 | var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n")) 1416 | return procedure(CACHED_CONSTRUCTORS[dtype], order) 1417 | } 1418 | 1419 | function arrayDType(data) { 1420 | if(hasBuffer) { 1421 | if(Buffer.isBuffer(data)) { 1422 | return "buffer" 1423 | } 1424 | } 1425 | if(hasTypedArrays) { 1426 | switch(Object.prototype.toString.call(data)) { 1427 | case "[object Float64Array]": 1428 | return "float64" 1429 | case "[object Float32Array]": 1430 | return "float32" 1431 | case "[object Int8Array]": 1432 | return "int8" 1433 | case "[object Int16Array]": 1434 | return "int16" 1435 | case "[object Int32Array]": 1436 | return "int32" 1437 | case "[object Uint8Array]": 1438 | return "uint8" 1439 | case "[object Uint16Array]": 1440 | return "uint16" 1441 | case "[object Uint32Array]": 1442 | return "uint32" 1443 | case "[object Uint8ClampedArray]": 1444 | return "uint8_clamped" 1445 | } 1446 | } 1447 | if(Array.isArray(data)) { 1448 | return "array" 1449 | } 1450 | return "generic" 1451 | } 1452 | 1453 | var CACHED_CONSTRUCTORS = { 1454 | "float32":[], 1455 | "float64":[], 1456 | "int8":[], 1457 | "int16":[], 1458 | "int32":[], 1459 | "uint8":[], 1460 | "uint16":[], 1461 | "uint32":[], 1462 | "array":[], 1463 | "uint8_clamped":[], 1464 | "buffer":[], 1465 | "generic":[] 1466 | } 1467 | 1468 | ;(function() { 1469 | for(var id in CACHED_CONSTRUCTORS) { 1470 | CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1)) 1471 | } 1472 | }); 1473 | 1474 | function wrappedNDArrayCtor(data, shape, stride, offset) { 1475 | if(data === undefined) { 1476 | var ctor = CACHED_CONSTRUCTORS.array[0] 1477 | return ctor([]) 1478 | } else if(typeof data === "number") { 1479 | data = [data] 1480 | } 1481 | if(shape === undefined) { 1482 | shape = [ data.length ] 1483 | } 1484 | var d = shape.length 1485 | if(stride === undefined) { 1486 | stride = new Array(d) 1487 | for(var i=d-1, sz=1; i>=0; --i) { 1488 | stride[i] = sz 1489 | sz *= shape[i] 1490 | } 1491 | } 1492 | if(offset === undefined) { 1493 | offset = 0 1494 | for(var i=0; i 0) - (v < 0); 1546 | } 1547 | 1548 | //Computes absolute value of integer 1549 | exports.abs = function(v) { 1550 | var mask = v >> (INT_BITS-1); 1551 | return (v ^ mask) - mask; 1552 | } 1553 | 1554 | //Computes minimum of integers x and y 1555 | exports.min = function(x, y) { 1556 | return y ^ ((x ^ y) & -(x < y)); 1557 | } 1558 | 1559 | //Computes maximum of integers x and y 1560 | exports.max = function(x, y) { 1561 | return x ^ ((x ^ y) & -(x < y)); 1562 | } 1563 | 1564 | //Checks if a number is a power of two 1565 | exports.isPow2 = function(v) { 1566 | return !(v & (v-1)) && (!!v); 1567 | } 1568 | 1569 | //Computes log base 2 of v 1570 | exports.log2 = function(v) { 1571 | var r, shift; 1572 | r = (v > 0xFFFF) << 4; v >>>= r; 1573 | shift = (v > 0xFF ) << 3; v >>>= shift; r |= shift; 1574 | shift = (v > 0xF ) << 2; v >>>= shift; r |= shift; 1575 | shift = (v > 0x3 ) << 1; v >>>= shift; r |= shift; 1576 | return r | (v >> 1); 1577 | } 1578 | 1579 | //Computes log base 10 of v 1580 | exports.log10 = function(v) { 1581 | return (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 : 1582 | (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 : 1583 | (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0; 1584 | } 1585 | 1586 | //Counts number of bits 1587 | exports.popCount = function(v) { 1588 | v = v - ((v >>> 1) & 0x55555555); 1589 | v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); 1590 | return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 1591 | } 1592 | 1593 | //Counts number of trailing zeros 1594 | function countTrailingZeros(v) { 1595 | var c = 32; 1596 | v &= -v; 1597 | if (v) c--; 1598 | if (v & 0x0000FFFF) c -= 16; 1599 | if (v & 0x00FF00FF) c -= 8; 1600 | if (v & 0x0F0F0F0F) c -= 4; 1601 | if (v & 0x33333333) c -= 2; 1602 | if (v & 0x55555555) c -= 1; 1603 | return c; 1604 | } 1605 | exports.countTrailingZeros = countTrailingZeros; 1606 | 1607 | //Rounds to next power of 2 1608 | exports.nextPow2 = function(v) { 1609 | v += v === 0; 1610 | --v; 1611 | v |= v >>> 1; 1612 | v |= v >>> 2; 1613 | v |= v >>> 4; 1614 | v |= v >>> 8; 1615 | v |= v >>> 16; 1616 | return v + 1; 1617 | } 1618 | 1619 | //Rounds down to previous power of 2 1620 | exports.prevPow2 = function(v) { 1621 | v |= v >>> 1; 1622 | v |= v >>> 2; 1623 | v |= v >>> 4; 1624 | v |= v >>> 8; 1625 | v |= v >>> 16; 1626 | return v - (v>>>1); 1627 | } 1628 | 1629 | //Computes parity of word 1630 | exports.parity = function(v) { 1631 | v ^= v >>> 16; 1632 | v ^= v >>> 8; 1633 | v ^= v >>> 4; 1634 | v &= 0xf; 1635 | return (0x6996 >>> v) & 1; 1636 | } 1637 | 1638 | var REVERSE_TABLE = new Array(256); 1639 | 1640 | (function(tab) { 1641 | for(var i=0; i<256; ++i) { 1642 | var v = i, r = i, s = 7; 1643 | for (v >>>= 1; v; v >>>= 1) { 1644 | r <<= 1; 1645 | r |= v & 1; 1646 | --s; 1647 | } 1648 | tab[i] = (r << s) & 0xff; 1649 | } 1650 | })(REVERSE_TABLE); 1651 | 1652 | //Reverse bits in a 32 bit word 1653 | exports.reverse = function(v) { 1654 | return (REVERSE_TABLE[ v & 0xff] << 24) | 1655 | (REVERSE_TABLE[(v >>> 8) & 0xff] << 16) | 1656 | (REVERSE_TABLE[(v >>> 16) & 0xff] << 8) | 1657 | REVERSE_TABLE[(v >>> 24) & 0xff]; 1658 | } 1659 | 1660 | //Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes 1661 | exports.interleave2 = function(x, y) { 1662 | x &= 0xFFFF; 1663 | x = (x | (x << 8)) & 0x00FF00FF; 1664 | x = (x | (x << 4)) & 0x0F0F0F0F; 1665 | x = (x | (x << 2)) & 0x33333333; 1666 | x = (x | (x << 1)) & 0x55555555; 1667 | 1668 | y &= 0xFFFF; 1669 | y = (y | (y << 8)) & 0x00FF00FF; 1670 | y = (y | (y << 4)) & 0x0F0F0F0F; 1671 | y = (y | (y << 2)) & 0x33333333; 1672 | y = (y | (y << 1)) & 0x55555555; 1673 | 1674 | return x | (y << 1); 1675 | } 1676 | 1677 | //Extracts the nth interleaved component 1678 | exports.deinterleave2 = function(v, n) { 1679 | v = (v >>> n) & 0x55555555; 1680 | v = (v | (v >>> 1)) & 0x33333333; 1681 | v = (v | (v >>> 2)) & 0x0F0F0F0F; 1682 | v = (v | (v >>> 4)) & 0x00FF00FF; 1683 | v = (v | (v >>> 16)) & 0x000FFFF; 1684 | return (v << 16) >> 16; 1685 | } 1686 | 1687 | 1688 | //Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes 1689 | exports.interleave3 = function(x, y, z) { 1690 | x &= 0x3FF; 1691 | x = (x | (x<<16)) & 4278190335; 1692 | x = (x | (x<<8)) & 251719695; 1693 | x = (x | (x<<4)) & 3272356035; 1694 | x = (x | (x<<2)) & 1227133513; 1695 | 1696 | y &= 0x3FF; 1697 | y = (y | (y<<16)) & 4278190335; 1698 | y = (y | (y<<8)) & 251719695; 1699 | y = (y | (y<<4)) & 3272356035; 1700 | y = (y | (y<<2)) & 1227133513; 1701 | x |= (y << 1); 1702 | 1703 | z &= 0x3FF; 1704 | z = (z | (z<<16)) & 4278190335; 1705 | z = (z | (z<<8)) & 251719695; 1706 | z = (z | (z<<4)) & 3272356035; 1707 | z = (z | (z<<2)) & 1227133513; 1708 | 1709 | return x | (z << 2); 1710 | } 1711 | 1712 | //Extracts nth interleaved component of a 3-tuple 1713 | exports.deinterleave3 = function(v, n) { 1714 | v = (v >>> n) & 1227133513; 1715 | v = (v | (v>>>2)) & 3272356035; 1716 | v = (v | (v>>>4)) & 251719695; 1717 | v = (v | (v>>>8)) & 4278190335; 1718 | v = (v | (v>>>16)) & 0x3FF; 1719 | return (v<<22)>>22; 1720 | } 1721 | 1722 | //Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page) 1723 | exports.nextCombination = function(v) { 1724 | var t = v | (v - 1); 1725 | return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1)); 1726 | } 1727 | 1728 | 1729 | },{}],11:[function(require,module,exports){ 1730 | "use strict" 1731 | 1732 | function dupe_array(count, value, i) { 1733 | var c = count[i]|0 1734 | if(c <= 0) { 1735 | return [] 1736 | } 1737 | var result = new Array(c), j 1738 | if(i === count.length-1) { 1739 | for(j=0; j 0) { 1766 | return dupe_number(count|0, value) 1767 | } 1768 | break 1769 | case "object": 1770 | if(typeof (count.length) === "number") { 1771 | return dupe_array(count, value, 0) 1772 | } 1773 | break 1774 | } 1775 | return [] 1776 | } 1777 | 1778 | module.exports = dupe 1779 | },{}],12:[function(require,module,exports){ 1780 | (function (global,Buffer){ 1781 | 'use strict' 1782 | 1783 | var bits = require('bit-twiddle') 1784 | var dup = require('dup') 1785 | 1786 | //Legacy pool support 1787 | if(!global.__TYPEDARRAY_POOL) { 1788 | global.__TYPEDARRAY_POOL = { 1789 | UINT8 : dup([32, 0]) 1790 | , UINT16 : dup([32, 0]) 1791 | , UINT32 : dup([32, 0]) 1792 | , INT8 : dup([32, 0]) 1793 | , INT16 : dup([32, 0]) 1794 | , INT32 : dup([32, 0]) 1795 | , FLOAT : dup([32, 0]) 1796 | , DOUBLE : dup([32, 0]) 1797 | , DATA : dup([32, 0]) 1798 | , UINT8C : dup([32, 0]) 1799 | , BUFFER : dup([32, 0]) 1800 | } 1801 | } 1802 | 1803 | var hasUint8C = (typeof Uint8ClampedArray) !== 'undefined' 1804 | var POOL = global.__TYPEDARRAY_POOL 1805 | 1806 | //Upgrade pool 1807 | if(!POOL.UINT8C) { 1808 | POOL.UINT8C = dup([32, 0]) 1809 | } 1810 | if(!POOL.BUFFER) { 1811 | POOL.BUFFER = dup([32, 0]) 1812 | } 1813 | 1814 | //New technique: Only allocate from ArrayBufferView and Buffer 1815 | var DATA = POOL.DATA 1816 | , BUFFER = POOL.BUFFER 1817 | 1818 | exports.free = function free(array) { 1819 | if(Buffer.isBuffer(array)) { 1820 | BUFFER[bits.log2(array.length)].push(array) 1821 | } else { 1822 | if(Object.prototype.toString.call(array) !== '[object ArrayBuffer]') { 1823 | array = array.buffer 1824 | } 1825 | if(!array) { 1826 | return 1827 | } 1828 | var n = array.length || array.byteLength 1829 | var log_n = bits.log2(n)|0 1830 | DATA[log_n].push(array) 1831 | } 1832 | } 1833 | 1834 | function freeArrayBuffer(buffer) { 1835 | if(!buffer) { 1836 | return 1837 | } 1838 | var n = buffer.length || buffer.byteLength 1839 | var log_n = bits.log2(n) 1840 | DATA[log_n].push(buffer) 1841 | } 1842 | 1843 | function freeTypedArray(array) { 1844 | freeArrayBuffer(array.buffer) 1845 | } 1846 | 1847 | exports.freeUint8 = 1848 | exports.freeUint16 = 1849 | exports.freeUint32 = 1850 | exports.freeInt8 = 1851 | exports.freeInt16 = 1852 | exports.freeInt32 = 1853 | exports.freeFloat32 = 1854 | exports.freeFloat = 1855 | exports.freeFloat64 = 1856 | exports.freeDouble = 1857 | exports.freeUint8Clamped = 1858 | exports.freeDataView = freeTypedArray 1859 | 1860 | exports.freeArrayBuffer = freeArrayBuffer 1861 | 1862 | exports.freeBuffer = function freeBuffer(array) { 1863 | BUFFER[bits.log2(array.length)].push(array) 1864 | } 1865 | 1866 | exports.malloc = function malloc(n, dtype) { 1867 | if(dtype === undefined || dtype === 'arraybuffer') { 1868 | return mallocArrayBuffer(n) 1869 | } else { 1870 | switch(dtype) { 1871 | case 'uint8': 1872 | return mallocUint8(n) 1873 | case 'uint16': 1874 | return mallocUint16(n) 1875 | case 'uint32': 1876 | return mallocUint32(n) 1877 | case 'int8': 1878 | return mallocInt8(n) 1879 | case 'int16': 1880 | return mallocInt16(n) 1881 | case 'int32': 1882 | return mallocInt32(n) 1883 | case 'float': 1884 | case 'float32': 1885 | return mallocFloat(n) 1886 | case 'double': 1887 | case 'float64': 1888 | return mallocDouble(n) 1889 | case 'uint8_clamped': 1890 | return mallocUint8Clamped(n) 1891 | case 'buffer': 1892 | return mallocBuffer(n) 1893 | case 'data': 1894 | case 'dataview': 1895 | return mallocDataView(n) 1896 | 1897 | default: 1898 | return null 1899 | } 1900 | } 1901 | return null 1902 | } 1903 | 1904 | function mallocArrayBuffer(n) { 1905 | var n = bits.nextPow2(n) 1906 | var log_n = bits.log2(n) 1907 | var d = DATA[log_n] 1908 | if(d.length > 0) { 1909 | return d.pop() 1910 | } 1911 | return new ArrayBuffer(n) 1912 | } 1913 | exports.mallocArrayBuffer = mallocArrayBuffer 1914 | 1915 | function mallocUint8(n) { 1916 | return new Uint8Array(mallocArrayBuffer(n), 0, n) 1917 | } 1918 | exports.mallocUint8 = mallocUint8 1919 | 1920 | function mallocUint16(n) { 1921 | return new Uint16Array(mallocArrayBuffer(2*n), 0, n) 1922 | } 1923 | exports.mallocUint16 = mallocUint16 1924 | 1925 | function mallocUint32(n) { 1926 | return new Uint32Array(mallocArrayBuffer(4*n), 0, n) 1927 | } 1928 | exports.mallocUint32 = mallocUint32 1929 | 1930 | function mallocInt8(n) { 1931 | return new Int8Array(mallocArrayBuffer(n), 0, n) 1932 | } 1933 | exports.mallocInt8 = mallocInt8 1934 | 1935 | function mallocInt16(n) { 1936 | return new Int16Array(mallocArrayBuffer(2*n), 0, n) 1937 | } 1938 | exports.mallocInt16 = mallocInt16 1939 | 1940 | function mallocInt32(n) { 1941 | return new Int32Array(mallocArrayBuffer(4*n), 0, n) 1942 | } 1943 | exports.mallocInt32 = mallocInt32 1944 | 1945 | function mallocFloat(n) { 1946 | return new Float32Array(mallocArrayBuffer(4*n), 0, n) 1947 | } 1948 | exports.mallocFloat32 = exports.mallocFloat = mallocFloat 1949 | 1950 | function mallocDouble(n) { 1951 | return new Float64Array(mallocArrayBuffer(8*n), 0, n) 1952 | } 1953 | exports.mallocFloat64 = exports.mallocDouble = mallocDouble 1954 | 1955 | function mallocUint8Clamped(n) { 1956 | if(hasUint8C) { 1957 | return new Uint8ClampedArray(mallocArrayBuffer(n), 0, n) 1958 | } else { 1959 | return mallocUint8(n) 1960 | } 1961 | } 1962 | exports.mallocUint8Clamped = mallocUint8Clamped 1963 | 1964 | function mallocDataView(n) { 1965 | return new DataView(mallocArrayBuffer(n), 0, n) 1966 | } 1967 | exports.mallocDataView = mallocDataView 1968 | 1969 | function mallocBuffer(n) { 1970 | n = bits.nextPow2(n) 1971 | var log_n = bits.log2(n) 1972 | var cache = BUFFER[log_n] 1973 | if(cache.length > 0) { 1974 | return cache.pop() 1975 | } 1976 | return new Buffer(n) 1977 | } 1978 | exports.mallocBuffer = mallocBuffer 1979 | 1980 | exports.clearCache = function clearCache() { 1981 | for(var i=0; i<32; ++i) { 1982 | POOL.UINT8[i].length = 0 1983 | POOL.UINT16[i].length = 0 1984 | POOL.UINT32[i].length = 0 1985 | POOL.INT8[i].length = 0 1986 | POOL.INT16[i].length = 0 1987 | POOL.INT32[i].length = 0 1988 | POOL.FLOAT[i].length = 0 1989 | POOL.DOUBLE[i].length = 0 1990 | POOL.UINT8C[i].length = 0 1991 | DATA[i].length = 0 1992 | BUFFER[i].length = 0 1993 | } 1994 | } 1995 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) 1996 | },{"bit-twiddle":10,"buffer":23,"dup":11}],13:[function(require,module,exports){ 1997 | // Copyright (C) 2011 Google Inc. 1998 | // 1999 | // Licensed under the Apache License, Version 2.0 (the "License"); 2000 | // you may not use this file except in compliance with the License. 2001 | // You may obtain a copy of the License at 2002 | // 2003 | // http://www.apache.org/licenses/LICENSE-2.0 2004 | // 2005 | // Unless required by applicable law or agreed to in writing, software 2006 | // distributed under the License is distributed on an "AS IS" BASIS, 2007 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2008 | // See the License for the specific language governing permissions and 2009 | // limitations under the License. 2010 | 2011 | /** 2012 | * @fileoverview Install a leaky WeakMap emulation on platforms that 2013 | * don't provide a built-in one. 2014 | * 2015 | *

Assumes that an ES5 platform where, if {@code WeakMap} is 2016 | * already present, then it conforms to the anticipated ES6 2017 | * specification. To run this file on an ES5 or almost ES5 2018 | * implementation where the {@code WeakMap} specification does not 2019 | * quite conform, run repairES5.js first. 2020 | * 2021 | *

Even though WeakMapModule is not global, the linter thinks it 2022 | * is, which is why it is in the overrides list below. 2023 | * 2024 | *

NOTE: Before using this WeakMap emulation in a non-SES 2025 | * environment, see the note below about hiddenRecord. 2026 | * 2027 | * @author Mark S. Miller 2028 | * @requires crypto, ArrayBuffer, Uint8Array, navigator, console 2029 | * @overrides WeakMap, ses, Proxy 2030 | * @overrides WeakMapModule 2031 | */ 2032 | 2033 | /** 2034 | * This {@code WeakMap} emulation is observably equivalent to the 2035 | * ES-Harmony WeakMap, but with leakier garbage collection properties. 2036 | * 2037 | *

As with true WeakMaps, in this emulation, a key does not 2038 | * retain maps indexed by that key and (crucially) a map does not 2039 | * retain the keys it indexes. A map by itself also does not retain 2040 | * the values associated with that map. 2041 | * 2042 | *

However, the values associated with a key in some map are 2043 | * retained so long as that key is retained and those associations are 2044 | * not overridden. For example, when used to support membranes, all 2045 | * values exported from a given membrane will live for the lifetime 2046 | * they would have had in the absence of an interposed membrane. Even 2047 | * when the membrane is revoked, all objects that would have been 2048 | * reachable in the absence of revocation will still be reachable, as 2049 | * far as the GC can tell, even though they will no longer be relevant 2050 | * to ongoing computation. 2051 | * 2052 | *

The API implemented here is approximately the API as implemented 2053 | * in FF6.0a1 and agreed to by MarkM, Andreas Gal, and Dave Herman, 2054 | * rather than the offially approved proposal page. TODO(erights): 2055 | * upgrade the ecmascript WeakMap proposal page to explain this API 2056 | * change and present to EcmaScript committee for their approval. 2057 | * 2058 | *

The first difference between the emulation here and that in 2059 | * FF6.0a1 is the presence of non enumerable {@code get___, has___, 2060 | * set___, and delete___} methods on WeakMap instances to represent 2061 | * what would be the hidden internal properties of a primitive 2062 | * implementation. Whereas the FF6.0a1 WeakMap.prototype methods 2063 | * require their {@code this} to be a genuine WeakMap instance (i.e., 2064 | * an object of {@code [[Class]]} "WeakMap}), since there is nothing 2065 | * unforgeable about the pseudo-internal method names used here, 2066 | * nothing prevents these emulated prototype methods from being 2067 | * applied to non-WeakMaps with pseudo-internal methods of the same 2068 | * names. 2069 | * 2070 | *

Another difference is that our emulated {@code 2071 | * WeakMap.prototype} is not itself a WeakMap. A problem with the 2072 | * current FF6.0a1 API is that WeakMap.prototype is itself a WeakMap 2073 | * providing ambient mutability and an ambient communications 2074 | * channel. Thus, if a WeakMap is already present and has this 2075 | * problem, repairES5.js wraps it in a safe wrappper in order to 2076 | * prevent access to this channel. (See 2077 | * PATCH_MUTABLE_FROZEN_WEAKMAP_PROTO in repairES5.js). 2078 | */ 2079 | 2080 | /** 2081 | * If this is a full secureable ES5 platform and the ES-Harmony {@code WeakMap} is 2084 | * absent, install an approximate emulation. 2085 | * 2086 | *

If WeakMap is present but cannot store some objects, use our approximate 2087 | * emulation as a wrapper. 2088 | * 2089 | *

If this is almost a secureable ES5 platform, then WeakMap.js 2090 | * should be run after repairES5.js. 2091 | * 2092 | *

See {@code WeakMap} for documentation of the garbage collection 2093 | * properties of this WeakMap emulation. 2094 | */ 2095 | (function WeakMapModule() { 2096 | "use strict"; 2097 | 2098 | if (typeof ses !== 'undefined' && ses.ok && !ses.ok()) { 2099 | // already too broken, so give up 2100 | return; 2101 | } 2102 | 2103 | /** 2104 | * In some cases (current Firefox), we must make a choice betweeen a 2105 | * WeakMap which is capable of using all varieties of host objects as 2106 | * keys and one which is capable of safely using proxies as keys. See 2107 | * comments below about HostWeakMap and DoubleWeakMap for details. 2108 | * 2109 | * This function (which is a global, not exposed to guests) marks a 2110 | * WeakMap as permitted to do what is necessary to index all host 2111 | * objects, at the cost of making it unsafe for proxies. 2112 | * 2113 | * Do not apply this function to anything which is not a genuine 2114 | * fresh WeakMap. 2115 | */ 2116 | function weakMapPermitHostObjects(map) { 2117 | // identity of function used as a secret -- good enough and cheap 2118 | if (map.permitHostObjects___) { 2119 | map.permitHostObjects___(weakMapPermitHostObjects); 2120 | } 2121 | } 2122 | if (typeof ses !== 'undefined') { 2123 | ses.weakMapPermitHostObjects = weakMapPermitHostObjects; 2124 | } 2125 | 2126 | // IE 11 has no Proxy but has a broken WeakMap such that we need to patch 2127 | // it using DoubleWeakMap; this flag tells DoubleWeakMap so. 2128 | var doubleWeakMapCheckSilentFailure = false; 2129 | 2130 | // Check if there is already a good-enough WeakMap implementation, and if so 2131 | // exit without replacing it. 2132 | if (typeof WeakMap === 'function') { 2133 | var HostWeakMap = WeakMap; 2134 | // There is a WeakMap -- is it good enough? 2135 | if (typeof navigator !== 'undefined' && 2136 | /Firefox/.test(navigator.userAgent)) { 2137 | // We're now *assuming not*, because as of this writing (2013-05-06) 2138 | // Firefox's WeakMaps have a miscellany of objects they won't accept, and 2139 | // we don't want to make an exhaustive list, and testing for just one 2140 | // will be a problem if that one is fixed alone (as they did for Event). 2141 | 2142 | // If there is a platform that we *can* reliably test on, here's how to 2143 | // do it: 2144 | // var problematic = ... ; 2145 | // var testHostMap = new HostWeakMap(); 2146 | // try { 2147 | // testHostMap.set(problematic, 1); // Firefox 20 will throw here 2148 | // if (testHostMap.get(problematic) === 1) { 2149 | // return; 2150 | // } 2151 | // } catch (e) {} 2152 | 2153 | } else { 2154 | // IE 11 bug: WeakMaps silently fail to store frozen objects. 2155 | var testMap = new HostWeakMap(); 2156 | var testObject = Object.freeze({}); 2157 | testMap.set(testObject, 1); 2158 | if (testMap.get(testObject) !== 1) { 2159 | doubleWeakMapCheckSilentFailure = true; 2160 | // Fall through to installing our WeakMap. 2161 | } else { 2162 | module.exports = WeakMap; 2163 | return; 2164 | } 2165 | } 2166 | } 2167 | 2168 | var hop = Object.prototype.hasOwnProperty; 2169 | var gopn = Object.getOwnPropertyNames; 2170 | var defProp = Object.defineProperty; 2171 | var isExtensible = Object.isExtensible; 2172 | 2173 | /** 2174 | * Security depends on HIDDEN_NAME being both unguessable and 2175 | * undiscoverable by untrusted code. 2176 | * 2177 | *

Given the known weaknesses of Math.random() on existing 2178 | * browsers, it does not generate unguessability we can be confident 2179 | * of. 2180 | * 2181 | *

It is the monkey patching logic in this file that is intended 2182 | * to ensure undiscoverability. The basic idea is that there are 2183 | * three fundamental means of discovering properties of an object: 2184 | * The for/in loop, Object.keys(), and Object.getOwnPropertyNames(), 2185 | * as well as some proposed ES6 extensions that appear on our 2186 | * whitelist. The first two only discover enumerable properties, and 2187 | * we only use HIDDEN_NAME to name a non-enumerable property, so the 2188 | * only remaining threat should be getOwnPropertyNames and some 2189 | * proposed ES6 extensions that appear on our whitelist. We monkey 2190 | * patch them to remove HIDDEN_NAME from the list of properties they 2191 | * returns. 2192 | * 2193 | *

TODO(erights): On a platform with built-in Proxies, proxies 2194 | * could be used to trap and thereby discover the HIDDEN_NAME, so we 2195 | * need to monkey patch Proxy.create, Proxy.createFunction, etc, in 2196 | * order to wrap the provided handler with the real handler which 2197 | * filters out all traps using HIDDEN_NAME. 2198 | * 2199 | *

TODO(erights): Revisit Mike Stay's suggestion that we use an 2200 | * encapsulated function at a not-necessarily-secret name, which 2201 | * uses the Stiegler shared-state rights amplification pattern to 2202 | * reveal the associated value only to the WeakMap in which this key 2203 | * is associated with that value. Since only the key retains the 2204 | * function, the function can also remember the key without causing 2205 | * leakage of the key, so this doesn't violate our general gc 2206 | * goals. In addition, because the name need not be a guarded 2207 | * secret, we could efficiently handle cross-frame frozen keys. 2208 | */ 2209 | var HIDDEN_NAME_PREFIX = 'weakmap:'; 2210 | var HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'ident:' + Math.random() + '___'; 2211 | 2212 | if (typeof crypto !== 'undefined' && 2213 | typeof crypto.getRandomValues === 'function' && 2214 | typeof ArrayBuffer === 'function' && 2215 | typeof Uint8Array === 'function') { 2216 | var ab = new ArrayBuffer(25); 2217 | var u8s = new Uint8Array(ab); 2218 | crypto.getRandomValues(u8s); 2219 | HIDDEN_NAME = HIDDEN_NAME_PREFIX + 'rand:' + 2220 | Array.prototype.map.call(u8s, function(u8) { 2221 | return (u8 % 36).toString(36); 2222 | }).join('') + '___'; 2223 | } 2224 | 2225 | function isNotHiddenName(name) { 2226 | return !( 2227 | name.substr(0, HIDDEN_NAME_PREFIX.length) == HIDDEN_NAME_PREFIX && 2228 | name.substr(name.length - 3) === '___'); 2229 | } 2230 | 2231 | /** 2232 | * Monkey patch getOwnPropertyNames to avoid revealing the 2233 | * HIDDEN_NAME. 2234 | * 2235 | *

The ES5.1 spec requires each name to appear only once, but as 2236 | * of this writing, this requirement is controversial for ES6, so we 2237 | * made this code robust against this case. If the resulting extra 2238 | * search turns out to be expensive, we can probably relax this once 2239 | * ES6 is adequately supported on all major browsers, iff no browser 2240 | * versions we support at that time have relaxed this constraint 2241 | * without providing built-in ES6 WeakMaps. 2242 | */ 2243 | defProp(Object, 'getOwnPropertyNames', { 2244 | value: function fakeGetOwnPropertyNames(obj) { 2245 | return gopn(obj).filter(isNotHiddenName); 2246 | } 2247 | }); 2248 | 2249 | /** 2250 | * getPropertyNames is not in ES5 but it is proposed for ES6 and 2251 | * does appear in our whitelist, so we need to clean it too. 2252 | */ 2253 | if ('getPropertyNames' in Object) { 2254 | var originalGetPropertyNames = Object.getPropertyNames; 2255 | defProp(Object, 'getPropertyNames', { 2256 | value: function fakeGetPropertyNames(obj) { 2257 | return originalGetPropertyNames(obj).filter(isNotHiddenName); 2258 | } 2259 | }); 2260 | } 2261 | 2262 | /** 2263 | *

To treat objects as identity-keys with reasonable efficiency 2264 | * on ES5 by itself (i.e., without any object-keyed collections), we 2265 | * need to add a hidden property to such key objects when we 2266 | * can. This raises several issues: 2267 | *

    2268 | *
  • Arranging to add this property to objects before we lose the 2269 | * chance, and 2270 | *
  • Hiding the existence of this new property from most 2271 | * JavaScript code. 2272 | *
  • Preventing certification theft, where one object is 2273 | * created falsely claiming to be the key of an association 2274 | * actually keyed by another object. 2275 | *
  • Preventing value theft, where untrusted code with 2276 | * access to a key object but not a weak map nevertheless 2277 | * obtains access to the value associated with that key in that 2278 | * weak map. 2279 | *
2280 | * We do so by 2281 | *
    2282 | *
  • Making the name of the hidden property unguessable, so "[]" 2283 | * indexing, which we cannot intercept, cannot be used to access 2284 | * a property without knowing the name. 2285 | *
  • Making the hidden property non-enumerable, so we need not 2286 | * worry about for-in loops or {@code Object.keys}, 2287 | *
  • monkey patching those reflective methods that would 2288 | * prevent extensions, to add this hidden property first, 2289 | *
  • monkey patching those methods that would reveal this 2290 | * hidden property. 2291 | *
2292 | * Unfortunately, because of same-origin iframes, we cannot reliably 2293 | * add this hidden property before an object becomes 2294 | * non-extensible. Instead, if we encounter a non-extensible object 2295 | * without a hidden record that we can detect (whether or not it has 2296 | * a hidden record stored under a name secret to us), then we just 2297 | * use the key object itself to represent its identity in a brute 2298 | * force leaky map stored in the weak map, losing all the advantages 2299 | * of weakness for these. 2300 | */ 2301 | function getHiddenRecord(key) { 2302 | if (key !== Object(key)) { 2303 | throw new TypeError('Not an object: ' + key); 2304 | } 2305 | var hiddenRecord = key[HIDDEN_NAME]; 2306 | if (hiddenRecord && hiddenRecord.key === key) { return hiddenRecord; } 2307 | if (!isExtensible(key)) { 2308 | // Weak map must brute force, as explained in doc-comment above. 2309 | return void 0; 2310 | } 2311 | 2312 | // The hiddenRecord and the key point directly at each other, via 2313 | // the "key" and HIDDEN_NAME properties respectively. The key 2314 | // field is for quickly verifying that this hidden record is an 2315 | // own property, not a hidden record from up the prototype chain. 2316 | // 2317 | // NOTE: Because this WeakMap emulation is meant only for systems like 2318 | // SES where Object.prototype is frozen without any numeric 2319 | // properties, it is ok to use an object literal for the hiddenRecord. 2320 | // This has two advantages: 2321 | // * It is much faster in a performance critical place 2322 | // * It avoids relying on Object.create(null), which had been 2323 | // problematic on Chrome 28.0.1480.0. See 2324 | // https://code.google.com/p/google-caja/issues/detail?id=1687 2325 | hiddenRecord = { key: key }; 2326 | 2327 | // When using this WeakMap emulation on platforms where 2328 | // Object.prototype might not be frozen and Object.create(null) is 2329 | // reliable, use the following two commented out lines instead. 2330 | // hiddenRecord = Object.create(null); 2331 | // hiddenRecord.key = key; 2332 | 2333 | // Please contact us if you need this to work on platforms where 2334 | // Object.prototype might not be frozen and 2335 | // Object.create(null) might not be reliable. 2336 | 2337 | try { 2338 | defProp(key, HIDDEN_NAME, { 2339 | value: hiddenRecord, 2340 | writable: false, 2341 | enumerable: false, 2342 | configurable: false 2343 | }); 2344 | return hiddenRecord; 2345 | } catch (error) { 2346 | // Under some circumstances, isExtensible seems to misreport whether 2347 | // the HIDDEN_NAME can be defined. 2348 | // The circumstances have not been isolated, but at least affect 2349 | // Node.js v0.10.26 on TravisCI / Linux, but not the same version of 2350 | // Node.js on OS X. 2351 | return void 0; 2352 | } 2353 | } 2354 | 2355 | /** 2356 | * Monkey patch operations that would make their argument 2357 | * non-extensible. 2358 | * 2359 | *

The monkey patched versions throw a TypeError if their 2360 | * argument is not an object, so it should only be done to functions 2361 | * that should throw a TypeError anyway if their argument is not an 2362 | * object. 2363 | */ 2364 | (function(){ 2365 | var oldFreeze = Object.freeze; 2366 | defProp(Object, 'freeze', { 2367 | value: function identifyingFreeze(obj) { 2368 | getHiddenRecord(obj); 2369 | return oldFreeze(obj); 2370 | } 2371 | }); 2372 | var oldSeal = Object.seal; 2373 | defProp(Object, 'seal', { 2374 | value: function identifyingSeal(obj) { 2375 | getHiddenRecord(obj); 2376 | return oldSeal(obj); 2377 | } 2378 | }); 2379 | var oldPreventExtensions = Object.preventExtensions; 2380 | defProp(Object, 'preventExtensions', { 2381 | value: function identifyingPreventExtensions(obj) { 2382 | getHiddenRecord(obj); 2383 | return oldPreventExtensions(obj); 2384 | } 2385 | }); 2386 | })(); 2387 | 2388 | function constFunc(func) { 2389 | func.prototype = null; 2390 | return Object.freeze(func); 2391 | } 2392 | 2393 | var calledAsFunctionWarningDone = false; 2394 | function calledAsFunctionWarning() { 2395 | // Future ES6 WeakMap is currently (2013-09-10) expected to reject WeakMap() 2396 | // but we used to permit it and do it ourselves, so warn only. 2397 | if (!calledAsFunctionWarningDone && typeof console !== 'undefined') { 2398 | calledAsFunctionWarningDone = true; 2399 | console.warn('WeakMap should be invoked as new WeakMap(), not ' + 2400 | 'WeakMap(). This will be an error in the future.'); 2401 | } 2402 | } 2403 | 2404 | var nextId = 0; 2405 | 2406 | var OurWeakMap = function() { 2407 | if (!(this instanceof OurWeakMap)) { // approximate test for new ...() 2408 | calledAsFunctionWarning(); 2409 | } 2410 | 2411 | // We are currently (12/25/2012) never encountering any prematurely 2412 | // non-extensible keys. 2413 | var keys = []; // brute force for prematurely non-extensible keys. 2414 | var values = []; // brute force for corresponding values. 2415 | var id = nextId++; 2416 | 2417 | function get___(key, opt_default) { 2418 | var index; 2419 | var hiddenRecord = getHiddenRecord(key); 2420 | if (hiddenRecord) { 2421 | return id in hiddenRecord ? hiddenRecord[id] : opt_default; 2422 | } else { 2423 | index = keys.indexOf(key); 2424 | return index >= 0 ? values[index] : opt_default; 2425 | } 2426 | } 2427 | 2428 | function has___(key) { 2429 | var hiddenRecord = getHiddenRecord(key); 2430 | if (hiddenRecord) { 2431 | return id in hiddenRecord; 2432 | } else { 2433 | return keys.indexOf(key) >= 0; 2434 | } 2435 | } 2436 | 2437 | function set___(key, value) { 2438 | var index; 2439 | var hiddenRecord = getHiddenRecord(key); 2440 | if (hiddenRecord) { 2441 | hiddenRecord[id] = value; 2442 | } else { 2443 | index = keys.indexOf(key); 2444 | if (index >= 0) { 2445 | values[index] = value; 2446 | } else { 2447 | // Since some browsers preemptively terminate slow turns but 2448 | // then continue computing with presumably corrupted heap 2449 | // state, we here defensively get keys.length first and then 2450 | // use it to update both the values and keys arrays, keeping 2451 | // them in sync. 2452 | index = keys.length; 2453 | values[index] = value; 2454 | // If we crash here, values will be one longer than keys. 2455 | keys[index] = key; 2456 | } 2457 | } 2458 | return this; 2459 | } 2460 | 2461 | function delete___(key) { 2462 | var hiddenRecord = getHiddenRecord(key); 2463 | var index, lastIndex; 2464 | if (hiddenRecord) { 2465 | return id in hiddenRecord && delete hiddenRecord[id]; 2466 | } else { 2467 | index = keys.indexOf(key); 2468 | if (index < 0) { 2469 | return false; 2470 | } 2471 | // Since some browsers preemptively terminate slow turns but 2472 | // then continue computing with potentially corrupted heap 2473 | // state, we here defensively get keys.length first and then use 2474 | // it to update both the keys and the values array, keeping 2475 | // them in sync. We update the two with an order of assignments, 2476 | // such that any prefix of these assignments will preserve the 2477 | // key/value correspondence, either before or after the delete. 2478 | // Note that this needs to work correctly when index === lastIndex. 2479 | lastIndex = keys.length - 1; 2480 | keys[index] = void 0; 2481 | // If we crash here, there's a void 0 in the keys array, but 2482 | // no operation will cause a "keys.indexOf(void 0)", since 2483 | // getHiddenRecord(void 0) will always throw an error first. 2484 | values[index] = values[lastIndex]; 2485 | // If we crash here, values[index] cannot be found here, 2486 | // because keys[index] is void 0. 2487 | keys[index] = keys[lastIndex]; 2488 | // If index === lastIndex and we crash here, then keys[index] 2489 | // is still void 0, since the aliasing killed the previous key. 2490 | keys.length = lastIndex; 2491 | // If we crash here, keys will be one shorter than values. 2492 | values.length = lastIndex; 2493 | return true; 2494 | } 2495 | } 2496 | 2497 | return Object.create(OurWeakMap.prototype, { 2498 | get___: { value: constFunc(get___) }, 2499 | has___: { value: constFunc(has___) }, 2500 | set___: { value: constFunc(set___) }, 2501 | delete___: { value: constFunc(delete___) } 2502 | }); 2503 | }; 2504 | 2505 | OurWeakMap.prototype = Object.create(Object.prototype, { 2506 | get: { 2507 | /** 2508 | * Return the value most recently associated with key, or 2509 | * opt_default if none. 2510 | */ 2511 | value: function get(key, opt_default) { 2512 | return this.get___(key, opt_default); 2513 | }, 2514 | writable: true, 2515 | configurable: true 2516 | }, 2517 | 2518 | has: { 2519 | /** 2520 | * Is there a value associated with key in this WeakMap? 2521 | */ 2522 | value: function has(key) { 2523 | return this.has___(key); 2524 | }, 2525 | writable: true, 2526 | configurable: true 2527 | }, 2528 | 2529 | set: { 2530 | /** 2531 | * Associate value with key in this WeakMap, overwriting any 2532 | * previous association if present. 2533 | */ 2534 | value: function set(key, value) { 2535 | return this.set___(key, value); 2536 | }, 2537 | writable: true, 2538 | configurable: true 2539 | }, 2540 | 2541 | 'delete': { 2542 | /** 2543 | * Remove any association for key in this WeakMap, returning 2544 | * whether there was one. 2545 | * 2546 | *

Note that the boolean return here does not work like the 2547 | * {@code delete} operator. The {@code delete} operator returns 2548 | * whether the deletion succeeds at bringing about a state in 2549 | * which the deleted property is absent. The {@code delete} 2550 | * operator therefore returns true if the property was already 2551 | * absent, whereas this {@code delete} method returns false if 2552 | * the association was already absent. 2553 | */ 2554 | value: function remove(key) { 2555 | return this.delete___(key); 2556 | }, 2557 | writable: true, 2558 | configurable: true 2559 | } 2560 | }); 2561 | 2562 | if (typeof HostWeakMap === 'function') { 2563 | (function() { 2564 | // If we got here, then the platform has a WeakMap but we are concerned 2565 | // that it may refuse to store some key types. Therefore, make a map 2566 | // implementation which makes use of both as possible. 2567 | 2568 | // In this mode we are always using double maps, so we are not proxy-safe. 2569 | // This combination does not occur in any known browser, but we had best 2570 | // be safe. 2571 | if (doubleWeakMapCheckSilentFailure && typeof Proxy !== 'undefined') { 2572 | Proxy = undefined; 2573 | } 2574 | 2575 | function DoubleWeakMap() { 2576 | if (!(this instanceof OurWeakMap)) { // approximate test for new ...() 2577 | calledAsFunctionWarning(); 2578 | } 2579 | 2580 | // Preferable, truly weak map. 2581 | var hmap = new HostWeakMap(); 2582 | 2583 | // Our hidden-property-based pseudo-weak-map. Lazily initialized in the 2584 | // 'set' implementation; thus we can avoid performing extra lookups if 2585 | // we know all entries actually stored are entered in 'hmap'. 2586 | var omap = undefined; 2587 | 2588 | // Hidden-property maps are not compatible with proxies because proxies 2589 | // can observe the hidden name and either accidentally expose it or fail 2590 | // to allow the hidden property to be set. Therefore, we do not allow 2591 | // arbitrary WeakMaps to switch to using hidden properties, but only 2592 | // those which need the ability, and unprivileged code is not allowed 2593 | // to set the flag. 2594 | // 2595 | // (Except in doubleWeakMapCheckSilentFailure mode in which case we 2596 | // disable proxies.) 2597 | var enableSwitching = false; 2598 | 2599 | function dget(key, opt_default) { 2600 | if (omap) { 2601 | return hmap.has(key) ? hmap.get(key) 2602 | : omap.get___(key, opt_default); 2603 | } else { 2604 | return hmap.get(key, opt_default); 2605 | } 2606 | } 2607 | 2608 | function dhas(key) { 2609 | return hmap.has(key) || (omap ? omap.has___(key) : false); 2610 | } 2611 | 2612 | var dset; 2613 | if (doubleWeakMapCheckSilentFailure) { 2614 | dset = function(key, value) { 2615 | hmap.set(key, value); 2616 | if (!hmap.has(key)) { 2617 | if (!omap) { omap = new OurWeakMap(); } 2618 | omap.set(key, value); 2619 | } 2620 | return this; 2621 | }; 2622 | } else { 2623 | dset = function(key, value) { 2624 | if (enableSwitching) { 2625 | try { 2626 | hmap.set(key, value); 2627 | } catch (e) { 2628 | if (!omap) { omap = new OurWeakMap(); } 2629 | omap.set___(key, value); 2630 | } 2631 | } else { 2632 | hmap.set(key, value); 2633 | } 2634 | return this; 2635 | }; 2636 | } 2637 | 2638 | function ddelete(key) { 2639 | var result = !!hmap['delete'](key); 2640 | if (omap) { return omap.delete___(key) || result; } 2641 | return result; 2642 | } 2643 | 2644 | return Object.create(OurWeakMap.prototype, { 2645 | get___: { value: constFunc(dget) }, 2646 | has___: { value: constFunc(dhas) }, 2647 | set___: { value: constFunc(dset) }, 2648 | delete___: { value: constFunc(ddelete) }, 2649 | permitHostObjects___: { value: constFunc(function(token) { 2650 | if (token === weakMapPermitHostObjects) { 2651 | enableSwitching = true; 2652 | } else { 2653 | throw new Error('bogus call to permitHostObjects___'); 2654 | } 2655 | })} 2656 | }); 2657 | } 2658 | DoubleWeakMap.prototype = OurWeakMap.prototype; 2659 | module.exports = DoubleWeakMap; 2660 | 2661 | // define .constructor to hide OurWeakMap ctor 2662 | Object.defineProperty(WeakMap.prototype, 'constructor', { 2663 | value: WeakMap, 2664 | enumerable: false, // as default .constructor is 2665 | configurable: true, 2666 | writable: true 2667 | }); 2668 | })(); 2669 | } else { 2670 | // There is no host WeakMap, so we must use the emulation. 2671 | 2672 | // Emulated WeakMaps are incompatible with native proxies (because proxies 2673 | // can observe the hidden name), so we must disable Proxy usage (in 2674 | // ArrayLike and Domado, currently). 2675 | if (typeof Proxy !== 'undefined') { 2676 | Proxy = undefined; 2677 | } 2678 | 2679 | module.exports = OurWeakMap; 2680 | } 2681 | })(); 2682 | 2683 | },{}],14:[function(require,module,exports){ 2684 | 'use strict' 2685 | 2686 | var weakMap = typeof WeakMap === 'undefined' ? require('weak-map') : WeakMap 2687 | 2688 | var WebGLEWStruct = new weakMap() 2689 | 2690 | function baseName(ext_name) { 2691 | return ext_name.replace(/^[A-Z]+_/, '') 2692 | } 2693 | 2694 | function initWebGLEW(gl) { 2695 | var struct = WebGLEWStruct.get(gl) 2696 | if(struct) { 2697 | return struct 2698 | } 2699 | var extensions = {} 2700 | var supported = gl.getSupportedExtensions() 2701 | for(var i=0; i nattribs) { 2737 | throw new Error("gl-vao: Too many vertex attributes") 2738 | } 2739 | for(var i=0; i 2936 | * 2937 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 2938 | * associated documentation files (the 'Software'), to deal in the Software without restriction, 2939 | * including without limitation the rights to use, copy, modify, merge, publish, distribute, 2940 | * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 2941 | * furnished to do so, subject to the following conditions: 2942 | * 2943 | * The above copyright notice and this permission notice shall be included with all copies or 2944 | * substantial portions of the Software. 2945 | * 2946 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 2947 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2948 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 2949 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2950 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2951 | */ 2952 | 2953 | // Original WeakMap implementation by Gozala @ https://gist.github.com/1269991 2954 | // Updated and bugfixed by Raynos @ https://gist.github.com/1638059 2955 | // Expanded by Benvie @ https://github.com/Benvie/harmony-collections 2956 | 2957 | void function(global, undefined_, undefined){ 2958 | var getProps = Object.getOwnPropertyNames, 2959 | defProp = Object.defineProperty, 2960 | toSource = Function.prototype.toString, 2961 | create = Object.create, 2962 | hasOwn = Object.prototype.hasOwnProperty, 2963 | funcName = /^\n?function\s?(\w*)?_?\(/; 2964 | 2965 | 2966 | function define(object, key, value){ 2967 | if (typeof key === 'function') { 2968 | value = key; 2969 | key = nameOf(value).replace(/_$/, ''); 2970 | } 2971 | return defProp(object, key, { configurable: true, writable: true, value: value }); 2972 | } 2973 | 2974 | function nameOf(func){ 2975 | return typeof func !== 'function' 2976 | ? '' : 'name' in func 2977 | ? func.name : toSource.call(func).match(funcName)[1]; 2978 | } 2979 | 2980 | // ############ 2981 | // ### Data ### 2982 | // ############ 2983 | 2984 | var Data = (function(){ 2985 | var dataDesc = { value: { writable: true, value: undefined } }, 2986 | datalock = 'return function(k){if(k===s)return l}', 2987 | uids = create(null), 2988 | 2989 | createUID = function(){ 2990 | var key = Math.random().toString(36).slice(2); 2991 | return key in uids ? createUID() : uids[key] = key; 2992 | }, 2993 | 2994 | globalID = createUID(), 2995 | 2996 | storage = function(obj){ 2997 | if (hasOwn.call(obj, globalID)) 2998 | return obj[globalID]; 2999 | 3000 | if (!Object.isExtensible(obj)) 3001 | throw new TypeError("Object must be extensible"); 3002 | 3003 | var store = create(null); 3004 | defProp(obj, globalID, { value: store }); 3005 | return store; 3006 | }; 3007 | 3008 | // common per-object storage area made visible by patching getOwnPropertyNames' 3009 | define(Object, function getOwnPropertyNames(obj){ 3010 | var props = getProps(obj); 3011 | if (hasOwn.call(obj, globalID)) 3012 | props.splice(props.indexOf(globalID), 1); 3013 | return props; 3014 | }); 3015 | 3016 | function Data(){ 3017 | var puid = createUID(), 3018 | secret = {}; 3019 | 3020 | this.unlock = function(obj){ 3021 | var store = storage(obj); 3022 | if (hasOwn.call(store, puid)) 3023 | return store[puid](secret); 3024 | 3025 | var data = create(null, dataDesc); 3026 | defProp(store, puid, { 3027 | value: new Function('s', 'l', datalock)(secret, data) 3028 | }); 3029 | return data; 3030 | } 3031 | } 3032 | 3033 | define(Data.prototype, function get(o){ return this.unlock(o).value }); 3034 | define(Data.prototype, function set(o, v){ this.unlock(o).value = v }); 3035 | 3036 | return Data; 3037 | }()); 3038 | 3039 | 3040 | var WM = (function(data){ 3041 | var validate = function(key){ 3042 | if (key == null || typeof key !== 'object' && typeof key !== 'function') 3043 | throw new TypeError("Invalid WeakMap key"); 3044 | } 3045 | 3046 | var wrap = function(collection, value){ 3047 | var store = data.unlock(collection); 3048 | if (store.value) 3049 | throw new TypeError("Object is already a WeakMap"); 3050 | store.value = value; 3051 | } 3052 | 3053 | var unwrap = function(collection){ 3054 | var storage = data.unlock(collection).value; 3055 | if (!storage) 3056 | throw new TypeError("WeakMap is not generic"); 3057 | return storage; 3058 | } 3059 | 3060 | var initialize = function(weakmap, iterable){ 3061 | if (iterable !== null && typeof iterable === 'object' && typeof iterable.forEach === 'function') { 3062 | iterable.forEach(function(item, i){ 3063 | if (item instanceof Array && item.length === 2) 3064 | set.call(weakmap, iterable[i][0], iterable[i][1]); 3065 | }); 3066 | } 3067 | } 3068 | 3069 | 3070 | function WeakMap(iterable){ 3071 | if (this === global || this == null || this === WeakMap.prototype) 3072 | return new WeakMap(iterable); 3073 | 3074 | wrap(this, new Data); 3075 | initialize(this, iterable); 3076 | } 3077 | 3078 | function get(key){ 3079 | validate(key); 3080 | var value = unwrap(this).get(key); 3081 | return value === undefined_ ? undefined : value; 3082 | } 3083 | 3084 | function set(key, value){ 3085 | validate(key); 3086 | // store a token for explicit undefined so that "has" works correctly 3087 | unwrap(this).set(key, value === undefined ? undefined_ : value); 3088 | } 3089 | 3090 | function has(key){ 3091 | validate(key); 3092 | return unwrap(this).get(key) !== undefined; 3093 | } 3094 | 3095 | function delete_(key){ 3096 | validate(key); 3097 | var data = unwrap(this), 3098 | had = data.get(key) !== undefined; 3099 | data.set(key, undefined); 3100 | return had; 3101 | } 3102 | 3103 | function toString(){ 3104 | unwrap(this); 3105 | return '[object WeakMap]'; 3106 | } 3107 | 3108 | try { 3109 | var src = ('return '+delete_).replace('e_', '\\u0065'), 3110 | del = new Function('unwrap', 'validate', src)(unwrap, validate); 3111 | } catch (e) { 3112 | var del = delete_; 3113 | } 3114 | 3115 | var src = (''+Object).split('Object'); 3116 | var stringifier = function toString(){ 3117 | return src[0] + nameOf(this) + src[1]; 3118 | }; 3119 | 3120 | define(stringifier, stringifier); 3121 | 3122 | var prep = { __proto__: [] } instanceof Array 3123 | ? function(f){ f.__proto__ = stringifier } 3124 | : function(f){ define(f, stringifier) }; 3125 | 3126 | prep(WeakMap); 3127 | 3128 | [toString, get, set, has, del].forEach(function(method){ 3129 | define(WeakMap.prototype, method); 3130 | prep(method); 3131 | }); 3132 | 3133 | return WeakMap; 3134 | }(new Data)); 3135 | 3136 | var defaultCreator = Object.create 3137 | ? function(){ return Object.create(null) } 3138 | : function(){ return {} }; 3139 | 3140 | function createStorage(creator){ 3141 | var weakmap = new WM; 3142 | creator || (creator = defaultCreator); 3143 | 3144 | function storage(object, value){ 3145 | if (value || arguments.length === 2) { 3146 | weakmap.set(object, value); 3147 | } else { 3148 | value = weakmap.get(object); 3149 | if (value === undefined) { 3150 | value = creator(object); 3151 | weakmap.set(object, value); 3152 | } 3153 | } 3154 | return value; 3155 | } 3156 | 3157 | return storage; 3158 | } 3159 | 3160 | 3161 | if (typeof module !== 'undefined') { 3162 | module.exports = WM; 3163 | } else if (typeof exports !== 'undefined') { 3164 | exports.WeakMap = WM; 3165 | } else if (!('WeakMap' in global)) { 3166 | global.WeakMap = WM; 3167 | } 3168 | 3169 | WM.createStorage = createStorage; 3170 | if (global.WeakMap) 3171 | global.WeakMap.createStorage = createStorage; 3172 | }((0, eval)('this')); 3173 | 3174 | },{}],22:[function(require,module,exports){ 3175 | 'use strict' 3176 | 3177 | var weakMap = typeof WeakMap === 'undefined' ? require('weakmap') : WeakMap 3178 | var createBuffer = require('gl-buffer') 3179 | var createVAO = require('gl-vao') 3180 | 3181 | var TriangleCache = new weakMap() 3182 | 3183 | function createABigTriangle(gl) { 3184 | 3185 | var triangleVAO = TriangleCache.get(gl) 3186 | if(!triangleVAO) { 3187 | var buf = createBuffer(gl, new Float32Array([-1, -1, -1, 4, 4, -1])) 3188 | triangleVAO = createVAO(gl, [ 3189 | { buffer: buf, 3190 | type: gl.FLOAT, 3191 | size: 2 3192 | } 3193 | ]) 3194 | TriangleCache.set(gl, triangleVAO) 3195 | } 3196 | triangleVAO.bind() 3197 | gl.drawArrays(gl.TRIANGLES, 0, 3) 3198 | triangleVAO.unbind() 3199 | } 3200 | 3201 | module.exports = createABigTriangle 3202 | },{"gl-buffer":2,"gl-vao":20,"weakmap":21}],23:[function(require,module,exports){ 3203 | /*! 3204 | * The buffer module from node.js, for the browser. 3205 | * 3206 | * @author Feross Aboukhadijeh 3207 | * @license MIT 3208 | */ 3209 | 3210 | var base64 = require('base64-js') 3211 | var ieee754 = require('ieee754') 3212 | var isArray = require('is-array') 3213 | 3214 | exports.Buffer = Buffer 3215 | exports.SlowBuffer = SlowBuffer 3216 | exports.INSPECT_MAX_BYTES = 50 3217 | Buffer.poolSize = 8192 // not used by this implementation 3218 | 3219 | var kMaxLength = 0x3fffffff 3220 | var rootParent = {} 3221 | 3222 | /** 3223 | * If `Buffer.TYPED_ARRAY_SUPPORT`: 3224 | * === true Use Uint8Array implementation (fastest) 3225 | * === false Use Object implementation (most compatible, even IE6) 3226 | * 3227 | * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, 3228 | * Opera 11.6+, iOS 4.2+. 3229 | * 3230 | * Note: 3231 | * 3232 | * - Implementation must support adding new properties to `Uint8Array` instances. 3233 | * Firefox 4-29 lacked support, fixed in Firefox 30+. 3234 | * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. 3235 | * 3236 | * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. 3237 | * 3238 | * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of 3239 | * incorrect length in some situations. 3240 | * 3241 | * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will 3242 | * get the Object implementation, which is slower but will work correctly. 3243 | */ 3244 | Buffer.TYPED_ARRAY_SUPPORT = (function () { 3245 | try { 3246 | var buf = new ArrayBuffer(0) 3247 | var arr = new Uint8Array(buf) 3248 | arr.foo = function () { return 42 } 3249 | return arr.foo() === 42 && // typed array instances can be augmented 3250 | typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` 3251 | new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` 3252 | } catch (e) { 3253 | return false 3254 | } 3255 | })() 3256 | 3257 | /** 3258 | * Class: Buffer 3259 | * ============= 3260 | * 3261 | * The Buffer constructor returns instances of `Uint8Array` that are augmented 3262 | * with function properties for all the node `Buffer` API functions. We use 3263 | * `Uint8Array` so that square bracket notation works as expected -- it returns 3264 | * a single octet. 3265 | * 3266 | * By augmenting the instances, we can avoid modifying the `Uint8Array` 3267 | * prototype. 3268 | */ 3269 | function Buffer (subject, encoding) { 3270 | var self = this 3271 | if (!(self instanceof Buffer)) return new Buffer(subject, encoding) 3272 | 3273 | var type = typeof subject 3274 | var length 3275 | 3276 | if (type === 'number') { 3277 | length = +subject 3278 | } else if (type === 'string') { 3279 | length = Buffer.byteLength(subject, encoding) 3280 | } else if (type === 'object' && subject !== null) { 3281 | // assume object is array-like 3282 | if (subject.type === 'Buffer' && isArray(subject.data)) subject = subject.data 3283 | length = +subject.length 3284 | } else { 3285 | throw new TypeError('must start with number, buffer, array or string') 3286 | } 3287 | 3288 | if (length > kMaxLength) { 3289 | throw new RangeError('Attempt to allocate Buffer larger than maximum size: 0x' + 3290 | kMaxLength.toString(16) + ' bytes') 3291 | } 3292 | 3293 | if (length < 0) length = 0 3294 | else length >>>= 0 // coerce to uint32 3295 | 3296 | if (Buffer.TYPED_ARRAY_SUPPORT) { 3297 | // Preferred: Return an augmented `Uint8Array` instance for best performance 3298 | self = Buffer._augment(new Uint8Array(length)) // eslint-disable-line consistent-this 3299 | } else { 3300 | // Fallback: Return THIS instance of Buffer (created by `new`) 3301 | self.length = length 3302 | self._isBuffer = true 3303 | } 3304 | 3305 | var i 3306 | if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { 3307 | // Speed optimization -- use set if we're copying from a typed array 3308 | self._set(subject) 3309 | } else if (isArrayish(subject)) { 3310 | // Treat array-ish objects as a byte array 3311 | if (Buffer.isBuffer(subject)) { 3312 | for (i = 0; i < length; i++) { 3313 | self[i] = subject.readUInt8(i) 3314 | } 3315 | } else { 3316 | for (i = 0; i < length; i++) { 3317 | self[i] = ((subject[i] % 256) + 256) % 256 3318 | } 3319 | } 3320 | } else if (type === 'string') { 3321 | self.write(subject, 0, encoding) 3322 | } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT) { 3323 | for (i = 0; i < length; i++) { 3324 | self[i] = 0 3325 | } 3326 | } 3327 | 3328 | if (length > 0 && length <= Buffer.poolSize) self.parent = rootParent 3329 | 3330 | return self 3331 | } 3332 | 3333 | function SlowBuffer (subject, encoding) { 3334 | if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) 3335 | 3336 | var buf = new Buffer(subject, encoding) 3337 | delete buf.parent 3338 | return buf 3339 | } 3340 | 3341 | Buffer.isBuffer = function isBuffer (b) { 3342 | return !!(b != null && b._isBuffer) 3343 | } 3344 | 3345 | Buffer.compare = function compare (a, b) { 3346 | if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { 3347 | throw new TypeError('Arguments must be Buffers') 3348 | } 3349 | 3350 | if (a === b) return 0 3351 | 3352 | var x = a.length 3353 | var y = b.length 3354 | for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} 3355 | if (i !== len) { 3356 | x = a[i] 3357 | y = b[i] 3358 | } 3359 | if (x < y) return -1 3360 | if (y < x) return 1 3361 | return 0 3362 | } 3363 | 3364 | Buffer.isEncoding = function isEncoding (encoding) { 3365 | switch (String(encoding).toLowerCase()) { 3366 | case 'hex': 3367 | case 'utf8': 3368 | case 'utf-8': 3369 | case 'ascii': 3370 | case 'binary': 3371 | case 'base64': 3372 | case 'raw': 3373 | case 'ucs2': 3374 | case 'ucs-2': 3375 | case 'utf16le': 3376 | case 'utf-16le': 3377 | return true 3378 | default: 3379 | return false 3380 | } 3381 | } 3382 | 3383 | Buffer.concat = function concat (list, totalLength) { 3384 | if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') 3385 | 3386 | if (list.length === 0) { 3387 | return new Buffer(0) 3388 | } else if (list.length === 1) { 3389 | return list[0] 3390 | } 3391 | 3392 | var i 3393 | if (totalLength === undefined) { 3394 | totalLength = 0 3395 | for (i = 0; i < list.length; i++) { 3396 | totalLength += list[i].length 3397 | } 3398 | } 3399 | 3400 | var buf = new Buffer(totalLength) 3401 | var pos = 0 3402 | for (i = 0; i < list.length; i++) { 3403 | var item = list[i] 3404 | item.copy(buf, pos) 3405 | pos += item.length 3406 | } 3407 | return buf 3408 | } 3409 | 3410 | Buffer.byteLength = function byteLength (str, encoding) { 3411 | var ret 3412 | str = str + '' 3413 | switch (encoding || 'utf8') { 3414 | case 'ascii': 3415 | case 'binary': 3416 | case 'raw': 3417 | ret = str.length 3418 | break 3419 | case 'ucs2': 3420 | case 'ucs-2': 3421 | case 'utf16le': 3422 | case 'utf-16le': 3423 | ret = str.length * 2 3424 | break 3425 | case 'hex': 3426 | ret = str.length >>> 1 3427 | break 3428 | case 'utf8': 3429 | case 'utf-8': 3430 | ret = utf8ToBytes(str).length 3431 | break 3432 | case 'base64': 3433 | ret = base64ToBytes(str).length 3434 | break 3435 | default: 3436 | ret = str.length 3437 | } 3438 | return ret 3439 | } 3440 | 3441 | // pre-set for values that may exist in the future 3442 | Buffer.prototype.length = undefined 3443 | Buffer.prototype.parent = undefined 3444 | 3445 | // toString(encoding, start=0, end=buffer.length) 3446 | Buffer.prototype.toString = function toString (encoding, start, end) { 3447 | var loweredCase = false 3448 | 3449 | start = start >>> 0 3450 | end = end === undefined || end === Infinity ? this.length : end >>> 0 3451 | 3452 | if (!encoding) encoding = 'utf8' 3453 | if (start < 0) start = 0 3454 | if (end > this.length) end = this.length 3455 | if (end <= start) return '' 3456 | 3457 | while (true) { 3458 | switch (encoding) { 3459 | case 'hex': 3460 | return hexSlice(this, start, end) 3461 | 3462 | case 'utf8': 3463 | case 'utf-8': 3464 | return utf8Slice(this, start, end) 3465 | 3466 | case 'ascii': 3467 | return asciiSlice(this, start, end) 3468 | 3469 | case 'binary': 3470 | return binarySlice(this, start, end) 3471 | 3472 | case 'base64': 3473 | return base64Slice(this, start, end) 3474 | 3475 | case 'ucs2': 3476 | case 'ucs-2': 3477 | case 'utf16le': 3478 | case 'utf-16le': 3479 | return utf16leSlice(this, start, end) 3480 | 3481 | default: 3482 | if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) 3483 | encoding = (encoding + '').toLowerCase() 3484 | loweredCase = true 3485 | } 3486 | } 3487 | } 3488 | 3489 | Buffer.prototype.equals = function equals (b) { 3490 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 3491 | if (this === b) return true 3492 | return Buffer.compare(this, b) === 0 3493 | } 3494 | 3495 | Buffer.prototype.inspect = function inspect () { 3496 | var str = '' 3497 | var max = exports.INSPECT_MAX_BYTES 3498 | if (this.length > 0) { 3499 | str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') 3500 | if (this.length > max) str += ' ... ' 3501 | } 3502 | return '' 3503 | } 3504 | 3505 | Buffer.prototype.compare = function compare (b) { 3506 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 3507 | if (this === b) return 0 3508 | return Buffer.compare(this, b) 3509 | } 3510 | 3511 | Buffer.prototype.indexOf = function indexOf (val, byteOffset) { 3512 | if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff 3513 | else if (byteOffset < -0x80000000) byteOffset = -0x80000000 3514 | byteOffset >>= 0 3515 | 3516 | if (this.length === 0) return -1 3517 | if (byteOffset >= this.length) return -1 3518 | 3519 | // Negative offsets start from the end of the buffer 3520 | if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) 3521 | 3522 | if (typeof val === 'string') { 3523 | if (val.length === 0) return -1 // special case: looking for empty string always fails 3524 | return String.prototype.indexOf.call(this, val, byteOffset) 3525 | } 3526 | if (Buffer.isBuffer(val)) { 3527 | return arrayIndexOf(this, val, byteOffset) 3528 | } 3529 | if (typeof val === 'number') { 3530 | if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { 3531 | return Uint8Array.prototype.indexOf.call(this, val, byteOffset) 3532 | } 3533 | return arrayIndexOf(this, [ val ], byteOffset) 3534 | } 3535 | 3536 | function arrayIndexOf (arr, val, byteOffset) { 3537 | var foundIndex = -1 3538 | for (var i = 0; byteOffset + i < arr.length; i++) { 3539 | if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { 3540 | if (foundIndex === -1) foundIndex = i 3541 | if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex 3542 | } else { 3543 | foundIndex = -1 3544 | } 3545 | } 3546 | return -1 3547 | } 3548 | 3549 | throw new TypeError('val must be string, number or Buffer') 3550 | } 3551 | 3552 | // `get` will be removed in Node 0.13+ 3553 | Buffer.prototype.get = function get (offset) { 3554 | console.log('.get() is deprecated. Access using array indexes instead.') 3555 | return this.readUInt8(offset) 3556 | } 3557 | 3558 | // `set` will be removed in Node 0.13+ 3559 | Buffer.prototype.set = function set (v, offset) { 3560 | console.log('.set() is deprecated. Access using array indexes instead.') 3561 | return this.writeUInt8(v, offset) 3562 | } 3563 | 3564 | function hexWrite (buf, string, offset, length) { 3565 | offset = Number(offset) || 0 3566 | var remaining = buf.length - offset 3567 | if (!length) { 3568 | length = remaining 3569 | } else { 3570 | length = Number(length) 3571 | if (length > remaining) { 3572 | length = remaining 3573 | } 3574 | } 3575 | 3576 | // must be an even number of digits 3577 | var strLen = string.length 3578 | if (strLen % 2 !== 0) throw new Error('Invalid hex string') 3579 | 3580 | if (length > strLen / 2) { 3581 | length = strLen / 2 3582 | } 3583 | for (var i = 0; i < length; i++) { 3584 | var parsed = parseInt(string.substr(i * 2, 2), 16) 3585 | if (isNaN(parsed)) throw new Error('Invalid hex string') 3586 | buf[offset + i] = parsed 3587 | } 3588 | return i 3589 | } 3590 | 3591 | function utf8Write (buf, string, offset, length) { 3592 | var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) 3593 | return charsWritten 3594 | } 3595 | 3596 | function asciiWrite (buf, string, offset, length) { 3597 | var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) 3598 | return charsWritten 3599 | } 3600 | 3601 | function binaryWrite (buf, string, offset, length) { 3602 | return asciiWrite(buf, string, offset, length) 3603 | } 3604 | 3605 | function base64Write (buf, string, offset, length) { 3606 | var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) 3607 | return charsWritten 3608 | } 3609 | 3610 | function utf16leWrite (buf, string, offset, length) { 3611 | var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) 3612 | return charsWritten 3613 | } 3614 | 3615 | Buffer.prototype.write = function write (string, offset, length, encoding) { 3616 | // Support both (string, offset, length, encoding) 3617 | // and the legacy (string, encoding, offset, length) 3618 | if (isFinite(offset)) { 3619 | if (!isFinite(length)) { 3620 | encoding = length 3621 | length = undefined 3622 | } 3623 | } else { // legacy 3624 | var swap = encoding 3625 | encoding = offset 3626 | offset = length 3627 | length = swap 3628 | } 3629 | 3630 | offset = Number(offset) || 0 3631 | 3632 | if (length < 0 || offset < 0 || offset > this.length) { 3633 | throw new RangeError('attempt to write outside buffer bounds') 3634 | } 3635 | 3636 | var remaining = this.length - offset 3637 | if (!length) { 3638 | length = remaining 3639 | } else { 3640 | length = Number(length) 3641 | if (length > remaining) { 3642 | length = remaining 3643 | } 3644 | } 3645 | encoding = String(encoding || 'utf8').toLowerCase() 3646 | 3647 | var ret 3648 | switch (encoding) { 3649 | case 'hex': 3650 | ret = hexWrite(this, string, offset, length) 3651 | break 3652 | case 'utf8': 3653 | case 'utf-8': 3654 | ret = utf8Write(this, string, offset, length) 3655 | break 3656 | case 'ascii': 3657 | ret = asciiWrite(this, string, offset, length) 3658 | break 3659 | case 'binary': 3660 | ret = binaryWrite(this, string, offset, length) 3661 | break 3662 | case 'base64': 3663 | ret = base64Write(this, string, offset, length) 3664 | break 3665 | case 'ucs2': 3666 | case 'ucs-2': 3667 | case 'utf16le': 3668 | case 'utf-16le': 3669 | ret = utf16leWrite(this, string, offset, length) 3670 | break 3671 | default: 3672 | throw new TypeError('Unknown encoding: ' + encoding) 3673 | } 3674 | return ret 3675 | } 3676 | 3677 | Buffer.prototype.toJSON = function toJSON () { 3678 | return { 3679 | type: 'Buffer', 3680 | data: Array.prototype.slice.call(this._arr || this, 0) 3681 | } 3682 | } 3683 | 3684 | function base64Slice (buf, start, end) { 3685 | if (start === 0 && end === buf.length) { 3686 | return base64.fromByteArray(buf) 3687 | } else { 3688 | return base64.fromByteArray(buf.slice(start, end)) 3689 | } 3690 | } 3691 | 3692 | function utf8Slice (buf, start, end) { 3693 | var res = '' 3694 | var tmp = '' 3695 | end = Math.min(buf.length, end) 3696 | 3697 | for (var i = start; i < end; i++) { 3698 | if (buf[i] <= 0x7F) { 3699 | res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) 3700 | tmp = '' 3701 | } else { 3702 | tmp += '%' + buf[i].toString(16) 3703 | } 3704 | } 3705 | 3706 | return res + decodeUtf8Char(tmp) 3707 | } 3708 | 3709 | function asciiSlice (buf, start, end) { 3710 | var ret = '' 3711 | end = Math.min(buf.length, end) 3712 | 3713 | for (var i = start; i < end; i++) { 3714 | ret += String.fromCharCode(buf[i] & 0x7F) 3715 | } 3716 | return ret 3717 | } 3718 | 3719 | function binarySlice (buf, start, end) { 3720 | var ret = '' 3721 | end = Math.min(buf.length, end) 3722 | 3723 | for (var i = start; i < end; i++) { 3724 | ret += String.fromCharCode(buf[i]) 3725 | } 3726 | return ret 3727 | } 3728 | 3729 | function hexSlice (buf, start, end) { 3730 | var len = buf.length 3731 | 3732 | if (!start || start < 0) start = 0 3733 | if (!end || end < 0 || end > len) end = len 3734 | 3735 | var out = '' 3736 | for (var i = start; i < end; i++) { 3737 | out += toHex(buf[i]) 3738 | } 3739 | return out 3740 | } 3741 | 3742 | function utf16leSlice (buf, start, end) { 3743 | var bytes = buf.slice(start, end) 3744 | var res = '' 3745 | for (var i = 0; i < bytes.length; i += 2) { 3746 | res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) 3747 | } 3748 | return res 3749 | } 3750 | 3751 | Buffer.prototype.slice = function slice (start, end) { 3752 | var len = this.length 3753 | start = ~~start 3754 | end = end === undefined ? len : ~~end 3755 | 3756 | if (start < 0) { 3757 | start += len 3758 | if (start < 0) start = 0 3759 | } else if (start > len) { 3760 | start = len 3761 | } 3762 | 3763 | if (end < 0) { 3764 | end += len 3765 | if (end < 0) end = 0 3766 | } else if (end > len) { 3767 | end = len 3768 | } 3769 | 3770 | if (end < start) end = start 3771 | 3772 | var newBuf 3773 | if (Buffer.TYPED_ARRAY_SUPPORT) { 3774 | newBuf = Buffer._augment(this.subarray(start, end)) 3775 | } else { 3776 | var sliceLen = end - start 3777 | newBuf = new Buffer(sliceLen, undefined) 3778 | for (var i = 0; i < sliceLen; i++) { 3779 | newBuf[i] = this[i + start] 3780 | } 3781 | } 3782 | 3783 | if (newBuf.length) newBuf.parent = this.parent || this 3784 | 3785 | return newBuf 3786 | } 3787 | 3788 | /* 3789 | * Need to make sure that buffer isn't trying to write out of bounds. 3790 | */ 3791 | function checkOffset (offset, ext, length) { 3792 | if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') 3793 | if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') 3794 | } 3795 | 3796 | Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { 3797 | offset = offset >>> 0 3798 | byteLength = byteLength >>> 0 3799 | if (!noAssert) checkOffset(offset, byteLength, this.length) 3800 | 3801 | var val = this[offset] 3802 | var mul = 1 3803 | var i = 0 3804 | while (++i < byteLength && (mul *= 0x100)) { 3805 | val += this[offset + i] * mul 3806 | } 3807 | 3808 | return val 3809 | } 3810 | 3811 | Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { 3812 | offset = offset >>> 0 3813 | byteLength = byteLength >>> 0 3814 | if (!noAssert) { 3815 | checkOffset(offset, byteLength, this.length) 3816 | } 3817 | 3818 | var val = this[offset + --byteLength] 3819 | var mul = 1 3820 | while (byteLength > 0 && (mul *= 0x100)) { 3821 | val += this[offset + --byteLength] * mul 3822 | } 3823 | 3824 | return val 3825 | } 3826 | 3827 | Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { 3828 | if (!noAssert) checkOffset(offset, 1, this.length) 3829 | return this[offset] 3830 | } 3831 | 3832 | Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { 3833 | if (!noAssert) checkOffset(offset, 2, this.length) 3834 | return this[offset] | (this[offset + 1] << 8) 3835 | } 3836 | 3837 | Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { 3838 | if (!noAssert) checkOffset(offset, 2, this.length) 3839 | return (this[offset] << 8) | this[offset + 1] 3840 | } 3841 | 3842 | Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { 3843 | if (!noAssert) checkOffset(offset, 4, this.length) 3844 | 3845 | return ((this[offset]) | 3846 | (this[offset + 1] << 8) | 3847 | (this[offset + 2] << 16)) + 3848 | (this[offset + 3] * 0x1000000) 3849 | } 3850 | 3851 | Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { 3852 | if (!noAssert) checkOffset(offset, 4, this.length) 3853 | 3854 | return (this[offset] * 0x1000000) + 3855 | ((this[offset + 1] << 16) | 3856 | (this[offset + 2] << 8) | 3857 | this[offset + 3]) 3858 | } 3859 | 3860 | Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { 3861 | offset = offset >>> 0 3862 | byteLength = byteLength >>> 0 3863 | if (!noAssert) checkOffset(offset, byteLength, this.length) 3864 | 3865 | var val = this[offset] 3866 | var mul = 1 3867 | var i = 0 3868 | while (++i < byteLength && (mul *= 0x100)) { 3869 | val += this[offset + i] * mul 3870 | } 3871 | mul *= 0x80 3872 | 3873 | if (val >= mul) val -= Math.pow(2, 8 * byteLength) 3874 | 3875 | return val 3876 | } 3877 | 3878 | Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { 3879 | offset = offset >>> 0 3880 | byteLength = byteLength >>> 0 3881 | if (!noAssert) checkOffset(offset, byteLength, this.length) 3882 | 3883 | var i = byteLength 3884 | var mul = 1 3885 | var val = this[offset + --i] 3886 | while (i > 0 && (mul *= 0x100)) { 3887 | val += this[offset + --i] * mul 3888 | } 3889 | mul *= 0x80 3890 | 3891 | if (val >= mul) val -= Math.pow(2, 8 * byteLength) 3892 | 3893 | return val 3894 | } 3895 | 3896 | Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { 3897 | if (!noAssert) checkOffset(offset, 1, this.length) 3898 | if (!(this[offset] & 0x80)) return (this[offset]) 3899 | return ((0xff - this[offset] + 1) * -1) 3900 | } 3901 | 3902 | Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { 3903 | if (!noAssert) checkOffset(offset, 2, this.length) 3904 | var val = this[offset] | (this[offset + 1] << 8) 3905 | return (val & 0x8000) ? val | 0xFFFF0000 : val 3906 | } 3907 | 3908 | Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { 3909 | if (!noAssert) checkOffset(offset, 2, this.length) 3910 | var val = this[offset + 1] | (this[offset] << 8) 3911 | return (val & 0x8000) ? val | 0xFFFF0000 : val 3912 | } 3913 | 3914 | Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { 3915 | if (!noAssert) checkOffset(offset, 4, this.length) 3916 | 3917 | return (this[offset]) | 3918 | (this[offset + 1] << 8) | 3919 | (this[offset + 2] << 16) | 3920 | (this[offset + 3] << 24) 3921 | } 3922 | 3923 | Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { 3924 | if (!noAssert) checkOffset(offset, 4, this.length) 3925 | 3926 | return (this[offset] << 24) | 3927 | (this[offset + 1] << 16) | 3928 | (this[offset + 2] << 8) | 3929 | (this[offset + 3]) 3930 | } 3931 | 3932 | Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { 3933 | if (!noAssert) checkOffset(offset, 4, this.length) 3934 | return ieee754.read(this, offset, true, 23, 4) 3935 | } 3936 | 3937 | Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { 3938 | if (!noAssert) checkOffset(offset, 4, this.length) 3939 | return ieee754.read(this, offset, false, 23, 4) 3940 | } 3941 | 3942 | Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { 3943 | if (!noAssert) checkOffset(offset, 8, this.length) 3944 | return ieee754.read(this, offset, true, 52, 8) 3945 | } 3946 | 3947 | Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { 3948 | if (!noAssert) checkOffset(offset, 8, this.length) 3949 | return ieee754.read(this, offset, false, 52, 8) 3950 | } 3951 | 3952 | function checkInt (buf, value, offset, ext, max, min) { 3953 | if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') 3954 | if (value > max || value < min) throw new RangeError('value is out of bounds') 3955 | if (offset + ext > buf.length) throw new RangeError('index out of range') 3956 | } 3957 | 3958 | Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { 3959 | value = +value 3960 | offset = offset >>> 0 3961 | byteLength = byteLength >>> 0 3962 | if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) 3963 | 3964 | var mul = 1 3965 | var i = 0 3966 | this[offset] = value & 0xFF 3967 | while (++i < byteLength && (mul *= 0x100)) { 3968 | this[offset + i] = (value / mul) >>> 0 & 0xFF 3969 | } 3970 | 3971 | return offset + byteLength 3972 | } 3973 | 3974 | Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { 3975 | value = +value 3976 | offset = offset >>> 0 3977 | byteLength = byteLength >>> 0 3978 | if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) 3979 | 3980 | var i = byteLength - 1 3981 | var mul = 1 3982 | this[offset + i] = value & 0xFF 3983 | while (--i >= 0 && (mul *= 0x100)) { 3984 | this[offset + i] = (value / mul) >>> 0 & 0xFF 3985 | } 3986 | 3987 | return offset + byteLength 3988 | } 3989 | 3990 | Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { 3991 | value = +value 3992 | offset = offset >>> 0 3993 | if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) 3994 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 3995 | this[offset] = value 3996 | return offset + 1 3997 | } 3998 | 3999 | function objectWriteUInt16 (buf, value, offset, littleEndian) { 4000 | if (value < 0) value = 0xffff + value + 1 4001 | for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { 4002 | buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> 4003 | (littleEndian ? i : 1 - i) * 8 4004 | } 4005 | } 4006 | 4007 | Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { 4008 | value = +value 4009 | offset = offset >>> 0 4010 | if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 4011 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4012 | this[offset] = value 4013 | this[offset + 1] = (value >>> 8) 4014 | } else { 4015 | objectWriteUInt16(this, value, offset, true) 4016 | } 4017 | return offset + 2 4018 | } 4019 | 4020 | Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { 4021 | value = +value 4022 | offset = offset >>> 0 4023 | if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) 4024 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4025 | this[offset] = (value >>> 8) 4026 | this[offset + 1] = value 4027 | } else { 4028 | objectWriteUInt16(this, value, offset, false) 4029 | } 4030 | return offset + 2 4031 | } 4032 | 4033 | function objectWriteUInt32 (buf, value, offset, littleEndian) { 4034 | if (value < 0) value = 0xffffffff + value + 1 4035 | for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { 4036 | buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff 4037 | } 4038 | } 4039 | 4040 | Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { 4041 | value = +value 4042 | offset = offset >>> 0 4043 | if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 4044 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4045 | this[offset + 3] = (value >>> 24) 4046 | this[offset + 2] = (value >>> 16) 4047 | this[offset + 1] = (value >>> 8) 4048 | this[offset] = value 4049 | } else { 4050 | objectWriteUInt32(this, value, offset, true) 4051 | } 4052 | return offset + 4 4053 | } 4054 | 4055 | Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { 4056 | value = +value 4057 | offset = offset >>> 0 4058 | if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) 4059 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4060 | this[offset] = (value >>> 24) 4061 | this[offset + 1] = (value >>> 16) 4062 | this[offset + 2] = (value >>> 8) 4063 | this[offset + 3] = value 4064 | } else { 4065 | objectWriteUInt32(this, value, offset, false) 4066 | } 4067 | return offset + 4 4068 | } 4069 | 4070 | Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { 4071 | value = +value 4072 | offset = offset >>> 0 4073 | if (!noAssert) { 4074 | checkInt( 4075 | this, value, offset, byteLength, 4076 | Math.pow(2, 8 * byteLength - 1) - 1, 4077 | -Math.pow(2, 8 * byteLength - 1) 4078 | ) 4079 | } 4080 | 4081 | var i = 0 4082 | var mul = 1 4083 | var sub = value < 0 ? 1 : 0 4084 | this[offset] = value & 0xFF 4085 | while (++i < byteLength && (mul *= 0x100)) { 4086 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 4087 | } 4088 | 4089 | return offset + byteLength 4090 | } 4091 | 4092 | Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { 4093 | value = +value 4094 | offset = offset >>> 0 4095 | if (!noAssert) { 4096 | checkInt( 4097 | this, value, offset, byteLength, 4098 | Math.pow(2, 8 * byteLength - 1) - 1, 4099 | -Math.pow(2, 8 * byteLength - 1) 4100 | ) 4101 | } 4102 | 4103 | var i = byteLength - 1 4104 | var mul = 1 4105 | var sub = value < 0 ? 1 : 0 4106 | this[offset + i] = value & 0xFF 4107 | while (--i >= 0 && (mul *= 0x100)) { 4108 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 4109 | } 4110 | 4111 | return offset + byteLength 4112 | } 4113 | 4114 | Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { 4115 | value = +value 4116 | offset = offset >>> 0 4117 | if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) 4118 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 4119 | if (value < 0) value = 0xff + value + 1 4120 | this[offset] = value 4121 | return offset + 1 4122 | } 4123 | 4124 | Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { 4125 | value = +value 4126 | offset = offset >>> 0 4127 | if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 4128 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4129 | this[offset] = value 4130 | this[offset + 1] = (value >>> 8) 4131 | } else { 4132 | objectWriteUInt16(this, value, offset, true) 4133 | } 4134 | return offset + 2 4135 | } 4136 | 4137 | Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { 4138 | value = +value 4139 | offset = offset >>> 0 4140 | if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) 4141 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4142 | this[offset] = (value >>> 8) 4143 | this[offset + 1] = value 4144 | } else { 4145 | objectWriteUInt16(this, value, offset, false) 4146 | } 4147 | return offset + 2 4148 | } 4149 | 4150 | Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { 4151 | value = +value 4152 | offset = offset >>> 0 4153 | if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 4154 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4155 | this[offset] = value 4156 | this[offset + 1] = (value >>> 8) 4157 | this[offset + 2] = (value >>> 16) 4158 | this[offset + 3] = (value >>> 24) 4159 | } else { 4160 | objectWriteUInt32(this, value, offset, true) 4161 | } 4162 | return offset + 4 4163 | } 4164 | 4165 | Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { 4166 | value = +value 4167 | offset = offset >>> 0 4168 | if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 4169 | if (value < 0) value = 0xffffffff + value + 1 4170 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4171 | this[offset] = (value >>> 24) 4172 | this[offset + 1] = (value >>> 16) 4173 | this[offset + 2] = (value >>> 8) 4174 | this[offset + 3] = value 4175 | } else { 4176 | objectWriteUInt32(this, value, offset, false) 4177 | } 4178 | return offset + 4 4179 | } 4180 | 4181 | function checkIEEE754 (buf, value, offset, ext, max, min) { 4182 | if (value > max || value < min) throw new RangeError('value is out of bounds') 4183 | if (offset + ext > buf.length) throw new RangeError('index out of range') 4184 | if (offset < 0) throw new RangeError('index out of range') 4185 | } 4186 | 4187 | function writeFloat (buf, value, offset, littleEndian, noAssert) { 4188 | if (!noAssert) { 4189 | checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) 4190 | } 4191 | ieee754.write(buf, value, offset, littleEndian, 23, 4) 4192 | return offset + 4 4193 | } 4194 | 4195 | Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { 4196 | return writeFloat(this, value, offset, true, noAssert) 4197 | } 4198 | 4199 | Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { 4200 | return writeFloat(this, value, offset, false, noAssert) 4201 | } 4202 | 4203 | function writeDouble (buf, value, offset, littleEndian, noAssert) { 4204 | if (!noAssert) { 4205 | checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) 4206 | } 4207 | ieee754.write(buf, value, offset, littleEndian, 52, 8) 4208 | return offset + 8 4209 | } 4210 | 4211 | Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { 4212 | return writeDouble(this, value, offset, true, noAssert) 4213 | } 4214 | 4215 | Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { 4216 | return writeDouble(this, value, offset, false, noAssert) 4217 | } 4218 | 4219 | // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) 4220 | Buffer.prototype.copy = function copy (target, target_start, start, end) { 4221 | var self = this // source 4222 | 4223 | if (!start) start = 0 4224 | if (!end && end !== 0) end = this.length 4225 | if (target_start >= target.length) target_start = target.length 4226 | if (!target_start) target_start = 0 4227 | if (end > 0 && end < start) end = start 4228 | 4229 | // Copy 0 bytes; we're done 4230 | if (end === start) return 0 4231 | if (target.length === 0 || self.length === 0) return 0 4232 | 4233 | // Fatal error conditions 4234 | if (target_start < 0) { 4235 | throw new RangeError('targetStart out of bounds') 4236 | } 4237 | if (start < 0 || start >= self.length) throw new RangeError('sourceStart out of bounds') 4238 | if (end < 0) throw new RangeError('sourceEnd out of bounds') 4239 | 4240 | // Are we oob? 4241 | if (end > this.length) end = this.length 4242 | if (target.length - target_start < end - start) { 4243 | end = target.length - target_start + start 4244 | } 4245 | 4246 | var len = end - start 4247 | 4248 | if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { 4249 | for (var i = 0; i < len; i++) { 4250 | target[i + target_start] = this[i + start] 4251 | } 4252 | } else { 4253 | target._set(this.subarray(start, start + len), target_start) 4254 | } 4255 | 4256 | return len 4257 | } 4258 | 4259 | // fill(value, start=0, end=buffer.length) 4260 | Buffer.prototype.fill = function fill (value, start, end) { 4261 | if (!value) value = 0 4262 | if (!start) start = 0 4263 | if (!end) end = this.length 4264 | 4265 | if (end < start) throw new RangeError('end < start') 4266 | 4267 | // Fill 0 bytes; we're done 4268 | if (end === start) return 4269 | if (this.length === 0) return 4270 | 4271 | if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') 4272 | if (end < 0 || end > this.length) throw new RangeError('end out of bounds') 4273 | 4274 | var i 4275 | if (typeof value === 'number') { 4276 | for (i = start; i < end; i++) { 4277 | this[i] = value 4278 | } 4279 | } else { 4280 | var bytes = utf8ToBytes(value.toString()) 4281 | var len = bytes.length 4282 | for (i = start; i < end; i++) { 4283 | this[i] = bytes[i % len] 4284 | } 4285 | } 4286 | 4287 | return this 4288 | } 4289 | 4290 | /** 4291 | * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. 4292 | * Added in Node 0.12. Only available in browsers that support ArrayBuffer. 4293 | */ 4294 | Buffer.prototype.toArrayBuffer = function toArrayBuffer () { 4295 | if (typeof Uint8Array !== 'undefined') { 4296 | if (Buffer.TYPED_ARRAY_SUPPORT) { 4297 | return (new Buffer(this)).buffer 4298 | } else { 4299 | var buf = new Uint8Array(this.length) 4300 | for (var i = 0, len = buf.length; i < len; i += 1) { 4301 | buf[i] = this[i] 4302 | } 4303 | return buf.buffer 4304 | } 4305 | } else { 4306 | throw new TypeError('Buffer.toArrayBuffer not supported in this browser') 4307 | } 4308 | } 4309 | 4310 | // HELPER FUNCTIONS 4311 | // ================ 4312 | 4313 | var BP = Buffer.prototype 4314 | 4315 | /** 4316 | * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods 4317 | */ 4318 | Buffer._augment = function _augment (arr) { 4319 | arr.constructor = Buffer 4320 | arr._isBuffer = true 4321 | 4322 | // save reference to original Uint8Array get/set methods before overwriting 4323 | arr._get = arr.get 4324 | arr._set = arr.set 4325 | 4326 | // deprecated, will be removed in node 0.13+ 4327 | arr.get = BP.get 4328 | arr.set = BP.set 4329 | 4330 | arr.write = BP.write 4331 | arr.toString = BP.toString 4332 | arr.toLocaleString = BP.toString 4333 | arr.toJSON = BP.toJSON 4334 | arr.equals = BP.equals 4335 | arr.compare = BP.compare 4336 | arr.indexOf = BP.indexOf 4337 | arr.copy = BP.copy 4338 | arr.slice = BP.slice 4339 | arr.readUIntLE = BP.readUIntLE 4340 | arr.readUIntBE = BP.readUIntBE 4341 | arr.readUInt8 = BP.readUInt8 4342 | arr.readUInt16LE = BP.readUInt16LE 4343 | arr.readUInt16BE = BP.readUInt16BE 4344 | arr.readUInt32LE = BP.readUInt32LE 4345 | arr.readUInt32BE = BP.readUInt32BE 4346 | arr.readIntLE = BP.readIntLE 4347 | arr.readIntBE = BP.readIntBE 4348 | arr.readInt8 = BP.readInt8 4349 | arr.readInt16LE = BP.readInt16LE 4350 | arr.readInt16BE = BP.readInt16BE 4351 | arr.readInt32LE = BP.readInt32LE 4352 | arr.readInt32BE = BP.readInt32BE 4353 | arr.readFloatLE = BP.readFloatLE 4354 | arr.readFloatBE = BP.readFloatBE 4355 | arr.readDoubleLE = BP.readDoubleLE 4356 | arr.readDoubleBE = BP.readDoubleBE 4357 | arr.writeUInt8 = BP.writeUInt8 4358 | arr.writeUIntLE = BP.writeUIntLE 4359 | arr.writeUIntBE = BP.writeUIntBE 4360 | arr.writeUInt16LE = BP.writeUInt16LE 4361 | arr.writeUInt16BE = BP.writeUInt16BE 4362 | arr.writeUInt32LE = BP.writeUInt32LE 4363 | arr.writeUInt32BE = BP.writeUInt32BE 4364 | arr.writeIntLE = BP.writeIntLE 4365 | arr.writeIntBE = BP.writeIntBE 4366 | arr.writeInt8 = BP.writeInt8 4367 | arr.writeInt16LE = BP.writeInt16LE 4368 | arr.writeInt16BE = BP.writeInt16BE 4369 | arr.writeInt32LE = BP.writeInt32LE 4370 | arr.writeInt32BE = BP.writeInt32BE 4371 | arr.writeFloatLE = BP.writeFloatLE 4372 | arr.writeFloatBE = BP.writeFloatBE 4373 | arr.writeDoubleLE = BP.writeDoubleLE 4374 | arr.writeDoubleBE = BP.writeDoubleBE 4375 | arr.fill = BP.fill 4376 | arr.inspect = BP.inspect 4377 | arr.toArrayBuffer = BP.toArrayBuffer 4378 | 4379 | return arr 4380 | } 4381 | 4382 | var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g 4383 | 4384 | function base64clean (str) { 4385 | // Node strips out invalid characters like \n and \t from the string, base64-js does not 4386 | str = stringtrim(str).replace(INVALID_BASE64_RE, '') 4387 | // Node converts strings with length < 2 to '' 4388 | if (str.length < 2) return '' 4389 | // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not 4390 | while (str.length % 4 !== 0) { 4391 | str = str + '=' 4392 | } 4393 | return str 4394 | } 4395 | 4396 | function stringtrim (str) { 4397 | if (str.trim) return str.trim() 4398 | return str.replace(/^\s+|\s+$/g, '') 4399 | } 4400 | 4401 | function isArrayish (subject) { 4402 | return isArray(subject) || Buffer.isBuffer(subject) || 4403 | subject && typeof subject === 'object' && 4404 | typeof subject.length === 'number' 4405 | } 4406 | 4407 | function toHex (n) { 4408 | if (n < 16) return '0' + n.toString(16) 4409 | return n.toString(16) 4410 | } 4411 | 4412 | function utf8ToBytes (string, units) { 4413 | units = units || Infinity 4414 | var codePoint 4415 | var length = string.length 4416 | var leadSurrogate = null 4417 | var bytes = [] 4418 | var i = 0 4419 | 4420 | for (; i < length; i++) { 4421 | codePoint = string.charCodeAt(i) 4422 | 4423 | // is surrogate component 4424 | if (codePoint > 0xD7FF && codePoint < 0xE000) { 4425 | // last char was a lead 4426 | if (leadSurrogate) { 4427 | // 2 leads in a row 4428 | if (codePoint < 0xDC00) { 4429 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4430 | leadSurrogate = codePoint 4431 | continue 4432 | } else { 4433 | // valid surrogate pair 4434 | codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 4435 | leadSurrogate = null 4436 | } 4437 | } else { 4438 | // no lead yet 4439 | 4440 | if (codePoint > 0xDBFF) { 4441 | // unexpected trail 4442 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4443 | continue 4444 | } else if (i + 1 === length) { 4445 | // unpaired lead 4446 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4447 | continue 4448 | } else { 4449 | // valid lead 4450 | leadSurrogate = codePoint 4451 | continue 4452 | } 4453 | } 4454 | } else if (leadSurrogate) { 4455 | // valid bmp char, but last char was a lead 4456 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 4457 | leadSurrogate = null 4458 | } 4459 | 4460 | // encode utf8 4461 | if (codePoint < 0x80) { 4462 | if ((units -= 1) < 0) break 4463 | bytes.push(codePoint) 4464 | } else if (codePoint < 0x800) { 4465 | if ((units -= 2) < 0) break 4466 | bytes.push( 4467 | codePoint >> 0x6 | 0xC0, 4468 | codePoint & 0x3F | 0x80 4469 | ) 4470 | } else if (codePoint < 0x10000) { 4471 | if ((units -= 3) < 0) break 4472 | bytes.push( 4473 | codePoint >> 0xC | 0xE0, 4474 | codePoint >> 0x6 & 0x3F | 0x80, 4475 | codePoint & 0x3F | 0x80 4476 | ) 4477 | } else if (codePoint < 0x200000) { 4478 | if ((units -= 4) < 0) break 4479 | bytes.push( 4480 | codePoint >> 0x12 | 0xF0, 4481 | codePoint >> 0xC & 0x3F | 0x80, 4482 | codePoint >> 0x6 & 0x3F | 0x80, 4483 | codePoint & 0x3F | 0x80 4484 | ) 4485 | } else { 4486 | throw new Error('Invalid code point') 4487 | } 4488 | } 4489 | 4490 | return bytes 4491 | } 4492 | 4493 | function asciiToBytes (str) { 4494 | var byteArray = [] 4495 | for (var i = 0; i < str.length; i++) { 4496 | // Node's code seems to be doing this and not & 0x7F.. 4497 | byteArray.push(str.charCodeAt(i) & 0xFF) 4498 | } 4499 | return byteArray 4500 | } 4501 | 4502 | function utf16leToBytes (str, units) { 4503 | var c, hi, lo 4504 | var byteArray = [] 4505 | for (var i = 0; i < str.length; i++) { 4506 | if ((units -= 2) < 0) break 4507 | 4508 | c = str.charCodeAt(i) 4509 | hi = c >> 8 4510 | lo = c % 256 4511 | byteArray.push(lo) 4512 | byteArray.push(hi) 4513 | } 4514 | 4515 | return byteArray 4516 | } 4517 | 4518 | function base64ToBytes (str) { 4519 | return base64.toByteArray(base64clean(str)) 4520 | } 4521 | 4522 | function blitBuffer (src, dst, offset, length) { 4523 | for (var i = 0; i < length; i++) { 4524 | if ((i + offset >= dst.length) || (i >= src.length)) break 4525 | dst[i + offset] = src[i] 4526 | } 4527 | return i 4528 | } 4529 | 4530 | function decodeUtf8Char (str) { 4531 | try { 4532 | return decodeURIComponent(str) 4533 | } catch (err) { 4534 | return String.fromCharCode(0xFFFD) // UTF 8 invalid char 4535 | } 4536 | } 4537 | 4538 | },{"base64-js":24,"ieee754":25,"is-array":26}],24:[function(require,module,exports){ 4539 | var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 4540 | 4541 | ;(function (exports) { 4542 | 'use strict'; 4543 | 4544 | var Arr = (typeof Uint8Array !== 'undefined') 4545 | ? Uint8Array 4546 | : Array 4547 | 4548 | var PLUS = '+'.charCodeAt(0) 4549 | var SLASH = '/'.charCodeAt(0) 4550 | var NUMBER = '0'.charCodeAt(0) 4551 | var LOWER = 'a'.charCodeAt(0) 4552 | var UPPER = 'A'.charCodeAt(0) 4553 | var PLUS_URL_SAFE = '-'.charCodeAt(0) 4554 | var SLASH_URL_SAFE = '_'.charCodeAt(0) 4555 | 4556 | function decode (elt) { 4557 | var code = elt.charCodeAt(0) 4558 | if (code === PLUS || 4559 | code === PLUS_URL_SAFE) 4560 | return 62 // '+' 4561 | if (code === SLASH || 4562 | code === SLASH_URL_SAFE) 4563 | return 63 // '/' 4564 | if (code < NUMBER) 4565 | return -1 //no match 4566 | if (code < NUMBER + 10) 4567 | return code - NUMBER + 26 + 26 4568 | if (code < UPPER + 26) 4569 | return code - UPPER 4570 | if (code < LOWER + 26) 4571 | return code - LOWER + 26 4572 | } 4573 | 4574 | function b64ToByteArray (b64) { 4575 | var i, j, l, tmp, placeHolders, arr 4576 | 4577 | if (b64.length % 4 > 0) { 4578 | throw new Error('Invalid string. Length must be a multiple of 4') 4579 | } 4580 | 4581 | // the number of equal signs (place holders) 4582 | // if there are two placeholders, than the two characters before it 4583 | // represent one byte 4584 | // if there is only one, then the three characters before it represent 2 bytes 4585 | // this is just a cheap hack to not do indexOf twice 4586 | var len = b64.length 4587 | placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 4588 | 4589 | // base64 is 4/3 + up to two characters of the original data 4590 | arr = new Arr(b64.length * 3 / 4 - placeHolders) 4591 | 4592 | // if there are placeholders, only get up to the last complete 4 chars 4593 | l = placeHolders > 0 ? b64.length - 4 : b64.length 4594 | 4595 | var L = 0 4596 | 4597 | function push (v) { 4598 | arr[L++] = v 4599 | } 4600 | 4601 | for (i = 0, j = 0; i < l; i += 4, j += 3) { 4602 | tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) 4603 | push((tmp & 0xFF0000) >> 16) 4604 | push((tmp & 0xFF00) >> 8) 4605 | push(tmp & 0xFF) 4606 | } 4607 | 4608 | if (placeHolders === 2) { 4609 | tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) 4610 | push(tmp & 0xFF) 4611 | } else if (placeHolders === 1) { 4612 | tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) 4613 | push((tmp >> 8) & 0xFF) 4614 | push(tmp & 0xFF) 4615 | } 4616 | 4617 | return arr 4618 | } 4619 | 4620 | function uint8ToBase64 (uint8) { 4621 | var i, 4622 | extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes 4623 | output = "", 4624 | temp, length 4625 | 4626 | function encode (num) { 4627 | return lookup.charAt(num) 4628 | } 4629 | 4630 | function tripletToBase64 (num) { 4631 | return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) 4632 | } 4633 | 4634 | // go through the array every three bytes, we'll deal with trailing stuff later 4635 | for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { 4636 | temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) 4637 | output += tripletToBase64(temp) 4638 | } 4639 | 4640 | // pad the end with zeros, but make sure to not forget the extra bytes 4641 | switch (extraBytes) { 4642 | case 1: 4643 | temp = uint8[uint8.length - 1] 4644 | output += encode(temp >> 2) 4645 | output += encode((temp << 4) & 0x3F) 4646 | output += '==' 4647 | break 4648 | case 2: 4649 | temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) 4650 | output += encode(temp >> 10) 4651 | output += encode((temp >> 4) & 0x3F) 4652 | output += encode((temp << 2) & 0x3F) 4653 | output += '=' 4654 | break 4655 | } 4656 | 4657 | return output 4658 | } 4659 | 4660 | exports.toByteArray = b64ToByteArray 4661 | exports.fromByteArray = uint8ToBase64 4662 | }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) 4663 | 4664 | },{}],25:[function(require,module,exports){ 4665 | exports.read = function(buffer, offset, isLE, mLen, nBytes) { 4666 | var e, m, 4667 | eLen = nBytes * 8 - mLen - 1, 4668 | eMax = (1 << eLen) - 1, 4669 | eBias = eMax >> 1, 4670 | nBits = -7, 4671 | i = isLE ? (nBytes - 1) : 0, 4672 | d = isLE ? -1 : 1, 4673 | s = buffer[offset + i]; 4674 | 4675 | i += d; 4676 | 4677 | e = s & ((1 << (-nBits)) - 1); 4678 | s >>= (-nBits); 4679 | nBits += eLen; 4680 | for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); 4681 | 4682 | m = e & ((1 << (-nBits)) - 1); 4683 | e >>= (-nBits); 4684 | nBits += mLen; 4685 | for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); 4686 | 4687 | if (e === 0) { 4688 | e = 1 - eBias; 4689 | } else if (e === eMax) { 4690 | return m ? NaN : ((s ? -1 : 1) * Infinity); 4691 | } else { 4692 | m = m + Math.pow(2, mLen); 4693 | e = e - eBias; 4694 | } 4695 | return (s ? -1 : 1) * m * Math.pow(2, e - mLen); 4696 | }; 4697 | 4698 | exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { 4699 | var e, m, c, 4700 | eLen = nBytes * 8 - mLen - 1, 4701 | eMax = (1 << eLen) - 1, 4702 | eBias = eMax >> 1, 4703 | rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), 4704 | i = isLE ? 0 : (nBytes - 1), 4705 | d = isLE ? 1 : -1, 4706 | s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; 4707 | 4708 | value = Math.abs(value); 4709 | 4710 | if (isNaN(value) || value === Infinity) { 4711 | m = isNaN(value) ? 1 : 0; 4712 | e = eMax; 4713 | } else { 4714 | e = Math.floor(Math.log(value) / Math.LN2); 4715 | if (value * (c = Math.pow(2, -e)) < 1) { 4716 | e--; 4717 | c *= 2; 4718 | } 4719 | if (e + eBias >= 1) { 4720 | value += rt / c; 4721 | } else { 4722 | value += rt * Math.pow(2, 1 - eBias); 4723 | } 4724 | if (value * c >= 2) { 4725 | e++; 4726 | c /= 2; 4727 | } 4728 | 4729 | if (e + eBias >= eMax) { 4730 | m = 0; 4731 | e = eMax; 4732 | } else if (e + eBias >= 1) { 4733 | m = (value * c - 1) * Math.pow(2, mLen); 4734 | e = e + eBias; 4735 | } else { 4736 | m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); 4737 | e = 0; 4738 | } 4739 | } 4740 | 4741 | for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); 4742 | 4743 | e = (e << mLen) | m; 4744 | eLen += mLen; 4745 | for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); 4746 | 4747 | buffer[offset + i - d] |= s * 128; 4748 | }; 4749 | 4750 | },{}],26:[function(require,module,exports){ 4751 | 4752 | /** 4753 | * isArray 4754 | */ 4755 | 4756 | var isArray = Array.isArray; 4757 | 4758 | /** 4759 | * toString 4760 | */ 4761 | 4762 | var str = Object.prototype.toString; 4763 | 4764 | /** 4765 | * Whether or not the given `val` 4766 | * is an array. 4767 | * 4768 | * example: 4769 | * 4770 | * isArray([]); 4771 | * // > true 4772 | * isArray(arguments); 4773 | * // > false 4774 | * isArray(''); 4775 | * // > false 4776 | * 4777 | * @param {mixed} val 4778 | * @return {bool} 4779 | */ 4780 | 4781 | module.exports = isArray || function (val) { 4782 | return !! val && '[object Array]' == str.call(val); 4783 | }; 4784 | 4785 | },{}],27:[function(require,module,exports){ 4786 | var size = require('element-size') 4787 | 4788 | module.exports = fit 4789 | 4790 | function fit(canvas, parent, scale) { 4791 | canvas.style.position = canvas.style.position || 'absolute' 4792 | canvas.style.top = 0 4793 | canvas.style.left = 0 4794 | 4795 | scale = parseFloat(scale || 1) 4796 | 4797 | 4798 | return resize() 4799 | 4800 | function resize() { 4801 | var p = parent || canvas.parentNode 4802 | if (p && p !== document.body) { 4803 | var psize = size(p) 4804 | var width = psize[0]|0 4805 | var height = psize[1]|0 4806 | } else { 4807 | var width = window.innerWidth 4808 | var height = window.innerHeight 4809 | } 4810 | 4811 | canvas.width = width * scale 4812 | canvas.height = height * scale 4813 | canvas.style.width = width + 'px' 4814 | canvas.style.height = height + 'px' 4815 | 4816 | return resize 4817 | } 4818 | } 4819 | 4820 | },{"element-size":28}],28:[function(require,module,exports){ 4821 | module.exports = getSize 4822 | 4823 | function getSize(element) { 4824 | // Handle cases where the element is not already 4825 | // attached to the DOM by briefly appending it 4826 | // to document.body, and removing it again later. 4827 | if (element === window || element === document.body) { 4828 | return [window.innerWidth, window.innerHeight] 4829 | } 4830 | 4831 | if (!element.parentNode) { 4832 | var temporary = true 4833 | document.body.appendChild(element) 4834 | } 4835 | 4836 | var bounds = element.getBoundingClientRect() 4837 | var styles = getComputedStyle(element) 4838 | var height = (bounds.height|0) 4839 | + parse(styles.getPropertyValue('margin-top')) 4840 | + parse(styles.getPropertyValue('margin-bottom')) 4841 | var width = (bounds.width|0) 4842 | + parse(styles.getPropertyValue('margin-left')) 4843 | + parse(styles.getPropertyValue('margin-right')) 4844 | 4845 | if (temporary) { 4846 | document.body.removeChild(element) 4847 | } 4848 | 4849 | return [width, height] 4850 | } 4851 | 4852 | function parse(prop) { 4853 | return parseFloat(prop) || 0 4854 | } 4855 | 4856 | },{}],29:[function(require,module,exports){ 4857 | var raf = require('raf-component') 4858 | 4859 | module.exports = createContext 4860 | 4861 | function createContext(canvas, opts, render) { 4862 | if (typeof opts === 'function') { 4863 | render = opts 4864 | opts = {} 4865 | } else { 4866 | opts = opts || {} 4867 | } 4868 | 4869 | var gl = ( 4870 | canvas.getContext('webgl', opts) || 4871 | canvas.getContext('webgl-experimental', opts) || 4872 | canvas.getContext('experimental-webgl', opts) 4873 | ) 4874 | 4875 | if (!gl) { 4876 | throw new Error('Unable to initialize WebGL') 4877 | } 4878 | 4879 | if (render) raf(tick) 4880 | 4881 | return gl 4882 | 4883 | function tick() { 4884 | render(gl) 4885 | raf(tick) 4886 | } 4887 | } 4888 | 4889 | },{"raf-component":30}],30:[function(require,module,exports){ 4890 | /** 4891 | * Expose `requestAnimationFrame()`. 4892 | */ 4893 | 4894 | exports = module.exports = window.requestAnimationFrame 4895 | || window.webkitRequestAnimationFrame 4896 | || window.mozRequestAnimationFrame 4897 | || window.oRequestAnimationFrame 4898 | || window.msRequestAnimationFrame 4899 | || fallback; 4900 | 4901 | /** 4902 | * Fallback implementation. 4903 | */ 4904 | 4905 | var prev = new Date().getTime(); 4906 | function fallback(fn) { 4907 | var curr = new Date().getTime(); 4908 | var ms = Math.max(0, 16 - (curr - prev)); 4909 | var req = setTimeout(fn, ms); 4910 | prev = curr; 4911 | return req; 4912 | } 4913 | 4914 | /** 4915 | * Cancel. 4916 | */ 4917 | 4918 | var cancel = window.cancelAnimationFrame 4919 | || window.webkitCancelAnimationFrame 4920 | || window.mozCancelAnimationFrame 4921 | || window.oCancelAnimationFrame 4922 | || window.msCancelAnimationFrame 4923 | || window.clearTimeout; 4924 | 4925 | exports.cancel = function(id){ 4926 | cancel.call(window, id); 4927 | }; 4928 | 4929 | },{}],31:[function(require,module,exports){ 4930 | 'use strict' 4931 | 4932 | var createUniformWrapper = require('./lib/create-uniforms') 4933 | var createAttributeWrapper = require('./lib/create-attributes') 4934 | var makeReflect = require('./lib/reflect') 4935 | var shaderCache = require('./lib/shader-cache') 4936 | var runtime = require('./lib/runtime-reflect') 4937 | 4938 | //Shader object 4939 | function Shader(gl) { 4940 | this.gl = gl 4941 | 4942 | //Default initialize these to null 4943 | this._vref = 4944 | this._fref = 4945 | this._relink = 4946 | this.vertShader = 4947 | this.fragShader = 4948 | this.program = 4949 | this.attributes = 4950 | this.uniforms = 4951 | this.types = null 4952 | } 4953 | 4954 | var proto = Shader.prototype 4955 | 4956 | proto.bind = function() { 4957 | if(!this.program) { 4958 | this._relink() 4959 | } 4960 | this.gl.useProgram(this.program) 4961 | } 4962 | 4963 | proto.dispose = function() { 4964 | if(this._fref) { 4965 | this._fref.dispose() 4966 | } 4967 | if(this._vref) { 4968 | this._vref.dispose() 4969 | } 4970 | this.attributes = 4971 | this.types = 4972 | this.vertShader = 4973 | this.fragShader = 4974 | this.program = 4975 | this._relink = 4976 | this._fref = 4977 | this._vref = null 4978 | } 4979 | 4980 | function compareAttributes(a, b) { 4981 | if(a.name < b.name) { 4982 | return -1 4983 | } 4984 | return 1 4985 | } 4986 | 4987 | //Update export hook for glslify-live 4988 | proto.update = function( 4989 | vertSource 4990 | , fragSource 4991 | , uniforms 4992 | , attributes) { 4993 | 4994 | //If only one object passed, assume glslify style output 4995 | if(!fragSource || arguments.length === 1) { 4996 | var obj = vertSource 4997 | vertSource = obj.vertex 4998 | fragSource = obj.fragment 4999 | uniforms = obj.uniforms 5000 | attributes = obj.attributes 5001 | } 5002 | 5003 | var wrapper = this 5004 | var gl = wrapper.gl 5005 | 5006 | //Compile vertex and fragment shaders 5007 | var pvref = wrapper._vref 5008 | wrapper._vref = shaderCache.shader(gl, gl.VERTEX_SHADER, vertSource) 5009 | if(pvref) { 5010 | pvref.dispose() 5011 | } 5012 | wrapper.vertShader = wrapper._vref.shader 5013 | var pfref = this._fref 5014 | wrapper._fref = shaderCache.shader(gl, gl.FRAGMENT_SHADER, fragSource) 5015 | if(pfref) { 5016 | pfref.dispose() 5017 | } 5018 | wrapper.fragShader = wrapper._fref.shader 5019 | 5020 | //If uniforms/attributes is not specified, use RT reflection 5021 | if(!uniforms || !attributes) { 5022 | 5023 | //Create initial test program 5024 | var testProgram = gl.createProgram() 5025 | gl.attachShader(testProgram, wrapper.fragShader) 5026 | gl.attachShader(testProgram, wrapper.vertShader) 5027 | gl.linkProgram(testProgram) 5028 | if(!gl.getProgramParameter(testProgram, gl.LINK_STATUS)) { 5029 | var errLog = gl.getProgramInfoLog(testProgram) 5030 | console.error('gl-shader: Error linking program:', errLog) 5031 | throw new Error('gl-shader: Error linking program:' + errLog) 5032 | } 5033 | 5034 | //Load data from runtime 5035 | uniforms = uniforms || runtime.uniforms(gl, testProgram) 5036 | attributes = attributes || runtime.attributes(gl, testProgram) 5037 | 5038 | //Release test program 5039 | gl.deleteProgram(testProgram) 5040 | } 5041 | 5042 | //Sort attributes lexicographically 5043 | // overrides undefined WebGL behavior for attribute locations 5044 | attributes = attributes.slice() 5045 | attributes.sort(compareAttributes) 5046 | 5047 | //Convert attribute types, read out locations 5048 | var attributeUnpacked = [] 5049 | var attributeNames = [] 5050 | var attributeLocations = [] 5051 | for(var i=0; i= 0) { 5054 | var size = attr.type.charAt(attr.type.length-1)|0 5055 | var locVector = new Array(size) 5056 | for(var j=0; j= 0) { 5094 | curLocation += 1 5095 | } 5096 | attributeLocations[i] = curLocation 5097 | } 5098 | } 5099 | 5100 | //Rebuild program and recompute all uniform locations 5101 | var uniformLocations = new Array(uniforms.length) 5102 | function relink() { 5103 | wrapper.program = shaderCache.program( 5104 | gl 5105 | , wrapper._vref 5106 | , wrapper._fref 5107 | , attributeNames 5108 | , attributeLocations) 5109 | 5110 | for(var i=0; i= 0) { 5393 | var d = type.charCodeAt(type.length-1) - 48 5394 | if(d < 2 || d > 4) { 5395 | throw new Error('gl-shader: Invalid data type for attribute ' + name + ': ' + type) 5396 | } 5397 | addVectorAttribute( 5398 | gl 5399 | , wrapper 5400 | , locs[0] 5401 | , locations 5402 | , d 5403 | , obj 5404 | , name) 5405 | } else if(type.indexOf('mat') >= 0) { 5406 | var d = type.charCodeAt(type.length-1) - 48 5407 | if(d < 2 || d > 4) { 5408 | throw new Error('gl-shader: Invalid data type for attribute ' + name + ': ' + type) 5409 | } 5410 | addMatrixAttribute( 5411 | gl 5412 | , wrapper 5413 | , locs 5414 | , locations 5415 | , d 5416 | , obj 5417 | , name) 5418 | } else { 5419 | throw new Error('gl-shader: Unknown data type for attribute ' + name + ': ' + type) 5420 | } 5421 | break 5422 | } 5423 | } 5424 | return obj 5425 | } 5426 | },{}],33:[function(require,module,exports){ 5427 | 'use strict' 5428 | 5429 | var dup = require('dup') 5430 | var coallesceUniforms = require('./reflect') 5431 | 5432 | module.exports = createUniformWrapper 5433 | 5434 | //Binds a function and returns a value 5435 | function identity(x) { 5436 | var c = new Function('y', 'return function(){return y}') 5437 | return c(x) 5438 | } 5439 | 5440 | //Create shims for uniforms 5441 | function createUniformWrapper(gl, wrapper, uniforms, locations) { 5442 | 5443 | function makeGetter(index) { 5444 | var proc = new Function( 5445 | 'gl' 5446 | , 'wrapper' 5447 | , 'locations' 5448 | , 'return function(){return gl.getUniform(wrapper.program,locations[' + index + '])}') 5449 | return proc(gl, wrapper, locations) 5450 | } 5451 | 5452 | function makePropSetter(path, index, type) { 5453 | switch(type) { 5454 | case 'bool': 5455 | case 'int': 5456 | case 'sampler2D': 5457 | case 'samplerCube': 5458 | return 'gl.uniform1i(locations[' + index + '],obj' + path + ')' 5459 | case 'float': 5460 | return 'gl.uniform1f(locations[' + index + '],obj' + path + ')' 5461 | default: 5462 | var vidx = type.indexOf('vec') 5463 | if(0 <= vidx && vidx <= 1 && type.length === 4 + vidx) { 5464 | var d = type.charCodeAt(type.length-1) - 48 5465 | if(d < 2 || d > 4) { 5466 | throw new Error('gl-shader: Invalid data type') 5467 | } 5468 | switch(type.charAt(0)) { 5469 | case 'b': 5470 | case 'i': 5471 | return 'gl.uniform' + d + 'iv(locations[' + index + '],obj' + path + ')' 5472 | case 'v': 5473 | return 'gl.uniform' + d + 'fv(locations[' + index + '],obj' + path + ')' 5474 | default: 5475 | throw new Error('gl-shader: Unrecognized data type for vector ' + name + ': ' + type) 5476 | } 5477 | } else if(type.indexOf('mat') === 0 && type.length === 4) { 5478 | var d = type.charCodeAt(type.length-1) - 48 5479 | if(d < 2 || d > 4) { 5480 | throw new Error('gl-shader: Invalid uniform dimension type for matrix ' + name + ': ' + type) 5481 | } 5482 | return 'gl.uniformMatrix' + d + 'fv(locations[' + index + '],false,obj' + path + ')' 5483 | } else { 5484 | throw new Error('gl-shader: Unknown uniform data type for ' + name + ': ' + type) 5485 | } 5486 | break 5487 | } 5488 | } 5489 | 5490 | function enumerateIndices(prefix, type) { 5491 | if(typeof type !== 'object') { 5492 | return [ [prefix, type] ] 5493 | } 5494 | var indices = [] 5495 | for(var id in type) { 5496 | var prop = type[id] 5497 | var tprefix = prefix 5498 | if(parseInt(id) + '' === id) { 5499 | tprefix += '[' + id + ']' 5500 | } else { 5501 | tprefix += '.' + id 5502 | } 5503 | if(typeof prop === 'object') { 5504 | indices.push.apply(indices, enumerateIndices(tprefix, prop)) 5505 | } else { 5506 | indices.push([tprefix, prop]) 5507 | } 5508 | } 5509 | return indices 5510 | } 5511 | 5512 | function makeSetter(type) { 5513 | var code = [ 'return function updateProperty(obj){' ] 5514 | var indices = enumerateIndices('', type) 5515 | for(var i=0; i 4) { 5543 | throw new Error('gl-shader: Invalid data type') 5544 | } 5545 | if(type.charAt(0) === 'b') { 5546 | return dup(d, false) 5547 | } 5548 | return dup(d) 5549 | } else if(type.indexOf('mat') === 0 && type.length === 4) { 5550 | var d = type.charCodeAt(type.length-1) - 48 5551 | if(d < 2 || d > 4) { 5552 | throw new Error('gl-shader: Invalid uniform dimension type for matrix ' + name + ': ' + type) 5553 | } 5554 | return dup(d*d) 5555 | } else { 5556 | throw new Error('gl-shader: Unknown uniform data type for ' + name + ': ' + type) 5557 | } 5558 | break 5559 | } 5560 | } 5561 | 5562 | function storeProperty(obj, prop, type) { 5563 | if(typeof type === 'object') { 5564 | var child = processObject(type) 5565 | Object.defineProperty(obj, prop, { 5566 | get: identity(child), 5567 | set: makeSetter(type), 5568 | enumerable: true, 5569 | configurable: false 5570 | }) 5571 | } else { 5572 | if(locations[type]) { 5573 | Object.defineProperty(obj, prop, { 5574 | get: makeGetter(type), 5575 | set: makeSetter(type), 5576 | enumerable: true, 5577 | configurable: false 5578 | }) 5579 | } else { 5580 | obj[prop] = defaultValue(uniforms[type].type) 5581 | } 5582 | } 5583 | } 5584 | 5585 | function processObject(obj) { 5586 | var result 5587 | if(Array.isArray(obj)) { 5588 | result = new Array(obj.length) 5589 | for(var i=0; i 1) { 5630 | if(!(x[0] in o)) { 5631 | o[x[0]] = [] 5632 | } 5633 | o = o[x[0]] 5634 | for(var k=1; k maxd) break; 45 | h = doModel(ro+rd*t); 46 | t += h; 47 | } 48 | 49 | if (t < maxd) res = t; 50 | return res; 51 | } 52 | 53 | vec3 calcNormal(vec3 pos) { 54 | const float eps = 0.002; 55 | 56 | const vec3 v1 = vec3( 1.0,-1.0,-1.0); 57 | const vec3 v2 = vec3(-1.0,-1.0, 1.0); 58 | const vec3 v3 = vec3(-1.0, 1.0,-1.0); 59 | const vec3 v4 = vec3( 1.0, 1.0, 1.0); 60 | 61 | return normalize( v1*doModel( pos + v1*eps ) + 62 | v2*doModel( pos + v2*eps ) + 63 | v3*doModel( pos + v3*eps ) + 64 | v4*doModel( pos + v4*eps ) ); 65 | } 66 | 67 | void main() { 68 | float cameraAngle = 0.8 * iGlobalTime; 69 | vec3 rayOrigin = vec3(3.5 * sin(cameraAngle), 3.0, 3.5 * cos(cameraAngle)); 70 | vec3 rayTarget = vec3(0, 0, 0); 71 | vec2 screenPos = square(iResolution); 72 | vec3 rayDirection = camera(rayOrigin, rayTarget, screenPos, 2.0); 73 | 74 | vec3 col = vec3(0.0); 75 | float t = calcIntersection(rayOrigin, rayDirection); 76 | 77 | if (t > -0.5) { 78 | vec3 pos = rayOrigin + t*rayDirection; 79 | vec3 nor = calcNormal(pos); 80 | vec3 mal = doMaterial(pos, nor); 81 | 82 | col = doLighting(pos, nor, rayDirection, t, mal); 83 | } 84 | 85 | col = pow(clamp(col,0.0,1.0), vec3(0.4545)); 86 | 87 | gl_FragColor = vec4( col, 1.0 ); 88 | } 89 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | var canvas = document.body.appendChild(document.createElement('canvas')) 2 | var triangle = require('a-big-triangle') 3 | var context = require('gl-context') 4 | var fit = require('canvas-fit') 5 | var Shader = require('gl-shader') 6 | var glslify = require('glslify') 7 | 8 | var start = Date.now() 9 | 10 | window.addEventListener('resize', fit(canvas, window, 0.25), false) 11 | 12 | Toy(function(gl) { 13 | return Shader(gl 14 | , glslify('./demo.vert') 15 | , glslify('./demo.frag') 16 | ) 17 | }, function(gl, shader) { 18 | shader.uniforms.iResolution = [gl.drawingBufferWidth, gl.drawingBufferHeight] 19 | shader.uniforms.iGlobalTime = (Date.now() - start) / 1000 20 | }) 21 | 22 | // Extracted for gl-toy, need to do manual 23 | // downsampling here :) 24 | function Toy(shader, cb) { 25 | var gl = context(canvas, render) 26 | shader = shader(gl) 27 | 28 | function render() { 29 | var width = gl.drawingBufferWidth 30 | var height = gl.drawingBufferHeight 31 | gl.viewport(0, 0, width, height) 32 | 33 | shader.bind() 34 | cb(gl, shader) 35 | triangle(gl) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /demo.vert: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | attribute vec2 position; 4 | 5 | void main() { 6 | gl_Position = vec4(position, 1, 1); 7 | } 8 | -------------------------------------------------------------------------------- /index.glsl: -------------------------------------------------------------------------------- 1 | #pragma glslify: lookAt = require('glsl-look-at') 2 | 3 | vec3 getRay(mat3 camMat, vec2 screenPos, float lensLength) { 4 | return normalize(camMat * vec3(screenPos, lensLength)); 5 | } 6 | 7 | vec3 getRay(vec3 origin, vec3 target, vec2 screenPos, float lensLength) { 8 | mat3 camMat = lookAt(origin, target, 0.0); 9 | return getRay(camMat, screenPos, lensLength); 10 | } 11 | 12 | #pragma glslify: export(getRay) 13 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | glsl-camera-ray 5 | 6 | 52 | 53 | 54 |

55 |

glsl-camera-ray

56 |

57 | Generates a ray for Shadertoy-style raycasting in GLSL. 58 | Accepts either either a camera origin/target or an arbitrary 59 | mat3 matrix. 60 |

61 |

62 | 63 | Check it out on GitHub 64 | 65 |

66 |
67 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "glsl-camera-ray", 3 | "version": "1.0.0", 4 | "description": "Generates a ray for Shadertoy-style raycasting in GLSL", 5 | "main": "index.glsl", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "beefy demo.js:bundle.js -- -t glslify", 9 | "bundle": "browserify demo.js -o bundle.js -t glslify" 10 | }, 11 | "author": { 12 | "name": "Hugh Kennedy", 13 | "email": "hughskennedy@gmail.com", 14 | "url": "http://hughsk.io/" 15 | }, 16 | "dependencies": { 17 | "glsl-look-at": "^1.0.0" 18 | }, 19 | "devDependencies": { 20 | "a-big-triangle": "^1.0.0", 21 | "beefy": "^2.1.3", 22 | "browserify": "^9.0.3", 23 | "canvas-fit": "^1.2.0", 24 | "gl-context": "^0.1.1", 25 | "gl-shader": "^4.0.0", 26 | "gl-toy": "^1.0.0", 27 | "glsl-smooth-min": "^1.0.0", 28 | "glsl-square-frame": "^1.0.1", 29 | "glslify": "^2.0.1" 30 | }, 31 | "repository": { 32 | "type": "git", 33 | "url": "git://github.com/stackgl/glsl-camera-ray.git" 34 | }, 35 | "keywords": [ 36 | "ecosystem:stackgl" 37 | ], 38 | "homepage": "https://github.com/stackgl/glsl-camera-ray", 39 | "bugs": { 40 | "url": "https://github.com/stackgl/glsl-camera-ray/issues" 41 | } 42 | } 43 | --------------------------------------------------------------------------------