this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

shadow scrapping, processing & comparing

+7196 -34
+31
assets/css/style.css
··· 1 1 body 2 2 { 3 3 margin: 0; 4 + padding: 0; 4 5 }; 5 6 canvas{ 6 7 width: 100%; 7 8 height: 100%; 9 + } 10 + 11 + .imageWrapper{ 12 + /*position: relative;*/ 13 + } 14 + .sampleSC 15 + { 16 + float:left; 17 + width: 40%; 18 + } 19 + 20 + .submittedSC 21 + { 22 + float:right; 23 + width: 40%; 24 + } 25 + 26 + .invisible{ 27 + display: none; 28 + } 29 + 30 + .show{ 31 + display: block; 32 + } 33 + 34 + .absoluteWrapper { 35 + position: absolute; 36 + top: 50px; 37 + width: 100%; 38 + /*border: 1px solid red;*/ 8 39 }
assets/images/cropData.png

This is a binary file and will not be displayed.

assets/images/sample.png

This is a binary file and will not be displayed.

+130
assets/js/THREEx.screenshot.js
··· 1 + /** @namespace */ 2 + var THREEx = THREEx || {}; 3 + 4 + // TODO http://29a.ch/2011/9/11/uploading-from-html5-canvas-to-imgur-data-uri 5 + // able to upload your screenshot without running servers 6 + 7 + // forced closure 8 + (function(){ 9 + 10 + /** 11 + * Take a screenshot of a renderer 12 + * - require WebGLRenderer to have "preserveDrawingBuffer: true" to be set 13 + * - TODO is it possible to check if this variable is set ? if so check it 14 + * and make advice in the console.log 15 + * - maybe with direct access to the gl context... 16 + * 17 + * @param {Object} renderer to use 18 + * @param {String} mimetype of the output image. default to "image/png" 19 + * @param {String} dataUrl of the image 20 + */ 21 + var toDataURL = function(renderer, mimetype) 22 + { 23 + mimetype = mimetype || "image/png"; 24 + var dataUrl = renderer.domElement.toDataURL(mimetype); 25 + return dataUrl; 26 + } 27 + 28 + /** 29 + * resize an image to another resolution while preserving aspect 30 + * 31 + * @param {String} srcUrl the url of the image to resize 32 + * @param {Number} dstWidth the destination width of the image 33 + * @param {Number} dstHeight the destination height of the image 34 + * @param {Number} callback the callback to notify once completed with callback(newImageUrl) 35 + */ 36 + var _aspectResize = function(srcUrl, dstW, dstH, callback){ 37 + // to compute the width/height while keeping aspect 38 + var cpuScaleAspect = function(maxW, maxH, curW, curH){ 39 + var ratio = curH / curW; 40 + if( curW >= maxW && ratio <= 1 ){ 41 + curW = maxW; 42 + curH = maxW * ratio; 43 + }else if(curH >= maxH){ 44 + curH = maxH; 45 + curW = maxH / ratio; 46 + } 47 + return { width: curW, height: curH }; 48 + } 49 + // callback once the image is loaded 50 + var onLoad = function(){ 51 + // init the canvas 52 + var canvas = document.createElement('canvas'); 53 + canvas.width = dstW; canvas.height = dstH; 54 + var ctx = canvas.getContext('2d'); 55 + 56 + // TODO is this needed 57 + ctx.fillStyle = "black"; 58 + ctx.fillRect(0, 0, canvas.width, canvas.height); 59 + 60 + // scale the image while preserving the aspect 61 + var scaled = cpuScaleAspect(canvas.width, canvas.height, image.width, image.height); 62 + 63 + // actually draw the image on canvas 64 + var offsetX = (canvas.width - scaled.width )/2; 65 + var offsetY = (canvas.height - scaled.height)/2; 66 + ctx.drawImage(image, offsetX, offsetY, scaled.width, scaled.height); 67 + 68 + // dump the canvas to an URL 69 + var mimetype = "image/png"; 70 + var newDataUrl = canvas.toDataURL(mimetype); 71 + // notify the url to the caller 72 + callback && callback(newDataUrl) 73 + }.bind(this); 74 + 75 + // Create new Image object 76 + var image = new Image(); 77 + image.onload = onLoad; 78 + image.src = srcUrl; 79 + } 80 + 81 + 82 + // Super cooked function: THREEx.Screenshot.bindKey(renderer) 83 + // and you are done to get screenshot on your demo 84 + 85 + /** 86 + * Bind a key to renderer screenshot 87 + */ 88 + var bindKey = function(renderer, opts){ 89 + // handle parameters 90 + opts = opts || {}; 91 + var charCode = opts.charCode || 'p'.charCodeAt(0); 92 + var width = opts.width; 93 + var height = opts.height; 94 + var callback = opts.callback || function(url){ 95 + window.open(url, "name-"+Math.random()); 96 + }; 97 + 98 + // callback to handle keypress 99 + var onKeyPress = function(event){ 100 + // return now if the KeyPress isnt for the proper charCode 101 + if( event.which !== charCode ) return; 102 + // get the renderer output 103 + var dataUrl = this.toDataURL(renderer); 104 + 105 + if( width === undefined && height === undefined ){ 106 + callback( dataUrl ) 107 + }else{ 108 + // resize it and notify the callback 109 + // * resize == async so if callback is a window open, it triggers the pop blocker 110 + _aspectResize(dataUrl, width, height, callback); 111 + } 112 + }.bind(this); 113 + 114 + // listen to keypress 115 + // NOTE: for firefox it seems mandatory to listen to document directly 116 + document.addEventListener('keypress', onKeyPress, false); 117 + 118 + return { 119 + unbind : function(){ 120 + document.removeEventListener('keypress', onKeyPress, false); 121 + } 122 + }; 123 + } 124 + 125 + // export it 126 + THREEx.Screenshot = { 127 + toDataURL : toDataURL, 128 + bindKey : bindKey 129 + }; 130 + })();
+36 -1
assets/js/device/index.js
··· 9 9 var counter = 0; 10 10 11 11 var accel = require('accel-mma84').use(tessel.port['A']); 12 + var accelB = require('accel-mma84').use(tessel.port['C']); 13 + 14 + var button = require('tessel-gpio-button').use(tessel.port['GPIO'].pin['G3']); 15 + 12 16 13 17 // Initialize the accelerometer. 14 18 accel.on('ready', function() { ··· 17 21 accel.on('data', function(xyz) { 18 22 process.send({ 19 23 x: xyz[0].toFixed(2), 20 - y: xyz[1].toFixed(2) 24 + y: xyz[1].toFixed(2), 25 + port: "A" 26 + }); 27 + 28 + }); 29 + }); 30 + 31 + }); 32 + 33 + accelB.on('ready', function() { 34 + // Stream accelerometer data 35 + accelB.setOutputRate(1.56, function rateSet() { 36 + accelB.on('data', function(xyz) { 37 + process.send({ 38 + x: xyz[0].toFixed(2), 39 + y: xyz[1].toFixed(2), 40 + port: "B" 21 41 }); 22 42 23 43 }); 24 44 }); 25 45 46 + }); 47 + 48 + button.on('ready',function(){ 49 + button.on('press',function(){ 50 + process.send({ 51 + port: 'gpio', 52 + event: 'press' 53 + }); 54 + }); 55 + button.on('release',function(){ 56 + process.send({ 57 + port: 'gpio', 58 + event: 'release' 59 + }); 60 + }); 26 61 }); 27 62 28 63 // Keep the event loop alive
+28
assets/js/device/node_modules/tessel-gpio-button/.npmignore
··· 1 + # Logs 2 + logs 3 + *.log 4 + 5 + # Runtime data 6 + pids 7 + *.pid 8 + *.seed 9 + 10 + # Directory for instrumented libs generated by jscoverage/JSCover 11 + lib-cov 12 + 13 + # Coverage directory used by tools like istanbul 14 + coverage 15 + 16 + # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 + .grunt 18 + 19 + # Compiled binary addons (http://nodejs.org/api/addons.html) 20 + build/Release 21 + 22 + # Dependency directory 23 + # Commenting this out is preferred by some people, see 24 + # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 + node_modules 26 + 27 + # Users Environment Variables 28 + .lock-wscript
+202
assets/js/device/node_modules/tessel-gpio-button/LICENSE
··· 1 + Apache License 2 + Version 2.0, January 2004 3 + http://www.apache.org/licenses/ 4 + 5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 + 7 + 1. Definitions. 8 + 9 + "License" shall mean the terms and conditions for use, reproduction, 10 + and distribution as defined by Sections 1 through 9 of this document. 11 + 12 + "Licensor" shall mean the copyright owner or entity authorized by 13 + the copyright owner that is granting the License. 14 + 15 + "Legal Entity" shall mean the union of the acting entity and all 16 + other entities that control, are controlled by, or are under common 17 + control with that entity. For the purposes of this definition, 18 + "control" means (i) the power, direct or indirect, to cause the 19 + direction or management of such entity, whether by contract or 20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 + outstanding shares, or (iii) beneficial ownership of such entity. 22 + 23 + "You" (or "Your") shall mean an individual or Legal Entity 24 + exercising permissions granted by this License. 25 + 26 + "Source" form shall mean the preferred form for making modifications, 27 + including but not limited to software source code, documentation 28 + source, and configuration files. 29 + 30 + "Object" form shall mean any form resulting from mechanical 31 + transformation or translation of a Source form, including but 32 + not limited to compiled object code, generated documentation, 33 + and conversions to other media types. 34 + 35 + "Work" shall mean the work of authorship, whether in Source or 36 + Object form, made available under the License, as indicated by a 37 + copyright notice that is included in or attached to the work 38 + (an example is provided in the Appendix below). 39 + 40 + "Derivative Works" shall mean any work, whether in Source or Object 41 + form, that is based on (or derived from) the Work and for which the 42 + editorial revisions, annotations, elaborations, or other modifications 43 + represent, as a whole, an original work of authorship. For the purposes 44 + of this License, Derivative Works shall not include works that remain 45 + separable from, or merely link (or bind by name) to the interfaces of, 46 + the Work and Derivative Works thereof. 47 + 48 + "Contribution" shall mean any work of authorship, including 49 + the original version of the Work and any modifications or additions 50 + to that Work or Derivative Works thereof, that is intentionally 51 + submitted to Licensor for inclusion in the Work by the copyright owner 52 + or by an individual or Legal Entity authorized to submit on behalf of 53 + the copyright owner. For the purposes of this definition, "submitted" 54 + means any form of electronic, verbal, or written communication sent 55 + to the Licensor or its representatives, including but not limited to 56 + communication on electronic mailing lists, source code control systems, 57 + and issue tracking systems that are managed by, or on behalf of, the 58 + Licensor for the purpose of discussing and improving the Work, but 59 + excluding communication that is conspicuously marked or otherwise 60 + designated in writing by the copyright owner as "Not a Contribution." 61 + 62 + "Contributor" shall mean Licensor and any individual or Legal Entity 63 + on behalf of whom a Contribution has been received by Licensor and 64 + subsequently incorporated within the Work. 65 + 66 + 2. Grant of Copyright License. Subject to the terms and conditions of 67 + this License, each Contributor hereby grants to You a perpetual, 68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 + copyright license to reproduce, prepare Derivative Works of, 70 + publicly display, publicly perform, sublicense, and distribute the 71 + Work and such Derivative Works in Source or Object form. 72 + 73 + 3. Grant of Patent License. Subject to the terms and conditions of 74 + this License, each Contributor hereby grants to You a perpetual, 75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 + (except as stated in this section) patent license to make, have made, 77 + use, offer to sell, sell, import, and otherwise transfer the Work, 78 + where such license applies only to those patent claims licensable 79 + by such Contributor that are necessarily infringed by their 80 + Contribution(s) alone or by combination of their Contribution(s) 81 + with the Work to which such Contribution(s) was submitted. If You 82 + institute patent litigation against any entity (including a 83 + cross-claim or counterclaim in a lawsuit) alleging that the Work 84 + or a Contribution incorporated within the Work constitutes direct 85 + or contributory patent infringement, then any patent licenses 86 + granted to You under this License for that Work shall terminate 87 + as of the date such litigation is filed. 88 + 89 + 4. Redistribution. You may reproduce and distribute copies of the 90 + Work or Derivative Works thereof in any medium, with or without 91 + modifications, and in Source or Object form, provided that You 92 + meet the following conditions: 93 + 94 + (a) You must give any other recipients of the Work or 95 + Derivative Works a copy of this License; and 96 + 97 + (b) You must cause any modified files to carry prominent notices 98 + stating that You changed the files; and 99 + 100 + (c) You must retain, in the Source form of any Derivative Works 101 + that You distribute, all copyright, patent, trademark, and 102 + attribution notices from the Source form of the Work, 103 + excluding those notices that do not pertain to any part of 104 + the Derivative Works; and 105 + 106 + (d) If the Work includes a "NOTICE" text file as part of its 107 + distribution, then any Derivative Works that You distribute must 108 + include a readable copy of the attribution notices contained 109 + within such NOTICE file, excluding those notices that do not 110 + pertain to any part of the Derivative Works, in at least one 111 + of the following places: within a NOTICE text file distributed 112 + as part of the Derivative Works; within the Source form or 113 + documentation, if provided along with the Derivative Works; or, 114 + within a display generated by the Derivative Works, if and 115 + wherever such third-party notices normally appear. The contents 116 + of the NOTICE file are for informational purposes only and 117 + do not modify the License. You may add Your own attribution 118 + notices within Derivative Works that You distribute, alongside 119 + or as an addendum to the NOTICE text from the Work, provided 120 + that such additional attribution notices cannot be construed 121 + as modifying the License. 122 + 123 + You may add Your own copyright statement to Your modifications and 124 + may provide additional or different license terms and conditions 125 + for use, reproduction, or distribution of Your modifications, or 126 + for any such Derivative Works as a whole, provided Your use, 127 + reproduction, and distribution of the Work otherwise complies with 128 + the conditions stated in this License. 129 + 130 + 5. Submission of Contributions. Unless You explicitly state otherwise, 131 + any Contribution intentionally submitted for inclusion in the Work 132 + by You to the Licensor shall be under the terms and conditions of 133 + this License, without any additional terms or conditions. 134 + Notwithstanding the above, nothing herein shall supersede or modify 135 + the terms of any separate license agreement you may have executed 136 + with Licensor regarding such Contributions. 137 + 138 + 6. Trademarks. This License does not grant permission to use the trade 139 + names, trademarks, service marks, or product names of the Licensor, 140 + except as required for reasonable and customary use in describing the 141 + origin of the Work and reproducing the content of the NOTICE file. 142 + 143 + 7. Disclaimer of Warranty. Unless required by applicable law or 144 + agreed to in writing, Licensor provides the Work (and each 145 + Contributor provides its Contributions) on an "AS IS" BASIS, 146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 + implied, including, without limitation, any warranties or conditions 148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 + PARTICULAR PURPOSE. You are solely responsible for determining the 150 + appropriateness of using or redistributing the Work and assume any 151 + risks associated with Your exercise of permissions under this License. 152 + 153 + 8. Limitation of Liability. In no event and under no legal theory, 154 + whether in tort (including negligence), contract, or otherwise, 155 + unless required by applicable law (such as deliberate and grossly 156 + negligent acts) or agreed to in writing, shall any Contributor be 157 + liable to You for damages, including any direct, indirect, special, 158 + incidental, or consequential damages of any character arising as a 159 + result of this License or out of the use or inability to use the 160 + Work (including but not limited to damages for loss of goodwill, 161 + work stoppage, computer failure or malfunction, or any and all 162 + other commercial damages or losses), even if such Contributor 163 + has been advised of the possibility of such damages. 164 + 165 + 9. Accepting Warranty or Additional Liability. While redistributing 166 + the Work or Derivative Works thereof, You may choose to offer, 167 + and charge a fee for, acceptance of support, warranty, indemnity, 168 + or other liability obligations and/or rights consistent with this 169 + License. However, in accepting such obligations, You may act only 170 + on Your own behalf and on Your sole responsibility, not on behalf 171 + of any other Contributor, and only if You agree to indemnify, 172 + defend, and hold each Contributor harmless for any liability 173 + incurred by, or claims asserted against, such Contributor by reason 174 + of your accepting any such warranty or additional liability. 175 + 176 + END OF TERMS AND CONDITIONS 177 + 178 + APPENDIX: How to apply the Apache License to your work. 179 + 180 + To apply the Apache License to your work, attach the following 181 + boilerplate notice, with the fields enclosed by brackets "{}" 182 + replaced with your own identifying information. (Don't include 183 + the brackets!) The text should be enclosed in the appropriate 184 + comment syntax for the file format. We also recommend that a 185 + file or class name and description of purpose be included on the 186 + same "printed page" as the copyright notice for easier 187 + identification within third-party archives. 188 + 189 + Copyright {yyyy} {name of copyright owner} 190 + 191 + Licensed under the Apache License, Version 2.0 (the "License"); 192 + you may not use this file except in compliance with the License. 193 + You may obtain a copy of the License at 194 + 195 + http://www.apache.org/licenses/LICENSE-2.0 196 + 197 + Unless required by applicable law or agreed to in writing, software 198 + distributed under the License is distributed on an "AS IS" BASIS, 199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 + See the License for the specific language governing permissions and 201 + limitations under the License. 202 +
+209
assets/js/device/node_modules/tessel-gpio-button/README.md
··· 1 + tessel-gpio-button 2 + ============= 3 + 4 + A button on Tessel's GPIO bank. 5 + 6 + * [Quick start](https://github.com/Frijol/tessel-button#quick-start-i-just-want-a-button) 7 + * [Theory of buttons](https://github.com/Frijol/tessel-button#why-add-a-button-over-the-gpio) 8 + * [Multiple buttons](https://github.com/Frijol/tessel-button#multiple-buttons) 9 + 10 + ## Quick start: I just want a button. 11 + 12 + Your button should have two wires sticking out of it. Plug in one side to ground, and the other to pin G3. 13 + 14 + ![](https://lh5.googleusercontent.com/-VFXEUYqlb2w/VCHwX6JIsnI/AAAAAAAAKak/XS4eqXJ5RmM/w913-h514-no/20140923_151215.jpg) 15 + 16 + Install: 17 + 18 + ```sh 19 + npm install tessel-gpio-button 20 + ``` 21 + Use: 22 + 23 + ```js 24 + // examples/button.js 25 + // Count button presses 26 + 27 + var tessel = require('tessel'); 28 + var buttonLib = require('../'); 29 + var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']); 30 + 31 + var i = 0; 32 + 33 + myButton.on('ready', function () { 34 + myButton.on('press', function () { 35 + i++; 36 + console.log('Press', i); 37 + }); 38 + 39 + myButton.on('release', function () { 40 + i++; 41 + console.log('Release', i); 42 + }); 43 + }); 44 + ``` 45 + 46 + Congratulations, you now have a button! 47 + 48 + ## How it works, and why 49 + 50 + ### Why add a button over the GPIO? 51 + Buttons are a nice, easy way to make your project interactive. Tessel comes with [API access to the Config button on the board](https://tessel.io/docs/hardwareAPI#buttons). For many use cases, this is enough. But perhaps you want more buttons, or buttons with a certain look or feel. That's where this tutorial will come in handy. 52 + 53 + ### What is a button, in terms of circuits? 54 + Electrically, a button is nothing more than a switch. One wire goes into the button; one wire comes out. When the button is pressed, the wires are connected. When not pressed, the wires are not connected. 55 + 56 + ### Making a button talk to Tessel 57 + Tessel communicates over 3.3V. That means that its [pins](https://tessel.io/docs/hardwareAPI#pins) operate between 0V and 3.3V. For a digital pin, 3.3V evaluates to "high" or 1 (truthy), and 0V evaluates to "low" or 0 (falsy). 58 + 59 + Tessel has six digital pins along the GPIO bank, marked G1-G6. Each of these pins is pulled high (3.3V) by default. In order to change the state of these pins from high to low, all you have to do is connect a digital pin to ground (GND). 60 + 61 + If you have a wire, you can try it out– plug in a wire (ideally black, for ground) in to the GND pin on Tessel's GPIO bank. While running the code below, try sticking the other end of the wire into G3: 62 + 63 + ![](https://lh4.googleusercontent.com/-sgF_HmYkKLs/VCIGYOqdtcI/AAAAAAAAKdY/8PmTATEWaII/w913-h514-no/20140923_164633.jpg) 64 + 65 + ```js 66 + // tutorial/polling-read.js 67 + // Read Tessel's GPIO pin G3 every 100ms 68 + 69 + var tessel = require('tessel'); 70 + var myPin = tessel.port['GPIO'].pin['G3']; 71 + 72 + setInterval(function readPin () { 73 + console.log(myPin.read()); 74 + }, 100); 75 + ``` 76 + 77 + You should see a stream of ones while the wire is not plugged in, and a stream of zeroes when it is plugged in. 78 + 79 + Okay, now let's try it with a button. It's basically the same thing. Unplug your Tessel (it's bad practice to mess around with wires while your Tessel is powered). Your button should have two wires sticking out of it. One of them should plug into GND; the other into pin G3. 80 + 81 + ![](https://lh5.googleusercontent.com/-VFXEUYqlb2w/VCHwX6JIsnI/AAAAAAAAKak/XS4eqXJ5RmM/w913-h514-no/20140923_151215.jpg) 82 + 83 + Run the same code, and try pressing the button. You should see zeroes when the button is pressed, and ones when the button is not pressed. 84 + 85 + ### Button events 86 + 87 + Tessel has [events](https://tessel.io/docs/hardwareAPI#api-pin-on-type-callback-time-type) for its pins. It fires an event each for `rise`, `fall`, and `change`. 88 + 89 + Since the signal falls to low when the button is pressed, and rises to high when the button is released, it seems like you should be able to just use `pin.on(fall, function () {})`. Let's try it and see what happens: 90 + 91 + ```js 92 + // tutorial/simple-event.js 93 + // Logs a message each time the pin falls 94 + 95 + var tessel = require('tessel'); 96 + var button = tessel.port['GPIO'].pin['G3']; 97 + 98 + var i = 0 99 + 100 + button.on('fall', function buttonPress () { 101 + i++; 102 + console.log('You pressed the button!', i); 103 + }); 104 + ``` 105 + 106 + If you have a really nice button, this might just work. However, if you have a cheap button like mine, the `fall` event will be emitted more than once per button press. This is because you are dealing with a mechanical system, and the electrical contact is actually bouncing a little bit on contact and messing up the signal. You can read about this phenomenon [here](http://en.wikipedia.org/wiki/Switch#Contact_bounce). 107 + 108 + ![](http://upload.wikimedia.org/wikipedia/commons/a/ac/Bouncy_Switch.png) 109 + 110 + In order to correct this problem, we need to do some software debouncing. 111 + 112 + Debouncing can be a very complicated problem if you need the ability to read the button several times a second (read a few approaches [here](http://www.embedded.com/electronics-blogs/break-points/4024981/My-favorite-software-debouncers)). However, for most applications, you can simply reduce the rate at which your events can fire. 113 + 114 + Let's try adding a delay timer to the event: 115 + 116 + ```js 117 + // tutorial/debounced-event.js 118 + // Logs a message at button presses that are sufficiently spaced 119 + 120 + var tessel = require('tessel'); 121 + var button = tessel.port['GPIO'].pin['G3']; 122 + 123 + var delay = 500; // Let's try every 500ms 124 + var ready = true; 125 + 126 + var i = 0 127 + 128 + button.on('fall', function () { 129 + if(ready) { 130 + buttonPress(); 131 + } 132 + }); 133 + 134 + function buttonPress () { 135 + i++; 136 + console.log('You pressed the button!', i); 137 + 138 + // Set a delay timer 139 + ready = false; 140 + setTimeout(function () { 141 + ready = true; 142 + }, delay); 143 + } 144 + ``` 145 + 146 + 500ms worked well for my button, but feel free to adjust the delay and see how long it takes for your button to stop bouncing. 147 + 148 + ### Wrapping the events 149 + For the sake of consistency, I've set up index.js of this folder [the same way we set up every module](http://blog.technical.io/post/94084496782/making-a-tessel-style-library-for-third-party-hardware), to emit an event on `press`. `press` and `release` are individually easy, but harder to have both due to our simple debouncing method. 150 + 151 + I've done something rather interesting to get around this in index.js; feel free to check it out (and PRs welcome if you can think of a better way). 152 + 153 + Here's some example code requiring index (or just `npm install tessel-gpio-button`): 154 + 155 + ```js 156 + // examples/button.js 157 + // Count button presses 158 + 159 + var tessel = require('tessel'); 160 + var buttonLib = require('../'); 161 + var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']); 162 + 163 + var i = 0; 164 + 165 + myButton.on('ready', function () { 166 + myButton.on('press', function () { 167 + i++; 168 + console.log('Press', i); 169 + }); 170 + 171 + myButton.on('release', function () { 172 + i++; 173 + console.log('Release', i); 174 + }); 175 + }); 176 + ``` 177 + 178 + ### Multiple buttons 179 + Say you want more than one button. Maybe you're making a game controller, or a musical instrument or something. So you have several buttons to connect. 180 + 181 + All you have to do is connect one side of each to ground, and the other side to a different digital pin. 182 + 183 + ![](https://lh6.googleusercontent.com/-Cr5us5zJ9SA/VCIBTDnpmqI/AAAAAAAAKcw/O-NE2P8AJOE/w913-h514-no/20140923_162433.jpg) 184 + 185 + Then make different instances for each button. Like this: 186 + 187 + ```js 188 + // examples/two-buttons.js 189 + // Log button presses from two different buttons 190 + 191 + var tessel = require('tessel'); 192 + var buttonLib = require('tessel-gpio-button'); 193 + 194 + var button1 = buttonLib.use(tessel.port['GPIO'].pin['G3']); 195 + var button2 = buttonLib.use(tessel.port['GPIO'].pin['G2']); 196 + 197 + button1.on('press', function () { 198 + console.log('Pressing button 1.'); 199 + }); 200 + 201 + button2.on('press', function () { 202 + console.log('Pressing button 2.'); 203 + }); 204 + ``` 205 + Pressing the different buttons will give you different messages. 206 + 207 + Note that I used a breadboard to connect several buttons to the same ground. If you're interested/want to know more about breadboards, [this](http://www.instructables.com/id/Breadboard-How-To/) is a really good place to start. 208 + 209 + That's all! Enjoy.
+20
assets/js/device/node_modules/tessel-gpio-button/examples/button.js
··· 1 + // examples/button.js 2 + // Count button presses 3 + 4 + var tessel = require('tessel'); 5 + var buttonLib = require('../'); 6 + var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']); 7 + 8 + var i = 0; 9 + 10 + myButton.on('ready', function () { 11 + myButton.on('press', function () { 12 + i++; 13 + console.log('Press', i); 14 + }); 15 + 16 + myButton.on('release', function () { 17 + i++; 18 + console.log('Release', i); 19 + }); 20 + });
+16
assets/js/device/node_modules/tessel-gpio-button/examples/two-buttons.js
··· 1 + // examples/two-buttons.js 2 + // Log button presses from two different buttons 3 + 4 + var tessel = require('tessel'); 5 + var buttonLib = require('../'); 6 + 7 + var button1 = buttonLib.use(tessel.port['GPIO'].pin['G3']); 8 + var button2 = buttonLib.use(tessel.port['GPIO'].pin['G2']); 9 + 10 + button1.on('press', function () { 11 + console.log('Pressing button 1.'); 12 + }); 13 + 14 + button2.on('press', function () { 15 + console.log('Pressing button 2.'); 16 + });
+89
assets/js/device/node_modules/tessel-gpio-button/index.js
··· 1 + // Any dependencies, notably the event emitter utility 2 + var util = require('util'); 3 + var EventEmitter = require('events').EventEmitter; 4 + 5 + // Constructor function to instantiate the hardware object 6 + function Button (hardware, callback) { 7 + var self = this; 8 + 9 + // Check to ensure proper hardware has been passed in 10 + if (typeof hardware.pin != 'number') { 11 + // Pin not specified 12 + var error = new Error("Specify a pin, e.g. tessel.port['GPIO'].pin['G3']"); 13 + self.emit('error', error); 14 + if(callback) { 15 + callback(error); 16 + } 17 + } else if ([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 34, 35, 36, 37, 38, 39].indexOf(hardware.pin) < 0) { 18 + // Not a digital pin 19 + var error = new Error('Specified pin is not a digital pin: ' + hardware.pin); 20 + self.emit('error', error); 21 + if(callback) { 22 + callback(error); 23 + } 24 + } 25 + 26 + // Set hardware connection of the object 27 + self.hardware = hardware; 28 + 29 + // Object properties 30 + self.delay = 100; 31 + self.pressed = false; 32 + 33 + // Begin listening for events 34 + self.hardware.on('fall', function () { 35 + self._press(); 36 + }); 37 + 38 + self.hardware.on('rise', function () { 39 + self._release(); 40 + }); 41 + 42 + // Make sure the events get emitted, even if late 43 + setInterval(function () { 44 + if(!self.hardware.read()) { 45 + self._press(); 46 + } else { 47 + self._release(); 48 + } 49 + }, self.delay); 50 + 51 + // Emit the ready event when everything is set up 52 + setImmediate(function emitReady() { 53 + self.emit('ready'); 54 + }); 55 + // Call the callback with object 56 + if (callback) { 57 + callback(null, self); 58 + } 59 + } 60 + 61 + // Inherit event emission 62 + util.inherits(Button, EventEmitter); 63 + 64 + Button.prototype._press = function () { 65 + var self = this; 66 + 67 + if(!self.pressed) { 68 + self.emit('press'); 69 + self.pressed = true; 70 + } 71 + } 72 + 73 + Button.prototype._release = function () { 74 + var self = this; 75 + 76 + if(self.pressed) { 77 + self.emit('release'); 78 + self.pressed = false; 79 + } 80 + } 81 + 82 + // Use function which calls the constructor 83 + function use (hardware, callback) { 84 + return new Button(hardware, callback); 85 + } 86 + 87 + // Export functions 88 + exports.Button = Button; 89 + exports.use = use;
+51
assets/js/device/node_modules/tessel-gpio-button/package.json
··· 1 + { 2 + "name": "tessel-gpio-button", 3 + "version": "1.1.0", 4 + "description": "\"A button on Tessel's GPIO\"", 5 + "main": "index.js", 6 + "scripts": { 7 + "test": "echo \"Error: no test specified\" && exit 1" 8 + }, 9 + "repository": { 10 + "type": "git", 11 + "url": "https://github.com/Frijol/tessel-button.git" 12 + }, 13 + "keywords": [ 14 + "tessel", 15 + "button" 16 + ], 17 + "author": { 18 + "name": "Kelsey Breseman" 19 + }, 20 + "license": "Apache 2.0", 21 + "bugs": { 22 + "url": "https://github.com/Frijol/tessel-button/issues" 23 + }, 24 + "hardware": { 25 + "./examples": false, 26 + "./tutorial": false 27 + }, 28 + "homepage": "https://github.com/Frijol/tessel-button", 29 + "gitHead": "71624918cf4530c9191b9e73f668edd65faf55a2", 30 + "_id": "tessel-gpio-button@1.1.0", 31 + "_shasum": "aa1729201b546185c3d281394431db3a4d83d8fc", 32 + "_from": "tessel-gpio-button@*", 33 + "_npmVersion": "1.4.23", 34 + "_npmUser": { 35 + "name": "frijol", 36 + "email": "ifoundthemeaningoflife@gmail.com" 37 + }, 38 + "maintainers": [ 39 + { 40 + "name": "frijol", 41 + "email": "ifoundthemeaningoflife@gmail.com" 42 + } 43 + ], 44 + "dist": { 45 + "shasum": "aa1729201b546185c3d281394431db3a4d83d8fc", 46 + "tarball": "http://registry.npmjs.org/tessel-gpio-button/-/tessel-gpio-button-1.1.0.tgz" 47 + }, 48 + "directories": {}, 49 + "_resolved": "https://registry.npmjs.org/tessel-gpio-button/-/tessel-gpio-button-1.1.0.tgz", 50 + "readme": "ERROR: No README data found!" 51 + }
+27
assets/js/device/node_modules/tessel-gpio-button/tutorial/debounced-event.js
··· 1 + // debounced-event.js 2 + // Logs a message at button presses that are sufficiently spaced 3 + 4 + var tessel = require('tessel'); 5 + var button = tessel.port['GPIO'].pin['G3']; 6 + 7 + var delay = 500; // Let's try every 500ms 8 + var ready = true; 9 + 10 + var i = 0 11 + 12 + button.on('fall', function () { 13 + if(ready) { 14 + buttonPress(); 15 + } 16 + }); 17 + 18 + function buttonPress () { 19 + i++; 20 + console.log('You pressed the button!', i); 21 + 22 + // Set a delay timer 23 + ready = false; 24 + setTimeout(function () { 25 + ready = true; 26 + }, delay); 27 + }
+8
assets/js/device/node_modules/tessel-gpio-button/tutorial/polling-read.js
··· 1 + // Read Tessel's GPIO pin G3 every 100ms 2 + 3 + var tessel = require('tessel'); 4 + var myPin = tessel.port['GPIO'].pin['G3']; 5 + 6 + setInterval(function readPin () { 7 + console.log(myPin.read()); 8 + }, 100);
+12
assets/js/device/node_modules/tessel-gpio-button/tutorial/simple-event.js
··· 1 + // simple-event.js 2 + // Logs a message each time the pin falls 3 + 4 + var tessel = require('tessel'); 5 + var button = tessel.port['GPIO'].pin['G3']; 6 + 7 + var i = 0 8 + 9 + button.on('fall', function buttonPress () { 10 + i++; 11 + console.log('You pressed the button!', i); 12 + });
+2 -1
assets/js/device/package.json
··· 8 8 "author": "Kaushik", 9 9 "license": "Public Domain", 10 10 "dependencies": { 11 - "accel-mma84": "^0.2.3" 11 + "accel-mma84": "^0.2.3", 12 + "tessel-gpio-button": "^1.1.0" 12 13 } 13 14 }
+89 -28
assets/js/gl.js
··· 1 - var x_from_tessel = 0.01; 2 - var y_from_tessel = 0.01; 1 + var x_from_tessel_A = 0.01; 2 + var y_from_tessel_A = 0.01; 3 + var x_from_tessel_B = 0.01; 4 + var y_from_tessel_B = 0.01; 3 5 var prev_x = 0.01 4 6 var prev_y = 0.01 5 7 console.log("here"); ··· 7 9 var socket = io('http://localhost:8000'); 8 10 socket.on('t_data', function(data) { 9 11 //console.log(data.message.x); 10 - if (data.message.x !== undefined) { 11 - x_from_tessel = data.message.x; 12 + 13 + if (data.message.port === "gpio"){ 14 + if (data.message.event === "release"){ 15 + saveScreenShot(); 16 + } 12 17 } 13 - if (data.message.y !== undefined) { 14 - y_from_tessel = data.message.y; 18 + 19 + if (data.message.port === "A") { 20 + if (data.message.x !== undefined) { 21 + x_from_tessel_A = data.message.x; 22 + } 23 + if (data.message.y !== undefined) { 24 + y_from_tessel_A = data.message.y; 25 + } 26 + } 27 + 28 + if (data.message.port === "B") { 29 + if (data.message.x !== undefined) { 30 + x_from_tessel_B = data.message.x; 31 + } 32 + if (data.message.y !== undefined) { 33 + y_from_tessel_B = data.message.y; 34 + } 15 35 } 36 + 16 37 17 38 //socket.emit('ping', { my: 'hello from client' }); 18 39 }); 40 + 41 + socket.on("sc-succ", function(data) { 42 + 43 + if (data.status === 1) { 44 + 45 + document.getElementById("submittedSC").src = "assets/images/cropData.png?g="+Date.now(); 46 + document.getElementById("submittedSC").className = document.getElementById("submittedSC").className + " show"; 47 + } 48 + 49 + }); 50 + 51 + socket.on("win", function(data){ 52 + if (data.status === 1){ 53 + window.message = "asd"; 54 + } 55 + }); 19 56 socket.emit('ping', { 20 57 my: 'hello from client' 21 58 }); ··· 28 65 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.0001, 100000); 29 66 30 67 var renderer = new THREE.WebGLRenderer({ 31 - antialias: true 68 + antialias: true, 69 + preserveDrawingBuffer: true 32 70 }); 33 71 renderer.setSize(window.innerWidth, window.innerHeight); 34 72 renderer.shadowMapEnabled = true ··· 53 91 spotLight.shadowCameraNear = 0.1; 54 92 spotLight.castShadow = true; 55 93 spotLight.shadowDarkness = 0.5; 56 - spotLight.shadowCameraVisible = true; 94 + // spotLight.shadowCameraVisible = true; 57 95 scene.add(spotLight); 58 96 59 97 onRenderFcts.push(function() { ··· 137 175 // cube.rotation.x += 0.01; 138 176 // cube.rotation.y += 0.01; 139 177 140 - if (x_from_tessel !== prev_x) { 141 - cube.rotation.x += x_from_tessel / 2; 142 - prev_x = x_from_tessel; 178 + if (x_from_tessel_A !== prev_x) { 179 + cube.rotation.x += x_from_tessel_A / 2; 180 + prev_x = x_from_tessel_A; 143 181 } 144 182 145 183 146 - if (y_from_tessel !== prev_y) { 147 - cube.rotation.y += y_from_tessel / 2; 148 - prev_y = y_from_tessel; 184 + if (y_from_tessel_A !== prev_y) { 185 + cube.rotation.y += y_from_tessel_A / 2; 186 + prev_y = y_from_tessel_A; 149 187 } 150 188 151 189 //var angle = Date.now()/1000 * Math.PI; 152 - // var angleX = prev_x/1000 * Math.PI; 153 - // var angleY = prev_y/1000 * Math.PI; 154 - 155 - // // if (angleX * 10000 * -1 <= 1.0){ 156 - // console.log(angleX * 10000 * -1); 157 - // spotLight.position.x += Math.cos(angleX*-0.1)*20; 158 - // // } 159 - // // if (angleY * 10000 <= 1.0){ 160 - // console.log(angleY * 10000); 161 - // spotLight.position.y += 10 + Math.sin(angleY*0.5)*6; 162 - // } 163 - 164 - //spotLight.position.z = Math.sin(angle*-0.1)*20; 190 + // console.log("B",x_from_tessel_B); 191 + // console.log("A",x_from_tessel_A); 192 + var prev_x_B = 0.01; 193 + if (x_from_tessel_B !== prev_x_B) { 194 + spotLight.position.x = x_from_tessel_B * Math.PI + spotLight.position.x; 195 + prev_x_B = x_from_tessel_B; 196 + } 197 + 198 + // var angleY = y_from_tessel_B/1000 * Math.PI; 199 + 200 + // // if (angleX * 10000 * -1 <= 1.0){ 201 + // //console.log(angleX * 10000 * -1); 202 + // spotLight.position.x += Math.cos(angleX*-0.1)*20; 203 + // // } 204 + // // if (angleY * 10000 <= 1.0){ 205 + // // console.log(angleY * 10000); 206 + // spotLight.position.y += 10 + Math.sin(angleY*0.5)*6; 207 + //} 208 + 209 + //spotLight.position.z = Math.sin(angle*-0.1)*20; 165 210 166 211 167 212 lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60 ··· 175 220 176 221 camera.lookAt(scene.position) 177 222 178 - 179 223 renderer.render(scene, camera); 180 224 }; 225 + 226 + var saveScreenShot = function() { 227 + var dataURL = THREEx.Screenshot.toDataURL(renderer); 228 + console.log(dataURL); 229 + // if (width === undefined && height === undefined) { 230 + // post to node 231 + socket.emit('sc', { 232 + data: dataURL 233 + }); 234 + // } else { 235 + // // resize it and notify the callback 236 + // // * resize == async so if callback is a window open, it triggers the pop blocker 237 + // _aspectResize(dataUrl, width, height, callback); 238 + // } 239 + } 240 + 241 + 181 242 182 243 render();
+40 -1
assets/js/plugins/socketio/index.js
··· 2 2 console.log("socket io plugin"); 3 3 var tessel = require('tessel'); 4 4 var socket = require('socket.io').listen(server.listener); 5 + var fs = require('fs'); 6 + var gm = require('gm') 5 7 var script = require.resolve('../../device/index.js'); 6 8 var opts = { 7 9 // Stop existing script, if any ··· 51 53 52 54 socket.on("connection", function(socket) { 53 55 socket.on("ping", function(data) { 54 - console.log(data); 55 56 socket.emit("pong", { 56 57 message: "pong" 57 58 }); 58 59 }); 60 + 61 + socket.on("sc", function(data) { 62 + var regex = /^data:.+\/(.+);base64,(.*)$/; 63 + 64 + var matches = data.data.match(regex); 65 + var ext = matches[1]; 66 + var data1 = matches[2]; 67 + var buffer = new Buffer(data1, 'base64'); 68 + fs.writeFileSync('data.' + ext, buffer); 69 + 70 + gm('/Users/139137_local/projects/mit_proj/data.png').options({imageMagick: true}).crop(1213,322,0,480).resize(520,210).write('/Users/139137_local/projects/mit_proj/assets/images/cropData.png',function(err){ 71 + console.log(err); 72 + }); 73 + 74 + gm.compare('/Users/139137_local/projects/mit_proj/assets/images/cropData.png','/Users/139137_local/projects/mit_proj/assets/images/sample.png',function(err,isEqual,equality){ 75 + console.log(equality); 76 + console.log(equality*100); 77 + 78 + // if ((equality*100) > 50 & (equality*100) <= 51.5){ 79 + // console.log((equality*100) > 50 & (equality*100) <= 51.5); 80 + // socket.emit("win",{ 81 + // status: 1 82 + // }); 83 + // } 84 + 85 + }); 86 + 87 + // gm('/Users/139137_local/projects/mit_proj/sample.png').resize(240,240).noProfile().write('/Users/139137_local/projects/mit_proj/resizeSample.png',function(err){ 88 + // console.log(err); 89 + // }); 90 + 91 + socket.emit("sc-succ",{ 92 + status : 1 93 + }); 94 + 95 + }); 59 96 }); 97 + 98 + 60 99 next(); 61 100 }; 62 101
+3
assets/js/socket.io-1.3.0.js
··· 1 + !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return 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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module,exports){module.exports=_dereq_("./lib/")},{"./lib/":2}],2:[function(_dereq_,module,exports){var url=_dereq_("./url");var parser=_dereq_("socket.io-parser");var Manager=_dereq_("./manager");var debug=_dereq_("debug")("socket.io-client");module.exports=exports=lookup;var cache=exports.managers={};function lookup(uri,opts){if(typeof uri=="object"){opts=uri;uri=undefined}opts=opts||{};var parsed=url(uri);var source=parsed.source;var id=parsed.id;var io;if(opts.forceNew||opts["force new connection"]||false===opts.multiplex){debug("ignoring socket cache for %s",source);io=Manager(source,opts)}else{if(!cache[id]){debug("new io instance for %s",source);cache[id]=Manager(source,opts)}io=cache[id]}return io.socket(parsed.path)}exports.protocol=parser.protocol;exports.connect=lookup;exports.Manager=_dereq_("./manager");exports.Socket=_dereq_("./socket")},{"./manager":3,"./socket":5,"./url":6,debug:10,"socket.io-parser":44}],3:[function(_dereq_,module,exports){var url=_dereq_("./url");var eio=_dereq_("engine.io-client");var Socket=_dereq_("./socket");var Emitter=_dereq_("component-emitter");var parser=_dereq_("socket.io-parser");var on=_dereq_("./on");var bind=_dereq_("component-bind");var object=_dereq_("object-component");var debug=_dereq_("debug")("socket.io-client:manager");var indexOf=_dereq_("indexof");var Backoff=_dereq_("backo2");module.exports=Manager;function Manager(uri,opts){if(!(this instanceof Manager))return new Manager(uri,opts);if(uri&&"object"==typeof uri){opts=uri;uri=undefined}opts=opts||{};opts.path=opts.path||"/socket.io";this.nsps={};this.subs=[];this.opts=opts;this.reconnection(opts.reconnection!==false);this.reconnectionAttempts(opts.reconnectionAttempts||Infinity);this.reconnectionDelay(opts.reconnectionDelay||1e3);this.reconnectionDelayMax(opts.reconnectionDelayMax||5e3);this.randomizationFactor(opts.randomizationFactor||.5);this.backoff=new Backoff({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()});this.timeout(null==opts.timeout?2e4:opts.timeout);this.readyState="closed";this.uri=uri;this.connected=[];this.encoding=false;this.packetBuffer=[];this.encoder=new parser.Encoder;this.decoder=new parser.Decoder;this.autoConnect=opts.autoConnect!==false;if(this.autoConnect)this.open()}Manager.prototype.emitAll=function(){this.emit.apply(this,arguments);for(var nsp in this.nsps){this.nsps[nsp].emit.apply(this.nsps[nsp],arguments)}};Manager.prototype.updateSocketIds=function(){for(var nsp in this.nsps){this.nsps[nsp].id=this.engine.id}};Emitter(Manager.prototype);Manager.prototype.reconnection=function(v){if(!arguments.length)return this._reconnection;this._reconnection=!!v;return this};Manager.prototype.reconnectionAttempts=function(v){if(!arguments.length)return this._reconnectionAttempts;this._reconnectionAttempts=v;return this};Manager.prototype.reconnectionDelay=function(v){if(!arguments.length)return this._reconnectionDelay;this._reconnectionDelay=v;this.backoff&&this.backoff.setMin(v);return this};Manager.prototype.randomizationFactor=function(v){if(!arguments.length)return this._randomizationFactor;this._randomizationFactor=v;this.backoff&&this.backoff.setJitter(v);return this};Manager.prototype.reconnectionDelayMax=function(v){if(!arguments.length)return this._reconnectionDelayMax;this._reconnectionDelayMax=v;this.backoff&&this.backoff.setMax(v);return this};Manager.prototype.timeout=function(v){if(!arguments.length)return this._timeout;this._timeout=v;return this};Manager.prototype.maybeReconnectOnOpen=function(){if(!this.reconnecting&&this._reconnection&&this.backoff.attempts===0){this.reconnect()}};Manager.prototype.open=Manager.prototype.connect=function(fn){debug("readyState %s",this.readyState);if(~this.readyState.indexOf("open"))return this;debug("opening %s",this.uri);this.engine=eio(this.uri,this.opts);var socket=this.engine;var self=this;this.readyState="opening";this.skipReconnect=false;var openSub=on(socket,"open",function(){self.onopen();fn&&fn()});var errorSub=on(socket,"error",function(data){debug("connect_error");self.cleanup();self.readyState="closed";self.emitAll("connect_error",data);if(fn){var err=new Error("Connection error");err.data=data;fn(err)}else{self.maybeReconnectOnOpen()}});if(false!==this._timeout){var timeout=this._timeout;debug("connect attempt will timeout after %d",timeout);var timer=setTimeout(function(){debug("connect attempt timed out after %d",timeout);openSub.destroy();socket.close();socket.emit("error","timeout");self.emitAll("connect_timeout",timeout)},timeout);this.subs.push({destroy:function(){clearTimeout(timer)}})}this.subs.push(openSub);this.subs.push(errorSub);return this};Manager.prototype.onopen=function(){debug("open");this.cleanup();this.readyState="open";this.emit("open");var socket=this.engine;this.subs.push(on(socket,"data",bind(this,"ondata")));this.subs.push(on(this.decoder,"decoded",bind(this,"ondecoded")));this.subs.push(on(socket,"error",bind(this,"onerror")));this.subs.push(on(socket,"close",bind(this,"onclose")))};Manager.prototype.ondata=function(data){this.decoder.add(data)};Manager.prototype.ondecoded=function(packet){this.emit("packet",packet)};Manager.prototype.onerror=function(err){debug("error",err);this.emitAll("error",err)};Manager.prototype.socket=function(nsp){var socket=this.nsps[nsp];if(!socket){socket=new Socket(this,nsp);this.nsps[nsp]=socket;var self=this;socket.on("connect",function(){socket.id=self.engine.id;if(!~indexOf(self.connected,socket)){self.connected.push(socket)}})}return socket};Manager.prototype.destroy=function(socket){var index=indexOf(this.connected,socket);if(~index)this.connected.splice(index,1);if(this.connected.length)return;this.close()};Manager.prototype.packet=function(packet){debug("writing packet %j",packet);var self=this;if(!self.encoding){self.encoding=true;this.encoder.encode(packet,function(encodedPackets){for(var i=0;i<encodedPackets.length;i++){self.engine.write(encodedPackets[i])}self.encoding=false;self.processPacketQueue()})}else{self.packetBuffer.push(packet)}};Manager.prototype.processPacketQueue=function(){if(this.packetBuffer.length>0&&!this.encoding){var pack=this.packetBuffer.shift();this.packet(pack)}};Manager.prototype.cleanup=function(){var sub;while(sub=this.subs.shift())sub.destroy();this.packetBuffer=[];this.encoding=false;this.decoder.destroy()};Manager.prototype.close=Manager.prototype.disconnect=function(){this.skipReconnect=true;this.backoff.reset();this.readyState="closed";this.engine&&this.engine.close()};Manager.prototype.onclose=function(reason){debug("close");this.cleanup();this.backoff.reset();this.readyState="closed";this.emit("close",reason);if(this._reconnection&&!this.skipReconnect){this.reconnect()}};Manager.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var self=this;if(this.backoff.attempts>=this._reconnectionAttempts){debug("reconnect failed");this.backoff.reset();this.emitAll("reconnect_failed");this.reconnecting=false}else{var delay=this.backoff.duration();debug("will wait %dms before reconnect attempt",delay);this.reconnecting=true;var timer=setTimeout(function(){if(self.skipReconnect)return;debug("attempting reconnect");self.emitAll("reconnect_attempt",self.backoff.attempts);self.emitAll("reconnecting",self.backoff.attempts);if(self.skipReconnect)return;self.open(function(err){if(err){debug("reconnect attempt error");self.reconnecting=false;self.reconnect();self.emitAll("reconnect_error",err.data)}else{debug("reconnect success");self.onreconnect()}})},delay);this.subs.push({destroy:function(){clearTimeout(timer)}})}};Manager.prototype.onreconnect=function(){var attempt=this.backoff.attempts;this.reconnecting=false;this.backoff.reset();this.updateSocketIds();this.emitAll("reconnect",attempt)}},{"./on":4,"./socket":5,"./url":6,backo2:7,"component-bind":8,"component-emitter":9,debug:10,"engine.io-client":11,indexof:40,"object-component":41,"socket.io-parser":44}],4:[function(_dereq_,module,exports){module.exports=on;function on(obj,ev,fn){obj.on(ev,fn);return{destroy:function(){obj.removeListener(ev,fn)}}}},{}],5:[function(_dereq_,module,exports){var parser=_dereq_("socket.io-parser");var Emitter=_dereq_("component-emitter");var toArray=_dereq_("to-array");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:socket");var hasBin=_dereq_("has-binary");module.exports=exports=Socket;var events={connect:1,connect_error:1,connect_timeout:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1};var emit=Emitter.prototype.emit;function Socket(io,nsp){this.io=io;this.nsp=nsp;this.json=this;this.ids=0;this.acks={};if(this.io.autoConnect)this.open();this.receiveBuffer=[];this.sendBuffer=[];this.connected=false;this.disconnected=true}Emitter(Socket.prototype);Socket.prototype.subEvents=function(){if(this.subs)return;var io=this.io;this.subs=[on(io,"open",bind(this,"onopen")),on(io,"packet",bind(this,"onpacket")),on(io,"close",bind(this,"onclose"))]};Socket.prototype.open=Socket.prototype.connect=function(){if(this.connected)return this;this.subEvents();this.io.open();if("open"==this.io.readyState)this.onopen();return this};Socket.prototype.send=function(){var args=toArray(arguments);args.unshift("message");this.emit.apply(this,args);return this};Socket.prototype.emit=function(ev){if(events.hasOwnProperty(ev)){emit.apply(this,arguments);return this}var args=toArray(arguments);var parserType=parser.EVENT;if(hasBin(args)){parserType=parser.BINARY_EVENT}var packet={type:parserType,data:args};if("function"==typeof args[args.length-1]){debug("emitting packet with ack id %d",this.ids);this.acks[this.ids]=args.pop();packet.id=this.ids++}if(this.connected){this.packet(packet)}else{this.sendBuffer.push(packet)}return this};Socket.prototype.packet=function(packet){packet.nsp=this.nsp;this.io.packet(packet)};Socket.prototype.onopen=function(){debug("transport is open - connecting");if("/"!=this.nsp){this.packet({type:parser.CONNECT})}};Socket.prototype.onclose=function(reason){debug("close (%s)",reason);this.connected=false;this.disconnected=true;delete this.id;this.emit("disconnect",reason)};Socket.prototype.onpacket=function(packet){if(packet.nsp!=this.nsp)return;switch(packet.type){case parser.CONNECT:this.onconnect();break;case parser.EVENT:this.onevent(packet);break;case parser.BINARY_EVENT:this.onevent(packet);break;case parser.ACK:this.onack(packet);break;case parser.BINARY_ACK:this.onack(packet);break;case parser.DISCONNECT:this.ondisconnect();break;case parser.ERROR:this.emit("error",packet.data);break}};Socket.prototype.onevent=function(packet){var args=packet.data||[];debug("emitting event %j",args);if(null!=packet.id){debug("attaching ack callback to event");args.push(this.ack(packet.id))}if(this.connected){emit.apply(this,args)}else{this.receiveBuffer.push(args)}};Socket.prototype.ack=function(id){var self=this;var sent=false;return function(){if(sent)return;sent=true;var args=toArray(arguments);debug("sending ack %j",args);var type=hasBin(args)?parser.BINARY_ACK:parser.ACK;self.packet({type:type,id:id,data:args})}};Socket.prototype.onack=function(packet){debug("calling ack %s with %j",packet.id,packet.data);var fn=this.acks[packet.id];fn.apply(this,packet.data);delete this.acks[packet.id]};Socket.prototype.onconnect=function(){this.connected=true;this.disconnected=false;this.emit("connect");this.emitBuffered()};Socket.prototype.emitBuffered=function(){var i;for(i=0;i<this.receiveBuffer.length;i++){emit.apply(this,this.receiveBuffer[i])}this.receiveBuffer=[];for(i=0;i<this.sendBuffer.length;i++){this.packet(this.sendBuffer[i])}this.sendBuffer=[]};Socket.prototype.ondisconnect=function(){debug("server disconnect (%s)",this.nsp);this.destroy();this.onclose("io server disconnect")};Socket.prototype.destroy=function(){if(this.subs){for(var i=0;i<this.subs.length;i++){this.subs[i].destroy()}this.subs=null}this.io.destroy(this)};Socket.prototype.close=Socket.prototype.disconnect=function(){if(this.connected){debug("performing disconnect (%s)",this.nsp);this.packet({type:parser.DISCONNECT})}this.destroy();if(this.connected){this.onclose("io client disconnect")}return this}},{"./on":4,"component-bind":8,"component-emitter":9,debug:10,"has-binary":36,"socket.io-parser":44,"to-array":48}],6:[function(_dereq_,module,exports){(function(global){var parseuri=_dereq_("parseuri");var debug=_dereq_("debug")("socket.io-client:url");module.exports=url;function url(uri,loc){var obj=uri;var loc=loc||global.location;if(null==uri)uri=loc.protocol+"//"+loc.host;if("string"==typeof uri){if("/"==uri.charAt(0)){if("/"==uri.charAt(1)){uri=loc.protocol+uri}else{uri=loc.hostname+uri}}if(!/^(https?|wss?):\/\//.test(uri)){debug("protocol-less url %s",uri);if("undefined"!=typeof loc){uri=loc.protocol+"//"+uri}else{uri="https://"+uri}}debug("parse %s",uri);obj=parseuri(uri)}if(!obj.port){if(/^(http|ws)$/.test(obj.protocol)){obj.port="80"}else if(/^(http|ws)s$/.test(obj.protocol)){obj.port="443"}}obj.path=obj.path||"/";obj.id=obj.protocol+"://"+obj.host+":"+obj.port;obj.href=obj.protocol+"://"+obj.host+(loc&&loc.port==obj.port?"":":"+obj.port);return obj}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{debug:10,parseuri:42}],7:[function(_dereq_,module,exports){module.exports=Backoff;function Backoff(opts){opts=opts||{};this.ms=opts.min||100;this.max=opts.max||1e4;this.factor=opts.factor||2;this.jitter=opts.jitter>0&&opts.jitter<=1?opts.jitter:0;this.attempts=0}Backoff.prototype.duration=function(){var ms=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var rand=Math.random();var deviation=Math.floor(rand*this.jitter*ms);ms=(Math.floor(rand*10)&1)==0?ms-deviation:ms+deviation}return Math.min(ms,this.max)|0};Backoff.prototype.reset=function(){this.attempts=0};Backoff.prototype.setMin=function(min){this.ms=min};Backoff.prototype.setMax=function(max){this.max=max};Backoff.prototype.setJitter=function(jitter){this.jitter=jitter}},{}],8:[function(_dereq_,module,exports){var slice=[].slice;module.exports=function(obj,fn){if("string"==typeof fn)fn=obj[fn];if("function"!=typeof fn)throw new Error("bind() requires a function");var args=slice.call(arguments,2);return function(){return fn.apply(obj,args.concat(slice.call(arguments)))}}},{}],9:[function(_dereq_,module,exports){module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks[event]=this._callbacks[event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){var self=this;this._callbacks=this._callbacks||{};function on(){self.off(event,on);fn.apply(this,arguments)}on.fn=fn;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks[event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks[event];return this}var cb;for(var i=0;i<callbacks.length;i++){cb=callbacks[i];if(cb===fn||cb.fn===fn){callbacks.splice(i,1);break}}return this};Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks[event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;i<len;++i){callbacks[i].apply(this,args)}}return this};Emitter.prototype.listeners=function(event){this._callbacks=this._callbacks||{};return this._callbacks[event]||[]};Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{}],10:[function(_dereq_,module,exports){module.exports=debug;function debug(name){if(!debug.enabled(name))return function(){};return function(fmt){fmt=coerce(fmt);var curr=new Date;var ms=curr-(debug[name]||curr);debug[name]=curr;fmt=name+" "+fmt+" +"+debug.humanize(ms);window.console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}}debug.names=[];debug.skips=[];debug.enable=function(name){try{localStorage.debug=name}catch(e){}var split=(name||"").split(/[\s,]+/),len=split.length;for(var i=0;i<len;i++){name=split[i].replace("*",".*?");if(name[0]==="-"){debug.skips.push(new RegExp("^"+name.substr(1)+"$"))}else{debug.names.push(new RegExp("^"+name+"$"))}}};debug.disable=function(){debug.enable("")};debug.humanize=function(ms){var sec=1e3,min=60*1e3,hour=60*min;if(ms>=hour)return(ms/hour).toFixed(1)+"h";if(ms>=min)return(ms/min).toFixed(1)+"m";if(ms>=sec)return(ms/sec|0)+"s";return ms+"ms"};debug.enabled=function(name){for(var i=0,len=debug.skips.length;i<len;i++){if(debug.skips[i].test(name)){return false}}for(var i=0,len=debug.names.length;i<len;i++){if(debug.names[i].test(name)){return true}}return false};function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}try{if(window.localStorage)debug.enable(localStorage.debug)}catch(e){}},{}],11:[function(_dereq_,module,exports){module.exports=_dereq_("./lib/")},{"./lib/":12}],12:[function(_dereq_,module,exports){module.exports=_dereq_("./socket");module.exports.parser=_dereq_("engine.io-parser")},{"./socket":13,"engine.io-parser":25}],13:[function(_dereq_,module,exports){(function(global){var transports=_dereq_("./transports");var Emitter=_dereq_("component-emitter");var debug=_dereq_("debug")("engine.io-client:socket");var index=_dereq_("indexof");var parser=_dereq_("engine.io-parser");var parseuri=_dereq_("parseuri");var parsejson=_dereq_("parsejson");var parseqs=_dereq_("parseqs");module.exports=Socket;function noop(){}function Socket(uri,opts){if(!(this instanceof Socket))return new Socket(uri,opts);opts=opts||{};if(uri&&"object"==typeof uri){opts=uri;uri=null}if(uri){uri=parseuri(uri);opts.host=uri.host;opts.secure=uri.protocol=="https"||uri.protocol=="wss";opts.port=uri.port;if(uri.query)opts.query=uri.query}this.secure=null!=opts.secure?opts.secure:global.location&&"https:"==location.protocol;if(opts.host){var pieces=opts.host.split(":");opts.hostname=pieces.shift();if(pieces.length)opts.port=pieces.pop()}this.agent=opts.agent||false;this.hostname=opts.hostname||(global.location?location.hostname:"localhost");this.port=opts.port||(global.location&&location.port?location.port:this.secure?443:80);this.query=opts.query||{};if("string"==typeof this.query)this.query=parseqs.decode(this.query);this.upgrade=false!==opts.upgrade;this.path=(opts.path||"/engine.io").replace(/\/$/,"")+"/";this.forceJSONP=!!opts.forceJSONP;this.jsonp=false!==opts.jsonp;this.forceBase64=!!opts.forceBase64;this.enablesXDR=!!opts.enablesXDR;this.timestampParam=opts.timestampParam||"t";this.timestampRequests=opts.timestampRequests;this.transports=opts.transports||["polling","websocket"];this.readyState="";this.writeBuffer=[];this.callbackBuffer=[];this.policyPort=opts.policyPort||843;this.rememberUpgrade=opts.rememberUpgrade||false;this.open();this.binaryType=null;this.onlyBinaryUpgrades=opts.onlyBinaryUpgrades}Socket.priorWebsocketSuccess=false;Emitter(Socket.prototype);Socket.protocol=parser.protocol;Socket.Socket=Socket;Socket.Transport=_dereq_("./transport");Socket.transports=_dereq_("./transports");Socket.parser=_dereq_("engine.io-parser");Socket.prototype.createTransport=function(name){debug('creating transport "%s"',name);var query=clone(this.query);query.EIO=parser.protocol;query.transport=name;if(this.id)query.sid=this.id;var transport=new transports[name]({agent:this.agent,hostname:this.hostname,port:this.port,secure:this.secure,path:this.path,query:query,forceJSONP:this.forceJSONP,jsonp:this.jsonp,forceBase64:this.forceBase64,enablesXDR:this.enablesXDR,timestampRequests:this.timestampRequests,timestampParam:this.timestampParam,policyPort:this.policyPort,socket:this});return transport};function clone(obj){var o={};for(var i in obj){if(obj.hasOwnProperty(i)){o[i]=obj[i]}}return o}Socket.prototype.open=function(){var transport;if(this.rememberUpgrade&&Socket.priorWebsocketSuccess&&this.transports.indexOf("websocket")!=-1){transport="websocket"}else if(0==this.transports.length){var self=this;setTimeout(function(){self.emit("error","No transports available")},0);return}else{transport=this.transports[0]}this.readyState="opening";var transport;try{transport=this.createTransport(transport)}catch(e){this.transports.shift();this.open();return}transport.open();this.setTransport(transport)};Socket.prototype.setTransport=function(transport){debug("setting transport %s",transport.name);var self=this;if(this.transport){debug("clearing existing transport %s",this.transport.name);this.transport.removeAllListeners()}this.transport=transport;transport.on("drain",function(){self.onDrain()}).on("packet",function(packet){self.onPacket(packet)}).on("error",function(e){self.onError(e)}).on("close",function(){self.onClose("transport close")})};Socket.prototype.probe=function(name){debug('probing transport "%s"',name);var transport=this.createTransport(name,{probe:1}),failed=false,self=this;Socket.priorWebsocketSuccess=false;function onTransportOpen(){if(self.onlyBinaryUpgrades){var upgradeLosesBinary=!this.supportsBinary&&self.transport.supportsBinary;failed=failed||upgradeLosesBinary}if(failed)return;debug('probe transport "%s" opened',name);transport.send([{type:"ping",data:"probe"}]);transport.once("packet",function(msg){if(failed)return;if("pong"==msg.type&&"probe"==msg.data){debug('probe transport "%s" pong',name);self.upgrading=true;self.emit("upgrading",transport);if(!transport)return;Socket.priorWebsocketSuccess="websocket"==transport.name;debug('pausing current transport "%s"',self.transport.name);self.transport.pause(function(){if(failed)return;if("closed"==self.readyState)return;debug("changing transport and sending upgrade packet");cleanup();self.setTransport(transport);transport.send([{type:"upgrade"}]);self.emit("upgrade",transport);transport=null;self.upgrading=false;self.flush()})}else{debug('probe transport "%s" failed',name);var err=new Error("probe error");err.transport=transport.name;self.emit("upgradeError",err)}})}function freezeTransport(){if(failed)return;failed=true;cleanup();transport.close();transport=null}function onerror(err){var error=new Error("probe error: "+err);error.transport=transport.name;freezeTransport();debug('probe transport "%s" failed because of error: %s',name,err);self.emit("upgradeError",error)}function onTransportClose(){onerror("transport closed")}function onclose(){onerror("socket closed")}function onupgrade(to){if(transport&&to.name!=transport.name){debug('"%s" works - aborting "%s"',to.name,transport.name);freezeTransport()}}function cleanup(){transport.removeListener("open",onTransportOpen);transport.removeListener("error",onerror);transport.removeListener("close",onTransportClose);self.removeListener("close",onclose);self.removeListener("upgrading",onupgrade)}transport.once("open",onTransportOpen);transport.once("error",onerror);transport.once("close",onTransportClose);this.once("close",onclose);this.once("upgrading",onupgrade);transport.open()};Socket.prototype.onOpen=function(){debug("socket open");this.readyState="open";Socket.priorWebsocketSuccess="websocket"==this.transport.name;this.emit("open");this.flush();if("open"==this.readyState&&this.upgrade&&this.transport.pause){debug("starting upgrade probes");for(var i=0,l=this.upgrades.length;i<l;i++){this.probe(this.upgrades[i])}}};Socket.prototype.onPacket=function(packet){if("opening"==this.readyState||"open"==this.readyState){debug('socket receive: type "%s", data "%s"',packet.type,packet.data);this.emit("packet",packet);this.emit("heartbeat");switch(packet.type){case"open":this.onHandshake(parsejson(packet.data));break;case"pong":this.setPing();break;case"error":var err=new Error("server error");err.code=packet.data;this.emit("error",err);break;case"message":this.emit("data",packet.data);this.emit("message",packet.data);break}}else{debug('packet received with socket readyState "%s"',this.readyState)}};Socket.prototype.onHandshake=function(data){this.emit("handshake",data);this.id=data.sid;this.transport.query.sid=data.sid;this.upgrades=this.filterUpgrades(data.upgrades);this.pingInterval=data.pingInterval;this.pingTimeout=data.pingTimeout;this.onOpen();if("closed"==this.readyState)return;this.setPing();this.removeListener("heartbeat",this.onHeartbeat);this.on("heartbeat",this.onHeartbeat)};Socket.prototype.onHeartbeat=function(timeout){clearTimeout(this.pingTimeoutTimer);var self=this;self.pingTimeoutTimer=setTimeout(function(){if("closed"==self.readyState)return;self.onClose("ping timeout")},timeout||self.pingInterval+self.pingTimeout)};Socket.prototype.setPing=function(){var self=this;clearTimeout(self.pingIntervalTimer);self.pingIntervalTimer=setTimeout(function(){debug("writing ping packet - expecting pong within %sms",self.pingTimeout);self.ping();self.onHeartbeat(self.pingTimeout)},self.pingInterval)};Socket.prototype.ping=function(){this.sendPacket("ping")};Socket.prototype.onDrain=function(){for(var i=0;i<this.prevBufferLen;i++){if(this.callbackBuffer[i]){this.callbackBuffer[i]()}}this.writeBuffer.splice(0,this.prevBufferLen);this.callbackBuffer.splice(0,this.prevBufferLen);this.prevBufferLen=0;if(this.writeBuffer.length==0){this.emit("drain")}else{this.flush()}};Socket.prototype.flush=function(){if("closed"!=this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){debug("flushing %d packets in socket",this.writeBuffer.length);this.transport.send(this.writeBuffer);this.prevBufferLen=this.writeBuffer.length;this.emit("flush")}};Socket.prototype.write=Socket.prototype.send=function(msg,fn){this.sendPacket("message",msg,fn);return this};Socket.prototype.sendPacket=function(type,data,fn){if("closing"==this.readyState||"closed"==this.readyState){return}var packet={type:type,data:data};this.emit("packetCreate",packet);this.writeBuffer.push(packet);this.callbackBuffer.push(fn);this.flush()};Socket.prototype.close=function(){if("opening"==this.readyState||"open"==this.readyState){this.readyState="closing";var self=this;function close(){self.onClose("forced close");debug("socket closing - telling transport to close");self.transport.close()}function cleanupAndClose(){self.removeListener("upgrade",cleanupAndClose);self.removeListener("upgradeError",cleanupAndClose);close()}function waitForUpgrade(){self.once("upgrade",cleanupAndClose);self.once("upgradeError",cleanupAndClose)}if(this.writeBuffer.length){this.once("drain",function(){if(this.upgrading){waitForUpgrade()}else{close()}})}else if(this.upgrading){waitForUpgrade()}else{close()}}return this};Socket.prototype.onError=function(err){debug("socket error %j",err);Socket.priorWebsocketSuccess=false;this.emit("error",err);this.onClose("transport error",err)};Socket.prototype.onClose=function(reason,desc){if("opening"==this.readyState||"open"==this.readyState||"closing"==this.readyState){debug('socket close with reason: "%s"',reason);var self=this;clearTimeout(this.pingIntervalTimer);clearTimeout(this.pingTimeoutTimer);setTimeout(function(){self.writeBuffer=[];self.callbackBuffer=[];self.prevBufferLen=0},0);this.transport.removeAllListeners("close");this.transport.close();this.transport.removeAllListeners();this.readyState="closed";this.id=null;this.emit("close",reason,desc)}};Socket.prototype.filterUpgrades=function(upgrades){var filteredUpgrades=[];for(var i=0,j=upgrades.length;i<j;i++){if(~index(this.transports,upgrades[i]))filteredUpgrades.push(upgrades[i])}return filteredUpgrades}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./transport":14,"./transports":15,"component-emitter":9,debug:22,"engine.io-parser":25,indexof:40,parsejson:32,parseqs:33,parseuri:34}],14:[function(_dereq_,module,exports){var parser=_dereq_("engine.io-parser");var Emitter=_dereq_("component-emitter");module.exports=Transport;function Transport(opts){this.path=opts.path;this.hostname=opts.hostname;this.port=opts.port;this.secure=opts.secure;this.query=opts.query;this.timestampParam=opts.timestampParam;this.timestampRequests=opts.timestampRequests;this.readyState="";this.agent=opts.agent||false;this.socket=opts.socket;this.enablesXDR=opts.enablesXDR}Emitter(Transport.prototype);Transport.timestamps=0;Transport.prototype.onError=function(msg,desc){var err=new Error(msg);err.type="TransportError";err.description=desc;this.emit("error",err);return this};Transport.prototype.open=function(){if("closed"==this.readyState||""==this.readyState){this.readyState="opening";this.doOpen()}return this};Transport.prototype.close=function(){if("opening"==this.readyState||"open"==this.readyState){this.doClose();this.onClose()}return this};Transport.prototype.send=function(packets){if("open"==this.readyState){this.write(packets)}else{throw new Error("Transport not open")}};Transport.prototype.onOpen=function(){this.readyState="open";this.writable=true;this.emit("open")};Transport.prototype.onData=function(data){var packet=parser.decodePacket(data,this.socket.binaryType);this.onPacket(packet)};Transport.prototype.onPacket=function(packet){this.emit("packet",packet)};Transport.prototype.onClose=function(){this.readyState="closed";this.emit("close")}},{"component-emitter":9,"engine.io-parser":25}],15:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest");var XHR=_dereq_("./polling-xhr");var JSONP=_dereq_("./polling-jsonp");var websocket=_dereq_("./websocket");exports.polling=polling;exports.websocket=websocket;function polling(opts){var xhr;var xd=false;var xs=false;var jsonp=false!==opts.jsonp;if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}xd=opts.hostname!=location.hostname||port!=opts.port;xs=opts.secure!=isSSL}opts.xdomain=xd;opts.xscheme=xs;xhr=new XMLHttpRequest(opts);if("open"in xhr&&!opts.forceJSONP){return new XHR(opts)}else{if(!jsonp)throw new Error("JSONP disabled");return new JSONP(opts)}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling-jsonp":16,"./polling-xhr":17,"./websocket":19,xmlhttprequest:20}],16:[function(_dereq_,module,exports){(function(global){var Polling=_dereq_("./polling");var inherit=_dereq_("component-inherit");module.exports=JSONPPolling;var rNewline=/\n/g;var rEscapedNewline=/\\n/g;var callbacks;var index=0;function empty(){}function JSONPPolling(opts){Polling.call(this,opts);this.query=this.query||{};if(!callbacks){if(!global.___eio)global.___eio=[];callbacks=global.___eio}this.index=callbacks.length;var self=this;callbacks.push(function(msg){self.onData(msg)});this.query.j=this.index;if(global.document&&global.addEventListener){global.addEventListener("beforeunload",function(){if(self.script)self.script.onerror=empty},false)}}inherit(JSONPPolling,Polling);JSONPPolling.prototype.supportsBinary=false;JSONPPolling.prototype.doClose=function(){if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}if(this.form){this.form.parentNode.removeChild(this.form); 2 + this.form=null;this.iframe=null}Polling.prototype.doClose.call(this)};JSONPPolling.prototype.doPoll=function(){var self=this;var script=document.createElement("script");if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}script.async=true;script.src=this.uri();script.onerror=function(e){self.onError("jsonp poll error",e)};var insertAt=document.getElementsByTagName("script")[0];insertAt.parentNode.insertBefore(script,insertAt);this.script=script;var isUAgecko="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);if(isUAgecko){setTimeout(function(){var iframe=document.createElement("iframe");document.body.appendChild(iframe);document.body.removeChild(iframe)},100)}};JSONPPolling.prototype.doWrite=function(data,fn){var self=this;if(!this.form){var form=document.createElement("form");var area=document.createElement("textarea");var id=this.iframeId="eio_iframe_"+this.index;var iframe;form.className="socketio";form.style.position="absolute";form.style.top="-1000px";form.style.left="-1000px";form.target=id;form.method="POST";form.setAttribute("accept-charset","utf-8");area.name="d";form.appendChild(area);document.body.appendChild(form);this.form=form;this.area=area}this.form.action=this.uri();function complete(){initIframe();fn()}function initIframe(){if(self.iframe){try{self.form.removeChild(self.iframe)}catch(e){self.onError("jsonp polling iframe removal error",e)}}try{var html='<iframe src="javascript:0" name="'+self.iframeId+'">';iframe=document.createElement(html)}catch(e){iframe=document.createElement("iframe");iframe.name=self.iframeId;iframe.src="javascript:0"}iframe.id=self.iframeId;self.form.appendChild(iframe);self.iframe=iframe}initIframe();data=data.replace(rEscapedNewline,"\\\n");this.area.value=data.replace(rNewline,"\\n");try{this.form.submit()}catch(e){}if(this.iframe.attachEvent){this.iframe.onreadystatechange=function(){if(self.iframe.readyState=="complete"){complete()}}}else{this.iframe.onload=complete}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling":18,"component-inherit":21}],17:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest");var Polling=_dereq_("./polling");var Emitter=_dereq_("component-emitter");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling-xhr");module.exports=XHR;module.exports.Request=Request;function empty(){}function XHR(opts){Polling.call(this,opts);if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}this.xd=opts.hostname!=global.location.hostname||port!=opts.port;this.xs=opts.secure!=isSSL}}inherit(XHR,Polling);XHR.prototype.supportsBinary=true;XHR.prototype.request=function(opts){opts=opts||{};opts.uri=this.uri();opts.xd=this.xd;opts.xs=this.xs;opts.agent=this.agent||false;opts.supportsBinary=this.supportsBinary;opts.enablesXDR=this.enablesXDR;return new Request(opts)};XHR.prototype.doWrite=function(data,fn){var isBinary=typeof data!=="string"&&data!==undefined;var req=this.request({method:"POST",data:data,isBinary:isBinary});var self=this;req.on("success",fn);req.on("error",function(err){self.onError("xhr post error",err)});this.sendXhr=req};XHR.prototype.doPoll=function(){debug("xhr poll");var req=this.request();var self=this;req.on("data",function(data){self.onData(data)});req.on("error",function(err){self.onError("xhr poll error",err)});this.pollXhr=req};function Request(opts){this.method=opts.method||"GET";this.uri=opts.uri;this.xd=!!opts.xd;this.xs=!!opts.xs;this.async=false!==opts.async;this.data=undefined!=opts.data?opts.data:null;this.agent=opts.agent;this.isBinary=opts.isBinary;this.supportsBinary=opts.supportsBinary;this.enablesXDR=opts.enablesXDR;this.create()}Emitter(Request.prototype);Request.prototype.create=function(){var xhr=this.xhr=new XMLHttpRequest({agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR});var self=this;try{debug("xhr open %s: %s",this.method,this.uri);xhr.open(this.method,this.uri,this.async);if(this.supportsBinary){xhr.responseType="arraybuffer"}if("POST"==this.method){try{if(this.isBinary){xhr.setRequestHeader("Content-type","application/octet-stream")}else{xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8")}}catch(e){}}if("withCredentials"in xhr){xhr.withCredentials=true}if(this.hasXDR()){xhr.onload=function(){self.onLoad()};xhr.onerror=function(){self.onError(xhr.responseText)}}else{xhr.onreadystatechange=function(){if(4!=xhr.readyState)return;if(200==xhr.status||1223==xhr.status){self.onLoad()}else{setTimeout(function(){self.onError(xhr.status)},0)}}}debug("xhr data %s",this.data);xhr.send(this.data)}catch(e){setTimeout(function(){self.onError(e)},0);return}if(global.document){this.index=Request.requestsCount++;Request.requests[this.index]=this}};Request.prototype.onSuccess=function(){this.emit("success");this.cleanup()};Request.prototype.onData=function(data){this.emit("data",data);this.onSuccess()};Request.prototype.onError=function(err){this.emit("error",err);this.cleanup()};Request.prototype.cleanup=function(){if("undefined"==typeof this.xhr||null===this.xhr){return}if(this.hasXDR()){this.xhr.onload=this.xhr.onerror=empty}else{this.xhr.onreadystatechange=empty}try{this.xhr.abort()}catch(e){}if(global.document){delete Request.requests[this.index]}this.xhr=null};Request.prototype.onLoad=function(){var data;try{var contentType;try{contentType=this.xhr.getResponseHeader("Content-Type").split(";")[0]}catch(e){}if(contentType==="application/octet-stream"){data=this.xhr.response}else{if(!this.supportsBinary){data=this.xhr.responseText}else{data="ok"}}}catch(e){this.onError(e)}if(null!=data){this.onData(data)}};Request.prototype.hasXDR=function(){return"undefined"!==typeof global.XDomainRequest&&!this.xs&&this.enablesXDR};Request.prototype.abort=function(){this.cleanup()};if(global.document){Request.requestsCount=0;Request.requests={};if(global.attachEvent){global.attachEvent("onunload",unloadHandler)}else if(global.addEventListener){global.addEventListener("beforeunload",unloadHandler,false)}}function unloadHandler(){for(var i in Request.requests){if(Request.requests.hasOwnProperty(i)){Request.requests[i].abort()}}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./polling":18,"component-emitter":9,"component-inherit":21,debug:22,xmlhttprequest:20}],18:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parseqs=_dereq_("parseqs");var parser=_dereq_("engine.io-parser");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling");module.exports=Polling;var hasXHR2=function(){var XMLHttpRequest=_dereq_("xmlhttprequest");var xhr=new XMLHttpRequest({xdomain:false});return null!=xhr.responseType}();function Polling(opts){var forceBase64=opts&&opts.forceBase64;if(!hasXHR2||forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(Polling,Transport);Polling.prototype.name="polling";Polling.prototype.doOpen=function(){this.poll()};Polling.prototype.pause=function(onPause){var pending=0;var self=this;this.readyState="pausing";function pause(){debug("paused");self.readyState="paused";onPause()}if(this.polling||!this.writable){var total=0;if(this.polling){debug("we are currently polling - waiting to pause");total++;this.once("pollComplete",function(){debug("pre-pause polling complete");--total||pause()})}if(!this.writable){debug("we are currently writing - waiting to pause");total++;this.once("drain",function(){debug("pre-pause writing complete");--total||pause()})}}else{pause()}};Polling.prototype.poll=function(){debug("polling");this.polling=true;this.doPoll();this.emit("poll")};Polling.prototype.onData=function(data){var self=this;debug("polling got data %s",data);var callback=function(packet,index,total){if("opening"==self.readyState){self.onOpen()}if("close"==packet.type){self.onClose();return false}self.onPacket(packet)};parser.decodePayload(data,this.socket.binaryType,callback);if("closed"!=this.readyState){this.polling=false;this.emit("pollComplete");if("open"==this.readyState){this.poll()}else{debug('ignoring poll - transport state "%s"',this.readyState)}}};Polling.prototype.doClose=function(){var self=this;function close(){debug("writing close packet");self.write([{type:"close"}])}if("open"==this.readyState){debug("transport open - closing");close()}else{debug("transport not open - deferring close");this.once("open",close)}};Polling.prototype.write=function(packets){var self=this;this.writable=false;var callbackfn=function(){self.writable=true;self.emit("drain")};var self=this;parser.encodePayload(packets,this.supportsBinary,function(data){self.doWrite(data,callbackfn)})};Polling.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"https":"http";var port="";if(false!==this.timestampRequests){query[this.timestampParam]=+new Date+"-"+Transport.timestamps++}if(!this.supportsBinary&&!query.sid){query.b64=1}query=parseqs.encode(query);if(this.port&&("https"==schema&&this.port!=443||"http"==schema&&this.port!=80)){port=":"+this.port}if(query.length){query="?"+query}return schema+"://"+this.hostname+port+this.path+query}},{"../transport":14,"component-inherit":21,debug:22,"engine.io-parser":25,parseqs:33,xmlhttprequest:20}],19:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parser=_dereq_("engine.io-parser");var parseqs=_dereq_("parseqs");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:websocket");var WebSocket=_dereq_("ws");module.exports=WS;function WS(opts){var forceBase64=opts&&opts.forceBase64;if(forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(WS,Transport);WS.prototype.name="websocket";WS.prototype.supportsBinary=true;WS.prototype.doOpen=function(){if(!this.check()){return}var self=this;var uri=this.uri();var protocols=void 0;var opts={agent:this.agent};this.ws=new WebSocket(uri,protocols,opts);if(this.ws.binaryType===undefined){this.supportsBinary=false}this.ws.binaryType="arraybuffer";this.addEventListeners()};WS.prototype.addEventListeners=function(){var self=this;this.ws.onopen=function(){self.onOpen()};this.ws.onclose=function(){self.onClose()};this.ws.onmessage=function(ev){self.onData(ev.data)};this.ws.onerror=function(e){self.onError("websocket error",e)}};if("undefined"!=typeof navigator&&/iPad|iPhone|iPod/i.test(navigator.userAgent)){WS.prototype.onData=function(data){var self=this;setTimeout(function(){Transport.prototype.onData.call(self,data)},0)}}WS.prototype.write=function(packets){var self=this;this.writable=false;for(var i=0,l=packets.length;i<l;i++){parser.encodePacket(packets[i],this.supportsBinary,function(data){try{self.ws.send(data)}catch(e){debug("websocket closed before onclose event")}})}function ondrain(){self.writable=true;self.emit("drain")}setTimeout(ondrain,0)};WS.prototype.onClose=function(){Transport.prototype.onClose.call(this)};WS.prototype.doClose=function(){if(typeof this.ws!=="undefined"){this.ws.close()}};WS.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"wss":"ws";var port="";if(this.port&&("wss"==schema&&this.port!=443||"ws"==schema&&this.port!=80)){port=":"+this.port}if(this.timestampRequests){query[this.timestampParam]=+new Date}if(!this.supportsBinary){query.b64=1}query=parseqs.encode(query);if(query.length){query="?"+query}return schema+"://"+this.hostname+port+this.path+query};WS.prototype.check=function(){return!!WebSocket&&!("__initialize"in WebSocket&&this.name===WS.prototype.name)}},{"../transport":14,"component-inherit":21,debug:22,"engine.io-parser":25,parseqs:33,ws:35}],20:[function(_dereq_,module,exports){var hasCORS=_dereq_("has-cors");module.exports=function(opts){var xdomain=opts.xdomain;var xscheme=opts.xscheme;var enablesXDR=opts.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!xdomain||hasCORS)){return new XMLHttpRequest}}catch(e){}try{if("undefined"!=typeof XDomainRequest&&!xscheme&&enablesXDR){return new XDomainRequest}}catch(e){}if(!xdomain){try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}}},{"has-cors":38}],21:[function(_dereq_,module,exports){module.exports=function(a,b){var fn=function(){};fn.prototype=b.prototype;a.prototype=new fn;a.prototype.constructor=a}},{}],22:[function(_dereq_,module,exports){exports=module.exports=_dereq_("./debug");exports.log=log;exports.formatArgs=formatArgs;exports.save=save;exports.load=load;exports.useColors=useColors;exports.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"];function useColors(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}exports.formatters.j=function(v){return JSON.stringify(v)};function formatArgs(){var args=arguments;var useColors=this.useColors;args[0]=(useColors?"%c":"")+this.namespace+(useColors?" %c":" ")+args[0]+(useColors?"%c ":" ")+"+"+exports.humanize(this.diff);if(!useColors)return args;var c="color: "+this.color;args=[args[0],c,"color: inherit"].concat(Array.prototype.slice.call(args,1));var index=0;var lastC=0;args[0].replace(/%[a-z%]/g,function(match){if("%"===match)return;index++;if("%c"===match){lastC=index}});args.splice(lastC,0,c);return args}function log(){return"object"==typeof console&&"function"==typeof console.log&&Function.prototype.apply.call(console.log,console,arguments)}function save(namespaces){try{if(null==namespaces){localStorage.removeItem("debug")}else{localStorage.debug=namespaces}}catch(e){}}function load(){var r;try{r=localStorage.debug}catch(e){}return r}exports.enable(load())},{"./debug":23}],23:[function(_dereq_,module,exports){exports=module.exports=debug;exports.coerce=coerce;exports.disable=disable;exports.enable=enable;exports.enabled=enabled;exports.humanize=_dereq_("ms");exports.names=[];exports.skips=[];exports.formatters={};var prevColor=0;var prevTime;function selectColor(){return exports.colors[prevColor++%exports.colors.length]}function debug(namespace){function disabled(){}disabled.enabled=false;function enabled(){var self=enabled;var curr=+new Date;var ms=curr-(prevTime||curr);self.diff=ms;self.prev=prevTime;self.curr=curr;prevTime=curr;if(null==self.useColors)self.useColors=exports.useColors();if(null==self.color&&self.useColors)self.color=selectColor();var args=Array.prototype.slice.call(arguments);args[0]=exports.coerce(args[0]);if("string"!==typeof args[0]){args=["%o"].concat(args)}var index=0;args[0]=args[0].replace(/%([a-z%])/g,function(match,format){if(match==="%")return match;index++;var formatter=exports.formatters[format];if("function"===typeof formatter){var val=args[index];match=formatter.call(self,val);args.splice(index,1);index--}return match});if("function"===typeof exports.formatArgs){args=exports.formatArgs.apply(self,args)}var logFn=enabled.log||exports.log||console.log.bind(console);logFn.apply(self,args)}enabled.enabled=true;var fn=exports.enabled(namespace)?enabled:disabled;fn.namespace=namespace;return fn}function enable(namespaces){exports.save(namespaces);var split=(namespaces||"").split(/[\s,]+/);var len=split.length;for(var i=0;i<len;i++){if(!split[i])continue;namespaces=split[i].replace(/\*/g,".*?");if(namespaces[0]==="-"){exports.skips.push(new RegExp("^"+namespaces.substr(1)+"$"))}else{exports.names.push(new RegExp("^"+namespaces+"$"))}}}function disable(){exports.enable("")}function enabled(name){var i,len;for(i=0,len=exports.skips.length;i<len;i++){if(exports.skips[i].test(name)){return false}}for(i=0,len=exports.names.length;i<len;i++){if(exports.names[i].test(name)){return true}}return false}function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}},{ms:24}],24:[function(_dereq_,module,exports){var s=1e3;var m=s*60;var h=m*60;var d=h*24;var y=d*365.25;module.exports=function(val,options){options=options||{};if("string"==typeof val)return parse(val);return options.long?long(val):short(val)};function parse(str){var match=/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);if(!match)return;var n=parseFloat(match[1]);var type=(match[2]||"ms").toLowerCase();switch(type){case"years":case"year":case"y":return n*y;case"days":case"day":case"d":return n*d;case"hours":case"hour":case"h":return n*h;case"minutes":case"minute":case"m":return n*m;case"seconds":case"second":case"s":return n*s;case"ms":return n}}function short(ms){if(ms>=d)return Math.round(ms/d)+"d";if(ms>=h)return Math.round(ms/h)+"h";if(ms>=m)return Math.round(ms/m)+"m";if(ms>=s)return Math.round(ms/s)+"s";return ms+"ms"}function long(ms){return plural(ms,d,"day")||plural(ms,h,"hour")||plural(ms,m,"minute")||plural(ms,s,"second")||ms+" ms"}function plural(ms,n,name){if(ms<n)return;if(ms<n*1.5)return Math.floor(ms/n)+" "+name;return Math.ceil(ms/n)+" "+name+"s"}},{}],25:[function(_dereq_,module,exports){(function(global){var keys=_dereq_("./keys");var sliceBuffer=_dereq_("arraybuffer.slice");var base64encoder=_dereq_("base64-arraybuffer");var after=_dereq_("after");var utf8=_dereq_("utf8");var isAndroid=navigator.userAgent.match(/Android/i);exports.protocol=3;var packets=exports.packets={open:0,close:1,ping:2,pong:3,message:4,upgrade:5,noop:6};var packetslist=keys(packets);var err={type:"error",data:"parser error"};var Blob=_dereq_("blob");exports.encodePacket=function(packet,supportsBinary,utf8encode,callback){if("function"==typeof supportsBinary){callback=supportsBinary;supportsBinary=false}if("function"==typeof utf8encode){callback=utf8encode;utf8encode=null}var data=packet.data===undefined?undefined:packet.data.buffer||packet.data;if(global.ArrayBuffer&&data instanceof ArrayBuffer){return encodeArrayBuffer(packet,supportsBinary,callback)}else if(Blob&&data instanceof global.Blob){return encodeBlob(packet,supportsBinary,callback)}var encoded=packets[packet.type];if(undefined!==packet.data){encoded+=utf8encode?utf8.encode(String(packet.data)):String(packet.data)}return callback(""+encoded)};function encodeArrayBuffer(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}var data=packet.data;var contentArray=new Uint8Array(data);var resultBuffer=new Uint8Array(1+data.byteLength);resultBuffer[0]=packets[packet.type];for(var i=0;i<contentArray.length;i++){resultBuffer[i+1]=contentArray[i]}return callback(resultBuffer.buffer)}function encodeBlobAsArrayBuffer(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}var fr=new FileReader;fr.onload=function(){packet.data=fr.result;exports.encodePacket(packet,supportsBinary,true,callback)};return fr.readAsArrayBuffer(packet.data)}function encodeBlob(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}if(isAndroid){return encodeBlobAsArrayBuffer(packet,supportsBinary,callback)}var length=new Uint8Array(1);length[0]=packets[packet.type];var blob=new Blob([length.buffer,packet.data]);return callback(blob)}exports.encodeBase64Packet=function(packet,callback){var message="b"+exports.packets[packet.type];if(Blob&&packet.data instanceof Blob){var fr=new FileReader;fr.onload=function(){var b64=fr.result.split(",")[1];callback(message+b64)};return fr.readAsDataURL(packet.data)}var b64data;try{b64data=String.fromCharCode.apply(null,new Uint8Array(packet.data))}catch(e){var typed=new Uint8Array(packet.data);var basic=new Array(typed.length);for(var i=0;i<typed.length;i++){basic[i]=typed[i]}b64data=String.fromCharCode.apply(null,basic)}message+=global.btoa(b64data);return callback(message)};exports.decodePacket=function(data,binaryType,utf8decode){if(typeof data=="string"||data===undefined){if(data.charAt(0)=="b"){return exports.decodeBase64Packet(data.substr(1),binaryType)}if(utf8decode){try{data=utf8.decode(data)}catch(e){return err}}var type=data.charAt(0);if(Number(type)!=type||!packetslist[type]){return err}if(data.length>1){return{type:packetslist[type],data:data.substring(1)}}else{return{type:packetslist[type]}}}var asArray=new Uint8Array(data);var type=asArray[0];var rest=sliceBuffer(data,1);if(Blob&&binaryType==="blob"){rest=new Blob([rest])}return{type:packetslist[type],data:rest}};exports.decodeBase64Packet=function(msg,binaryType){var type=packetslist[msg.charAt(0)];if(!global.ArrayBuffer){return{type:type,data:{base64:true,data:msg.substr(1)}}}var data=base64encoder.decode(msg.substr(1));if(binaryType==="blob"&&Blob){data=new Blob([data])}return{type:type,data:data}};exports.encodePayload=function(packets,supportsBinary,callback){if(typeof supportsBinary=="function"){callback=supportsBinary;supportsBinary=null}if(supportsBinary){if(Blob&&!isAndroid){return exports.encodePayloadAsBlob(packets,callback)}return exports.encodePayloadAsArrayBuffer(packets,callback)}if(!packets.length){return callback("0:")}function setLengthHeader(message){return message.length+":"+message}function encodeOne(packet,doneCallback){exports.encodePacket(packet,supportsBinary,true,function(message){doneCallback(null,setLengthHeader(message))})}map(packets,encodeOne,function(err,results){return callback(results.join(""))})};function map(ary,each,done){var result=new Array(ary.length);var next=after(ary.length,done);var eachWithIndex=function(i,el,cb){each(el,function(error,msg){result[i]=msg;cb(error,result)})};for(var i=0;i<ary.length;i++){eachWithIndex(i,ary[i],next)}}exports.decodePayload=function(data,binaryType,callback){if(typeof data!="string"){return exports.decodePayloadAsBinary(data,binaryType,callback)}if(typeof binaryType==="function"){callback=binaryType;binaryType=null}var packet;if(data==""){return callback(err,0,1)}var length="",n,msg;for(var i=0,l=data.length;i<l;i++){var chr=data.charAt(i);if(":"!=chr){length+=chr}else{if(""==length||length!=(n=Number(length))){return callback(err,0,1)}msg=data.substr(i+1,n);if(length!=msg.length){return callback(err,0,1)}if(msg.length){packet=exports.decodePacket(msg,binaryType,true);if(err.type==packet.type&&err.data==packet.data){return callback(err,0,1)}var ret=callback(packet,i+n,l);if(false===ret)return}i+=n;length=""}}if(length!=""){return callback(err,0,1)}};exports.encodePayloadAsArrayBuffer=function(packets,callback){if(!packets.length){return callback(new ArrayBuffer(0))}function encodeOne(packet,doneCallback){exports.encodePacket(packet,true,true,function(data){return doneCallback(null,data)})}map(packets,encodeOne,function(err,encodedPackets){var totalLength=encodedPackets.reduce(function(acc,p){var len;if(typeof p==="string"){len=p.length}else{len=p.byteLength}return acc+len.toString().length+len+2},0);var resultArray=new Uint8Array(totalLength);var bufferIndex=0;encodedPackets.forEach(function(p){var isString=typeof p==="string";var ab=p;if(isString){var view=new Uint8Array(p.length);for(var i=0;i<p.length;i++){view[i]=p.charCodeAt(i)}ab=view.buffer}if(isString){resultArray[bufferIndex++]=0}else{resultArray[bufferIndex++]=1}var lenStr=ab.byteLength.toString();for(var i=0;i<lenStr.length;i++){resultArray[bufferIndex++]=parseInt(lenStr[i])}resultArray[bufferIndex++]=255;var view=new Uint8Array(ab);for(var i=0;i<view.length;i++){resultArray[bufferIndex++]=view[i]}});return callback(resultArray.buffer)})};exports.encodePayloadAsBlob=function(packets,callback){function encodeOne(packet,doneCallback){exports.encodePacket(packet,true,true,function(encoded){var binaryIdentifier=new Uint8Array(1);binaryIdentifier[0]=1;if(typeof encoded==="string"){var view=new Uint8Array(encoded.length);for(var i=0;i<encoded.length;i++){view[i]=encoded.charCodeAt(i)}encoded=view.buffer;binaryIdentifier[0]=0}var len=encoded instanceof ArrayBuffer?encoded.byteLength:encoded.size;var lenStr=len.toString();var lengthAry=new Uint8Array(lenStr.length+1);for(var i=0;i<lenStr.length;i++){lengthAry[i]=parseInt(lenStr[i])}lengthAry[lenStr.length]=255;if(Blob){var blob=new Blob([binaryIdentifier.buffer,lengthAry.buffer,encoded]);doneCallback(null,blob)}})}map(packets,encodeOne,function(err,results){return callback(new Blob(results))})};exports.decodePayloadAsBinary=function(data,binaryType,callback){if(typeof binaryType==="function"){callback=binaryType;binaryType=null}var bufferTail=data;var buffers=[];var numberTooLong=false;while(bufferTail.byteLength>0){var tailArray=new Uint8Array(bufferTail);var isString=tailArray[0]===0;var msgLength="";for(var i=1;;i++){if(tailArray[i]==255)break;if(msgLength.length>310){numberTooLong=true;break}msgLength+=tailArray[i]}if(numberTooLong)return callback(err,0,1);bufferTail=sliceBuffer(bufferTail,2+msgLength.length);msgLength=parseInt(msgLength);var msg=sliceBuffer(bufferTail,0,msgLength);if(isString){try{msg=String.fromCharCode.apply(null,new Uint8Array(msg))}catch(e){var typed=new Uint8Array(msg);msg="";for(var i=0;i<typed.length;i++){msg+=String.fromCharCode(typed[i])}}}buffers.push(msg);bufferTail=sliceBuffer(bufferTail,msgLength)}var total=buffers.length;buffers.forEach(function(buffer,i){callback(exports.decodePacket(buffer,binaryType,true),i,total)})}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./keys":26,after:27,"arraybuffer.slice":28,"base64-arraybuffer":29,blob:30,utf8:31}],26:[function(_dereq_,module,exports){module.exports=Object.keys||function keys(obj){var arr=[];var has=Object.prototype.hasOwnProperty;for(var i in obj){if(has.call(obj,i)){arr.push(i)}}return arr}},{}],27:[function(_dereq_,module,exports){module.exports=after;function after(count,callback,err_cb){var bail=false;err_cb=err_cb||noop;proxy.count=count;return count===0?callback():proxy;function proxy(err,result){if(proxy.count<=0){throw new Error("after called too many times")}--proxy.count;if(err){bail=true;callback(err);callback=err_cb}else if(proxy.count===0&&!bail){callback(null,result)}}}function noop(){}},{}],28:[function(_dereq_,module,exports){module.exports=function(arraybuffer,start,end){var bytes=arraybuffer.byteLength;start=start||0;end=end||bytes;if(arraybuffer.slice){return arraybuffer.slice(start,end)}if(start<0){start+=bytes}if(end<0){end+=bytes}if(end>bytes){end=bytes}if(start>=bytes||start>=end||bytes===0){return new ArrayBuffer(0)}var abv=new Uint8Array(arraybuffer);var result=new Uint8Array(end-start);for(var i=start,ii=0;i<end;i++,ii++){result[ii]=abv[i]}return result.buffer}},{}],29:[function(_dereq_,module,exports){(function(chars){"use strict";exports.encode=function(arraybuffer){var bytes=new Uint8Array(arraybuffer),i,len=bytes.length,base64="";for(i=0;i<len;i+=3){base64+=chars[bytes[i]>>2];base64+=chars[(bytes[i]&3)<<4|bytes[i+1]>>4];base64+=chars[(bytes[i+1]&15)<<2|bytes[i+2]>>6];base64+=chars[bytes[i+2]&63]}if(len%3===2){base64=base64.substring(0,base64.length-1)+"="}else if(len%3===1){base64=base64.substring(0,base64.length-2)+"=="}return base64};exports.decode=function(base64){var bufferLength=base64.length*.75,len=base64.length,i,p=0,encoded1,encoded2,encoded3,encoded4;if(base64[base64.length-1]==="="){bufferLength--;if(base64[base64.length-2]==="="){bufferLength--}}var arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer);for(i=0;i<len;i+=4){encoded1=chars.indexOf(base64[i]);encoded2=chars.indexOf(base64[i+1]);encoded3=chars.indexOf(base64[i+2]);encoded4=chars.indexOf(base64[i+3]);bytes[p++]=encoded1<<2|encoded2>>4;bytes[p++]=(encoded2&15)<<4|encoded3>>2;bytes[p++]=(encoded3&3)<<6|encoded4&63}return arraybuffer}})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")},{}],30:[function(_dereq_,module,exports){(function(global){var BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder||global.MSBlobBuilder||global.MozBlobBuilder;var blobSupported=function(){try{var b=new Blob(["hi"]);return b.size==2}catch(e){return false}}();var blobBuilderSupported=BlobBuilder&&BlobBuilder.prototype.append&&BlobBuilder.prototype.getBlob;function BlobBuilderConstructor(ary,options){options=options||{};var bb=new BlobBuilder;for(var i=0;i<ary.length;i++){bb.append(ary[i])}return options.type?bb.getBlob(options.type):bb.getBlob()}module.exports=function(){if(blobSupported){return global.Blob}else if(blobBuilderSupported){return BlobBuilderConstructor}else{return undefined}}()}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],31:[function(_dereq_,module,exports){(function(global){(function(root){var freeExports=typeof exports=="object"&&exports;var freeModule=typeof module=="object"&&module&&module.exports==freeExports&&module;var freeGlobal=typeof global=="object"&&global;if(freeGlobal.global===freeGlobal||freeGlobal.window===freeGlobal){root=freeGlobal}var stringFromCharCode=String.fromCharCode;function ucs2decode(string){var output=[];var counter=0;var length=string.length;var value;var extra;while(counter<length){value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){extra=string.charCodeAt(counter++);if((extra&64512)==56320){output.push(((value&1023)<<10)+(extra&1023)+65536)}else{output.push(value);counter--}}else{output.push(value)}}return output}function ucs2encode(array){var length=array.length;var index=-1;var value;var output="";while(++index<length){value=array[index];if(value>65535){value-=65536;output+=stringFromCharCode(value>>>10&1023|55296);value=56320|value&1023}output+=stringFromCharCode(value)}return output}function createByte(codePoint,shift){return stringFromCharCode(codePoint>>shift&63|128)}function encodeCodePoint(codePoint){if((codePoint&4294967168)==0){return stringFromCharCode(codePoint)}var symbol="";if((codePoint&4294965248)==0){symbol=stringFromCharCode(codePoint>>6&31|192)}else if((codePoint&4294901760)==0){symbol=stringFromCharCode(codePoint>>12&15|224);symbol+=createByte(codePoint,6)}else if((codePoint&4292870144)==0){symbol=stringFromCharCode(codePoint>>18&7|240);symbol+=createByte(codePoint,12);symbol+=createByte(codePoint,6)}symbol+=stringFromCharCode(codePoint&63|128);return symbol}function utf8encode(string){var codePoints=ucs2decode(string);var length=codePoints.length;var index=-1;var codePoint;var byteString="";while(++index<length){codePoint=codePoints[index];byteString+=encodeCodePoint(codePoint)}return byteString}function readContinuationByte(){if(byteIndex>=byteCount){throw Error("Invalid byte index")}var continuationByte=byteArray[byteIndex]&255;byteIndex++;if((continuationByte&192)==128){return continuationByte&63}throw Error("Invalid continuation byte")}function decodeSymbol(){var byte1;var byte2;var byte3;var byte4;var codePoint;if(byteIndex>byteCount){throw Error("Invalid byte index")}if(byteIndex==byteCount){return false}byte1=byteArray[byteIndex]&255;byteIndex++;if((byte1&128)==0){return byte1}if((byte1&224)==192){var byte2=readContinuationByte();codePoint=(byte1&31)<<6|byte2;if(codePoint>=128){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&240)==224){byte2=readContinuationByte();byte3=readContinuationByte();codePoint=(byte1&15)<<12|byte2<<6|byte3;if(codePoint>=2048){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&248)==240){byte2=readContinuationByte();byte3=readContinuationByte();byte4=readContinuationByte();codePoint=(byte1&15)<<18|byte2<<12|byte3<<6|byte4;if(codePoint>=65536&&codePoint<=1114111){return codePoint}}throw Error("Invalid UTF-8 detected")}var byteArray;var byteCount;var byteIndex;function utf8decode(byteString){byteArray=ucs2decode(byteString);byteCount=byteArray.length;byteIndex=0;var codePoints=[];var tmp;while((tmp=decodeSymbol())!==false){codePoints.push(tmp)}return ucs2encode(codePoints)}var utf8={version:"2.0.0",encode:utf8encode,decode:utf8decode};if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){define(function(){return utf8})}else if(freeExports&&!freeExports.nodeType){if(freeModule){freeModule.exports=utf8}else{var object={};var hasOwnProperty=object.hasOwnProperty; 3 + for(var key in utf8){hasOwnProperty.call(utf8,key)&&(freeExports[key]=utf8[key])}}}else{root.utf8=utf8}})(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],32:[function(_dereq_,module,exports){(function(global){var rvalidchars=/^[\],:{}\s]*$/;var rvalidescape=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;var rvalidtokens=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;var rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g;var rtrimLeft=/^\s+/;var rtrimRight=/\s+$/;module.exports=function parsejson(data){if("string"!=typeof data||!data){return null}data=data.replace(rtrimLeft,"").replace(rtrimRight,"");if(global.JSON&&JSON.parse){return JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],33:[function(_dereq_,module,exports){exports.encode=function(obj){var str="";for(var i in obj){if(obj.hasOwnProperty(i)){if(str.length)str+="&";str+=encodeURIComponent(i)+"="+encodeURIComponent(obj[i])}}return str};exports.decode=function(qs){var qry={};var pairs=qs.split("&");for(var i=0,l=pairs.length;i<l;i++){var pair=pairs[i].split("=");qry[decodeURIComponent(pair[0])]=decodeURIComponent(pair[1])}return qry}},{}],34:[function(_dereq_,module,exports){var re=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;var parts=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];module.exports=function parseuri(str){var src=str,b=str.indexOf("["),e=str.indexOf("]");if(b!=-1&&e!=-1){str=str.substring(0,b)+str.substring(b,e).replace(/:/g,";")+str.substring(e,str.length)}var m=re.exec(str||""),uri={},i=14;while(i--){uri[parts[i]]=m[i]||""}if(b!=-1&&e!=-1){uri.source=src;uri.host=uri.host.substring(1,uri.host.length-1).replace(/;/g,":");uri.authority=uri.authority.replace("[","").replace("]","").replace(/;/g,":");uri.ipv6uri=true}return uri}},{}],35:[function(_dereq_,module,exports){var global=function(){return this}();var WebSocket=global.WebSocket||global.MozWebSocket;module.exports=WebSocket?ws:null;function ws(uri,protocols,opts){var instance;if(protocols){instance=new WebSocket(uri,protocols)}else{instance=new WebSocket(uri)}return instance}if(WebSocket)ws.prototype=WebSocket.prototype},{}],36:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");module.exports=hasBinary;function hasBinary(data){function _hasBinary(obj){if(!obj)return false;if(global.Buffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer||global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){return true}if(isArray(obj)){for(var i=0;i<obj.length;i++){if(_hasBinary(obj[i])){return true}}}else if(obj&&"object"==typeof obj){if(obj.toJSON){obj=obj.toJSON()}for(var key in obj){if(obj.hasOwnProperty(key)&&_hasBinary(obj[key])){return true}}}return false}return _hasBinary(data)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{isarray:37}],37:[function(_dereq_,module,exports){module.exports=Array.isArray||function(arr){return Object.prototype.toString.call(arr)=="[object Array]"}},{}],38:[function(_dereq_,module,exports){var global=_dereq_("global");try{module.exports="XMLHttpRequest"in global&&"withCredentials"in new global.XMLHttpRequest}catch(err){module.exports=false}},{global:39}],39:[function(_dereq_,module,exports){module.exports=function(){return this}()},{}],40:[function(_dereq_,module,exports){var indexOf=[].indexOf;module.exports=function(arr,obj){if(indexOf)return arr.indexOf(obj);for(var i=0;i<arr.length;++i){if(arr[i]===obj)return i}return-1}},{}],41:[function(_dereq_,module,exports){var has=Object.prototype.hasOwnProperty;exports.keys=Object.keys||function(obj){var keys=[];for(var key in obj){if(has.call(obj,key)){keys.push(key)}}return keys};exports.values=function(obj){var vals=[];for(var key in obj){if(has.call(obj,key)){vals.push(obj[key])}}return vals};exports.merge=function(a,b){for(var key in b){if(has.call(b,key)){a[key]=b[key]}}return a};exports.length=function(obj){return exports.keys(obj).length};exports.isEmpty=function(obj){return 0==exports.length(obj)}},{}],42:[function(_dereq_,module,exports){var re=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;var parts=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];module.exports=function parseuri(str){var m=re.exec(str||""),uri={},i=14;while(i--){uri[parts[i]]=m[i]||""}return uri}},{}],43:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");var isBuf=_dereq_("./is-buffer");exports.deconstructPacket=function(packet){var buffers=[];var packetData=packet.data;function _deconstructPacket(data){if(!data)return data;if(isBuf(data)){var placeholder={_placeholder:true,num:buffers.length};buffers.push(data);return placeholder}else if(isArray(data)){var newData=new Array(data.length);for(var i=0;i<data.length;i++){newData[i]=_deconstructPacket(data[i])}return newData}else if("object"==typeof data&&!(data instanceof Date)){var newData={};for(var key in data){newData[key]=_deconstructPacket(data[key])}return newData}return data}var pack=packet;pack.data=_deconstructPacket(packetData);pack.attachments=buffers.length;return{packet:pack,buffers:buffers}};exports.reconstructPacket=function(packet,buffers){var curPlaceHolder=0;function _reconstructPacket(data){if(data&&data._placeholder){var buf=buffers[data.num];return buf}else if(isArray(data)){for(var i=0;i<data.length;i++){data[i]=_reconstructPacket(data[i])}return data}else if(data&&"object"==typeof data){for(var key in data){data[key]=_reconstructPacket(data[key])}return data}return data}packet.data=_reconstructPacket(packet.data);packet.attachments=undefined;return packet};exports.removeBlobs=function(data,callback){function _removeBlobs(obj,curKey,containingObject){if(!obj)return obj;if(global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){pendingBlobs++;var fileReader=new FileReader;fileReader.onload=function(){if(containingObject){containingObject[curKey]=this.result}else{bloblessData=this.result}if(!--pendingBlobs){callback(bloblessData)}};fileReader.readAsArrayBuffer(obj)}else if(isArray(obj)){for(var i=0;i<obj.length;i++){_removeBlobs(obj[i],i,obj)}}else if(obj&&"object"==typeof obj&&!isBuf(obj)){for(var key in obj){_removeBlobs(obj[key],key,obj)}}}var pendingBlobs=0;var bloblessData=data;_removeBlobs(bloblessData);if(!pendingBlobs){callback(bloblessData)}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"./is-buffer":45,isarray:46}],44:[function(_dereq_,module,exports){var debug=_dereq_("debug")("socket.io-parser");var json=_dereq_("json3");var isArray=_dereq_("isarray");var Emitter=_dereq_("component-emitter");var binary=_dereq_("./binary");var isBuf=_dereq_("./is-buffer");exports.protocol=4;exports.types=["CONNECT","DISCONNECT","EVENT","BINARY_EVENT","ACK","BINARY_ACK","ERROR"];exports.CONNECT=0;exports.DISCONNECT=1;exports.EVENT=2;exports.ACK=3;exports.ERROR=4;exports.BINARY_EVENT=5;exports.BINARY_ACK=6;exports.Encoder=Encoder;exports.Decoder=Decoder;function Encoder(){}Encoder.prototype.encode=function(obj,callback){debug("encoding packet %j",obj);if(exports.BINARY_EVENT==obj.type||exports.BINARY_ACK==obj.type){encodeAsBinary(obj,callback)}else{var encoding=encodeAsString(obj);callback([encoding])}};function encodeAsString(obj){var str="";var nsp=false;str+=obj.type;if(exports.BINARY_EVENT==obj.type||exports.BINARY_ACK==obj.type){str+=obj.attachments;str+="-"}if(obj.nsp&&"/"!=obj.nsp){nsp=true;str+=obj.nsp}if(null!=obj.id){if(nsp){str+=",";nsp=false}str+=obj.id}if(null!=obj.data){if(nsp)str+=",";str+=json.stringify(obj.data)}debug("encoded %j as %s",obj,str);return str}function encodeAsBinary(obj,callback){function writeEncoding(bloblessData){var deconstruction=binary.deconstructPacket(bloblessData);var pack=encodeAsString(deconstruction.packet);var buffers=deconstruction.buffers;buffers.unshift(pack);callback(buffers)}binary.removeBlobs(obj,writeEncoding)}function Decoder(){this.reconstructor=null}Emitter(Decoder.prototype);Decoder.prototype.add=function(obj){var packet;if("string"==typeof obj){packet=decodeString(obj);if(exports.BINARY_EVENT==packet.type||exports.BINARY_ACK==packet.type){this.reconstructor=new BinaryReconstructor(packet);if(this.reconstructor.reconPack.attachments==0){this.emit("decoded",packet)}}else{this.emit("decoded",packet)}}else if(isBuf(obj)||obj.base64){if(!this.reconstructor){throw new Error("got binary data when not reconstructing a packet")}else{packet=this.reconstructor.takeBinaryData(obj);if(packet){this.reconstructor=null;this.emit("decoded",packet)}}}else{throw new Error("Unknown type: "+obj)}};function decodeString(str){var p={};var i=0;p.type=Number(str.charAt(0));if(null==exports.types[p.type])return error();if(exports.BINARY_EVENT==p.type||exports.BINARY_ACK==p.type){p.attachments="";while(str.charAt(++i)!="-"){p.attachments+=str.charAt(i)}p.attachments=Number(p.attachments)}if("/"==str.charAt(i+1)){p.nsp="";while(++i){var c=str.charAt(i);if(","==c)break;p.nsp+=c;if(i+1==str.length)break}}else{p.nsp="/"}var next=str.charAt(i+1);if(""!=next&&Number(next)==next){p.id="";while(++i){var c=str.charAt(i);if(null==c||Number(c)!=c){--i;break}p.id+=str.charAt(i);if(i+1==str.length)break}p.id=Number(p.id)}if(str.charAt(++i)){try{p.data=json.parse(str.substr(i))}catch(e){return error()}}debug("decoded %s as %j",str,p);return p}Decoder.prototype.destroy=function(){if(this.reconstructor){this.reconstructor.finishedReconstruction()}};function BinaryReconstructor(packet){this.reconPack=packet;this.buffers=[]}BinaryReconstructor.prototype.takeBinaryData=function(binData){this.buffers.push(binData);if(this.buffers.length==this.reconPack.attachments){var packet=binary.reconstructPacket(this.reconPack,this.buffers);this.finishedReconstruction();return packet}return null};BinaryReconstructor.prototype.finishedReconstruction=function(){this.reconPack=null;this.buffers=[]};function error(data){return{type:exports.ERROR,data:"parser error"}}},{"./binary":43,"./is-buffer":45,"component-emitter":9,debug:10,isarray:46,json3:47}],45:[function(_dereq_,module,exports){(function(global){module.exports=isBuf;function isBuf(obj){return global.Buffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],46:[function(_dereq_,module,exports){module.exports=_dereq_(37)},{}],47:[function(_dereq_,module,exports){(function(window){var getClass={}.toString,isProperty,forEach,undef;var isLoader=typeof define==="function"&&define.amd;var nativeJSON=typeof JSON=="object"&&JSON;var JSON3=typeof exports=="object"&&exports&&!exports.nodeType&&exports;if(JSON3&&nativeJSON){JSON3.stringify=nativeJSON.stringify;JSON3.parse=nativeJSON.parse}else{JSON3=window.JSON=nativeJSON||{}}var isExtended=new Date(-0xc782b5b800cec);try{isExtended=isExtended.getUTCFullYear()==-109252&&isExtended.getUTCMonth()===0&&isExtended.getUTCDate()===1&&isExtended.getUTCHours()==10&&isExtended.getUTCMinutes()==37&&isExtended.getUTCSeconds()==6&&isExtended.getUTCMilliseconds()==708}catch(exception){}function has(name){if(has[name]!==undef){return has[name]}var isSupported;if(name=="bug-string-char-index"){isSupported="a"[0]!="a"}else if(name=="json"){isSupported=has("json-stringify")&&has("json-parse")}else{var value,serialized='{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';if(name=="json-stringify"){var stringify=JSON3.stringify,stringifySupported=typeof stringify=="function"&&isExtended;if(stringifySupported){(value=function(){return 1}).toJSON=value;try{stringifySupported=stringify(0)==="0"&&stringify(new Number)==="0"&&stringify(new String)=='""'&&stringify(getClass)===undef&&stringify(undef)===undef&&stringify()===undef&&stringify(value)==="1"&&stringify([value])=="[1]"&&stringify([undef])=="[null]"&&stringify(null)=="null"&&stringify([undef,getClass,null])=="[null,null,null]"&&stringify({a:[value,true,false,null,"\x00\b\n\f\r "]})==serialized&&stringify(null,value)==="1"&&stringify([1,2],null,1)=="[\n 1,\n 2\n]"&&stringify(new Date(-864e13))=='"-271821-04-20T00:00:00.000Z"'&&stringify(new Date(864e13))=='"+275760-09-13T00:00:00.000Z"'&&stringify(new Date(-621987552e5))=='"-000001-01-01T00:00:00.000Z"'&&stringify(new Date(-1))=='"1969-12-31T23:59:59.999Z"'}catch(exception){stringifySupported=false}}isSupported=stringifySupported}if(name=="json-parse"){var parse=JSON3.parse;if(typeof parse=="function"){try{if(parse("0")===0&&!parse(false)){value=parse(serialized);var parseSupported=value["a"].length==5&&value["a"][0]===1;if(parseSupported){try{parseSupported=!parse('" "')}catch(exception){}if(parseSupported){try{parseSupported=parse("01")!==1}catch(exception){}}if(parseSupported){try{parseSupported=parse("1.")!==1}catch(exception){}}}}}catch(exception){parseSupported=false}}isSupported=parseSupported}}return has[name]=!!isSupported}if(!has("json")){var functionClass="[object Function]";var dateClass="[object Date]";var numberClass="[object Number]";var stringClass="[object String]";var arrayClass="[object Array]";var booleanClass="[object Boolean]";var charIndexBuggy=has("bug-string-char-index");if(!isExtended){var floor=Math.floor;var Months=[0,31,59,90,120,151,181,212,243,273,304,334];var getDay=function(year,month){return Months[month]+365*(year-1970)+floor((year-1969+(month=+(month>1)))/4)-floor((year-1901+month)/100)+floor((year-1601+month)/400)}}if(!(isProperty={}.hasOwnProperty)){isProperty=function(property){var members={},constructor;if((members.__proto__=null,members.__proto__={toString:1},members).toString!=getClass){isProperty=function(property){var original=this.__proto__,result=property in(this.__proto__=null,this);this.__proto__=original;return result}}else{constructor=members.constructor;isProperty=function(property){var parent=(this.constructor||constructor).prototype;return property in this&&!(property in parent&&this[property]===parent[property])}}members=null;return isProperty.call(this,property)}}var PrimitiveTypes={"boolean":1,number:1,string:1,undefined:1};var isHostType=function(object,property){var type=typeof object[property];return type=="object"?!!object[property]:!PrimitiveTypes[type]};forEach=function(object,callback){var size=0,Properties,members,property;(Properties=function(){this.valueOf=0}).prototype.valueOf=0;members=new Properties;for(property in members){if(isProperty.call(members,property)){size++}}Properties=members=null;if(!size){members=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,length;var hasProperty=!isFunction&&typeof object.constructor!="function"&&isHostType(object,"hasOwnProperty")?object.hasOwnProperty:isProperty;for(property in object){if(!(isFunction&&property=="prototype")&&hasProperty.call(object,property)){callback(property)}}for(length=members.length;property=members[--length];hasProperty.call(object,property)&&callback(property));}}else if(size==2){forEach=function(object,callback){var members={},isFunction=getClass.call(object)==functionClass,property;for(property in object){if(!(isFunction&&property=="prototype")&&!isProperty.call(members,property)&&(members[property]=1)&&isProperty.call(object,property)){callback(property)}}}}else{forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,isConstructor;for(property in object){if(!(isFunction&&property=="prototype")&&isProperty.call(object,property)&&!(isConstructor=property==="constructor")){callback(property)}}if(isConstructor||isProperty.call(object,property="constructor")){callback(property)}}}return forEach(object,callback)};if(!has("json-stringify")){var Escapes={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"};var leadingZeroes="000000";var toPaddedString=function(width,value){return(leadingZeroes+(value||0)).slice(-width)};var unicodePrefix="\\u00";var quote=function(value){var result='"',index=0,length=value.length,isLarge=length>10&&charIndexBuggy,symbols;if(isLarge){symbols=value.split("")}for(;index<length;index++){var charCode=value.charCodeAt(index);switch(charCode){case 8:case 9:case 10:case 12:case 13:case 34:case 92:result+=Escapes[charCode];break;default:if(charCode<32){result+=unicodePrefix+toPaddedString(2,charCode.toString(16));break}result+=isLarge?symbols[index]:charIndexBuggy?value.charAt(index):value[index]}}return result+'"'};var serialize=function(property,object,callback,properties,whitespace,indentation,stack){var value,className,year,month,date,time,hours,minutes,seconds,milliseconds,results,element,index,length,prefix,result;try{value=object[property]}catch(exception){}if(typeof value=="object"&&value){className=getClass.call(value);if(className==dateClass&&!isProperty.call(value,"toJSON")){if(value>-1/0&&value<1/0){if(getDay){date=floor(value/864e5);for(year=floor(date/365.2425)+1970-1;getDay(year+1,0)<=date;year++);for(month=floor((date-getDay(year,0))/30.42);getDay(year,month+1)<=date;month++);date=1+date-getDay(year,month);time=(value%864e5+864e5)%864e5;hours=floor(time/36e5)%24;minutes=floor(time/6e4)%60;seconds=floor(time/1e3)%60;milliseconds=time%1e3}else{year=value.getUTCFullYear();month=value.getUTCMonth();date=value.getUTCDate();hours=value.getUTCHours();minutes=value.getUTCMinutes();seconds=value.getUTCSeconds();milliseconds=value.getUTCMilliseconds()}value=(year<=0||year>=1e4?(year<0?"-":"+")+toPaddedString(6,year<0?-year:year):toPaddedString(4,year))+"-"+toPaddedString(2,month+1)+"-"+toPaddedString(2,date)+"T"+toPaddedString(2,hours)+":"+toPaddedString(2,minutes)+":"+toPaddedString(2,seconds)+"."+toPaddedString(3,milliseconds)+"Z"}else{value=null}}else if(typeof value.toJSON=="function"&&(className!=numberClass&&className!=stringClass&&className!=arrayClass||isProperty.call(value,"toJSON"))){value=value.toJSON(property)}}if(callback){value=callback.call(object,property,value)}if(value===null){return"null"}className=getClass.call(value);if(className==booleanClass){return""+value}else if(className==numberClass){return value>-1/0&&value<1/0?""+value:"null"}else if(className==stringClass){return quote(""+value)}if(typeof value=="object"){for(length=stack.length;length--;){if(stack[length]===value){throw TypeError()}}stack.push(value);results=[];prefix=indentation;indentation+=whitespace;if(className==arrayClass){for(index=0,length=value.length;index<length;index++){element=serialize(index,value,callback,properties,whitespace,indentation,stack);results.push(element===undef?"null":element)}result=results.length?whitespace?"[\n"+indentation+results.join(",\n"+indentation)+"\n"+prefix+"]":"["+results.join(",")+"]":"[]"}else{forEach(properties||value,function(property){var element=serialize(property,value,callback,properties,whitespace,indentation,stack);if(element!==undef){results.push(quote(property)+":"+(whitespace?" ":"")+element)}});result=results.length?whitespace?"{\n"+indentation+results.join(",\n"+indentation)+"\n"+prefix+"}":"{"+results.join(",")+"}":"{}"}stack.pop();return result}};JSON3.stringify=function(source,filter,width){var whitespace,callback,properties,className;if(typeof filter=="function"||typeof filter=="object"&&filter){if((className=getClass.call(filter))==functionClass){callback=filter}else if(className==arrayClass){properties={};for(var index=0,length=filter.length,value;index<length;value=filter[index++],(className=getClass.call(value),className==stringClass||className==numberClass)&&(properties[value]=1));}}if(width){if((className=getClass.call(width))==numberClass){if((width-=width%1)>0){for(whitespace="",width>10&&(width=10);whitespace.length<width;whitespace+=" ");}}else if(className==stringClass){whitespace=width.length<=10?width:width.slice(0,10)}}return serialize("",(value={},value[""]=source,value),callback,properties,whitespace,"",[])}}if(!has("json-parse")){var fromCharCode=String.fromCharCode;var Unescapes={92:"\\",34:'"',47:"/",98:"\b",116:" ",110:"\n",102:"\f",114:"\r"};var Index,Source;var abort=function(){Index=Source=null;throw SyntaxError()};var lex=function(){var source=Source,length=source.length,value,begin,position,isSigned,charCode;while(Index<length){charCode=source.charCodeAt(Index);switch(charCode){case 9:case 10:case 13:case 32:Index++;break;case 123:case 125:case 91:case 93:case 58:case 44:value=charIndexBuggy?source.charAt(Index):source[Index];Index++;return value;case 34:for(value="@",Index++;Index<length;){charCode=source.charCodeAt(Index);if(charCode<32){abort()}else if(charCode==92){charCode=source.charCodeAt(++Index);switch(charCode){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:value+=Unescapes[charCode];Index++;break;case 117:begin=++Index;for(position=Index+4;Index<position;Index++){charCode=source.charCodeAt(Index);if(!(charCode>=48&&charCode<=57||charCode>=97&&charCode<=102||charCode>=65&&charCode<=70)){abort()}}value+=fromCharCode("0x"+source.slice(begin,Index));break;default:abort()}}else{if(charCode==34){break}charCode=source.charCodeAt(Index);begin=Index;while(charCode>=32&&charCode!=92&&charCode!=34){charCode=source.charCodeAt(++Index)}value+=source.slice(begin,Index)}}if(source.charCodeAt(Index)==34){Index++;return value}abort();default:begin=Index;if(charCode==45){isSigned=true;charCode=source.charCodeAt(++Index)}if(charCode>=48&&charCode<=57){if(charCode==48&&(charCode=source.charCodeAt(Index+1),charCode>=48&&charCode<=57)){abort()}isSigned=false;for(;Index<length&&(charCode=source.charCodeAt(Index),charCode>=48&&charCode<=57);Index++);if(source.charCodeAt(Index)==46){position=++Index;for(;position<length&&(charCode=source.charCodeAt(position),charCode>=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}charCode=source.charCodeAt(Index);if(charCode==101||charCode==69){charCode=source.charCodeAt(++Index);if(charCode==43||charCode==45){Index++}for(position=Index;position<length&&(charCode=source.charCodeAt(position),charCode>=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}return+source.slice(begin,Index)}if(isSigned){abort()}if(source.slice(Index,Index+4)=="true"){Index+=4;return true}else if(source.slice(Index,Index+5)=="false"){Index+=5;return false}else if(source.slice(Index,Index+4)=="null"){Index+=4;return null}abort()}}return"$"};var get=function(value){var results,hasMembers;if(value=="$"){abort()}if(typeof value=="string"){if((charIndexBuggy?value.charAt(0):value[0])=="@"){return value.slice(1)}if(value=="["){results=[];for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="]"){break}if(hasMembers){if(value==","){value=lex();if(value=="]"){abort()}}else{abort()}}if(value==","){abort()}results.push(get(value))}return results}else if(value=="{"){results={};for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="}"){break}if(hasMembers){if(value==","){value=lex();if(value=="}"){abort()}}else{abort()}}if(value==","||typeof value!="string"||(charIndexBuggy?value.charAt(0):value[0])!="@"||lex()!=":"){abort()}results[value.slice(1)]=get(lex())}return results}abort()}return value};var update=function(source,property,callback){var element=walk(source,property,callback);if(element===undef){delete source[property]}else{source[property]=element}};var walk=function(source,property,callback){var value=source[property],length;if(typeof value=="object"&&value){if(getClass.call(value)==arrayClass){for(length=value.length;length--;){update(value,length,callback)}}else{forEach(value,function(property){update(value,property,callback)})}}return callback.call(source,property,value)};JSON3.parse=function(source,callback){var result,value;Index=0;Source=""+source;result=get(lex());if(lex()!="$"){abort()}Index=Source=null;return callback&&getClass.call(callback)==functionClass?walk((value={},value[""]=result,value),"",callback):result}}}if(isLoader){define(function(){return JSON3})}})(this)},{}],48:[function(_dereq_,module,exports){module.exports=toArray;function toArray(list,index){var array=[];index=index||0;for(var i=index||0;i<list.length;i++){array[i-index]=list[i]}return array}},{}]},{},[1])(1)});
cropData.png

This is a binary file and will not be displayed.

data.png

This is a binary file and will not be displayed.

+2
node_modules/gm/.npmignore
··· 1 + test/ 2 + examples/
+7
node_modules/gm/.travis.yml
··· 1 + before_install: 2 + - sudo apt-get update 3 + - sudo apt-get install imagemagick graphicsmagick 4 + language: node_js 5 + node_js: 6 + - "0.8" 7 + - "0.10"
+507
node_modules/gm/History.md
··· 1 + 1.17.0 / 2014-10-28 2 + ================== 3 + 4 + * changed: extended compare callback also returns the file names #297 [mastix](https://github.com/mastix) 5 + * changed: pass spawn crash to callback #306 [medikoo](https://github.com/medikoo) 6 + * changed: geometry supports arbitary string as first argument #330 [jdiez17](https://github.com/jdiez17) 7 + * added: support for repage+ option #275 [desigens](https://github.com/desigens) 8 + * added: added the dissolve command #300 [microadm](https://github.com/microadam) 9 + * added: composite method #332 [jdiez17](https://github.com/jdiez17) 10 + * fixed: cannot set tolerance to 0 #302 [rwky](https://github.com/rwky) 11 + * fixed: handle empty buffers #330 [alcidesv](https://github.com/alcidesv) 12 + 13 + 1.16.0 / 2014-05-09 14 + ================== 15 + 16 + * fixed; dropped "+" when 0 passed as vertical roll amt #267 [dwtkns](https://github.com/dwtkns) 17 + * added; highlight-style support #272 [fdecampredon](https://github.com/fdecampredon) 18 + 19 + 1.15.0 / 2014-05-03 20 + =================== 21 + 22 + * changed; gm.compare logic to always run the mse comparison as expected #258 [Vokkim](https://github.com/Vokkim) 23 + * added; `tolerance` to gm.compare options object #258 [Vokkim](https://github.com/Vokkim) 24 + * added; option to set ImageMagick application path explicitly #250 (akreitals) 25 + * fixed; gm.compare: support values like 9.51582e-05 #260 [normanrz](https://github.com/normanrz) 26 + * README: add call for maintainers 27 + 28 + 1.14.2 / 2013-12-24 29 + =================== 30 + 31 + * fixed; background is now a setting #246 (PEM--) 32 + 33 + 1.14.1 / 2013-12-09 34 + =================== 35 + 36 + * fixed; identify -verbose colon behavior #240 ludow 37 + 38 + 1.14.0 / 2013-12-04 39 + =================== 40 + 41 + * added; compare method for imagemagick (longlho) 42 + 43 + 1.13.3 / 2013-10-22 44 + =================== 45 + 46 + * fixed; escape diffOptions.file in compare (dwabyick) 47 + 48 + 1.13.2 / 2013-10-18 49 + =================== 50 + 51 + * fixed; density is a setting not an operator 52 + 53 + 1.13.1 / 2013-09-15 54 + =================== 55 + 56 + * added; boolean for % crop 57 + 58 + 1.13.0 / 2013-09-07 59 + =================== 60 + 61 + * added; morph more than two images (overra) 62 + 63 + 1.12.2 / 2013-08-29 64 + =================== 65 + 66 + * fixed; fallback to through in node 0.8 67 + 68 + 1.12.1 / 2013-08-29 (unpublished) 69 + =================== 70 + 71 + * refactor; replace through with stream.PassThrough 72 + 73 + 1.12.0 / 2013-08-27 74 + =================== 75 + 76 + * added; diff image output file (chenglou) 77 + 78 + 1.11.1 / 2013-08-17 79 + =================== 80 + 81 + * added; proto.selectFrame(#) 82 + * fixed; getters should not ignore frame selection 83 + 84 + 1.11.0 / 2013-07-23 85 + =================== 86 + 87 + * added; optional formatting string for gm().identify(format, callback) (tornillo) 88 + * removed; error messages when gm/im binary is not installed 89 + 90 + 1.10.0 / 2013-06-27 91 + =================== 92 + 93 + * refactor; use native `-auto-orient` for imagemagick 94 + 95 + 1.9.2 / 2013-06-12 96 + ================== 97 + 98 + * refactor; move `streamToBuffer` to a separate module 99 + * fixed; .stream(format) without a callback 100 + 101 + 1.9.1 / 2013-05-07 102 + ================== 103 + 104 + * fixed; gm().resize(width) always only resizes width 105 + * fixed; gm('img.gif').format() returns the format of the first frame 106 + 107 + 1.9.0 / 2013-04-21 108 + ================== 109 + 110 + * added; node v0.10 support 111 + * removed; node < v0.8 support - `Buffer.concat()` 112 + * tests; all tests now run on Travis 113 + * added; gm().stream() returns a stream when no callback is present 114 + * added; gm().toBuffer(callback) 115 + * fixed; gm().size() only returns the size of the first frame of a GIF 116 + 117 + 1.8.2 / 2013-03-07 118 + ================== 119 + 120 + * include source path in identify data #126 [soupdiver](https://github.com/soupdiver) 121 + 122 + 1.8.1 / 2012-12-21 123 + ================== 124 + 125 + * Avoid losing already set arguments on identify #105 #113 #109 [JNissi](https://github.com/JNissi) 126 + * tests; add autoOrient + thumb() test 127 + * tests; add test case for #113 128 + * tests; added test for #109 129 + * tests; add resize on buffer test 130 + 131 + 1.8.0 / 2012-12-14 132 + ================== 133 + 134 + * added; geometry support to scale() #98 135 + * removed; incorrect/broken dissolve() method (never worked) 136 + * fixed; handle child_proc error when using Buffer input #109 137 + * fixed; use of Buffers with identify() #109 138 + * fixed; no longer include -size arg with resize() #98 139 + * fixed; remove -size arg from extent() #103 140 + * fixed; magnify support 141 + * fixed; autoOrient to work with all types of exif orientations [dambalah](https://github.com/dambalah) #108 142 + * tests; npm test runs unit only (now compatible with travis) 143 + * tests; fix magnify test on imagemagick 144 + * tests; added for cmd line args 145 + 146 + 1.7.0 / 2012-12-06 147 + ================== 148 + 149 + * added; gm.compare support 150 + * added; passing Buffers directly [danmilon](https://github.com/danmilon) 151 + 152 + 1.6.1 / 2012-11-13 153 + ================== 154 + 155 + * fixed regression; only pass additional params on error #96 156 + 157 + 1.6.0 / 2012-11-10 158 + ================== 159 + 160 + * changed; rename internal buffer to _buffer #88 [kof](https://github.com/kof) 161 + * changed; optimized identify getters (format, depth, size, color, filesize). #83 please read this for details: https://github.com/aheckmann/gm/commit/8fcf3f8f84a02cc2001da874cbebb89bf7084409 162 + * added; visionmedia/debug support 163 + * added; `gm convert -thumbnail` support. _differs from thumb()._ [danmilon](https://github.com/danmilon) 164 + * fixed; -rotate 0 support #90 165 + * fixed; multi-execution of same gm instance arguments corruption 166 + * fixed; gracefully handle parser errors #94 [eldilibra](https://github.com/eldilibra) 167 + 168 + 1.5.1 / 2012-10-02 169 + ================== 170 + 171 + * fixed; passing multiple paths to append() #77 172 + 173 + 1.5.0 / 2012-09-15 174 + ================== 175 + 176 + * fixed; callback scope 177 + * fixed; append() usage #77 178 + 179 + 1.4.2 / 2012-08-17 180 + ================== 181 + 182 + * fixed; identify parsing for ImageMagick exif data (#58) 183 + * fixed; when in imageMagick mode, complain about missing imageMagick [bcherry](https://github.com/bcherry) (#73) 184 + * added; tests 185 + 186 + 1.4.1 / 2012-07-31 187 + ================== 188 + 189 + * fixed; scenes() args 190 + * fixed; accept the left-to-right arg of append() 191 + * added; _subCommand 192 + 193 + ## v1.4 - 07/28/2012 194 + 195 + * added; adjoin() [Math-] 196 + * added; affine() [Math-] 197 + * added; append() [Math-] 198 + * added; authenticate() [Math-] 199 + * added; average() [Math-] 200 + * added; backdrop() [Math-] 201 + * added; blackThreshold() [Math-] 202 + * added; bluePrimary() [Math-] 203 + * added; border() [Math-] 204 + * added; borderColor() [Math-] 205 + * added; box() [Math-] 206 + * added; channel() [Math-] 207 + * added; clip() [Math-] 208 + * added; coalesce() [Math-] 209 + * added; colorMap() [Math-] 210 + * added; compose() [Math-] 211 + * added; compress() [Math-] 212 + * added; convolve() [Math-] 213 + * added; createDirectories() [Math-] 214 + * added; deconstruct() [Math-] 215 + * added; delay() [Math-] 216 + * added; define() [Math-] 217 + * added; displace() [Math-] 218 + * added; display() [Math-] 219 + * added; dispose() [Math-] 220 + * added; disolve() [Math-] 221 + * added; encoding() [Math-] 222 + * added; endian() [Math-] 223 + * added; file() [Math-] 224 + * added; flatten() [Math-] 225 + * added; foreground() [Math-] 226 + * added; frame() [Math-] 227 + * added; fuzz() [Math-] 228 + * added; gaussian() [Math-] 229 + * added; geometry() [Math-] 230 + * added; greenPrimary() [Math-] 231 + * added; highlightColor() [Math-] 232 + * added; highlightStyle() [Math-] 233 + * added; iconGeometry() [Math-] 234 + * added; intent() [Math-] 235 + * added; lat() [Math-] 236 + * added; level() [Math-] 237 + * added; list() [Math-] 238 + * added; log() [Math-] 239 + * added; map() [Math-] 240 + * added; matte() [Math-] 241 + * added; matteColor() [Math-] 242 + * added; mask() [Math-] 243 + * added; maximumError() [Math-] 244 + * added; mode() [Math-] 245 + * added; monitor() [Math-] 246 + * added; mosaic() [Math-] 247 + * added; motionBlur() [Math-] 248 + * added; name() [Math-] 249 + * added; noop() [Math-] 250 + * added; normalize() [Math-] 251 + * added; opaque() [Math-] 252 + * added; operator() [Math-] 253 + * added; orderedDither() [Math-] 254 + * added; outputDirectory() [Math-] 255 + * added; page() [Math-] 256 + * added; pause() [Math-] 257 + * added; pen() [Math-] 258 + * added; ping() [Math-] 259 + * added; pointSize() [Math-] 260 + * added; preview() [Math-] 261 + * added; process() [Math-] 262 + * added; profile() [Math-] 263 + * added; progress() [Math-] 264 + * added; rawSize() [Math-] 265 + * added; randomThreshold() [Math-] 266 + * added; recolor() [Math-] 267 + * added; redPrimary() [Math-] 268 + * added; remote() [Math-] 269 + * added; render() [Math-] 270 + * added; repage() [Math-] 271 + * added; sample() [Math-] 272 + * added; samplingFactor() [Math-] 273 + * added; scene() [Math-] 274 + * added; scenes() [Math-] 275 + * added; screen() [Math-] 276 + * added; segment() [Math-] 277 + * added; set() [Math-] 278 + * added; shade() [Math-] 279 + * added; shadow() [Math-] 280 + * added; sharedMemory() [Math-] 281 + * added; shave() [Math-] 282 + * added; shear() [Math-] 283 + * added; silent() [Math-] 284 + * added; snaps() [Math-] 285 + * added; stagano() [Math-] 286 + * added; stereo() [Math-] 287 + * added; textFont() [Math-] 288 + * added; texture() [Math-] 289 + * added; threshold() [Math-] 290 + * added; tile() [Math-] 291 + * added; transform() [Math-] 292 + * added; transparent() [Math-] 293 + * added; treeDepth() [Math-] 294 + * added; update() [Math-] 295 + * added; units() [Math-] 296 + * added; unsharp() [Math-] 297 + * added; usePixmap() [Math-] 298 + * added; view() [Math-] 299 + * added; virtualPixel() [Math-] 300 + * added; visual() [Math-] 301 + * added; watermark() [Math-] 302 + * added; wave() [Math-] 303 + * added; whitePoint() [Math-] 304 + * added; whiteThreshold() [Math-] 305 + * added; window() [Math-] 306 + * added; windowGroup() [Math-] 307 + 308 + ## v1.3.2 - 06/22/2012 309 + 310 + * added; node >= 0.7/0.8 compat 311 + 312 + ## v1.3.1 - 06/06/2012 313 + 314 + * fixed; thumb() alignment and cropping [thomaschaaf] 315 + * added; hint when graphicsmagick is not installed (#62) 316 + * fixed; minify() (#59) 317 + 318 + ## v1.3.0 - 04/11/2012 319 + 320 + * added; flatten support [jwarchol] 321 + * added; background support [jwarchol] 322 + * fixed; identify parser error [chriso] 323 + 324 + ## v1.2.0 - 03/30/2012 325 + 326 + * added; extent and gravity support [jwarchol] 327 + 328 + ## v1.1.0 - 03/15/2012 329 + 330 + * added; filter() support [travisbeck] 331 + * added; density() [travisbeck] 332 + * fixed; permit either width or height in resize [dambalah] 333 + * updated; docs 334 + 335 + ## v1.0.5 - 02/15/2012 336 + 337 + * added; strip() support [Math-] 338 + * added; interlace() support [Math-] 339 + * added; setFormat() support [Math-] 340 + * fixed; regexps for image types [Math-] 341 + 342 + ## v1.0.4 - 02/09/2012 343 + 344 + * expose utils 345 + 346 + ## v1.0.3 - 01/27/2012 347 + 348 + * removed; console.log 349 + 350 + ## v1.0.2 - 01/24/2012 351 + 352 + * added; debugging info on parser errors 353 + * fixed; exports.version 354 + 355 + ## v1.0.1 - 01/12/2012 356 + 357 + * fixed; use of reserved keyword `super` for node v0.5+ 358 + 359 + ## v1.0.0 - 01/12/2012 360 + 361 + * added; autoOrient support [kainosnoema] (#21) 362 + * added; orientation support [kainosnoema] (#21) 363 + * fixed; identify parser now properly JSON formats all data output by `gm identify` such as IPTC, GPS, Make, etc (#20) 364 + * added; support for running as imagemagick (#23, #29) 365 + * added; subclassing support; useful for setting default constructor options like one constructor for ImageMagick, the other for GM 366 + * added; more tests 367 + * changed; remove redundant `orientation`, `resolution`, and `filesize` from `this.data` in `indentify()`. Use their uppercase equivalents. 368 + 369 + ## v0.6.0 - 12/14/2011 370 + 371 + * added; stream support [kainosnoema] (#22) 372 + 373 + ## v0.5.0 - 07/07/2011 374 + 375 + * added; gm#trim() support [lepokle] 376 + * added; gm#inputIs() support 377 + * fixed; 'geometry does not contain image' error: gh-17 378 + 379 + ## v0.4.3 - 05/17/2011 380 + 381 + * added; bunch of tests 382 + * fixed; polygon, polyline, bezier drawing bug 383 + 384 + ## v0.4.2 - 05/10/2011 385 + 386 + * added; resize options support 387 + 388 + ## v0.4.1 - 04/28/2011 389 + 390 + * shell args are now escaped (thanks @visionmedia) 391 + * added; gm.in() 392 + * added; gm.out() 393 + * various refactoring 394 + 395 + ## v0.4.0 - 9/21/2010 396 + 397 + * removed deprecated `new` method 398 + * added drawing docs 399 + 400 + ## v0.3.2 - 9/06/2010 401 + 402 + * new images are now created using same gm() constructor 403 + 404 + ## v0.3.1 - 9/06/2010 405 + 406 + * can now create images from scratch 407 + * add type method 408 + 409 + ## v0.3.0 - 8/26/2010 410 + 411 + * add drawing api 412 + 413 + ## v0.2.2 - 8/22/2010 414 + 415 + * add quality option to thumb() 416 + * add teropa to contributors 417 + * added support for colorspace() 418 + 419 + ## v0.2.1 - 7/31/2010 420 + 421 + * fixed naming conflict. depth() manipulation method renamed bitdepth() 422 + * added better docs 423 + 424 + ## v0.2.0 - 7/29/2010 425 + 426 + new methods 427 + 428 + - swirl 429 + - spread 430 + - solarize 431 + - sharpen 432 + - roll 433 + - sepia 434 + - region 435 + - raise 436 + - lower 437 + - paint 438 + - noise 439 + - negative 440 + - morph 441 + - median 442 + - antialias 443 + - limit 444 + - label 445 + - implode 446 + - gamma 447 + - enhance 448 + - equalize 449 + - emboss 450 + - edge 451 + - dither 452 + - monochrome 453 + - despeckle 454 + - depth 455 + - cycle 456 + - contrast 457 + - comment 458 + - colors 459 + 460 + added more default args to several methods 461 + added more examples 462 + 463 + 464 + ## v0.1.2 - 7/28/2010 465 + 466 + * refactor project into separate modules 467 + 468 + 469 + ## v0.1.1 - 7/27/2010 470 + 471 + * add modulate method 472 + * add colorize method 473 + * add charcoal method 474 + * add chop method 475 + * bug fix in write without a callback 476 + 477 + 478 + ## v0.1.0 - 6/27/2010 479 + 480 + * no longer supporting mogrify 481 + * add image data getter methods 482 + 483 + * size 484 + * format 485 + * color 486 + * res 487 + * depth 488 + * filesize 489 + * identify 490 + 491 + * add new convert methods 492 + 493 + * scale 494 + * resample 495 + * rotate 496 + * flip 497 + * flop 498 + * crop 499 + * magnify 500 + * minify 501 + * quality 502 + * blur 503 + * thumb 504 + 505 + 506 + ## v0.0.1 - 6/11/2010 507 + Initial release
+8
node_modules/gm/Makefile
··· 1 + 2 + test: 3 + @node test/ --integration $(TESTS) 4 + 5 + test-unit: 6 + @node test/ $(TESTS) 7 + 8 + .PHONY: test test-unit
+598
node_modules/gm/README.md
··· 1 + 2 + # gm v1.17.0 [![Build Status](https://travis-ci.org/aheckmann/gm.png?branch=master)](https://travis-ci.org/aheckmann/gm) [![NPM Version](https://img.shields.io/npm/v/gm.svg?style=flat)](https://www.npmjs.org/package/gm) 3 + 4 + GraphicsMagick and ImageMagick for node 5 + 6 + ## Getting started 7 + First download and install [GraphicsMagick](http://www.graphicsmagick.org/) or [ImageMagick](http://www.imagemagick.org/). In Mac OS X, you can simply use [Homebrew](http://mxcl.github.io/homebrew/) and do: 8 + 9 + brew install imagemagick 10 + brew install graphicsmagick 11 + 12 + If you want WebP support with ImageMagick, you must add the WebP option: 13 + 14 + brew install imagemagick --with-webp 15 + 16 + then either use npm: 17 + 18 + npm install gm 19 + 20 + or clone the repo: 21 + 22 + git clone git://github.com/aheckmann/gm.git 23 + 24 + 25 + ## Use ImageMagick instead of gm 26 + 27 + Just pass the option `{imageMagick: true}` to enable ImageMagick 28 + 29 + ```js 30 + var fs = require('fs') 31 + , gm = require('./gm'); 32 + 33 + // resize and remove EXIF profile data 34 + gm('/path/to/my/img.jpg') 35 + .options({imageMagick: true}) 36 + .resize(240, 240) 37 + ... 38 + ``` 39 + 40 + 41 + ## Basic Usage 42 + 43 + ```js 44 + var fs = require('fs') 45 + , gm = require('./gm'); 46 + 47 + // resize and remove EXIF profile data 48 + gm('/path/to/my/img.jpg') 49 + .resize(240, 240) 50 + .noProfile() 51 + .write('/path/to/resize.png', function (err) { 52 + if (!err) console.log('done'); 53 + }); 54 + 55 + // obtain the size of an image 56 + gm('/path/to/my/img.jpg') 57 + .size(function (err, size) { 58 + if (!err) 59 + console.log(size.width > size.height ? 'wider' : 'taller than you'); 60 + }); 61 + 62 + // output all available image properties 63 + gm('/path/to/img.png') 64 + .identify(function (err, data) { 65 + if (!err) console.log(data) 66 + }); 67 + 68 + // pull out the first frame of an animated gif and save as png 69 + gm('/path/to/animated.gif[0]') 70 + .write('/path/to/firstframe.png', function (err) { 71 + if (err) console.log('aaw, shucks'); 72 + }); 73 + 74 + // auto-orient an image 75 + gm('/path/to/img.jpg') 76 + .autoOrient() 77 + .write('/path/to/oriented.jpg', function (err) { 78 + if (err) ... 79 + }) 80 + 81 + // crazytown 82 + gm('/path/to/my/img.jpg') 83 + .flip() 84 + .magnify() 85 + .rotate('green', 45) 86 + .blur(7, 3) 87 + .crop(300, 300, 150, 130) 88 + .edge(3) 89 + .write('/path/to/crazy.jpg', function (err) { 90 + if (!err) console.log('crazytown has arrived'); 91 + }) 92 + 93 + // annotate an image 94 + gm('/path/to/my/img.jpg') 95 + .stroke("#ffffff") 96 + .drawCircle(10, 10, 20, 10) 97 + .font("Helvetica.ttf", 12) 98 + .drawText(30, 20, "GMagick!") 99 + .write("/path/to/drawing.png", function (err) { 100 + if (!err) console.log('done'); 101 + }); 102 + 103 + // creating an image 104 + gm(200, 400, "#ddff99f3") 105 + .drawText(10, 50, "from scratch") 106 + .write("/path/to/brandNewImg.jpg", function (err) { 107 + // ... 108 + }); 109 + ``` 110 + 111 + ## Streams 112 + 113 + ```js 114 + // passing a stream 115 + var readStream = fs.createReadStream('/path/to/my/img.jpg'); 116 + gm(readStream, 'img.jpg') 117 + .write('/path/to/reformat.png', function (err) { 118 + if (!err) console.log('done'); 119 + }); 120 + 121 + // can also stream output to a ReadableStream 122 + // (can be piped to a local file or remote server) 123 + gm('/path/to/my/img.jpg') 124 + .resize('200', '200') 125 + .stream(function (err, stdout, stderr) { 126 + var writeStream = fs.createWriteStream('/path/to/my/resized.jpg'); 127 + stdout.pipe(writeStream); 128 + }); 129 + 130 + // without a callback, .stream() returns a stream 131 + // this is just a convenience wrapper for above. 132 + var writeStream = fs.createWriteStream('/path/to/my/resized.jpg'); 133 + gm('/path/to/my/img.jpg') 134 + .resize('200', '200') 135 + .stream() 136 + .pipe(writeStream); 137 + 138 + // pass a format or filename to stream() and 139 + // gm will provide image data in that format 140 + gm('/path/to/my/img.jpg') 141 + .stream('png', function (err, stdout, stderr) { 142 + var writeStream = fs.createWriteStream('/path/to/my/reformated.png'); 143 + stdout.pipe(writeStream); 144 + }); 145 + 146 + // or without the callback 147 + var writeStream = fs.createWriteStream('/path/to/my/reformated.png'); 148 + gm('/path/to/my/img.jpg') 149 + .stream('png') 150 + .pipe(writeStream); 151 + 152 + // combine the two for true streaming image processing 153 + var readStream = fs.createReadStream('/path/to/my/img.jpg'); 154 + gm(readStream, 'img.jpg') 155 + .resize('200', '200') 156 + .stream(function (err, stdout, stderr) { 157 + var writeStream = fs.createWriteStream('/path/to/my/resized.jpg'); 158 + stdout.pipe(writeStream); 159 + }); 160 + 161 + // GOTCHA: 162 + // when working with input streams and any 'identify' 163 + // operation (size, format, etc), you must pass "{bufferStream: true}" if 164 + // you also need to convert (write() or stream()) the image afterwards 165 + // NOTE: this buffers the readStream in memory! 166 + var readStream = fs.createReadStream('/path/to/my/img.jpg'); 167 + gm(readStream, 'img.jpg') 168 + .size({bufferStream: true}, function(err, size) { 169 + this.resize(size.width / 2, size.height / 2) 170 + this.write('/path/to/resized.jpg', function (err) { 171 + if (!err) console.log('done'); 172 + }); 173 + }); 174 + 175 + ``` 176 + 177 + ## Buffers 178 + 179 + ```js 180 + // A buffer can be passed instead of a filepath as well 181 + var buf = require('fs').readFileSync('/path/to/image.jpg'); 182 + 183 + gm(buf, 'image.jpg') 184 + .noise('laplacian') 185 + .write('/path/to/out.jpg', function (err) { 186 + if (err) return handle(err); 187 + console.log('Created an image from a Buffer!'); 188 + }); 189 + 190 + /* 191 + A buffer can also be returned instead of a stream 192 + The first argument to toBuffer is optional, it specifies the image format 193 + */ 194 + gm('img.jpg') 195 + .resize(100, 100) 196 + .toBuffer('PNG',function (err, buffer) { 197 + if (err) return handle(err); 198 + console.log('done!'); 199 + }) 200 + ``` 201 + 202 + ## Custom Arguments 203 + 204 + If `gm` does not supply you with a method you need or does not work as you'd like, you can simply use `gm().in()` or `gm().out()` to set your own arguments. 205 + 206 + - `gm().command()` - Custom command such as `identify` or `convert` 207 + - `gm().in()` - Custom input arguments 208 + - `gm().out()` - Custom output arguments 209 + 210 + The command will be formatted in the following order: 211 + 212 + 1. `command` - ie `convert` 213 + 2. `in` - the input arguments 214 + 3. `source` - stdin or an image file 215 + 4. `out` - the output arguments 216 + 5. `output` - stdout or the image file to write to 217 + 218 + For example, suppose you want the following command: 219 + 220 + ```bash 221 + gm "convert" "label:Offline" "PNG:-" 222 + ``` 223 + 224 + However, using `gm().label()` may not work as intended for you: 225 + 226 + ```js 227 + gm() 228 + .label('Offline') 229 + .stream(); 230 + ``` 231 + 232 + would yield: 233 + 234 + ```bash 235 + gm "convert" "-label" "\"Offline\"" "PNG:-" 236 + ``` 237 + 238 + Instead, you can use `gm().out()`: 239 + 240 + ```js 241 + gm() 242 + .out('label:Offline') 243 + .stream(); 244 + ``` 245 + 246 + which correctly yields: 247 + 248 + ```bash 249 + gm "convert" "label:Offline" "PNG:-" 250 + ``` 251 + 252 + ### Custom Identify Format String 253 + 254 + When identifying an image, you may want to use a custom formatting string instead of using `-verbose`, which is quite slow. 255 + You can use your own [formatting string](http://www.imagemagick.org/script/escape.php) when using `gm().identify(format, callback)`. 256 + For example, 257 + 258 + ```js 259 + gm('img.png').format(function (err, format) { 260 + 261 + }) 262 + 263 + // is equivalent to 264 + 265 + gm('img.png').identify('%m', function (err, format) { 266 + 267 + }) 268 + ``` 269 + 270 + since `%m` is the format option for getting the image file format. 271 + 272 + ## Platform differences 273 + 274 + Please document and refer to any [platform or ImageMagick/GraphicsMagick issues/differences here](https://github.com/aheckmann/gm/wiki/GraphicsMagick-and-ImageMagick-versions). 275 + 276 + ## Examples: 277 + 278 + Check out the [examples](http://github.com/aheckmann/gm/tree/master/examples/) directory to play around. 279 + Also take a look at the [extending gm](http://wiki.github.com/aheckmann/gm/extending-gm) 280 + page to see how to customize gm to your own needs. 281 + 282 + ## Constructor: 283 + 284 + There are a few ways you can use the `gm` image constructor. 285 + 286 + - 1) `gm(path)` When you pass a string as the first argument it is interpreted as the path to an image you intend to manipulate. 287 + - 2) `gm(stream || buffer, [filename])` You may also pass a ReadableStream or Buffer as the first argument, with an optional file name for format inference. 288 + - 3) `gm(width, height, [color])` When you pass two integer arguments, gm will create a new image on the fly with the provided dimensions and an optional background color. And you can still chain just like you do with pre-existing images too. See [here](http://github.com/aheckmann/gm/blob/master/examples/new.js) for an example. 289 + 290 + ## Methods 291 + 292 + - getters 293 + - [size](http://aheckmann.github.com/gm/docs.html#getters) - returns the size (WxH) of the image 294 + - [orientation](http://aheckmann.github.com/gm/docs.html#orientation) - returns the EXIF orientation of the image 295 + - [format](http://aheckmann.github.com/gm/docs.html#getters) - returns the image format (gif, jpeg, png, etc) 296 + - [depth](http://aheckmann.github.com/gm/docs.html#getters) - returns the image color depth 297 + - [color](http://aheckmann.github.com/gm/docs.html#getters) - returns the number of colors 298 + - [res](http://aheckmann.github.com/gm/docs.html#getters) - returns the image resolution 299 + - [filesize](http://aheckmann.github.com/gm/docs.html#getters) - returns image filesize 300 + - [identify](http://aheckmann.github.com/gm/docs.html#getters) - returns all image data available. Takes an optional format string. 301 + 302 + - manipulation 303 + - [adjoin](http://aheckmann.github.com/gm/docs.html#adjoin) 304 + - [affine](http://aheckmann.github.com/gm/docs.html#affine) 305 + - [antialias](http://aheckmann.github.com/gm/docs.html#antialias) 306 + - [append](http://aheckmann.github.com/gm/docs.html#append) 307 + - [authenticate](http://aheckmann.github.com/gm/docs.html#authenticate) 308 + - [autoOrient](http://aheckmann.github.com/gm/docs.html#autoOrient) 309 + - [average](http://aheckmann.github.com/gm/docs.html#average) 310 + - [backdrop](http://aheckmann.github.com/gm/docs.html#backdrop) 311 + - [bitdepth](http://aheckmann.github.com/gm/docs.html#bitdepth) 312 + - [blackThreshold](http://aheckmann.github.com/gm/docs.html#blackThreshold) 313 + - [bluePrimary](http://aheckmann.github.com/gm/docs.html#bluePrimary) 314 + - [blur](http://aheckmann.github.com/gm/docs.html#blur) 315 + - [border](http://aheckmann.github.com/gm/docs.html#border) 316 + - [borderColor](http://aheckmann.github.com/gm/docs.html#borderColor) 317 + - [box](http://aheckmann.github.com/gm/docs.html#box) 318 + - [channel](http://aheckmann.github.com/gm/docs.html#channel) 319 + - [charcoal](http://aheckmann.github.com/gm/docs.html#charcoal) 320 + - [chop](http://aheckmann.github.com/gm/docs.html#chop) 321 + - [clip](http://aheckmann.github.com/gm/docs.html#clip) 322 + - [coalesce](http://aheckmann.github.com/gm/docs.html#coalesce) 323 + - [colors](http://aheckmann.github.com/gm/docs.html#colors) 324 + - [colorize](http://aheckmann.github.com/gm/docs.html#colorize) 325 + - [colorMap](http://aheckmann.github.com/gm/docs.html#colorMap) 326 + - [colorspace](http://aheckmann.github.com/gm/docs.html#colorspace) 327 + - [comment](http://aheckmann.github.com/gm/docs.html#comment) 328 + - [compose](http://aheckmann.github.com/gm/docs.html#compose) 329 + - [compress](http://aheckmann.github.com/gm/docs.html#compress) 330 + - [contrast](http://aheckmann.github.com/gm/docs.html#contrast) 331 + - [convolve](http://aheckmann.github.com/gm/docs.html#convolve) 332 + - [createDirectories](http://aheckmann.github.com/gm/docs.html#createDirectories) 333 + - [crop](http://aheckmann.github.com/gm/docs.html#crop) 334 + - [cycle](http://aheckmann.github.com/gm/docs.html#cycle) 335 + - [deconstruct](http://aheckmann.github.com/gm/docs.html#deconstruct) 336 + - [delay](http://aheckmann.github.com/gm/docs.html#delay) 337 + - [define](http://aheckmann.github.com/gm/docs.html#define) 338 + - [density](http://aheckmann.github.com/gm/docs.html#density) 339 + - [despeckle](http://aheckmann.github.com/gm/docs.html#despeckle) 340 + - [dither](http://aheckmann.github.com/gm/docs.html#dither) 341 + - [displace](http://aheckmann.github.com/gm/docs.html#dither) 342 + - [display](http://aheckmann.github.com/gm/docs.html#display) 343 + - [dispose](http://aheckmann.github.com/gm/docs.html#dispose) 344 + - [dissolve](http://aheckmann.github.com/gm/docs.html#dissolve) 345 + - [edge](http://aheckmann.github.com/gm/docs.html#edge) 346 + - [emboss](http://aheckmann.github.com/gm/docs.html#emboss) 347 + - [encoding](http://aheckmann.github.com/gm/docs.html#encoding) 348 + - [enhance](http://aheckmann.github.com/gm/docs.html#enhance) 349 + - [endian](http://aheckmann.github.com/gm/docs.html#endian) 350 + - [equalize](http://aheckmann.github.com/gm/docs.html#equalize) 351 + - [extent](http://aheckmann.github.com/gm/docs.html#extent) 352 + - [file](http://aheckmann.github.com/gm/docs.html#file) 353 + - [filter](http://aheckmann.github.com/gm/docs.html#filter) 354 + - [flatten](http://aheckmann.github.com/gm/docs.html#flatten) 355 + - [flip](http://aheckmann.github.com/gm/docs.html#flip) 356 + - [flop](http://aheckmann.github.com/gm/docs.html#flop) 357 + - [foreground](http://aheckmann.github.com/gm/docs.html#foreground) 358 + - [frame](http://aheckmann.github.com/gm/docs.html#frame) 359 + - [fuzz](http://aheckmann.github.com/gm/docs.html#fuzz) 360 + - [gamma](http://aheckmann.github.com/gm/docs.html#gamma) 361 + - [gaussian](http://aheckmann.github.com/gm/docs.html#gaussian) 362 + - [geometry](http://aheckmann.github.com/gm/docs.html#geometry) 363 + - [gravity](http://aheckmann.github.com/gm/docs.html#gravity) 364 + - [greenPrimary](http://aheckmann.github.com/gm/docs.html#greenPrimary) 365 + - [highlightColor](http://aheckmann.github.com/gm/docs.html#highlightColor) 366 + - [highlightStyle](http://aheckmann.github.com/gm/docs.html#highlightStyle) 367 + - [iconGeometry](http://aheckmann.github.com/gm/docs.html#iconGeometry) 368 + - [implode](http://aheckmann.github.com/gm/docs.html#implode) 369 + - [intent](http://aheckmann.github.com/gm/docs.html#intent) 370 + - [interlace](http://aheckmann.github.com/gm/docs.html#interlace) 371 + - [label](http://aheckmann.github.com/gm/docs.html#label) 372 + - [lat](http://aheckmann.github.com/gm/docs.html#lat) 373 + - [level](http://aheckmann.github.com/gm/docs.html#level) 374 + - [list](http://aheckmann.github.com/gm/docs.html#list) 375 + - [limit](http://aheckmann.github.com/gm/docs.html#limit) 376 + - [log](http://aheckmann.github.com/gm/docs.html#log) 377 + - [loop](http://aheckmann.github.com/gm/docs.html#loop) 378 + - [lower](http://aheckmann.github.com/gm/docs.html#lower) 379 + - [magnify](http://aheckmann.github.com/gm/docs.html#magnify) 380 + - [map](http://aheckmann.github.com/gm/docs.html#map) 381 + - [matte](http://aheckmann.github.com/gm/docs.html#matte) 382 + - [matteColor](http://aheckmann.github.com/gm/docs.html#matteColor) 383 + - [mask](http://aheckmann.github.com/gm/docs.html#mask) 384 + - [maximumError](http://aheckmann.github.com/gm/docs.html#maximumError) 385 + - [median](http://aheckmann.github.com/gm/docs.html#median) 386 + - [minify](http://aheckmann.github.com/gm/docs.html#minify) 387 + - [mode](http://aheckmann.github.com/gm/docs.html#mode) 388 + - [modulate](http://aheckmann.github.com/gm/docs.html#modulate) 389 + - [monitor](http://aheckmann.github.com/gm/docs.html#monitor) 390 + - [monochrome](http://aheckmann.github.com/gm/docs.html#monochrome) 391 + - [morph](http://aheckmann.github.com/gm/docs.html#morph) 392 + - [mosaic](http://aheckmann.github.com/gm/docs.html#mosaic) 393 + - [motionBlur](http://aheckmann.github.com/gm/docs.html#motionBlur) 394 + - [name](http://aheckmann.github.com/gm/docs.html#name) 395 + - [negative](http://aheckmann.github.com/gm/docs.html#negative) 396 + - [noise](http://aheckmann.github.com/gm/docs.html#noise) 397 + - [noop](http://aheckmann.github.com/gm/docs.html#noop) 398 + - [normalize](http://aheckmann.github.com/gm/docs.html#normalize) 399 + - [noProfile](http://aheckmann.github.com/gm/docs.html#profile) 400 + - [opaque](http://aheckmann.github.com/gm/docs.html#opaque) 401 + - [operator](http://aheckmann.github.com/gm/docs.html#operator) 402 + - [orderedDither](http://aheckmann.github.com/gm/docs.html#orderedDither) 403 + - [outputDirectory](http://aheckmann.github.com/gm/docs.html#outputDirectory) 404 + - [paint](http://aheckmann.github.com/gm/docs.html#paint) 405 + - [page](http://aheckmann.github.com/gm/docs.html#page) 406 + - [pause](http://aheckmann.github.com/gm/docs.html#pause) 407 + - [pen](http://aheckmann.github.com/gm/docs.html#pen) 408 + - [ping](http://aheckmann.github.com/gm/docs.html#ping) 409 + - [pointSize](http://aheckmann.github.com/gm/docs.html#pointSize) 410 + - [preview](http://aheckmann.github.com/gm/docs.html#preview) 411 + - [process](http://aheckmann.github.com/gm/docs.html#process) 412 + - [profile](http://aheckmann.github.com/gm/docs.html#profile) 413 + - [progress](http://aheckmann.github.com/gm/docs.html#progress) 414 + - [quality](http://aheckmann.github.com/gm/docs.html#quality) 415 + - [raise](http://aheckmann.github.com/gm/docs.html#raise) 416 + - [rawSize](http://aheckmann.github.com/gm/docs.html#rawSize) 417 + - [randomThreshold](http://aheckmann.github.com/gm/docs.html#randomThreshold) 418 + - [recolor](http://aheckmann.github.com/gm/docs.html#recolor) 419 + - [redPrimary](http://aheckmann.github.com/gm/docs.html#redPrimary) 420 + - [region](http://aheckmann.github.com/gm/docs.html#region) 421 + - [remote](http://aheckmann.github.com/gm/docs.html#remote) 422 + - [render](http://aheckmann.github.com/gm/docs.html#render) 423 + - [repage](http://aheckmann.github.com/gm/docs.html#repage) 424 + - [resample](http://aheckmann.github.com/gm/docs.html#resample) 425 + - [resize](http://aheckmann.github.com/gm/docs.html#resize) 426 + - [roll](http://aheckmann.github.com/gm/docs.html#roll) 427 + - [rotate](http://aheckmann.github.com/gm/docs.html#rotate) 428 + - [sample](http://aheckmann.github.com/gm/docs.html#sample) 429 + - [samplingFactor](http://aheckmann.github.com/gm/docs.html#samplingFactor) 430 + - [scale](http://aheckmann.github.com/gm/docs.html#scale) 431 + - [scene](http://aheckmann.github.com/gm/docs.html#scene) 432 + - [scenes](http://aheckmann.github.com/gm/docs.html#scenes) 433 + - [screen](http://aheckmann.github.com/gm/docs.html#screen) 434 + - [segment](http://aheckmann.github.com/gm/docs.html#segment) 435 + - [sepia](http://aheckmann.github.com/gm/docs.html#sepia) 436 + - [set](http://aheckmann.github.com/gm/docs.html#set) 437 + - [setFormat](http://aheckmann.github.com/gm/docs.html#setformat) 438 + - [shade](http://aheckmann.github.com/gm/docs.html#shade) 439 + - [shadow](http://aheckmann.github.com/gm/docs.html#shadow) 440 + - [sharedMemory](http://aheckmann.github.com/gm/docs.html#sharedMemory) 441 + - [sharpen](http://aheckmann.github.com/gm/docs.html#sharpen) 442 + - [shave](http://aheckmann.github.com/gm/docs.html#shave) 443 + - [shear](http://aheckmann.github.com/gm/docs.html#shear) 444 + - [silent](http://aheckmann.github.com/gm/docs.html#silent) 445 + - [solarize](http://aheckmann.github.com/gm/docs.html#solarize) 446 + - [snaps](http://aheckmann.github.com/gm/docs.html#snaps) 447 + - [stegano](http://aheckmann.github.com/gm/docs.html#stegano) 448 + - [stereo](http://aheckmann.github.com/gm/docs.html#stereo) 449 + - [strip](http://aheckmann.github.com/gm/docs.html#strip) _imagemagick only_ 450 + - [spread](http://aheckmann.github.com/gm/docs.html#spread) 451 + - [swirl](http://aheckmann.github.com/gm/docs.html#swirl) 452 + - [textFont](http://aheckmann.github.com/gm/docs.html#textFont) 453 + - [texture](http://aheckmann.github.com/gm/docs.html#texture) 454 + - [threshold](http://aheckmann.github.com/gm/docs.html#threshold) 455 + - [thumb](http://aheckmann.github.com/gm/docs.html#thumb) 456 + - [tile](http://aheckmann.github.com/gm/docs.html#tile) 457 + - [transform](http://aheckmann.github.com/gm/docs.html#transform) 458 + - [transparent](http://aheckmann.github.com/gm/docs.html#transparent) 459 + - [treeDepth](http://aheckmann.github.com/gm/docs.html#treeDepth) 460 + - [trim](http://aheckmann.github.com/gm/docs.html#trim) 461 + - [type](http://aheckmann.github.com/gm/docs.html#type) 462 + - [update](http://aheckmann.github.com/gm/docs.html#update) 463 + - [units](http://aheckmann.github.com/gm/docs.html#units) 464 + - [unsharp](http://aheckmann.github.com/gm/docs.html#unsharp) 465 + - [usePixmap](http://aheckmann.github.com/gm/docs.html#usePixmap) 466 + - [view](http://aheckmann.github.com/gm/docs.html#view) 467 + - [virtualPixel](http://aheckmann.github.com/gm/docs.html#virtualPixel) 468 + - [visual](http://aheckmann.github.com/gm/docs.html#visual) 469 + - [watermark](http://aheckmann.github.com/gm/docs.html#watermark) 470 + - [wave](http://aheckmann.github.com/gm/docs.html#wave) 471 + - [whitePoint](http://aheckmann.github.com/gm/docs.html#whitePoint) 472 + - [whiteThreshold](http://aheckmann.github.com/gm/docs.html#whiteThreshold) 473 + - [window](http://aheckmann.github.com/gm/docs.html#window) 474 + - [windowGroup](http://aheckmann.github.com/gm/docs.html#windowGroup) 475 + 476 + - drawing primitives 477 + - [draw](http://aheckmann.github.com/gm/docs.html#draw) 478 + - [drawArc](http://aheckmann.github.com/gm/docs.html#drawArc) 479 + - [drawBezier](http://aheckmann.github.com/gm/docs.html#drawBezier) 480 + - [drawCircle](http://aheckmann.github.com/gm/docs.html#drawCircle) 481 + - [drawEllipse](http://aheckmann.github.com/gm/docs.html#drawEllipse) 482 + - [drawLine](http://aheckmann.github.com/gm/docs.html#drawLine) 483 + - [drawPoint](http://aheckmann.github.com/gm/docs.html#drawPoint) 484 + - [drawPolygon](http://aheckmann.github.com/gm/docs.html#drawPolygon) 485 + - [drawPolyline](http://aheckmann.github.com/gm/docs.html#drawPolyline) 486 + - [drawRectangle](http://aheckmann.github.com/gm/docs.html#drawRectangle) 487 + - [drawText](http://aheckmann.github.com/gm/docs.html#drawText) 488 + - [fill](http://aheckmann.github.com/gm/docs.html#fill) 489 + - [font](http://aheckmann.github.com/gm/docs.html#font) 490 + - [fontSize](http://aheckmann.github.com/gm/docs.html#fontSize) 491 + - [stroke](http://aheckmann.github.com/gm/docs.html#stroke) 492 + - [strokeWidth](http://aheckmann.github.com/gm/docs.html#strokeWidth) 493 + - [setDraw](http://aheckmann.github.com/gm/docs.html#setDraw) 494 + 495 + - image output 496 + - **write** - writes the processed image data to the specified filename 497 + - **stream** - provides a `ReadableStream` with the processed image data 498 + - **toBuffer** - returns the image as a `Buffer` instead of a stream 499 + 500 + ##compare 501 + 502 + Graphicsmagicks `compare` command is exposed through `gm.compare()`. This allows us to determine if two images can be considered "equal". 503 + 504 + Currently `gm.compare` only accepts file paths. 505 + 506 + gm.compare(path1, path2 [, options], callback) 507 + 508 + ```js 509 + gm.compare('/path/to/image1.jpg', '/path/to/another.png', function (err, isEqual, equality, raw, path1, path2) { 510 + if (err) return handle(err); 511 + 512 + // if the images were considered equal, `isEqual` will be true, otherwise, false. 513 + console.log('The images were equal: %s', isEqual); 514 + 515 + // to see the total equality returned by graphicsmagick we can inspect the `equality` argument. 516 + console.log('Actual equality: %d', equality); 517 + 518 + // inspect the raw output 519 + console.log(raw); 520 + 521 + // print file paths 522 + console.log(path1, path2); 523 + }) 524 + ``` 525 + 526 + You may wish to pass a custom tolerance threshold to increase or decrease the default level of `0.4`. 527 + 528 + 529 + ```js 530 + gm.compare('/path/to/image1.jpg', '/path/to/another.png', 1.2, function (err, isEqual) { 531 + ... 532 + }) 533 + ``` 534 + 535 + To output a diff image, pass a configuration object to define the diff options and tolerance. 536 + 537 + 538 + ```js 539 + var options = { 540 + file: '/path/to/diff.png', 541 + highlightColor: 'yellow', 542 + tolerance: 0.02 543 + } 544 + gm.compare('/path/to/image1.jpg', '/path/to/another.png', options, function (err, isEqual, equality, raw) { 545 + ... 546 + }) 547 + ``` 548 + 549 + ##composite 550 + 551 + GraphicsMagick supports compositing one image on top of another. This is exposed through `gm.composite()`. Its first argument is an image path with the changes to the base image, and an optional mask image. 552 + 553 + Currently, `gm.composite()` only accepts file paths. 554 + 555 + gm.composite(other [, mask]) 556 + 557 + ```js 558 + gm('/path/to/image.jpg') 559 + .composite('/path/to/second_image.jpg') 560 + .geometry('+100+150') 561 + .write('/path/to/composite.png', function(err) { 562 + if(!err) console.log("Written composite image."); 563 + }); 564 + ``` 565 + 566 + ## Contributors 567 + [https://github.com/aheckmann/gm/contributors](https://github.com/aheckmann/gm/contributors) 568 + 569 + ## Inspiration 570 + http://github.com/quiiver/magickal-node 571 + 572 + ## Plugins 573 + [https://github.com/aheckmann/gm/wiki](https://github.com/aheckmann/gm/wiki) 574 + 575 + ## License 576 + 577 + (The MIT License) 578 + 579 + Copyright (c) 2010 [Aaron Heckmann](aaron.heckmann+github@gmail.com) 580 + 581 + Permission is hereby granted, free of charge, to any person obtaining 582 + a copy of this software and associated documentation files (the 583 + 'Software'), to deal in the Software without restriction, including 584 + without limitation the rights to use, copy, modify, merge, publish, 585 + distribute, sublicense, and/or sell copies of the Software, and to 586 + permit persons to whom the Software is furnished to do so, subject to 587 + the following conditions: 588 + 589 + The above copyright notice and this permission notice shall be 590 + included in all copies or substantial portions of the Software. 591 + 592 + THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 593 + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 594 + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 595 + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 596 + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 597 + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 598 + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+131
node_modules/gm/index.js
··· 1 + 2 + /** 3 + * Module dependencies. 4 + */ 5 + 6 + var Stream = require('stream').Stream; 7 + var EventEmitter = require('events').EventEmitter; 8 + var util = require('util'); 9 + 10 + util.inherits(gm, EventEmitter); 11 + 12 + /** 13 + * Constructor. 14 + * 15 + * @param {String|Number} path - path to img source or ReadableStream or width of img to create 16 + * @param {Number} [height] - optional filename of ReadableStream or height of img to create 17 + * @param {String} [color] - optional hex background color of created img 18 + */ 19 + 20 + function gm (source, height, color) { 21 + var width; 22 + 23 + if (!(this instanceof gm)) { 24 + return new gm(source, height, color); 25 + } 26 + 27 + EventEmitter.call(this); 28 + 29 + this._options = {}; 30 + this.options(this.__proto__._options); 31 + 32 + this.data = {}; 33 + this._in = []; 34 + this._out = []; 35 + this._outputFormat = null; 36 + this._subCommand = 'convert'; 37 + 38 + if (source instanceof Stream) { 39 + this.sourceStream = source; 40 + source = height || 'unknown.jpg'; 41 + } else if (Buffer.isBuffer(source)) { 42 + this.sourceBuffer = source; 43 + source = height || 'unknown.jpg'; 44 + } else if (height) { 45 + // new images 46 + width = source; 47 + source = ""; 48 + 49 + this.in("-size", width + "x" + height); 50 + 51 + if (color) { 52 + this.in("xc:"+ color); 53 + } 54 + } 55 + 56 + if (typeof source === "string") { 57 + // then source is a path 58 + 59 + // parse out gif frame brackets from filename 60 + // since stream doesn't use source path 61 + // eg. "filename.gif[0]" 62 + var frames = source.match(/(\[.+\])$/); 63 + if (frames) { 64 + this.sourceFrames = source.substr(frames.index, frames[0].length); 65 + source = source.substr(0, frames.index); 66 + } 67 + } 68 + 69 + this.source = source; 70 + 71 + this.addSrcFormatter(function (src) { 72 + // must be first source formatter 73 + 74 + var inputFromStdin = this.sourceStream || this.sourceBuffer; 75 + var ret = inputFromStdin ? '-' : this.source; 76 + 77 + if (ret && this.sourceFrames) ret += this.sourceFrames; 78 + 79 + src.length = 0; 80 + src[0] = ret; 81 + }); 82 + } 83 + 84 + /** 85 + * Subclasses the gm constructor with custom options. 86 + * 87 + * @param {options} options 88 + * @return {gm} the subclasses gm constructor 89 + */ 90 + 91 + var parent = gm; 92 + gm.subClass = function subClass (options) { 93 + function gm (source, height, color) { 94 + if (!(this instanceof parent)) { 95 + return new gm(source, height, color); 96 + } 97 + 98 + parent.call(this, source, height, color); 99 + } 100 + 101 + gm.prototype.__proto__ = parent.prototype; 102 + gm.prototype._options = {}; 103 + gm.prototype.options(options); 104 + 105 + return gm; 106 + } 107 + 108 + /** 109 + * Augment the prototype. 110 + */ 111 + 112 + require("./lib/options")(gm.prototype); 113 + require("./lib/getters")(gm); 114 + require("./lib/args")(gm.prototype); 115 + require("./lib/drawing")(gm.prototype); 116 + require("./lib/convenience")(gm.prototype); 117 + require("./lib/command")(gm.prototype); 118 + require("./lib/compare")(gm.prototype); 119 + require("./lib/composite")(gm.prototype); 120 + 121 + /** 122 + * Expose. 123 + */ 124 + 125 + module.exports = exports = gm; 126 + module.exports.utils = require('./lib/utils'); 127 + module.exports.compare = require('./lib/compare')(); 128 + module.exports.version = JSON.parse( 129 + require('fs').readFileSync(__dirname + '/package.json', 'utf8') 130 + ).version; 131 +
+1075
node_modules/gm/lib/args.js
··· 1 + /** 2 + * Dependencies 3 + */ 4 + 5 + var argsToArray = require('./utils').argsToArray; 6 + 7 + /** 8 + * Extend proto 9 + */ 10 + 11 + module.exports = function (proto) { 12 + // change the specified frame. 13 + // See #202. 14 + proto.selectFrame = function (frame) { 15 + if (typeof frame === 'number') 16 + this.sourceFrames = '[' + frame + ']'; 17 + return this; 18 + } 19 + 20 + // define the sub-command to use, http://www.graphicsmagick.org/utilities.html 21 + proto.command = proto.subCommand = function subCommand (name){ 22 + this._subCommand = name; 23 + return this; 24 + } 25 + 26 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-adjoin 27 + proto.adjoin = function adjoin () { 28 + return this.out("-adjoin"); 29 + } 30 + 31 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-affine 32 + proto.affine = function affine (matrix) { 33 + return this.out("-affine", matrix); 34 + } 35 + 36 + /** 37 + * Appends images to the list of "source" images. 38 + * 39 + * We may also specify either top-to-bottom or left-to-right 40 + * behavior of the appending by passing a boolean argument. 41 + * 42 + * Examples: 43 + * 44 + * img = gm(src); 45 + * 46 + * // +append means left-to-right 47 + * img.append(img1, img2) gm convert src img1 img2 -append 48 + * img.append(img, true) gm convert src img +append 49 + * img.append(img, false) gm convert src img -append 50 + * img.append(img) gm convert src img -append 51 + * img.append(img).append() gm convert src img -append 52 + * img.append(img).append(true) gm convert src img +append 53 + * img.append(img).append(true) gm convert src img +append 54 + * img.append(img).background('#222) gm convert src img -background #222 +append 55 + * 56 + * @param {String} [img] 57 + * @param {Boolean} [ltr] 58 + * @see http://www.graphicsmagick.org/GraphicsMagick.html#details-append 59 + */ 60 + 61 + proto.append = function append (img, ltr) { 62 + if (!this._append) { 63 + this._append = []; 64 + this.addSrcFormatter(function (src) { 65 + this.out(this._append.ltr ? '+append' : '-append'); 66 + src.push.apply(src, this._append); 67 + }); 68 + } 69 + 70 + if (0 === arguments.length) { 71 + this._append.ltr = false; 72 + return this; 73 + } 74 + 75 + for (var i = 0; i < arguments.length; ++i) { 76 + var arg = arguments[i]; 77 + switch (typeof arg) { 78 + case 'boolean': 79 + this._append.ltr = arg; 80 + break; 81 + case 'string': 82 + this._append.push(arg); 83 + break; 84 + } 85 + } 86 + 87 + return this; 88 + } 89 + 90 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-authenticate 91 + proto.authenticate = function authenticate (string) { 92 + return this.out("-authenticate", string); 93 + } 94 + 95 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-average 96 + proto.average = function average () { 97 + return this.out("-average"); 98 + } 99 + 100 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-backdrop 101 + proto.backdrop = function backdrop () { 102 + return this.out("-backdrop"); 103 + } 104 + 105 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-black-threshold 106 + proto.blackThreshold = function blackThreshold (red, green, blue, opacity) { 107 + return this.out("-black-threshold", argsToArray(red, green, blue, opacity).join(',')); 108 + } 109 + 110 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-blue-primary 111 + proto.bluePrimary = function bluePrimary (x, y) { 112 + return this.out("-blue-primary", argsToArray(x, y).join(',')); 113 + } 114 + 115 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-border 116 + proto.border = function border (width, height) { 117 + return this.out("-border", width+"x"+height); 118 + } 119 + 120 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-bordercolor 121 + proto.borderColor = function borderColor (color) { 122 + return this.out("-bordercolor", color); 123 + } 124 + 125 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-box 126 + proto.box = function box (color) { 127 + return this.out("-box", color); 128 + } 129 + 130 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-channel 131 + proto.channel = function channel (type) { 132 + return this.out("-channel", type); 133 + } 134 + 135 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-chop 136 + proto.chop = function chop (w, h, x, y) { 137 + return this.in("-chop", w+"x"+h + "+"+(x||0)+"+"+(y||0)); 138 + } 139 + 140 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-clip 141 + proto.clip = function clip () { 142 + return this.out("-clip"); 143 + } 144 + 145 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-coalesce 146 + proto.coalesce = function coalesce () { 147 + return this.out("-coalesce"); 148 + } 149 + 150 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-colorize 151 + proto.colorize = function colorize (r, g, b) { 152 + return this.out("-colorize", [r,g,b].join(",")); 153 + } 154 + 155 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-colormap 156 + proto.colorMap = function colorMap (type) { 157 + return this.out("-colormap", type); 158 + } 159 + 160 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-compose 161 + proto.compose = function compose (operator) { 162 + return this.out("-compose", operator); 163 + } 164 + 165 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-compress 166 + proto.compress = function compress (type) { 167 + return this.out("-compress", type); 168 + } 169 + 170 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-kernel 171 + proto.convolve = function convolve (kernel) { 172 + return this.out("-convolve", kernel); 173 + } 174 + 175 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-create-directories 176 + proto.createDirectories = function createDirectories () { 177 + return this.out("-create-directories"); 178 + } 179 + 180 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-deconstruct 181 + proto.deconstruct = function deconstruct () { 182 + return this.out("-deconstruct"); 183 + } 184 + 185 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-define 186 + proto.define = function define (value) { 187 + return this.out("-define", value); 188 + } 189 + 190 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-delay 191 + proto.delay = function delay (value) { 192 + return this.out("-delay", value); 193 + } 194 + 195 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-displace 196 + proto.displace = function displace (horizontalScale, verticalScale) { 197 + return this.out("-displace", horizontalScale+'x'+verticalScale); 198 + } 199 + 200 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-display 201 + proto.display = function display (value) { 202 + return this.out("-display", value); 203 + } 204 + 205 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-dispose 206 + proto.dispose = function dispose (method) { 207 + return this.out("-dispose", method); 208 + } 209 + 210 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-dissolve 211 + proto.dissolve = function dissolve (percent) { 212 + return this.out("-dissolve", percent+'%'); 213 + } 214 + 215 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-encoding 216 + proto.encoding = function encoding (type) { 217 + return this.out("-encoding", type); 218 + } 219 + 220 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-endian 221 + proto.endian = function endian (type) { 222 + return this.out("-endian", type); 223 + } 224 + 225 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-file 226 + proto.file = function file (filename) { 227 + return this.out("-file", filename); 228 + } 229 + 230 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten 231 + proto.flatten = function flatten () { 232 + return this.out("-flatten"); 233 + } 234 + 235 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-foreground 236 + proto.foreground = function foreground (color) { 237 + return this.out("-foreground", color); 238 + } 239 + 240 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-frame 241 + proto.frame = function frame (width, height, outerBevelWidth, innerBevelWidth) { 242 + if(arguments.length==0) return this.out("-frame"); 243 + return this.out("-frame", width+'x'+height+'+'+outerBevelWidth+'+'+innerBevelWidth); 244 + } 245 + 246 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-fuzz 247 + proto.fuzz = function fuzz (distance, percent) { 248 + return this.out("-fuzz", distance+(percent?'%':'')); 249 + } 250 + 251 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-gaussian 252 + proto.gaussian = function gaussian (radius, sigma) { 253 + return this.out("-gaussian", argsToArray(radius, sigma).join('x')); 254 + } 255 + 256 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-geometry 257 + proto.geometry = function geometry (width, height, arg) { 258 + // If the first argument is a string, and there is only one argument, this is a custom geometry command. 259 + if(arguments.length == 1 && typeof arguments[0] === "string") 260 + return this.out("-geometry", arguments[0]); 261 + 262 + // Otherwise, return a resizing geometry command with an option alrgument. 263 + return this.out("-geometry", width+'x'+height+(arg||'')); 264 + } 265 + 266 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-green-primary 267 + proto.greenPrimary = function greenPrimary (x, y) { 268 + return this.out("-green-primary", x+','+y); 269 + } 270 + 271 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-highlight-color 272 + proto.highlightColor = function highlightColor (color) { 273 + return this.out("-highlight-color", color); 274 + } 275 + 276 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-highlight-style 277 + proto.highlightStyle = function highlightStyle (style) { 278 + return this.out("-highlight-style", style); 279 + } 280 + 281 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-iconGeometry 282 + proto.iconGeometry = function iconGeometry (geometry) { 283 + return this.out("-iconGeometry", geometry); 284 + } 285 + 286 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-intent 287 + proto.intent = function intent (type) { 288 + return this.out("-intent", type); 289 + } 290 + 291 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-lat 292 + proto.lat = function lat (width, height, offset, percent) { 293 + return this.out("-lat", width+'x'+height+offset+(percent?'%':'')); 294 + } 295 + 296 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-level 297 + proto.level = function level (blackPoint, gamma, whitePoint, percent) { 298 + return this.out("-level", argsToArray(blackPoint, gamma, whitePoint).join(',')+(percent?'%':'')); 299 + } 300 + 301 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-list 302 + proto.list = function list (type) { 303 + return this.out("-list", type); 304 + } 305 + 306 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-log 307 + proto.log = function log (string) { 308 + return this.out("-log", string); 309 + } 310 + 311 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-loop 312 + proto.loop = function loop (iterations) { 313 + return this.out("-loop", iterations); 314 + } 315 + 316 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-map 317 + proto.map = function map (filename) { 318 + return this.out("-map", filename); 319 + } 320 + 321 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-mask 322 + proto.mask = function mask (filename) { 323 + return this.out("-mask", filename); 324 + } 325 + 326 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-matte 327 + proto.matte = function matte () { 328 + return this.out("-matte"); 329 + } 330 + 331 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-mattecolor 332 + proto.matteColor = function matteColor (color) { 333 + return this.out("-mattecolor", color); 334 + } 335 + 336 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-maximum-error 337 + proto.maximumError = function maximumError (limit) { 338 + return this.out("-maximum-error", limit); 339 + } 340 + 341 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-mode 342 + proto.mode = function mode (value) { 343 + return this.out("-mode", value); 344 + } 345 + 346 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-monitor 347 + proto.monitor = function monitor () { 348 + return this.out("-monitor"); 349 + } 350 + 351 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-mosaic 352 + proto.mosaic = function mosaic () { 353 + return this.out("-mosaic"); 354 + } 355 + 356 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-motion-blur 357 + proto.motionBlur = function motionBlur (radius, sigma, angle) { 358 + var arg=radius; 359 + if (typeof sigma!='undefined') arg+='x'+sigma; 360 + if (typeof angle!='undefined') arg+='+'+angle; 361 + return this.out("-motion-blur", arg); 362 + } 363 + 364 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-name 365 + proto.name = function name () { 366 + return this.out("-name"); 367 + } 368 + 369 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-noop 370 + proto.noop = function noop () { 371 + return this.out("-noop"); 372 + } 373 + 374 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-normalize 375 + proto.normalize = function normalize () { 376 + return this.out("-normalize"); 377 + } 378 + 379 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-opaque 380 + proto.opaque = function opaque (color) { 381 + return this.out("-opaque", color); 382 + } 383 + 384 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-operator 385 + proto.operator = function operator (channel, operator, rvalue, percent) { 386 + return this.out("-operator", channel, operator, rvalue+(percent?'%':'')); 387 + } 388 + 389 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-ordered-dither 390 + proto.orderedDither = function orderedDither (channeltype, NxN) { 391 + return this.out("-ordered-dither", channeltype, NxN); 392 + } 393 + 394 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-output-directory 395 + proto.outputDirectory = function outputDirectory (directory) { 396 + return this.out("-output-directory", directory); 397 + } 398 + 399 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-page 400 + proto.page = function page (width, height, arg) { 401 + return this.out("-page", width+'x'+height+(arg||'')); 402 + } 403 + 404 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-pause 405 + proto.pause = function pause (seconds) { 406 + return this.out("-pause", seconds); 407 + } 408 + 409 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-pen 410 + proto.pen = function pen (color) { 411 + return this.out("-pen", color); 412 + } 413 + 414 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-ping 415 + proto.ping = function ping () { 416 + return this.out("-ping"); 417 + } 418 + 419 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-pointsize 420 + proto.pointSize = function pointSize (value) { 421 + return this.out("-pointsize", value); 422 + } 423 + 424 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-preview 425 + proto.preview = function preview (type) { 426 + return this.out("-preview", type); 427 + } 428 + 429 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-process 430 + proto.process = function process (command) { 431 + return this.out("-process", command); 432 + } 433 + 434 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-profile 435 + proto.profile = function profile (filename) { 436 + return this.out("-profile", filename); 437 + } 438 + 439 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-progress 440 + proto.progress = function progress () { 441 + return this.out("+progress"); 442 + } 443 + 444 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-random-threshold 445 + proto.randomThreshold = function randomThreshold (channeltype, LOWxHIGH) { 446 + return this.out("-random-threshold", channeltype, LOWxHIGH); 447 + } 448 + 449 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-recolor 450 + proto.recolor = function recolor (matrix) { 451 + return this.out("-recolor", matrix); 452 + } 453 + 454 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-red-primary 455 + proto.redPrimary = function redPrimary (x, y) { 456 + return this.out("-red-primary", x, y); 457 + } 458 + 459 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-remote 460 + proto.remote = function remote () { 461 + return this.out("-remote"); 462 + } 463 + 464 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-render 465 + proto.render = function render () { 466 + return this.out("-render"); 467 + } 468 + 469 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-repage 470 + proto.repage = function repage (width, height, xoff, yoff, arg) { 471 + if (arguments[0] === "+") return this.out("+repage"); 472 + return this.out("-repage", width+'x'+height+'+'+xoff+'+'+yoff+(arg||'')); 473 + } 474 + 475 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-sample 476 + proto.sample = function sample (geometry) { 477 + return this.out("-sample", geometry); 478 + } 479 + 480 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-sampling-factor 481 + proto.samplingFactor = function samplingFactor (horizontalFactor, verticalFactor) { 482 + return this.out("-sampling-factor", horizontalFactor+'x'+verticalFactor); 483 + } 484 + 485 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-scene 486 + proto.scene = function scene (value) { 487 + return this.out("-scene", value); 488 + } 489 + 490 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-scenes 491 + proto.scenes = function scenes (start, end) { 492 + return this.out("-scenes", start+'-'+end); 493 + } 494 + 495 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-screen 496 + proto.screen = function screen () { 497 + return this.out("-screen"); 498 + } 499 + 500 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-set 501 + proto.set = function set (attribute, value) { 502 + return this.out("-set", attribute, value); 503 + } 504 + 505 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-segment 506 + proto.segment = function segment (clusterThreshold, smoothingThreshold) { 507 + return this.out("-segment", clusterThreshold+'x'+smoothingThreshold); 508 + } 509 + 510 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-shade 511 + proto.shade = function shade (azimuth, elevation) { 512 + return this.out("-shade", azimuth+'x'+elevation); 513 + } 514 + 515 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-shadow 516 + proto.shadow = function shadow (radius, sigma) { 517 + return this.out("-shadow", argsToArray(radius, sigma).join('x')); 518 + } 519 + 520 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-shared-memory 521 + proto.sharedMemory = function sharedMemory () { 522 + return this.out("-shared-memory"); 523 + } 524 + 525 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-shave 526 + proto.shave = function shave (width, height, percent) { 527 + return this.out("-shave", width+'x'+height+(percent?'%':'')); 528 + } 529 + 530 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-shear 531 + proto.shear = function shear (xDegrees, yDegreees) { 532 + return this.out("-shear", xDegrees+'x'+yDegreees); 533 + } 534 + 535 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-silent 536 + proto.silent = function silent (color) { 537 + return this.out("-silent"); 538 + } 539 + 540 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-size 541 + proto.rawSize = function rawSize (width, height, offset) { 542 + var off = 'undefined' != typeof offset 543 + ? '+' + offset 544 + : ''; 545 + return this.out("-size", width +'x'+ height + off); 546 + } 547 + 548 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-snaps 549 + proto.snaps = function snaps (value) { 550 + return this.out("-snaps", value); 551 + } 552 + 553 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-stegano 554 + proto.stegano = function stegano (offset) { 555 + return this.out("-stegano", offset); 556 + } 557 + 558 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-stereo 559 + proto.stereo = function stereo () { 560 + return this.out("-stereo"); 561 + } 562 + 563 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-text-font 564 + proto.textFont = function textFont (name) { 565 + return this.out("-text-font", name); 566 + } 567 + 568 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-texture 569 + proto.texture = function texture (filename) { 570 + return this.out("-texture", filename); 571 + } 572 + 573 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-threshold 574 + proto.threshold = function threshold (value, percent) { 575 + return this.out("-threshold", value+(percent?'%':'')); 576 + } 577 + 578 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-thumbnail 579 + proto.thumbnail = function thumbnail (width, height) { 580 + return this.out("-thumbnail", width + "x" + height); 581 + } 582 + 583 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-tile 584 + proto.tile = function tile (filename) { 585 + return this.out("-tile", filename); 586 + } 587 + 588 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-title 589 + proto.title = function title (string) { 590 + return this.out("-title", string); 591 + } 592 + 593 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-transform 594 + proto.transform = function transform (color) { 595 + return this.out("-transform", color); 596 + } 597 + 598 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-transparent 599 + proto.transparent = function transparent (color) { 600 + return this.out("-transparent", color); 601 + } 602 + 603 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-treedepth 604 + proto.treeDepth = function treeDepth (value) { 605 + return this.out("-treedepth", value); 606 + } 607 + 608 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-update 609 + proto.update = function update (seconds) { 610 + return this.out("-update", seconds); 611 + } 612 + 613 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-units 614 + proto.units = function units (type) { 615 + return this.out("-units", type); 616 + } 617 + 618 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-unsharp 619 + proto.unsharp = function unsharp (radius, sigma, amount, threshold) { 620 + var arg=radius; 621 + if (typeof sigma != 'undefined') arg+='x'+sigma; 622 + if (typeof amount != 'undefined') arg+='+'+amount; 623 + if (typeof threshold != 'undefined') arg+='+'+threshold; 624 + return this.out("-unsharp", arg); 625 + } 626 + 627 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-use-pixmap 628 + proto.usePixmap = function usePixmap () { 629 + return this.out("-use-pixmap"); 630 + } 631 + 632 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-view 633 + proto.view = function view (string) { 634 + return this.out("-view", string); 635 + } 636 + 637 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-virtual-pixel 638 + proto.virtualPixel = function virtualPixel (method) { 639 + return this.out("-virtual-pixel", method); 640 + } 641 + 642 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-visual 643 + proto.visual = function visual (type) { 644 + return this.out("-visual", type); 645 + } 646 + 647 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-watermark 648 + proto.watermark = function watermark (brightness, saturation) { 649 + return this.out("-watermark", brightness+'x'+saturation); 650 + } 651 + 652 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-wave 653 + proto.wave = function wave (amplitude, wavelength) { 654 + return this.out("-wave", amplitude+'x'+wavelength); 655 + } 656 + 657 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-white-point 658 + proto.whitePoint = function whitePoint (x, y) { 659 + return this.out("-white-point", x+'x'+y); 660 + } 661 + 662 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-white-threshold 663 + proto.whiteThreshold = function whiteThreshold (red, green, blue, opacity) { 664 + return this.out("-white-threshold", argsToArray(red, green, blue, opacity).join(',')); 665 + } 666 + 667 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-window 668 + proto.window = function window (id) { 669 + return this.out("-window", id); 670 + } 671 + 672 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-window-group 673 + proto.windowGroup = function windowGroup () { 674 + return this.out("-window-group"); 675 + } 676 + 677 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-strip (graphicsMagick >= 1.3.15) 678 + proto.strip = function strip () { 679 + if (this._options.imageMagick) return this.out("-strip"); 680 + return this.noProfile().out("+comment");//Equivalent to "-strip" for all versions of graphicsMagick 681 + } 682 + 683 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-interlace 684 + proto.interlace = function interlace (type) { 685 + return this.out("-interlace", type || "None"); 686 + } 687 + 688 + // force output format 689 + proto.setFormat = function setFormat (format) { 690 + if (format) this._outputFormat = format; 691 + return this; 692 + } 693 + 694 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-resize 695 + proto.resize = function resize (w, h, options) { 696 + options = options || ""; 697 + var geometry; 698 + if (w && h) { 699 + geometry = w + "x" + h + options 700 + } else if (w && !h) { 701 + // GraphicsMagick requires <width>x<options>, ImageMagick requires <width><options> 702 + geometry = (this._options.imageMagick) ? w + options : w + 'x' + options; 703 + } else if (!w && h) { 704 + geometry = 'x' + h + options 705 + } 706 + 707 + return this.out("-resize", geometry); 708 + } 709 + 710 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-scale 711 + proto.scale = function scale (w, h, options) { 712 + options = options || ""; 713 + var geometry; 714 + if (w && h) { 715 + geometry = w + "x" + h + options 716 + } else if (w && !h) { 717 + geometry = (this._options.imageMagick) ? w + options : w + 'x' + options; 718 + } else if (!w && h) { 719 + geometry = 'x' + h + options 720 + } 721 + 722 + return this.out("-scale", geometry); 723 + } 724 + 725 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-filter 726 + proto.filter = function filter (val) { 727 + return this.out("-filter", val); 728 + } 729 + 730 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-density 731 + proto.density = function density (w, h) { 732 + return this.in("-density", w +"x"+ h); 733 + } 734 + 735 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-profile 736 + proto.noProfile = function noProfile () { 737 + this.out('+profile', '"*"'); 738 + return this; 739 + } 740 + 741 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-resample 742 + proto.resample = function resample (w, h) { 743 + return this.out("-resample", w+"x"+h); 744 + } 745 + 746 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-rotate 747 + proto.rotate = function rotate (color, deg) { 748 + return this.out("-background", color, "-rotate", String(deg || 0)); 749 + } 750 + 751 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-flip 752 + proto.flip = function flip () { 753 + return this.out("-flip"); 754 + } 755 + 756 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-flop 757 + proto.flop = function flop () { 758 + return this.out("-flop"); 759 + } 760 + 761 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-crop 762 + proto.crop = function crop (w, h, x, y, percent) { 763 + if (this.inputIs('jpg')) { 764 + // avoid error "geometry does not contain image (unable to crop image)" - gh-17 765 + var index = this._in.indexOf('-size'); 766 + if (~index) { 767 + this._in.splice(index, 2); 768 + } 769 + } 770 + 771 + return this.out("-crop", w + "x" + h + "+" + (x || 0) + "+" + (y || 0) + (percent ? '%' : '')); 772 + } 773 + 774 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-magnify 775 + proto.magnify = function magnify (factor) { 776 + return this.in("-magnify"); 777 + } 778 + 779 + // http://www.graphicsmagick.org/GraphicsMagick.html 780 + proto.minify = function minify () { 781 + return this.in("-minify") 782 + } 783 + 784 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-quality 785 + proto.quality = function quality (val) { 786 + return this.in("-quality", val || 75); 787 + } 788 + 789 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-blur 790 + proto.blur = function blur (radius, sigma) { 791 + return this.out("-blur", radius + (sigma ? "x"+sigma : "")); 792 + } 793 + 794 + // http://www.graphicsmagick.org/convert.html 795 + proto.charcoal = function charcoal (factor) { 796 + return this.out("-charcoal", factor || 2); 797 + } 798 + 799 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-modulate 800 + proto.modulate = function modulate (b, s, h) { 801 + return this.out("-modulate", [b,s,h].join(",")); 802 + } 803 + 804 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-antialias 805 + // note: antialiasing is enabled by default 806 + proto.antialias = function antialias (disable) { 807 + return false === disable 808 + ? this.out("+antialias") 809 + : this; 810 + } 811 + 812 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-depth 813 + proto.bitdepth = function bitdepth (val) { 814 + return this.out("-depth", val); 815 + } 816 + 817 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-colors 818 + proto.colors = function colors (val) { 819 + return this.out("-colors", val || 128); 820 + } 821 + 822 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-colorspace 823 + proto.colorspace = function colorspace (val) { 824 + return this.out("-colorspace", val); 825 + } 826 + 827 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-comment 828 + proto.comment = comment("-comment"); 829 + 830 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-contrast 831 + proto.contrast = function contrast (mult) { 832 + var arg = (parseInt(mult, 10) || 0) > 0 833 + ? "+contrast" 834 + : "-contrast"; 835 + 836 + mult = Math.abs(mult) || 1; 837 + 838 + while (mult--) { 839 + this.out(arg); 840 + } 841 + 842 + return this; 843 + } 844 + 845 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-cycle 846 + proto.cycle = function cycle (amount) { 847 + return this.out("-cycle", amount || 2); 848 + } 849 + 850 + // http://www.graphicsmagick.org/GraphicsMagick.html 851 + proto.despeckle = function despeckle () { 852 + return this.out("-despeckle"); 853 + } 854 + 855 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-dither 856 + // note: either colors() or monochrome() must be used for this 857 + // to take effect. 858 + proto.dither = function dither (on) { 859 + var sign = false === on 860 + ? "+" 861 + : "-"; 862 + 863 + return this.out(sign + "dither"); 864 + } 865 + 866 + // http://www.graphicsmagick.org/GraphicsMagick.html 867 + proto.monochrome = function monochrome () { 868 + return this.out("-monochrome"); 869 + } 870 + 871 + // http://www.graphicsmagick.org/GraphicsMagick.html 872 + proto.edge = function edge (radius) { 873 + return this.out("-edge", radius || 1); 874 + } 875 + 876 + // http://www.graphicsmagick.org/GraphicsMagick.html 877 + proto.emboss = function emboss (radius) { 878 + return this.out("-emboss", radius || 1); 879 + } 880 + 881 + // http://www.graphicsmagick.org/GraphicsMagick.html 882 + proto.enhance = function enhance () { 883 + return this.out("-enhance"); 884 + } 885 + 886 + // http://www.graphicsmagick.org/GraphicsMagick.html 887 + proto.equalize = function equalize () { 888 + return this.out("-equalize"); 889 + } 890 + 891 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-gamma 892 + proto.gamma = function gamma (r, g, b) { 893 + return this.out("-gamma", [r,g,b].join()); 894 + } 895 + 896 + // http://www.graphicsmagick.org/GraphicsMagick.html 897 + proto.implode = function implode (factor) { 898 + return this.out("-implode", factor || 1); 899 + } 900 + 901 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-comment 902 + proto.label = comment("-label"); 903 + 904 + var limits = [ "disk", "file", "map", "memory", "pixels", "threads"]; 905 + 906 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-limit 907 + proto.limit = function limit (type, val) { 908 + type = type.toLowerCase(); 909 + 910 + if (!~limits.indexOf(type)) { 911 + return this; 912 + } 913 + 914 + return this.out("-limit", type, val); 915 + } 916 + 917 + // http://www.graphicsmagick.org/GraphicsMagick.html 918 + proto.median = function median (radius) { 919 + return this.out("-median", radius || 1); 920 + } 921 + 922 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-negate 923 + proto.negative = function negative (grayscale) { 924 + var sign = grayscale ? "+" : "-"; 925 + return this.out(sign + "negate"); 926 + } 927 + 928 + var noises = [ 929 + "uniform" 930 + , "gaussian" 931 + , "multiplicative" 932 + , "impulse" 933 + , "laplacian" 934 + , "poisson" 935 + ]; 936 + 937 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-noise 938 + proto.noise = function noise (radius) { 939 + radius = (String(radius)).toLowerCase(); 940 + 941 + var sign = ~noises.indexOf(radius) 942 + ? "+" 943 + : "-"; 944 + 945 + return this.out(sign + "noise", radius); 946 + } 947 + 948 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-paint 949 + proto.paint = function paint (radius) { 950 + return this.out("-paint", radius); 951 + } 952 + 953 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-raise 954 + proto.raise = function raise (w, h) { 955 + return this.out("-raise", (w||0)+"x"+(h||0)); 956 + } 957 + 958 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-raise 959 + proto.lower = function lower (w, h) { 960 + return this.out("+raise", (w||0)+"x"+(h||0)); 961 + } 962 + 963 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-region 964 + proto.region = function region (w, h, x, y) { 965 + w = w || 0; 966 + h = h || 0; 967 + x = x || 0; 968 + y = y || 0; 969 + return this.out("-region", w + "x" + h + "+" + x + "+" + y); 970 + } 971 + 972 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-roll 973 + proto.roll = function roll (x, y) { 974 + x = ((x = parseInt(x, 10) || 0) >= 0 ? "+" : "") + x; 975 + y = ((y = parseInt(y, 10) || 0) >= 0 ? "+" : "") + y; 976 + return this.out("-roll", x+y); 977 + } 978 + 979 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-sharpen 980 + proto.sharpen = function sharpen (radius, sigma) { 981 + sigma = sigma 982 + ? "x" + sigma 983 + : ""; 984 + 985 + return this.out("-sharpen", radius + sigma); 986 + } 987 + 988 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-solarize 989 + proto.solarize = function solarize (factor) { 990 + return this.out("-solarize", (factor || 1)+"%"); 991 + } 992 + 993 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-spread 994 + proto.spread = function spread (amount) { 995 + return this.out("-spread", amount || 5); 996 + } 997 + 998 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-swirl 999 + proto.swirl = function swirl (degrees) { 1000 + return this.out("-swirl", degrees || 180); 1001 + } 1002 + 1003 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-type 1004 + proto.type = function type (type) { 1005 + return this.in("-type", type); 1006 + } 1007 + 1008 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-trim 1009 + proto.trim = function trim () { 1010 + return this.out("-trim"); 1011 + } 1012 + 1013 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-extent 1014 + proto.extent = function extent (w, h, options) { 1015 + options = options || ""; 1016 + var geometry; 1017 + if (w && h) { 1018 + geometry = w + "x" + h + options 1019 + } else if (w && !h) { 1020 + geometry = (this._options.imageMagick) ? w + options : w + 'x' + options; 1021 + } else if (!w && h) { 1022 + geometry = 'x' + h + options 1023 + } 1024 + 1025 + return this.out("-extent", geometry); 1026 + } 1027 + 1028 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-gravity 1029 + // Be sure to use gravity BEFORE extent 1030 + proto.gravity = function gravity (type) { 1031 + if (!type || !~gravity.types.indexOf(type)) { 1032 + type = "NorthWest"; // Documented default. 1033 + } 1034 + 1035 + return this.out("-gravity", type); 1036 + } 1037 + 1038 + proto.gravity.types = [ 1039 + "NorthWest" 1040 + , "North" 1041 + , "NorthEast" 1042 + , "West" 1043 + , "Center" 1044 + , "East" 1045 + , "SouthWest" 1046 + , "South" 1047 + , "SouthEast" 1048 + ]; 1049 + 1050 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten 1051 + proto.flatten = function flatten () { 1052 + return this.out("-flatten"); 1053 + } 1054 + 1055 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-background 1056 + proto.background = function background (color) { 1057 + return this.in("-background", color); 1058 + } 1059 + }; 1060 + 1061 + /** 1062 + * Generates a handler for comments/labels. 1063 + */ 1064 + 1065 + function comment (arg) { 1066 + return function (format) { 1067 + format = String(format); 1068 + 1069 + format = "@" == format.charAt(0) 1070 + ? format.substring(1) 1071 + : format; 1072 + 1073 + return this.out(arg, '"' + format + '"'); 1074 + } 1075 + }
+394
node_modules/gm/lib/command.js
··· 1 + 2 + /** 3 + * Module dependencies. 4 + */ 5 + 6 + var exec = require('child_process').exec; 7 + var spawn = require('child_process').spawn; 8 + var utils = require('./utils'); 9 + var debug = require('debug')('gm'); 10 + var series = require('array-series'); 11 + 12 + /* 13 + * Creates a pass through stream. 14 + * We need to fallback to the `through` lib for node 0.8 support 15 + * as PassThrough was added in node 0.10. 16 + */ 17 + 18 + var PassThrough = require('stream').PassThrough || require('through'); 19 + 20 + /** 21 + * Error messaging. 22 + */ 23 + 24 + var noBufferConcat = 'gm v1.9.0+ required node v0.8+. Please update your version of node, downgrade gm < 1.9, or do not use `bufferStream`.'; 25 + 26 + /** 27 + * Extend proto 28 + */ 29 + 30 + module.exports = function (proto) { 31 + 32 + function args (prop) { 33 + return function args () { 34 + var len = arguments.length; 35 + var a = []; 36 + var i = 0; 37 + 38 + for (; i < len; ++i) { 39 + a.push(arguments[i]); 40 + } 41 + 42 + this[prop] = this[prop].concat(a); 43 + return this; 44 + } 45 + } 46 + 47 + function streamToUnemptyBuffer(stream, callback) { 48 + var done = false 49 + var buffers = [] 50 + 51 + stream.on('data', function (data) { 52 + buffers.push(data) 53 + }) 54 + 55 + stream.on('end', function () { 56 + var result, err; 57 + if (done) 58 + return 59 + 60 + done = true 61 + result = Buffer.concat(buffers) 62 + buffers = null 63 + if (result.length==0) 64 + { 65 + err = new Error("Stream yields empty buffer"); 66 + callback(err, null); 67 + } else { 68 + callback(null, result); 69 + } 70 + }) 71 + 72 + stream.on('error', function (err) { 73 + done = true 74 + buffers = null 75 + callback(err) 76 + }) 77 + } 78 + 79 + proto.in = args('_in'); 80 + proto.out = args('_out'); 81 + 82 + proto._preprocessor = []; 83 + proto.preprocessor = args('_preprocessor'); 84 + 85 + /** 86 + * Execute the command and write the image to the specified file name. 87 + * 88 + * @param {String} name 89 + * @param {Function} callback 90 + * @return {Object} gm 91 + */ 92 + 93 + proto.write = function write (name, callback) { 94 + if (!callback) callback = name, name = null; 95 + 96 + if ("function" !== typeof callback) { 97 + throw new TypeError("gm().write() expects a callback function") 98 + } 99 + 100 + if (!name) { 101 + return callback(TypeError("gm().write() expects a filename when writing new files")); 102 + } 103 + 104 + this.outname = name; 105 + 106 + var self = this; 107 + this._preprocess(function (err) { 108 + if (err) return callback(err); 109 + self._spawn(self.args(), true, callback); 110 + }); 111 + } 112 + 113 + /** 114 + * Execute the command and return stdin and stderr 115 + * ReadableStreams providing the image data. 116 + * If no callback is passed, a "through" stream will be returned, 117 + * and stdout will be piped through, otherwise the error will be passed. 118 + * 119 + * @param {String} format (optional) 120 + * @param {Function} callback (optional) 121 + * @return {Stream} 122 + */ 123 + 124 + proto.stream = function stream (format, callback) { 125 + if (!callback && typeof format === 'function') { 126 + callback = format; 127 + format = null; 128 + } 129 + 130 + var throughStream; 131 + 132 + if ("function" !== typeof callback) { 133 + throughStream = new PassThrough(); 134 + callback = function (err, stdout, stderr) { 135 + if (err) throughStream.emit('error', err); 136 + else stdout.pipe(throughStream); 137 + } 138 + } 139 + 140 + if (format) { 141 + format = format.split('.').pop(); 142 + this.outname = format + ":-"; 143 + } 144 + 145 + var self = this; 146 + this._preprocess(function (err) { 147 + if (err) return callback(err); 148 + return self._spawn(self.args(), false, callback); 149 + }); 150 + 151 + return throughStream || this; 152 + } 153 + 154 + /** 155 + * Convenience function for `proto.stream`. 156 + * Simply returns the buffer instead of the stream. 157 + * 158 + * @param {String} format (optional) 159 + * @param {Function} callback 160 + * @return {null} 161 + */ 162 + 163 + proto.toBuffer = function toBuffer (format, callback) { 164 + if (!callback) callback = format, format = null; 165 + 166 + if ("function" !== typeof callback) { 167 + throw new Error('gm().toBuffer() expects a callback.'); 168 + } 169 + 170 + return this.stream(format, function (err, stdout) { 171 + if (err) return callback(err); 172 + 173 + streamToUnemptyBuffer(stdout, callback); 174 + }) 175 + } 176 + 177 + /** 178 + * Run any preProcessor functions in series. Used by autoOrient. 179 + * 180 + * @param {Function} callback 181 + * @return {Object} gm 182 + */ 183 + 184 + proto._preprocess = function _preprocess (callback) { 185 + series(this._preprocessor, this, callback); 186 + } 187 + 188 + /** 189 + * Execute the command, buffer input and output, return stdout and stderr buffers. 190 + * 191 + * @param {String} bin 192 + * @param {Array} args 193 + * @param {Function} callback 194 + * @return {Object} gm 195 + */ 196 + 197 + proto._exec = function _exec (args, callback) { 198 + return this._spawn(args, true, callback); 199 + } 200 + 201 + /** 202 + * Execute the command with stdin, returning stdout and stderr streams or buffers. 203 + * @param {String} bin 204 + * @param {Array} args 205 + * @param {ReadableStream} stream 206 + * @param {Boolean} shouldBuffer 207 + * @param {Function} callback, signature (err, stdout, stderr) -> * 208 + * @return {Object} gm 209 + * @TODO refactor this mess 210 + */ 211 + 212 + proto._spawn = function _spawn (args, bufferOutput, callback) { 213 + var appPath = this._options.appPath || ''; 214 + var bin = this._options.imageMagick 215 + ? appPath + args.shift() 216 + : 'gm' 217 + 218 + var cmd = bin + ' ' + args.map(utils.escape).join(' ') 219 + , self = this 220 + , proc, err; 221 + 222 + debug(cmd); 223 + 224 + try { 225 + proc = spawn(bin, args); 226 + } catch (e) { 227 + return cb(e); 228 + } 229 + 230 + if (self.sourceBuffer) { 231 + proc.stdin.write(this.sourceBuffer); 232 + proc.stdin.end(); 233 + } else if (self.sourceStream) { 234 + 235 + if (!self.sourceStream.readable) { 236 + err = new Error("gm().stream() or gm().write() with a non-readable stream."); 237 + return cb(err); 238 + } 239 + 240 + self.sourceStream.pipe(proc.stdin); 241 + 242 + // bufferStream 243 + // We convert the input source from a stream to a buffer. 244 + if (self.bufferStream && !this._buffering) { 245 + if (!Buffer.concat) { 246 + throw new Error(noBufferConcat); 247 + } 248 + 249 + // Incase there are multiple processes in parallel, 250 + // we only need one 251 + self._buffering = true; 252 + 253 + streamToUnemptyBuffer(self.sourceStream, function (err, buffer) { 254 + self.sourceBuffer = buffer; 255 + self.sourceStream = null; // The stream is now dead 256 + }) 257 + } 258 + } 259 + 260 + // for _exec operations (identify() mostly), we also 261 + // need to buffer the output stream before returning 262 + if (bufferOutput) { 263 + var stdout = '' 264 + , stderr = '' 265 + , onOut 266 + , onErr 267 + , onExit 268 + 269 + proc.stdout.on('data', onOut = function (data) { 270 + stdout += data; 271 + }); 272 + 273 + proc.stderr.on('data', onErr = function (data) { 274 + stderr += data; 275 + }); 276 + 277 + proc.on('close', onExit = function (code, signal) { 278 + if (code !== 0 || signal !== null) { 279 + err = new Error('Command failed: ' + stderr); 280 + err.code = code; 281 + err.signal = signal; 282 + }; 283 + cb(err, stdout, stderr, cmd); 284 + stdout = stderr = onOut = onErr = onExit = null; 285 + }); 286 + 287 + proc.on('error', cb); 288 + } else { 289 + cb(null, proc.stdout, proc.stderr, cmd); 290 + } 291 + 292 + return self; 293 + 294 + function cb (err, stdout, stderr, cmd) { 295 + if (cb.called) return; 296 + cb.called = 1; 297 + if (args[0] !== 'identify' && bin !== 'identify') { 298 + self._in = []; 299 + self._out = []; 300 + } 301 + callback.call(self, err, stdout, stderr, cmd); 302 + } 303 + } 304 + 305 + /** 306 + * Returns arguments to be used in the command. 307 + * 308 + * @return {Array} 309 + */ 310 + 311 + proto.args = function args () { 312 + var outname = this.outname || "-"; 313 + if (this._outputFormat) outname = this._outputFormat + ':' + outname; 314 + 315 + return [].concat( 316 + this._subCommand 317 + , this._in 318 + , this.src() 319 + , this._out 320 + , outname 321 + ).filter(Boolean); // remove falsey 322 + } 323 + 324 + /** 325 + * Adds an img source formatter. 326 + * 327 + * `formatters` are passed an array of images which will be 328 + * used as 'input' images for the command. Useful for methods 329 + * like `.append()` where multiple source images may be used. 330 + * 331 + * @param {Function} formatter 332 + * @return {gm} this 333 + */ 334 + 335 + proto.addSrcFormatter = function addSrcFormatter (formatter) { 336 + if ('function' != typeof formatter) 337 + throw new TypeError('sourceFormatter must be a function'); 338 + this._sourceFormatters || (this._sourceFormatters = []); 339 + this._sourceFormatters.push(formatter); 340 + return this; 341 + } 342 + 343 + /** 344 + * Applies all _sourceFormatters 345 + * 346 + * @return {Array} 347 + */ 348 + 349 + proto.src = function src () { 350 + var arr = []; 351 + for (var i = 0; i < this._sourceFormatters.length; ++i) { 352 + this._sourceFormatters[i].call(this, arr); 353 + } 354 + return arr; 355 + } 356 + 357 + /** 358 + * Image types. 359 + */ 360 + 361 + var types = { 362 + 'jpg': /\.jpe?g$/i 363 + , 'png' : /\.png$/i 364 + , 'gif' : /\.gif$/i 365 + , 'tiff': /\.tif?f$/i 366 + , 'bmp' : /(?:\.bmp|\.dib)$/i 367 + , 'webp': /\.webp$/i 368 + }; 369 + 370 + types.jpeg = types.jpg; 371 + types.tif = types.tiff; 372 + types.dib = types.bmp; 373 + 374 + /** 375 + * Determine the type of source image. 376 + * 377 + * @param {String} type 378 + * @return {Boolean} 379 + * @example 380 + * if (this.inputIs('png')) ... 381 + */ 382 + 383 + proto.inputIs = function inputIs (type) { 384 + if (!type) return false; 385 + 386 + var rgx = types[type]; 387 + if (!rgx) { 388 + if ('.' !== type[0]) type = '.' + type; 389 + rgx = new RegExp('\\' + type + '$', 'i'); 390 + } 391 + 392 + return rgx.test(this.source); 393 + } 394 + }
+100
node_modules/gm/lib/compare.js
··· 1 + // compare 2 + 3 + var exec = require('child_process').exec; 4 + var utils = require('./utils'); 5 + 6 + /** 7 + * Compare two images uses graphicsmagicks `compare` command. 8 + * 9 + * gm.compare(img1, img2, 0.4, function (err, equal, equality) { 10 + * if (err) return handle(err); 11 + * console.log('The images are equal: %s', equal); 12 + * console.log('There equality was %d', equality); 13 + * }); 14 + * 15 + * @param {String} orig Path to an image. 16 + * @param {String} compareTo Path to another image to compare to `orig`. 17 + * @param {Number|Object} [options] Options object or the amount of difference to tolerate before failing - defaults to 0.4 18 + * @param {Function} cb(err, Boolean, equality, rawOutput) 19 + */ 20 + 21 + module.exports = exports = function (proto) { 22 + function compare(orig, compareTo, options, cb) { 23 + orig = utils.escape(orig); 24 + compareTo = utils.escape(compareTo); 25 + 26 + var isImageMagick = this._options && this._options.imageMagick; 27 + // compare binary for IM is `compare`, for GM it's `gm compare` 28 + var bin = isImageMagick ? '' : 'gm '; 29 + var execCmd = bin + 'compare -metric mse ' + orig + ' ' + compareTo; 30 + var tolerance = 0.4; 31 + // outputting the diff image 32 + if (typeof options === 'object') { 33 + if (options.file) { 34 + if (typeof options.file !== 'string') { 35 + throw new TypeError('The path for the diff output is invalid'); 36 + } 37 + // graphicsmagick defaults to red 38 + var highlightColorOption = options.highlightColor 39 + ? ' -highlight-color ' + options.highlightColor + ' ' 40 + : ' '; 41 + var highlightStyleOption = options.highlightStyle 42 + ? ' -highlight-style ' + options.highlightStyle + ' ' 43 + : ' '; 44 + var diffFilename = utils.escape(options.file); 45 + // For IM, filename is the last argument. For GM it's `-file <filename>` 46 + var diffOpt = isImageMagick ? diffFilename : ('-file ' + diffFilename); 47 + execCmd += highlightColorOption + highlightStyleOption + ' ' + diffOpt; 48 + } 49 + 50 + if (typeof options.tolerance != 'undefined') { 51 + if (typeof options.tolerance !== 'number') { 52 + throw new TypeError('The tolerance value should be a number'); 53 + } 54 + tolerance = options.tolerance; 55 + } 56 + } else { 57 + // For ImageMagick diff file is required but we don't care about it, so null it out 58 + isImageMagick && (execCmd += ' null:'); 59 + 60 + if (typeof options == 'function') { 61 + cb = options; // tolerance value not provided, flip the cb place 62 + } else { 63 + tolerance = options 64 + } 65 + } 66 + 67 + exec(execCmd, function (err, stdout, stderr) { 68 + // ImageMagick returns err code 2 if err, 0 if similar, 1 if dissimilar 69 + if (isImageMagick) { 70 + if (!err) { 71 + return cb(null, 0 <= tolerance, 0, stdout); 72 + } 73 + if (err.code === 1) { 74 + err = null; 75 + stdout = stderr; 76 + } 77 + } 78 + if (err) { 79 + return cb(err); 80 + } 81 + // Since ImageMagick similar gives err code 0 and no stdout, there's really no matching 82 + // Otherwise, output format for IM is `12.00 (0.123)` and for GM it's `Total: 0.123` 83 + var regex = isImageMagick ? /\((\d+\.?[\d\-\+e]*)\)/m : /Total: (\d+\.?\d*)/m; 84 + var match = regex.exec(stdout); 85 + if (!match) { 86 + err = new Error('Unable to parse output.\nGot ' + stdout); 87 + return cb(err); 88 + } 89 + 90 + var equality = parseFloat(match[1]); 91 + cb(null, equality <= tolerance, equality, stdout, utils.unescape(orig), utils.unescape(compareTo)); 92 + }); 93 + } 94 + 95 + if (proto) { 96 + proto.compare = compare; 97 + } 98 + return compare; 99 + }; 100 +
+32
node_modules/gm/lib/composite.js
··· 1 + // composite 2 + 3 + var exec = require('child_process').exec; 4 + var utils = require('./utils'); 5 + 6 + /** 7 + * Composite images together using the `composite` command in graphicsmagick. 8 + * 9 + * gm('/path/to/image.jpg') 10 + * .composite('/path/to/second_image.jpg') 11 + * .geometry('+100+150') 12 + * .write('/path/to/composite.png', function(err) { 13 + * if(!err) console.log("Written composite image."); 14 + * }); 15 + * 16 + * @param {String} other Path to the image that contains the changes. 17 + * @param {String} [mask] Path to the image with opacity informtion. Grayscale. 18 + */ 19 + 20 + module.exports = exports = function(proto) { 21 + proto.composite = function(other, mask) { 22 + this.in(other); 23 + 24 + // If the mask is defined, add it to the output. 25 + if(typeof mask !== "undefined") 26 + this.out(mask); 27 + 28 + this.subCommand("composite"); 29 + 30 + return this; 31 + } 32 + }
+11
node_modules/gm/lib/convenience.js
··· 1 + 2 + /** 3 + * Extend proto 4 + */ 5 + 6 + module.exports = function (proto) { 7 + require("./convenience/thumb")(proto); 8 + require("./convenience/morph")(proto); 9 + require("./convenience/sepia")(proto); 10 + require("./convenience/autoOrient")(proto); 11 + }
+57
node_modules/gm/lib/convenience/autoOrient.js
··· 1 + 2 + /** 3 + * Extend proto. 4 + */ 5 + 6 + module.exports = function (proto) { 7 + 8 + var exifTransforms = { 9 + topleft: '' 10 + , topright: ['-flop'] 11 + , bottomright: ['-rotate', 180] 12 + , bottomleft: ['-flip'] 13 + , lefttop: ['-flip', '-rotate', 90] 14 + , righttop: ['-rotate', 90] 15 + , rightbottom: ['-flop', '-rotate', 90] 16 + , leftbottom: ['-rotate', 270] 17 + } 18 + 19 + proto.autoOrient = function autoOrient () { 20 + // Always strip EXIF data since we can't 21 + // change/edit it. 22 + 23 + // imagemagick has a native -auto-orient option 24 + // so does graphicsmagick, but in 1.3.18. 25 + // apt doesn't release this version yet. 26 + if (this._options.imageMagick) { 27 + this.out('-auto-orient'); 28 + this.strip(); 29 + return this; 30 + } 31 + 32 + this.preprocessor(function (callback) { 33 + this.orientation({bufferStream: true}, function (err, orientation) { 34 + if (err) return callback(err); 35 + 36 + var transforms = exifTransforms[orientation.toLowerCase()]; 37 + if (transforms) { 38 + 39 + // remove any existing transforms that might conflict 40 + var index = this._out.indexOf(transforms[0]); 41 + if (~index) { 42 + this._out.splice(index, transforms.length); 43 + } 44 + 45 + // repage to fix coordinates 46 + this._out.unshift.apply(this._out, transforms.concat('-page', '+0+0')); 47 + } 48 + 49 + this.strip(); 50 + 51 + callback(); 52 + }); 53 + }); 54 + 55 + return this; 56 + } 57 + }
+61
node_modules/gm/lib/convenience/morph.js
··· 1 + 2 + /** 3 + * Module dependencies. 4 + */ 5 + 6 + var fs = require('fs'); 7 + var parallel = require('array-parallel'); 8 + 9 + /** 10 + * Extend proto. 11 + */ 12 + 13 + module.exports = function (proto) { 14 + 15 + /** 16 + * Do nothing. 17 + */ 18 + 19 + function noop () {} 20 + 21 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-morph 22 + proto.morph = function morph (other, outname, callback) { 23 + if (!outname) { 24 + throw new Error("an output filename is required"); 25 + } 26 + 27 + callback = (callback || noop).bind(this) 28 + 29 + var self = this; 30 + 31 + if (Array.isArray(other)) { 32 + other.forEach(function (img) { 33 + self.out(img); 34 + }); 35 + self.out("-morph", other.length); 36 + } else { 37 + self.out(other, "-morph", 1); 38 + } 39 + 40 + self.write(outname, function (err, stdout, stderr, cmd) { 41 + if (err) return callback(err, stdout, stderr, cmd); 42 + 43 + // Apparently some platforms create the following temporary files. 44 + // Check if the output file exists, if it doesn't, then 45 + // work with temporary files. 46 + fs.exists(outname, function (exists) { 47 + if (exists) return callback(null, stdout, stderr, cmd); 48 + 49 + parallel([ 50 + fs.unlink.bind(fs, outname + '.0'), 51 + fs.unlink.bind(fs, outname + '.2'), 52 + fs.rename.bind(fs, outname + '.1', outname) 53 + ], function (err) { 54 + callback(err, stdout, stderr, cmd); 55 + }) 56 + }) 57 + }); 58 + 59 + return self; 60 + } 61 + }
+10
node_modules/gm/lib/convenience/sepia.js
··· 1 + 2 + /** 3 + * Extend proto. 4 + */ 5 + 6 + module.exports = function (proto) { 7 + proto.sepia = function sepia () { 8 + return this.modulate(115, 0, 100).colorize(7, 21, 50); 9 + } 10 + }
+73
node_modules/gm/lib/convenience/thumb.js
··· 1 + 2 + /** 3 + * Extend proto. 4 + */ 5 + 6 + module.exports = function (proto) { 7 + 8 + proto.thumb = function thumb (w, h, name, quality, align, callback) { 9 + var self = this 10 + , args = Array.prototype.slice.call(arguments); 11 + 12 + callback = args.pop(); 13 + w = args.shift(); 14 + h = args.shift(); 15 + name = args.shift(); 16 + quality = args.shift() || 63; 17 + align = args.shift() || 'topleft'; 18 + 19 + self.size(function (err, size) { 20 + if (err) { 21 + return callback.apply(self, arguments); 22 + } 23 + 24 + w = parseInt(w, 10); 25 + h = parseInt(h, 10); 26 + 27 + var w1, h1; 28 + var xoffset = 0; 29 + var yoffset = 0; 30 + 31 + if (size.width < size.height) { 32 + w1 = w; 33 + h1 = Math.floor(size.height * (w/size.width)); 34 + if (h1 < h) { 35 + w1 = Math.floor(w1 * (((h-h1)/h) + 1)); 36 + h1 = h; 37 + } 38 + } else if (size.width > size.height) { 39 + h1 = h; 40 + w1 = Math.floor(size.width * (h/size.height)); 41 + if (w1 < w) { 42 + h1 = Math.floor(h1 * (((w-w1)/w) + 1)); 43 + w1 = w; 44 + } 45 + } else if (size.width == size.height) { 46 + var bigger = (w>h?w:h); 47 + w1 = bigger; 48 + h1 = bigger; 49 + } 50 + 51 + if (align == 'center') { 52 + if (w < w1) { 53 + xoffset = (w1-w)/2; 54 + } 55 + if (h < h1) { 56 + yoffset = (h1-h)/2; 57 + } 58 + } 59 + 60 + self 61 + .quality(quality) 62 + .in("-size", w1+"x"+h1) 63 + .scale(w1, h1) 64 + .crop(w, h, xoffset, yoffset) 65 + .noProfile() 66 + .write(name, function () { 67 + callback.apply(self, arguments) 68 + }); 69 + }); 70 + 71 + return self; 72 + } 73 + }
+160
node_modules/gm/lib/drawing.js
··· 1 + 2 + /** 3 + * Module dependencies. 4 + */ 5 + 6 + var escape = require('./utils').escape; 7 + 8 + /** 9 + * Extend proto. 10 + */ 11 + 12 + module.exports = function (proto) { 13 + 14 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-fill 15 + proto.fill = function fill (color) { 16 + return this.out("-fill", color || "none"); 17 + } 18 + 19 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-stroke 20 + proto.stroke = function stroke (color, width) { 21 + if (width) { 22 + this.strokeWidth(width); 23 + } 24 + 25 + return this.out("-stroke", color || "none"); 26 + } 27 + 28 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-strokewidth 29 + proto.strokeWidth = function strokeWidth (width) { 30 + return this.out("-strokewidth", width); 31 + } 32 + 33 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-font 34 + proto.font = function font (font, size) { 35 + if (size) { 36 + this.fontSize(size); 37 + } 38 + 39 + return this.out("-font", font); 40 + } 41 + 42 + // http://www.graphicsmagick.org/GraphicsMagick.html 43 + proto.fontSize = function fontSize (size) { 44 + return this.out("-pointsize", size); 45 + } 46 + 47 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 48 + proto.draw = function draw (args) { 49 + return this.out("-draw", [].slice.call(arguments).join(" ")); 50 + } 51 + 52 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 53 + proto.drawPoint = function drawPoint (x, y) { 54 + return this.draw("point", x +","+ y); 55 + } 56 + 57 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 58 + proto.drawLine = function drawLine (x0, y0, x1, y1) { 59 + return this.draw("line", x0+","+y0, x1+","+y1); 60 + } 61 + 62 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 63 + proto.drawRectangle = function drawRectangle (x0, y0, x1, y1, wc, hc) { 64 + var shape = "rectangle" 65 + , lastarg; 66 + 67 + if ("undefined" !== typeof wc) { 68 + shape = "roundRectangle"; 69 + 70 + if ("undefined" === typeof hc) { 71 + hc = wc; 72 + } 73 + 74 + lastarg = wc+","+hc; 75 + } 76 + 77 + return this.draw(shape, x0+","+y0, x1+","+y1, lastarg); 78 + } 79 + 80 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 81 + proto.drawArc = function drawArc (x0, y0, x1, y1, a0, a1) { 82 + return this.draw("arc", x0+","+y0, x1+","+y1, a0+","+a1); 83 + } 84 + 85 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 86 + proto.drawEllipse = function drawEllipse (x0, y0, rx, ry, a0, a1) { 87 + if (a0 == undefined) a0 = 0; 88 + if (a1 == undefined) a1 = 360; 89 + return this.draw("ellipse", x0+","+y0, rx+","+ry, a0+","+a1); 90 + } 91 + 92 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 93 + proto.drawCircle = function drawCircle (x0, y0, x1, y1) { 94 + return this.draw("circle", x0+","+y0, x1+","+y1); 95 + } 96 + 97 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 98 + proto.drawPolyline = function drawPolyline () { 99 + return this.draw("polyline", formatPoints(arguments)); 100 + } 101 + 102 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 103 + proto.drawPolygon = function drawPolygon () { 104 + return this.draw("polygon", formatPoints(arguments)); 105 + } 106 + 107 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 108 + proto.drawBezier = function drawBezier () { 109 + return this.draw("bezier", formatPoints(arguments)); 110 + } 111 + 112 + proto._gravities = [ 113 + "northwest" 114 + , "north" 115 + , "northeast" 116 + , "west" 117 + , "center" 118 + , "east" 119 + , "southwest" 120 + , "south" 121 + , "southeast"]; 122 + 123 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 124 + proto.drawText = function drawText (x0, y0, text, gravity) { 125 + var gravity = String(gravity || "").toLowerCase() 126 + , arg = ["text " + x0 + "," + y0 + " " + escape(text)]; 127 + 128 + if (~this._gravities.indexOf(gravity)) { 129 + arg.unshift("gravity", gravity); 130 + } 131 + 132 + return this.draw.apply(this, arg); 133 + } 134 + 135 + proto._drawProps = ["color", "matte"]; 136 + 137 + // http://www.graphicsmagick.org/GraphicsMagick.html#details-draw 138 + proto.setDraw = function setDraw (prop, x, y, method) { 139 + prop = String(prop || "").toLowerCase(); 140 + 141 + if (!~this._drawProps.indexOf(prop)) { 142 + return this; 143 + } 144 + 145 + return this.draw(prop, x+","+y, method); 146 + } 147 + 148 + } 149 + 150 + function formatPoints (points) { 151 + var len = points.length 152 + , result = [] 153 + , i = 0; 154 + 155 + for (; i < len; ++i) { 156 + result.push(points[i].join(",")); 157 + } 158 + 159 + return result; 160 + }
+300
node_modules/gm/lib/getters.js
··· 1 + /** 2 + * Extend proto. 3 + */ 4 + 5 + module.exports = function (gm) { 6 + 7 + var proto = gm.prototype; 8 + 9 + /** 10 + * `identify` states 11 + */ 12 + 13 + const IDENTIFYING = 1; 14 + const IDENTIFIED = 2; 15 + 16 + /** 17 + * Map getter functions to output names. 18 + * 19 + * - format: specifying the -format argument (see man gm) 20 + * - verbose: use -verbose instead of -format (only if necessary b/c its slow) 21 + * - helper: use the conversion helper 22 + */ 23 + 24 + var map = { 25 + 'format': { key: 'format', format: '%m ', helper: 'Format' } 26 + , 'depth': { key: 'depth', format: '%q' } 27 + , 'filesize': { key: 'Filesize', format: '%b' } 28 + , 'size': { key: 'size', format: '%wx%h ', helper: 'Geometry' } 29 + , 'color': { key: 'color', format: '%k', helper: 'Colors' } 30 + , 'orientation': { key: 'Orientation', verbose: true } 31 + , 'res': { key: 'Resolution', verbose: true } 32 + } 33 + 34 + /** 35 + * Getter functions 36 + */ 37 + 38 + Object.keys(map).forEach(function (getter) { 39 + proto[getter] = function (opts, callback) { 40 + if (!callback) callback = opts, opts = {}; 41 + if (!callback) return this; 42 + 43 + var val = map[getter] 44 + , key = val.key 45 + , self = this; 46 + 47 + if (self.data[key]) { 48 + callback.call(self, null, self.data[key]); 49 + return self; 50 + } 51 + 52 + self.on(getter, callback); 53 + 54 + self.bufferStream = !!opts.bufferStream; 55 + 56 + if (val.verbose) { 57 + self.identify(opts, function (err, stdout, stderr, cmd) { 58 + if (err) { 59 + self.emit(getter, err, self.data[key], stdout, stderr, cmd); 60 + } else { 61 + self.emit(getter, err, self.data[key]); 62 + } 63 + }); 64 + return self; 65 + } 66 + 67 + var args = makeArgs(self, val); 68 + self._exec(args, function (err, stdout, stderr, cmd) { 69 + if (err) { 70 + self.emit(getter, err, self.data[key], stdout, stderr, cmd); 71 + return; 72 + } 73 + 74 + var result = (stdout||'').trim(); 75 + 76 + if (val.helper in helper) { 77 + helper[val.helper](self.data, result); 78 + } else { 79 + self.data[key] = result; 80 + } 81 + 82 + self.emit(getter, err, self.data[key]); 83 + }); 84 + 85 + return self; 86 + } 87 + }); 88 + 89 + /** 90 + * identify command 91 + * 92 + * Overwrites all internal data with the parsed output 93 + * which is more accurate than the fast shortcut 94 + * getters. 95 + */ 96 + 97 + proto.identify = function identify (opts, callback) { 98 + // identify with pattern 99 + if (typeof(opts) === 'string') { 100 + opts = { 101 + format: opts 102 + } 103 + } 104 + if (!callback) callback = opts, opts = {}; 105 + if (!callback) return this; 106 + if (opts && opts.format) return identifyPattern.call(this, opts, callback); 107 + 108 + var self = this; 109 + 110 + if (IDENTIFIED === self._identifyState) { 111 + callback.call(self, null, self.data); 112 + return self; 113 + } 114 + 115 + self.on('identify', callback); 116 + 117 + if (IDENTIFYING === self._identifyState) { 118 + return self; 119 + } 120 + 121 + self._identifyState = IDENTIFYING; 122 + 123 + self.bufferStream = !!opts.bufferStream; 124 + 125 + var args = makeArgs(self, { verbose: true }); 126 + 127 + self._exec(args, function (err, stdout, stderr, cmd) { 128 + if (err) { 129 + self.emit('identify', err, self.data, stdout, stderr, cmd); 130 + return; 131 + } 132 + 133 + err = parse(stdout, self); 134 + 135 + if (err) { 136 + self.emit('identify', err, self.data, stdout, stderr, cmd); 137 + return; 138 + } 139 + 140 + self.data.path = self.source; 141 + 142 + self.emit('identify', null, self.data); 143 + self._identifyState = IDENTIFIED; 144 + }); 145 + 146 + return self; 147 + } 148 + 149 + 150 + /** 151 + * identify with pattern 152 + * 153 + * Execute `identify -format` with custom pattern 154 + */ 155 + 156 + function identifyPattern (opts, callback) { 157 + var self = this; 158 + 159 + self.bufferStream = !!opts.bufferStream; 160 + 161 + var args = makeArgs(self, opts); 162 + self._exec(args, function (err, stdout, stderr, cmd) { 163 + if (err) { 164 + return callback.call(self, err, undefined, stdout, stderr, cmd); 165 + } 166 + 167 + callback.call(self, err, (stdout||'').trim()); 168 + }); 169 + 170 + return self; 171 + } 172 + 173 + 174 + /** 175 + * Parses `identify` responses. 176 + * 177 + * @param {String} stdout 178 + * @param {Gm} self 179 + * @return {Error} [optionally] 180 + */ 181 + 182 + function parse (stdout, self) { 183 + // normalize 184 + var parts = (stdout||"").trim().replace(/\r\n|\r/g, "\n").split("\n"); 185 + 186 + // skip the first line (its just the filename) 187 + parts.shift(); 188 + 189 + try { 190 + var len = parts.length 191 + , rgx1 = /^( *)(.+?): (.*)$/ // key: val 192 + , rgx2 = /^( *)(.+?):$/ // key: begin nested object 193 + , out = { indent: {} } 194 + , level = null 195 + , lastkey 196 + , i = 0 197 + , res 198 + , o 199 + 200 + for (; i < len; ++i) { 201 + res = rgx1.exec(parts[i]) || rgx2.exec(parts[i]); 202 + if (!res) continue; 203 + 204 + var indent = res[1].length 205 + , key = res[2] ? res[2].trim() : ''; 206 + 207 + if ('Image' == key) continue; 208 + 209 + var val = res[3] ? res[3].trim() : null; 210 + 211 + // first iteration? 212 + if (null === level) { 213 + level = indent; 214 + o = out.root = out.indent[level] = self.data; 215 + } else if (indent < level) { 216 + // outdent 217 + if (!(indent in out.indent)) { 218 + continue; 219 + } 220 + o = out.indent[indent]; 221 + } else if (indent > level) { 222 + // dropping into a nested object 223 + out.indent[level] = o; 224 + // wierd format, key/val pair with nested children. discard the val 225 + o = o[lastkey] = {}; 226 + } 227 + 228 + level = indent; 229 + 230 + if (val) { 231 + o[key] = val; 232 + 233 + if (key in helper) { 234 + helper[key](o, val); 235 + } 236 + } 237 + 238 + lastkey = key; 239 + } 240 + 241 + } catch (err) { 242 + err.message = err.message + "\n\n Identify stdout:\n " + stdout; 243 + return err; 244 + } 245 + } 246 + 247 + /** 248 + * Create an argument array for the identify command. 249 + * 250 + * @param {gm} self 251 + * @param {Object} val 252 + * @return {Array} 253 + */ 254 + 255 + function makeArgs (self, val) { 256 + var args = [ 257 + 'identify' 258 + , '-ping' 259 + ]; 260 + 261 + if (val.format) { 262 + args.push('-format', val.format); 263 + } 264 + 265 + if (val.verbose) { 266 + args.push('-verbose'); 267 + } 268 + 269 + args = args.concat(self.src()); 270 + return args; 271 + } 272 + 273 + /** 274 + * identify -verbose helpers 275 + */ 276 + 277 + var helper = gm.identifyHelpers = {}; 278 + 279 + helper.Geometry = function Geometry (o, val) { 280 + // We only want the size of the first frame. 281 + // Each frame is separated by a space. 282 + var split = val.split(" ").shift().split("x"); 283 + o.size = { 284 + width: parseInt(split[0], 10) 285 + , height: parseInt(split[1], 10) 286 + } 287 + }; 288 + 289 + helper.Format = function Format (o, val) { 290 + o.format = val.split(" ")[0]; 291 + }; 292 + 293 + helper.Depth = function Depth (o, val) { 294 + o.depth = parseInt(val, 10); 295 + }; 296 + 297 + helper.Colors = function Colors (o, val) { 298 + o.color = parseInt(val, 10); 299 + }; 300 + }
+17
node_modules/gm/lib/options.js
··· 1 + 2 + module.exports = exports = function (proto) { 3 + proto._options = {}; 4 + 5 + proto.options = function setOptions (options) { 6 + var keys = Object.keys(options) 7 + , i = keys.length 8 + , key 9 + 10 + while (i--) { 11 + key = keys[i]; 12 + this._options[key] = options[key]; 13 + } 14 + 15 + return this; 16 + } 17 + }
+27
node_modules/gm/lib/utils.js
··· 1 + 2 + /** 3 + * Escape the given shell `arg`. 4 + * 5 + * @param {String} arg 6 + * @return {String} 7 + * @api public 8 + */ 9 + 10 + exports.escape = function escape (arg) { 11 + return '"' + String(arg).trim().replace(/"/g, '\\"') + '"'; 12 + }; 13 + 14 + exports.unescape = function escape (arg) { 15 + return String(arg).trim().replace(/"/g, ""); 16 + }; 17 + 18 + exports.argsToArray = function (args) { 19 + var arr = []; 20 + 21 + for (var i = 0; i <= arguments.length; i++) { 22 + if ('undefined' != typeof arguments[i]) 23 + arr.push(arguments[i]); 24 + } 25 + 26 + return arr; 27 + };
+58
node_modules/gm/node_modules/array-parallel/.npmignore
··· 1 + # Compiled source # 2 + ################### 3 + *.com 4 + *.class 5 + *.dll 6 + *.exe 7 + *.o 8 + *.so 9 + 10 + # Packages # 11 + ############ 12 + # it's better to unpack these files and commit the raw source 13 + # git has its own built in compression methods 14 + *.7z 15 + *.dmg 16 + *.gz 17 + *.iso 18 + *.jar 19 + *.rar 20 + *.tar 21 + *.zip 22 + 23 + # Logs and databases # 24 + ###################### 25 + *.log 26 + *.sql 27 + *.sqlite 28 + 29 + # OS generated files # 30 + ###################### 31 + .DS_Store* 32 + ehthumbs.db 33 + Icon? 34 + Thumbs.db 35 + 36 + # Node.js # 37 + ########### 38 + lib-cov 39 + *.seed 40 + *.log 41 + *.csv 42 + *.dat 43 + *.out 44 + *.pid 45 + *.gz 46 + 47 + pids 48 + logs 49 + results 50 + 51 + node_modules 52 + npm-debug.log 53 + 54 + # Components # 55 + ############## 56 + 57 + /build 58 + /components
+6
node_modules/gm/node_modules/array-parallel/.travis.yml
··· 1 + language: node_js 2 + node_js: 3 + - "0.4" 4 + - "0.6" 5 + - "0.8" 6 + - "0.10"
+78
node_modules/gm/node_modules/array-parallel/README.md
··· 1 + # Array Series [![Build Status](https://travis-ci.org/component/array-parallel.png)](https://travis-ci.org/component/array-parallel) 2 + 3 + Call an array of asynchronous functions in parallel 4 + 5 + ### API 6 + 7 + #### parallel(fns[, context[, callback]]) 8 + 9 + ```js 10 + var parallel = require('array-parallel') 11 + 12 + parallel([ 13 + function (done) { 14 + done() 15 + } 16 + ], this, function (err) { 17 + 18 + }) 19 + ``` 20 + 21 + #### fns 22 + 23 + `fns` is an array of functions to call in parallel. 24 + The argument signature should be: 25 + 26 + ```js 27 + function (done) { 28 + done(new Error()) 29 + // or 30 + done(null, result) 31 + } 32 + ``` 33 + 34 + That is, each function should only take a `done` as an argument. 35 + Each callback should only take an `Error` as the first argument, 36 + or a value as the second. 37 + 38 + #### context 39 + 40 + Optional context to pass to each `fn`. 41 + Basically `fn.call(context, done)`. 42 + 43 + #### callback(err, results) 44 + 45 + ```js 46 + function (err, results) { 47 + 48 + } 49 + ``` 50 + 51 + Only argument is an `Error` argument. 52 + It will be the first error retrieved from all the `fns`. 53 + `results` will be an array of results from each `fn`, 54 + thus this could be considered an asynchronous version of `[].map`. 55 + 56 + ### License 57 + 58 + The MIT License (MIT) 59 + 60 + Copyright (c) 2013 Jonathan Ong me@jongleberry.com 61 + 62 + Permission is hereby granted, free of charge, to any person obtaining a copy 63 + of this software and associated documentation files (the "Software"), to deal 64 + in the Software without restriction, including without limitation the rights 65 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 66 + copies of the Software, and to permit persons to whom the Software is 67 + furnished to do so, subject to the following conditions: 68 + 69 + The above copyright notice and this permission notice shall be included in 70 + all copies or substantial portions of the Software. 71 + 72 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 73 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 74 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 75 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 76 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 77 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 78 + THE SOFTWARE.
+11
node_modules/gm/node_modules/array-parallel/component.json
··· 1 + { 2 + "name": "array-parallel", 3 + "description": "Call an array of asynchronous functions in parallel", 4 + "repo": "array-parallel", 5 + "version": "0.1.3", 6 + "main": "index.js", 7 + "scripts": [ 8 + "index.js" 9 + ], 10 + "license": "MIT" 11 + }
+40
node_modules/gm/node_modules/array-parallel/index.js
··· 1 + module.exports = function parallel(fns, context, callback) { 2 + if (!callback) { 3 + if (typeof context === 'function') { 4 + callback = context 5 + context = null 6 + } else { 7 + callback = noop 8 + } 9 + } 10 + 11 + var pending = fns && fns.length 12 + if (!pending) return callback(null, []); 13 + 14 + var finished = false 15 + var results = new Array(pending) 16 + 17 + fns.forEach(context ? function (fn, i) { 18 + fn.call(context, maybeDone(i)) 19 + } : function (fn, i) { 20 + fn(maybeDone(i)) 21 + }) 22 + 23 + function maybeDone(i) { 24 + return function (err, result) { 25 + if (finished) return; 26 + 27 + if (err) { 28 + callback(err, results) 29 + finished = true 30 + return 31 + } 32 + 33 + results[i] = result 34 + 35 + if (!--pending) callback(null, results); 36 + } 37 + } 38 + } 39 + 40 + function noop() {}
+44
node_modules/gm/node_modules/array-parallel/package.json
··· 1 + { 2 + "name": "array-parallel", 3 + "description": "Call an array of asynchronous functions in parallel", 4 + "version": "0.1.3", 5 + "scripts": { 6 + "test": "node test" 7 + }, 8 + "author": { 9 + "name": "Jonathan Ong", 10 + "email": "me@jongleberry.com", 11 + "url": "http://jongleberry.com" 12 + }, 13 + "repository": { 14 + "type": "git", 15 + "url": "https://github.com/component/array-parallel.git" 16 + }, 17 + "bugs": { 18 + "url": "https://github.com/component/array-parallel/issues", 19 + "email": "me@jongleberry.com" 20 + }, 21 + "license": "MIT", 22 + "homepage": "https://github.com/component/array-parallel", 23 + "_id": "array-parallel@0.1.3", 24 + "dist": { 25 + "shasum": "8f785308926ed5aa478c47e64d1b334b6c0c947d", 26 + "tarball": "http://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz" 27 + }, 28 + "_from": "array-parallel@>=0.1.0 <0.2.0", 29 + "_npmVersion": "1.3.17", 30 + "_npmUser": { 31 + "name": "jongleberry", 32 + "email": "jonathanrichardong@gmail.com" 33 + }, 34 + "maintainers": [ 35 + { 36 + "name": "jongleberry", 37 + "email": "jonathanrichardong@gmail.com" 38 + } 39 + ], 40 + "directories": {}, 41 + "_shasum": "8f785308926ed5aa478c47e64d1b334b6c0c947d", 42 + "_resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz", 43 + "readme": "ERROR: No README data found!" 44 + }
+62
node_modules/gm/node_modules/array-parallel/test.js
··· 1 + var assert = require('assert') 2 + var parallel = require('./') 3 + 4 + var a, b, c 5 + parallel([ 6 + function (done) { 7 + setTimeout(function () { 8 + done(null, a = 0) 9 + }, 5) 10 + }, 11 + function (done) { 12 + setTimeout(function () { 13 + done(null, b = 1) 14 + }, 10) 15 + }, 16 + function (done) { 17 + setTimeout(function () { 18 + done(null, c = 2) 19 + }, 15) 20 + } 21 + ], function (err, results) { 22 + assert.equal(a, 0) 23 + assert.equal(b, 1) 24 + assert.equal(c, 2) 25 + 26 + assert.deepEqual(results, [0, 1, 2]) 27 + }) 28 + 29 + var d, e 30 + parallel([ 31 + function (done) { 32 + setTimeout(function () { 33 + d = 1 34 + done(new Error('message')) 35 + }, 5) 36 + }, 37 + function (done) { 38 + setTimeout(function () { 39 + e = 2 40 + done() 41 + }, 10) 42 + } 43 + ], function (err) { 44 + assert.equal(err.message, 'message') 45 + assert.equal(d, 1) 46 + assert.equal(e, undefined) 47 + }) 48 + 49 + var context = 'hello' 50 + parallel([function (done) { 51 + assert.equal(this, context) 52 + }], context) 53 + 54 + var f 55 + parallel([function (done) { 56 + f = true 57 + done() 58 + }]) 59 + 60 + process.nextTick(function () { 61 + assert.equal(f, true) 62 + })
+58
node_modules/gm/node_modules/array-series/.npmignore
··· 1 + # Compiled source # 2 + ################### 3 + *.com 4 + *.class 5 + *.dll 6 + *.exe 7 + *.o 8 + *.so 9 + 10 + # Packages # 11 + ############ 12 + # it's better to unpack these files and commit the raw source 13 + # git has its own built in compression methods 14 + *.7z 15 + *.dmg 16 + *.gz 17 + *.iso 18 + *.jar 19 + *.rar 20 + *.tar 21 + *.zip 22 + 23 + # Logs and databases # 24 + ###################### 25 + *.log 26 + *.sql 27 + *.sqlite 28 + 29 + # OS generated files # 30 + ###################### 31 + .DS_Store* 32 + ehthumbs.db 33 + Icon? 34 + Thumbs.db 35 + 36 + # Node.js # 37 + ########### 38 + lib-cov 39 + *.seed 40 + *.log 41 + *.csv 42 + *.dat 43 + *.out 44 + *.pid 45 + *.gz 46 + 47 + pids 48 + logs 49 + results 50 + 51 + node_modules 52 + npm-debug.log 53 + 54 + # Components # 55 + ############## 56 + 57 + /build 58 + /components
+4
node_modules/gm/node_modules/array-series/.travis.yml
··· 1 + language: node_js 2 + node_js: 3 + - "0.8" 4 + - "0.10"
+76
node_modules/gm/node_modules/array-series/README.md
··· 1 + # Array Series [![Build Status](https://travis-ci.org/component/array-series.png)](https://travis-ci.org/component/array-series) 2 + 3 + Call an array of asynchronous functions in series 4 + 5 + ### API 6 + 7 + #### series(fns[, context[, callback]]) 8 + 9 + ```js 10 + var series = require('array-series') 11 + 12 + series([ 13 + function (done) { 14 + done() 15 + } 16 + ], this, function (err) { 17 + 18 + }) 19 + ``` 20 + 21 + #### fns 22 + 23 + `fns` is an array of functions to call in series. 24 + The argument signature should be: 25 + 26 + ```js 27 + function (done) { 28 + done(new Error()) 29 + // or 30 + done() 31 + } 32 + ``` 33 + 34 + That is, each function should only take a `done` as an argument. 35 + Each callback should only take an optional `Error` as an argument. 36 + 37 + #### context 38 + 39 + Optional context to pass to each `fn`. 40 + Basically `fn.call(context, done)`. 41 + 42 + #### callback(err) 43 + 44 + ```js 45 + function (err) { 46 + 47 + } 48 + ``` 49 + 50 + Only argument is an `Error` argument. 51 + It will return the first error in the series of functions that returns an error, 52 + and no function after will be called. 53 + 54 + ### License 55 + 56 + The MIT License (MIT) 57 + 58 + Copyright (c) 2013 Jonathan Ong me@jongleberry.com 59 + 60 + Permission is hereby granted, free of charge, to any person obtaining a copy 61 + of this software and associated documentation files (the "Software"), to deal 62 + in the Software without restriction, including without limitation the rights 63 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 64 + copies of the Software, and to permit persons to whom the Software is 65 + furnished to do so, subject to the following conditions: 66 + 67 + The above copyright notice and this permission notice shall be included in 68 + all copies or substantial portions of the Software. 69 + 70 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 71 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 72 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 73 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 74 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 75 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 76 + THE SOFTWARE.
+11
node_modules/gm/node_modules/array-series/component.json
··· 1 + { 2 + "name": "array-series", 3 + "description": "Call an array of asynchronous functions in series", 4 + "repo": "component/array-series", 5 + "version": "0.1.5", 6 + "main": "index.js", 7 + "scripts": [ 8 + "index.js" 9 + ], 10 + "license": "MIT" 11 + }
+34
node_modules/gm/node_modules/array-series/index.js
··· 1 + module.exports = function series(fns, context, callback) { 2 + if (!callback) { 3 + if (typeof context === 'function') { 4 + callback = context 5 + context = null 6 + } else { 7 + callback = noop 8 + } 9 + } 10 + 11 + if (!(fns && fns.length)) return callback(); 12 + 13 + fns = fns.slice(0) 14 + 15 + var call = context 16 + ? function () { 17 + fns.length 18 + ? fns.shift().call(context, next) 19 + : callback() 20 + } 21 + : function () { 22 + fns.length 23 + ? fns.shift()(next) 24 + : callback() 25 + } 26 + 27 + call() 28 + 29 + function next(err) { 30 + err ? callback(err) : call() 31 + } 32 + } 33 + 34 + function noop() {}
+44
node_modules/gm/node_modules/array-series/package.json
··· 1 + { 2 + "name": "array-series", 3 + "description": "Call an array of asynchronous functions in series", 4 + "version": "0.1.5", 5 + "scripts": { 6 + "test": "node test" 7 + }, 8 + "author": { 9 + "name": "Jonathan Ong", 10 + "email": "me@jongleberry.com", 11 + "url": "http://jongleberry.com" 12 + }, 13 + "repository": { 14 + "type": "git", 15 + "url": "https://github.com/component/array-series.git" 16 + }, 17 + "bugs": { 18 + "url": "https://github.com/component/array-series/issues", 19 + "email": "me@jongleberry.com" 20 + }, 21 + "license": "MIT", 22 + "homepage": "https://github.com/component/array-series", 23 + "_id": "array-series@0.1.5", 24 + "dist": { 25 + "shasum": "df5d37bfc5c2ef0755e2aa4f92feae7d4b5a972f", 26 + "tarball": "http://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz" 27 + }, 28 + "_from": "array-series@>=0.1.0 <0.2.0", 29 + "_npmVersion": "1.3.17", 30 + "_npmUser": { 31 + "name": "jongleberry", 32 + "email": "jonathanrichardong@gmail.com" 33 + }, 34 + "maintainers": [ 35 + { 36 + "name": "jongleberry", 37 + "email": "jonathanrichardong@gmail.com" 38 + } 39 + ], 40 + "directories": {}, 41 + "_shasum": "df5d37bfc5c2ef0755e2aa4f92feae7d4b5a972f", 42 + "_resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz", 43 + "readme": "ERROR: No README data found!" 44 + }
+88
node_modules/gm/node_modules/array-series/test.js
··· 1 + var assert = require('assert') 2 + var series = require('./') 3 + 4 + var a, b, c 5 + 6 + series([ 7 + function (done) { 8 + a = 1 9 + process.nextTick(done) 10 + check('a') 11 + }, 12 + function (done) { 13 + b = 2 14 + process.nextTick(done) 15 + check('b') 16 + }, 17 + function (done) { 18 + c = 3 19 + process.nextTick(done) 20 + check('c') 21 + } 22 + ], function (err) { 23 + assert.ifError(err) 24 + assert.equal(a, 1) 25 + assert.equal(b, 2) 26 + assert.equal(c, 3) 27 + }) 28 + 29 + function check(x) { 30 + switch (x) { 31 + case 'a': 32 + assert.equal(a, 1) 33 + assert.equal(b, undefined) 34 + assert.equal(c, undefined) 35 + break 36 + case 'b': 37 + assert.equal(a, 1) 38 + assert.equal(b, 2) 39 + assert.equal(c, undefined) 40 + break 41 + case 'c': 42 + assert.equal(a, 1) 43 + assert.equal(b, 2) 44 + assert.equal(c, 3) 45 + break 46 + } 47 + } 48 + 49 + var context = 'hello' 50 + series([function (done) { 51 + assert.equal(this, context) 52 + done() 53 + }], context) 54 + 55 + var finished 56 + series([], function (err) { 57 + finished = true 58 + }) 59 + 60 + process.nextTick(function () { 61 + if (!finished) 62 + throw new Error('Failed with no functions.'); 63 + }) 64 + 65 + var r, d, o 66 + series([ 67 + function (done) { 68 + r = 1 69 + process.nextTick(done) 70 + }, 71 + function (done) { 72 + d = 0 73 + process.nextTick(function () { 74 + done(new Error('message')) 75 + }) 76 + }, 77 + function (done) { 78 + o = 0 79 + process.nextTick(done) 80 + } 81 + ], function (err) { 82 + assert.equal(err.message, 'message') 83 + assert.equal(r, 1) 84 + assert.equal(d, 0) 85 + assert.equal(o, undefined) 86 + }) 87 + 88 + console.log('Array series tests pass!')
+4
node_modules/gm/node_modules/debug/.npmignore
··· 1 + support 2 + test 3 + examples 4 + *.sock
+47
node_modules/gm/node_modules/debug/History.md
··· 1 + 2 + 0.7.0 / 2012-05-04 3 + ================== 4 + 5 + * Added .component to package.json 6 + * Added debug.component.js build 7 + 8 + 0.6.0 / 2012-03-16 9 + ================== 10 + 11 + * Added support for "-" prefix in DEBUG [Vinay Pulim] 12 + * Added `.enabled` flag to the node version [TooTallNate] 13 + 14 + 0.5.0 / 2012-02-02 15 + ================== 16 + 17 + * Added: humanize diffs. Closes #8 18 + * Added `debug.disable()` to the CS variant 19 + * Removed padding. Closes #10 20 + * Fixed: persist client-side variant again. Closes #9 21 + 22 + 0.4.0 / 2012-02-01 23 + ================== 24 + 25 + * Added browser variant support for older browsers [TooTallNate] 26 + * Added `debug.enable('project:*')` to browser variant [TooTallNate] 27 + * Added padding to diff (moved it to the right) 28 + 29 + 0.3.0 / 2012-01-26 30 + ================== 31 + 32 + * Added millisecond diff when isatty, otherwise UTC string 33 + 34 + 0.2.0 / 2012-01-22 35 + ================== 36 + 37 + * Added wildcard support 38 + 39 + 0.1.0 / 2011-12-02 40 + ================== 41 + 42 + * Added: remove colors unless stderr isatty [TooTallNate] 43 + 44 + 0.0.1 / 2010-01-03 45 + ================== 46 + 47 + * Initial release
+4
node_modules/gm/node_modules/debug/Makefile
··· 1 + 2 + debug.component.js: head.js debug.js tail.js 3 + cat $^ > $@ 4 +
+130
node_modules/gm/node_modules/debug/Readme.md
··· 1 + 2 + # debug 3 + 4 + tiny node.js debugging utility. 5 + 6 + ## Installation 7 + 8 + ``` 9 + $ npm install debug 10 + ``` 11 + 12 + ## Example 13 + 14 + This module is modelled after node core's debugging technique, allowing you to enable one or more topic-specific debugging functions, for example core does the following within many modules: 15 + 16 + ```js 17 + var debug; 18 + if (process.env.NODE_DEBUG && /cluster/.test(process.env.NODE_DEBUG)) { 19 + debug = function(x) { 20 + var prefix = process.pid + ',' + 21 + (process.env.NODE_WORKER_ID ? 'Worker' : 'Master'); 22 + console.error(prefix, x); 23 + }; 24 + } else { 25 + debug = function() { }; 26 + } 27 + ``` 28 + 29 + This concept is extremely simple but it works well. With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility. 30 + 31 + Example _app.js_: 32 + 33 + ```js 34 + var debug = require('debug')('http') 35 + , http = require('http') 36 + , name = 'My App'; 37 + 38 + // fake app 39 + 40 + debug('booting %s', name); 41 + 42 + http.createServer(function(req, res){ 43 + debug(req.method + ' ' + req.url); 44 + res.end('hello\n'); 45 + }).listen(3000, function(){ 46 + debug('listening'); 47 + }); 48 + 49 + // fake worker of some kind 50 + 51 + require('./worker'); 52 + ``` 53 + 54 + Example _worker.js_: 55 + 56 + ```js 57 + var debug = require('debug')('worker'); 58 + 59 + setInterval(function(){ 60 + debug('doing some work'); 61 + }, 1000); 62 + ``` 63 + 64 + The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples: 65 + 66 + ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png) 67 + 68 + ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png) 69 + 70 + ## Millisecond diff 71 + 72 + When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. 73 + 74 + ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png) 75 + 76 + When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below: 77 + 78 + ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png) 79 + 80 + ## Conventions 81 + 82 + If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". 83 + 84 + ## Wildcards 85 + 86 + The "*" character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. 87 + 88 + You can also exclude specific debuggers by prefixing them with a "-" character. For example, `DEBUG=* -connect:*` would include all debuggers except those starting with "connect:". 89 + 90 + ## Browser support 91 + 92 + Debug works in the browser as well, currently persisted by `localStorage`. For example if you have `worker:a` and `worker:b` as shown below, and wish to debug both type `debug.enable('worker:*')` in the console and refresh the page, this will remain until you disable with `debug.disable()`. 93 + 94 + ```js 95 + a = debug('worker:a'); 96 + b = debug('worker:b'); 97 + 98 + setInterval(function(){ 99 + a('doing some work'); 100 + }, 1000); 101 + 102 + setInterval(function(){ 103 + a('doing some work'); 104 + }, 1200); 105 + ``` 106 + 107 + ## License 108 + 109 + (The MIT License) 110 + 111 + Copyright (c) 2011 TJ Holowaychuk &lt;tj@vision-media.ca&gt; 112 + 113 + Permission is hereby granted, free of charge, to any person obtaining 114 + a copy of this software and associated documentation files (the 115 + 'Software'), to deal in the Software without restriction, including 116 + without limitation the rights to use, copy, modify, merge, publish, 117 + distribute, sublicense, and/or sell copies of the Software, and to 118 + permit persons to whom the Software is furnished to do so, subject to 119 + the following conditions: 120 + 121 + The above copyright notice and this permission notice shall be 122 + included in all copies or substantial portions of the Software. 123 + 124 + THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 125 + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 126 + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 127 + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 128 + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 129 + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 130 + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+120
node_modules/gm/node_modules/debug/debug.component.js
··· 1 + ;(function(){ 2 + 3 + /** 4 + * Create a debugger with the given `name`. 5 + * 6 + * @param {String} name 7 + * @return {Type} 8 + * @api public 9 + */ 10 + 11 + function debug(name) { 12 + if (!debug.enabled(name)) return function(){}; 13 + 14 + return function(fmt){ 15 + var curr = new Date; 16 + var ms = curr - (debug[name] || curr); 17 + debug[name] = curr; 18 + 19 + fmt = name 20 + + ' ' 21 + + fmt 22 + + ' +' + debug.humanize(ms); 23 + 24 + // This hackery is required for IE8 25 + // where `console.log` doesn't have 'apply' 26 + window.console 27 + && console.log 28 + && Function.prototype.apply.call(console.log, console, arguments); 29 + } 30 + } 31 + 32 + /** 33 + * The currently active debug mode names. 34 + */ 35 + 36 + debug.names = []; 37 + debug.skips = []; 38 + 39 + /** 40 + * Enables a debug mode by name. This can include modes 41 + * separated by a colon and wildcards. 42 + * 43 + * @param {String} name 44 + * @api public 45 + */ 46 + 47 + debug.enable = function(name) { 48 + localStorage.debug = name; 49 + 50 + var split = (name || '').split(/[\s,]+/) 51 + , len = split.length; 52 + 53 + for (var i = 0; i < len; i++) { 54 + name = split[i].replace('*', '.*?'); 55 + if (name[0] === '-') { 56 + debug.skips.push(new RegExp('^' + name.substr(1) + '$')); 57 + } 58 + else { 59 + debug.names.push(new RegExp('^' + name + '$')); 60 + } 61 + } 62 + }; 63 + 64 + /** 65 + * Disable debug output. 66 + * 67 + * @api public 68 + */ 69 + 70 + debug.disable = function(){ 71 + debug.enable(''); 72 + }; 73 + 74 + /** 75 + * Humanize the given `ms`. 76 + * 77 + * @param {Number} m 78 + * @return {String} 79 + * @api private 80 + */ 81 + 82 + debug.humanize = function(ms) { 83 + var sec = 1000 84 + , min = 60 * 1000 85 + , hour = 60 * min; 86 + 87 + if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; 88 + if (ms >= min) return (ms / min).toFixed(1) + 'm'; 89 + if (ms >= sec) return (ms / sec | 0) + 's'; 90 + return ms + 'ms'; 91 + }; 92 + 93 + /** 94 + * Returns true if the given mode name is enabled, false otherwise. 95 + * 96 + * @param {String} name 97 + * @return {Boolean} 98 + * @api public 99 + */ 100 + 101 + debug.enabled = function(name) { 102 + for (var i = 0, len = debug.skips.length; i < len; i++) { 103 + if (debug.skips[i].test(name)) { 104 + return false; 105 + } 106 + } 107 + for (var i = 0, len = debug.names.length; i < len; i++) { 108 + if (debug.names[i].test(name)) { 109 + return true; 110 + } 111 + } 112 + return false; 113 + }; 114 + 115 + // persist 116 + 117 + if (window.localStorage) debug.enable(localStorage.debug); 118 + module.exports = debug; 119 + 120 + })();
+116
node_modules/gm/node_modules/debug/debug.js
··· 1 + 2 + /** 3 + * Create a debugger with the given `name`. 4 + * 5 + * @param {String} name 6 + * @return {Type} 7 + * @api public 8 + */ 9 + 10 + function debug(name) { 11 + if (!debug.enabled(name)) return function(){}; 12 + 13 + return function(fmt){ 14 + var curr = new Date; 15 + var ms = curr - (debug[name] || curr); 16 + debug[name] = curr; 17 + 18 + fmt = name 19 + + ' ' 20 + + fmt 21 + + ' +' + debug.humanize(ms); 22 + 23 + // This hackery is required for IE8 24 + // where `console.log` doesn't have 'apply' 25 + window.console 26 + && console.log 27 + && Function.prototype.apply.call(console.log, console, arguments); 28 + } 29 + } 30 + 31 + /** 32 + * The currently active debug mode names. 33 + */ 34 + 35 + debug.names = []; 36 + debug.skips = []; 37 + 38 + /** 39 + * Enables a debug mode by name. This can include modes 40 + * separated by a colon and wildcards. 41 + * 42 + * @param {String} name 43 + * @api public 44 + */ 45 + 46 + debug.enable = function(name) { 47 + localStorage.debug = name; 48 + 49 + var split = (name || '').split(/[\s,]+/) 50 + , len = split.length; 51 + 52 + for (var i = 0; i < len; i++) { 53 + name = split[i].replace('*', '.*?'); 54 + if (name[0] === '-') { 55 + debug.skips.push(new RegExp('^' + name.substr(1) + '$')); 56 + } 57 + else { 58 + debug.names.push(new RegExp('^' + name + '$')); 59 + } 60 + } 61 + }; 62 + 63 + /** 64 + * Disable debug output. 65 + * 66 + * @api public 67 + */ 68 + 69 + debug.disable = function(){ 70 + debug.enable(''); 71 + }; 72 + 73 + /** 74 + * Humanize the given `ms`. 75 + * 76 + * @param {Number} m 77 + * @return {String} 78 + * @api private 79 + */ 80 + 81 + debug.humanize = function(ms) { 82 + var sec = 1000 83 + , min = 60 * 1000 84 + , hour = 60 * min; 85 + 86 + if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; 87 + if (ms >= min) return (ms / min).toFixed(1) + 'm'; 88 + if (ms >= sec) return (ms / sec | 0) + 's'; 89 + return ms + 'ms'; 90 + }; 91 + 92 + /** 93 + * Returns true if the given mode name is enabled, false otherwise. 94 + * 95 + * @param {String} name 96 + * @return {Boolean} 97 + * @api public 98 + */ 99 + 100 + debug.enabled = function(name) { 101 + for (var i = 0, len = debug.skips.length; i < len; i++) { 102 + if (debug.skips[i].test(name)) { 103 + return false; 104 + } 105 + } 106 + for (var i = 0, len = debug.names.length; i < len; i++) { 107 + if (debug.names[i].test(name)) { 108 + return true; 109 + } 110 + } 111 + return false; 112 + }; 113 + 114 + // persist 115 + 116 + if (window.localStorage) debug.enable(localStorage.debug);
+19
node_modules/gm/node_modules/debug/example/app.js
··· 1 + 2 + var debug = require('../')('http') 3 + , http = require('http') 4 + , name = 'My App'; 5 + 6 + // fake app 7 + 8 + debug('booting %s', name); 9 + 10 + http.createServer(function(req, res){ 11 + debug(req.method + ' ' + req.url); 12 + res.end('hello\n'); 13 + }).listen(3000, function(){ 14 + debug('listening'); 15 + }); 16 + 17 + // fake worker of some kind 18 + 19 + require('./worker');
+24
node_modules/gm/node_modules/debug/example/browser.html
··· 1 + <html> 2 + <head> 3 + <title>debug()</title> 4 + <script src="../debug.js"></script> 5 + <script> 6 + // type debug.enable('*') in 7 + // the console and refresh :) 8 + 9 + a = debug('worker:a'); 10 + b = debug('worker:b'); 11 + 12 + setInterval(function(){ 13 + a('doing some work'); 14 + }, 1000); 15 + 16 + setInterval(function(){ 17 + a('doing some work'); 18 + }, 1200); 19 + </script> 20 + </head> 21 + <body> 22 + 23 + </body> 24 + </html>
+10
node_modules/gm/node_modules/debug/example/wildcards.js
··· 1 + 2 + var debug = { 3 + foo: require('../')('test:foo'), 4 + bar: require('../')('test:bar'), 5 + baz: require('../')('test:baz') 6 + }; 7 + 8 + debug.foo('foo') 9 + debug.bar('bar') 10 + debug.baz('baz')
+22
node_modules/gm/node_modules/debug/example/worker.js
··· 1 + 2 + // DEBUG=* node example/worker 3 + // DEBUG=worker:* node example/worker 4 + // DEBUG=worker:a node example/worker 5 + // DEBUG=worker:b node example/worker 6 + 7 + var a = require('../')('worker:a') 8 + , b = require('../')('worker:b'); 9 + 10 + function work() { 11 + a('doing lots of uninteresting work'); 12 + setTimeout(work, Math.random() * 1000); 13 + } 14 + 15 + work(); 16 + 17 + function workb() { 18 + b('doing some work'); 19 + setTimeout(workb, Math.random() * 2000); 20 + } 21 + 22 + workb();
+1
node_modules/gm/node_modules/debug/head.js
··· 1 + ;(function(){
+2
node_modules/gm/node_modules/debug/index.js
··· 1 + 2 + module.exports = require('./lib/debug');
+135
node_modules/gm/node_modules/debug/lib/debug.js
··· 1 + 2 + /** 3 + * Module dependencies. 4 + */ 5 + 6 + var tty = require('tty'); 7 + 8 + /** 9 + * Expose `debug()` as the module. 10 + */ 11 + 12 + module.exports = debug; 13 + 14 + /** 15 + * Enabled debuggers. 16 + */ 17 + 18 + var names = [] 19 + , skips = []; 20 + 21 + (process.env.DEBUG || '') 22 + .split(/[\s,]+/) 23 + .forEach(function(name){ 24 + name = name.replace('*', '.*?'); 25 + if (name[0] === '-') { 26 + skips.push(new RegExp('^' + name.substr(1) + '$')); 27 + } else { 28 + names.push(new RegExp('^' + name + '$')); 29 + } 30 + }); 31 + 32 + /** 33 + * Colors. 34 + */ 35 + 36 + var colors = [6, 2, 3, 4, 5, 1]; 37 + 38 + /** 39 + * Previous debug() call. 40 + */ 41 + 42 + var prev = {}; 43 + 44 + /** 45 + * Previously assigned color. 46 + */ 47 + 48 + var prevColor = 0; 49 + 50 + /** 51 + * Is stdout a TTY? Colored output is disabled when `true`. 52 + */ 53 + 54 + var isatty = tty.isatty(2); 55 + 56 + /** 57 + * Select a color. 58 + * 59 + * @return {Number} 60 + * @api private 61 + */ 62 + 63 + function color() { 64 + return colors[prevColor++ % colors.length]; 65 + } 66 + 67 + /** 68 + * Humanize the given `ms`. 69 + * 70 + * @param {Number} m 71 + * @return {String} 72 + * @api private 73 + */ 74 + 75 + function humanize(ms) { 76 + var sec = 1000 77 + , min = 60 * 1000 78 + , hour = 60 * min; 79 + 80 + if (ms >= hour) return (ms / hour).toFixed(1) + 'h'; 81 + if (ms >= min) return (ms / min).toFixed(1) + 'm'; 82 + if (ms >= sec) return (ms / sec | 0) + 's'; 83 + return ms + 'ms'; 84 + } 85 + 86 + /** 87 + * Create a debugger with the given `name`. 88 + * 89 + * @param {String} name 90 + * @return {Type} 91 + * @api public 92 + */ 93 + 94 + function debug(name) { 95 + function disabled(){} 96 + disabled.enabled = false; 97 + 98 + var match = skips.some(function(re){ 99 + return re.test(name); 100 + }); 101 + 102 + if (match) return disabled; 103 + 104 + match = names.some(function(re){ 105 + return re.test(name); 106 + }); 107 + 108 + if (!match) return disabled; 109 + var c = color(); 110 + 111 + function colored(fmt) { 112 + var curr = new Date; 113 + var ms = curr - (prev[name] || curr); 114 + prev[name] = curr; 115 + 116 + fmt = ' \033[9' + c + 'm' + name + ' ' 117 + + '\033[3' + c + 'm\033[90m' 118 + + fmt + '\033[3' + c + 'm' 119 + + ' +' + humanize(ms) + '\033[0m'; 120 + 121 + console.error.apply(this, arguments); 122 + } 123 + 124 + function plain(fmt) { 125 + fmt = new Date().toUTCString() 126 + + ' ' + name + ' ' + fmt; 127 + console.error.apply(this, arguments); 128 + } 129 + 130 + colored.enabled = plain.enabled = true; 131 + 132 + return isatty 133 + ? colored 134 + : plain; 135 + }
+44
node_modules/gm/node_modules/debug/package.json
··· 1 + { 2 + "name": "debug", 3 + "version": "0.7.0", 4 + "description": "small debugging utility", 5 + "keywords": [ 6 + "debug", 7 + "log", 8 + "debugger" 9 + ], 10 + "author": { 11 + "name": "TJ Holowaychuk", 12 + "email": "tj@vision-media.ca" 13 + }, 14 + "dependencies": {}, 15 + "devDependencies": { 16 + "mocha": "*" 17 + }, 18 + "main": "index", 19 + "browserify": "debug.component.js", 20 + "engines": { 21 + "node": "*" 22 + }, 23 + "component": { 24 + "scripts": { 25 + "debug": "debug.component.js" 26 + } 27 + }, 28 + "_id": "debug@0.7.0", 29 + "dist": { 30 + "shasum": "f5be05ec0434c992d79940e50b2695cfb2e01b08", 31 + "tarball": "http://registry.npmjs.org/debug/-/debug-0.7.0.tgz" 32 + }, 33 + "maintainers": [ 34 + { 35 + "name": "tjholowaychuk", 36 + "email": "tj@vision-media.ca" 37 + } 38 + ], 39 + "directories": {}, 40 + "_shasum": "f5be05ec0434c992d79940e50b2695cfb2e01b08", 41 + "_resolved": "https://registry.npmjs.org/debug/-/debug-0.7.0.tgz", 42 + "_from": "debug@0.7.0", 43 + "readme": "ERROR: No README data found!" 44 + }
+4
node_modules/gm/node_modules/debug/tail.js
··· 1 + 2 + module.exports = debug; 3 + 4 + })();
+5
node_modules/gm/node_modules/through/.travis.yml
··· 1 + language: node_js 2 + node_js: 3 + - 0.6 4 + - 0.8 5 + - "0.10"
+15
node_modules/gm/node_modules/through/LICENSE.APACHE2
··· 1 + Apache License, Version 2.0 2 + 3 + Copyright (c) 2011 Dominic Tarr 4 + 5 + Licensed under the Apache License, Version 2.0 (the "License"); 6 + you may not use this file except in compliance with the License. 7 + You may obtain a copy of the License at 8 + 9 + http://www.apache.org/licenses/LICENSE-2.0 10 + 11 + Unless required by applicable law or agreed to in writing, software 12 + distributed under the License is distributed on an "AS IS" BASIS, 13 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 + See the License for the specific language governing permissions and 15 + limitations under the License.
+24
node_modules/gm/node_modules/through/LICENSE.MIT
··· 1 + The MIT License 2 + 3 + Copyright (c) 2011 Dominic Tarr 4 + 5 + Permission is hereby granted, free of charge, 6 + to any person obtaining a copy of this software and 7 + associated documentation files (the "Software"), to 8 + deal in the Software without restriction, including 9 + without limitation the rights to use, copy, modify, 10 + merge, publish, distribute, sublicense, and/or sell 11 + copies of the Software, and to permit persons to whom 12 + the Software is furnished to do so, 13 + subject to the following conditions: 14 + 15 + The above copyright notice and this permission notice 16 + shall be included in all copies or substantial portions of the Software. 17 + 18 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 22 + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+108
node_modules/gm/node_modules/through/index.js
··· 1 + var Stream = require('stream') 2 + 3 + // through 4 + // 5 + // a stream that does nothing but re-emit the input. 6 + // useful for aggregating a series of changing but not ending streams into one stream) 7 + 8 + exports = module.exports = through 9 + through.through = through 10 + 11 + //create a readable writable stream. 12 + 13 + function through (write, end, opts) { 14 + write = write || function (data) { this.queue(data) } 15 + end = end || function () { this.queue(null) } 16 + 17 + var ended = false, destroyed = false, buffer = [], _ended = false 18 + var stream = new Stream() 19 + stream.readable = stream.writable = true 20 + stream.paused = false 21 + 22 + // stream.autoPause = !(opts && opts.autoPause === false) 23 + stream.autoDestroy = !(opts && opts.autoDestroy === false) 24 + 25 + stream.write = function (data) { 26 + write.call(this, data) 27 + return !stream.paused 28 + } 29 + 30 + function drain() { 31 + while(buffer.length && !stream.paused) { 32 + var data = buffer.shift() 33 + if(null === data) 34 + return stream.emit('end') 35 + else 36 + stream.emit('data', data) 37 + } 38 + } 39 + 40 + stream.queue = stream.push = function (data) { 41 + // console.error(ended) 42 + if(_ended) return stream 43 + if(data == null) _ended = true 44 + buffer.push(data) 45 + drain() 46 + return stream 47 + } 48 + 49 + //this will be registered as the first 'end' listener 50 + //must call destroy next tick, to make sure we're after any 51 + //stream piped from here. 52 + //this is only a problem if end is not emitted synchronously. 53 + //a nicer way to do this is to make sure this is the last listener for 'end' 54 + 55 + stream.on('end', function () { 56 + stream.readable = false 57 + if(!stream.writable && stream.autoDestroy) 58 + process.nextTick(function () { 59 + stream.destroy() 60 + }) 61 + }) 62 + 63 + function _end () { 64 + stream.writable = false 65 + end.call(stream) 66 + if(!stream.readable && stream.autoDestroy) 67 + stream.destroy() 68 + } 69 + 70 + stream.end = function (data) { 71 + if(ended) return 72 + ended = true 73 + if(arguments.length) stream.write(data) 74 + _end() // will emit or queue 75 + return stream 76 + } 77 + 78 + stream.destroy = function () { 79 + if(destroyed) return 80 + destroyed = true 81 + ended = true 82 + buffer.length = 0 83 + stream.writable = stream.readable = false 84 + stream.emit('close') 85 + return stream 86 + } 87 + 88 + stream.pause = function () { 89 + if(stream.paused) return 90 + stream.paused = true 91 + return stream 92 + } 93 + 94 + stream.resume = function () { 95 + if(stream.paused) { 96 + stream.paused = false 97 + stream.emit('resume') 98 + } 99 + drain() 100 + //may have become paused again, 101 + //as drain emits 'data'. 102 + if(!stream.paused) 103 + stream.emit('drain') 104 + return stream 105 + } 106 + return stream 107 + } 108 +
+65
node_modules/gm/node_modules/through/package.json
··· 1 + { 2 + "name": "through", 3 + "version": "2.3.6", 4 + "description": "simplified stream construction", 5 + "main": "index.js", 6 + "scripts": { 7 + "test": "set -e; for t in test/*.js; do node $t; done" 8 + }, 9 + "devDependencies": { 10 + "stream-spec": "~0.3.5", 11 + "tape": "~2.3.2", 12 + "from": "~0.1.3" 13 + }, 14 + "keywords": [ 15 + "stream", 16 + "streams", 17 + "user-streams", 18 + "pipe" 19 + ], 20 + "author": { 21 + "name": "Dominic Tarr", 22 + "email": "dominic.tarr@gmail.com", 23 + "url": "dominictarr.com" 24 + }, 25 + "license": "MIT", 26 + "repository": { 27 + "type": "git", 28 + "url": "https://github.com/dominictarr/through.git" 29 + }, 30 + "homepage": "http://github.com/dominictarr/through", 31 + "testling": { 32 + "browsers": [ 33 + "ie/8..latest", 34 + "ff/15..latest", 35 + "chrome/20..latest", 36 + "safari/5.1..latest" 37 + ], 38 + "files": "test/*.js" 39 + }, 40 + "gitHead": "19ed9b7e84efe7c3e3c8be80f29390b1620e13c0", 41 + "bugs": { 42 + "url": "https://github.com/dominictarr/through/issues" 43 + }, 44 + "_id": "through@2.3.6", 45 + "_shasum": "26681c0f524671021d4e29df7c36bce2d0ecf2e8", 46 + "_from": "through@>=2.3.1 <2.4.0", 47 + "_npmVersion": "1.4.26", 48 + "_npmUser": { 49 + "name": "dominictarr", 50 + "email": "dominic.tarr@gmail.com" 51 + }, 52 + "maintainers": [ 53 + { 54 + "name": "dominictarr", 55 + "email": "dominic.tarr@gmail.com" 56 + } 57 + ], 58 + "dist": { 59 + "shasum": "26681c0f524671021d4e29df7c36bce2d0ecf2e8", 60 + "tarball": "http://registry.npmjs.org/through/-/through-2.3.6.tgz" 61 + }, 62 + "directories": {}, 63 + "_resolved": "https://registry.npmjs.org/through/-/through-2.3.6.tgz", 64 + "readme": "ERROR: No README data found!" 65 + }
+64
node_modules/gm/node_modules/through/readme.markdown
··· 1 + #through 2 + 3 + [![build status](https://secure.travis-ci.org/dominictarr/through.png)](http://travis-ci.org/dominictarr/through) 4 + [![testling badge](https://ci.testling.com/dominictarr/through.png)](https://ci.testling.com/dominictarr/through) 5 + 6 + Easy way to create a `Stream` that is both `readable` and `writable`. 7 + 8 + * Pass in optional `write` and `end` methods. 9 + * `through` takes care of pause/resume logic if you use `this.queue(data)` instead of `this.emit('data', data)`. 10 + * Use `this.pause()` and `this.resume()` to manage flow. 11 + * Check `this.paused` to see current flow state. (`write` always returns `!this.paused`). 12 + 13 + This function is the basis for most of the synchronous streams in 14 + [event-stream](http://github.com/dominictarr/event-stream). 15 + 16 + ``` js 17 + var through = require('through') 18 + 19 + through(function write(data) { 20 + this.queue(data) //data *must* not be null 21 + }, 22 + function end () { //optional 23 + this.queue(null) 24 + }) 25 + ``` 26 + 27 + Or, can also be used _without_ buffering on pause, use `this.emit('data', data)`, 28 + and this.emit('end') 29 + 30 + ``` js 31 + var through = require('through') 32 + 33 + through(function write(data) { 34 + this.emit('data', data) 35 + //this.pause() 36 + }, 37 + function end () { //optional 38 + this.emit('end') 39 + }) 40 + ``` 41 + 42 + ## Extended Options 43 + 44 + You will probably not need these 99% of the time. 45 + 46 + ### autoDestroy=false 47 + 48 + By default, `through` emits close when the writable 49 + and readable side of the stream has ended. 50 + If that is not desired, set `autoDestroy=false`. 51 + 52 + ``` js 53 + var through = require('through') 54 + 55 + //like this 56 + var ts = through(write, end, {autoDestroy: false}) 57 + //or like this 58 + var ts = through(write, end) 59 + ts.autoDestroy = false 60 + ``` 61 + 62 + ## License 63 + 64 + MIT / Apache2
+28
node_modules/gm/node_modules/through/test/async.js
··· 1 + var from = require('from') 2 + var through = require('../') 3 + 4 + var tape = require('tape') 5 + 6 + tape('simple async example', function (t) { 7 + 8 + var n = 0, expected = [1,2,3,4,5], actual = [] 9 + from(expected) 10 + .pipe(through(function(data) { 11 + this.pause() 12 + n ++ 13 + setTimeout(function(){ 14 + console.log('pushing data', data) 15 + this.push(data) 16 + this.resume() 17 + }.bind(this), 300) 18 + })).pipe(through(function(data) { 19 + console.log('pushing data second time', data); 20 + this.push(data) 21 + })).on('data', function (d) { 22 + actual.push(d) 23 + }).on('end', function() { 24 + t.deepEqual(actual, expected) 25 + t.end() 26 + }) 27 + 28 + })
+30
node_modules/gm/node_modules/through/test/auto-destroy.js
··· 1 + var test = require('tape') 2 + var through = require('../') 3 + 4 + // must emit end before close. 5 + 6 + test('end before close', function (assert) { 7 + var ts = through() 8 + ts.autoDestroy = false 9 + var ended = false, closed = false 10 + 11 + ts.on('end', function () { 12 + assert.ok(!closed) 13 + ended = true 14 + }) 15 + ts.on('close', function () { 16 + assert.ok(ended) 17 + closed = true 18 + }) 19 + 20 + ts.write(1) 21 + ts.write(2) 22 + ts.write(3) 23 + ts.end() 24 + assert.ok(ended) 25 + assert.notOk(closed) 26 + ts.destroy() 27 + assert.ok(closed) 28 + assert.end() 29 + }) 30 +
+71
node_modules/gm/node_modules/through/test/buffering.js
··· 1 + var test = require('tape') 2 + var through = require('../') 3 + 4 + // must emit end before close. 5 + 6 + test('buffering', function(assert) { 7 + var ts = through(function (data) { 8 + this.queue(data) 9 + }, function () { 10 + this.queue(null) 11 + }) 12 + 13 + var ended = false, actual = [] 14 + 15 + ts.on('data', actual.push.bind(actual)) 16 + ts.on('end', function () { 17 + ended = true 18 + }) 19 + 20 + ts.write(1) 21 + ts.write(2) 22 + ts.write(3) 23 + assert.deepEqual(actual, [1, 2, 3]) 24 + ts.pause() 25 + ts.write(4) 26 + ts.write(5) 27 + ts.write(6) 28 + assert.deepEqual(actual, [1, 2, 3]) 29 + ts.resume() 30 + assert.deepEqual(actual, [1, 2, 3, 4, 5, 6]) 31 + ts.pause() 32 + ts.end() 33 + assert.ok(!ended) 34 + ts.resume() 35 + assert.ok(ended) 36 + assert.end() 37 + }) 38 + 39 + test('buffering has data in queue, when ends', function (assert) { 40 + 41 + /* 42 + * If stream ends while paused with data in the queue, 43 + * stream should still emit end after all data is written 44 + * on resume. 45 + */ 46 + 47 + var ts = through(function (data) { 48 + this.queue(data) 49 + }, function () { 50 + this.queue(null) 51 + }) 52 + 53 + var ended = false, actual = [] 54 + 55 + ts.on('data', actual.push.bind(actual)) 56 + ts.on('end', function () { 57 + ended = true 58 + }) 59 + 60 + ts.pause() 61 + ts.write(1) 62 + ts.write(2) 63 + ts.write(3) 64 + ts.end() 65 + assert.deepEqual(actual, [], 'no data written yet, still paused') 66 + assert.ok(!ended, 'end not emitted yet, still paused') 67 + ts.resume() 68 + assert.deepEqual(actual, [1, 2, 3], 'resumed, all data should be delivered') 69 + assert.ok(ended, 'end should be emitted once all data was delivered') 70 + assert.end(); 71 + })
+45
node_modules/gm/node_modules/through/test/end.js
··· 1 + var test = require('tape') 2 + var through = require('../') 3 + 4 + // must emit end before close. 5 + 6 + test('end before close', function (assert) { 7 + var ts = through() 8 + var ended = false, closed = false 9 + 10 + ts.on('end', function () { 11 + assert.ok(!closed) 12 + ended = true 13 + }) 14 + ts.on('close', function () { 15 + assert.ok(ended) 16 + closed = true 17 + }) 18 + 19 + ts.write(1) 20 + ts.write(2) 21 + ts.write(3) 22 + ts.end() 23 + assert.ok(ended) 24 + assert.ok(closed) 25 + assert.end() 26 + }) 27 + 28 + test('end only once', function (t) { 29 + 30 + var ts = through() 31 + var ended = false, closed = false 32 + 33 + ts.on('end', function () { 34 + t.equal(ended, false) 35 + ended = true 36 + }) 37 + 38 + ts.queue(null) 39 + ts.queue(null) 40 + ts.queue(null) 41 + 42 + ts.resume() 43 + 44 + t.end() 45 + })
+117
node_modules/gm/node_modules/through/test/index.js
··· 1 + 2 + var test = require('tape') 3 + var spec = require('stream-spec') 4 + var through = require('../') 5 + 6 + /* 7 + I'm using these two functions, and not streams and pipe 8 + so there is less to break. if this test fails it must be 9 + the implementation of _through_ 10 + */ 11 + 12 + function write(array, stream) { 13 + array = array.slice() 14 + function next() { 15 + while(array.length) 16 + if(stream.write(array.shift()) === false) 17 + return stream.once('drain', next) 18 + 19 + stream.end() 20 + } 21 + 22 + next() 23 + } 24 + 25 + function read(stream, callback) { 26 + var actual = [] 27 + stream.on('data', function (data) { 28 + actual.push(data) 29 + }) 30 + stream.once('end', function () { 31 + callback(null, actual) 32 + }) 33 + stream.once('error', function (err) { 34 + callback(err) 35 + }) 36 + } 37 + 38 + test('simple defaults', function(assert) { 39 + 40 + var l = 1000 41 + , expected = [] 42 + 43 + while(l--) expected.push(l * Math.random()) 44 + 45 + var t = through() 46 + var s = spec(t).through().pausable() 47 + 48 + read(t, function (err, actual) { 49 + assert.ifError(err) 50 + assert.deepEqual(actual, expected) 51 + assert.end() 52 + }) 53 + 54 + t.on('close', s.validate) 55 + 56 + write(expected, t) 57 + }); 58 + 59 + test('simple functions', function(assert) { 60 + 61 + var l = 1000 62 + , expected = [] 63 + 64 + while(l--) expected.push(l * Math.random()) 65 + 66 + var t = through(function (data) { 67 + this.emit('data', data*2) 68 + }) 69 + var s = spec(t).through().pausable() 70 + 71 + 72 + read(t, function (err, actual) { 73 + assert.ifError(err) 74 + assert.deepEqual(actual, expected.map(function (data) { 75 + return data*2 76 + })) 77 + assert.end() 78 + }) 79 + 80 + t.on('close', s.validate) 81 + 82 + write(expected, t) 83 + }) 84 + 85 + test('pauses', function(assert) { 86 + 87 + var l = 1000 88 + , expected = [] 89 + 90 + while(l--) expected.push(l) //Math.random()) 91 + 92 + var t = through() 93 + 94 + var s = spec(t) 95 + .through() 96 + .pausable() 97 + 98 + t.on('data', function () { 99 + if(Math.random() > 0.1) return 100 + t.pause() 101 + process.nextTick(function () { 102 + t.resume() 103 + }) 104 + }) 105 + 106 + read(t, function (err, actual) { 107 + assert.ifError(err) 108 + assert.deepEqual(actual, expected) 109 + }) 110 + 111 + t.on('close', function () { 112 + s.validate() 113 + assert.end() 114 + }) 115 + 116 + write(expected, t) 117 + })
+86
node_modules/gm/package.json
··· 1 + { 2 + "name": "gm", 3 + "description": "GraphicsMagick and ImageMagick for node.js", 4 + "version": "1.17.0", 5 + "author": { 6 + "name": "Aaron Heckmann", 7 + "email": "aaron.heckmann+github@gmail.com" 8 + }, 9 + "keywords": [ 10 + "graphics", 11 + "magick", 12 + "image", 13 + "graphicsmagick", 14 + "imagemagick", 15 + "gm", 16 + "convert", 17 + "identify", 18 + "compare" 19 + ], 20 + "engines": { 21 + "node": ">= 0.8.0" 22 + }, 23 + "bugs": { 24 + "url": "http://github.com/aheckmann/gm/issues" 25 + }, 26 + "licenses": [ 27 + { 28 + "type": "MIT", 29 + "url": "http://www.opensource.org/licenses/mit-license.php" 30 + } 31 + ], 32 + "main": "./index", 33 + "scripts": { 34 + "test": "make test-unit; make test;" 35 + }, 36 + "repository": { 37 + "type": "git", 38 + "url": "https://github.com/aheckmann/gm.git" 39 + }, 40 + "license": "MIT", 41 + "devDependencies": { 42 + "gleak": "0.4.0", 43 + "async": "~0.2.7" 44 + }, 45 + "dependencies": { 46 + "debug": "0.7.0", 47 + "array-series": "~0.1.0", 48 + "array-parallel": "~0.1.0", 49 + "through": "~2.3.1" 50 + }, 51 + "gitHead": "2fb65bac7c09ab8b09e87b791b146b82c209076e", 52 + "homepage": "https://github.com/aheckmann/gm", 53 + "_id": "gm@1.17.0", 54 + "_shasum": "27a261e0bdfee3d373d24b5a27bd249057355068", 55 + "_from": "gm@>=1.17.0 <2.0.0", 56 + "_npmVersion": "1.4.28", 57 + "_npmUser": { 58 + "name": "rwky", 59 + "email": "admin@rwky.net" 60 + }, 61 + "maintainers": [ 62 + { 63 + "name": "aaron", 64 + "email": "aaron.heckmann+github@gmail.com" 65 + }, 66 + { 67 + "name": "jongleberry", 68 + "email": "me@jongleberry.com" 69 + }, 70 + { 71 + "name": "rwky", 72 + "email": "admin@rwky.net" 73 + }, 74 + { 75 + "name": "fragphace", 76 + "email": "fragphace@gmail.com" 77 + } 78 + ], 79 + "dist": { 80 + "shasum": "27a261e0bdfee3d373d24b5a27bd249057355068", 81 + "tarball": "http://registry.npmjs.org/gm/-/gm-1.17.0.tgz" 82 + }, 83 + "directories": {}, 84 + "_resolved": "https://registry.npmjs.org/gm/-/gm-1.17.0.tgz", 85 + "readme": "ERROR: No README data found!" 86 + }
+28
node_modules/tessel-gpio-button/.npmignore
··· 1 + # Logs 2 + logs 3 + *.log 4 + 5 + # Runtime data 6 + pids 7 + *.pid 8 + *.seed 9 + 10 + # Directory for instrumented libs generated by jscoverage/JSCover 11 + lib-cov 12 + 13 + # Coverage directory used by tools like istanbul 14 + coverage 15 + 16 + # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 + .grunt 18 + 19 + # Compiled binary addons (http://nodejs.org/api/addons.html) 20 + build/Release 21 + 22 + # Dependency directory 23 + # Commenting this out is preferred by some people, see 24 + # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 + node_modules 26 + 27 + # Users Environment Variables 28 + .lock-wscript
+202
node_modules/tessel-gpio-button/LICENSE
··· 1 + Apache License 2 + Version 2.0, January 2004 3 + http://www.apache.org/licenses/ 4 + 5 + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 + 7 + 1. Definitions. 8 + 9 + "License" shall mean the terms and conditions for use, reproduction, 10 + and distribution as defined by Sections 1 through 9 of this document. 11 + 12 + "Licensor" shall mean the copyright owner or entity authorized by 13 + the copyright owner that is granting the License. 14 + 15 + "Legal Entity" shall mean the union of the acting entity and all 16 + other entities that control, are controlled by, or are under common 17 + control with that entity. For the purposes of this definition, 18 + "control" means (i) the power, direct or indirect, to cause the 19 + direction or management of such entity, whether by contract or 20 + otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 + outstanding shares, or (iii) beneficial ownership of such entity. 22 + 23 + "You" (or "Your") shall mean an individual or Legal Entity 24 + exercising permissions granted by this License. 25 + 26 + "Source" form shall mean the preferred form for making modifications, 27 + including but not limited to software source code, documentation 28 + source, and configuration files. 29 + 30 + "Object" form shall mean any form resulting from mechanical 31 + transformation or translation of a Source form, including but 32 + not limited to compiled object code, generated documentation, 33 + and conversions to other media types. 34 + 35 + "Work" shall mean the work of authorship, whether in Source or 36 + Object form, made available under the License, as indicated by a 37 + copyright notice that is included in or attached to the work 38 + (an example is provided in the Appendix below). 39 + 40 + "Derivative Works" shall mean any work, whether in Source or Object 41 + form, that is based on (or derived from) the Work and for which the 42 + editorial revisions, annotations, elaborations, or other modifications 43 + represent, as a whole, an original work of authorship. For the purposes 44 + of this License, Derivative Works shall not include works that remain 45 + separable from, or merely link (or bind by name) to the interfaces of, 46 + the Work and Derivative Works thereof. 47 + 48 + "Contribution" shall mean any work of authorship, including 49 + the original version of the Work and any modifications or additions 50 + to that Work or Derivative Works thereof, that is intentionally 51 + submitted to Licensor for inclusion in the Work by the copyright owner 52 + or by an individual or Legal Entity authorized to submit on behalf of 53 + the copyright owner. For the purposes of this definition, "submitted" 54 + means any form of electronic, verbal, or written communication sent 55 + to the Licensor or its representatives, including but not limited to 56 + communication on electronic mailing lists, source code control systems, 57 + and issue tracking systems that are managed by, or on behalf of, the 58 + Licensor for the purpose of discussing and improving the Work, but 59 + excluding communication that is conspicuously marked or otherwise 60 + designated in writing by the copyright owner as "Not a Contribution." 61 + 62 + "Contributor" shall mean Licensor and any individual or Legal Entity 63 + on behalf of whom a Contribution has been received by Licensor and 64 + subsequently incorporated within the Work. 65 + 66 + 2. Grant of Copyright License. Subject to the terms and conditions of 67 + this License, each Contributor hereby grants to You a perpetual, 68 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 + copyright license to reproduce, prepare Derivative Works of, 70 + publicly display, publicly perform, sublicense, and distribute the 71 + Work and such Derivative Works in Source or Object form. 72 + 73 + 3. Grant of Patent License. Subject to the terms and conditions of 74 + this License, each Contributor hereby grants to You a perpetual, 75 + worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 + (except as stated in this section) patent license to make, have made, 77 + use, offer to sell, sell, import, and otherwise transfer the Work, 78 + where such license applies only to those patent claims licensable 79 + by such Contributor that are necessarily infringed by their 80 + Contribution(s) alone or by combination of their Contribution(s) 81 + with the Work to which such Contribution(s) was submitted. If You 82 + institute patent litigation against any entity (including a 83 + cross-claim or counterclaim in a lawsuit) alleging that the Work 84 + or a Contribution incorporated within the Work constitutes direct 85 + or contributory patent infringement, then any patent licenses 86 + granted to You under this License for that Work shall terminate 87 + as of the date such litigation is filed. 88 + 89 + 4. Redistribution. You may reproduce and distribute copies of the 90 + Work or Derivative Works thereof in any medium, with or without 91 + modifications, and in Source or Object form, provided that You 92 + meet the following conditions: 93 + 94 + (a) You must give any other recipients of the Work or 95 + Derivative Works a copy of this License; and 96 + 97 + (b) You must cause any modified files to carry prominent notices 98 + stating that You changed the files; and 99 + 100 + (c) You must retain, in the Source form of any Derivative Works 101 + that You distribute, all copyright, patent, trademark, and 102 + attribution notices from the Source form of the Work, 103 + excluding those notices that do not pertain to any part of 104 + the Derivative Works; and 105 + 106 + (d) If the Work includes a "NOTICE" text file as part of its 107 + distribution, then any Derivative Works that You distribute must 108 + include a readable copy of the attribution notices contained 109 + within such NOTICE file, excluding those notices that do not 110 + pertain to any part of the Derivative Works, in at least one 111 + of the following places: within a NOTICE text file distributed 112 + as part of the Derivative Works; within the Source form or 113 + documentation, if provided along with the Derivative Works; or, 114 + within a display generated by the Derivative Works, if and 115 + wherever such third-party notices normally appear. The contents 116 + of the NOTICE file are for informational purposes only and 117 + do not modify the License. You may add Your own attribution 118 + notices within Derivative Works that You distribute, alongside 119 + or as an addendum to the NOTICE text from the Work, provided 120 + that such additional attribution notices cannot be construed 121 + as modifying the License. 122 + 123 + You may add Your own copyright statement to Your modifications and 124 + may provide additional or different license terms and conditions 125 + for use, reproduction, or distribution of Your modifications, or 126 + for any such Derivative Works as a whole, provided Your use, 127 + reproduction, and distribution of the Work otherwise complies with 128 + the conditions stated in this License. 129 + 130 + 5. Submission of Contributions. Unless You explicitly state otherwise, 131 + any Contribution intentionally submitted for inclusion in the Work 132 + by You to the Licensor shall be under the terms and conditions of 133 + this License, without any additional terms or conditions. 134 + Notwithstanding the above, nothing herein shall supersede or modify 135 + the terms of any separate license agreement you may have executed 136 + with Licensor regarding such Contributions. 137 + 138 + 6. Trademarks. This License does not grant permission to use the trade 139 + names, trademarks, service marks, or product names of the Licensor, 140 + except as required for reasonable and customary use in describing the 141 + origin of the Work and reproducing the content of the NOTICE file. 142 + 143 + 7. Disclaimer of Warranty. Unless required by applicable law or 144 + agreed to in writing, Licensor provides the Work (and each 145 + Contributor provides its Contributions) on an "AS IS" BASIS, 146 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 + implied, including, without limitation, any warranties or conditions 148 + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 + PARTICULAR PURPOSE. You are solely responsible for determining the 150 + appropriateness of using or redistributing the Work and assume any 151 + risks associated with Your exercise of permissions under this License. 152 + 153 + 8. Limitation of Liability. In no event and under no legal theory, 154 + whether in tort (including negligence), contract, or otherwise, 155 + unless required by applicable law (such as deliberate and grossly 156 + negligent acts) or agreed to in writing, shall any Contributor be 157 + liable to You for damages, including any direct, indirect, special, 158 + incidental, or consequential damages of any character arising as a 159 + result of this License or out of the use or inability to use the 160 + Work (including but not limited to damages for loss of goodwill, 161 + work stoppage, computer failure or malfunction, or any and all 162 + other commercial damages or losses), even if such Contributor 163 + has been advised of the possibility of such damages. 164 + 165 + 9. Accepting Warranty or Additional Liability. While redistributing 166 + the Work or Derivative Works thereof, You may choose to offer, 167 + and charge a fee for, acceptance of support, warranty, indemnity, 168 + or other liability obligations and/or rights consistent with this 169 + License. However, in accepting such obligations, You may act only 170 + on Your own behalf and on Your sole responsibility, not on behalf 171 + of any other Contributor, and only if You agree to indemnify, 172 + defend, and hold each Contributor harmless for any liability 173 + incurred by, or claims asserted against, such Contributor by reason 174 + of your accepting any such warranty or additional liability. 175 + 176 + END OF TERMS AND CONDITIONS 177 + 178 + APPENDIX: How to apply the Apache License to your work. 179 + 180 + To apply the Apache License to your work, attach the following 181 + boilerplate notice, with the fields enclosed by brackets "{}" 182 + replaced with your own identifying information. (Don't include 183 + the brackets!) The text should be enclosed in the appropriate 184 + comment syntax for the file format. We also recommend that a 185 + file or class name and description of purpose be included on the 186 + same "printed page" as the copyright notice for easier 187 + identification within third-party archives. 188 + 189 + Copyright {yyyy} {name of copyright owner} 190 + 191 + Licensed under the Apache License, Version 2.0 (the "License"); 192 + you may not use this file except in compliance with the License. 193 + You may obtain a copy of the License at 194 + 195 + http://www.apache.org/licenses/LICENSE-2.0 196 + 197 + Unless required by applicable law or agreed to in writing, software 198 + distributed under the License is distributed on an "AS IS" BASIS, 199 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 + See the License for the specific language governing permissions and 201 + limitations under the License. 202 +
+209
node_modules/tessel-gpio-button/README.md
··· 1 + tessel-gpio-button 2 + ============= 3 + 4 + A button on Tessel's GPIO bank. 5 + 6 + * [Quick start](https://github.com/Frijol/tessel-button#quick-start-i-just-want-a-button) 7 + * [Theory of buttons](https://github.com/Frijol/tessel-button#why-add-a-button-over-the-gpio) 8 + * [Multiple buttons](https://github.com/Frijol/tessel-button#multiple-buttons) 9 + 10 + ## Quick start: I just want a button. 11 + 12 + Your button should have two wires sticking out of it. Plug in one side to ground, and the other to pin G3. 13 + 14 + ![](https://lh5.googleusercontent.com/-VFXEUYqlb2w/VCHwX6JIsnI/AAAAAAAAKak/XS4eqXJ5RmM/w913-h514-no/20140923_151215.jpg) 15 + 16 + Install: 17 + 18 + ```sh 19 + npm install tessel-gpio-button 20 + ``` 21 + Use: 22 + 23 + ```js 24 + // examples/button.js 25 + // Count button presses 26 + 27 + var tessel = require('tessel'); 28 + var buttonLib = require('../'); 29 + var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']); 30 + 31 + var i = 0; 32 + 33 + myButton.on('ready', function () { 34 + myButton.on('press', function () { 35 + i++; 36 + console.log('Press', i); 37 + }); 38 + 39 + myButton.on('release', function () { 40 + i++; 41 + console.log('Release', i); 42 + }); 43 + }); 44 + ``` 45 + 46 + Congratulations, you now have a button! 47 + 48 + ## How it works, and why 49 + 50 + ### Why add a button over the GPIO? 51 + Buttons are a nice, easy way to make your project interactive. Tessel comes with [API access to the Config button on the board](https://tessel.io/docs/hardwareAPI#buttons). For many use cases, this is enough. But perhaps you want more buttons, or buttons with a certain look or feel. That's where this tutorial will come in handy. 52 + 53 + ### What is a button, in terms of circuits? 54 + Electrically, a button is nothing more than a switch. One wire goes into the button; one wire comes out. When the button is pressed, the wires are connected. When not pressed, the wires are not connected. 55 + 56 + ### Making a button talk to Tessel 57 + Tessel communicates over 3.3V. That means that its [pins](https://tessel.io/docs/hardwareAPI#pins) operate between 0V and 3.3V. For a digital pin, 3.3V evaluates to "high" or 1 (truthy), and 0V evaluates to "low" or 0 (falsy). 58 + 59 + Tessel has six digital pins along the GPIO bank, marked G1-G6. Each of these pins is pulled high (3.3V) by default. In order to change the state of these pins from high to low, all you have to do is connect a digital pin to ground (GND). 60 + 61 + If you have a wire, you can try it out– plug in a wire (ideally black, for ground) in to the GND pin on Tessel's GPIO bank. While running the code below, try sticking the other end of the wire into G3: 62 + 63 + ![](https://lh4.googleusercontent.com/-sgF_HmYkKLs/VCIGYOqdtcI/AAAAAAAAKdY/8PmTATEWaII/w913-h514-no/20140923_164633.jpg) 64 + 65 + ```js 66 + // tutorial/polling-read.js 67 + // Read Tessel's GPIO pin G3 every 100ms 68 + 69 + var tessel = require('tessel'); 70 + var myPin = tessel.port['GPIO'].pin['G3']; 71 + 72 + setInterval(function readPin () { 73 + console.log(myPin.read()); 74 + }, 100); 75 + ``` 76 + 77 + You should see a stream of ones while the wire is not plugged in, and a stream of zeroes when it is plugged in. 78 + 79 + Okay, now let's try it with a button. It's basically the same thing. Unplug your Tessel (it's bad practice to mess around with wires while your Tessel is powered). Your button should have two wires sticking out of it. One of them should plug into GND; the other into pin G3. 80 + 81 + ![](https://lh5.googleusercontent.com/-VFXEUYqlb2w/VCHwX6JIsnI/AAAAAAAAKak/XS4eqXJ5RmM/w913-h514-no/20140923_151215.jpg) 82 + 83 + Run the same code, and try pressing the button. You should see zeroes when the button is pressed, and ones when the button is not pressed. 84 + 85 + ### Button events 86 + 87 + Tessel has [events](https://tessel.io/docs/hardwareAPI#api-pin-on-type-callback-time-type) for its pins. It fires an event each for `rise`, `fall`, and `change`. 88 + 89 + Since the signal falls to low when the button is pressed, and rises to high when the button is released, it seems like you should be able to just use `pin.on(fall, function () {})`. Let's try it and see what happens: 90 + 91 + ```js 92 + // tutorial/simple-event.js 93 + // Logs a message each time the pin falls 94 + 95 + var tessel = require('tessel'); 96 + var button = tessel.port['GPIO'].pin['G3']; 97 + 98 + var i = 0 99 + 100 + button.on('fall', function buttonPress () { 101 + i++; 102 + console.log('You pressed the button!', i); 103 + }); 104 + ``` 105 + 106 + If you have a really nice button, this might just work. However, if you have a cheap button like mine, the `fall` event will be emitted more than once per button press. This is because you are dealing with a mechanical system, and the electrical contact is actually bouncing a little bit on contact and messing up the signal. You can read about this phenomenon [here](http://en.wikipedia.org/wiki/Switch#Contact_bounce). 107 + 108 + ![](http://upload.wikimedia.org/wikipedia/commons/a/ac/Bouncy_Switch.png) 109 + 110 + In order to correct this problem, we need to do some software debouncing. 111 + 112 + Debouncing can be a very complicated problem if you need the ability to read the button several times a second (read a few approaches [here](http://www.embedded.com/electronics-blogs/break-points/4024981/My-favorite-software-debouncers)). However, for most applications, you can simply reduce the rate at which your events can fire. 113 + 114 + Let's try adding a delay timer to the event: 115 + 116 + ```js 117 + // tutorial/debounced-event.js 118 + // Logs a message at button presses that are sufficiently spaced 119 + 120 + var tessel = require('tessel'); 121 + var button = tessel.port['GPIO'].pin['G3']; 122 + 123 + var delay = 500; // Let's try every 500ms 124 + var ready = true; 125 + 126 + var i = 0 127 + 128 + button.on('fall', function () { 129 + if(ready) { 130 + buttonPress(); 131 + } 132 + }); 133 + 134 + function buttonPress () { 135 + i++; 136 + console.log('You pressed the button!', i); 137 + 138 + // Set a delay timer 139 + ready = false; 140 + setTimeout(function () { 141 + ready = true; 142 + }, delay); 143 + } 144 + ``` 145 + 146 + 500ms worked well for my button, but feel free to adjust the delay and see how long it takes for your button to stop bouncing. 147 + 148 + ### Wrapping the events 149 + For the sake of consistency, I've set up index.js of this folder [the same way we set up every module](http://blog.technical.io/post/94084496782/making-a-tessel-style-library-for-third-party-hardware), to emit an event on `press`. `press` and `release` are individually easy, but harder to have both due to our simple debouncing method. 150 + 151 + I've done something rather interesting to get around this in index.js; feel free to check it out (and PRs welcome if you can think of a better way). 152 + 153 + Here's some example code requiring index (or just `npm install tessel-gpio-button`): 154 + 155 + ```js 156 + // examples/button.js 157 + // Count button presses 158 + 159 + var tessel = require('tessel'); 160 + var buttonLib = require('../'); 161 + var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']); 162 + 163 + var i = 0; 164 + 165 + myButton.on('ready', function () { 166 + myButton.on('press', function () { 167 + i++; 168 + console.log('Press', i); 169 + }); 170 + 171 + myButton.on('release', function () { 172 + i++; 173 + console.log('Release', i); 174 + }); 175 + }); 176 + ``` 177 + 178 + ### Multiple buttons 179 + Say you want more than one button. Maybe you're making a game controller, or a musical instrument or something. So you have several buttons to connect. 180 + 181 + All you have to do is connect one side of each to ground, and the other side to a different digital pin. 182 + 183 + ![](https://lh6.googleusercontent.com/-Cr5us5zJ9SA/VCIBTDnpmqI/AAAAAAAAKcw/O-NE2P8AJOE/w913-h514-no/20140923_162433.jpg) 184 + 185 + Then make different instances for each button. Like this: 186 + 187 + ```js 188 + // examples/two-buttons.js 189 + // Log button presses from two different buttons 190 + 191 + var tessel = require('tessel'); 192 + var buttonLib = require('tessel-gpio-button'); 193 + 194 + var button1 = buttonLib.use(tessel.port['GPIO'].pin['G3']); 195 + var button2 = buttonLib.use(tessel.port['GPIO'].pin['G2']); 196 + 197 + button1.on('press', function () { 198 + console.log('Pressing button 1.'); 199 + }); 200 + 201 + button2.on('press', function () { 202 + console.log('Pressing button 2.'); 203 + }); 204 + ``` 205 + Pressing the different buttons will give you different messages. 206 + 207 + Note that I used a breadboard to connect several buttons to the same ground. If you're interested/want to know more about breadboards, [this](http://www.instructables.com/id/Breadboard-How-To/) is a really good place to start. 208 + 209 + That's all! Enjoy.
+20
node_modules/tessel-gpio-button/examples/button.js
··· 1 + // examples/button.js 2 + // Count button presses 3 + 4 + var tessel = require('tessel'); 5 + var buttonLib = require('../'); 6 + var myButton = buttonLib.use(tessel.port['GPIO'].pin['G3']); 7 + 8 + var i = 0; 9 + 10 + myButton.on('ready', function () { 11 + myButton.on('press', function () { 12 + i++; 13 + console.log('Press', i); 14 + }); 15 + 16 + myButton.on('release', function () { 17 + i++; 18 + console.log('Release', i); 19 + }); 20 + });
+16
node_modules/tessel-gpio-button/examples/two-buttons.js
··· 1 + // examples/two-buttons.js 2 + // Log button presses from two different buttons 3 + 4 + var tessel = require('tessel'); 5 + var buttonLib = require('../'); 6 + 7 + var button1 = buttonLib.use(tessel.port['GPIO'].pin['G3']); 8 + var button2 = buttonLib.use(tessel.port['GPIO'].pin['G2']); 9 + 10 + button1.on('press', function () { 11 + console.log('Pressing button 1.'); 12 + }); 13 + 14 + button2.on('press', function () { 15 + console.log('Pressing button 2.'); 16 + });
+89
node_modules/tessel-gpio-button/index.js
··· 1 + // Any dependencies, notably the event emitter utility 2 + var util = require('util'); 3 + var EventEmitter = require('events').EventEmitter; 4 + 5 + // Constructor function to instantiate the hardware object 6 + function Button (hardware, callback) { 7 + var self = this; 8 + 9 + // Check to ensure proper hardware has been passed in 10 + if (typeof hardware.pin != 'number') { 11 + // Pin not specified 12 + var error = new Error("Specify a pin, e.g. tessel.port['GPIO'].pin['G3']"); 13 + self.emit('error', error); 14 + if(callback) { 15 + callback(error); 16 + } 17 + } else if ([16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 34, 35, 36, 37, 38, 39].indexOf(hardware.pin) < 0) { 18 + // Not a digital pin 19 + var error = new Error('Specified pin is not a digital pin: ' + hardware.pin); 20 + self.emit('error', error); 21 + if(callback) { 22 + callback(error); 23 + } 24 + } 25 + 26 + // Set hardware connection of the object 27 + self.hardware = hardware; 28 + 29 + // Object properties 30 + self.delay = 100; 31 + self.pressed = false; 32 + 33 + // Begin listening for events 34 + self.hardware.on('fall', function () { 35 + self._press(); 36 + }); 37 + 38 + self.hardware.on('rise', function () { 39 + self._release(); 40 + }); 41 + 42 + // Make sure the events get emitted, even if late 43 + setInterval(function () { 44 + if(!self.hardware.read()) { 45 + self._press(); 46 + } else { 47 + self._release(); 48 + } 49 + }, self.delay); 50 + 51 + // Emit the ready event when everything is set up 52 + setImmediate(function emitReady() { 53 + self.emit('ready'); 54 + }); 55 + // Call the callback with object 56 + if (callback) { 57 + callback(null, self); 58 + } 59 + } 60 + 61 + // Inherit event emission 62 + util.inherits(Button, EventEmitter); 63 + 64 + Button.prototype._press = function () { 65 + var self = this; 66 + 67 + if(!self.pressed) { 68 + self.emit('press'); 69 + self.pressed = true; 70 + } 71 + } 72 + 73 + Button.prototype._release = function () { 74 + var self = this; 75 + 76 + if(self.pressed) { 77 + self.emit('release'); 78 + self.pressed = false; 79 + } 80 + } 81 + 82 + // Use function which calls the constructor 83 + function use (hardware, callback) { 84 + return new Button(hardware, callback); 85 + } 86 + 87 + // Export functions 88 + exports.Button = Button; 89 + exports.use = use;
+50
node_modules/tessel-gpio-button/package.json
··· 1 + { 2 + "name": "tessel-gpio-button", 3 + "version": "1.1.0", 4 + "description": "\"A button on Tessel's GPIO\"", 5 + "main": "index.js", 6 + "scripts": { 7 + "test": "echo \"Error: no test specified\" && exit 1" 8 + }, 9 + "repository": { 10 + "type": "git", 11 + "url": "https://github.com/Frijol/tessel-button.git" 12 + }, 13 + "keywords": [ 14 + "tessel", 15 + "button" 16 + ], 17 + "author": { 18 + "name": "Kelsey Breseman" 19 + }, 20 + "license": "Apache 2.0", 21 + "bugs": { 22 + "url": "https://github.com/Frijol/tessel-button/issues" 23 + }, 24 + "hardware": { 25 + "./examples": false, 26 + "./tutorial": false 27 + }, 28 + "homepage": "https://github.com/Frijol/tessel-button", 29 + "gitHead": "71624918cf4530c9191b9e73f668edd65faf55a2", 30 + "_id": "tessel-gpio-button@1.1.0", 31 + "_shasum": "aa1729201b546185c3d281394431db3a4d83d8fc", 32 + "_from": "tessel-gpio-button@*", 33 + "_npmVersion": "1.4.23", 34 + "_npmUser": { 35 + "name": "frijol", 36 + "email": "ifoundthemeaningoflife@gmail.com" 37 + }, 38 + "maintainers": [ 39 + { 40 + "name": "frijol", 41 + "email": "ifoundthemeaningoflife@gmail.com" 42 + } 43 + ], 44 + "dist": { 45 + "shasum": "aa1729201b546185c3d281394431db3a4d83d8fc", 46 + "tarball": "http://registry.npmjs.org/tessel-gpio-button/-/tessel-gpio-button-1.1.0.tgz" 47 + }, 48 + "directories": {}, 49 + "_resolved": "https://registry.npmjs.org/tessel-gpio-button/-/tessel-gpio-button-1.1.0.tgz" 50 + }
+27
node_modules/tessel-gpio-button/tutorial/debounced-event.js
··· 1 + // debounced-event.js 2 + // Logs a message at button presses that are sufficiently spaced 3 + 4 + var tessel = require('tessel'); 5 + var button = tessel.port['GPIO'].pin['G3']; 6 + 7 + var delay = 500; // Let's try every 500ms 8 + var ready = true; 9 + 10 + var i = 0 11 + 12 + button.on('fall', function () { 13 + if(ready) { 14 + buttonPress(); 15 + } 16 + }); 17 + 18 + function buttonPress () { 19 + i++; 20 + console.log('You pressed the button!', i); 21 + 22 + // Set a delay timer 23 + ready = false; 24 + setTimeout(function () { 25 + ready = true; 26 + }, delay); 27 + }
+8
node_modules/tessel-gpio-button/tutorial/polling-read.js
··· 1 + // Read Tessel's GPIO pin G3 every 100ms 2 + 3 + var tessel = require('tessel'); 4 + var myPin = tessel.port['GPIO'].pin['G3']; 5 + 6 + setInterval(function readPin () { 7 + console.log(myPin.read()); 8 + }, 100);
+12
node_modules/tessel-gpio-button/tutorial/simple-event.js
··· 1 + // simple-event.js 2 + // Logs a message each time the pin falls 3 + 4 + var tessel = require('tessel'); 5 + var button = tessel.port['GPIO'].pin['G3']; 6 + 7 + var i = 0 8 + 9 + button.on('fall', function buttonPress () { 10 + i++; 11 + console.log('You pressed the button!', i); 12 + });
+1
out.png
··· 1 + ���rӛ��-
+3 -1
package.json
··· 11 11 "license": "ISC", 12 12 "dependencies": { 13 13 "accel-mma84": "^0.2.3", 14 - "tessel": "^0.3.19" 14 + "gm": "^1.17.0", 15 + "tessel": "^0.3.19", 16 + "tessel-gpio-button": "^1.1.0" 15 17 } 16 18 }
sample.png

This is a binary file and will not be displayed.

+14 -2
webgl.html
··· 2 2 3 3 <head> 4 4 <link rel="stylesheet" type="text/css" href="assets/css/style.css"> 5 - <script src="https://cdn.socket.io/socket.io-1.3.0.js"></script> 5 + <script src="assets/js/socket.io-1.3.0.js"></script> 6 6 <script type="text/javascript" src="assets/js/three.min.js"></script> 7 + <script type="text/javascript" src="assets/js/THREEx.screenshot.js"></script> 7 8 <!--script type="text/javascript" src="http://www.html5canvastutorials.com/libraries/three.min.js"></script--> 8 9 9 10 </head> 10 11 11 12 <body> 12 - <script type="text/javascript" src="assets/js/gl.js"></script> 13 + <!-- <div class="imageWrapper"> 14 + <img src="assets/images/cropData.png" id="submittedSC" class="submittedSC"> 15 + <img src="assets/images/sample.png" class="sampleSC"> 16 + </div> --> 17 + 18 + <div class="absoluteWrapper"> 19 + <img src="" id="submittedSC" class="submittedSC invisible"> 20 + <img src="assets/images/sample.png" class="sampleSC"> 21 + </div> 22 + 23 + <!-- <button name="amDone" onclick="saveScreenShot()">I'm Done</button> --> 24 + <script type="text/javascript" src="assets/js/gl.js"></script> 13 25 </body> 14 26 15 27 </html>