diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..397b4a7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.log
diff --git a/.gitignore.swp b/.gitignore.swp
new file mode 100644
index 0000000..4323df8
Binary files /dev/null and b/.gitignore.swp differ
diff --git a/myapp/app.js b/myapp/app.js
index 08d51d7..f28d5af 100644
--- a/myapp/app.js
+++ b/myapp/app.js
@@ -10,6 +10,16 @@ var session = require('express-session');
var passport = require('passport')
, FacebookStrategy = require('passport-facebook').Strategy;
+var winston = require('winston');
+
+winston.log('info', 'Hello distributed log files!');
+winston.info('Hello again distributed logs');
+
+winston.level = 'debug';
+winston.log('debug', 'Now my debug messages are written to console!');
+
+winston.add(winston.transports.File, { filename: 'booklog3-info.log' });
+winston.remove(winston.transports.Console);
var routes = require('./routes/index');
var users = require('./routes/users');
@@ -18,10 +28,10 @@ var account = require('./routes/account');
mongoose.connect('mongodb://booklog3:123456@ds047622.mongolab.com:47622/booklog3');
mongoose.connection.on('error', function(){
- console.log('MongoDB: connect error.');
+ winston.log('info', 'MongoDB: connect error.');
});
mongoose.connection.on('open', function(){
- console.log('MongoDB: connected.');
+ winston.log('info', 'MongoDB: connected.');
});
var Schema = mongoose.Schema;
@@ -114,6 +124,7 @@ app.get('/auth/facebook',
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/auth/facebook' }),
function(req, res){
+// winston.log('info', 'Pass FB auth!');
res.redirect('/1/post');
});
diff --git a/myapp/node_modules/winston/.jshintrc b/myapp/node_modules/winston/.jshintrc
new file mode 100755
index 0000000..af0e1fc
--- /dev/null
+++ b/myapp/node_modules/winston/.jshintrc
@@ -0,0 +1,54 @@
+{
+ "passfail": false,
+ "maxerr": 100,
+
+ "browser": false,
+ "node": true,
+ "rhino": false,
+ "couch": true,
+ "wsh": true,
+ "jquery": true,
+ "prototypejs": false,
+ "mootools": false,
+ "dojo": false,
+
+ "devel": true,
+
+ "es5": true,
+ "strict": false,
+ "globalstrict": false,
+
+ "asi": false,
+ "lastsemic": true,
+ "laxbreak": true,
+ "laxcomma": false,
+ "bitwise": false,
+ "boss": false,
+ "curly": true,
+ "eqeqeq": true,
+ "eqnull": false,
+ "evil": false,
+ "expr": false,
+ "forin": false,
+ "immed": false,
+ "latedef": false,
+ "loopfunc": true,
+ "noarg": true,
+ "regexp": true,
+ "regexdash": false,
+ "scripturl": true,
+ "shadow": true,
+ "supernew": true,
+ "undef": true,
+
+ "newcap": true,
+ "noempty": true,
+ "nonew": true,
+ "nomen": false,
+ "onevar": true,
+ "plusplus": false,
+ "sub": true,
+ "trailing": true,
+ "white": false,
+ "indent": 2
+}
\ No newline at end of file
diff --git a/myapp/node_modules/winston/.npmignore b/myapp/node_modules/winston/.npmignore
new file mode 100644
index 0000000..0774416
--- /dev/null
+++ b/myapp/node_modules/winston/.npmignore
@@ -0,0 +1,6 @@
+test/*.log
+test/fixtures/*.json
+test/fixtures/logs/*.log*
+node_modules/
+node_modules/*
+npm-debug.log
\ No newline at end of file
diff --git a/myapp/node_modules/winston/.travis.yml b/myapp/node_modules/winston/.travis.yml
new file mode 100644
index 0000000..50a4b78
--- /dev/null
+++ b/myapp/node_modules/winston/.travis.yml
@@ -0,0 +1,21 @@
+language: node_js
+node_js:
+ - "0.8"
+ - "0.10"
+ - "0.12"
+
+before_install:
+ - travis_retry npm install -g npm@2.5.1
+ - travis_retry npm install
+
+script:
+ - npm test
+
+matrix:
+ allow_failures:
+ - node_js: "0.12"
+
+notifications:
+ email:
+ - travis@nodejitsu.com
+ irc: "irc.freenode.org#nodejitsu"
diff --git a/myapp/node_modules/winston/CHANGELOG.md b/myapp/node_modules/winston/CHANGELOG.md
new file mode 100644
index 0000000..17d2ce6
--- /dev/null
+++ b/myapp/node_modules/winston/CHANGELOG.md
@@ -0,0 +1,100 @@
+## v1.0.0 / 2015-04-07
+
+### Breaking Changes
+ * [#587](https://github.com/winstonjs/winston/pull/587) Do not extend `String` prototypes as a side effect of using `colors`. (`kenperkins`)
+ * [#581](https://github.com/winstonjs/winston/pull/581) File transports now emit `error` on error of the underlying streams after `maxRetries` attempts. (`ambbell`).
+ * [#583](https://github.com/winstonjs/winston/pull/583), [92729a](https://github.com/winstonjs/winston/commit/92729a68d71d07715501c35d94d2ac06ac03ca08) Use `os.EOL` for all file writing by default. (`Mik13`, `indexzero`)
+ * [#532](https://github.com/winstonjs/winston/pull/532) Delete logger instance from `Container` when `close` event is emitted. (`snater`)
+ * [#380](https://github.com/winstonjs/winston/pull/380) Rename `duration` to `durationMs`, which is now a number a not a string ending in `ms`. (`neoziro`)
+ * [#253](https://github.com/winstonjs/winston/pull/253) Do not set a default level. When `level` is falsey on any `Transport` instance, any `Logger` instance uses the configured level (instead of the Transport level) (`jstamerj`).
+
+### Other changes
+
+ * [b83de62](https://github.com/winstonjs/winston/commit/b83de62) Fix rendering of stack traces.
+ * [c899cc](https://github.com/winstonjs/winston/commit/c899cc1f0719e49b26ec933e0fa263578168ea3b) Update documentation (Fixes [#549](https://github.com/winstonjs/winston/issues/549))
+ * [#551](https://github.com/winstonjs/winston/pull/551) Filter metadata along with messages
+ * [#578](https://github.com/winstonjs/winston/pull/578) Fixes minor issue with `maxFiles` in `File` transport (Fixes [#556](https://github.com/winstonjs/winston/issues/556)).
+ * [#560](https://github.com/winstonjs/winston/pull/560) Added `showLevel` support to `File` transport.
+ * [#558](https://github.com/winstonjs/winston/pull/558) Added `showLevel` support to `Console` transport.
+
+## v0.9.0 / 2015-02-03
+
+ * [#496](https://github.com/flatiron/winston/pull/496) Updated default option handling for CLI (`oojacoboo`).
+ * [f37634b](https://github.com/flatiron/winston/commit/f37634b) [dist] Only support `node >= 0.8.0`. (`indexzero`)
+ * [91a1e90](https://github.com/flatiron/winston/commit/91a1e90), [50163a0](https://github.com/flatiron/winston/commit/50163a0) Fix #84 [Enable a better unhandled exception experience](https://github.com/flatiron/winston/issues/84) (`samz`)
+ * [8b5fbcd](https://github.com/flatiron/winston/commit/8b5fbcd) #448 Added tailable option to file transport which rolls files backwards instead of creating incrementing appends. Implements #268 (`neouser99`)
+ * [a34f7d2](https://github.com/flatiron/winston/commit/a34f7d2) Custom log formatter functionality were added. (`Melnyk Andii`)
+ * [4c08191](https://github.com/flatiron/winston/commit/4c08191) Added showLevel flag to common.js, file*, memory and console transports. (`Tony Germaneri`)
+ * [64ed8e0](https://github.com/flatiron/winston/commit/64ed8e0) Adding custom pretty print function test. (`Alberto Pose`)
+ * [3872dfb](https://github.com/flatiron/winston/commit/3872dfb) Adding prettyPrint parameter as function example. (`Alberto Pose`)
+ * [2b96eee](https://github.com/flatiron/winston/commit/2b96eee) implemented filters #526 (`Chris Oloff`)
+ * [72273b1](https://github.com/flatiron/winston/commit/72273b1) Added the options to colorize only the level, only the message or all. Default behavior is kept. Using true will only colorize the level and false will not colorize anything. (`Michiel De Mey`)
+ * [178e8a6](https://github.com/flatiron/winston/commit/178e8a6) Prevent message from meta input being overwritten (`Leonard Martin`)
+ * [270be86](https://github.com/flatiron/winston/commit/270be86) [api] Allow for transports to be removed by their string name [test fix] Add test coverage for multiple transports of the same type added in #187. [doc] Document using multiple transports of the same type (`indexzero`)
+ * [0a848fa](https://github.com/flatiron/winston/commit/0a848fa) Add depth options for meta pretty print (`Loïc Mahieu`)
+ * [106b670](https://github.com/flatiron/winston/commit/106b670) Allow debug messages to be sent to stdout (`John Frizelle`)
+ * [ad2d5e1](https://github.com/flatiron/winston/commit/ad2d5e1) [fix] Handle Error instances in a sane way since their properties are non-enumerable __by default.__ Fixes #280. (`indexzero`)
+ * [5109dd0](https://github.com/flatiron/winston/commit/5109dd0) [fix] Have a default `until` before a default `from`. Fixes #478. (`indexzero`)
+ * [d761960](https://github.com/flatiron/winston/commit/d761960) Fix logging regular expression objects (`Chasen Le Hara`)
+ * [2632eb8](https://github.com/flatiron/winston/commit/2632eb8) Add option for EOL chars on FileTransport (`José F. Romaniello`)
+ * [bdecce7](https://github.com/flatiron/winston/commit/bdecce7) Remove duplicate logstash option (`José F. Romaniello`)
+ * [7a01f9a](https://github.com/flatiron/winston/commit/7a01f9a) Update declaration block according to project's style guide (`Ricardo Torres`)
+ * [ae27a19](https://github.com/flatiron/winston/commit/ae27a19) Fixes #306: Can't set customlevels to my loggers (RangeError: Maximum call stack size exceeded) (`Alberto Pose`)
+ * [1ba4f51](https://github.com/flatiron/winston/commit/1ba4f51) [fix] Call `res.resume()` in HttpTransport to get around known issues in streams2. (`indexzero`)
+ * [39e0258](https://github.com/flatiron/winston/commit/39e0258) Updated default option handling for CLI (`Jacob Thomason`)
+ * [8252801](https://github.com/flatiron/winston/commit/8252801) Added logstash support to console transport (`Ramon Snir`)
+ * [18aa301](https://github.com/flatiron/winston/commit/18aa301) Module isStream should be isstream (`Michael Neil`)
+ * [2f5f296](https://github.com/flatiron/winston/commit/2f5f296) options.prettyPrint can now be a function (`Matt Zukowski`)
+ * [a87a876](https://github.com/flatiron/winston/commit/a87a876) Adding rotationFormat prop to file.js (`orcaman`)
+ * [ff187f4](https://github.com/flatiron/winston/commit/ff187f4) Allow custom exception level (`jupiter`)
+
+## 0.8.3 / 2014-11-04
+
+* [fix lowercase issue (`jcrugzz`)](https://github.com/flatiron/winston/commit/b3ffaa10b5fe9d2a510af5348cf4fb3870534123)
+
+## 0.8.2 / 2014-11-04
+
+* [Full fix for #296 with proper streams2 detection with `isstream` for file transport (`jcrugzz`)](https://github.com/flatiron/winston/commit/5c4bd4191468570e46805ed399cad63cfb1856cc)
+* [Add isstream module (`jcrugzz`)](https://github.com/flatiron/winston/commit/498b216d0199aebaef72ee4d8659a00fb737b9ae)
+* [Partially fix #296 with streams2 detection for file transport (`indexzero`)](https://github.com/flatiron/winston/commit/b0227b6c27cf651ffa8b8192ef79ab24296362e3)
+* [add stress test for issue #288 (`indexzero`)](https://github.com/flatiron/winston/commit/e08e504b5b3a00f0acaade75c5ba69e6439c84a6)
+* [lessen timeouts to check test sanity (`indexzero`)](https://github.com/flatiron/winston/commit/e925f5bc398a88464f3e796545ff88912aff7568)
+* [update winston-graylog2 documentation (`unlucio`)](https://github.com/flatiron/winston/commit/49fa86c31baf12c8ac3adced3bdba6deeea2e363)
+* [fix test formatting (`indexzero`)](https://github.com/flatiron/winston/commit/8e2225799520a4598044cdf93006d216812a27f9)
+* [fix so options are not redefined (`indexzero`)](https://github.com/flatiron/winston/commit/d1d146e8a5bb73dcb01579ad433f6d4f70b668ea)
+* [fix self/this issue that broke `http` transport (`indexzero`)](https://github.com/flatiron/winston/commit/d10cbc07755c853b60729ab0cd14aa665da2a63b)
+
+
+## 0.8.1 / 2014-10-06
+
+* [Add label option for DailyRotateFile transport (`francoisTemasys`)](https://github.com/flatiron/winston/pull/459)
+* [fix Logger#transports length check upon Logger#log (`adriano-di-giovanni`, `indexzero`)](https://github.com/flatiron/winston/pull/404)
+* [err can be a string. (`gdw2`, `indexzero`)](https://github.com/flatiron/winston/pull/396)
+* [Added color for pre-defined cli set. (`danilo1105`, `indexzero`)](https://github.com/flatiron/winston/pull/365)
+* [Fix dates on transport test (`revington`)](https://github.com/flatiron/winston/pull/346)
+* [Included the label from options to the output in JSON mode. (`arxony`)](https://github.com/flatiron/winston/pull/326)
+* [Allow using logstash option with the File transport (`gmajoulet`)](https://github.com/flatiron/winston/pull/299)
+* [Be more defensive when working with `query` methods from Transports. Fixes #356. (indexzero)](https://github.com/flatiron/winston/commit/b80638974057f74b521dbe6f43fef2105110afa2)
+* [Catch exceptions for file transport unlinkSync (`calvinfo`)](https://github.com/flatiron/winston/pull/266)
+* [Adding the 'addRewriter' to winston (`machadogj`)](https://github.com/flatiron/winston/pull/258)
+* [Updates to transport documentation (`pose`)](https://github.com/flatiron/winston/pull/262)
+* [fix typo in "Extending another object with Logging" section.](https://github.com/flatiron/winston/pull/281)
+* [Updated README.md - Replaced properties with those listed in winston-mongodb module](https://github.com/flatiron/winston/pull/264)
+
+## 0.8.0 / 2014-09-15
+ * [Fixes for HTTP Transport](https://github.com/flatiron/winston/commit/a876a012641f8eba1a976eada15b6687d4a03f82)
+ * Removing [jsonquest](https://github.com/flatiron/winston/commit/4f088382aeda28012b7a0498829ceb243ed74ac1) and [request](https://github.com/flatiron/winston/commit/a5676313b4e9744802cc3b8e1468e4af48830876) dependencies.
+ * Configuration is now [shalow cloned](https://github.com/flatiron/winston/commit/08fccc81d18536d33050496102d98bde648853f2).
+ * [Added logstash support](https://github.com/flatiron/winston/pull/445/files)
+ * Fix for ["flush" event should always fire after "flush" call bug](https://github.com/flatiron/winston/pull/446/files)
+ * Added tests for file: [open and stress](https://github.com/flatiron/winston/commit/47d885797a2dd0d3cd879305ca813a0bd951c378).
+ * [Test fixes](https://github.com/flatiron/winston/commit/9e39150e0018f43d198ca4c160acef2af9860bf4)
+ * [Fix ")" on string interpolation](https://github.com/flatiron/winston/pull/394/files)
+
+## 0.6.2 / 2012-07-08
+
+ * Added prettyPrint option for console logging
+ * Multi-line values for conditional returns are not allowed
+ * Added acceptance of `stringify` option
+ * Fixed padding for log levels
+
diff --git a/myapp/node_modules/winston/LICENSE b/myapp/node_modules/winston/LICENSE
new file mode 100644
index 0000000..948d80d
--- /dev/null
+++ b/myapp/node_modules/winston/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Charlie Robbins
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/myapp/node_modules/winston/README.md b/myapp/node_modules/winston/README.md
new file mode 100644
index 0000000..8bba8c3
--- /dev/null
+++ b/myapp/node_modules/winston/README.md
@@ -0,0 +1,1042 @@
+# winston [](http://travis-ci.org/winstonjs/winston)
+
+A multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs."
+
+## Motivation
+Winston is designed to be a simple and universal logging library with support for multiple transports. A transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.
+
+There also seemed to be a lot of logging libraries out there that coupled their implementation of logging (i.e. how the logs are stored / indexed) to the API that they exposed to the programmer. This library aims to decouple those parts of the process to make it more flexible and extensible.
+
+## Installation
+
+```bashp
+npm install winston
+```
+
+## Usage
+There are two different ways to use winston: directly via the default logger, or by instantiating your own Logger. The former is merely intended to be a convenient shared logger to use throughout your application if you so choose.
+
+* [Logging](#logging)
+ * [Using the Default Logger](#using-the-default-logger)
+ * [Instantiating your own Logger](#instantiating-your-own-logger)
+ * [Logging with Metadata](#logging-with-metadata)
+ * [String interpolation](#string-interpolation)
+* [Transports](https://github.com/winstonjs/winston/blob/master/docs/transports.md)
+ * [Multiple transports of the same type](#multiple-transports-of-the-same-type)
+* [Profiling](#profiling)
+* [Streaming Logs](#streaming-logs)
+* [Querying Logs](#querying-logs)
+* [Exceptions](#exceptions)
+ * [Handling Uncaught Exceptions with winston](#handling-uncaught-exceptions-with-winston)
+ * [To Exit or Not to Exit](#to-exit-or-not-to-exit)
+* [Logging Levels](#logging-levels)
+ * [Using Logging Levels](#using-logging-levels)
+ * [Using Custom Logging Levels](#using-custom-logging-levels)
+* [Further Reading](#further-reading)
+ * [Events and Callbacks in Winston](#events-and-callbacks-in-winston)
+ * [Working with multiple Loggers in winston](#working-with-multiple-loggers-in-winston)
+ * [Using winston in a CLI tool](#using-winston-in-a-cli-tool)
+ * [Extending another object with Logging](#extending-another-object-with-logging)
+ * [Filters and Rewriters](#filters-and-rewriters)
+* [Working with transports](#working-with-transports)
+ * [Adding Custom Transports](#adding-custom-transports)
+* [Installation](#installation)
+* [Run Tests](#run-tests)
+
+
+## Logging
+
+### Using the Default Logger
+The default logger is accessible through the winston module directly. Any method that you could call on an instance of a logger is available on the default logger:
+
+``` js
+ var winston = require('winston');
+
+ winston.log('info', 'Hello distributed log files!');
+ winston.info('Hello again distributed logs');
+
+ winston.level = 'debug';
+ winston.log('debug', 'Now my debug messages are written to console!');
+```
+
+By default, only the Console transport is set on the default logger. You can add or remove transports via the add() and remove() methods:
+
+``` js
+ winston.add(winston.transports.File, { filename: 'somefile.log' });
+ winston.remove(winston.transports.Console);
+```
+
+For more documentation about working with each individual transport supported by Winston see the [Working with transports](#working-with-transports) section below.
+
+### Instantiating your own Logger
+If you would prefer to manage the object lifetime of loggers you are free to instantiate them yourself:
+
+``` js
+ var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)(),
+ new (winston.transports.File)({ filename: 'somefile.log' })
+ ]
+ });
+```
+
+You can work with this logger in the same way that you work with the default logger:
+
+``` js
+ //
+ // Logging
+ //
+ logger.log('info', 'Hello distributed log files!');
+ logger.info('Hello again distributed logs');
+
+ //
+ // Adding / Removing Transports
+ // (Yes It's chainable)
+ //
+ logger.add(winston.transports.File)
+ .remove(winston.transports.Console);
+```
+
+### Logging with Metadata
+In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:
+
+``` js
+ winston.log('info', 'Test Log Message', { anything: 'This is metadata' });
+```
+
+The way these objects are stored varies from transport to transport (to best support the storage mechanisms offered). Here's a quick summary of how each transports handles metadata:
+
+1. __Console:__ Logged via util.inspect(meta)
+2. __File:__ Logged via util.inspect(meta)
+
+## Multiple transports of the same type
+
+It is possible to use multiple transports of the same type e.g. `winston.transports.File` by passing in a custom `name` when you construct the transport.
+
+``` js
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.File)({
+ name: 'info-file',
+ filename: 'filelog-info.log',
+ level: 'info'
+ }),
+ new (winston.transports.File)({
+ name: 'error-file',
+ filename: 'filelog-error.log',
+ level: 'error'
+ })
+ ]
+});
+```
+
+If you later want to remove one of these transports you can do so by using the string name. e.g.:
+
+``` js
+logger.remove('info-file');
+```
+
+In this example one could also remove by passing in the instance of the Transport itself. e.g. this is equivalent to the string example above;
+
+``` js
+// Notice it was first in the Array above
+var infoFile = logger.transports[0];
+logger.remove(infoFile);
+```
+
+## Profiling
+In addition to logging messages and metadata, winston also has a simple profiling mechanism implemented for any logger:
+
+``` js
+ //
+ // Start profile of 'test'
+ // Remark: Consider using Date.now() with async operations
+ //
+ winston.profile('test');
+
+ setTimeout(function () {
+ //
+ // Stop profile of 'test'. Logging will now take place:
+ // "17 Jan 21:00:00 - info: test duration=1000ms"
+ //
+ winston.profile('test');
+ }, 1000);
+```
+
+All profile messages are set to the 'info' by default and both message and metadata are optional There are no plans in the Roadmap to make this configurable, but I'm open to suggestions / issues.
+
+### String interpolation
+The `log` method provides the same string interpolation methods like [`util.format`][10].
+
+This allows for the following log messages.
+``` js
+logger.log('info', 'test message %s', 'my string');
+// info: test message my string
+
+logger.log('info', 'test message %d', 123);
+// info: test message 123
+
+logger.log('info', 'test message %j', {number: 123}, {});
+// info: test message {"number":123}
+// meta = {}
+
+logger.log('info', 'test message %s, %s', 'first', 'second', {number: 123});
+// info: test message first, second
+// meta = {number: 123}
+
+logger.log('info', 'test message', 'first', 'second', {number: 123});
+// info: test message first second
+// meta = {number: 123}
+
+logger.log('info', 'test message %s, %s', 'first', 'second', {number: 123}, function(){});
+// info: test message first, second
+// meta = {numer: 123}
+// callback = function(){}
+
+logger.log('info', 'test message', 'first', 'second', {number: 123}, function(){});
+// info: test message first second
+// meta = {numer: 123}
+// callback = function(){}
+```
+
+
+
+
+
+## Querying Logs
+Winston supports querying of logs with Loggly-like options. [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional).
+Specifically: `File`, `Couchdb`, `Redis`, `Loggly`, `Nssocket`, and `Http`.
+
+``` js
+ var options = {
+ from: new Date - 24 * 60 * 60 * 1000,
+ until: new Date,
+ limit: 10,
+ start: 0,
+ order: 'desc',
+ fields: ['message']
+ };
+
+ //
+ // Find items logged between today and yesterday.
+ //
+ winston.query(options, function (err, results) {
+ if (err) {
+ throw err;
+ }
+
+ console.log(results);
+ });
+```
+
+## Streaming Logs
+Streaming allows you to stream your logs back from your chosen transport.
+
+``` js
+ //
+ // Start at the end.
+ //
+ winston.stream({ start: -1 }).on('log', function(log) {
+ console.log(log);
+ });
+```
+
+## Exceptions
+
+### Handling Uncaught Exceptions with winston
+
+With `winston`, it is possible to catch and log `uncaughtException` events from your process. There are two distinct ways of enabling this functionality either through the default winston logger or your own logger instance.
+
+If you want to use this feature with the default logger simply call `.handleExceptions()` with a transport instance.
+
+``` js
+ //
+ // You can add a separate exception logger by passing it to `.handleExceptions`
+ //
+ winston.handleExceptions(new winston.transports.File({ filename: 'path/to/exceptions.log' }))
+
+ //
+ // Alternatively you can set `.handleExceptions` to true when adding transports to winston
+ //
+ winston.add(winston.transports.File, {
+ filename: 'path/to/all-logs.log',
+ handleExceptions: true
+ });
+```
+
+### To Exit or Not to Exit
+
+By default, winston will exit after logging an uncaughtException. if this is not the behavior you want,
+set `exitOnError = false`
+
+``` js
+ var logger = new (winston.Logger)({ exitOnError: false });
+
+ //
+ // or, like this:
+ //
+ logger.exitOnError = false;
+```
+
+When working with custom logger instances, you can pass in separate transports to the `exceptionHandlers` property or set `.handleExceptions` on any transport.
+
+Example 1
+
+``` js
+ var logger = new (winston.Logger)({
+ transports: [
+ new winston.transports.File({ filename: 'path/to/all-logs.log' })
+ ],
+ exceptionHandlers: [
+ new winston.transports.File({ filename: 'path/to/exceptions.log' })
+ ]
+ });
+```
+
+Example 2
+
+``` js
+var logger = new winston.Logger({
+ transports: [
+ new winston.transports.Console({
+ handleExceptions: true,
+ json: true
+ })
+ ],
+ exitOnError: false
+});
+```
+
+The `exitOnError` option can also be a function to prevent exit on only certain types of errors:
+
+``` js
+ function ignoreEpipe(err) {
+ return err.code !== 'EPIPE';
+ }
+
+ var logger = new (winston.Logger)({ exitOnError: ignoreEpipe });
+
+ //
+ // or, like this:
+ //
+ logger.exitOnError = ignoreEpipe;
+```
+
+## Logging Levels
+
+### Using Logging Levels
+Setting the level for your logging message can be accomplished in one of two ways. You can pass a string representing the logging level to the log() method or use the level specified methods defined on every winston Logger.
+
+``` js
+ //
+ // Any logger instance
+ //
+ logger.log('silly', "127.0.0.1 - there's no place like home");
+ logger.log('debug', "127.0.0.1 - there's no place like home");
+ logger.log('verbose', "127.0.0.1 - there's no place like home");
+ logger.log('info', "127.0.0.1 - there's no place like home");
+ logger.log('warn', "127.0.0.1 - there's no place like home");
+ logger.log('error', "127.0.0.1 - there's no place like home");
+ logger.info("127.0.0.1 - there's no place like home");
+ logger.warn("127.0.0.1 - there's no place like home");
+ logger.error("127.0.0.1 - there's no place like home");
+
+ //
+ // Default logger
+ //
+ winston.log('info', "127.0.0.1 - there's no place like home");
+ winston.info("127.0.0.1 - there's no place like home");
+```
+
+Winston allows you to set a `level` on each transport that specifies the level of messages this transport should log. For example, you could log only errors to the console, with the full logs in a file (note that the default level of a transport is `info`):
+
+``` js
+ var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({ level: 'error' }),
+ new (winston.transports.File)({ filename: 'somefile.log' })
+ ]
+ });
+```
+
+You may also dynamically change the log level of a transport:
+
+``` js
+ var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({ level: 'warn' }),
+ new (winston.transports.File)({ filename: 'somefile.log', level: 'error' })
+ ]
+ });
+ logger.debug("Will not be logged in either transport!");
+ logger.transports.console.level = 'debug';
+ logger.transports.file.level = 'verbose';
+ logger.verbose("Will be logged in both transports!");
+```
+
+As of 0.2.0, winston supports customizable logging levels, defaulting to [npm][0] style logging levels. Changing logging levels is easy:
+
+``` js
+ //
+ // Change levels on the default winston logger
+ //
+ winston.setLevels(winston.config.syslog.levels);
+
+ //
+ // Change levels on an instance of a logger
+ //
+ logger.setLevels(winston.config.syslog.levels);
+```
+
+Calling `.setLevels` on a logger will remove all of the previous helper methods for the old levels and define helper methods for the new levels. Thus, you should be careful about the logging statements you use when changing levels. For example, if you ran this code after changing to the syslog levels:
+
+``` js
+ //
+ // Logger does not have 'silly' defined since that level is not in the syslog levels
+ //
+ logger.silly('some silly message');
+```
+
+### Using Custom Logging Levels
+In addition to the predefined `npm` and `syslog` levels available in Winston, you can also choose to define your own:
+
+``` js
+ var myCustomLevels = {
+ levels: {
+ foo: 0,
+ bar: 1,
+ baz: 2,
+ foobar: 3
+ },
+ colors: {
+ foo: 'blue',
+ bar: 'green',
+ baz: 'yellow',
+ foobar: 'red'
+ }
+ };
+
+ var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });
+ customLevelLogger.foobar('some foobar level-ed message');
+```
+
+Although there is slight repetition in this data structure, it enables simple encapsulation if you not to have colors. If you do wish to have colors, in addition to passing the levels to the Logger itself, you must make winston aware of them:
+
+``` js
+ //
+ // Make winston aware of these colors
+ //
+ winston.addColors(myCustomLevels.colors);
+```
+
+This enables transports with the 'colorize' option set to appropriately color the output of custom levels.
+
+## Further Reading
+
+### Events and Callbacks in Winston
+Each instance of winston.Logger is also an instance of an [EventEmitter][1]. A log event will be raised each time a transport successfully logs a message:
+
+``` js
+ logger.on('logging', function (transport, level, msg, meta) {
+ // [msg] and [meta] have now been logged at [level] to [transport]
+ });
+
+ logger.info('CHILL WINSTON!', { seriously: true });
+```
+
+It is also worth mentioning that the logger also emits an 'error' event which you should handle or suppress if you don't want unhandled exceptions:
+
+``` js
+ //
+ // Handle errors
+ //
+ logger.on('error', function (err) { /* Do Something */ });
+
+ //
+ // Or just suppress them.
+ //
+ logger.emitErrs = false;
+```
+
+Every logging method described in the previous section also takes an optional callback which will be called only when all of the transports have logged the specified message.
+
+``` js
+ logger.info('CHILL WINSTON!', { seriously: true }, function (err, level, msg, meta) {
+ // [msg] and [meta] have now been logged at [level] to **every** transport.
+ });
+```
+
+### Working with multiple Loggers in winston
+
+Often in larger, more complex applications it is necessary to have multiple logger instances with different settings. Each logger is responsible for a different feature area (or category). This is exposed in `winston` in two ways: through `winston.loggers` and instances of `winston.Container`. In fact, `winston.loggers` is just a predefined instance of `winston.Container`:
+
+``` js
+ var winston = require('winston');
+
+ //
+ // Configure the logger for `category1`
+ //
+ winston.loggers.add('category1', {
+ console: {
+ level: 'silly',
+ colorize: true,
+ label: 'category one'
+ },
+ file: {
+ filename: '/path/to/some/file'
+ }
+ });
+
+ //
+ // Configure the logger for `category2`
+ //
+ winston.loggers.add('category2', {
+ couchdb: {
+ host: '127.0.0.1',
+ port: 5984
+ }
+ });
+```
+
+Now that your loggers are setup you can require winston _in any file in your application_ and access these pre-configured loggers:
+
+``` js
+ var winston = require('winston');
+
+ //
+ // Grab your preconfigured logger
+ //
+ var category1 = winston.loggers.get('category1');
+
+ category1.info('logging from your IoC container-based logger');
+```
+
+If you prefer to manage the `Container` yourself you can simply instantiate one:
+
+``` js
+ var winston = require('winston'),
+ container = new winston.Container();
+
+ container.add('category1', {
+ console: {
+ level: 'silly',
+ colorize: true
+ },
+ file: {
+ filename: '/path/to/some/file'
+ }
+ });
+```
+
+### Sharing transports between Loggers in winston
+
+``` js
+ var winston = require('winston');
+
+ //
+ // Setup transports to be shared across all loggers
+ // in three ways:
+ //
+ // 1. By setting it on the default Container
+ // 2. By passing `transports` into the constructor function of winston.Container
+ // 3. By passing `transports` into the `.get()` or `.add()` methods
+ //
+
+ //
+ // 1. By setting it on the default Container
+ //
+ winston.loggers.options.transports = [
+ // Setup your shared transports here
+ ];
+
+ //
+ // 2. By passing `transports` into the constructor function of winston.Container
+ //
+ var container = new winston.Container({
+ transports: [
+ // Setup your shared transports here
+ ]
+ });
+
+ //
+ // 3. By passing `transports` into the `.get()` or `.add()` methods
+ //
+ winston.loggers.add('some-category', {
+ transports: [
+ // Setup your shared transports here
+ ]
+ });
+
+ container.add('some-category', {
+ transports: [
+ // Setup your shared transports here
+ ]
+ });
+```
+
+### Using winston in a CLI tool
+A common use-case for logging is output to a CLI tool. Winston has a special helper method which will pretty print output from your CLI tool. Here's an example from the [require-analyzer][2] written by [Nodejitsu][3]:
+
+```
+ info: require-analyzer starting in /Users/Charlie/Nodejitsu/require-analyzer
+ info: Found existing dependencies
+ data: {
+ data: colors: '0.x.x',
+ data: eyes: '0.1.x',
+ data: findit: '0.0.x',
+ data: npm: '1.0.x',
+ data: optimist: '0.2.x',
+ data: semver: '1.0.x',
+ data: winston: '0.2.x'
+ data: }
+ info: Analyzing dependencies...
+ info: Done analyzing raw dependencies
+ info: Retrieved packages from npm
+ warn: No additional dependencies found
+```
+
+Configuring output for this style is easy, just use the `.cli()` method on `winston` or an instance of `winston.Logger`:
+
+``` js
+ var winston = require('winston');
+
+ //
+ // Configure CLI output on the default logger
+ //
+ winston.cli();
+
+ //
+ // Configure CLI on an instance of winston.Logger
+ //
+ var logger = new winston.Logger({
+ transports: [
+ new (winston.transports.Console)()
+ ]
+ });
+
+ logger.cli();
+```
+
+### Extending another object with Logging
+Often in a given code base with lots of Loggers it is useful to add logging methods to a different object so that these methods can be called with less syntax. Winston exposes this functionality via the 'extend' method:
+
+``` js
+ var myObject = {};
+
+ logger.extend(myObject);
+
+ //
+ // You can now call logger methods on 'myObject'
+ //
+ myObject.info("127.0.0.1 - there's no place like home");
+```
+
+### Filters and Rewriters
+Filters allow modifying the contents of **log messages**, and Rewriters allow modifying the contents of **log meta** e.g. to mask data that should not appear in logs.
+
+``` js
+logger.addFilter(function(msg, meta, level) {
+ return meta.production
+ ? maskCardNumbers(msg)
+ : msg;
+});
+
+logger.info('transaction with card number 123456789012345 successful.');
+```
+
+This may result in this output:
+
+```
+info: transaction with card number 123456****2345 successful.
+```
+
+Where as for rewriters, if you wanted to sanitize the `creditCard` field of your `meta` you could:
+
+``` js
+logger.addRewriter(function(level, msg, meta) {
+ if (meta.creditCard) {
+ meta.creditCard = maskCardNumbers(meta.creditCard)
+ }
+
+ return meta;
+});
+
+logger.info('transaction ok', { creditCard: 123456789012345 });
+```
+
+which may result in this output:
+
+```
+info: transaction ok creditCard=123456****2345
+```
+
+See [log-filter-test.js](./test/log-filter-test.js), where card number masking is implemented as an example along with [log-rewriter-test.js](./test/log-rewriter-test.js)
+
+## Working with Transports
+There are many transports supported by winston core. If you have a transport you would like to add either open an issue or fork and submit a pull request. Commits are welcome, but I'll give you extra street cred if you __add tests too :D__
+
+
+### Console Transport
+``` js
+ winston.add(winston.transports.Console, options)
+```
+
+The Console transport takes a few simple options:
+
+* __level:__ Level of messages that this transport should log (default 'info').
+* __silent:__ Boolean flag indicating whether to suppress output (default false).
+* __colorize:__ Boolean flag indicating if we should colorize output (default false).
+* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps.
+* __prettyPrint:__ Boolean flag indicating if we should `util.inspect` the meta (default false). If function is specified, its return value will be the string representing the meta.
+* __depth__ Numeric indicating how many times to recurse while formatting the object with `util.inspect` (only used with `prettyPrint: true`) (default null, unlimited)
+* __showLevel:__ Boolean flag indicating if we should prepend output with level (default true).
+* __formatter:__ If function is specified, its return value will be used instead of default output. (default undefined)
+* __debugStdout:__ Boolean flag indicating if 'debug'-level output should be redirected to stdout instead of to stderr. (default false)
+
+*Metadata:* Logged via util.inspect(meta);
+
+### File Transport
+``` js
+ winston.add(winston.transports.File, options)
+```
+
+The File transport should really be the 'Stream' transport since it will accept any [WritableStream][14]. It is named such because it will also accept filenames via the 'filename' option:
+
+* __level:__ Level of messages that this transport should log.
+* __silent:__ Boolean flag indicating whether to suppress output.
+* __colorize:__ Boolean flag indicating if we should colorize output.
+* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default true). If function is specified, its return value will be used instead of timestamps.
+* __filename:__ The filename of the logfile to write output to.
+* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created, a counter will become a suffix of the log file.
+* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded.
+* __stream:__ The WriteableStream to write output to.
+* __json:__ If true, messages will be logged as JSON (default true).
+* __prettyPrint:__ If true, additional JSON metadata objects that are added to logging string messages will be displayed as a JSON string representation. If function is specified, its return value will be the string representing the meta.
+* __depth__ Numeric indicating how many times to recurse while formatting the object with `util.inspect` (only used with `prettyPrint: true`) (default null, unlimited)
+* __logstash:__ If true, messages will be logged as JSON and formatted for logstash (default false).
+* __showLevel:__ Boolean flag indicating if we should prepend output with level (default true).
+* __formatter:__ If function is specified and `json` is set to `false`, its return value will be used instead of default output. (default undefined)
+* __tailable:__ If true, log files will be rolled based on maxsize and maxfiles, but in ascending order. The __filename__ will always have the most recent log lines. The larger the appended number, the older the log file.
+* __maxRetries:__ The number of stream creation retry attempts before entering a failed state. In a failed state the transport stays active but performs a NOOP on it's log function. (default 2)
+* __zippedArchive:__ If true, all log files but the current one will be zipped.
+
+*Metadata:* Logged via util.inspect(meta);
+
+### Daily Rotate File Transport
+``` js
+ winston.add(winston.transports.DailyRotateFile, options)
+```
+
+The Daily Rotate File transport lets you rotate log files based on time.
+
+In addition to the options accepted by the File transport, the Daily Rotate File Transport also accepts the following option.
+
+* __datePattern:__ Defines rolling time of a log file and suffix appended to the file. Following meta characters can be used: `yy`, `yyyy`, `M`, `MM`, `d`, `dd`, `H`, `HH`, `m`, `mm`. The default pattern is `'.yyyy-MM-dd'`. Rotation time of the log file will be equal to the smallest given time token timespan, so `'.yyyy-MM-ddTHH'` will rotate logfile every hour. You can not rotate files more frequent then every minute.
+
+### Loggly Transport
+``` js
+ var Loggly = require('winston-loggly').Loggly
+ winston.add(Loggly, options);
+```
+
+The Loggly transport is based on [Nodejitsu's][3] [node-loggly][6] implementation of the [Loggly][7] API. If you haven't heard of Loggly before, you should probably read their [value proposition][8]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:
+
+* __level:__ Level of messages that this transport should log.
+* __subdomain:__ The subdomain of your Loggly account. *[required]*
+* __auth__: The authentication information for your Loggly account. *[required with inputName]*
+* __inputName:__ The name of the input this instance should log to.
+* __inputToken:__ The input token of the input this instance should log to.
+* __json:__ If true, messages will be sent to Loggly as JSON.
+
+*Metadata:* Logged in suggested [Loggly format][2]
+
+### Riak Transport
+As of `0.3.0` the Riak transport has been broken out into a new module: [winston-riak][17]. Using it is just as easy:
+
+``` js
+ var Riak = require('winston-riak').Riak;
+ winston.add(Riak, options);
+```
+
+In addition to the options accepted by the [riak-js][3] [client][4], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default:
+
+* __level:__ Level of messages that this transport should log.
+* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically.
+
+``` js
+ // Use a single bucket for all your logs
+ var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' });
+
+ // Generate a dynamic bucket based on the date and level
+ var dynamicBucketTransport = new (Riak)({
+ bucket: function (level, msg, meta, now) {
+ var d = new Date(now);
+ return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-');
+ }
+ });
+```
+
+*Metadata:* Logged as JSON literal in Riak
+
+### MongoDB Transport
+As of `0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][16]. Using it is just as easy:
+
+``` js
+ var MongoDB = require('winston-mongodb').MongoDB;
+ winston.add(MongoDB, options);
+```
+
+For more information about its arguments, check [winston-mongodb's README][16].
+
+* __level:__ Level of messages that this transport should log.
+* __silent:__ Boolean flag indicating whether to suppress output.
+* __db:__ The name of the database you want to log to. *[required]*
+* __collection__: The name of the collection you want to store log messages in, defaults to 'log'.
+* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true.
+* __host:__ The host running MongoDB, defaults to localhost.
+* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port.
+
+*Metadata:* Logged as a native JSON object.
+
+### SimpleDB Transport
+
+The [winston-simpledb][18] transport is just as easy:
+
+``` js
+ var SimpleDB = require('winston-simpledb').SimpleDB;
+ winston.add(SimpleDB, options);
+```
+
+The SimpleDB transport takes the following options. All items marked with an asterisk are required:
+
+* __awsAccessKey__:* your AWS Access Key
+* __secretAccessKey__:* your AWS Secret Access Key
+* __awsAccountId__:* your AWS Account Id
+* __domainName__:* a string or function that returns the domain name to log to
+* __region__:* the region your domain resides in
+* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log
+
+*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.
+
+### Mail Transport
+
+The [winston-mail][19] is an email transport:
+
+``` js
+ var Mail = require('winston-mail').Mail;
+ winston.add(Mail, options);
+```
+
+The Mail transport uses [emailjs](https://github.com/eleith/emailjs) behind the scenes. Options are the following:
+
+* __to:__ The address(es) you want to send to. *[required]*
+* __from:__ The address you want to send from. (default: `winston@[server-host-name]`)
+* __host:__ SMTP server hostname (default: localhost)
+* __port:__ SMTP port (default: 587 or 25)
+* __username__ User for server auth
+* __password__ Password for server auth
+* __ssl:__ Use SSL (boolean or object { key, ca, cert })
+* __tls:__ Boolean (if true, use starttls)
+* __level:__ Level of messages that this transport should log.
+* __silent:__ Boolean flag indicating whether to suppress output.
+
+*Metadata:* Stringified as JSON in email.
+
+### Amazon SNS (Simple Notification System) Transport
+
+The [winston-sns][25] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. Since this transport uses the Amazon AWS SDK for JavaScript, you can take advantage of the various methods of authentication found in Amazon's [Configuring the SDK in Node.js](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) document.
+
+``` js
+ var winston = require('winston'),
+ winstonSNS = require('winston-sns');
+
+ winston.add(winstonSNS, options);
+```
+
+Options:
+
+* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]*
+* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]*
+* __aws_key:__ Your Amazon Web Services Key.
+* __aws_secret:__ Your Amazon Web Services Secret.
+* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`)
+* __subject:__ Subject for notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Winston Error Report")
+* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m")
+* __level:__ lowest level this transport will log. (default: `info`)
+* __json:__ use json instead of a prettier (human friendly) string for meta information in the notification. (default: `false`)
+* __handleExceptions:__ set to true to have this transport handle exceptions. (default: `false`)
+
+### Graylog2 Transport
+
+[winston-graylog2][22] is a Graylog2 transport:
+
+``` js
+ var Graylog2 = require('winston-graylog2').Graylog2;
+ winston.add(Graylog2, options);
+```
+
+The Graylog2 transport connects to a Graylog2 server over UDP using the following options:
+
+* __level:__ Level of messages this transport should log. (default: info)
+* __silent:__ Boolean flag indicating whether to suppress output. (default: false)
+
+* __graylogHost:__ IP address or hostname of the graylog2 server. (default: localhost)
+* __graylogPort:__ Port to send messages to on the graylog2 server. (default: 12201)
+* __graylogHostname:__ The hostname associated with graylog2 messages. (default: require('os').hostname())
+* __graylogFacility:__ The graylog2 facility to send log messages.. (default: nodejs)
+
+*Metadata:* Stringified as JSON in the full message GELF field.
+
+### Papertrail Transport
+
+[winston-papertrail][23] is a Papertrail transport:
+
+``` js
+ var Papertrail = require('winston-papertrail').Papertrail;
+ winston.add(Papertrail, options);
+```
+
+The Papertrail transport connects to a [PapertrailApp log destination](https://papertrailapp.com) over TCP (TLS) using the following options:
+
+* __level:__ Level of messages this transport should log. (default: info)
+* __host:__ FQDN or IP address of the Papertrail endpoint.
+* __port:__ Port for the Papertrail log destination.
+* __hostname:__ The hostname associated with messages. (default: require('os').hostname())
+* __program:__ The facility to send log messages.. (default: default)
+* __logFormat:__ a log formatting function with the signature `function(level, message)`, which allows custom formatting of the level or message prior to delivery
+
+*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.
+
+### Cassandra Transport
+
+[winston-cassandra][24] is a Cassandra transport:
+
+``` js
+ var Cassandra = require('winston-cassandra').Cassandra;
+ winston.add(Cassandra, options);
+```
+
+The Cassandra transport connects to a cluster using the native protocol with the following options:
+
+* __level:__ Level of messages that this transport should log (default: `'info'`).
+* __table:__ The name of the Cassandra column family you want to store log messages in (default: `'logs'`).
+* __partitionBy:__ How you want the logs to be partitioned. Possible values `'hour'` and `'day'`(Default).
+* __consistency:__ The consistency of the insert query (default: `quorum`).
+
+In addition to the options accepted by the [Node.js Cassandra driver](https://github.com/datastax/nodejs-driver) Client.
+
+* __contactPoints:__ Cluster nodes that will handle the write requests:
+Array of strings containing the contact points, for example `['host1', 'host2']` (required).
+* __keyspace:__ The name of the keyspace that will contain the logs table (required). The keyspace should be already created in the cluster.
+
+### Adding Custom Transports
+Adding a custom transport (say for one of the datastore on the Roadmap) is actually pretty easy. All you need to do is accept a couple of options, set a name, implement a log() method, and add it to the set of transports exposed by winston.
+
+``` js
+ var util = require('util'),
+ winston = require('winston');
+
+ var CustomLogger = winston.transports.CustomLogger = function (options) {
+ //
+ // Name this logger
+ //
+ this.name = 'customLogger';
+
+ //
+ // Set the level from your options
+ //
+ this.level = options.level || 'info';
+
+ //
+ // Configure your storage backing as you see fit
+ //
+ };
+
+ //
+ // Inherit from `winston.Transport` so you can take advantage
+ // of the base functionality and `.handleExceptions()`.
+ //
+ util.inherits(CustomLogger, winston.Transport);
+
+ CustomLogger.prototype.log = function (level, msg, meta, callback) {
+ //
+ // Store this message and metadata, maybe use some custom logic
+ // then callback indicating success.
+ //
+ callback(null, true);
+ };
+```
+
+### Custom Log Format
+To specify custom log format you should set formatter function for transport. Currently supported transports are: Console, File, Memory.
+Options object will be passed to the format function. It's general properties are: timestamp, level, message, meta. Depending on the transport type may be additional properties.
+
+``` js
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({
+ timestamp: function() {
+ return Date.now();
+ },
+ formatter: function(options) {
+ // Return string will be passed to logger.
+ return options.timestamp() +' '+ options.level.toUpperCase() +' '+ (undefined !== options.message ? options.message : '') +
+ (options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' );
+ }
+ })
+ ]
+});
+logger.info('Data to log.');
+```
+
+### Inspirations
+1. [npm][0]
+2. [log.js][4]
+3. [socket.io][5]
+4. [node-rlog][6]
+5. [BigBrother][7]
+6. [Loggly][8]
+
+## Installation
+
+### Installing npm (node package manager)
+```
+ curl http://npmjs.org/install.sh | sh
+```
+
+### Installing winston
+```
+ [sudo] npm install winston
+```
+
+## Run Tests
+All of the winston tests are written in [vows][9], and designed to be run with npm.
+
+``` bash
+ $ npm test
+```
+
+#### Author: [Charlie Robbins](http://twitter.com/indexzero)
+#### Contributors: [Matthew Bergman](http://github.com/fotoverite), [Marak Squires](http://github.com/marak)
+
+[0]: https://github.com/npm/npmlog/blob/master/log.js
+[1]: http://nodejs.org/docs/v0.3.5/api/events.html#events.EventEmitter
+[2]: http://github.com/nodejitsu/require-analyzer
+[3]: http://nodejitsu.com
+[4]: https://github.com/visionmedia/log.js
+[5]: http://socket.io
+[6]: https://github.com/jbrisbin/node-rlog
+[7]: https://github.com/feisty/BigBrother
+[8]: http://loggly.com
+[9]: http://vowsjs.org
+[10]: http://nodejs.org/api/util.html#util_util_format_format
+[14]: http://nodejs.org/api/stream.html#stream_class_stream_writable
+[16]: https://github.com/indexzero/winston-mongodb
+[17]: https://github.com/indexzero/winston-riak
+[18]: https://github.com/appsattic/winston-simpledb
+[19]: https://github.com/wavded/winston-mail
+[21]: https://github.com/jesseditson/winston-sns
+[22]: https://github.com/flite/winston-graylog2
+[23]: https://github.com/kenperkins/winston-papertrail
+[24]: https://github.com/jorgebay/winston-cassandra
+[25]: https://github.com/jesseditson/winston-sns
diff --git a/myapp/node_modules/winston/docs/transports.md b/myapp/node_modules/winston/docs/transports.md
new file mode 100644
index 0000000..89197c7
--- /dev/null
+++ b/myapp/node_modules/winston/docs/transports.md
@@ -0,0 +1,473 @@
+# Winston Transports
+
+In `winston` a transport is essentially a storage device for your logs. Each instance of a winston logger can have multiple transports configured at different levels. For example, one may want error logs to be stored in a persistent remote location (like a database), but all logs output to the console or a local file.
+
+There are several [core transports](#winston-core) included in `winston`, which leverage the built-in networking and file I/O offered by node.js core. In addition, there are [third-party transports which are supported by the winston core team](#winston-more). And last (but not least) there are [additional transports written by members of the community](#additional-transports).
+
+* **[Winston Core](#winston-core)**
+ * [Console](#console-transport)
+ * [File](#file-transport)
+ * [DailyRotateFile](#dailyrotatefile-transport)
+ * [Http](#http-transport)
+ * [Webhook](#webhook-transport)
+
+* **[Winston More](#winston-more)**
+ * [CouchDB](#couchdb-transport)
+ * [Loggly](#loggly-transport)
+ * [MongoDB](#mongodb-transport)
+ * [Redis](#redis-transport)
+ * [Riak](#riak-transport)
+
+* **[Additional Transports](#additional-transports)**
+ * [SimpleDB](#simpledb-transport)
+ * [Mail](#mail-transport)
+ * [Amazon SNS](#amazon-sns-simple-notification-system-transport)
+ * [Graylog2](#graylog2-transport)
+ * [Cassandra](#cassandra-transport)
+ * [Azure Table](#azure-table)
+ * [Airbrake](#airbrake-transport)
+
+## Winston Core
+
+There are several core transports included in `winston`, which leverage the built-in networking and file I/O offered by node.js core.
+
+* [Console](#console-transport)
+* [File](#file-transport)
+* [DailyRotateFile](#dailyrotatefile-transport)
+* [Http](#http-transport)
+* [Webhook](#webhook-transport)
+
+### Console Transport
+
+``` js
+ winston.add(winston.transports.Console, options)
+```
+
+The Console transport takes four simple options:
+
+* __level:__ Level of messages that this transport should log (default 'debug').
+* __silent:__ Boolean flag indicating whether to suppress output (default false).
+* __colorize:__ Boolean flag indicating if we should colorize output (default false).
+* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps.
+* __json:__ Boolean flag indicating whether or not the output should be JSON. If true, will log out multi-line JSON objects. (default false)
+* __stringify:__ Boolean flag indiciating if the output should be passed through JSON.stringify, resulting in single-line output. Most useful when used in conjunction with the json flag. (default false)
+* __prettyPrint:__ Boolean flag indicating if we should `util.inspect` the meta (default false). If function is specified, its return value will be the string representing the meta.
+* __depth__ Numeric indicating how many times to recurse while formatting the object with `util.inspect` (only used with `prettyPrint: true`) (default null, unlimited)
+* __humanReadableUnhandledException__ Boolean flag indicating if uncaught exception should be output as human readable, instead of a single line
+
+*Metadata:* Logged via util.inspect(meta);
+
+### File Transport
+
+``` js
+ winston.add(winston.transports.File, options)
+```
+
+The File transport should really be the 'Stream' transport since it will accept any [WritableStream][0]. It is named such because it will also accept filenames via the 'filename' option:
+
+* __level:__ Level of messages that this transport should log.
+* __silent:__ Boolean flag indicating whether to suppress output.
+* __colorize:__ Boolean flag indicating if we should colorize output.
+* __timestamp:__ Boolean flag indicating if we should prepend output with timestamps (default false). If function is specified, its return value will be used instead of timestamps.
+* __filename:__ The filename of the logfile to write output to.
+* __maxsize:__ Max size in bytes of the logfile, if the size is exceeded then a new file is created.
+* __maxFiles:__ Limit the number of files created when the size of the logfile is exceeded.
+* __stream:__ The WriteableStream to write output to.
+* __json:__ If true, messages will be logged as JSON (default true).
+* __eol:__ string indicating the end-of-line characters to use (default to `\n`).
+* __prettyPrint:__ Boolean flag indicating if we should `util.inspect` the meta (default false). If function is specified, its return value will be the string representing the meta.
+* __depth__ Numeric indicating how many times to recurse while formatting the object with `util.inspect` (only used with `prettyPrint: true`) (default null, unlimited)
+
+*Metadata:* Logged via util.inspect(meta);
+
+### DailyRotateFile Transport
+
+``` js
+ winston.add(winston.transports.DailyRotateFile, options)
+```
+
+The DailyRotateFile transport can rotate files by minute, hour, day, month or year. Its options are identical to the File transport with the lone addition of the 'datePattern' option:
+
+* __datePattern:__ A string representing the pattern to be used when appending the date to the filename (default '.yyyy-MM-dd'). The meta characters used in this string will dictate the frequency of the file rotation. For example if your datePattern is simply '.HH' you will end up with 24 log files that are picked up and appended to every day.
+
+Valid meta characters in the datePattern are:
+
+* __yy:__ Last two digits of the year.
+* __yyyy:__ Full year.
+* __M:__ The month.
+* __MM:__ The zero padded month.
+* __d:__ The day.
+* __dd:__ The zero padded day.
+* __H:__ The hour.
+* __HH:__ The zero padded hour.
+* __m:__ The minute.
+* __mm:__ The zero padded minute.
+
+*Metadata:* Logged via util.inspect(meta);
+
+### Http Transport
+
+``` js
+ winston.add(winston.transports.Http, options)
+```
+
+The `Http` transport is a generic way to log, query, and stream logs from an arbitrary Http endpoint, preferably [winstond][1]. It takes options that are passed to the node.js `http` or `https` request:
+
+* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint
+* __port:__ (Default: **80 or 443**) Remote port of the HTTP logging endpoint
+* __path:__ (Default: **/**) Remote URI of the HTTP logging endpoint
+* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth
+* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS
+
+## Winston More
+
+Starting with `winston@0.3.0` an effort was made to remove any transport which added additional dependencies to `winston`. At the time there were several transports already in `winston` which will **always be supported by the winston core team.**
+
+* [CouchDB](#couchdb-transport)
+* [Redis](#redis-transport)
+* [MongoDB](#mongodb-transport)
+* [Riak](#riak-transport)
+* [Loggly](#loggly-transport)
+
+### CouchDB Transport
+
+_As of `winston@0.6.0` the CouchDB transport has been broken out into a new module: [winston-couchdb][2]._
+
+``` js
+ winston.add(winston.transports.Couchdb, options)
+```
+
+The `Couchdb` will place your logs in a remote CouchDB database. It will also create a [Design Document][3], `_design/Logs` for later querying and streaming your logs from CouchDB. The transport takes the following options:
+
+* __host:__ (Default: **localhost**) Remote host of the HTTP logging endpoint
+* __port:__ (Default: **5984**) Remote port of the HTTP logging endpoint
+* __db:__ (Default: **winston**) Remote URI of the HTTP logging endpoint
+* __auth:__ (Default: **None**) An object representing the `username` and `password` for HTTP Basic Auth
+* __ssl:__ (Default: **false**) Value indicating if we should us HTTPS
+
+### Redis Transport
+
+``` js
+ winston.add(winston.transports.Redis, options)
+```
+
+This transport accepts the options accepted by the [node-redis][4] client:
+
+* __host:__ (Default **localhost**) Remote host of the Redis server
+* __port:__ (Default **6379**) Port the Redis server is running on.
+* __auth:__ (Default **None**) Password set on the Redis server
+
+In addition to these, the Redis transport also accepts the following options.
+
+* __length:__ (Default **200**) Number of log messages to store.
+* __container:__ (Default **winston**) Name of the Redis container you wish your logs to be in.
+* __channel:__ (Default **None**) Name of the Redis channel to stream logs from.
+
+*Metadata:* Logged as JSON literal in Redis
+
+### Loggly Transport
+
+_As of `winston@0.6.0` the Loggly transport has been broken out into a new module: [winston-loggly][5]._
+
+``` js
+ winston.add(winston.transports.Loggly, options);
+```
+
+The Loggly transport is based on [Nodejitsu's][6] [node-loggly][7] implementation of the [Loggly][8] API. If you haven't heard of Loggly before, you should probably read their [value proposition][9]. The Loggly transport takes the following options. Either 'inputToken' or 'inputName' is required:
+
+* __level:__ Level of messages that this transport should log.
+* __subdomain:__ The subdomain of your Loggly account. *[required]*
+* __auth__: The authentication information for your Loggly account. *[required with inputName]*
+* __inputName:__ The name of the input this instance should log to.
+* __inputToken:__ The input token of the input this instance should log to.
+* __json:__ If true, messages will be sent to Loggly as JSON.
+
+*Metadata:* Logged in suggested [Loggly format][10]
+
+### Riak Transport
+
+_As of `winston@0.3.0` the Riak transport has been broken out into a new module: [winston-riak][11]._ Using it is just as easy:
+
+``` js
+ var Riak = require('winston-riak').Riak;
+ winston.add(Riak, options);
+```
+
+In addition to the options accepted by the [riak-js][12] [client][13], the Riak transport also accepts the following options. It is worth noting that the riak-js debug option is set to *false* by default:
+
+* __level:__ Level of messages that this transport should log.
+* __bucket:__ The name of the Riak bucket you wish your logs to be in or a function to generate bucket names dynamically.
+
+``` js
+ // Use a single bucket for all your logs
+ var singleBucketTransport = new (Riak)({ bucket: 'some-logs-go-here' });
+
+ // Generate a dynamic bucket based on the date and level
+ var dynamicBucketTransport = new (Riak)({
+ bucket: function (level, msg, meta, now) {
+ var d = new Date(now);
+ return level + [d.getDate(), d.getMonth(), d.getFullYear()].join('-');
+ }
+ });
+```
+
+*Metadata:* Logged as JSON literal in Riak
+
+### MongoDB Transport
+
+As of `winston@0.3.0` the MongoDB transport has been broken out into a new module: [winston-mongodb][14]. Using it is just as easy:
+
+``` js
+ var MongoDB = require('winston-mongodb').MongoDB;
+ winston.add(MongoDB, options);
+```
+
+The MongoDB transport takes the following options. 'db' is required:
+
+* __level:__ Level of messages that this transport should log.
+* __silent:__ Boolean flag indicating whether to suppress output.
+* __db:__ The name of the database you want to log to. *[required]*
+* __collection__: The name of the collection you want to store log messages in, defaults to 'log'.
+* __safe:__ Boolean indicating if you want eventual consistency on your log messages, if set to true it requires an extra round trip to the server to ensure the write was committed, defaults to true.
+* __host:__ The host running MongoDB, defaults to localhost.
+* __port:__ The port on the host that MongoDB is running on, defaults to MongoDB's default port.
+
+*Metadata:* Logged as a native JSON object.
+
+## Additional Transports
+
+The community has truly embraced `winston`; there are over **23** winston transports and over half of them are maintained by authors external to the winston core team. If you want to check them all out, just search `npm`:
+
+``` bash
+ $ npm search winston
+```
+
+**If you have an issue using one of these modules you should contact the module author directly**
+
+### SimpleDB Transport
+
+The [winston-simpledb][15] transport is just as easy:
+
+``` js
+ var SimpleDB = require('winston-simpledb').SimpleDB;
+ winston.add(SimpleDB, options);
+```
+
+The SimpleDB transport takes the following options. All items marked with an asterisk are required:
+
+* __awsAccessKey__:* your AWS Access Key
+* __secretAccessKey__:* your AWS Secret Access Key
+* __awsAccountId__:* your AWS Account Id
+* __domainName__:* a string or function that returns the domain name to log to
+* __region__:* the region your domain resides in
+* __itemName__: a string ('uuid', 'epoch', 'timestamp') or function that returns the item name to log
+
+*Metadata:* Logged as a native JSON object to the 'meta' attribute of the item.
+
+### Mail Transport
+
+The [winston-mail][16] is an email transport:
+
+``` js
+ var Mail = require('winston-mail').Mail;
+ winston.add(Mail, options);
+```
+
+The Mail transport uses [node-mail][17] behind the scenes. Options are the following, `to` and `host` are required:
+
+* __to:__ The address(es) you want to send to. *[required]*
+* __from:__ The address you want to send from. (default: `winston@[server-host-name]`)
+* __host:__ SMTP server hostname
+* __port:__ SMTP port (default: 587 or 25)
+* __secure:__ Use secure
+* __username__ User for server auth
+* __password__ Password for server auth
+* __level:__ Level of messages that this transport should log.
+* __silent:__ Boolean flag indicating whether to suppress output.
+
+*Metadata:* Stringified as JSON in email.
+
+### Amazon SNS (Simple Notification System) Transport
+
+The [winston-sns][18] transport uses amazon SNS to send emails, texts, or a bunch of other notifications. Since this transport uses the Amazon AWS SDK for JavaScript, you can take advantage of the various methods of authentication found in Amazon's [Configuring the SDK in Node.js](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) document.
+
+``` js
+ var winston = require('winston'),
+ winstonSNS = require('winston-sns');
+
+ winston.add(winstonSNS, options);
+```
+
+Options:
+
+* __subscriber:__ Subscriber number - found in your SNS AWS Console, after clicking on a topic. Same as AWS Account ID. *[required]*
+* __topic_arn:__ Also found in SNS AWS Console - listed under a topic as Topic ARN. *[required]*
+* __aws_key:__ Your Amazon Web Services Key.
+* __aws_secret:__ Your Amazon Web Services Secret.
+* __region:__ AWS Region to use. Can be one of: `us-east-1`,`us-west-1`,`eu-west-1`,`ap-southeast-1`,`ap-northeast-1`,`us-gov-west-1`,`sa-east-1`. (default: `us-east-1`)
+* __subject:__ Subject for notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Winston Error Report")
+* __message:__ Message of notifications. Uses placeholders for level (%l), error message (%e), and metadata (%m). (default: "Level '%l' Error:\n%e\n\nMetadata:\n%m")
+* __level:__ lowest level this transport will log. (default: `info`)
+* __json:__ use json instead of a prettier (human friendly) string for meta information in the notification. (default: `false`)
+* __handleExceptions:__ set to true to have this transport handle exceptions. (default: `false`)
+
+### Graylog2 Transport
+
+[winston-graylog2][19] is a Graylog2 transport:
+
+``` js
+ var winston = require('winston');
+ winston.add(require('winston-graylog2'), options);
+```
+
+The Graylog2 transport connects to a Graylog2 server over UDP using the following options:
+
+* __name__: Transport name
+* __level__: Level of messages this transport should log. (default: info)
+* __silent__: Boolean flag indicating whether to suppress output. (default: false)
+* __handleExceptions__: Boolean flag, whenever to handle uncaught exceptions. (default: false)
+* __graylog__:
+ - __servers__; list of graylog2 servers
+ * __host__: your server address (default: localhost)
+ * __port__: your server port (default: 12201)
+ - __hostname__: the name of this host (default: os.hostname())
+ - __facility__: the facility for these log messages (default: "Node.js")
+ - __bufferSize__: max UDP packet size, should never exceed the MTU of your system (default: 1400)
+
+
+### Cassandra Transport
+
+[winston-cassandra][20] is a Cassandra transport:
+
+``` js
+ var Cassandra = require('winston-cassandra').Cassandra;
+ winston.add(Cassandra, options);
+```
+
+The Cassandra transport connects to a cluster using the native protocol with the following options:
+
+* __level:__ Level of messages that this transport should log (default: `'info'`).
+* __table:__ The name of the Cassandra column family you want to store log messages in (default: `'logs'`).
+* __partitionBy:__ How you want the logs to be partitioned. Possible values `'hour'` and `'day'`(Default).
+* __consistency:__ The consistency of the insert query (default: `quorum`).
+
+In addition to the options accepted by the [Node.js Cassandra driver](https://github.com/jorgebay/node-cassandra-cql) Client.
+
+* __hosts:__ Cluster nodes that will handle the write requests:
+Array of strings containing the hosts, for example `['host1', 'host2']` (required).
+* __keyspace:__ The name of the keyspace that will contain the logs table (required). The keyspace should be already created in the cluster.
+
+### Azure Table
+
+[winston-azuretable][21] is a Azure Table transport:
+
+``` js
+ var azureLogger = require('winston-azuretable').AzureLogger
+ winston.add(azureLogger, options);
+```
+
+The Azure Table transport connects to an Azure Storage Account using the following options:
+
+* __useDevStorage__: Boolean flag denoting whether to use the Azure Storage Emulator (default: `false`)
+* __account__: Azure Storage Account Name. In lieu of this setting, you can set the environment variable: `AZURE_STORAGE_ACCOUNT`
+* __key__: Azure Storage Account Key. In lieu of this setting, you can set the environment variable: `AZURE_STORAGE_ACCESS_KEY`
+* __level__: lowest logging level transport to be logged (default: `info`)
+* __tableName__: name of the table to log messages (default: `log`)
+* __partitionKey__: table partition key to use (default: `process.env.NODE_ENV`)
+* __silent__: Boolean flag indicating whether to suppress output (default: `false`)
+
+### Airbrake Transport
+
+[winston-airbrake2][22] is a transport for winston that sends your logs to Airbrake.io.
+
+``` js
+ var winston = require('winston');
+ winston.add(require('winston-airbrake2').Airbrake, options);
+```
+
+The Airbrake transport utilises the node-airbrake module to send logs to the Airbrake.io API. You can set the following options:
+
+* __apiKey__: The project API Key. (required, default: null)
+* __name__: Transport name. (optional, default: 'airbrake')
+* __level__: The level of message that will be sent to Airbrake (optional, default: 'error')
+* __host__: The information that is displayed within the URL of the Airbrake interface. (optional, default: 'http://' + os.hostname())
+* __env__: The environment will dictate what happens with your message. If your environment is currently one of the 'developmentEnvironments', the error will not be sent to Airbrake. (optional, default: process.env.NODE_ENV)
+* __timeout__: The maximum time allowed to send to Airbrake in milliseconds. (optional, default: 30000)
+* __developmentEnvironments__: The environments that will **not** send errors to Airbrake. (optional, default: ['development', 'test'])
+* __projectRoot__: Extra string sent to Airbrake. (optional, default: null)
+* __appVersion__: Extra string or number sent to Airbrake. (optional, default: null)
+* __consoleLogError__: Toggle the logging of errors to console when the current environment is in the developmentEnvironments array. (optional, default: false)
+
+### Winlog2 Transport
+
+[winston-winlog2][19] is a Windows Event log transport:
+
+``` js
+ var winston = require('winston');
+ winston.add(require('winston-winlog2'), options);
+```
+
+The winlog2 transport uses the following options:
+
+* __name__: Transport name
+* __eventLog__: Log type (default: 'APPLICATION')
+* __source__: Name of application which will appear in event log (default: 'node')
+
+
+## Find more Transports
+
+``` bash
+ $ npm search winston
+ (...)
+ winston-amon Winston transport for Amon logging =zoramite
+ winston-amqp An AMQP transport for winston =kr1sp1n
+ winston-cassandra A Cassandra transport for winston =jorgebay
+ winston-couchdb a couchdb transport for winston =alz
+ winston-express Express middleware to let you use winston from the browser. =regality
+ winston-graylog2 A graylog2 transport for winston =smithclay
+ winston-hbase A HBase transport for winston =ddude
+ winston-loggly A Loggly transport for winston =indexzero
+ winston-mail A mail transport for winston =wavded
+ winston-mail2 A mail transport for winston =ivolo
+ winston-mongodb A MongoDB transport for winston =indexzero
+ winston-nodemail A mail transport for winston =reinpk
+ winston-nssocket nssocket transport for winston =mmalecki
+ winston-papertrail A Papertrail transport for winston =kenperkins
+ winston-redis A fixed-length Redis transport for winston =indexzero
+ winston-riak A Riak transport for winston =indexzero
+ winston-scribe A scribe transport for winston =wnoronha
+ winston-simpledb A Winston transport for Amazon SimpleDB =chilts
+ winston-skywriter A Windows Azure table storage transport for winston =pofallon
+ winston-sns A Simple Notification System Transport for winston =jesseditson
+ winston-syslog A syslog transport for winston =indexzero
+ winston-syslog-ain2 An ain2 based syslog transport for winston =lamtha
+ winston-winlog Windows Event Log logger for Winston =jfromaniello
+ winston-winlog2 Windows Event Log logger for Winston (no node-gyp) =peteward44
+ winston-zmq A 0MQ transport for winston =dhendo
+ winston-growl A growl transport for winston =pgherveou
+
+```
+
+[0]: http://nodejs.org/docs/v0.3.5/api/streams.html#writable_Stream
+[1]: https://github.com/flatiron/winstond
+[2]: https://github.com/indexzero/winston-couchdb
+[3]: http://guide.couchdb.org/draft/design.html
+[4]: https://github.com/mranney/node_redis
+[5]: https://github.com/indexzero/winston-loggly
+[6]: http://nodejitsu.com
+[7]: https://github.com/nodejitsu/node-loggly
+[8]: http://loggly.com
+[9]: http://www.loggly.com/product/
+[10]: http://wiki.loggly.com/loggingfromcode
+[11]: https://github.com/indexzero/winston-riak
+[12]: http://riakjs.org
+[13]: https://github.com/frank06/riak-js/blob/master/src/http_client.coffee#L10
+[14]: http://github.com/indexzero/winston-mongodb
+[15]: http://github.com/appsattic/winston-simpledb
+[16]: http://github.com/wavded/winston-mail
+[17]: https://github.com/weaver/node-mail
+[18]: https://github.com/jesseditson/winston-sns
+[19]: https://github.com/namshi/winston-graylog2
+[20]: https://github.com/jorgebay/winston-cassandra
+[21]: https://github.com/jpoon/winston-azuretable
+[22]: https://github.com/rickcraig/winston-airbrake2
diff --git a/myapp/node_modules/winston/examples/color-message.js b/myapp/node_modules/winston/examples/color-message.js
new file mode 100644
index 0000000..1622575
--- /dev/null
+++ b/myapp/node_modules/winston/examples/color-message.js
@@ -0,0 +1,11 @@
+var winston = require('../lib/winston');
+
+var logger = module.exports = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({
+ colorize: 'all'
+ })
+ ]
+});
+
+logger.log('info', 'This is an information message.');
\ No newline at end of file
diff --git a/myapp/node_modules/winston/examples/couchdb.js b/myapp/node_modules/winston/examples/couchdb.js
new file mode 100644
index 0000000..ce2d960
--- /dev/null
+++ b/myapp/node_modules/winston/examples/couchdb.js
@@ -0,0 +1,18 @@
+var winston = require('../lib/winston');
+
+//
+// Create a new winston logger instance with two tranports: Console, and Couchdb
+//
+//
+// The Console transport will simply output to the console screen
+// The Couchdb tranport will perform an HTTP POST request to the specified CouchDB instance
+//
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)(),
+ new (winston.transports.Couchdb)({ 'host': 'localhost', 'db': 'logs' })
+ // if you need auth do this: new (winston.transports.Couchdb)({ 'user': 'admin', 'pass': 'admin', 'host': 'localhost', 'db': 'logs' })
+ ]
+});
+
+logger.log('info', 'Hello webhook log files!', { 'foo': 'bar' });
diff --git a/myapp/node_modules/winston/examples/create-file.js b/myapp/node_modules/winston/examples/create-file.js
new file mode 100644
index 0000000..df7436c
--- /dev/null
+++ b/myapp/node_modules/winston/examples/create-file.js
@@ -0,0 +1,33 @@
+
+var fs = require('fs'),
+ path = require('path'),
+ winston = require('../lib/winston');
+
+var filename = path.join(__dirname, 'created-logfile.log');
+
+//
+// Remove the file, ignoring any errors
+//
+try { fs.unlinkSync(filename); }
+catch (ex) { }
+
+//
+// Create a new winston logger instance with two tranports: Console, and File
+//
+//
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)(),
+ new (winston.transports.File)({ filename: filename })
+ ]
+});
+
+logger.log('info', 'Hello created log files!', { 'foo': 'bar' });
+
+setTimeout(function () {
+ //
+ // Remove the file, ignoring any errors
+ //
+ try { fs.unlinkSync(filename); }
+ catch (ex) { }
+}, 1000);
diff --git a/myapp/node_modules/winston/examples/custom-levels.js b/myapp/node_modules/winston/examples/custom-levels.js
new file mode 100644
index 0000000..e425ecc
--- /dev/null
+++ b/myapp/node_modules/winston/examples/custom-levels.js
@@ -0,0 +1,44 @@
+/*
+ * custom-levels.js: Custom logger and color levels in winston
+ *
+ * (C) 2012, Nodejitsu Inc.
+ *
+ */
+
+var winston = require('../lib/winston');
+
+//
+// Logging levels
+//
+var config = {
+ levels: {
+ silly: 0,
+ verbose: 1,
+ info: 2,
+ data: 3,
+ warn: 4,
+ debug: 5,
+ error: 6
+ },
+ colors: {
+ silly: 'magenta',
+ verbose: 'cyan',
+ info: 'green',
+ data: 'grey',
+ warn: 'yellow',
+ debug: 'blue',
+ error: 'red'
+ }
+};
+
+var logger = module.exports = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({
+ colorize: true
+ })
+ ],
+ levels: config.levels,
+ colors: config.colors
+});
+
+logger.data('hello')
\ No newline at end of file
diff --git a/myapp/node_modules/winston/examples/custom-pretty-print.js b/myapp/node_modules/winston/examples/custom-pretty-print.js
new file mode 100644
index 0000000..74b6b80
--- /dev/null
+++ b/myapp/node_modules/winston/examples/custom-pretty-print.js
@@ -0,0 +1,18 @@
+var winston = require('../lib/winston');
+
+function myPrettyPrint(obj) {
+ return JSON.stringify(obj)
+ .replace(/\{/g, '< wow ')
+ .replace(/\:/g, ' such ')
+ .replace(/\}/g, ' >');
+}
+
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({ prettyPrint: myPrettyPrint }),
+ ]
+});
+
+logger.info('Hello, this is a logging event with a custom pretty print', { 'foo': 'bar' });
+logger.info('Hello, this is a logging event with a custom pretty print2', { 'foo': 'bar' });
+
diff --git a/myapp/node_modules/winston/examples/exception.js b/myapp/node_modules/winston/examples/exception.js
new file mode 100644
index 0000000..99f605b
--- /dev/null
+++ b/myapp/node_modules/winston/examples/exception.js
@@ -0,0 +1,4 @@
+var winston = require('../');
+winston.handleExceptions(new winston.transports.Console({ colorize: true, json: true }));
+
+throw new Error('Hello, winston!');
diff --git a/myapp/node_modules/winston/examples/raw-mode.js b/myapp/node_modules/winston/examples/raw-mode.js
new file mode 100644
index 0000000..89e070d
--- /dev/null
+++ b/myapp/node_modules/winston/examples/raw-mode.js
@@ -0,0 +1,10 @@
+var winston = require('../lib/winston');
+
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)({ raw: true }),
+ ]
+});
+
+logger.log('info', 'Hello, this is a raw logging event', { 'foo': 'bar' });
+logger.log('info', 'Hello, this is a raw logging event 2', { 'foo': 'bar' });
diff --git a/myapp/node_modules/winston/examples/regular-expressions.js b/myapp/node_modules/winston/examples/regular-expressions.js
new file mode 100644
index 0000000..8f78873
--- /dev/null
+++ b/myapp/node_modules/winston/examples/regular-expressions.js
@@ -0,0 +1,7 @@
+var winston = require('../');
+
+console.info(new RegExp('a'));
+// prints "/a/"
+
+winston.info(new RegExp('a'));
+// prints "info: /a/"
\ No newline at end of file
diff --git a/myapp/node_modules/winston/examples/silly-levels.js b/myapp/node_modules/winston/examples/silly-levels.js
new file mode 100644
index 0000000..06e68eb
--- /dev/null
+++ b/myapp/node_modules/winston/examples/silly-levels.js
@@ -0,0 +1,21 @@
+var winston = require('../lib/winston');
+
+var myCustomLevels = {
+ levels: {
+ foo: 0,
+ bar: 1,
+ baz: 2,
+ foobar: 3
+ },
+ colors: {
+ foo: 'blue',
+ bar: 'green',
+ baz: 'yellow',
+ foobar: 'red'
+ }
+};
+
+var customLevelLogger = new (winston.Logger)({ levels: myCustomLevels.levels });
+customLevelLogger.foobar('some foobar level-ed message');
+customLevelLogger.foobar('some foobar level-ed message');
+customLevelLogger.foobar('some foobar level-ed message');
\ No newline at end of file
diff --git a/myapp/node_modules/winston/examples/webhook-post.js b/myapp/node_modules/winston/examples/webhook-post.js
new file mode 100644
index 0000000..0fa1c8d
--- /dev/null
+++ b/myapp/node_modules/winston/examples/webhook-post.js
@@ -0,0 +1,17 @@
+var winston = require('../lib/winston');
+
+//
+// Create a new winston logger instance with two tranports: Console, and Webhook
+//
+//
+// The Console transport will simply output to the console screen
+// The Webhook tranports will perform an HTTP POST request to an abritrary end-point ( for post/recieve webhooks )
+//
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.Console)(),
+ new (winston.transports.Webhook)({ 'host': 'localhost', 'port': 8080, 'path': '/collectdata' })
+ ]
+});
+
+logger.log('info', 'Hello webhook log files!', { 'foo': 'bar' });
diff --git a/myapp/node_modules/winston/lib/winston.js b/myapp/node_modules/winston/lib/winston.js
new file mode 100644
index 0000000..43aa6d1
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston.js
@@ -0,0 +1,165 @@
+/*
+ * winston.js: Top-level include defining Winston.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var winston = exports;
+
+//
+// Expose version using `pkginfo`
+//
+require('pkginfo')(module, 'version');
+
+//
+// Include transports defined by default by winston
+//
+winston.transports = require('./winston/transports');
+
+//
+// Expose utility methods
+//
+var common = require('./winston/common');
+winston.hash = common.hash;
+winston.clone = common.clone;
+winston.longestElement = common.longestElement;
+winston.exception = require('./winston/exception');
+winston.config = require('./winston/config');
+winston.addColors = winston.config.addColors;
+
+//
+// Expose core Logging-related prototypes.
+//
+winston.Container = require('./winston/container').Container;
+winston.Logger = require('./winston/logger').Logger;
+winston.Transport = require('./winston/transports/transport').Transport;
+
+//
+// We create and expose a default `Container` to `winston.loggers` so that the
+// programmer may manage multiple `winston.Logger` instances without any additional overhead.
+//
+// ### some-file1.js
+//
+// var logger = require('winston').loggers.get('something');
+//
+// ### some-file2.js
+//
+// var logger = require('winston').loggers.get('something');
+//
+winston.loggers = new winston.Container();
+
+//
+// We create and expose a 'defaultLogger' so that the programmer may do the
+// following without the need to create an instance of winston.Logger directly:
+//
+// var winston = require('winston');
+// winston.log('info', 'some message');
+// winston.error('some error');
+//
+var defaultLogger = new winston.Logger({
+ transports: [new winston.transports.Console()]
+});
+
+//
+// Pass through the target methods onto `winston.
+//
+var methods = [
+ 'log',
+ 'query',
+ 'stream',
+ 'add',
+ 'remove',
+ 'clear',
+ 'profile',
+ 'startTimer',
+ 'extend',
+ 'cli',
+ 'handleExceptions',
+ 'unhandleExceptions',
+ 'addRewriter',
+ 'addFilter'
+];
+common.setLevels(winston, null, defaultLogger.levels);
+methods.forEach(function (method) {
+ winston[method] = function () {
+ return defaultLogger[method].apply(defaultLogger, arguments);
+ };
+});
+
+//
+// ### function cli ()
+// Configures the default winston logger to have the
+// settings for command-line interfaces: no timestamp,
+// colors enabled, padded output, and additional levels.
+//
+winston.cli = function () {
+ winston.padLevels = true;
+ common.setLevels(winston, defaultLogger.levels, winston.config.cli.levels);
+ defaultLogger.setLevels(winston.config.cli.levels);
+ winston.config.addColors(winston.config.cli.colors);
+
+ if (defaultLogger.transports.console) {
+ defaultLogger.transports.console.colorize = true;
+ defaultLogger.transports.console.timestamp = false;
+ }
+
+ return winston;
+};
+
+//
+// ### function setLevels (target)
+// #### @target {Object} Target levels to use
+// Sets the `target` levels specified on the default winston logger.
+//
+winston.setLevels = function (target) {
+ common.setLevels(winston, defaultLogger.levels, target);
+ defaultLogger.setLevels(target);
+};
+
+//
+// Define getter / setter for the default logger level
+// which need to be exposed by winston.
+//
+Object.defineProperty(winston, 'level', {
+ get: function () {
+ return defaultLogger.level;
+ },
+ set: function (val) {
+ defaultLogger.level = val;
+
+ Object.keys(defaultLogger.transports).forEach(function(key) {
+ defaultLogger.transports[key].level = val;
+ });
+ }
+});
+
+//
+// Define getters / setters for appropriate properties of the
+// default logger which need to be exposed by winston.
+//
+['emitErrs', 'exitOnError', 'padLevels', 'levelLength', 'stripColors'].forEach(function (prop) {
+ Object.defineProperty(winston, prop, {
+ get: function () {
+ return defaultLogger[prop];
+ },
+ set: function (val) {
+ defaultLogger[prop] = val;
+ }
+ });
+});
+
+//
+// @default {Object}
+// The default transports and exceptionHandlers for
+// the default winston logger.
+//
+Object.defineProperty(winston, 'default', {
+ get: function () {
+ return {
+ transports: defaultLogger.transports,
+ exceptionHandlers: defaultLogger.exceptionHandlers
+ };
+ }
+});
diff --git a/myapp/node_modules/winston/lib/winston/common.js b/myapp/node_modules/winston/lib/winston/common.js
new file mode 100644
index 0000000..e201c69
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/common.js
@@ -0,0 +1,396 @@
+/*
+ * common.js: Internal helper and utility functions for winston
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var util = require('util'),
+ crypto = require('crypto'),
+ cycle = require('cycle'),
+ fs = require('fs'),
+ config = require('./config');
+
+//
+// ### function setLevels (target, past, current)
+// #### @target {Object} Object on which to set levels.
+// #### @past {Object} Previous levels set on target.
+// #### @current {Object} Current levels to set on target.
+// Create functions on the target objects for each level
+// in current.levels. If past is defined, remove functions
+// for each of those levels.
+//
+exports.setLevels = function (target, past, current, isDefault) {
+ var self = this;
+ if (past) {
+ Object.keys(past).forEach(function (level) {
+ delete target[level];
+ });
+ }
+
+ target.levels = current || config.npm.levels;
+ if (target.padLevels) {
+ target.levelLength = exports.longestElement(Object.keys(target.levels));
+ }
+
+ //
+ // Define prototype methods for each log level
+ // e.g. target.log('info', msg) <=> target.info(msg)
+ //
+ Object.keys(target.levels).forEach(function (level) {
+
+ // TODO Refactor logging methods into a different object to avoid name clashes
+ if (level === 'log') {
+ console.warn('Log level named "log" will clash with the method "log". Consider using a different name.');
+ return;
+ }
+
+ target[level] = function (msg) {
+ // build argument list (level, msg, ... [string interpolate], [{metadata}], [callback])
+ var args = [level].concat(Array.prototype.slice.call(arguments));
+ target.log.apply(target, args);
+ };
+ });
+
+ return target;
+};
+
+//
+// ### function longestElement
+// #### @xs {Array} Array to calculate against
+// Returns the longest element in the `xs` array.
+//
+exports.longestElement = function (xs) {
+ return Math.max.apply(
+ null,
+ xs.map(function (x) { return x.length; })
+ );
+};
+
+//
+// ### function clone (obj)
+// #### @obj {Object} Object to clone.
+// Helper method for deep cloning pure JSON objects
+// i.e. JSON objects that are either literals or objects (no Arrays, etc)
+//
+exports.clone = function (obj) {
+ //
+ // We only need to clone reference types (Object)
+ //
+ if (obj instanceof Error) {
+ return obj;
+ }
+ else if (!(obj instanceof Object)) {
+ return obj;
+ }
+ else if (obj instanceof Date) {
+ return obj;
+ }
+
+ var copy = {};
+ for (var i in obj) {
+ if (Array.isArray(obj[i])) {
+ copy[i] = obj[i].slice(0);
+ }
+ else if (obj[i] instanceof Buffer) {
+ copy[i] = obj[i].slice(0);
+ }
+ else if (typeof obj[i] != 'function') {
+ copy[i] = obj[i] instanceof Object ? exports.clone(obj[i]) : obj[i];
+ }
+ else if (typeof obj[i] === 'function') {
+ copy[i] = obj[i];
+ }
+ }
+
+ return copy;
+};
+
+//
+// ### function log (options)
+// #### @options {Object} All information about the log serialization.
+// Generic logging function for returning timestamped strings
+// with the following options:
+//
+// {
+// level: 'level to add to serialized message',
+// message: 'message to serialize',
+// meta: 'additional logging metadata to serialize',
+// colorize: false, // Colorizes output (only if `.json` is false)
+// timestamp: true // Adds a timestamp to the serialized message
+// label: 'label to prepend the message'
+// }
+//
+exports.log = function (options) {
+ var timestampFn = typeof options.timestamp === 'function'
+ ? options.timestamp
+ : exports.timestamp,
+ timestamp = options.timestamp ? timestampFn() : null,
+ showLevel = options.showLevel === undefined ? true : options.showLevel,
+ meta = options.meta !== null && options.meta !== undefined && !(options.meta instanceof Error)
+ ? exports.clone(cycle.decycle(options.meta))
+ : options.meta || null,
+ output;
+
+ //
+ // raw mode is intended for outputing winston as streaming JSON to STDOUT
+ //
+ if (options.raw) {
+ if (typeof meta !== 'object' && meta != null) {
+ meta = { meta: meta };
+ }
+ output = exports.clone(meta) || {};
+ output.level = options.level;
+ output.message = options.message.stripColors;
+ return JSON.stringify(output);
+ }
+
+ //
+ // json mode is intended for pretty printing multi-line json to the terminal
+ //
+ if (options.json || true === options.logstash) {
+ if (typeof meta !== 'object' && meta != null) {
+ meta = { meta: meta };
+ }
+
+ output = exports.clone(meta) || {};
+ output.level = options.level;
+ output.message = output.message || '';
+
+ if (options.label) { output.label = options.label; }
+ if (options.message) { output.message = options.message; }
+ if (timestamp) { output.timestamp = timestamp; }
+
+ if (options.logstash === true) {
+ // use logstash format
+ var logstashOutput = {};
+ if (output.message !== undefined) {
+ logstashOutput['@message'] = output.message;
+ delete output.message;
+ }
+
+ if (output.timestamp !== undefined) {
+ logstashOutput['@timestamp'] = output.timestamp;
+ delete output.timestamp;
+ }
+
+ logstashOutput['@fields'] = exports.clone(output);
+ output = logstashOutput;
+ }
+
+ if (typeof options.stringify === 'function') {
+ return options.stringify(output);
+ }
+
+ return JSON.stringify(output, function (key, value) {
+ return value instanceof Buffer
+ ? value.toString('base64')
+ : value;
+ });
+ }
+
+ //
+ // Remark: this should really be a call to `util.format`.
+ //
+ if (typeof options.formatter == 'function') {
+ return String(options.formatter(exports.clone(options)));
+ }
+
+ output = timestamp ? timestamp + ' - ' : '';
+ if (showLevel) {
+ output += options.colorize === 'all' || options.colorize === 'level' || options.colorize === true
+ ? config.colorize(options.level)
+ : options.level;
+ }
+
+ output += (timestamp || showLevel) ? ': ' : '';
+ output += options.label ? ('[' + options.label + '] ') : '';
+ output += options.colorize === 'all' || options.colorize === 'message'
+ ? config.colorize(options.level, options.message)
+ : options.message;
+
+ if (meta !== null && meta !== undefined) {
+ if (meta && meta instanceof Error && meta.stack) {
+ meta = meta.stack;
+ }
+
+ if (typeof meta !== 'object') {
+ output += ' ' + meta;
+ }
+ else if (Object.keys(meta).length > 0) {
+ if (typeof options.prettyPrint === 'function') {
+ output += ' ' + options.prettyPrint(meta);
+ } else if (options.prettyPrint) {
+ output += ' ' + '\n' + util.inspect(meta, false, options.depth || null, options.colorize);
+ } else if (
+ options.humanReadableUnhandledException
+ && Object.keys(meta).length === 5
+ && meta.hasOwnProperty('date')
+ && meta.hasOwnProperty('process')
+ && meta.hasOwnProperty('os')
+ && meta.hasOwnProperty('trace')
+ && meta.hasOwnProperty('stack')) {
+
+ //
+ // If meta carries unhandled exception data serialize the stack nicely
+ //
+ var stack = meta.stack;
+ delete meta.stack;
+ delete meta.trace;
+ output += ' ' + exports.serialize(meta);
+ output += '\n' + stack.join('\n');
+ } else {
+ output += ' ' + exports.serialize(meta);
+ }
+ }
+ }
+
+ return output;
+};
+
+exports.capitalize = function (str) {
+ return str && str[0].toUpperCase() + str.slice(1);
+};
+
+//
+// ### function hash (str)
+// #### @str {string} String to hash.
+// Utility function for creating unique ids
+// e.g. Profiling incoming HTTP requests on the same tick
+//
+exports.hash = function (str) {
+ return crypto.createHash('sha1').update(str).digest('hex');
+};
+
+//
+// ### function pad (n)
+// Returns a padded string if `n < 10`.
+//
+exports.pad = function (n) {
+ return n < 10 ? '0' + n.toString(10) : n.toString(10);
+};
+
+//
+// ### function timestamp ()
+// Returns a timestamp string for the current time.
+//
+exports.timestamp = function () {
+ return new Date().toISOString();
+};
+
+//
+// ### function serialize (obj, key)
+// #### @obj {Object|literal} Object to serialize
+// #### @key {string} **Optional** Optional key represented by obj in a larger object
+// Performs simple comma-separated, `key=value` serialization for Loggly when
+// logging to non-JSON inputs.
+//
+exports.serialize = function (obj, key) {
+ if (obj === null) {
+ obj = 'null';
+ }
+ else if (obj === undefined) {
+ obj = 'undefined';
+ }
+ else if (obj === false) {
+ obj = 'false';
+ }
+
+ if (typeof obj !== 'object') {
+ return key ? key + '=' + obj : obj;
+ }
+
+ if (obj instanceof Buffer) {
+ return key ? key + '=' + obj.toString('base64') : obj.toString('base64');
+ }
+
+ var msg = '',
+ keys = Object.keys(obj),
+ length = keys.length;
+
+ for (var i = 0; i < length; i++) {
+ if (Array.isArray(obj[keys[i]])) {
+ msg += keys[i] + '=[';
+
+ for (var j = 0, l = obj[keys[i]].length; j < l; j++) {
+ msg += exports.serialize(obj[keys[i]][j]);
+ if (j < l - 1) {
+ msg += ', ';
+ }
+ }
+
+ msg += ']';
+ }
+ else if (obj[keys[i]] instanceof Date) {
+ msg += keys[i] + '=' + obj[keys[i]];
+ }
+ else {
+ msg += exports.serialize(obj[keys[i]], keys[i]);
+ }
+
+ if (i < length - 1) {
+ msg += ', ';
+ }
+ }
+
+ return msg;
+};
+
+
+//
+// ### function tailFile (options, callback)
+// #### @options {Object} Options for tail.
+// #### @callback {function} Callback to execute on every line.
+// `tail -f` a file. Options must include file.
+//
+exports.tailFile = function tail(options, callback) {
+ var stream = fs.createReadStream(options.file, { encoding: 'utf8' }),
+ buff = '',
+ destroy,
+ row = 0;
+
+ destroy = stream.destroy.bind(stream);
+ stream.destroy = function () {};
+
+ if (options.start === -1) {
+ delete options.start;
+ }
+
+ stream.on('data', function (data) {
+ var data = (buff + data).split(/\n+/),
+ l = data.length - 1,
+ i = 0;
+
+ for (; i < l; i++) {
+ if (options.start == null || row > options.start) {
+ callback(null, data[i]);
+ }
+ row++;
+ }
+
+ buff = data[l];
+ });
+
+ stream.on('error', function (err) {
+ callback(err);
+ destroy();
+ });
+
+ stream.on('end', function () {
+ if (buff) {
+ stream.emit('line', buff);
+ buff = '';
+ }
+
+ resume();
+ });
+
+ function resume() {
+ setTimeout(function () {
+ stream.resume();
+ }, 1000);
+ }
+
+ return destroy;
+};
diff --git a/myapp/node_modules/winston/lib/winston/config.js b/myapp/node_modules/winston/lib/winston/config.js
new file mode 100644
index 0000000..7c3c705
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/config.js
@@ -0,0 +1,62 @@
+/*
+ * config.js: Default settings for all levels that winston knows about
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var colors = require('colors/safe');
+
+var config = exports,
+ allColors = exports.allColors = {};
+
+config.addColors = function (colors) {
+ mixin(allColors, colors);
+};
+
+config.colorize = function (level, message) {
+ if (typeof message === 'undefined') message = level;
+
+ var colorized = message;
+ if (allColors[level] instanceof Array) {
+ for (var i = 0, l = allColors[level].length; i < l; ++i) {
+ colorized = colors[allColors[level][i]](colorized);
+ }
+ } else if (allColors[level].match(/\s/)) {
+ var colorArr = allColors[level].split(/\s+/);
+ for (var i = 0; i < colorArr.length; ++i) {
+ colorized = colors[colorArr[i]](colorized);
+ }
+ allColors[level] = colorArr;
+ } else {
+ colorized = colors[allColors[level]](colorized);
+ }
+ return colorized;
+};
+
+//
+// Export config sets
+//
+config.cli = require('./config/cli-config');
+config.npm = require('./config/npm-config');
+config.syslog = require('./config/syslog-config');
+
+//
+// Add colors for pre-defined config sets
+//
+config.addColors(config.cli.colors);
+config.addColors(config.npm.colors);
+config.addColors(config.syslog.colors);
+
+function mixin (target) {
+ var args = Array.prototype.slice.call(arguments, 1);
+
+ args.forEach(function (a) {
+ var keys = Object.keys(a);
+ for (var i = 0; i < keys.length; i++) {
+ target[keys[i]] = a[keys[i]];
+ }
+ });
+ return target;
+};
diff --git a/myapp/node_modules/winston/lib/winston/config/cli-config.js b/myapp/node_modules/winston/lib/winston/config/cli-config.js
new file mode 100644
index 0000000..ab49942
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/config/cli-config.js
@@ -0,0 +1,35 @@
+/*
+ * cli-config.js: Config that conform to commonly used CLI logging levels.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var cliConfig = exports;
+
+cliConfig.levels = {
+ silly: 0,
+ input: 1,
+ verbose: 2,
+ prompt: 3,
+ debug: 4,
+ info: 5,
+ data: 6,
+ help: 7,
+ warn: 8,
+ error: 9
+};
+
+cliConfig.colors = {
+ silly: 'magenta',
+ input: 'grey',
+ verbose: 'cyan',
+ prompt: 'grey',
+ debug: 'blue',
+ info: 'green',
+ data: 'grey',
+ help: 'cyan',
+ warn: 'yellow',
+ error: 'red'
+};
\ No newline at end of file
diff --git a/myapp/node_modules/winston/lib/winston/config/npm-config.js b/myapp/node_modules/winston/lib/winston/config/npm-config.js
new file mode 100644
index 0000000..12161a5
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/config/npm-config.js
@@ -0,0 +1,27 @@
+/*
+ * npm-config.js: Config that conform to npm logging levels.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var npmConfig = exports;
+
+npmConfig.levels = {
+ silly: 0,
+ debug: 1,
+ verbose: 2,
+ info: 3,
+ warn: 4,
+ error: 5
+};
+
+npmConfig.colors = {
+ silly: 'magenta',
+ verbose: 'cyan',
+ debug: 'blue',
+ info: 'green',
+ warn: 'yellow',
+ error: 'red'
+};
\ No newline at end of file
diff --git a/myapp/node_modules/winston/lib/winston/config/syslog-config.js b/myapp/node_modules/winston/lib/winston/config/syslog-config.js
new file mode 100644
index 0000000..55ed5e4
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/config/syslog-config.js
@@ -0,0 +1,31 @@
+/*
+ * syslog-config.js: Config that conform to syslog logging levels.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var syslogConfig = exports;
+
+syslogConfig.levels = {
+ emerg: 0,
+ alert: 1,
+ crit: 2,
+ error: 3,
+ warning: 4,
+ notice: 5,
+ info: 6,
+ debug: 7,
+};
+
+syslogConfig.colors = {
+ emerg: 'red',
+ alert: 'yellow',
+ crit: 'red',
+ error: 'red',
+ warning: 'red',
+ notice: 'yellow',
+ info: 'green',
+ debug: 'blue',
+};
\ No newline at end of file
diff --git a/myapp/node_modules/winston/lib/winston/container.js b/myapp/node_modules/winston/lib/winston/container.js
new file mode 100644
index 0000000..f5faaa7
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/container.js
@@ -0,0 +1,127 @@
+/*
+ * container.js: Inversion of control container for winston logger instances
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var common = require('./common'),
+ winston = require('../winston'),
+ extend = require('util')._extend;
+
+//
+// ### function Container (options)
+// #### @options {Object} Default pass-thru options for Loggers
+// Constructor function for the Container object responsible for managing
+// a set of `winston.Logger` instances based on string ids.
+//
+var Container = exports.Container = function (options) {
+ this.loggers = {};
+ this.options = options || {};
+ this.default = {
+ transports: [
+ new winston.transports.Console({
+ level: 'silly',
+ colorize: false
+ })
+ ]
+ }
+};
+
+//
+// ### function get / add (id, options)
+// #### @id {string} Id of the Logger to get
+// #### @options {Object} **Optional** Options for the Logger instance
+// Retreives a `winston.Logger` instance for the specified `id`. If
+// an instance does not exist, one is created.
+//
+Container.prototype.get = Container.prototype.add = function (id, options) {
+ var self = this,
+ existing;
+
+ if (!this.loggers[id]) {
+ //
+ // Remark: Simple shallow clone for configuration options in case we pass in
+ // instantiated protoypal objects
+ //
+ options = extend({}, options || this.options || this.default);
+ existing = options.transports || this.options.transports;
+ //
+ // Remark: Make sure if we have an array of transports we slice it to make copies
+ // of those references.
+ //
+ options.transports = existing ? existing.slice() : [];
+
+ if (options.transports.length === 0 && (!options || !options['console'])) {
+ options.transports.push(this.default.transports[0]);
+ }
+
+ Object.keys(options).forEach(function (key) {
+ if (key === 'transports') {
+ return;
+ }
+
+ var name = common.capitalize(key);
+
+ if (!winston.transports[name]) {
+ throw new Error('Cannot add unknown transport: ' + name);
+ }
+
+ var namedOptions = options[key];
+ namedOptions.id = id;
+ options.transports.push(new (winston.transports[name])(namedOptions));
+ });
+
+ this.loggers[id] = new winston.Logger(options);
+
+ this.loggers[id].on('close', function () {
+ self._delete(id);
+ });
+ }
+
+ return this.loggers[id];
+};
+
+//
+// ### function close (id)
+// #### @id {string} **Optional** Id of the Logger instance to find
+// Returns a boolean value indicating if this instance
+// has a logger with the specified `id`.
+//
+Container.prototype.has = function (id) {
+ return !!this.loggers[id];
+};
+
+//
+// ### function close (id)
+// #### @id {string} **Optional** Id of the Logger instance to close
+// Closes a `Logger` instance with the specified `id` if it exists.
+// If no `id` is supplied then all Loggers are closed.
+//
+Container.prototype.close = function (id) {
+ var self = this;
+
+ function _close (id) {
+ if (!self.loggers[id]) {
+ return;
+ }
+
+ self.loggers[id].close();
+ self._delete(id);
+ }
+
+ return id ? _close(id) : Object.keys(this.loggers).forEach(function (id) {
+ _close(id);
+ });
+};
+
+//
+// ### @private function _delete (id)
+// #### @id {string} Id of the Logger instance to delete from container
+// Deletes a `Logger` instance with the specified `id`.
+//
+Container.prototype._delete = function (id) {
+ delete this.loggers[id];
+}
+
diff --git a/myapp/node_modules/winston/lib/winston/exception.js b/myapp/node_modules/winston/lib/winston/exception.js
new file mode 100644
index 0000000..22717dd
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/exception.js
@@ -0,0 +1,56 @@
+/*
+ * exception.js: Utility methods for gathing information about uncaughtExceptions.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var os = require('os'),
+ stackTrace = require('stack-trace');
+
+var exception = exports;
+
+exception.getAllInfo = function (err) {
+ return {
+ date: new Date().toString(),
+ process: exception.getProcessInfo(),
+ os: exception.getOsInfo(),
+ trace: exception.getTrace(err),
+ stack: err.stack && err.stack.split('\n')
+ };
+};
+
+exception.getProcessInfo = function () {
+ return {
+ pid: process.pid,
+ uid: process.getuid ? process.getuid() : null,
+ gid: process.getgid ? process.getgid() : null,
+ cwd: process.cwd(),
+ execPath: process.execPath,
+ version: process.version,
+ argv: process.argv,
+ memoryUsage: process.memoryUsage()
+ };
+};
+
+exception.getOsInfo = function () {
+ return {
+ loadavg: os.loadavg(),
+ uptime: os.uptime()
+ };
+};
+
+exception.getTrace = function (err) {
+ var trace = err ? stackTrace.parse(err) : stackTrace.get();
+ return trace.map(function (site) {
+ return {
+ column: site.getColumnNumber(),
+ file: site.getFileName(),
+ function: site.getFunctionName(),
+ line: site.getLineNumber(),
+ method: site.getMethodName(),
+ native: site.isNative(),
+ }
+ });
+};
diff --git a/myapp/node_modules/winston/lib/winston/logger.js b/myapp/node_modules/winston/lib/winston/logger.js
new file mode 100755
index 0000000..33b32ab
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/logger.js
@@ -0,0 +1,701 @@
+/*
+ * logger.js: Core logger object used by winston.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var events = require('events'),
+ util = require('util'),
+ async = require('async'),
+ config = require('./config'),
+ common = require('./common'),
+ exception = require('./exception'),
+ Stream = require('stream').Stream;
+
+//
+// ### function Logger (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the Logger object responsible
+// for persisting log messages and metadata to one or more transports.
+//
+var Logger = exports.Logger = function (options) {
+ events.EventEmitter.call(this);
+ options = options || {};
+
+ var self = this,
+ handleExceptions = false;
+
+ //
+ // Set Levels and default logging level
+ //
+ this.padLevels = options.padLevels || false;
+ this.setLevels(options.levels);
+ if (options.colors) {
+ config.addColors(options.colors);
+ }
+
+ //
+ // Hoist other options onto this instance.
+ //
+ this.level = options.level || 'info';
+ this.emitErrs = options.emitErrs || false;
+ this.stripColors = options.stripColors || false;
+ this.exitOnError = typeof options.exitOnError !== 'undefined'
+ ? options.exitOnError
+ : true;
+
+ //
+ // Setup other intelligent default settings.
+ //
+ this.transports = {};
+ this.rewriters = [];
+ this.filters = [];
+ this.exceptionHandlers = {};
+ this.profilers = {};
+ this._names = [];
+ this._hnames = [];
+
+ if (options.transports) {
+ options.transports.forEach(function (transport) {
+ self.add(transport, null, true);
+
+ if (transport.handleExceptions) {
+ handleExceptions = true;
+ }
+ });
+ }
+
+ if (options.rewriters) {
+ options.rewriters.forEach(function (rewriter) {
+ self.addRewriter(rewriter);
+ });
+ }
+
+ if (options.exceptionHandlers) {
+ handleExceptions = true;
+ options.exceptionHandlers.forEach(function (handler) {
+ self._hnames.push(handler.name);
+ self.exceptionHandlers[handler.name] = handler;
+ });
+ }
+
+ if (options.handleExceptions || handleExceptions) {
+ this.handleExceptions();
+ }
+};
+
+//
+// Inherit from `events.EventEmitter`.
+//
+util.inherits(Logger, events.EventEmitter);
+
+//
+// ### function extend (target)
+// #### @target {Object} Target to extend.
+// Extends the target object with a 'log' method
+// along with a method for each level in this instance.
+//
+Logger.prototype.extend = function (target) {
+ var self = this;
+ ['log', 'profile', 'startTimer'].concat(Object.keys(this.levels)).forEach(function (method) {
+ target[method] = function () {
+ return self[method].apply(self, arguments);
+ };
+ });
+
+ return this;
+};
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+Logger.prototype.log = function (level) {
+ var self = this,
+ args = Array.prototype.slice.call(arguments, 1);
+
+ while(args[args.length - 1] === null) {
+ args.pop();
+ }
+
+ var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
+ meta = typeof args[args.length - 1] === 'object' && Object.prototype.toString.call(args[args.length - 1]) !== '[object RegExp]' ? args.pop() : {},
+ msg = util.format.apply(null, args);
+
+ // If we should pad for levels, do so
+ if (this.padLevels) {
+ msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
+ }
+
+ function onError (err) {
+ if (callback) {
+ callback(err);
+ }
+ else if (self.emitErrs) {
+ self.emit('error', err);
+ }
+ }
+
+
+ if (Object.keys(this.transports).length === 0) {
+ return onError(new Error('Cannot log with no transports.'));
+ }
+ else if (typeof self.levels[level] === 'undefined') {
+ return onError(new Error('Unknown log level: ' + level));
+ }
+
+ this.rewriters.forEach(function (rewriter) {
+ meta = rewriter(level, msg, meta);
+ });
+
+ this.filters.forEach(function(filter) {
+ var filtered = filter(msg, meta, level);
+ if (typeof filtered === 'string')
+ msg = filtered;
+ else {
+ msg = filtered.msg;
+ meta = filtered.meta;
+ }
+ });
+
+ //
+ // For consideration of terminal 'color" programs like colors.js,
+ // which can add ANSI escape color codes to strings, we destyle the
+ // ANSI color escape codes when `this.stripColors` is set.
+ //
+ // see: http://en.wikipedia.org/wiki/ANSI_escape_code
+ //
+ if (this.stripColors) {
+ var code = /\u001b\[(\d+(;\d+)*)?m/g;
+ msg = ('' + msg).replace(code, '');
+ }
+
+ //
+ // Log for each transport and emit 'logging' event
+ //
+ function emit(name, next) {
+ var transport = self.transports[name];
+ if ((transport.level && self.levels[transport.level] <= self.levels[level])
+ || (!transport.level && self.levels[self.level] <= self.levels[level])) {
+ transport.log(level, msg, meta, function (err) {
+ if (err) {
+ err.transport = transport;
+ cb(err);
+ return next();
+ }
+ self.emit('logging', transport, level, msg, meta);
+ next();
+ });
+ } else {
+ next();
+ }
+ }
+
+ //
+ // Respond to the callback
+ //
+ function cb(err) {
+ if (callback) {
+ if (err) return callback(err);
+ callback(null, level, msg, meta);
+ }
+ callback = null;
+ if (!err) {
+ self.emit('logged', level, msg, meta);
+ }
+ }
+
+ async.forEach(this._names, emit, cb);
+
+ return this;
+};
+
+//
+// ### function query (options, callback)
+// #### @options {Object} Query options for this instance.
+// #### @callback {function} Continuation to respond to when complete.
+// Queries the all transports for this instance with the specified `options`.
+// This will aggregate each transport's results into one object containing
+// a property per transport.
+//
+Logger.prototype.query = function (options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+
+ var self = this,
+ options = options || {},
+ results = {},
+ query = common.clone(options.query) || {},
+ transports;
+
+ //
+ // Helper function to query a single transport
+ //
+ function queryTransport(transport, next) {
+ if (options.query) {
+ options.query = transport.formatQuery(query);
+ }
+
+ transport.query(options, function (err, results) {
+ if (err) {
+ return next(err);
+ }
+
+ next(null, transport.formatResults(results, options.format));
+ });
+ }
+
+ //
+ // Helper function to accumulate the results from
+ // `queryTransport` into the `results`.
+ //
+ function addResults (transport, next) {
+ queryTransport(transport, function (err, result) {
+ //
+ // queryTransport could potentially invoke the callback
+ // multiple times since Transport code can be unpredictable.
+ //
+ if (next) {
+ result = err || result;
+ if (result) {
+ results[transport.name] = result;
+ }
+
+ next();
+ }
+
+ next = null;
+ });
+ }
+
+ //
+ // If an explicit transport is being queried then
+ // respond with the results from only that transport
+ //
+ if (options.transport) {
+ options.transport = options.transport.toLowerCase();
+ return queryTransport(this.transports[options.transport], callback);
+ }
+
+ //
+ // Create a list of all transports for this instance.
+ //
+ transports = this._names.map(function (name) {
+ return self.transports[name];
+ }).filter(function (transport) {
+ return !!transport.query;
+ });
+
+ //
+ // Iterate over the transports in parallel setting the
+ // appropriate key in the `results`
+ //
+ async.forEach(transports, addResults, function () {
+ callback(null, results);
+ });
+};
+
+//
+// ### function stream (options)
+// #### @options {Object} Stream options for this instance.
+// Returns a log stream for all transports. Options object is optional.
+//
+Logger.prototype.stream = function (options) {
+ var self = this,
+ options = options || {},
+ out = new Stream,
+ streams = [],
+ transports;
+
+ if (options.transport) {
+ var transport = this.transports[options.transport];
+ delete options.transport;
+ if (transport && transport.stream) {
+ return transport.stream(options);
+ }
+ }
+
+ out._streams = streams;
+ out.destroy = function () {
+ var i = streams.length;
+ while (i--) streams[i].destroy();
+ };
+
+ //
+ // Create a list of all transports for this instance.
+ //
+ transports = this._names.map(function (name) {
+ return self.transports[name];
+ }).filter(function (transport) {
+ return !!transport.stream;
+ });
+
+ transports.forEach(function (transport) {
+ var stream = transport.stream(options);
+ if (!stream) return;
+
+ streams.push(stream);
+
+ stream.on('log', function (log) {
+ log.transport = log.transport || [];
+ log.transport.push(transport.name);
+ out.emit('log', log);
+ });
+
+ stream.on('error', function (err) {
+ err.transport = err.transport || [];
+ err.transport.push(transport.name);
+ out.emit('error', err);
+ });
+ });
+
+ return out;
+};
+
+//
+// ### function close ()
+// Cleans up resources (streams, event listeners) for all
+// transports associated with this instance (if necessary).
+//
+Logger.prototype.close = function () {
+ var self = this;
+
+ this._names.forEach(function (name) {
+ var transport = self.transports[name];
+ if (transport && transport.close) {
+ transport.close();
+ }
+ });
+
+ this.emit('close');
+};
+
+//
+// ### function handleExceptions ()
+// Handles `uncaughtException` events for the current process
+//
+Logger.prototype.handleExceptions = function () {
+ var args = Array.prototype.slice.call(arguments),
+ handlers = [],
+ self = this;
+
+ args.forEach(function (a) {
+ if (Array.isArray(a)) {
+ handlers = handlers.concat(a);
+ }
+ else {
+ handlers.push(a);
+ }
+ });
+
+ handlers.forEach(function (handler) {
+ self.exceptionHandlers[handler.name] = handler;
+ });
+
+ this._hnames = Object.keys(self.exceptionHandlers);
+
+ if (!this.catchExceptions) {
+ this.catchExceptions = this._uncaughtException.bind(this);
+ process.on('uncaughtException', this.catchExceptions);
+ }
+};
+
+//
+// ### function unhandleExceptions ()
+// Removes any handlers to `uncaughtException` events
+// for the current process
+//
+Logger.prototype.unhandleExceptions = function () {
+ var self = this;
+
+ if (this.catchExceptions) {
+ Object.keys(this.exceptionHandlers).forEach(function (name) {
+ var handler = self.exceptionHandlers[name];
+ if (handler.close) {
+ handler.close();
+ }
+ });
+
+ this.exceptionHandlers = {};
+ Object.keys(this.transports).forEach(function (name) {
+ var transport = self.transports[name];
+ if (transport.handleExceptions) {
+ transport.handleExceptions = false;
+ }
+ })
+
+ process.removeListener('uncaughtException', this.catchExceptions);
+ this.catchExceptions = false;
+ }
+};
+
+//
+// ### function add (transport, [options])
+// #### @transport {Transport} Prototype of the Transport object to add.
+// #### @options {Object} **Optional** Options for the Transport to add.
+// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
+// Adds a transport of the specified type to this instance.
+//
+Logger.prototype.add = function (transport, options, created) {
+ var instance = created ? transport : (new (transport)(options));
+
+ if (!instance.name && !instance.log) {
+ throw new Error('Unknown transport with no log() method');
+ }
+ else if (this.transports[instance.name]) {
+ throw new Error('Transport already attached: ' + instance.name);
+ }
+
+ this.transports[instance.name] = instance;
+ this._names = Object.keys(this.transports);
+
+ //
+ // Listen for the `error` event on the new Transport
+ //
+ instance._onError = this._onError.bind(this, instance)
+ if (!created) {
+ instance.on('error', instance._onError);
+ }
+
+ //
+ // If this transport has `handleExceptions` set to `true`
+ // and we are not already handling exceptions, do so.
+ //
+ if (instance.handleExceptions && !this.catchExceptions) {
+ this.handleExceptions();
+ }
+
+ return this;
+};
+
+//
+// ### function addRewriter (transport, [options])
+// #### @transport {Transport} Prototype of the Transport object to add.
+// #### @options {Object} **Optional** Options for the Transport to add.
+// #### @instance {Boolean} **Optional** Value indicating if `transport` is already instantiated.
+// Adds a transport of the specified type to this instance.
+//
+Logger.prototype.addRewriter = function (rewriter) {
+ this.rewriters.push(rewriter);
+}
+
+//
+// ### function addFilter (filter)
+// #### @filter {function} Filter function, called with the message and
+// optional metadata as the two arguments.
+// Expected to return either the filtered message or an object with properties:
+// - msg = the filtered message string
+// - meta = the filtered metadata object
+//
+Logger.prototype.addFilter = function (filter) {
+ this.filters.push(filter);
+}
+
+//
+// ### function clear ()
+// Remove all transports from this instance
+//
+Logger.prototype.clear = function () {
+ for (var name in this.transports) {
+ this.remove({ name: name });
+ }
+};
+
+//
+// ### function remove (transport)
+// #### @transport {Transport|String} Transport or Name to remove.
+// Removes a transport of the specified type from this instance.
+//
+Logger.prototype.remove = function (transport) {
+ var name = typeof transport !== 'string'
+ ? transport.name || transport.prototype.name
+ : transport;
+
+ if (!this.transports[name]) {
+ throw new Error('Transport ' + name + ' not attached to this instance');
+ }
+
+ var instance = this.transports[name];
+ delete this.transports[name];
+ this._names = Object.keys(this.transports);
+
+ if (instance.close) {
+ instance.close();
+ }
+
+ if (instance._onError) {
+ instance.removeListener('error', instance._onError);
+ }
+ return this;
+};
+
+var ProfileHandler = function (logger) {
+ this.logger = logger;
+
+ this.start = Date.now();
+
+ this.done = function (msg) {
+ var args, callback, meta;
+ args = Array.prototype.slice.call(arguments);
+ callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
+ meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
+
+ meta.durationMs = (Date.now()) - this.start;
+
+ return this.logger.info(msg, meta, callback);
+ }
+}
+
+Logger.prototype.startTimer = function () {
+ return new ProfileHandler(this);
+}
+
+//
+// ### function profile (id, [msg, meta, callback])
+// #### @id {string} Unique id of the profiler
+// #### @msg {string} **Optional** Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} **Optional** Continuation to respond to when complete.
+// Tracks the time inbetween subsequent calls to this method
+// with the same `id` parameter. The second call to this method
+// will log the difference in milliseconds along with the message.
+//
+Logger.prototype.profile = function (id) {
+ var now = Date.now(), then, args,
+ msg, meta, callback;
+
+ if (this.profilers[id]) {
+ then = this.profilers[id];
+ delete this.profilers[id];
+
+ // Support variable arguments: msg, meta, callback
+ args = Array.prototype.slice.call(arguments);
+ callback = typeof args[args.length - 1] === 'function' ? args.pop() : null;
+ meta = typeof args[args.length - 1] === 'object' ? args.pop() : {};
+ msg = args.length === 2 ? args[1] : id;
+
+ // Set the duration property of the metadata
+ meta.durationMs = now - then;
+ return this.info(msg, meta, callback);
+ }
+ else {
+ this.profilers[id] = now;
+ }
+
+ return this;
+};
+
+//
+// ### function setLevels (target)
+// #### @target {Object} Target levels to use on this instance
+// Sets the `target` levels specified on this instance.
+//
+Logger.prototype.setLevels = function (target) {
+ return common.setLevels(this, this.levels, target);
+};
+
+//
+// ### function cli ()
+// Configures this instance to have the default
+// settings for command-line interfaces: no timestamp,
+// colors enabled, padded output, and additional levels.
+//
+Logger.prototype.cli = function () {
+ this.padLevels = true;
+ this.setLevels(config.cli.levels);
+ config.addColors(config.cli.colors);
+
+ if (this.transports.console) {
+ this.transports.console.colorize = this.transports.console.colorize || true;
+ this.transports.console.timestamp = this.transports.console.timestamp || false;
+ }
+
+ return this;
+};
+
+//
+// ### @private function _uncaughtException (err)
+// #### @err {Error} Error to handle
+// Logs all relevant information around the `err` and
+// exits the current process.
+//
+Logger.prototype._uncaughtException = function (err) {
+ var self = this,
+ responded = false,
+ info = exception.getAllInfo(err),
+ handlers = this._getExceptionHandlers(),
+ timeout,
+ doExit;
+
+ //
+ // Calculate if we should exit on this error
+ //
+ doExit = typeof this.exitOnError === 'function'
+ ? this.exitOnError(err)
+ : this.exitOnError;
+
+ function logAndWait(transport, next) {
+ transport.logException('uncaughtException: ' + (err.message || err), info, next, err);
+ }
+
+ function gracefulExit() {
+ if (doExit && !responded) {
+ //
+ // Remark: Currently ignoring any exceptions from transports
+ // when catching uncaught exceptions.
+ //
+ clearTimeout(timeout);
+ responded = true;
+ process.exit(1);
+ }
+ }
+
+ if (!handlers || handlers.length === 0) {
+ return gracefulExit();
+ }
+
+ //
+ // Log to all transports and allow the operation to take
+ // only up to `3000ms`.
+ //
+ async.forEach(handlers, logAndWait, gracefulExit);
+ if (doExit) {
+ timeout = setTimeout(gracefulExit, 3000);
+ }
+};
+
+//
+// ### @private function _getExceptionHandlers ()
+// Returns the list of transports and exceptionHandlers
+// for this instance.
+//
+Logger.prototype._getExceptionHandlers = function () {
+ var self = this;
+
+ return this._hnames.map(function (name) {
+ return self.exceptionHandlers[name];
+ }).concat(this._names.map(function (name) {
+ return self.transports[name].handleExceptions && self.transports[name];
+ })).filter(Boolean);
+};
+
+//
+// ### @private function _onError (transport, err)
+// #### @transport {Object} Transport on which the error occured
+// #### @err {Error} Error that occurred on the transport
+// Bubbles the error, `err`, that occured on the specified `transport`
+// up from this instance if `emitErrs` has been set.
+//
+Logger.prototype._onError = function (transport, err) {
+ if (this.emitErrs) {
+ this.emit('error', err, transport);
+ }
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports.js b/myapp/node_modules/winston/lib/winston/transports.js
new file mode 100644
index 0000000..cc7a96b
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports.js
@@ -0,0 +1,34 @@
+/*
+ * transports.js: Set of all transports Winston knows about
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var fs = require('fs'),
+ path = require('path'),
+ common = require('./common');
+
+var transports = exports;
+
+//
+// Setup all transports as lazy-loaded getters.
+//
+fs.readdirSync(path.join(__dirname, 'transports')).forEach(function (file) {
+ var transport = file.replace('.js', ''),
+ name = common.capitalize(transport);
+
+ if (transport === 'transport') {
+ return;
+ }
+ else if (~transport.indexOf('-')) {
+ name = transport.split('-').map(function (part) {
+ return common.capitalize(part);
+ }).join('');
+ }
+
+ transports.__defineGetter__(name, function () {
+ return require('./transports/' + transport)[name];
+ });
+});
\ No newline at end of file
diff --git a/myapp/node_modules/winston/lib/winston/transports/console.js b/myapp/node_modules/winston/lib/winston/transports/console.js
new file mode 100644
index 0000000..0aba876
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/console.js
@@ -0,0 +1,97 @@
+/*
+ * console.js: Transport for outputting to the console
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var events = require('events'),
+ util = require('util'),
+ common = require('../common'),
+ Transport = require('./transport').Transport;
+
+//
+// ### function Console (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the Console transport object responsible
+// for persisting log messages and metadata to a terminal or TTY.
+//
+var Console = exports.Console = function (options) {
+ Transport.call(this, options);
+ options = options || {};
+
+ this.json = options.json || false;
+ this.colorize = options.colorize || false;
+ this.prettyPrint = options.prettyPrint || false;
+ this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
+ this.showLevel = options.showLevel === undefined ? true : options.showLevel;
+ this.label = options.label || null;
+ this.logstash = options.logstash || false;
+ this.debugStdout = options.debugStdout || false;
+ this.depth = options.depth || null;
+
+ if (this.json) {
+ this.stringify = options.stringify || function (obj) {
+ return JSON.stringify(obj, null, 2);
+ };
+ }
+};
+
+//
+// Inherit from `winston.Transport`.
+//
+util.inherits(Console, Transport);
+
+//
+// Expose the name of this Transport on the prototype
+//
+Console.prototype.name = 'console';
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+Console.prototype.log = function (level, msg, meta, callback) {
+ if (this.silent) {
+ return callback(null, true);
+ }
+
+ var self = this,
+ output;
+
+ output = common.log({
+ colorize: this.colorize,
+ json: this.json,
+ level: level,
+ message: msg,
+ meta: meta,
+ stringify: this.stringify,
+ timestamp: this.timestamp,
+ showLevel: this.showLevel,
+ prettyPrint: this.prettyPrint,
+ raw: this.raw,
+ label: this.label,
+ logstash: this.logstash,
+ depth: this.depth,
+ formatter: this.formatter,
+ humanReadableUnhandledException: this.humanReadableUnhandledException
+ });
+
+ if (level === 'error' || (level === 'debug' && !this.debugStdout) ) {
+ process.stderr.write(output + '\n');
+ } else {
+ process.stdout.write(output + '\n');
+ }
+
+ //
+ // Emit the `logged` event immediately because the event loop
+ // will not exit until `process.stdout` has drained anyway.
+ //
+ self.emit('logged');
+ callback(null, true);
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports/daily-rotate-file.js b/myapp/node_modules/winston/lib/winston/transports/daily-rotate-file.js
new file mode 100644
index 0000000..5b77e21
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/daily-rotate-file.js
@@ -0,0 +1,601 @@
+/*
+ * daily-rotate-file.js: Transport for outputting to a local log file
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var events = require('events'),
+ fs = require('fs'),
+ path = require('path'),
+ util = require('util'),
+ common = require('../common'),
+ Transport = require('./transport').Transport,
+ Stream = require('stream').Stream,
+ os = require('os');
+
+//
+// ### function DailyRotateFile (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the DailyRotateFile transport object responsible
+// for persisting log messages and metadata to one or more files.
+//
+var DailyRotateFile = exports.DailyRotateFile = function (options) {
+ Transport.call(this, options);
+
+ //
+ // Helper function which throws an `Error` in the event
+ // that any of the rest of the arguments is present in `options`.
+ //
+ function throwIf (target /*, illegal... */) {
+ Array.prototype.slice.call(arguments, 1).forEach(function (name) {
+ if (options[name]) {
+ throw new Error('Cannot set ' + name + ' and ' + target + 'together');
+ }
+ });
+ }
+
+ if (options.filename || options.dirname) {
+ throwIf('filename or dirname', 'stream');
+ this._basename = this.filename = options.filename
+ ? path.basename(options.filename)
+ : 'winston.log';
+
+ this.dirname = options.dirname || path.dirname(options.filename);
+ this.options = options.options || { flags: 'a' };
+
+ //
+ // "24 bytes" is maybe a good value for logging lines.
+ //
+ this.options.highWaterMark = this.options.highWaterMark || 24;
+ }
+ else if (options.stream) {
+ throwIf('stream', 'filename', 'maxsize');
+ this._stream = options.stream;
+ this._stream.on('error', function(error){
+ self.emit('error', error);
+ });
+
+ //
+ // We need to listen for drain events when
+ // write() returns false. This can make node
+ // mad at times.
+ //
+ this._stream.setMaxListeners(Infinity);
+ }
+ else {
+ throw new Error('Cannot log to file without filename or stream.');
+ }
+
+ this.json = options.json !== false;
+ this.colorize = options.colorize || false;
+ this.maxsize = options.maxsize || null;
+ this.maxFiles = options.maxFiles || null;
+ this.label = options.label || null;
+ this.prettyPrint = options.prettyPrint || false;
+ this.showLevel = options.showLevel === undefined ? true : options.showLevel;
+ this.timestamp = options.timestamp != null ? options.timestamp : true;
+ this.datePattern = options.datePattern != null ? options.datePattern : '.yyyy-MM-dd';
+ this.depth = options.depth || null;
+ this.eol = options.eol || os.EOL;
+ this.maxRetries = options.maxRetries || 2;
+
+ if (this.json) {
+ this.stringify = options.stringify;
+ }
+
+ //
+ // Internal state variables representing the number
+ // of files this instance has created and the current
+ // size (in bytes) of the current logfile.
+ //
+ this._size = 0;
+ this._created = 0;
+ this._buffer = [];
+ this._draining = false;
+ this._failures = 0;
+
+ var now = new Date();
+ this._year = now.getFullYear();
+ this._month = now.getMonth();
+ this._date = now.getDate();
+ this._hour = now.getHours();
+ this._minute = now.getMinutes();
+
+ var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhM])\1?/g,
+ pad = function (val, len) {
+ val = String(val);
+ len = len || 2;
+ while (val.length < len) val = "0" + val;
+ return val;
+ };
+
+ this.getFormattedDate = function() {
+ var flags = {
+ yy: String(this._year).slice(2),
+ yyyy: this._year,
+ M: this._month + 1,
+ MM: pad(this._month + 1),
+ d: this._date,
+ dd: pad(this._date),
+ H: this._hour,
+ HH: pad(this._hour),
+ m: this._minute,
+ mm: pad(this._minute)
+ };
+ return this.datePattern.replace(token, function ($0) {
+ return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
+ });
+ };
+};
+
+//
+// Inherit from `winston.Transport`.
+//
+util.inherits(DailyRotateFile, Transport);
+
+//
+// Expose the name of this Transport on the prototype
+//
+DailyRotateFile.prototype.name = 'dailyRotateFile';
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+DailyRotateFile.prototype.log = function (level, msg, meta, callback) {
+ if (this.silent) {
+ return callback(null, true);
+ }
+
+ //
+ // If failures exceeds maxRetries then we can't access the
+ // stream. In this case we need to perform a noop and return
+ // an error.
+ //
+ if (this._failures >= this.maxRetries) {
+ return callback(new Error('Transport is in a failed state.'));
+ }
+
+ var self = this;
+
+ var output = common.log({
+ level: level,
+ message: msg,
+ meta: meta,
+ json: this.json,
+ colorize: this.colorize,
+ prettyPrint: this.prettyPrint,
+ timestamp: this.timestamp,
+ label: this.label,
+ stringify: this.stringify,
+ showLevel: this.showLevel,
+ depth: this.depth,
+ formatter: this.formatter,
+ humanReadableUnhandledException: this.humanReadableUnhandledException
+ }) + this.eol;
+
+ this._size += output.length;
+
+ if (!this.filename) {
+ //
+ // If there is no `filename` on this instance then it was configured
+ // with a raw `WriteableStream` instance and we should not perform any
+ // size restrictions.
+ //
+ this._write(output, callback);
+ this._lazyDrain();
+ }
+ else {
+ this.open(function (err) {
+ if (err) {
+ //
+ // If there was an error enqueue the message
+ //
+ return self._buffer.push([output, callback]);
+ }
+
+ self._write(output, callback);
+ self._lazyDrain();
+ });
+ }
+};
+
+//
+// ### function _write (data, cb)
+// #### @data {String|Buffer} Data to write to the instance's stream.
+// #### @cb {function} Continuation to respond to when complete.
+// Write to the stream, ensure execution of a callback on completion.
+//
+DailyRotateFile.prototype._write = function(data, callback) {
+ // If this is a file write stream, we could use the builtin
+ // callback functionality, however, the stream is not guaranteed
+ // to be an fs.WriteStream.
+ var ret = this._stream.write(data);
+ if (!callback) return;
+ if (ret === false) {
+ return this._stream.once('drain', function() {
+ callback(null, true);
+ });
+ }
+ callback(null, true);
+};
+
+//
+// ### function query (options, callback)
+// #### @options {Object} Loggly-like query options for this instance.
+// #### @callback {function} Continuation to respond to when complete.
+// Query the transport. Options object is optional.
+//
+DailyRotateFile.prototype.query = function (options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+
+ // TODO when maxfilesize rotate occurs
+ var file = path.join(this.dirname, this._basename + this.getFormattedDate()),
+ options = this.normalizeQuery(options),
+ buff = '',
+ results = [],
+ row = 0;
+
+ var stream = fs.createReadStream(file, {
+ encoding: 'utf8'
+ });
+
+ stream.on('error', function (err) {
+ if (stream.readable) {
+ stream.destroy();
+ }
+ if (!callback) return;
+ return err.code !== 'ENOENT'
+ ? callback(err)
+ : callback(null, results);
+ });
+
+ stream.on('data', function (data) {
+ var data = (buff + data).split(/\n+/),
+ l = data.length - 1,
+ i = 0;
+
+ for (; i < l; i++) {
+ if (!options.start || row >= options.start) {
+ add(data[i]);
+ }
+ row++;
+ }
+
+ buff = data[l];
+ });
+
+ stream.on('close', function () {
+ if (buff) add(buff, true);
+ if (options.order === 'desc') {
+ results = results.reverse();
+ }
+ if (callback) callback(null, results);
+ });
+
+ function add(buff, attempt) {
+ try {
+ var log = JSON.parse(buff);
+ if (check(log)) push(log);
+ } catch (e) {
+ if (!attempt) {
+ stream.emit('error', e);
+ }
+ }
+ }
+
+ function push(log) {
+ if (options.rows && results.length >= options.rows) {
+ if (stream.readable) {
+ stream.destroy();
+ }
+ return;
+ }
+
+ if (options.fields) {
+ var obj = {};
+ options.fields.forEach(function (key) {
+ obj[key] = log[key];
+ });
+ log = obj;
+ }
+
+ results.push(log);
+ }
+
+ function check(log) {
+ if (!log) return;
+
+ if (typeof log !== 'object') return;
+
+ var time = new Date(log.timestamp);
+ if ((options.from && time < options.from)
+ || (options.until && time > options.until)) {
+ return;
+ }
+
+ return true;
+ }
+};
+
+//
+// ### function stream (options)
+// #### @options {Object} Stream options for this instance.
+// Returns a log stream for this transport. Options object is optional.
+//
+DailyRotateFile.prototype.stream = function (options) {
+ var file = path.join(this.dirname, this._basename + this.getFormattedDate()),
+ options = options || {},
+ stream = new Stream;
+
+ var tail = {
+ file: file,
+ start: options.start
+ };
+
+ stream.destroy = common.tailFile(tail, function (err, line) {
+
+ if(err){
+ return stream.emit('error',err);
+ }
+
+ try {
+ stream.emit('data', line);
+ line = JSON.parse(line);
+ stream.emit('log', line);
+ } catch (e) {
+ stream.emit('error', e);
+ }
+ });
+
+ if(stream.resume){
+ stream.resume();
+ }
+
+ return stream;
+};
+
+//
+// ### function open (callback)
+// #### @callback {function} Continuation to respond to when complete
+// Checks to see if a new file needs to be created based on the `maxsize`
+// (if any) and the current size of the file used.
+//
+DailyRotateFile.prototype.open = function (callback) {
+ var now = new Date();
+ if (this.opening) {
+ //
+ // If we are already attempting to open the next
+ // available file then respond with a value indicating
+ // that the message should be buffered.
+ //
+ return callback(true);
+ }
+ else if (!this._stream || (this.maxsize && this._size >= this.maxsize) ||
+ (this._year < now.getFullYear() || this._month < now.getMonth() || this._date < now.getDate() || this._hour < now.getHours() || this._minute < now.getMinutes())) {
+ //
+ // If we dont have a stream or have exceeded our size, then create
+ // the next stream and respond with a value indicating that
+ // the message should be buffered.
+ //
+ callback(true);
+ return this._createStream();
+ }
+
+ //
+ // Otherwise we have a valid (and ready) stream.
+ //
+ callback();
+};
+
+//
+// ### function close ()
+// Closes the stream associated with this instance.
+//
+DailyRotateFile.prototype.close = function () {
+ var self = this;
+
+ if (this._stream) {
+ this._stream.end();
+ this._stream.destroySoon();
+
+ this._stream.once('drain', function () {
+ self.emit('flush');
+ self.emit('closed');
+ });
+ }
+};
+
+//
+// ### function flush ()
+// Flushes any buffered messages to the current `stream`
+// used by this instance.
+//
+DailyRotateFile.prototype.flush = function () {
+ var self = this;
+
+ //
+ // Iterate over the `_buffer` of enqueued messaged
+ // and then write them to the newly created stream.
+ //
+ this._buffer.forEach(function (item) {
+ var str = item[0],
+ callback = item[1];
+
+ process.nextTick(function () {
+ self._write(str, callback);
+ self._size += str.length;
+ });
+ });
+
+ //
+ // Quickly truncate the `_buffer` once the write operations
+ // have been started
+ //
+ self._buffer.length = 0;
+
+ //
+ // When the stream has drained we have flushed
+ // our buffer.
+ //
+ self._stream.once('drain', function () {
+ self.emit('flush');
+ self.emit('logged');
+ });
+};
+
+//
+// ### @private function _createStream ()
+// Attempts to open the next appropriate file for this instance
+// based on the common state (such as `maxsize` and `_basename`).
+//
+DailyRotateFile.prototype._createStream = function () {
+ var self = this;
+ this.opening = true;
+
+ (function checkFile (target) {
+ var fullname = path.join(self.dirname, target);
+
+ //
+ // Creates the `WriteStream` and then flushes any
+ // buffered messages.
+ //
+ function createAndFlush (size) {
+ if (self._stream) {
+ self._stream.end();
+ self._stream.destroySoon();
+ }
+
+ self._size = size;
+ self.filename = target;
+ self._stream = fs.createWriteStream(fullname, self.options);
+ self._stream.on('error', function(error){
+ if (self._failures < self.maxRetries) {
+ self._createStream();
+ self._failures++;
+ }
+ else {
+ self.emit('error', error);
+ }
+ });
+
+ //
+ // We need to listen for drain events when
+ // write() returns false. This can make node
+ // mad at times.
+ //
+ self._stream.setMaxListeners(Infinity);
+
+ //
+ // When the current stream has finished flushing
+ // then we can be sure we have finished opening
+ // and thus can emit the `open` event.
+ //
+ self.once('flush', function () {
+ self.opening = false;
+ self.emit('open', fullname);
+ });
+
+ //
+ // Remark: It is possible that in the time it has taken to find the
+ // next logfile to be written more data than `maxsize` has been buffered,
+ // but for sensible limits (10s - 100s of MB) this seems unlikely in less
+ // than one second.
+ //
+ self.flush();
+ }
+
+ fs.stat(fullname, function (err, stats) {
+ if (err) {
+ if (err.code !== 'ENOENT') {
+ return self.emit('error', err);
+ }
+
+ return createAndFlush(0);
+ }
+
+ if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
+ //
+ // If `stats.size` is greater than the `maxsize` for
+ // this instance then try again
+ //
+ return checkFile(self._getFile(true));
+ }
+
+ var now = new Date();
+ if (self._year < now.getFullYear() || self._month < now.getMonth() || self._date < now.getDate() || self._hour < now.getHours() || self._minute < now.getMinutes()) {
+ self._year = now.getFullYear();
+ self._month = now.getMonth();
+ self._date = now.getDate();
+ self._hour = now.getHours();
+ self._minute = now.getMinutes();
+ self._created = 0;
+ return checkFile(self._getFile());
+ }
+
+ createAndFlush(stats.size);
+ });
+ })(this._getFile());
+};
+
+//
+// ### @private function _getFile ()
+// Gets the next filename to use for this instance
+// in the case that log filesizes are being capped.
+//
+DailyRotateFile.prototype._getFile = function (inc) {
+ var self = this,
+ filename = this._basename + this.getFormattedDate(),
+ remaining;
+
+ if (inc) {
+ //
+ // Increment the number of files created or
+ // checked by this instance.
+ //
+ // Check for maxFiles option and delete file
+ if (this.maxFiles && (this._created >= (this.maxFiles - 1))) {
+ remaining = this._created - (this.maxFiles - 1);
+ if (remaining === 0) {
+ fs.unlinkSync(path.join(this.dirname, filename));
+ }
+ else {
+ fs.unlinkSync(path.join(this.dirname, filename + '.' + remaining));
+ }
+ }
+
+ this._created += 1;
+ }
+
+ return this._created
+ ? filename + '.' + this._created
+ : filename;
+};
+
+//
+// ### @private function _lazyDrain ()
+// Lazily attempts to emit the `logged` event when `this.stream` has
+// drained. This is really just a simple mutex that only works because
+// Node.js is single-threaded.
+//
+DailyRotateFile.prototype._lazyDrain = function () {
+ var self = this;
+
+ if (!this._draining && this._stream) {
+ this._draining = true;
+
+ this._stream.once('drain', function () {
+ this._draining = false;
+ self.emit('logged');
+ });
+ }
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports/file.js b/myapp/node_modules/winston/lib/winston/transports/file.js
new file mode 100644
index 0000000..b60fb92
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/file.js
@@ -0,0 +1,675 @@
+/*
+ * file.js: Transport for outputting to a local log file
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var events = require('events'),
+ fs = require('fs'),
+ path = require('path'),
+ util = require('util'),
+ async = require('async'),
+ zlib = require('zlib'),
+ common = require('../common'),
+ Transport = require('./transport').Transport,
+ isWritable = require('isstream').isWritable,
+ Stream = require('stream').Stream,
+ os = require('os');
+
+//
+// ### function File (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the File transport object responsible
+// for persisting log messages and metadata to one or more files.
+//
+var File = exports.File = function (options) {
+ var self = this;
+ Transport.call(this, options);
+
+ //
+ // Helper function which throws an `Error` in the event
+ // that any of the rest of the arguments is present in `options`.
+ //
+ function throwIf (target /*, illegal... */) {
+ Array.prototype.slice.call(arguments, 1).forEach(function (name) {
+ if (options[name]) {
+ throw new Error('Cannot set ' + name + ' and ' + target + 'together');
+ }
+ });
+ }
+
+ if (options.filename || options.dirname) {
+ throwIf('filename or dirname', 'stream');
+ this._basename = this.filename = options.filename
+ ? path.basename(options.filename)
+ : 'winston.log';
+
+ this.dirname = options.dirname || path.dirname(options.filename);
+ this.options = options.options || { flags: 'a' };
+
+ //
+ // "24 bytes" is maybe a good value for logging lines.
+ //
+ this.options.highWaterMark = this.options.highWaterMark || 24;
+ }
+ else if (options.stream) {
+ throwIf('stream', 'filename', 'maxsize');
+ this._stream = options.stream;
+ this._isStreams2 = isWritable(this._stream);
+ this._stream.on('error', function(error){
+ self.emit('error', error);
+ });
+ //
+ // We need to listen for drain events when
+ // write() returns false. This can make node
+ // mad at times.
+ //
+ this._stream.setMaxListeners(Infinity);
+ }
+ else {
+ throw new Error('Cannot log to file without filename or stream.');
+ }
+
+ this.json = options.json !== false;
+ this.logstash = options.logstash || false;
+ this.colorize = options.colorize || false;
+ this.maxsize = options.maxsize || null;
+ this.rotationFormat = options.rotationFormat || false;
+ this.zippedArchive = options.zippedArchive || false;
+ this.maxFiles = options.maxFiles || null;
+ this.prettyPrint = options.prettyPrint || false;
+ this.label = options.label || null;
+ this.timestamp = options.timestamp != null ? options.timestamp : true;
+ this.eol = options.eol || os.EOL;
+ this.tailable = options.tailable || false;
+ this.depth = options.depth || null;
+ this.showLevel = options.showLevel === undefined ? true : options.showLevel;
+ this.maxRetries = options.maxRetries || 2;
+
+ if (this.json) {
+ this.stringify = options.stringify;
+ }
+
+ //
+ // Internal state variables representing the number
+ // of files this instance has created and the current
+ // size (in bytes) of the current logfile.
+ //
+ this._size = 0;
+ this._created = 0;
+ this._buffer = [];
+ this._draining = false;
+ this._opening = false;
+ this._failures = 0;
+ this._archive = null;
+};
+
+//
+// Inherit from `winston.Transport`.
+//
+util.inherits(File, Transport);
+
+//
+// Expose the name of this Transport on the prototype
+//
+File.prototype.name = 'file';
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+File.prototype.log = function (level, msg, meta, callback) {
+ if (this.silent) {
+ return callback(null, true);
+ }
+
+ //
+ // If failures exceeds maxRetries then we can't access the
+ // stream. In this case we need to perform a noop and return
+ // an error.
+ //
+ if (this._failures >= this.maxRetries) {
+ return callback(new Error('Transport is in a failed state.'));
+ }
+
+ var self = this;
+
+ if (typeof msg !== 'string') {
+ msg = '' + msg;
+ }
+
+ var output = common.log({
+ level: level,
+ message: msg,
+ meta: meta,
+ json: this.json,
+ logstash: this.logstash,
+ colorize: this.colorize,
+ prettyPrint: this.prettyPrint,
+ timestamp: this.timestamp,
+ showLevel: this.showLevel,
+ stringify: this.stringify,
+ label: this.label,
+ depth: this.depth,
+ formatter: this.formatter,
+ humanReadableUnhandledException: this.humanReadableUnhandledException
+ }) + this.eol;
+
+
+ if (!this.filename) {
+ //
+ // If there is no `filename` on this instance then it was configured
+ // with a raw `WriteableStream` instance and we should not perform any
+ // size restrictions.
+ //
+ this._write(output, callback);
+ this._size += output.length;
+ this._lazyDrain();
+ }
+ else {
+ this.open(function (err) {
+ if (err) {
+ //
+ // If there was an error enqueue the message
+ //
+ return self._buffer.push([output, callback]);
+ }
+
+ self._write(output, callback);
+ self._size += output.length;
+ self._lazyDrain();
+ });
+ }
+};
+
+//
+// ### function _write (data, cb)
+// #### @data {String|Buffer} Data to write to the instance's stream.
+// #### @cb {function} Continuation to respond to when complete.
+// Write to the stream, ensure execution of a callback on completion.
+//
+File.prototype._write = function(data, callback) {
+ if (this._isStreams2) {
+ this._stream.write(data);
+ return callback && process.nextTick(function () {
+ callback(null, true);
+ });
+ }
+
+ // If this is a file write stream, we could use the builtin
+ // callback functionality, however, the stream is not guaranteed
+ // to be an fs.WriteStream.
+ var ret = this._stream.write(data);
+ if (!callback) return;
+ if (ret === false) {
+ return this._stream.once('drain', function() {
+ callback(null, true);
+ });
+ }
+ process.nextTick(function () {
+ callback(null, true);
+ });
+};
+
+//
+// ### function query (options, callback)
+// #### @options {Object} Loggly-like query options for this instance.
+// #### @callback {function} Continuation to respond to when complete.
+// Query the transport. Options object is optional.
+//
+File.prototype.query = function (options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+
+ var file = path.join(this.dirname, this.filename),
+ options = this.normalizeQuery(options),
+ buff = '',
+ results = [],
+ row = 0;
+
+ var stream = fs.createReadStream(file, {
+ encoding: 'utf8'
+ });
+
+ stream.on('error', function (err) {
+ if (stream.readable) {
+ stream.destroy();
+ }
+ if (!callback) return;
+ return err.code !== 'ENOENT'
+ ? callback(err)
+ : callback(null, results);
+ });
+
+ stream.on('data', function (data) {
+ var data = (buff + data).split(/\n+/),
+ l = data.length - 1,
+ i = 0;
+
+ for (; i < l; i++) {
+ if (!options.start || row >= options.start) {
+ add(data[i]);
+ }
+ row++;
+ }
+
+ buff = data[l];
+ });
+
+ stream.on('close', function () {
+ if (buff) add(buff, true);
+ if (options.order === 'desc') {
+ results = results.reverse();
+ }
+ if (callback) callback(null, results);
+ });
+
+ function add(buff, attempt) {
+ try {
+ var log = JSON.parse(buff);
+ if (check(log)) push(log);
+ } catch (e) {
+ if (!attempt) {
+ stream.emit('error', e);
+ }
+ }
+ }
+
+ function push(log) {
+ if (options.rows && results.length >= options.rows) {
+ if (stream.readable) {
+ stream.destroy();
+ }
+ return;
+ }
+
+ if (options.fields) {
+ var obj = {};
+ options.fields.forEach(function (key) {
+ obj[key] = log[key];
+ });
+ log = obj;
+ }
+
+ results.push(log);
+ }
+
+ function check(log) {
+ if (!log) return;
+
+ if (typeof log !== 'object') return;
+
+ var time = new Date(log.timestamp);
+ if ((options.from && time < options.from)
+ || (options.until && time > options.until)) {
+ return;
+ }
+
+ return true;
+ }
+};
+
+//
+// ### function stream (options)
+// #### @options {Object} Stream options for this instance.
+// Returns a log stream for this transport. Options object is optional.
+//
+File.prototype.stream = function (options) {
+ var file = path.join(this.dirname, this.filename),
+ options = options || {},
+ stream = new Stream;
+
+ var tail = {
+ file: file,
+ start: options.start
+ };
+
+ stream.destroy = common.tailFile(tail, function (err, line) {
+
+ if(err){
+ return stream.emit('error',err);
+ }
+
+ try {
+ stream.emit('data', line);
+ line = JSON.parse(line);
+ stream.emit('log', line);
+ } catch (e) {
+ stream.emit('error', e);
+ }
+ });
+
+ return stream;
+};
+
+//
+// ### function open (callback)
+// #### @callback {function} Continuation to respond to when complete
+// Checks to see if a new file needs to be created based on the `maxsize`
+// (if any) and the current size of the file used.
+//
+File.prototype.open = function (callback) {
+ if (this.opening) {
+ //
+ // If we are already attempting to open the next
+ // available file then respond with a value indicating
+ // that the message should be buffered.
+ //
+ return callback(true);
+ }
+ else if (!this._stream || (this.maxsize && this._size >= this.maxsize)) {
+ //
+ // If we dont have a stream or have exceeded our size, then create
+ // the next stream and respond with a value indicating that
+ // the message should be buffered.
+ //
+ callback(true);
+ return this._createStream();
+ }
+
+ this._archive = this.zippedArchive ? this._stream.path : null;
+
+ //
+ // Otherwise we have a valid (and ready) stream.
+ //
+ callback();
+};
+
+//
+// ### function close ()
+// Closes the stream associated with this instance.
+//
+File.prototype.close = function () {
+ var self = this;
+
+ if (this._stream) {
+ this._stream.end();
+ this._stream.destroySoon();
+
+ this._stream.once('drain', function () {
+ self.emit('flush');
+ self.emit('closed');
+ });
+ }
+};
+
+//
+// ### function flush ()
+// Flushes any buffered messages to the current `stream`
+// used by this instance.
+//
+File.prototype.flush = function () {
+ var self = this;
+
+ // If nothing to flush, there will be no "flush" event from native stream
+ // Thus, the "open" event will never be fired (see _createStream.createAndFlush function)
+ // That means, self.opening will never set to false and no logs will be written to disk
+ if (!this._buffer.length) {
+ return self.emit('flush');
+ }
+
+ //
+ // Iterate over the `_buffer` of enqueued messaged
+ // and then write them to the newly created stream.
+ //
+ this._buffer.forEach(function (item) {
+ var str = item[0],
+ callback = item[1];
+
+ process.nextTick(function () {
+ self._write(str, callback);
+ self._size += str.length;
+ });
+ });
+
+ //
+ // Quickly truncate the `_buffer` once the write operations
+ // have been started
+ //
+ self._buffer.length = 0;
+
+ //
+ // When the stream has drained we have flushed
+ // our buffer.
+ //
+ self._stream.once('drain', function () {
+ self.emit('flush');
+ self.emit('logged');
+ });
+};
+
+//
+// ### @private function _createStream ()
+// Attempts to open the next appropriate file for this instance
+// based on the common state (such as `maxsize` and `_basename`).
+//
+File.prototype._createStream = function () {
+ var self = this;
+ this.opening = true;
+
+ (function checkFile (target) {
+ var fullname = path.join(self.dirname, target);
+
+ //
+ // Creates the `WriteStream` and then flushes any
+ // buffered messages.
+ //
+ function createAndFlush (size) {
+ if (self._stream) {
+ self._stream.end();
+ self._stream.destroySoon();
+ }
+
+ self._size = size;
+ self.filename = target;
+ self._stream = fs.createWriteStream(fullname, self.options);
+ self._isStreams2 = isWritable(self._stream);
+ self._stream.on('error', function(error){
+ if (self._failures < self.maxRetries) {
+ self._createStream();
+ self._failures++;
+ }
+ else {
+ self.emit('error', error);
+ }
+ });
+ //
+ // We need to listen for drain events when
+ // write() returns false. This can make node
+ // mad at times.
+ //
+ self._stream.setMaxListeners(Infinity);
+
+ //
+ // When the current stream has finished flushing
+ // then we can be sure we have finished opening
+ // and thus can emit the `open` event.
+ //
+ self.once('flush', function () {
+ // Because "flush" event is based on native stream "drain" event,
+ // logs could be written inbetween "self.flush()" and here
+ // Therefore, we need to flush again to make sure everything is flushed
+ self.flush();
+
+ self.opening = false;
+ self.emit('open', fullname);
+ });
+ //
+ // Remark: It is possible that in the time it has taken to find the
+ // next logfile to be written more data than `maxsize` has been buffered,
+ // but for sensible limits (10s - 100s of MB) this seems unlikely in less
+ // than one second.
+ //
+ self.flush();
+ compressFile();
+ }
+
+ function compressFile() {
+ if (self._archive) {
+ var gzip = zlib.createGzip();
+
+ var inp = fs.createReadStream(String(self._archive));
+ var out = fs.createWriteStream(self._archive + '.gz');
+
+ inp.pipe(gzip).pipe(out);
+
+ fs.unlink(String(self._archive));
+ self._archive = '';
+ }
+ }
+
+ fs.stat(fullname, function (err, stats) {
+ if (err) {
+ if (err.code !== 'ENOENT') {
+ return self.emit('error', err);
+ }
+ return createAndFlush(0);
+ }
+
+ if (!stats || (self.maxsize && stats.size >= self.maxsize)) {
+ //
+ // If `stats.size` is greater than the `maxsize` for
+ // this instance then try again
+ //
+ return self._incFile(function() {
+ checkFile(self._getFile());
+ });
+ }
+
+ createAndFlush(stats.size);
+ });
+ })(this._getFile());
+};
+
+
+File.prototype._incFile = function (callback) {
+ var ext = path.extname(this._basename),
+ basename = path.basename(this._basename, ext),
+ oldest,
+ target;
+
+ if (!this.tailable) {
+ this._created += 1;
+ this._checkMaxFilesIncrementing(ext, basename, callback);
+ }
+ else {
+ this._checkMaxFilesTailable(ext, basename, callback);
+ }
+};
+
+//
+// ### @private function _getFile ()
+// Gets the next filename to use for this instance
+// in the case that log filesizes are being capped.
+//
+File.prototype._getFile = function () {
+ var ext = path.extname(this._basename),
+ basename = path.basename(this._basename, ext);
+
+ //
+ // Caveat emptor (indexzero): rotationFormat() was broken by design
+ // when combined with max files because the set of files to unlink
+ // is never stored.
+ //
+ return !this.tailable && this._created
+ ? basename + (this.rotationFormat ? this.rotationFormat() : this._created) + ext
+ : basename + ext;
+};
+
+//
+// ### @private function _checkMaxFilesIncrementing ()
+// Increment the number of files created or
+// checked by this instance.
+//
+File.prototype._checkMaxFilesIncrementing = function (ext, basename, callback) {
+ var oldest, target,
+ self = this;
+
+ if (self.zippedArchive) {
+ self._archive = path.join(self.dirname, basename +
+ ((self._created === 1) ? '' : self._created-1) +
+ ext);
+ }
+
+
+ // Check for maxFiles option and delete file
+ if (!self.maxFiles || self._created < self.maxFiles) {
+ return callback();
+ }
+
+ oldest = self._created - self.maxFiles;
+ target = path.join(self.dirname, basename + (oldest !== 0 ? oldest : '') + ext +
+ (self.zippedArchive ? '.gz' : ''));
+ fs.unlink(target, callback);
+};
+
+//
+// ### @private function _checkMaxFilesTailable ()
+//
+// Roll files forward based on integer, up to maxFiles.
+// e.g. if base if file.log and it becomes oversized, roll
+// to file1.log, and allow file.log to be re-used. If
+// file is oversized again, roll file1.log to file2.log,
+// roll file.log to file1.log, and so on.
+File.prototype._checkMaxFilesTailable = function (ext, basename, callback) {
+ var tasks = [],
+ self = this;
+
+ if (!this.maxFiles)
+ return;
+
+ for (var x = this.maxFiles - 1; x > 0; x--) {
+ tasks.push(function (i) {
+ return function (cb) {
+ var tmppath = path.join(self.dirname, basename + (i - 1) + ext +
+ (self.zippedArchive ? '.gz' : ''));
+ fs.exists(tmppath, function (exists) {
+ if (!exists) {
+ return cb(null);
+ }
+
+ fs.rename(tmppath, path.join(self.dirname, basename + i + ext +
+ (self.zippedArchive ? '.gz' : '')), cb);
+ });
+ };
+ }(x));
+ }
+
+ if (self.zippedArchive) {
+ self._archive = path.join(self.dirname, basename + 1 + ext);
+ }
+ async.series(tasks, function (err) {
+ fs.rename(
+ path.join(self.dirname, basename + ext),
+ path.join(self.dirname, basename + 1 + ext),
+ callback
+ );
+ });
+};
+
+//
+// ### @private function _lazyDrain ()
+// Lazily attempts to emit the `logged` event when `this.stream` has
+// drained. This is really just a simple mutex that only works because
+// Node.js is single-threaded.
+//
+File.prototype._lazyDrain = function () {
+ var self = this;
+
+ if (!this._draining && this._stream) {
+ this._draining = true;
+
+ this._stream.once('drain', function () {
+ this._draining = false;
+ self.emit('logged');
+ });
+ }
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports/http.js b/myapp/node_modules/winston/lib/winston/transports/http.js
new file mode 100644
index 0000000..f7e1af6
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/http.js
@@ -0,0 +1,232 @@
+var util = require('util'),
+ winston = require('../../winston'),
+ http = require('http'),
+ https = require('https'),
+ Stream = require('stream').Stream,
+ Transport = require('./transport').Transport;
+
+//
+// ### function Http (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the Http transport object responsible
+// for persisting log messages and metadata to a terminal or TTY.
+//
+var Http = exports.Http = function (options) {
+ Transport.call(this, options);
+ options = options || {};
+
+ this.name = 'http';
+ this.ssl = !!options.ssl;
+ this.host = options.host || 'localhost';
+ this.port = options.port;
+ this.auth = options.auth;
+ this.path = options.path || '';
+
+ if (!this.port) {
+ this.port = this.ssl ? 443 : 80;
+ }
+};
+
+util.inherits(Http, winston.Transport);
+
+//
+// Expose the name of this Transport on the prototype
+//
+Http.prototype.name = 'http';
+
+//
+// ### function _request (options, callback)
+// #### @callback {function} Continuation to respond to when complete.
+// Make a request to a winstond server or any http server which can
+// handle json-rpc.
+//
+Http.prototype._request = function (options, callback) {
+ options = options || {};
+
+ var auth = options.auth || this.auth,
+ path = options.path || this.path || '',
+ req;
+
+ delete options.auth;
+ delete options.path;
+
+ // Prepare options for outgoing HTTP request
+ req = (this.ssl ? https : http).request({
+ host: this.host,
+ port: this.port,
+ path: '/' + path.replace(/^\//, ''),
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ auth: (auth) ? auth.username + ':' + auth.password : ''
+ });
+
+ req.on('error', callback);
+ req.on('response', function (res) {
+ res.on('end', function () {
+ callback(null, res);
+ });
+
+ res.resume();
+ });
+
+ req.end(new Buffer(JSON.stringify(options), 'utf8'));
+};
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+Http.prototype.log = function (level, msg, meta, callback) {
+ var self = this;
+
+ if (typeof meta === 'function') {
+ callback = meta;
+ meta = {};
+ }
+
+ var options = {
+ method: 'collect',
+ params: {
+ level: level,
+ message: msg,
+ meta: meta
+ }
+ };
+
+ if (meta) {
+ if (meta.path) {
+ options.path = meta.path;
+ delete meta.path;
+ }
+
+ if (meta.auth) {
+ options.auth = meta.auth;
+ delete meta.auth;
+ }
+ }
+
+ this._request(options, function (err, res) {
+ if (res && res.statusCode !== 200) {
+ err = new Error('HTTP Status Code: ' + res.statusCode);
+ }
+
+ if (err) return callback(err);
+
+ // TODO: emit 'logged' correctly,
+ // keep track of pending logs.
+ self.emit('logged');
+
+ if (callback) callback(null, true);
+ });
+};
+
+//
+// ### function query (options, callback)
+// #### @options {Object} Loggly-like query options for this instance.
+// #### @callback {function} Continuation to respond to when complete.
+// Query the transport. Options object is optional.
+//
+Http.prototype.query = function (options, callback) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ }
+
+ var self = this,
+ options = this.normalizeQuery(options);
+
+ options = {
+ method: 'query',
+ params: options
+ };
+
+ if (options.params.path) {
+ options.path = options.params.path;
+ delete options.params.path;
+ }
+
+ if (options.params.auth) {
+ options.auth = options.params.auth;
+ delete options.params.auth;
+ }
+
+ this._request(options, function (err, res, body) {
+ if (res && res.statusCode !== 200) {
+ err = new Error('HTTP Status Code: ' + res.statusCode);
+ }
+
+ if (err) return callback(err);
+
+ if (typeof body === 'string') {
+ try {
+ body = JSON.parse(body);
+ } catch (e) {
+ return callback(e);
+ }
+ }
+
+ callback(null, body);
+ });
+};
+
+//
+// ### function stream (options)
+// #### @options {Object} Stream options for this instance.
+// Returns a log stream for this transport. Options object is optional.
+//
+Http.prototype.stream = function (options) {
+ options = options || {};
+
+ var self = this,
+ stream = new Stream,
+ req,
+ buff;
+
+ stream.destroy = function () {
+ req.destroy();
+ };
+
+ options = {
+ method: 'stream',
+ params: options
+ };
+
+ if (options.params.path) {
+ options.path = options.params.path;
+ delete options.params.path;
+ }
+
+ if (options.params.auth) {
+ options.auth = options.params.auth;
+ delete options.params.auth;
+ }
+
+ req = this._request(options);
+ buff = '';
+
+ req.on('data', function (data) {
+ var data = (buff + data).split(/\n+/),
+ l = data.length - 1,
+ i = 0;
+
+ for (; i < l; i++) {
+ try {
+ stream.emit('log', JSON.parse(data[i]));
+ } catch (e) {
+ stream.emit('error', e);
+ }
+ }
+
+ buff = data[l];
+ });
+
+ req.on('error', function (err) {
+ stream.emit('error', err);
+ });
+
+ return stream;
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports/memory.js b/myapp/node_modules/winston/lib/winston/transports/memory.js
new file mode 100644
index 0000000..e4f562e
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/memory.js
@@ -0,0 +1,89 @@
+var events = require('events'),
+ util = require('util'),
+ common = require('../common'),
+ Transport = require('./transport').Transport;
+
+//
+// ### function Memory (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the Memory transport object responsible
+// for persisting log messages and metadata to a memory array of messages.
+//
+var Memory = exports.Memory = function (options) {
+ Transport.call(this, options);
+ options = options || {};
+
+ this.errorOutput = [];
+ this.writeOutput = [];
+
+ this.json = options.json || false;
+ this.colorize = options.colorize || false;
+ this.prettyPrint = options.prettyPrint || false;
+ this.timestamp = typeof options.timestamp !== 'undefined' ? options.timestamp : false;
+ this.showLevel = options.showLevel === undefined ? true : options.showLevel;
+ this.label = options.label || null;
+ this.depth = options.depth || null;
+
+ if (this.json) {
+ this.stringify = options.stringify || function (obj) {
+ return JSON.stringify(obj, null, 2);
+ };
+ }
+};
+
+//
+// Inherit from `winston.Transport`.
+//
+util.inherits(Memory, Transport);
+
+//
+// Expose the name of this Transport on the prototype
+//
+Memory.prototype.name = 'memory';
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+Memory.prototype.log = function (level, msg, meta, callback) {
+ if (this.silent) {
+ return callback(null, true);
+ }
+
+ var self = this,
+ output;
+
+ output = common.log({
+ colorize: this.colorize,
+ json: this.json,
+ level: level,
+ message: msg,
+ meta: meta,
+ stringify: this.stringify,
+ timestamp: this.timestamp,
+ prettyPrint: this.prettyPrint,
+ raw: this.raw,
+ label: this.label,
+ depth: this.depth,
+ formatter: this.formatter,
+ humanReadableUnhandledException: this.humanReadableUnhandledException
+ });
+
+ if (level === 'error' || level === 'debug') {
+ this.errorOutput.push(output);
+ } else {
+ this.writeOutput.push(output);
+ }
+
+ self.emit('logged');
+ callback(null, true);
+};
+
+Memory.prototype.clearLogs = function () {
+ this.errorOutput = [];
+ this.writeOutput = [];
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports/transport.js b/myapp/node_modules/winston/lib/winston/transports/transport.js
new file mode 100644
index 0000000..93184af
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/transport.js
@@ -0,0 +1,131 @@
+/*
+ * transport.js: Base Transport object for all Winston transports.
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENCE
+ *
+ */
+
+var events = require('events'),
+ util = require('util');
+
+//
+// ### function Transport (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the Tranport object responsible
+// base functionality for all winston transports.
+//
+var Transport = exports.Transport = function (options) {
+ events.EventEmitter.call(this);
+
+ options = options || {};
+ this.silent = options.silent || false;
+ this.raw = options.raw || false;
+ this.name = options.name || this.name;
+ this.formatter = options.formatter;
+
+ //
+ // Do not set a default level. When `level` is falsey on any
+ // `Transport` instance, any `Logger` instance uses the
+ // configured level (instead of the Transport level)
+ //
+ this.level = options.level;
+
+ this.handleExceptions = options.handleExceptions || false;
+ this.exceptionsLevel = options.exceptionsLevel || 'error';
+ this.humanReadableUnhandledException = options.humanReadableUnhandledException || false;
+};
+
+//
+// Inherit from `events.EventEmitter`.
+//
+util.inherits(Transport, events.EventEmitter);
+
+//
+// ### function formatQuery (query)
+// #### @query {string|Object} Query to format
+// Formats the specified `query` Object (or string) to conform
+// with the underlying implementation of this transport.
+//
+Transport.prototype.formatQuery = function (query) {
+ return query;
+};
+
+//
+// ### function normalizeQuery (query)
+// #### @options {string|Object} Query to normalize
+// Normalize options for query
+//
+Transport.prototype.normalizeQuery = function (options) {
+ //
+ // Use options similar to loggly.
+ // [See Loggly Search API](http://wiki.loggly.com/retrieve_events#optional)
+ //
+
+ options = options || {};
+
+ // limit
+ options.rows = options.rows || options.limit || 10;
+
+ // starting row offset
+ options.start = options.start || 0;
+
+ // now
+ options.until = options.until || new Date;
+ if (typeof options.until !== 'object') {
+ options.until = new Date(options.until);
+ }
+
+ // now - 24
+ options.from = options.from || (options.until - (24 * 60 * 60 * 1000));
+ if (typeof options.from !== 'object') {
+ options.from = new Date(options.from);
+ }
+
+
+ // 'asc' or 'desc'
+ options.order = options.order || 'desc';
+
+ // which fields to select
+ options.fields = options.fields;
+
+ return options;
+};
+
+//
+// ### function formatResults (results, options)
+// #### @results {Object|Array} Results returned from `.query`.
+// #### @options {Object} **Optional** Formatting options
+// Formats the specified `results` with the given `options` accordinging
+// to the implementation of this transport.
+//
+Transport.prototype.formatResults = function (results, options) {
+ return results;
+};
+
+//
+// ### function logException (msg, meta, callback)
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Logs the specified `msg`, `meta` and responds to the callback once the log
+// operation is complete to ensure that the event loop will not exit before
+// all logging has completed.
+//
+Transport.prototype.logException = function (msg, meta, callback) {
+ var self = this;
+
+ function onLogged () {
+ self.removeListener('error', onError);
+ callback();
+ }
+
+ function onError () {
+ self.removeListener('logged', onLogged);
+ callback();
+ }
+
+ this.once('logged', onLogged);
+ this.once('error', onError);
+ this.log(self.exceptionsLevel, msg, meta, function () { });
+};
diff --git a/myapp/node_modules/winston/lib/winston/transports/webhook.js b/myapp/node_modules/winston/lib/winston/transports/webhook.js
new file mode 100644
index 0000000..ab0ca05
--- /dev/null
+++ b/myapp/node_modules/winston/lib/winston/transports/webhook.js
@@ -0,0 +1,146 @@
+/*
+ * webhook.js: Transport for logging to remote http endpoints ( POST / RECEIVE webhooks )
+ *
+ * (C) 2011 Marak Squires
+ * MIT LICENCE
+ *
+ */
+
+var events = require('events'),
+ http = require('http'),
+ https = require('https'),
+ util = require('util'),
+ cycle = require('cycle'),
+ common = require('../common'),
+ Transport = require('./transport').Transport;
+
+//
+// ### function WebHook (options)
+// #### @options {Object} Options for this instance.
+// Constructor function for the Console transport object responsible
+// for making arbitrary HTTP requests whenever log messages and metadata
+// are received.
+//
+var Webhook = exports.Webhook = function (options) {
+ Transport.call(this, options);
+
+ this.name = 'webhook';
+ this.host = options.host || 'localhost';
+ this.port = options.port || 8080;
+ this.method = options.method || 'POST';
+ this.path = options.path || '/winston-log';
+
+ if (options.auth) {
+ this.auth = {};
+ this.auth.username = options.auth.username || '';
+ this.auth.password = options.auth.password || '';
+ }
+
+ if (options.ssl) {
+ this.port = options.port || 443;
+ this.ssl = {
+ key: options.ssl.key || null,
+ cert: options.ssl.cert || null,
+ ca: options.ssl.ca
+ };
+ }
+};
+
+//
+// Inherit from `winston.Transport`.
+//
+util.inherits(Webhook, Transport);
+
+//
+// Expose the name of this Transport on the prototype
+//
+Webhook.prototype.name = 'webhook';
+
+//
+// ### function log (level, msg, [meta], callback)
+// #### @level {string} Level at which to log the message.
+// #### @msg {string} Message to log
+// #### @meta {Object} **Optional** Additional metadata to attach
+// #### @callback {function} Continuation to respond to when complete.
+// Core logging method exposed to Winston. Metadata is optional.
+//
+Webhook.prototype.log = function (level, msg, meta, callback) {
+ if (this.silent) {
+ return callback(null, true);
+ }
+
+ var self = this,
+ meta = cycle.decycle(meta),
+ message = common.clone(meta),
+ options,
+ req;
+
+ // Prepare options for outgoing HTTP request
+ options = {
+ host: this.host,
+ port: this.port,
+ path: this.path,
+ method: this.method,
+ headers: { 'Content-Type': 'application/json' }
+ };
+
+ if (this.ssl) {
+ options.ca = this.ssl.ca;
+ options.key = this.ssl.key;
+ options.cert = this.ssl.cert;
+
+ // Required for the test fixture SSL certificate to be considered valid.
+ options.rejectUnauthorized = false;
+ }
+
+ if (this.auth) {
+ // Encode `Authorization` header used by Basic Auth
+ options.headers['Authorization'] = 'Basic ' + new Buffer(
+ this.auth.username + ':' + this.auth.password, 'utf8'
+ ).toString('base64');
+ }
+
+ // Perform HTTP logging request
+ req = (self.ssl ? https : http).request(options, function (res) {
+ // TODO: emit 'logged' correctly,
+ // keep track of pending logs.
+ res.on('data', function(data) {
+ // Do nothing. We need to read the response, or we run into maxSockets
+ // after 5 requests.
+ });
+
+ self.emit('logged');
+ if (callback) callback(null, true);
+ callback = null;
+ });
+
+ req.on('error', function (err) {
+ //
+ // Propagate the `error` back up to the `Logger` that this
+ // instance belongs to.
+ //
+ self.emit('error', err);
+ if (callback) callback(err, false);
+ callback = null;
+ });
+
+ //
+ // Write logging event to the outgoing request body
+ //
+ // jsonMessage is currently conforming to JSON-RPC v1.0,
+ // but without the unique id since there is no anticipated response
+ // see: http://en.wikipedia.org/wiki/JSON-RPC
+ //
+
+ var params = common.clone(meta) || {};
+ params.timestamp = new Date();
+ params.message = msg;
+ params.level = level;
+
+ req.write(JSON.stringify({
+ method: 'log',
+ params: params
+ }));
+
+ req.end();
+};
diff --git a/myapp/node_modules/winston/node_modules/async/.travis.yml b/myapp/node_modules/winston/node_modules/async/.travis.yml
new file mode 100644
index 0000000..6064ca0
--- /dev/null
+++ b/myapp/node_modules/winston/node_modules/async/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - "0.10"
+ - "0.12"
+ - "iojs"
diff --git a/myapp/node_modules/winston/node_modules/async/LICENSE b/myapp/node_modules/winston/node_modules/async/LICENSE
new file mode 100644
index 0000000..8f29698
--- /dev/null
+++ b/myapp/node_modules/winston/node_modules/async/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2010-2014 Caolan McMahon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/myapp/node_modules/winston/node_modules/async/README.md b/myapp/node_modules/winston/node_modules/async/README.md
new file mode 100644
index 0000000..6cfb922
--- /dev/null
+++ b/myapp/node_modules/winston/node_modules/async/README.md
@@ -0,0 +1,1647 @@
+# Async.js
+
+[](https://travis-ci.org/caolan/async)
+
+
+Async is a utility module which provides straight-forward, powerful functions
+for working with asynchronous JavaScript. Although originally designed for
+use with [Node.js](http://nodejs.org) and installable via `npm install async`,
+it can also be used directly in the browser.
+
+Async is also installable via:
+
+- [bower](http://bower.io/): `bower install async`
+- [component](https://github.com/component/component): `component install
+ caolan/async`
+- [jam](http://jamjs.org/): `jam install async`
+- [spm](http://spmjs.io/): `spm install async`
+
+Async provides around 20 functions that include the usual 'functional'
+suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns
+for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these
+functions assume you follow the Node.js convention of providing a single
+callback as the last argument of your `async` function.
+
+
+## Quick Examples
+
+```javascript
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+ // results is now an array of stats for each file
+});
+
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+ // results now equals an array of the existing files
+});
+
+async.parallel([
+ function(){ ... },
+ function(){ ... }
+], callback);
+
+async.series([
+ function(){ ... },
+ function(){ ... }
+]);
+```
+
+There are many more functions available so take a look at the docs below for a
+full list. This module aims to be comprehensive, so if you feel anything is
+missing please create a GitHub issue for it.
+
+## Common Pitfalls
+
+### Binding a context to an iterator
+
+This section is really about `bind`, not about `async`. If you are wondering how to
+make `async` execute your iterators in a given context, or are confused as to why
+a method of another library isn't working as an iterator, study this example:
+
+```js
+// Here is a simple object with an (unnecessarily roundabout) squaring method
+var AsyncSquaringLibrary = {
+ squareExponent: 2,
+ square: function(number, callback){
+ var result = Math.pow(number, this.squareExponent);
+ setTimeout(function(){
+ callback(null, result);
+ }, 200);
+ }
+};
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){
+ // result is [NaN, NaN, NaN]
+ // This fails because the `this.squareExponent` expression in the square
+ // function is not evaluated in the context of AsyncSquaringLibrary, and is
+ // therefore undefined.
+});
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){
+ // result is [1, 4, 9]
+ // With the help of bind we can attach a context to the iterator before
+ // passing it to async. Now the square function will be executed in its
+ // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`
+ // will be as expected.
+});
+```
+
+## Download
+
+The source is available for download from
+[GitHub](http://github.com/caolan/async).
+Alternatively, you can install using Node Package Manager (`npm`):
+
+ npm install async
+
+__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed
+
+## In the Browser
+
+So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5.
+
+Usage:
+
+```html
+
+
+```
+
+## Documentation
+
+### Collections
+
+* [`each`](#each)
+* [`eachSeries`](#eachSeries)
+* [`eachLimit`](#eachLimit)
+* [`map`](#map)
+* [`mapSeries`](#mapSeries)
+* [`mapLimit`](#mapLimit)
+* [`filter`](#filter)
+* [`filterSeries`](#filterSeries)
+* [`reject`](#reject)
+* [`rejectSeries`](#rejectSeries)
+* [`reduce`](#reduce)
+* [`reduceRight`](#reduceRight)
+* [`detect`](#detect)
+* [`detectSeries`](#detectSeries)
+* [`sortBy`](#sortBy)
+* [`some`](#some)
+* [`every`](#every)
+* [`concat`](#concat)
+* [`concatSeries`](#concatSeries)
+
+### Control Flow
+
+* [`series`](#seriestasks-callback)
+* [`parallel`](#parallel)
+* [`parallelLimit`](#parallellimittasks-limit-callback)
+* [`whilst`](#whilst)
+* [`doWhilst`](#doWhilst)
+* [`until`](#until)
+* [`doUntil`](#doUntil)
+* [`forever`](#forever)
+* [`waterfall`](#waterfall)
+* [`compose`](#compose)
+* [`seq`](#seq)
+* [`applyEach`](#applyEach)
+* [`applyEachSeries`](#applyEachSeries)
+* [`queue`](#queue)
+* [`priorityQueue`](#priorityQueue)
+* [`cargo`](#cargo)
+* [`auto`](#auto)
+* [`retry`](#retry)
+* [`iterator`](#iterator)
+* [`apply`](#apply)
+* [`nextTick`](#nextTick)
+* [`times`](#times)
+* [`timesSeries`](#timesSeries)
+
+### Utils
+
+* [`memoize`](#memoize)
+* [`unmemoize`](#unmemoize)
+* [`log`](#log)
+* [`dir`](#dir)
+* [`noConflict`](#noConflict)
+
+
+## Collections
+
+
+
+### each(arr, iterator, callback)
+
+Applies the function `iterator` to each item in `arr`, in parallel.
+The `iterator` is called with an item from the list, and a callback for when it
+has finished. If the `iterator` passes an error to its `callback`, the main
+`callback` (for the `each` function) is immediately called with the error.
+
+Note, that since this function applies `iterator` to each item in parallel,
+there is no guarantee that the iterator functions will complete in order.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+ The iterator is passed a `callback(err)` which must be called once it has
+ completed. If no error has occurred, the `callback` should be run without
+ arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+ have finished, or an error occurs.
+
+__Examples__
+
+
+```js
+// assuming openFiles is an array of file names and saveFile is a function
+// to save the modified contents of that file:
+
+async.each(openFiles, saveFile, function(err){
+ // if any of the saves produced an error, err would equal that error
+});
+```
+
+```js
+// assuming openFiles is an array of file names
+
+async.each(openFiles, function(file, callback) {
+
+ // Perform operation on file here.
+ console.log('Processing file ' + file);
+
+ if( file.length > 32 ) {
+ console.log('This file name is too long');
+ callback('File name too long');
+ } else {
+ // Do work to process file here
+ console.log('File processed');
+ callback();
+ }
+}, function(err){
+ // if any of the file processing produced an error, err would equal that error
+ if( err ) {
+ // One of the iterations produced an error.
+ // All processing will now stop.
+ console.log('A file failed to process');
+ } else {
+ console.log('All files have been processed successfully');
+ }
+});
+```
+
+---------------------------------------
+
+
+
+### eachSeries(arr, iterator, callback)
+
+The same as [`each`](#each), only `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed.
+This means the `iterator` functions will complete in order.
+
+
+---------------------------------------
+
+
+
+### eachLimit(arr, limit, iterator, callback)
+
+The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously
+running at any time.
+
+Note that the items in `arr` are not processed in batches, so there is no guarantee that
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+ The iterator is passed a `callback(err)` which must be called once it has
+ completed. If no error has occurred, the callback should be run without
+ arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+ have finished, or an error occurs.
+
+__Example__
+
+```js
+// Assume documents is an array of JSON objects and requestApi is a
+// function that interacts with a rate-limited REST api.
+
+async.eachLimit(documents, 20, requestApi, function(err){
+ // if any of the saves produced an error, err would equal that error
+});
+```
+
+---------------------------------------
+
+
+### map(arr, iterator, callback)
+
+Produces a new array of values by mapping each value in `arr` through
+the `iterator` function. The `iterator` is called with an item from `arr` and a
+callback for when it has finished processing. Each of these callback takes 2 arguments:
+an `error`, and the transformed item from `arr`. If `iterator` passes an error to his
+callback, the main `callback` (for the `map` function) is immediately called with the error.
+
+Note, that since this function applies the `iterator` to each item in parallel,
+there is no guarantee that the `iterator` functions will complete in order.
+However, the results array will be in the same order as the original `arr`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+ The iterator is passed a `callback(err, transformed)` which must be called once
+ it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+ functions have finished, or an error occurs. Results is an array of the
+ transformed items from the `arr`.
+
+__Example__
+
+```js
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+ // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+
+### mapSeries(arr, iterator, callback)
+
+The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed.
+The results array will be in the same order as the original.
+
+
+---------------------------------------
+
+
+### mapLimit(arr, limit, iterator, callback)
+
+The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously
+running at any time.
+
+Note that the items are not processed in batches, so there is no guarantee that
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+ The iterator is passed a `callback(err, transformed)` which must be called once
+ it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+ calls have finished, or an error occurs. The result is an array of the
+ transformed items from the original `arr`.
+
+__Example__
+
+```js
+async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){
+ // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+
+
+### filter(arr, iterator, callback)
+
+__Alias:__ `select`
+
+Returns a new array of all the values in `arr` which pass an async truth test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. This operation is
+performed in parallel, but the results array will be in the same order as the
+original.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+ The `iterator` is passed a `callback(truthValue)`, which must be called with a
+ boolean argument once it has completed.
+* `callback(results)` - A callback which is called after all the `iterator`
+ functions have finished.
+
+__Example__
+
+```js
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+ // results now equals an array of the existing files
+});
+```
+
+---------------------------------------
+
+
+
+### filterSeries(arr, iterator, callback)
+
+__Alias:__ `selectSeries`
+
+The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed.
+The results array will be in the same order as the original.
+
+---------------------------------------
+
+
+### reject(arr, iterator, callback)
+
+The opposite of [`filter`](#filter). Removes values that pass an `async` truth test.
+
+---------------------------------------
+
+
+### rejectSeries(arr, iterator, callback)
+
+The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr`
+in series.
+
+
+---------------------------------------
+
+
+### reduce(arr, memo, iterator, callback)
+
+__Aliases:__ `inject`, `foldl`
+
+Reduces `arr` into a single value using an async `iterator` to return
+each successive step. `memo` is the initial state of the reduction.
+This function only operates in series.
+
+For performance reasons, it may make sense to split a call to this function into
+a parallel map, and then use the normal `Array.prototype.reduce` on the results.
+This function is for situations where each step in the reduction needs to be async;
+if you can get the data before reducing it, then it's probably a good idea to do so.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `memo` - The initial state of the reduction.
+* `iterator(memo, item, callback)` - A function applied to each item in the
+ array to produce the next step in the reduction. The `iterator` is passed a
+ `callback(err, reduction)` which accepts an optional error as its first
+ argument, and the state of the reduction as the second. If an error is
+ passed to the callback, the reduction is stopped and the main `callback` is
+ immediately called with the error.
+* `callback(err, result)` - A callback which is called after all the `iterator`
+ functions have finished. Result is the reduced value.
+
+__Example__
+
+```js
+async.reduce([1,2,3], 0, function(memo, item, callback){
+ // pointless async:
+ process.nextTick(function(){
+ callback(null, memo + item)
+ });
+}, function(err, result){
+ // result is now equal to the last value of memo, which is 6
+});
+```
+
+---------------------------------------
+
+
+### reduceRight(arr, memo, iterator, callback)
+
+__Alias:__ `foldr`
+
+Same as [`reduce`](#reduce), only operates on `arr` in reverse order.
+
+
+---------------------------------------
+
+
+### detect(arr, iterator, callback)
+
+Returns the first value in `arr` that passes an async truth test. The
+`iterator` is applied in parallel, meaning the first iterator to return `true` will
+fire the detect `callback` with that result. That means the result might not be
+the first item in the original `arr` (in terms of order) that passes the test.
+
+If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries).
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+ The iterator is passed a `callback(truthValue)` which must be called with a
+ boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+ `true`, or after all the `iterator` functions have finished. Result will be
+ the first item in the array that passes the truth test (iterator) or the
+ value `undefined` if none passed.
+
+__Example__
+
+```js
+async.detect(['file1','file2','file3'], fs.exists, function(result){
+ // result now equals the first file in the list that exists
+});
+```
+
+---------------------------------------
+
+
+### detectSeries(arr, iterator, callback)
+
+The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr`
+in series. This means the result is always the first in the original `arr` (in
+terms of array order) that passes the truth test.
+
+
+---------------------------------------
+
+
+### sortBy(arr, iterator, callback)
+
+Sorts a list by the results of running each `arr` value through an async `iterator`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+ The iterator is passed a `callback(err, sortValue)` which must be called once it
+ has completed with an error (which can be `null`) and a value to use as the sort
+ criteria.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+ functions have finished, or an error occurs. Results is the items from
+ the original `arr` sorted by the values returned by the `iterator` calls.
+
+__Example__
+
+```js
+async.sortBy(['file1','file2','file3'], function(file, callback){
+ fs.stat(file, function(err, stats){
+ callback(err, stats.mtime);
+ });
+}, function(err, results){
+ // results is now the original array of files sorted by
+ // modified date
+});
+```
+
+__Sort Order__
+
+By modifying the callback parameter the sorting order can be influenced:
+
+```js
+//ascending order
+async.sortBy([1,9,3,5], function(x, callback){
+ callback(null, x);
+}, function(err,result){
+ //result callback
+} );
+
+//descending order
+async.sortBy([1,9,3,5], function(x, callback){
+ callback(null, x*-1); //<- x*-1 instead of x, turns the order around
+}, function(err,result){
+ //result callback
+} );
+```
+
+---------------------------------------
+
+
+### some(arr, iterator, callback)
+
+__Alias:__ `any`
+
+Returns `true` if at least one element in the `arr` satisfies an async test.
+_The callback for each iterator call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. Once any iterator
+call returns `true`, the main `callback` is immediately called.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+ in parallel. The iterator is passed a callback(truthValue) which must be
+ called with a boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+ `true`, or after all the iterator functions have finished. Result will be
+ either `true` or `false` depending on the values of the async tests.
+
+__Example__
+
+```js
+async.some(['file1','file2','file3'], fs.exists, function(result){
+ // if result is true then at least one of the files exists
+});
+```
+
+---------------------------------------
+
+
+### every(arr, iterator, callback)
+
+__Alias:__ `all`
+
+Returns `true` if every element in `arr` satisfies an async test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+ in parallel. The iterator is passed a callback(truthValue) which must be
+ called with a boolean argument once it has completed.
+* `callback(result)` - A callback which is called after all the `iterator`
+ functions have finished. Result will be either `true` or `false` depending on
+ the values of the async tests.
+
+__Example__
+
+```js
+async.every(['file1','file2','file3'], fs.exists, function(result){
+ // if result is true then every file exists
+});
+```
+
+---------------------------------------
+
+
+### concat(arr, iterator, callback)
+
+Applies `iterator` to each item in `arr`, concatenating the results. Returns the
+concatenated list. The `iterator`s are called in parallel, and the results are
+concatenated as they return. There is no guarantee that the results array will
+be returned in the original order of `arr` passed to the `iterator` function.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+ The iterator is passed a `callback(err, results)` which must be called once it
+ has completed with an error (which can be `null`) and an array of results.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+ functions have finished, or an error occurs. Results is an array containing
+ the concatenated results of the `iterator` function.
+
+__Example__
+
+```js
+async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
+ // files is now a list of filenames that exist in the 3 directories
+});
+```
+
+---------------------------------------
+
+
+### concatSeries(arr, iterator, callback)
+
+Same as [`concat`](#concat), but executes in series instead of parallel.
+
+
+## Control Flow
+
+
+### series(tasks, [callback])
+
+Run the functions in the `tasks` array in series, each one running once the previous
+function has completed. If any functions in the series pass an error to its
+callback, no more functions are run, and `callback` is immediately called with the value of the error.
+Otherwise, `callback` receives an array of results when `tasks` have completed.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function, and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`series`](#series).
+
+**Note** that while many implementations preserve the order of object properties, the
+[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
+explicitly states that
+
+> The mechanics and order of enumerating the properties is not specified.
+
+So if you rely on the order in which your series of functions are executed, and want
+this to work on all platforms, consider using an array.
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed
+ a `callback(err, result)` it must call on completion with an error `err` (which can
+ be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+ have completed. This function gets a results array (or object) containing all
+ the result arguments passed to the `task` callbacks.
+
+__Example__
+
+```js
+async.series([
+ function(callback){
+ // do some stuff ...
+ callback(null, 'one');
+ },
+ function(callback){
+ // do some more stuff ...
+ callback(null, 'two');
+ }
+],
+// optional callback
+function(err, results){
+ // results is now equal to ['one', 'two']
+});
+
+
+// an example using an object instead of an array
+async.series({
+ one: function(callback){
+ setTimeout(function(){
+ callback(null, 1);
+ }, 200);
+ },
+ two: function(callback){
+ setTimeout(function(){
+ callback(null, 2);
+ }, 100);
+ }
+},
+function(err, results) {
+ // results is now equal to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+
+### parallel(tasks, [callback])
+
+Run the `tasks` array of functions in parallel, without waiting until the previous
+function has completed. If any of the functions pass an error to its
+callback, the main `callback` is immediately called with the value of the error.
+Once the `tasks` have completed, the results are passed to the final `callback` as an
+array.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`parallel`](#parallel).
+
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run. Each function is passed
+ a `callback(err, result)` which it must call on completion with an error `err`
+ (which can be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+ have completed. This function gets a results array (or object) containing all
+ the result arguments passed to the task callbacks.
+
+__Example__
+
+```js
+async.parallel([
+ function(callback){
+ setTimeout(function(){
+ callback(null, 'one');
+ }, 200);
+ },
+ function(callback){
+ setTimeout(function(){
+ callback(null, 'two');
+ }, 100);
+ }
+],
+// optional callback
+function(err, results){
+ // the results array will equal ['one','two'] even though
+ // the second function had a shorter timeout.
+});
+
+
+// an example using an object instead of an array
+async.parallel({
+ one: function(callback){
+ setTimeout(function(){
+ callback(null, 1);
+ }, 200);
+ },
+ two: function(callback){
+ setTimeout(function(){
+ callback(null, 2);
+ }, 100);
+ }
+},
+function(err, results) {
+ // results is now equals to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+
+### parallelLimit(tasks, limit, [callback])
+
+The same as [`parallel`](#parallel), only `tasks` are executed in parallel
+with a maximum of `limit` tasks executing at any time.
+
+Note that the `tasks` are not executed in batches, so there is no guarantee that
+the first `limit` tasks will complete before any others are started.
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed
+ a `callback(err, result)` it must call on completion with an error `err` (which can
+ be `null`) and an optional `result` value.
+* `limit` - The maximum number of `tasks` to run at any time.
+* `callback(err, results)` - An optional callback to run once all the functions
+ have completed. This function gets a results array (or object) containing all
+ the result arguments passed to the `task` callbacks.
+
+---------------------------------------
+
+
+### whilst(test, fn, callback)
+
+Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+__Arguments__
+
+* `test()` - synchronous truth test to perform before each execution of `fn`.
+* `fn(callback)` - A function which is called each time `test` passes. The function is
+ passed a `callback(err)`, which must be called once it has completed with an
+ optional `err` argument.
+* `callback(err)` - A callback which is called after the test fails and repeated
+ execution of `fn` has stopped.
+
+__Example__
+
+```js
+var count = 0;
+
+async.whilst(
+ function () { return count < 5; },
+ function (callback) {
+ count++;
+ setTimeout(callback, 1000);
+ },
+ function (err) {
+ // 5 seconds have passed
+ }
+);
+```
+
+---------------------------------------
+
+
+### doWhilst(fn, test, callback)
+
+The post-check version of [`whilst`](#whilst). To reflect the difference in
+the order of operations, the arguments `test` and `fn` are switched.
+
+`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
+
+---------------------------------------
+
+
+### until(test, fn, callback)
+
+Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+The inverse of [`whilst`](#whilst).
+
+---------------------------------------
+
+
+### doUntil(fn, test, callback)
+
+Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`.
+
+---------------------------------------
+
+
+### forever(fn, errback)
+
+Calls the asynchronous function `fn` with a callback parameter that allows it to
+call itself again, in series, indefinitely.
+
+If an error is passed to the callback then `errback` is called with the
+error, and execution stops, otherwise it will never be called.
+
+```js
+async.forever(
+ function(next) {
+ // next is suitable for passing to things that need a callback(err [, whatever]);
+ // it will result in this function being called again.
+ },
+ function(err) {
+ // if next is called with a value in its first parameter, it will appear
+ // in here as 'err', and execution will stop.
+ }
+);
+```
+
+---------------------------------------
+
+
+### waterfall(tasks, [callback])
+
+Runs the `tasks` array of functions in series, each passing their results to the next in
+the array. However, if any of the `tasks` pass an error to their own callback, the
+next function is not executed, and the main `callback` is immediately called with
+the error.
+
+__Arguments__
+
+* `tasks` - An array of functions to run, each function is passed a
+ `callback(err, result1, result2, ...)` it must call on completion. The first
+ argument is an error (which can be `null`) and any further arguments will be
+ passed as arguments in order to the next task.
+* `callback(err, [results])` - An optional callback to run once all the functions
+ have completed. This will be passed the results of the last task's callback.
+
+
+
+__Example__
+
+```js
+async.waterfall([
+ function(callback) {
+ callback(null, 'one', 'two');
+ },
+ function(arg1, arg2, callback) {
+ // arg1 now equals 'one' and arg2 now equals 'two'
+ callback(null, 'three');
+ },
+ function(arg1, callback) {
+ // arg1 now equals 'three'
+ callback(null, 'done');
+ }
+], function (err, result) {
+ // result now equals 'done'
+});
+```
+
+---------------------------------------
+
+### compose(fn1, fn2...)
+
+Creates a function which is a composition of the passed asynchronous
+functions. Each function consumes the return value of the function that
+follows. Composing functions `f()`, `g()`, and `h()` would produce the result of
+`f(g(h()))`, only this version uses callbacks to obtain the return values.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* `functions...` - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+function add1(n, callback) {
+ setTimeout(function () {
+ callback(null, n + 1);
+ }, 10);
+}
+
+function mul3(n, callback) {
+ setTimeout(function () {
+ callback(null, n * 3);
+ }, 10);
+}
+
+var add1mul3 = async.compose(mul3, add1);
+
+add1mul3(4, function (err, result) {
+ // result now equals 15
+});
+```
+
+---------------------------------------
+
+### seq(fn1, fn2...)
+
+Version of the compose function that is more natural to read.
+Each function consumes the return value of the previous function.
+It is the equivalent of [`compose`](#compose) with the arguments reversed.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* functions... - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+// Requires lodash (or underscore), express3 and dresende's orm2.
+// Part of an app, that fetches cats of the logged user.
+// This example uses `seq` function to avoid overnesting and error
+// handling clutter.
+app.get('/cats', function(request, response) {
+ var User = request.models.User;
+ async.seq(
+ _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data))
+ function(user, fn) {
+ user.getCats(fn); // 'getCats' has signature (callback(err, data))
+ }
+ )(req.session.user_id, function (err, cats) {
+ if (err) {
+ console.error(err);
+ response.json({ status: 'error', message: err.message });
+ } else {
+ response.json({ status: 'ok', message: 'Cats found', data: cats });
+ }
+ });
+});
+```
+
+---------------------------------------
+
+### applyEach(fns, args..., callback)
+
+Applies the provided arguments to each function in the array, calling
+`callback` after all functions have completed. If you only provide the first
+argument, then it will return a function which lets you pass in the
+arguments as if it were a single function call.
+
+__Arguments__
+
+* `fns` - the asynchronous functions to all call with the same arguments
+* `args...` - any number of separate arguments to pass to the function
+* `callback` - the final argument should be the callback, called when all
+ functions have completed processing
+
+
+__Example__
+
+```js
+async.applyEach([enableSearch, updateSchema], 'bucket', callback);
+
+// partial application example:
+async.each(
+ buckets,
+ async.applyEach([enableSearch, updateSchema]),
+ callback
+);
+```
+
+---------------------------------------
+
+
+### applyEachSeries(arr, iterator, callback)
+
+The same as [`applyEach`](#applyEach) only the functions are applied in series.
+
+---------------------------------------
+
+
+### queue(worker, concurrency)
+
+Creates a `queue` object with the specified `concurrency`. Tasks added to the
+`queue` are processed in parallel (up to the `concurrency` limit). If all
+`worker`s are in progress, the task is queued until one becomes available.
+Once a `worker` completes a `task`, that `task`'s callback is called.
+
+__Arguments__
+
+* `worker(task, callback)` - An asynchronous function for processing a queued
+ task, which must call its `callback(err)` argument when finished, with an
+ optional `error` as an argument.
+* `concurrency` - An `integer` for determining how many `worker` functions should be
+ run in parallel.
+
+__Queue objects__
+
+The `queue` object returned by this function has the following properties and
+methods:
+
+* `length()` - a function returning the number of items waiting to be processed.
+* `started` - a function returning whether or not any items have been pushed and processed by the queue
+* `running()` - a function returning the number of items currently being processed.
+* `idle()` - a function returning false if there are items waiting or being processed, or true if not.
+* `concurrency` - an integer for determining how many `worker` functions should be
+ run in parallel. This property can be changed after a `queue` is created to
+ alter the concurrency on-the-fly.
+* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once
+ the `worker` has finished processing the task. Instead of a single task, a `tasks` array
+ can be submitted. The respective callback is used for every task in the list.
+* `unshift(task, [callback])` - add a new task to the front of the `queue`.
+* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit,
+ and further tasks will be queued.
+* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.
+* `paused` - a boolean for determining whether the queue is in a paused state
+* `pause()` - a function that pauses the processing of tasks until `resume()` is called.
+* `resume()` - a function that resumes the processing of queued tasks when the queue is paused.
+* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle.
+
+__Example__
+
+```js
+// create a queue object with concurrency 2
+
+var q = async.queue(function (task, callback) {
+ console.log('hello ' + task.name);
+ callback();
+}, 2);
+
+
+// assign a callback
+q.drain = function() {
+ console.log('all items have been processed');
+}
+
+// add some items to the queue
+
+q.push({name: 'foo'}, function (err) {
+ console.log('finished processing foo');
+});
+q.push({name: 'bar'}, function (err) {
+ console.log('finished processing bar');
+});
+
+// add some items to the queue (batch-wise)
+
+q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {
+ console.log('finished processing item');
+});
+
+// add some items to the front of the queue
+
+q.unshift({name: 'bar'}, function (err) {
+ console.log('finished processing bar');
+});
+```
+
+
+---------------------------------------
+
+
+### priorityQueue(worker, concurrency)
+
+The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects:
+
+* `push(task, priority, [callback])` - `priority` should be a number. If an array of
+ `tasks` is given, all tasks will be assigned the same priority.
+* The `unshift` method was removed.
+
+---------------------------------------
+
+
+### cargo(worker, [payload])
+
+Creates a `cargo` object with the specified payload. Tasks added to the
+cargo will be processed altogether (up to the `payload` limit). If the
+`worker` is in progress, the task is queued until it becomes available. Once
+the `worker` has completed some tasks, each callback of those tasks is called.
+Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work.
+
+While [queue](#queue) passes only one task to one of a group of workers
+at a time, cargo passes an array of tasks to a single worker, repeating
+when the worker is finished.
+
+__Arguments__
+
+* `worker(tasks, callback)` - An asynchronous function for processing an array of
+ queued tasks, which must call its `callback(err)` argument when finished, with
+ an optional `err` argument.
+* `payload` - An optional `integer` for determining how many tasks should be
+ processed per round; if omitted, the default is unlimited.
+
+__Cargo objects__
+
+The `cargo` object returned by this function has the following properties and
+methods:
+
+* `length()` - A function returning the number of items waiting to be processed.
+* `payload` - An `integer` for determining how many tasks should be
+ process per round. This property can be changed after a `cargo` is created to
+ alter the payload on-the-fly.
+* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called
+ once the `worker` has finished processing the task. Instead of a single task, an array of `tasks`
+ can be submitted. The respective callback is used for every task in the list.
+* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued.
+* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`.
+
+__Example__
+
+```js
+// create a cargo object with payload 2
+
+var cargo = async.cargo(function (tasks, callback) {
+ for(var i=0; i
+### auto(tasks, [callback])
+
+Determines the best order for running the functions in `tasks`, based on their
+requirements. Each function can optionally depend on other functions being completed
+first, and each function is run as soon as its requirements are satisfied.
+
+If any of the functions pass an error to their callback, it will not
+complete (so any other functions depending on it will not run), and the main
+`callback` is immediately called with the error. Functions also receive an
+object containing the results of functions which have completed so far.
+
+Note, all functions are called with a `results` object as a second argument,
+so it is unsafe to pass functions in the `tasks` object which cannot handle the
+extra argument.
+
+For example, this snippet of code:
+
+```js
+async.auto({
+ readData: async.apply(fs.readFile, 'data.txt', 'utf-8')
+}, callback);
+```
+
+will have the effect of calling `readFile` with the results object as the last
+argument, which will fail:
+
+```js
+fs.readFile('data.txt', 'utf-8', cb, {});
+```
+
+Instead, wrap the call to `readFile` in a function which does not forward the
+`results` object:
+
+```js
+async.auto({
+ readData: function(cb, results){
+ fs.readFile('data.txt', 'utf-8', cb);
+ }
+}, callback);
+```
+
+__Arguments__
+
+* `tasks` - An object. Each of its properties is either a function or an array of
+ requirements, with the function itself the last item in the array. The object's key
+ of a property serves as the name of the task defined by that property,
+ i.e. can be used when specifying requirements for other tasks.
+ The function receives two arguments: (1) a `callback(err, result)` which must be
+ called when finished, passing an `error` (which can be `null`) and the result of
+ the function's execution, and (2) a `results` object, containing the results of
+ the previously executed functions.
+* `callback(err, results)` - An optional callback which is called when all the
+ tasks have been completed. It receives the `err` argument if any `tasks`
+ pass an error to their callback. Results are always returned; however, if
+ an error occurs, no further `tasks` will be performed, and the results
+ object will only contain partial results.
+
+
+__Example__
+
+```js
+async.auto({
+ get_data: function(callback){
+ console.log('in get_data');
+ // async code to get some data
+ callback(null, 'data', 'converted to array');
+ },
+ make_folder: function(callback){
+ console.log('in make_folder');
+ // async code to create a directory to store a file in
+ // this is run at the same time as getting the data
+ callback(null, 'folder');
+ },
+ write_file: ['get_data', 'make_folder', function(callback, results){
+ console.log('in write_file', JSON.stringify(results));
+ // once there is some data and the directory exists,
+ // write the data to a file in the directory
+ callback(null, 'filename');
+ }],
+ email_link: ['write_file', function(callback, results){
+ console.log('in email_link', JSON.stringify(results));
+ // once the file is written let's email a link to it...
+ // results.write_file contains the filename returned by write_file.
+ callback(null, {'file':results.write_file, 'email':'user@example.com'});
+ }]
+}, function(err, results) {
+ console.log('err = ', err);
+ console.log('results = ', results);
+});
+```
+
+This is a fairly trivial example, but to do this using the basic parallel and
+series functions would look like this:
+
+```js
+async.parallel([
+ function(callback){
+ console.log('in get_data');
+ // async code to get some data
+ callback(null, 'data', 'converted to array');
+ },
+ function(callback){
+ console.log('in make_folder');
+ // async code to create a directory to store a file in
+ // this is run at the same time as getting the data
+ callback(null, 'folder');
+ }
+],
+function(err, results){
+ async.series([
+ function(callback){
+ console.log('in write_file', JSON.stringify(results));
+ // once there is some data and the directory exists,
+ // write the data to a file in the directory
+ results.push('filename');
+ callback(null);
+ },
+ function(callback){
+ console.log('in email_link', JSON.stringify(results));
+ // once the file is written let's email a link to it...
+ callback(null, {'file':results.pop(), 'email':'user@example.com'});
+ }
+ ]);
+});
+```
+
+For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding
+new tasks much easier (and the code more readable).
+
+
+---------------------------------------
+
+
+### retry([times = 5], task, [callback])
+
+Attempts to get a successful response from `task` no more than `times` times before
+returning an error. If the task is successful, the `callback` will be passed the result
+of the successful task. If all attempts fail, the callback will be passed the error and
+result (if any) of the final attempt.
+
+__Arguments__
+
+* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5.
+* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)`
+ which must be called when finished, passing `err` (which can be `null`) and the `result` of
+ the function's execution, and (2) a `results` object, containing the results of
+ the previously executed functions (if nested inside another control flow).
+* `callback(err, results)` - An optional callback which is called when the
+ task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`.
+
+The [`retry`](#retry) function can be used as a stand-alone control flow by passing a
+callback, as shown below:
+
+```js
+async.retry(3, apiMethod, function(err, result) {
+ // do something with the result
+});
+```
+
+It can also be embeded within other control flow functions to retry individual methods
+that are not as reliable, like this:
+
+```js
+async.auto({
+ users: api.getUsers.bind(api),
+ payments: async.retry(3, api.getPayments.bind(api))
+}, function(err, results) {
+ // do something with the results
+});
+```
+
+
+---------------------------------------
+
+
+### iterator(tasks)
+
+Creates an iterator function which calls the next function in the `tasks` array,
+returning a continuation to call the next one after that. It's also possible to
+“peek” at the next iterator with `iterator.next()`.
+
+This function is used internally by the `async` module, but can be useful when
+you want to manually control the flow of functions in series.
+
+__Arguments__
+
+* `tasks` - An array of functions to run.
+
+__Example__
+
+```js
+var iterator = async.iterator([
+ function(){ sys.p('one'); },
+ function(){ sys.p('two'); },
+ function(){ sys.p('three'); }
+]);
+
+node> var iterator2 = iterator();
+'one'
+node> var iterator3 = iterator2();
+'two'
+node> iterator3();
+'three'
+node> var nextfn = iterator2.next();
+node> nextfn();
+'three'
+```
+
+---------------------------------------
+
+
+### apply(function, arguments..)
+
+Creates a continuation function with some arguments already applied.
+
+Useful as a shorthand when combined with other control flow functions. Any arguments
+passed to the returned function are added to the arguments originally passed
+to apply.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to automatically apply when the
+ continuation is called.
+
+__Example__
+
+```js
+// using apply
+
+async.parallel([
+ async.apply(fs.writeFile, 'testfile1', 'test1'),
+ async.apply(fs.writeFile, 'testfile2', 'test2'),
+]);
+
+
+// the same process without using apply
+
+async.parallel([
+ function(callback){
+ fs.writeFile('testfile1', 'test1', callback);
+ },
+ function(callback){
+ fs.writeFile('testfile2', 'test2', callback);
+ }
+]);
+```
+
+It's possible to pass any number of additional arguments when calling the
+continuation:
+
+```js
+node> var fn = async.apply(sys.puts, 'one');
+node> fn('two', 'three');
+one
+two
+three
+```
+
+---------------------------------------
+
+
+### nextTick(callback), setImmediate(callback)
+
+Calls `callback` on a later loop around the event loop. In Node.js this just
+calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)`
+if available, otherwise `setTimeout(callback, 0)`, which means other higher priority
+events may precede the execution of `callback`.
+
+This is used internally for browser-compatibility purposes.
+
+__Arguments__
+
+* `callback` - The function to call on a later loop around the event loop.
+
+__Example__
+
+```js
+var call_order = [];
+async.nextTick(function(){
+ call_order.push('two');
+ // call_order now equals ['one','two']
+});
+call_order.push('one')
+```
+
+
+### times(n, callback)
+
+Calls the `callback` function `n` times, and accumulates results in the same manner
+you would use with [`map`](#map).
+
+__Arguments__
+
+* `n` - The number of times to run the function.
+* `callback` - The function to call `n` times.
+
+__Example__
+
+```js
+// Pretend this is some complicated async factory
+var createUser = function(id, callback) {
+ callback(null, {
+ id: 'user' + id
+ })
+}
+// generate 5 users
+async.times(5, function(n, next){
+ createUser(n, function(err, user) {
+ next(err, user)
+ })
+}, function(err, users) {
+ // we should now have 5 users
+});
+```
+
+
+### timesSeries(n, callback)
+
+The same as [`times`](#times), only the iterator is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed.
+The results array will be in the same order as the original.
+
+
+## Utils
+
+
+### memoize(fn, [hasher])
+
+Caches the results of an `async` function. When creating a hash to store function
+results against, the callback is omitted from the hash and an optional hash
+function can be used.
+
+The cache of results is exposed as the `memo` property of the function returned
+by `memoize`.
+
+__Arguments__
+
+* `fn` - The function to proxy and cache results from.
+* `hasher` - Tn optional function for generating a custom hash for storing
+ results. It has all the arguments applied to it apart from the callback, and
+ must be synchronous.
+
+__Example__
+
+```js
+var slow_fn = function (name, callback) {
+ // do something
+ callback(null, result);
+};
+var fn = async.memoize(slow_fn);
+
+// fn can now be used as if it were slow_fn
+fn('some name', function () {
+ // callback
+});
+```
+
+
+### unmemoize(fn)
+
+Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized
+form. Handy for testing.
+
+__Arguments__
+
+* `fn` - the memoized function
+
+
+### log(function, arguments)
+
+Logs the result of an `async` function to the `console`. Only works in Node.js or
+in browsers that support `console.log` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.log` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+ setTimeout(function(){
+ callback(null, 'hello ' + name);
+ }, 1000);
+};
+```
+```js
+node> async.log(hello, 'world');
+'hello world'
+```
+
+---------------------------------------
+
+
+### dir(function, arguments)
+
+Logs the result of an `async` function to the `console` using `console.dir` to
+display the properties of the resulting object. Only works in Node.js or
+in browsers that support `console.dir` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.dir` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+ setTimeout(function(){
+ callback(null, {hello: name});
+ }, 1000);
+};
+```
+```js
+node> async.dir(hello, 'world');
+{hello: 'world'}
+```
+
+---------------------------------------
+
+
+### noConflict()
+
+Changes the value of `async` back to its original value, returning a reference to the
+`async` object.
diff --git a/myapp/node_modules/winston/node_modules/async/bower.json b/myapp/node_modules/winston/node_modules/async/bower.json
new file mode 100644
index 0000000..1817688
--- /dev/null
+++ b/myapp/node_modules/winston/node_modules/async/bower.json
@@ -0,0 +1,38 @@
+{
+ "name": "async",
+ "description": "Higher-order functions and common patterns for asynchronous code",
+ "version": "0.9.2",
+ "main": "lib/async.js",
+ "keywords": [
+ "async",
+ "callback",
+ "utility",
+ "module"
+ ],
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/caolan/async.git"
+ },
+ "devDependencies": {
+ "nodeunit": ">0.0.0",
+ "uglify-js": "1.2.x",
+ "nodelint": ">0.0.0",
+ "lodash": ">=2.4.1"
+ },
+ "moduleType": [
+ "amd",
+ "globals",
+ "node"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "authors": [
+ "Caolan McMahon"
+ ]
+}
\ No newline at end of file
diff --git a/myapp/node_modules/winston/node_modules/async/component.json b/myapp/node_modules/winston/node_modules/async/component.json
new file mode 100644
index 0000000..5003a7c
--- /dev/null
+++ b/myapp/node_modules/winston/node_modules/async/component.json
@@ -0,0 +1,16 @@
+{
+ "name": "async",
+ "description": "Higher-order functions and common patterns for asynchronous code",
+ "version": "0.9.2",
+ "keywords": [
+ "async",
+ "callback",
+ "utility",
+ "module"
+ ],
+ "license": "MIT",
+ "repository": "caolan/async",
+ "scripts": [
+ "lib/async.js"
+ ]
+}
\ No newline at end of file
diff --git a/myapp/node_modules/winston/node_modules/async/lib/async.js b/myapp/node_modules/winston/node_modules/async/lib/async.js
new file mode 100644
index 0000000..394c41c
--- /dev/null
+++ b/myapp/node_modules/winston/node_modules/async/lib/async.js
@@ -0,0 +1,1123 @@
+/*!
+ * async
+ * https://github.com/caolan/async
+ *
+ * Copyright 2010-2014 Caolan McMahon
+ * Released under the MIT license
+ */
+/*jshint onevar: false, indent:4 */
+/*global setImmediate: false, setTimeout: false, console: false */
+(function () {
+
+ var async = {};
+
+ // global on the server, window in the browser
+ var root, previous_async;
+
+ root = this;
+ if (root != null) {
+ previous_async = root.async;
+ }
+
+ async.noConflict = function () {
+ root.async = previous_async;
+ return async;
+ };
+
+ function only_once(fn) {
+ var called = false;
+ return function() {
+ if (called) throw new Error("Callback was already called.");
+ called = true;
+ fn.apply(root, arguments);
+ }
+ }
+
+ //// cross-browser compatiblity functions ////
+
+ var _toString = Object.prototype.toString;
+
+ var _isArray = Array.isArray || function (obj) {
+ return _toString.call(obj) === '[object Array]';
+ };
+
+ var _each = function (arr, iterator) {
+ for (var i = 0; i < arr.length; i += 1) {
+ iterator(arr[i], i, arr);
+ }
+ };
+
+ var _map = function (arr, iterator) {
+ if (arr.map) {
+ return arr.map(iterator);
+ }
+ var results = [];
+ _each(arr, function (x, i, a) {
+ results.push(iterator(x, i, a));
+ });
+ return results;
+ };
+
+ var _reduce = function (arr, iterator, memo) {
+ if (arr.reduce) {
+ return arr.reduce(iterator, memo);
+ }
+ _each(arr, function (x, i, a) {
+ memo = iterator(memo, x, i, a);
+ });
+ return memo;
+ };
+
+ var _keys = function (obj) {
+ if (Object.keys) {
+ return Object.keys(obj);
+ }
+ var keys = [];
+ for (var k in obj) {
+ if (obj.hasOwnProperty(k)) {
+ keys.push(k);
+ }
+ }
+ return keys;
+ };
+
+ //// exported async module functions ////
+
+ //// nextTick implementation with browser-compatible fallback ////
+ if (typeof process === 'undefined' || !(process.nextTick)) {
+ if (typeof setImmediate === 'function') {
+ async.nextTick = function (fn) {
+ // not a direct alias for IE10 compatibility
+ setImmediate(fn);
+ };
+ async.setImmediate = async.nextTick;
+ }
+ else {
+ async.nextTick = function (fn) {
+ setTimeout(fn, 0);
+ };
+ async.setImmediate = async.nextTick;
+ }
+ }
+ else {
+ async.nextTick = process.nextTick;
+ if (typeof setImmediate !== 'undefined') {
+ async.setImmediate = function (fn) {
+ // not a direct alias for IE10 compatibility
+ setImmediate(fn);
+ };
+ }
+ else {
+ async.setImmediate = async.nextTick;
+ }
+ }
+
+ async.each = function (arr, iterator, callback) {
+ callback = callback || function () {};
+ if (!arr.length) {
+ return callback();
+ }
+ var completed = 0;
+ _each(arr, function (x) {
+ iterator(x, only_once(done) );
+ });
+ function done(err) {
+ if (err) {
+ callback(err);
+ callback = function () {};
+ }
+ else {
+ completed += 1;
+ if (completed >= arr.length) {
+ callback();
+ }
+ }
+ }
+ };
+ async.forEach = async.each;
+
+ async.eachSeries = function (arr, iterator, callback) {
+ callback = callback || function () {};
+ if (!arr.length) {
+ return callback();
+ }
+ var completed = 0;
+ var iterate = function () {
+ iterator(arr[completed], function (err) {
+ if (err) {
+ callback(err);
+ callback = function () {};
+ }
+ else {
+ completed += 1;
+ if (completed >= arr.length) {
+ callback();
+ }
+ else {
+ iterate();
+ }
+ }
+ });
+ };
+ iterate();
+ };
+ async.forEachSeries = async.eachSeries;
+
+ async.eachLimit = function (arr, limit, iterator, callback) {
+ var fn = _eachLimit(limit);
+ fn.apply(null, [arr, iterator, callback]);
+ };
+ async.forEachLimit = async.eachLimit;
+
+ var _eachLimit = function (limit) {
+
+ return function (arr, iterator, callback) {
+ callback = callback || function () {};
+ if (!arr.length || limit <= 0) {
+ return callback();
+ }
+ var completed = 0;
+ var started = 0;
+ var running = 0;
+
+ (function replenish () {
+ if (completed >= arr.length) {
+ return callback();
+ }
+
+ while (running < limit && started < arr.length) {
+ started += 1;
+ running += 1;
+ iterator(arr[started - 1], function (err) {
+ if (err) {
+ callback(err);
+ callback = function () {};
+ }
+ else {
+ completed += 1;
+ running -= 1;
+ if (completed >= arr.length) {
+ callback();
+ }
+ else {
+ replenish();
+ }
+ }
+ });
+ }
+ })();
+ };
+ };
+
+
+ var doParallel = function (fn) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments);
+ return fn.apply(null, [async.each].concat(args));
+ };
+ };
+ var doParallelLimit = function(limit, fn) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments);
+ return fn.apply(null, [_eachLimit(limit)].concat(args));
+ };
+ };
+ var doSeries = function (fn) {
+ return function () {
+ var args = Array.prototype.slice.call(arguments);
+ return fn.apply(null, [async.eachSeries].concat(args));
+ };
+ };
+
+
+ var _asyncMap = function (eachfn, arr, iterator, callback) {
+ arr = _map(arr, function (x, i) {
+ return {index: i, value: x};
+ });
+ if (!callback) {
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (err) {
+ callback(err);
+ });
+ });
+ } else {
+ var results = [];
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (err, v) {
+ results[x.index] = v;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, results);
+ });
+ }
+ };
+ async.map = doParallel(_asyncMap);
+ async.mapSeries = doSeries(_asyncMap);
+ async.mapLimit = function (arr, limit, iterator, callback) {
+ return _mapLimit(limit)(arr, iterator, callback);
+ };
+
+ var _mapLimit = function(limit) {
+ return doParallelLimit(limit, _asyncMap);
+ };
+
+ // reduce only has a series version, as doing reduce in parallel won't
+ // work in many situations.
+ async.reduce = function (arr, memo, iterator, callback) {
+ async.eachSeries(arr, function (x, callback) {
+ iterator(memo, x, function (err, v) {
+ memo = v;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, memo);
+ });
+ };
+ // inject alias
+ async.inject = async.reduce;
+ // foldl alias
+ async.foldl = async.reduce;
+
+ async.reduceRight = function (arr, memo, iterator, callback) {
+ var reversed = _map(arr, function (x) {
+ return x;
+ }).reverse();
+ async.reduce(reversed, memo, iterator, callback);
+ };
+ // foldr alias
+ async.foldr = async.reduceRight;
+
+ var _filter = function (eachfn, arr, iterator, callback) {
+ var results = [];
+ arr = _map(arr, function (x, i) {
+ return {index: i, value: x};
+ });
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (v) {
+ if (v) {
+ results.push(x);
+ }
+ callback();
+ });
+ }, function (err) {
+ callback(_map(results.sort(function (a, b) {
+ return a.index - b.index;
+ }), function (x) {
+ return x.value;
+ }));
+ });
+ };
+ async.filter = doParallel(_filter);
+ async.filterSeries = doSeries(_filter);
+ // select alias
+ async.select = async.filter;
+ async.selectSeries = async.filterSeries;
+
+ var _reject = function (eachfn, arr, iterator, callback) {
+ var results = [];
+ arr = _map(arr, function (x, i) {
+ return {index: i, value: x};
+ });
+ eachfn(arr, function (x, callback) {
+ iterator(x.value, function (v) {
+ if (!v) {
+ results.push(x);
+ }
+ callback();
+ });
+ }, function (err) {
+ callback(_map(results.sort(function (a, b) {
+ return a.index - b.index;
+ }), function (x) {
+ return x.value;
+ }));
+ });
+ };
+ async.reject = doParallel(_reject);
+ async.rejectSeries = doSeries(_reject);
+
+ var _detect = function (eachfn, arr, iterator, main_callback) {
+ eachfn(arr, function (x, callback) {
+ iterator(x, function (result) {
+ if (result) {
+ main_callback(x);
+ main_callback = function () {};
+ }
+ else {
+ callback();
+ }
+ });
+ }, function (err) {
+ main_callback();
+ });
+ };
+ async.detect = doParallel(_detect);
+ async.detectSeries = doSeries(_detect);
+
+ async.some = function (arr, iterator, main_callback) {
+ async.each(arr, function (x, callback) {
+ iterator(x, function (v) {
+ if (v) {
+ main_callback(true);
+ main_callback = function () {};
+ }
+ callback();
+ });
+ }, function (err) {
+ main_callback(false);
+ });
+ };
+ // any alias
+ async.any = async.some;
+
+ async.every = function (arr, iterator, main_callback) {
+ async.each(arr, function (x, callback) {
+ iterator(x, function (v) {
+ if (!v) {
+ main_callback(false);
+ main_callback = function () {};
+ }
+ callback();
+ });
+ }, function (err) {
+ main_callback(true);
+ });
+ };
+ // all alias
+ async.all = async.every;
+
+ async.sortBy = function (arr, iterator, callback) {
+ async.map(arr, function (x, callback) {
+ iterator(x, function (err, criteria) {
+ if (err) {
+ callback(err);
+ }
+ else {
+ callback(null, {value: x, criteria: criteria});
+ }
+ });
+ }, function (err, results) {
+ if (err) {
+ return callback(err);
+ }
+ else {
+ var fn = function (left, right) {
+ var a = left.criteria, b = right.criteria;
+ return a < b ? -1 : a > b ? 1 : 0;
+ };
+ callback(null, _map(results.sort(fn), function (x) {
+ return x.value;
+ }));
+ }
+ });
+ };
+
+ async.auto = function (tasks, callback) {
+ callback = callback || function () {};
+ var keys = _keys(tasks);
+ var remainingTasks = keys.length
+ if (!remainingTasks) {
+ return callback();
+ }
+
+ var results = {};
+
+ var listeners = [];
+ var addListener = function (fn) {
+ listeners.unshift(fn);
+ };
+ var removeListener = function (fn) {
+ for (var i = 0; i < listeners.length; i += 1) {
+ if (listeners[i] === fn) {
+ listeners.splice(i, 1);
+ return;
+ }
+ }
+ };
+ var taskComplete = function () {
+ remainingTasks--
+ _each(listeners.slice(0), function (fn) {
+ fn();
+ });
+ };
+
+ addListener(function () {
+ if (!remainingTasks) {
+ var theCallback = callback;
+ // prevent final callback from calling itself if it errors
+ callback = function () {};
+
+ theCallback(null, results);
+ }
+ });
+
+ _each(keys, function (k) {
+ var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
+ var taskCallback = function (err) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ if (err) {
+ var safeResults = {};
+ _each(_keys(results), function(rkey) {
+ safeResults[rkey] = results[rkey];
+ });
+ safeResults[k] = args;
+ callback(err, safeResults);
+ // stop subsequent errors hitting callback multiple times
+ callback = function () {};
+ }
+ else {
+ results[k] = args;
+ async.setImmediate(taskComplete);
+ }
+ };
+ var requires = task.slice(0, Math.abs(task.length - 1)) || [];
+ var ready = function () {
+ return _reduce(requires, function (a, x) {
+ return (a && results.hasOwnProperty(x));
+ }, true) && !results.hasOwnProperty(k);
+ };
+ if (ready()) {
+ task[task.length - 1](taskCallback, results);
+ }
+ else {
+ var listener = function () {
+ if (ready()) {
+ removeListener(listener);
+ task[task.length - 1](taskCallback, results);
+ }
+ };
+ addListener(listener);
+ }
+ });
+ };
+
+ async.retry = function(times, task, callback) {
+ var DEFAULT_TIMES = 5;
+ var attempts = [];
+ // Use defaults if times not passed
+ if (typeof times === 'function') {
+ callback = task;
+ task = times;
+ times = DEFAULT_TIMES;
+ }
+ // Make sure times is a number
+ times = parseInt(times, 10) || DEFAULT_TIMES;
+ var wrappedTask = function(wrappedCallback, wrappedResults) {
+ var retryAttempt = function(task, finalAttempt) {
+ return function(seriesCallback) {
+ task(function(err, result){
+ seriesCallback(!err || finalAttempt, {err: err, result: result});
+ }, wrappedResults);
+ };
+ };
+ while (times) {
+ attempts.push(retryAttempt(task, !(times-=1)));
+ }
+ async.series(attempts, function(done, data){
+ data = data[data.length - 1];
+ (wrappedCallback || callback)(data.err, data.result);
+ });
+ }
+ // If a callback is passed, run this as a controll flow
+ return callback ? wrappedTask() : wrappedTask
+ };
+
+ async.waterfall = function (tasks, callback) {
+ callback = callback || function () {};
+ if (!_isArray(tasks)) {
+ var err = new Error('First argument to waterfall must be an array of functions');
+ return callback(err);
+ }
+ if (!tasks.length) {
+ return callback();
+ }
+ var wrapIterator = function (iterator) {
+ return function (err) {
+ if (err) {
+ callback.apply(null, arguments);
+ callback = function () {};
+ }
+ else {
+ var args = Array.prototype.slice.call(arguments, 1);
+ var next = iterator.next();
+ if (next) {
+ args.push(wrapIterator(next));
+ }
+ else {
+ args.push(callback);
+ }
+ async.setImmediate(function () {
+ iterator.apply(null, args);
+ });
+ }
+ };
+ };
+ wrapIterator(async.iterator(tasks))();
+ };
+
+ var _parallel = function(eachfn, tasks, callback) {
+ callback = callback || function () {};
+ if (_isArray(tasks)) {
+ eachfn.map(tasks, function (fn, callback) {
+ if (fn) {
+ fn(function (err) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ callback.call(null, err, args);
+ });
+ }
+ }, callback);
+ }
+ else {
+ var results = {};
+ eachfn.each(_keys(tasks), function (k, callback) {
+ tasks[k](function (err) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ results[k] = args;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, results);
+ });
+ }
+ };
+
+ async.parallel = function (tasks, callback) {
+ _parallel({ map: async.map, each: async.each }, tasks, callback);
+ };
+
+ async.parallelLimit = function(tasks, limit, callback) {
+ _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
+ };
+
+ async.series = function (tasks, callback) {
+ callback = callback || function () {};
+ if (_isArray(tasks)) {
+ async.mapSeries(tasks, function (fn, callback) {
+ if (fn) {
+ fn(function (err) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ callback.call(null, err, args);
+ });
+ }
+ }, callback);
+ }
+ else {
+ var results = {};
+ async.eachSeries(_keys(tasks), function (k, callback) {
+ tasks[k](function (err) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (args.length <= 1) {
+ args = args[0];
+ }
+ results[k] = args;
+ callback(err);
+ });
+ }, function (err) {
+ callback(err, results);
+ });
+ }
+ };
+
+ async.iterator = function (tasks) {
+ var makeCallback = function (index) {
+ var fn = function () {
+ if (tasks.length) {
+ tasks[index].apply(null, arguments);
+ }
+ return fn.next();
+ };
+ fn.next = function () {
+ return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+ };
+ return fn;
+ };
+ return makeCallback(0);
+ };
+
+ async.apply = function (fn) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return function () {
+ return fn.apply(
+ null, args.concat(Array.prototype.slice.call(arguments))
+ );
+ };
+ };
+
+ var _concat = function (eachfn, arr, fn, callback) {
+ var r = [];
+ eachfn(arr, function (x, cb) {
+ fn(x, function (err, y) {
+ r = r.concat(y || []);
+ cb(err);
+ });
+ }, function (err) {
+ callback(err, r);
+ });
+ };
+ async.concat = doParallel(_concat);
+ async.concatSeries = doSeries(_concat);
+
+ async.whilst = function (test, iterator, callback) {
+ if (test()) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err);
+ }
+ async.whilst(test, iterator, callback);
+ });
+ }
+ else {
+ callback();
+ }
+ };
+
+ async.doWhilst = function (iterator, test, callback) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err);
+ }
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (test.apply(null, args)) {
+ async.doWhilst(iterator, test, callback);
+ }
+ else {
+ callback();
+ }
+ });
+ };
+
+ async.until = function (test, iterator, callback) {
+ if (!test()) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err);
+ }
+ async.until(test, iterator, callback);
+ });
+ }
+ else {
+ callback();
+ }
+ };
+
+ async.doUntil = function (iterator, test, callback) {
+ iterator(function (err) {
+ if (err) {
+ return callback(err);
+ }
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (!test.apply(null, args)) {
+ async.doUntil(iterator, test, callback);
+ }
+ else {
+ callback();
+ }
+ });
+ };
+
+ async.queue = function (worker, concurrency) {
+ if (concurrency === undefined) {
+ concurrency = 1;
+ }
+ function _insert(q, data, pos, callback) {
+ if (!q.started){
+ q.started = true;
+ }
+ if (!_isArray(data)) {
+ data = [data];
+ }
+ if(data.length == 0) {
+ // call drain immediately if there are no tasks
+ return async.setImmediate(function() {
+ if (q.drain) {
+ q.drain();
+ }
+ });
+ }
+ _each(data, function(task) {
+ var item = {
+ data: task,
+ callback: typeof callback === 'function' ? callback : null
+ };
+
+ if (pos) {
+ q.tasks.unshift(item);
+ } else {
+ q.tasks.push(item);
+ }
+
+ if (q.saturated && q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ async.setImmediate(q.process);
+ });
+ }
+
+ var workers = 0;
+ var q = {
+ tasks: [],
+ concurrency: concurrency,
+ saturated: null,
+ empty: null,
+ drain: null,
+ started: false,
+ paused: false,
+ push: function (data, callback) {
+ _insert(q, data, false, callback);
+ },
+ kill: function () {
+ q.drain = null;
+ q.tasks = [];
+ },
+ unshift: function (data, callback) {
+ _insert(q, data, true, callback);
+ },
+ process: function () {
+ if (!q.paused && workers < q.concurrency && q.tasks.length) {
+ var task = q.tasks.shift();
+ if (q.empty && q.tasks.length === 0) {
+ q.empty();
+ }
+ workers += 1;
+ var next = function () {
+ workers -= 1;
+ if (task.callback) {
+ task.callback.apply(task, arguments);
+ }
+ if (q.drain && q.tasks.length + workers === 0) {
+ q.drain();
+ }
+ q.process();
+ };
+ var cb = only_once(next);
+ worker(task.data, cb);
+ }
+ },
+ length: function () {
+ return q.tasks.length;
+ },
+ running: function () {
+ return workers;
+ },
+ idle: function() {
+ return q.tasks.length + workers === 0;
+ },
+ pause: function () {
+ if (q.paused === true) { return; }
+ q.paused = true;
+ },
+ resume: function () {
+ if (q.paused === false) { return; }
+ q.paused = false;
+ // Need to call q.process once per concurrent
+ // worker to preserve full concurrency after pause
+ for (var w = 1; w <= q.concurrency; w++) {
+ async.setImmediate(q.process);
+ }
+ }
+ };
+ return q;
+ };
+
+ async.priorityQueue = function (worker, concurrency) {
+
+ function _compareTasks(a, b){
+ return a.priority - b.priority;
+ };
+
+ function _binarySearch(sequence, item, compare) {
+ var beg = -1,
+ end = sequence.length - 1;
+ while (beg < end) {
+ var mid = beg + ((end - beg + 1) >>> 1);
+ if (compare(item, sequence[mid]) >= 0) {
+ beg = mid;
+ } else {
+ end = mid - 1;
+ }
+ }
+ return beg;
+ }
+
+ function _insert(q, data, priority, callback) {
+ if (!q.started){
+ q.started = true;
+ }
+ if (!_isArray(data)) {
+ data = [data];
+ }
+ if(data.length == 0) {
+ // call drain immediately if there are no tasks
+ return async.setImmediate(function() {
+ if (q.drain) {
+ q.drain();
+ }
+ });
+ }
+ _each(data, function(task) {
+ var item = {
+ data: task,
+ priority: priority,
+ callback: typeof callback === 'function' ? callback : null
+ };
+
+ q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+ if (q.saturated && q.tasks.length === q.concurrency) {
+ q.saturated();
+ }
+ async.setImmediate(q.process);
+ });
+ }
+
+ // Start with a normal queue
+ var q = async.queue(worker, concurrency);
+
+ // Override push to accept second parameter representing priority
+ q.push = function (data, priority, callback) {
+ _insert(q, data, priority, callback);
+ };
+
+ // Remove unshift function
+ delete q.unshift;
+
+ return q;
+ };
+
+ async.cargo = function (worker, payload) {
+ var working = false,
+ tasks = [];
+
+ var cargo = {
+ tasks: tasks,
+ payload: payload,
+ saturated: null,
+ empty: null,
+ drain: null,
+ drained: true,
+ push: function (data, callback) {
+ if (!_isArray(data)) {
+ data = [data];
+ }
+ _each(data, function(task) {
+ tasks.push({
+ data: task,
+ callback: typeof callback === 'function' ? callback : null
+ });
+ cargo.drained = false;
+ if (cargo.saturated && tasks.length === payload) {
+ cargo.saturated();
+ }
+ });
+ async.setImmediate(cargo.process);
+ },
+ process: function process() {
+ if (working) return;
+ if (tasks.length === 0) {
+ if(cargo.drain && !cargo.drained) cargo.drain();
+ cargo.drained = true;
+ return;
+ }
+
+ var ts = typeof payload === 'number'
+ ? tasks.splice(0, payload)
+ : tasks.splice(0, tasks.length);
+
+ var ds = _map(ts, function (task) {
+ return task.data;
+ });
+
+ if(cargo.empty) cargo.empty();
+ working = true;
+ worker(ds, function () {
+ working = false;
+
+ var args = arguments;
+ _each(ts, function (data) {
+ if (data.callback) {
+ data.callback.apply(null, args);
+ }
+ });
+
+ process();
+ });
+ },
+ length: function () {
+ return tasks.length;
+ },
+ running: function () {
+ return working;
+ }
+ };
+ return cargo;
+ };
+
+ var _console_fn = function (name) {
+ return function (fn) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ fn.apply(null, args.concat([function (err) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ if (typeof console !== 'undefined') {
+ if (err) {
+ if (console.error) {
+ console.error(err);
+ }
+ }
+ else if (console[name]) {
+ _each(args, function (x) {
+ console[name](x);
+ });
+ }
+ }
+ }]));
+ };
+ };
+ async.log = _console_fn('log');
+ async.dir = _console_fn('dir');
+ /*async.info = _console_fn('info');
+ async.warn = _console_fn('warn');
+ async.error = _console_fn('error');*/
+
+ async.memoize = function (fn, hasher) {
+ var memo = {};
+ var queues = {};
+ hasher = hasher || function (x) {
+ return x;
+ };
+ var memoized = function () {
+ var args = Array.prototype.slice.call(arguments);
+ var callback = args.pop();
+ var key = hasher.apply(null, args);
+ if (key in memo) {
+ async.nextTick(function () {
+ callback.apply(null, memo[key]);
+ });
+ }
+ else if (key in queues) {
+ queues[key].push(callback);
+ }
+ else {
+ queues[key] = [callback];
+ fn.apply(null, args.concat([function () {
+ memo[key] = arguments;
+ var q = queues[key];
+ delete queues[key];
+ for (var i = 0, l = q.length; i < l; i++) {
+ q[i].apply(null, arguments);
+ }
+ }]));
+ }
+ };
+ memoized.memo = memo;
+ memoized.unmemoized = fn;
+ return memoized;
+ };
+
+ async.unmemoize = function (fn) {
+ return function () {
+ return (fn.unmemoized || fn).apply(null, arguments);
+ };
+ };
+
+ async.times = function (count, iterator, callback) {
+ var counter = [];
+ for (var i = 0; i < count; i++) {
+ counter.push(i);
+ }
+ return async.map(counter, iterator, callback);
+ };
+
+ async.timesSeries = function (count, iterator, callback) {
+ var counter = [];
+ for (var i = 0; i < count; i++) {
+ counter.push(i);
+ }
+ return async.mapSeries(counter, iterator, callback);
+ };
+
+ async.seq = function (/* functions... */) {
+ var fns = arguments;
+ return function () {
+ var that = this;
+ var args = Array.prototype.slice.call(arguments);
+ var callback = args.pop();
+ async.reduce(fns, args, function (newargs, fn, cb) {
+ fn.apply(that, newargs.concat([function () {
+ var err = arguments[0];
+ var nextargs = Array.prototype.slice.call(arguments, 1);
+ cb(err, nextargs);
+ }]))
+ },
+ function (err, results) {
+ callback.apply(that, [err].concat(results));
+ });
+ };
+ };
+
+ async.compose = function (/* functions... */) {
+ return async.seq.apply(null, Array.prototype.reverse.call(arguments));
+ };
+
+ var _applyEach = function (eachfn, fns /*args...*/) {
+ var go = function () {
+ var that = this;
+ var args = Array.prototype.slice.call(arguments);
+ var callback = args.pop();
+ return eachfn(fns, function (fn, cb) {
+ fn.apply(that, args.concat([cb]));
+ },
+ callback);
+ };
+ if (arguments.length > 2) {
+ var args = Array.prototype.slice.call(arguments, 2);
+ return go.apply(this, args);
+ }
+ else {
+ return go;
+ }
+ };
+ async.applyEach = doParallel(_applyEach);
+ async.applyEachSeries = doSeries(_applyEach);
+
+ async.forever = function (fn, callback) {
+ function next(err) {
+ if (err) {
+ if (callback) {
+ return callback(err);
+ }
+ throw err;
+ }
+ fn(next);
+ }
+ next();
+ };
+
+ // Node.js
+ if (typeof module !== 'undefined' && module.exports) {
+ module.exports = async;
+ }
+ // AMD / RequireJS
+ else if (typeof define !== 'undefined' && define.amd) {
+ define([], function () {
+ return async;
+ });
+ }
+ // included directly via