[Pkg-javascript-commits] [node-tap] 05/06: Use tap-mocha-reporter instead of patch

Bastien Roucariès rouca at moszumanska.debian.org
Thu Sep 7 09:30:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

rouca pushed a commit to branch master
in repository node-tap.

commit 3d47d8360fe094105e3cdfd97e31dc9adf125ea4
Author: Bastien ROUCARIÈS <roucaries.bastien at gmail.com>
Date:   Thu Sep 7 11:14:29 2017 +0200

    Use tap-mocha-reporter instead of patch
---
 debian/changelog                               |    1 +
 debian/control                                 |    2 +
 debian/patches/module-tap-mocha-reporter.patch | 3603 ------------------------
 debian/patches/script-not-executable.patch     |   12 -
 debian/patches/series                          |    2 -
 debian/patches/use_available_modules.patch     |   25 -
 6 files changed, 3 insertions(+), 3642 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 9e5af2d..3f67997 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ node-tap (8.0.0-6) unstable; urgency=medium
 
   * Team upload
   * Use module node-clean-yaml-object instad of patch
+  * Use node-tap-mocha-reporter instead of patch
 
  -- Bastien Roucariès <rouca at debian.org>  Thu, 07 Sep 2017 11:11:55 +0200
 
diff --git a/debian/control b/debian/control
index baf94cf..827e77b 100644
--- a/debian/control
+++ b/debian/control
@@ -22,6 +22,7 @@ Build-Depends:
  , node-strip-ansi  <!nocheck> <!nodoc>
  , node-signal-exit (>= 3.0.0) <!nocheck> <!nodoc>
  , node-tap-parser (>= 2.2.0) <!nocheck> <!nodoc>
+ , node-tap-mocha-reporter (>= 2.0.0) <!nocheck> <!nodoc>
  , node-tmatch (>= 3.0.0) <!nocheck> <!nodoc>
  , node-mkdirp (>= 0.5.0)
 Standards-Version: 3.9.8
@@ -48,6 +49,7 @@ Depends:
  , node-strip-ansi
  , node-signal-exit (>= 3.0.0)
  , node-tap-parser (>= 2.2.0)
+ , node-tap-mocha-reporter (>= 2.0.0)
  , node-tmatch (>= 3.0.0)
 Suggests:
  node-coveralls (>= 2.11.2)
diff --git a/debian/patches/module-tap-mocha-reporter.patch b/debian/patches/module-tap-mocha-reporter.patch
deleted file mode 100644
index 513fbdb..0000000
--- a/debian/patches/module-tap-mocha-reporter.patch
+++ /dev/null
@@ -1,3603 +0,0 @@
-Description: bundle module tap-mocha-reporter
- See copyright for more information
-Last-Update: 2016-11-11
-Forwarded: not-needed
-Author: Jérémy Lal <kapouer at melix.org>
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/formatter.js
-@@ -0,0 +1,87 @@
-+// A formatter is a Duplex stream that TAP data is written into,
-+// and then something else (presumably not-TAP) is read from.
-+//
-+// See tap-classic.js for an example of a formatter in use.
-+
-+var Duplex = require('stream').Duplex
-+if (!Duplex) {
-+  try {
-+    Duplex = require('readable-stream').Duplex
-+  } catch (er) {
-+    throw new Error('Please install "readable-stream" to use this module ' +
-+                    'with Node.js v0.8 and before')
-+  }
-+}
-+
-+var util = require('util')
-+var Parser = require('tap-parser')
-+util.inherits(Formatter, Duplex)
-+module.exports = Formatter
-+
-+function Formatter(options, parser, parent) {
-+  if (!(this instanceof Formatter))
-+    return new Formatter(options, parser, parent)
-+
-+  if (!parser)
-+    parser = new Parser()
-+
-+  Duplex.call(this, options)
-+  this.child = null
-+  this.parent = parent || null
-+  this.level = parser.level
-+  this.parser = parser
-+
-+  attachEvents(this, parser, options)
-+
-+  if (options.init)
-+    options.init.call(this)
-+}
-+
-+function attachEvents (self, parser, options) {
-+  var events = [
-+    'version', 'plan', 'assert', 'comment',
-+    'complete', 'extra', 'bailout'
-+  ]
-+
-+  parser.on('child', function (childparser) {
-+    self.child = new Formatter(options, childparser, self)
-+    if (options.child)
-+      options.child.call(self, self.child)
-+  })
-+
-+  events.forEach(function (ev) {
-+    if (typeof options[ev] === 'function')
-+      parser.on(ev, options[ev].bind(self))
-+  })
-+
-+  // proxy all stream events directly
-+  var streamEvents = [
-+    'pipe', 'prefinish', 'finish', 'unpipe', 'close'
-+  ]
-+
-+  streamEvents.forEach(function (ev) {
-+    parser.on(ev, function () {
-+      var args = [ev]
-+      args.push.apply(args, arguments)
-+      self.emit.apply(self, args)
-+    })
-+  })
-+}
-+
-+Formatter.prototype.write = function (c, e, cb) {
-+  return this.parser.write(c, e, cb)
-+}
-+
-+Formatter.prototype.end = function (c, e, cb) {
-+  return this.parser.end(c, e, cb)
-+}
-+
-+Formatter.prototype._read = function () {}
-+
-+// child formatters always push data to the root obj
-+Formatter.prototype.push = function (c) {
-+  if (this.parent)
-+    return this.parent.push(c)
-+
-+  Duplex.prototype.push.call(this, c)
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/ms.js
-@@ -0,0 +1,109 @@
-+/**
-+ * Helpers.
-+ */
-+
-+var s = 1000;
-+var m = s * 60;
-+var h = m * 60;
-+var d = h * 24;
-+var y = d * 365.25;
-+
-+/**
-+ * Parse or format the given `val`.
-+ *
-+ * Options:
-+ *
-+ *  - `long` verbose formatting [false]
-+ *
-+ * @param {String|Number} val
-+ * @param {Object} options
-+ * @return {String|Number}
-+ * @api public
-+ */
-+
-+module.exports = function(val, options){
-+  options = options || {};
-+  if ('string' == typeof val) return parse(val);
-+  return options['long'] ? longFormat(val) : shortFormat(val);
-+};
-+
-+/**
-+ * Parse the given `str` and return milliseconds.
-+ *
-+ * @param {String} str
-+ * @return {Number}
-+ * @api private
-+ */
-+
-+function parse(str) {
-+  var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str);
-+  if (!match) return;
-+  var n = parseFloat(match[1]);
-+  var type = (match[2] || 'ms').toLowerCase();
-+  switch (type) {
-+    case 'years':
-+    case 'year':
-+    case 'y':
-+      return n * y;
-+    case 'days':
-+    case 'day':
-+    case 'd':
-+      return n * d;
-+    case 'hours':
-+    case 'hour':
-+    case 'h':
-+      return n * h;
-+    case 'minutes':
-+    case 'minute':
-+    case 'm':
-+      return n * m;
-+    case 'seconds':
-+    case 'second':
-+    case 's':
-+      return n * s;
-+    case 'ms':
-+      return n;
-+  }
-+}
-+
-+/**
-+ * Short format for `ms`.
-+ *
-+ * @param {Number} ms
-+ * @return {String}
-+ * @api private
-+ */
-+
-+function shortFormat(ms) {
-+  if (ms >= d) return Math.round(ms / d) + 'd';
-+  if (ms >= h) return Math.round(ms / h) + 'h';
-+  if (ms >= m) return Math.round(ms / m) + 'm';
-+  if (ms >= s) return Math.round(ms / s) + 's';
-+  return ms + 'ms';
-+}
-+
-+/**
-+ * Long format for `ms`.
-+ *
-+ * @param {Number} ms
-+ * @return {String}
-+ * @api private
-+ */
-+
-+function longFormat(ms) {
-+  return plural(ms, d, 'day')
-+    || plural(ms, h, 'hour')
-+    || plural(ms, m, 'minute')
-+    || plural(ms, s, 'second')
-+    || ms + ' ms';
-+}
-+
-+/**
-+ * Pluralization helper.
-+ */
-+
-+function plural(ms, n, name) {
-+  if (ms < n) return;
-+  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
-+  return Math.ceil(ms / n) + ' ' + name + 's';
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/base.js
-@@ -0,0 +1,463 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var tty = require('tty')
-+  , diff = require('diff')
-+  , ms = require('../ms')
-+  , utils = require('../utils')
-+  , supportsColor = require('color-support')()
-+
-+/**
-+ * Save timer references to avoid Sinon interfering (see GH-237).
-+ */
-+
-+var Date = global.Date
-+  , setTimeout = global.setTimeout
-+  , setInterval = global.setInterval
-+  , clearTimeout = global.clearTimeout
-+  , clearInterval = global.clearInterval;
-+
-+/**
-+ * Check if both stdio streams are associated with a tty.
-+ */
-+
-+var isatty = tty.isatty(1);
-+
-+/**
-+ * Expose `Base`.
-+ */
-+
-+exports = module.exports = Base;
-+
-+/**
-+ * Enable coloring by default, except in the browser interface.
-+ */
-+
-+exports.useColors = process.env
-+  ? (supportsColor || (process.env.TAP_COLORS !== undefined))
-+  : false;
-+
-+if (exports.useColors && +process.env.TAP_COLORS === 0)
-+  exports.useColors = false
-+
-+/**
-+ * Inline diffs instead of +/-
-+ */
-+
-+exports.inlineDiffs = false;
-+
-+/**
-+ * Default color map.
-+ */
-+
-+exports.colors = {
-+    'pass': 90
-+  , 'fail': 31
-+  , 'bright pass': 92
-+  , 'bright fail': 91
-+  , 'bright yellow': 93
-+  , 'pending': 35
-+  , 'skip': 36
-+  , 'suite': 0
-+  , 'error title': 0
-+  , 'error message': 31
-+  , 'error stack': 90
-+  , 'checkmark': 32
-+  , 'fast': 90
-+  , 'medium': 33
-+  , 'slow': 31
-+  , 'green': 32
-+  , 'light': 90
-+  , 'diff gutter': 90
-+  , 'diff added': 42
-+  , 'diff removed': 41
-+};
-+
-+/**
-+ * Default symbol map.
-+ */
-+
-+exports.symbols = {
-+  ok: '✓',
-+  err: '✖',
-+  dot: '․'
-+};
-+
-+// With node.js on Windows: use symbols available in terminal default fonts
-+if ('win32' == process.platform) {
-+  exports.symbols.ok = '\u221A';
-+  exports.symbols.err = '\u00D7';
-+  exports.symbols.dot = '.';
-+}
-+
-+/**
-+ * Color `str` with the given `type`,
-+ * allowing colors to be disabled,
-+ * as well as user-defined color
-+ * schemes.
-+ *
-+ * @param {String} type
-+ * @param {String} str
-+ * @return {String}
-+ * @api private
-+ */
-+
-+var color = exports.color = function(type, str) {
-+  if (!exports.useColors) return String(str);
-+  return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
-+};
-+
-+/**
-+ * Expose term window size, with some
-+ * defaults for when stderr is not a tty.
-+ */
-+
-+exports.window = {
-+  width: isatty
-+    ? process.stdout.getWindowSize
-+      ? process.stdout.getWindowSize(1)[0]
-+      : tty.getWindowSize()[1]
-+    : 75
-+};
-+
-+/**
-+ * Expose some basic cursor interactions
-+ * that are common among reporters.
-+ */
-+
-+exports.cursor = {
-+  hide: function(){
-+    isatty && process.stdout.write('\u001b[?25l');
-+  },
-+
-+  show: function(){
-+    isatty && process.stdout.write('\u001b[?25h');
-+  },
-+
-+  deleteLine: function(){
-+    isatty && process.stdout.write('\u001b[2K');
-+  },
-+
-+  beginningOfLine: function(){
-+    isatty && process.stdout.write('\u001b[0G');
-+  },
-+
-+  CR: function(){
-+    if (isatty) {
-+      exports.cursor.deleteLine();
-+      exports.cursor.beginningOfLine();
-+    } else {
-+      process.stdout.write('\r');
-+    }
-+  }
-+};
-+
-+/**
-+ * Outut the given `failures` as a list.
-+ *
-+ * @param {Array} failures
-+ * @api public
-+ */
-+
-+exports.list = function(failures){
-+  console.log();
-+  failures.forEach(function(test, i){
-+    // format
-+    var fmt = color('error title', '  %s) %s:\n')
-+      + color('error message', '     %s')
-+      + color('error stack', '\n%s\n');
-+
-+    // msg
-+    var err = test.err
-+      , message = err.message || ''
-+      , stack = err.stack || message
-+
-+    var index = stack.indexOf(message) + message.length
-+      , msg = stack.slice(0, index)
-+      , actual = err.actual
-+      , expected = err.expected
-+      , escape = true;
-+
-+
-+    // uncaught
-+    if (err.uncaught) {
-+      msg = 'Uncaught ' + msg;
-+    }
-+    // explicitly show diff
-+    if (err.showDiff && sameType(actual, expected)) {
-+
-+      if ('string' !== typeof actual) {
-+        escape = false;
-+        err.actual = actual = utils.stringify(actual);
-+        err.expected = expected = utils.stringify(expected);
-+      }
-+
-+      fmt = color('error title', '  %s) %s:\n%s') + color('error stack', '\n%s\n');
-+      var match = message.match(/^([^:]+): expected/);
-+      msg = '\n      ' + color('error message', match ? match[1] : msg);
-+
-+      if (exports.inlineDiffs) {
-+        msg += inlineDiff(err, escape);
-+      } else {
-+        msg += unifiedDiff(err, escape);
-+      }
-+    }
-+
-+    // indent stack trace without msg
-+    stack = utils.stackTraceFilter()(stack.slice(index ? index + 1 : index)
-+      .replace(/^/gm, '  '));
-+
-+    console.log(fmt, (i + 1), test.fullTitle(), msg, stack);
-+  });
-+};
-+
-+/**
-+ * Initialize a new `Base` reporter.
-+ *
-+ * All other reporters generally
-+ * inherit from this reporter, providing
-+ * stats such as test duration, number
-+ * of tests passed / failed etc.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Base(runner) {
-+  var self = this
-+    , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
-+    , failures = this.failures = [];
-+
-+  if (!runner) return;
-+  this.runner = runner;
-+
-+  runner.stats = stats;
-+
-+  runner.on('start', function(){
-+    stats.start = new Date;
-+  });
-+
-+  runner.on('suite', function(suite){
-+    stats.suites = stats.suites || 0;
-+    suite.root || stats.suites++;
-+  });
-+
-+  runner.on('test end', function(test){
-+    stats.tests = stats.tests || 0;
-+    stats.tests++;
-+  });
-+
-+  runner.on('pass', function(test){
-+    stats.passes = stats.passes || 0;
-+
-+    var medium = test.slow() / 2;
-+    test.speed = test.duration > test.slow()
-+      ? 'slow'
-+      : test.duration > medium
-+        ? 'medium'
-+        : 'fast';
-+
-+    stats.passes++;
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    stats.failures = stats.failures || 0;
-+    stats.failures++;
-+    test.err = err;
-+    failures.push(test);
-+  });
-+
-+  runner.on('end', function(){
-+    stats.end = new Date;
-+    if (!stats.duration)
-+      stats.duration = stats.end - stats.start;
-+  });
-+
-+  runner.on('pending', function(){
-+    stats.pending++;
-+  });
-+}
-+
-+/**
-+ * Output common epilogue used by many of
-+ * the bundled reporters.
-+ *
-+ * @api public
-+ */
-+
-+Base.prototype.epilogue = function(){
-+  var stats = this.stats;
-+  var tests;
-+  var fmt;
-+
-+  console.log();
-+
-+  // passes
-+  fmt = color('bright pass', ' ')
-+    + color('green', ' %d passing')
-+    + color('light', ' (%s)');
-+
-+  console.log(fmt,
-+    stats.passes || 0,
-+    ms(stats.duration));
-+
-+  // pending
-+  if (stats.pending) {
-+    fmt = color('pending', ' ')
-+      + color('pending', ' %d pending');
-+
-+    console.log(fmt, stats.pending);
-+  }
-+
-+  // failures
-+  if (stats.failures) {
-+    fmt = color('fail', '  %d failing');
-+
-+    console.log(fmt, stats.failures);
-+
-+    Base.list(this.failures);
-+  }
-+};
-+
-+/**
-+ * Pad the given `str` to `len`.
-+ *
-+ * @param {String} str
-+ * @param {String} len
-+ * @return {String}
-+ * @api private
-+ */
-+
-+function pad(str, len) {
-+  str = String(str);
-+  return Array(len - str.length + 1).join(' ') + str;
-+}
-+
-+
-+/**
-+ * Returns an inline diff between 2 strings with coloured ANSI output
-+ *
-+ * @param {Error} Error with actual/expected
-+ * @return {String} Diff
-+ * @api private
-+ */
-+
-+function inlineDiff(err, escape) {
-+  var msg = errorDiff(err, 'WordsWithSpace', escape);
-+
-+  // linenos
-+  var lines = msg.split('\n');
-+  if (lines.length > 4) {
-+    var width = String(lines.length).length;
-+    msg = lines.map(function(str, i){
-+      return pad(++i, width) + ' |' + ' ' + str;
-+    }).join('\n');
-+  }
-+
-+  // legend
-+  msg = '\n'
-+    + color('diff removed', 'actual')
-+    + ' '
-+    + color('diff added', 'expected')
-+    + '\n\n'
-+    + msg
-+    + '\n';
-+
-+  // indent
-+  msg = msg.replace(/^/gm, '      ');
-+  return msg;
-+}
-+
-+/**
-+ * Returns a unified diff between 2 strings
-+ *
-+ * @param {Error} Error with actual/expected
-+ * @return {String} Diff
-+ * @api private
-+ */
-+
-+function unifiedDiff(err, escape) {
-+  var indent = '      ';
-+  function cleanUp(line) {
-+    if (escape) {
-+      line = escapeInvisibles(line);
-+    }
-+    if (line[0] === '+') return indent + colorLines('diff added', line);
-+    if (line[0] === '-') return indent + colorLines('diff removed', line);
-+    if (line.match(/\@\@/)) return null;
-+    if (line.match(/\\ No newline/)) return null;
-+    else return indent + line;
-+  }
-+  function notBlank(line) {
-+    return line != null;
-+  }
-+  var msg = diff.createPatch('string', err.actual, err.expected);
-+  var lines = msg.split('\n').splice(4);
-+  return '\n      '
-+         + colorLines('diff added',   '+ expected') + ' '
-+         + colorLines('diff removed', '- actual')
-+         + '\n\n'
-+         + lines.map(cleanUp).filter(notBlank).join('\n');
-+}
-+
-+/**
-+ * Return a character diff for `err`.
-+ *
-+ * @param {Error} err
-+ * @return {String}
-+ * @api private
-+ */
-+
-+function errorDiff(err, type, escape) {
-+  var actual   = escape ? escapeInvisibles(err.actual)   : err.actual;
-+  var expected = escape ? escapeInvisibles(err.expected) : err.expected;
-+  return diff['diff' + type](actual, expected).map(function(str){
-+    if (str.added) return colorLines('diff added', str.value);
-+    if (str.removed) return colorLines('diff removed', str.value);
-+    return str.value;
-+  }).join('');
-+}
-+
-+/**
-+ * Returns a string with all invisible characters in plain text
-+ *
-+ * @param {String} line
-+ * @return {String}
-+ * @api private
-+ */
-+function escapeInvisibles(line) {
-+    return line.replace(/\t/g, '<tab>')
-+               .replace(/\r/g, '<CR>')
-+               .replace(/\n/g, '<LF>\n');
-+}
-+
-+/**
-+ * Color lines for `str`, using the color `name`.
-+ *
-+ * @param {String} name
-+ * @param {String} str
-+ * @return {String}
-+ * @api private
-+ */
-+
-+function colorLines(name, str) {
-+  return str.split('\n').map(function(str){
-+    return color(name, str);
-+  }).join('\n');
-+}
-+
-+/**
-+ * Check that a / b have the same type.
-+ *
-+ * @param {Object} a
-+ * @param {Object} b
-+ * @return {Boolean}
-+ * @api private
-+ */
-+
-+function sameType(a, b) {
-+  a = Object.prototype.toString.call(a);
-+  b = Object.prototype.toString.call(b);
-+  return a == b;
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/classic.js
-@@ -0,0 +1,402 @@
-+exports = module.exports = Classic
-+
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color
-+  , yaml = require('js-yaml')
-+  , util = require('util')
-+  , fancy = Base.useColors && !process.env.TRAVIS
-+  , ms = require('../ms.js')
-+  , diff = require('diff')
-+  , utils = require('../utils.js')
-+  , uclen = require('unicode-length').get
-+  , colorSupport = require('color-support')()
-+
-+function hasOwnProperty (obj, key) {
-+  return Object.prototype.hasOwnProperty.call(obj, key)
-+}
-+
-+function doDiff (found, wanted, palette) {
-+  // TODO: Make this a configurable thing or something?
-+  //
-+  // Choosing a palette for diffs in a test-runner context
-+  // is really tricky.  The temptation is to make it look
-+  // exactly like `git diff`, but the default red and green
-+  // are very confusing with the colors used to indicate
-+  // pass/fail.
-+  //
-+  // So, I decided to experiment with setting a background to
-+  // distinguish the diff section from the rest of the test
-+  // output.  The obvious choice, then, was to mimick GitHub's
-+  // diff styling.
-+  //
-+  // The problem there is that, while those of us with an
-+  // abundance of cones tend to find that palette most pleasing,
-+  // it's virtually impossible for people with various sorts of
-+  // red/green colorblindness to distinguish those colors.
-+  //
-+  // The resulting option, with a somewhat pink-ish red and a
-+  // somewhat yellow-ish green, seems to be a pretty good
-+  // compromise between esthetics and accessibility.  In a poll
-+  // on twitter, it was the only one that no color-sighted people
-+  // strongly objected to, and no color-blind people had
-+  // significant trouble interpreting.  The twitter poll agrees
-+  // with the results of Sim Daltonism, which showed that this
-+  // palette was easily distinguishable across all forms of color
-+  // deficiency.
-+
-+  // TODO: add a TrueColor one that looks nicer
-+  palette = colorSupport.has256 ? 6 : 1
-+
-+  var plain = ''
-+  var reset = '\u001b[m'
-+
-+  switch (palette) {
-+    case 1:
-+      // most git-like.  r/g, no background, no bold
-+      var bg = ''
-+      var removed = '\u001b[31m'
-+      var added = '\u001b[32m'
-+      break
-+
-+    case 2:
-+      // dark option, maybe confusing with pass/fail colors?
-+      var bg = '\u001b[48;5;234m'
-+      var removed = '\u001b[31;1m'
-+      var added = '\u001b[32;1m'
-+      break
-+
-+    case 3:
-+      // pastel option, most githubby
-+      var removed = '\u001b[48;5;224m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;194m\u001b[38;5;22m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+    case 4:
-+      // orange/cyan pastel option, most r/g-colorblind friendly
-+      var removed = '\u001b[48;5;223m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;158m\u001b[38;5;22m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+    case 5:
-+      // pastel option, green is bluish, red is just red
-+      var removed = '\u001b[48;5;224m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;158m\u001b[38;5;22m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+    case 6:
-+      // pastel option, red is purplish, green is yellowish
-+      var removed = '\u001b[48;5;218m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;193m\u001b[38;5;22m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+    case 7:
-+      // pastel option, red is purplish, green is just green
-+      var removed = '\u001b[48;5;218m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;194m\u001b[38;5;22m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+    case 8:
-+      // pastel, red and blue
-+      var removed = '\u001b[48;5;224m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;189m\u001b[38;5;17m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+    case 9:
-+      // pastel option, red is purplish, green is yellowish
-+      var removed = '\u001b[48;5;224m\u001b[38;5;52m'
-+      var added = '\u001b[48;5;193m\u001b[38;5;22m'
-+      var plain = '\u001b[38;5;233m'
-+      var bg = '\u001b[48;5;255m'
-+      break
-+
-+  }
-+
-+
-+  var maxLen = process.stdout.columns || 0
-+  if (maxLen >= 5)
-+    maxLen -= 5
-+
-+  if (!Base.useColors) {
-+    bg = removed = added = reset = plain = ''
-+    maxLen = 0
-+  }
-+
-+  // If they are not strings, or only differ in trailing whitespace,
-+  // then stringify them so that we can see the difference.
-+  if (typeof found !== 'string' ||
-+      typeof wanted !== 'string' ||
-+      found.trim() === wanted.trim()) {
-+    found = utils.stringify(found)
-+    wanted = utils.stringify(wanted)
-+  }
-+
-+  var patch = diff.createPatch('', wanted, found)
-+  //console.error(patch)
-+  var width = 0
-+  patch = patch.split('\n').map(function (line, index) {
-+    if (uclen(line) > width)
-+      width = Math.min(maxLen, uclen(line))
-+    if (line.match(/^\=+$/) ||
-+        line === '\\ No newline at end of file')
-+      return null
-+    else
-+      return line
-+  }).filter(function (line, i) {
-+    return line && i > 4
-+  }).map(function (line) {
-+    if (uclen(line) < width)
-+      line += new Array(width - uclen(line) + 1).join(' ')
-+    return line
-+  }).map(function (line) {
-+    if (line.charAt(0) === '+')
-+      return bg + added + line + reset
-+    else if (line.charAt(0) === '-')
-+      return bg + removed + line + reset
-+    else
-+      return bg + plain + line + reset
-+  }).join('\n')
-+
-+  var pref =
-+    bg + added + '+++ found' +
-+      (Base.useColors
-+        ? new Array(width - '+++ found'.length + 1).join(' ')
-+        : '') +
-+      reset + '\n' +
-+    bg + removed + '--- wanted' +
-+      (Base.useColors
-+        ? new Array(width - '--- wanted'.length + 1).join(' ')
-+        : '') +
-+      reset + '\n'
-+
-+  return pref + patch
-+}
-+
-+util.inherits(Classic, Base)
-+
-+function Classic (runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+
-+  var grandTotal = 0
-+  var grandPass = 0
-+
-+  var bailed = false
-+  var hadFails = false
-+  var currentSuite = null
-+  var tests = []
-+  var skipped = 0
-+  var skipMsg = []
-+  var todo = []
-+  var fails = []
-+  var total = 0
-+  var pass = 0
-+  var tickDots = 0
-+  var tickColor = 'checkmark'
-+
-+  runner.on('bailout', function (bailout, suite) {
-+    if (currentSuite)
-+      runner.emit('suite end', currentSuite)
-+    if (bailed)
-+      return
-+    bailed = true
-+    console.log(Base.color('fail', 'Bail out! ' + bailout))
-+  })
-+
-+  runner.on('suite', function (suite) {
-+    if (!suite.root)
-+      return
-+
-+    if (fancy) {
-+      process.stdout.write(suite.title + ' ')
-+      tickDots = 0
-+      tickColor = 'checkmark'
-+    }
-+
-+    currentSuite = suite
-+    tests = []
-+    todo = []
-+    fails = []
-+    skipMsg = []
-+    skipped = 0
-+    pass = 0
-+    total = 0
-+  })
-+
-+  runner.on('suite end', function (suite) {
-+    if (!suite.root)
-+      return
-+
-+    if (fancy)
-+      Base.cursor.beginningOfLine()
-+
-+    currentSuite = null
-+    var len = 60
-+    var title = suite.title || '(unnamed)'
-+    var num = pass + '/' + total
-+    var dots = len - uclen(title) - uclen(num) - 2
-+    if (dots < 3)
-+      dots = 3
-+    dots = ' ' + new Array(dots).join('.') + ' '
-+    if (fails.length)
-+      num = Base.color('fail', num)
-+    else if (pass === total)
-+      num = Base.color('checkmark', num)
-+    else
-+      num = Base.color('pending', num)
-+
-+    var fmt = title + dots + num
-+    if (suite.duration / total > 250)
-+      fmt += Base.color('slow', ' ' + ms(Math.round(suite.duration)))
-+
-+    console.log(fmt)
-+
-+    if (fails.length) {
-+      var failMsg = ''
-+      fails.forEach(function (t) {
-+        if (t.parent)
-+          failMsg += t.parent + '\n'
-+        failMsg += Base.color('fail', 'not ok ' + t.name) + '\n'
-+        if (t.diag) {
-+          var printDiff = false
-+          if (hasOwnProperty(t.diag, 'found') &&
-+              hasOwnProperty(t.diag, 'wanted')) {
-+            printDiff = true
-+            var found = t.diag.found
-+            var wanted = t.diag.wanted
-+            failMsg += indent(doDiff(found, wanted), 2) + '\n'
-+          }
-+
-+          var o = {}
-+          var print = false
-+          for (var i in t.diag) {
-+            // Don't re-print what we already showed in the diff
-+            if (printDiff && ( i === 'found' || i === 'wanted'))
-+              continue
-+            o[i] = t.diag[i]
-+            print = true
-+          }
-+          if (print)
-+            failMsg += indent(yaml.safeDump(o), 2) + '\n'
-+        }
-+      })
-+      console.log(indent(failMsg, 2))
-+    }
-+
-+    if (todo.length) {
-+      var todoMsg = ''
-+      var bullet = Base.color('pending', '~ ')
-+      todo.forEach(function (t) {
-+        if (t.todo !== true)
-+          t.name += ' - ' + Base.color('pending', t.todo)
-+        todoMsg += bullet + t.name + '\n'
-+        if (t.diag)
-+          todoMsg += indent(yaml.safeDump(t.diag), 4) + '\n'
-+      })
-+      console.log(indent(todoMsg, 2))
-+    }
-+
-+    if (skipped) {
-+      var fmt = Base.color('skip', indent('Skipped: %d', 2))
-+      console.log(fmt, skipped)
-+      if (skipMsg.length)
-+        console.log(indent(skipMsg.join('\n'), 4))
-+      console.log('')
-+    }
-+  })
-+
-+  runner.on('test', function (test) {
-+    total ++
-+    grandTotal ++
-+    var t = test.result
-+    if (fancy && currentSuite) {
-+      var max = 57 - uclen(currentSuite.title)
-+      if (max < 3)
-+        max = 3
-+
-+      if (tickDots > max) {
-+        tickDots = 0
-+        Base.cursor.deleteLine()
-+        Base.cursor.beginningOfLine();
-+        process.stdout.write(currentSuite.title + ' ')
-+      }
-+      tickDots ++
-+
-+      if (t.todo &&
-+          (tickColor === 'checkmark' || tickColor === 'skip'))
-+        tickColor = 'pending'
-+      else if (t.skip && tickColor === 'checkmark')
-+        tickColor = 'skip'
-+      else if (!t.ok)
-+        tickColor = 'fail'
-+
-+      process.stdout.write(Base.color(tickColor, '.'))
-+    }
-+
-+    if (t.skip) {
-+      skipped += 1
-+      if (t.skip !== true)
-+        skipMsg.push(t.name + ' ' + Base.color('skip', t.skip))
-+      else
-+        skipMsg.push(t.name)
-+    }
-+    else if (t.todo)
-+      todo.push(t)
-+    else if (!t.ok) {
-+      t.parent = []
-+      var p = test.parent
-+      while (p && p !== currentSuite) {
-+        var n  = p.title || p.name || p.fullTitle()
-+        if (n)
-+          t.parent.unshift(n)
-+        p = p.parent
-+      }
-+      t.parent.shift()
-+      t.parent = t.parent.join(' > ')
-+      fails.push(t)
-+      hadFails = true
-+    }
-+    else {
-+      pass ++
-+      grandPass ++
-+    }
-+  })
-+
-+  runner.on('end', function () {
-+    total = grandTotal
-+    pass = grandPass
-+    tests = []
-+    todo = []
-+    fails = []
-+    skipMsg = []
-+    skipped = 0
-+    if (hadFails)
-+      fails = [,,,]
-+    runner.emit('suite end', { title: 'total', root: true })
-+    self.failures = []
-+    self.epilogue();
-+
-+    if (grandTotal === grandPass) {
-+      console.log(Base.color('checkmark', '\n  ok'))
-+    }
-+  })
-+}
-+
-+function indent (str, n) {
-+  var ind = new Array(n + 1).join(' ')
-+  str = ind + str.split('\n').join('\n' + ind)
-+  return str.replace(/(\n\s*)+$/, '\n')
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/dot.js
-@@ -0,0 +1,62 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , color = Base.color;
-+
-+/**
-+ * Expose `Dot`.
-+ */
-+
-+exports = module.exports = Dot;
-+
-+/**
-+ * Initialize a new `Dot` matrix test reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Dot(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , width = Base.window.width * .75 | 0
-+    , n = -1;
-+
-+  runner.on('start', function(){
-+    process.stdout.write('\n');
-+  });
-+
-+  runner.on('pending', function(test){
-+    if (++n % width == 0) process.stdout.write('\n  ');
-+    process.stdout.write(color('pending', Base.symbols.dot));
-+  });
-+
-+  runner.on('pass', function(test){
-+    if (++n % width == 0) process.stdout.write('\n  ');
-+    if ('slow' == test.speed) {
-+      process.stdout.write(color('bright yellow', Base.symbols.dot));
-+    } else {
-+      process.stdout.write(color(test.speed, Base.symbols.dot));
-+    }
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    if (++n % width == 0) process.stdout.write('\n  ');
-+    process.stdout.write(color('fail', Base.symbols.dot));
-+  });
-+
-+  runner.on('end', function(){
-+    console.log();
-+    self.epilogue();
-+  });
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+Dot.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/min.js
-@@ -0,0 +1,37 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base');
-+
-+/**
-+ * Expose `Min`.
-+ */
-+
-+exports = module.exports = Min;
-+
-+/**
-+ * Initialize a new `Min` minimal test reporter (best used with --watch).
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Min(runner) {
-+  Base.call(this, runner);
-+
-+  runner.on('start', function(){
-+    // clear screen
-+    process.stdout.write('\u001b[2J');
-+    // set cursor position
-+    process.stdout.write('\u001b[1;3H');
-+  });
-+
-+  runner.on('end', this.epilogue.bind(this));
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+Min.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/progress.js
-@@ -0,0 +1,92 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color;
-+
-+/**
-+ * Expose `Progress`.
-+ */
-+
-+exports = module.exports = Progress;
-+
-+/**
-+ * General progress bar color.
-+ */
-+
-+Base.colors.progress = 90;
-+
-+/**
-+ * Initialize a new `Progress` bar test reporter.
-+ *
-+ * @param {Runner} runner
-+ * @param {Object} options
-+ * @api public
-+ */
-+
-+function Progress(runner, options) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , options = options || {}
-+    , stats = this.stats
-+    , width = Base.window.width * .50 | 0
-+    , total = runner.total
-+    , complete = 0
-+    , max = Math.max
-+    , lastN = -1;
-+
-+  // default chars
-+  options.open = options.open || '[';
-+  options.complete = options.complete || '▬';
-+  options.incomplete = options.incomplete || Base.symbols.dot;
-+  options.close = options.close || ']';
-+  options.verbose = false;
-+
-+  // tests started
-+  runner.on('start', function(){
-+    console.log();
-+    cursor.hide();
-+  });
-+
-+  // tests complete
-+  runner.on('test end', function(){
-+    complete++;
-+    var incomplete = total - complete
-+      , percent = complete / total
-+      , n = width * percent | 0
-+      , i = width - n;
-+
-+    if (lastN === n && !options.verbose) {
-+      // Don't re-render the line if it hasn't changed
-+      return;
-+    }
-+    lastN = n;
-+
-+    cursor.CR();
-+    process.stdout.write('\u001b[J');
-+    process.stdout.write(color('progress', '  ' + options.open));
-+    process.stdout.write(Array(n).join(options.complete));
-+    process.stdout.write(Array(i).join(options.incomplete));
-+    process.stdout.write(color('progress', options.close));
-+    if (options.verbose) {
-+      process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
-+    }
-+  });
-+
-+  // tests are complete, output some stats
-+  // and the failures if any
-+  runner.on('end', function(){
-+    cursor.show();
-+    console.log();
-+    self.epilogue();
-+  });
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+Progress.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/silent.js
-@@ -0,0 +1 @@
-+exports = module.exports = function () {}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/spec.js
-@@ -0,0 +1,82 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color;
-+
-+/**
-+ * Expose `Spec`.
-+ */
-+
-+exports = module.exports = Spec;
-+
-+/**
-+ * Initialize a new `Spec` test reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Spec(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , indents = 0
-+    , n = 0;
-+
-+  function indent() {
-+    return Array(indents).join('  ')
-+  }
-+
-+  runner.on('start', function(){
-+    console.log();
-+  });
-+
-+  runner.on('suite', function(suite){
-+    ++indents;
-+    console.log(color('suite', '%s%s'), indent(), suite.title);
-+  });
-+
-+  runner.on('suite end', function(suite){
-+    --indents;
-+    if (1 == indents) console.log();
-+  });
-+
-+  runner.on('pending', function(test){
-+    var fmt = indent() + color('pending', '  - %s');
-+    console.log(fmt, test.title);
-+  });
-+
-+  runner.on('pass', function(test){
-+    if ('fast' == test.speed) {
-+      var fmt = indent()
-+        + color('checkmark', '  ' + Base.symbols.ok)
-+        + color('pass', ' %s');
-+      cursor.CR();
-+      console.log(fmt, test.title);
-+    } else {
-+      var fmt = indent()
-+        + color('checkmark', '  ' + Base.symbols.ok)
-+        + color('pass', ' %s')
-+        + color(test.speed, ' (%dms)');
-+      cursor.CR();
-+      console.log(fmt, test.title, test.duration);
-+    }
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    cursor.CR();
-+    console.log(indent() + color('fail', '  %d) %s'), ++n, test.title);
-+  });
-+
-+  runner.on('end', self.epilogue.bind(self));
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+Spec.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/runner.js
-@@ -0,0 +1,347 @@
-+// A facade from the tap-parser to the Mocha "Runner" object.
-+// Note that pass/fail/suite events need to also mock the "Runnable"
-+// objects (either "Suite" or "Test") since these have functions
-+// which are called by the formatters.
-+
-+module.exports = Runner
-+
-+// relevant events:
-+//
-+// start()
-+//   Start of the top-level test set
-+//
-+// end()
-+//   End of the top-level test set.
-+//
-+// fail(test, err)
-+//   any "not ok" test that is not the trailing test for a suite
-+//   of >0 test points.
-+//
-+// pass(test)
-+//   any "ok" test point that is not the trailing test for a suite
-+//   of >0 tests
-+//
-+// pending(test)
-+//   Any "todo" test
-+//
-+// suite(suite)
-+//   A suite is a child test with >0 test points.  This is a little bit
-+//   tricky, because TAP will provide a "child" event before we know
-+//   that it's a "suite".  We see the "# Subtest: name" comment as the
-+//   first thing in the subtest.  Then, when we get our first test point,
-+//   we know that it's a suite, and can emit the event with the mock suite.
-+//
-+// suite end(suite)
-+//   Emitted when we end the subtest
-+//
-+// test(test)
-+//   Any test point which is not the trailing test for a suite.
-+//
-+// test end(test)
-+//   Emitted immediately after the "test" event because test points are
-+//   not async in TAP.
-+
-+var util = require('util')
-+var Test = require('./test.js')
-+var Suite = require('./suite.js')
-+var Writable = require('stream').Writable
-+if (!Writable) {
-+  try {
-+    Writable = require('readable-stream').Writable
-+  } catch (er) {
-+    throw new Error('Please install "readable-stream" to use this module ' +
-+                    'with Node.js v0.8 and before')
-+  }
-+}
-+
-+var Parser = require('tap-parser')
-+
-+// $1 = number, $2 = units
-+var timere = /^#\s*time=((?:0|[1-9][0-9]*?)(?:\.[0-9]+)?)(ms|s)?$/
-+
-+util.inherits(Runner, Writable)
-+
-+function Runner (options) {
-+  if (!(this instanceof Runner))
-+    return new Runner(options)
-+
-+  var parser = this.parser = new Parser(options)
-+  this.startTime = new Date()
-+
-+  attachEvents(this, parser, 0)
-+  Writable.call(this, options)
-+}
-+
-+Runner.prototype.write = function () {
-+  if (!this.emittedStart) {
-+    this.emittedStart = true
-+    this.emit('start')
-+  }
-+
-+  return this.parser.write.apply(this.parser, arguments)
-+}
-+
-+Runner.prototype.end = function () {
-+  return this.parser.end.apply(this.parser, arguments)
-+}
-+
-+Parser.prototype.fullTitle = function () {
-+  if (!this.parent)
-+    return this.name || ''
-+  else
-+    return (this.parent.fullTitle() + ' ' + (this.name || '')).trim()
-+}
-+
-+function attachEvents (runner, parser, level) {
-+  parser.runner = runner
-+
-+  if (level === 0) {
-+    parser.on('line', function (c) {
-+      runner.emit('line', c)
-+    })
-+    parser.on('version', function (v) {
-+      runner.emit('version', v)
-+    })
-+    parser.on('complete', function (res) {
-+      runner.emit('end')
-+    })
-+    parser.on('comment', function (c) {
-+      var tmatch = c.trim().match(timere)
-+      if (tmatch) {
-+        var t = +tmatch[1]
-+        if (tmatch[2] === 's')
-+          t *= 1000
-+        parser.time = t
-+        if (runner.stats)
-+          runner.stats.duration = t
-+      }
-+    })
-+  }
-+
-+  parser.emittedSuite = false
-+  parser.didAssert = false
-+  parser.name = parser.name || ''
-+  parser.doingChild = null
-+
-+  parser.on('complete', function (res) {
-+    if (!res.ok) {
-+      var fail = { ok: false, diag: {} }
-+      var count = res.count
-+      if (res.plan) {
-+        var plan = res.plan.end - res.plan.start + 1
-+        if (count !== plan) {
-+          fail.name = 'test count !== plan'
-+          fail.diag = {
-+            found: count,
-+            wanted: plan
-+          }
-+        } else {
-+          // probably handled on child parser
-+          return
-+        }
-+      } else {
-+        fail.name = 'missing plan'
-+      }
-+      fail.diag.results = res
-+      emitTest(parser, fail)
-+    }
-+  })
-+
-+  parser.on('child', function (child) {
-+    child.parent = parser
-+    attachEvents(runner, child, level + 1)
-+
-+    // if we're in a suite, but we haven't emitted it yet, then we
-+    // know that an assert will follow this child, even if there are
-+    // no others. That means that we will definitely have a 'suite'
-+    // event to emit.
-+    emitSuite(this)
-+
-+    this.didAssert = true
-+    this.doingChild = child
-+  })
-+
-+  if (!parser.name) {
-+    parser.on('comment', function (c) {
-+      if (!this.name && c.match(/^# Subtest: /)) {
-+        c = c.trim().replace(/^# Subtest: /, '')
-+        this.name = c
-+      }
-+    })
-+  }
-+
-+  // Just dump all non-parsing stuff to stderr
-+  parser.on('extra', function (c) {
-+    process.stderr.write(c)
-+  })
-+
-+  parser.on('assert', function (result) {
-+    emitSuite(this)
-+
-+    // no need to print the trailing assert for subtests
-+    // we've already emitted a 'suite end' event for this.
-+    // UNLESS, there were no other asserts, AND it's root level
-+    if (this.doingChild) {
-+      var suite = this.doingChild.suite
-+      if (this.doingChild.name === result.name) {
-+        if (suite) {
-+          if (result.time)
-+            suite.duration = result.time
-+
-+          // If it's ok so far, but the ending result is not-ok, then
-+          // that means that it exited non-zero.  Emit the test so
-+          // that we can print it as a failure.
-+          if (suite.ok && !result.ok)
-+            emitTest(this, result)
-+        }
-+      }
-+
-+      var emitOn = this
-+      var dc = this.doingChild
-+      this.doingChild = null
-+
-+      if (!dc.didAssert && dc.level === 1) {
-+        emitOn = dc
-+      } else if (dc.didAssert) {
-+        if (dc.suite)
-+          runner.emit('suite end', dc.suite)
-+        return
-+      } else {
-+        emitOn = this
-+      }
-+
-+      emitSuite(emitOn)
-+      emitTest(emitOn, result)
-+      if (emitOn !== this && emitOn.suite) {
-+        runner.emit('suite end', emitOn.suite)
-+        delete emitOn.suite
-+      }
-+      if (dc.suite) {
-+        runner.emit('suite end', dc.suite)
-+      }
-+      return
-+    }
-+
-+    this.didAssert = true
-+    this.doingChild = null
-+
-+    emitTest(this, result)
-+  })
-+
-+  parser.on('complete', function (results) {
-+    this.results = results
-+  })
-+
-+  parser.on('bailout', function (reason) {
-+    var suite = this.suite
-+    runner.emit('bailout', reason, suite)
-+    if (suite)
-+      this.suite = suite.parent
-+  })
-+
-+  // proxy all stream events directly
-+  var streamEvents = [
-+    'pipe', 'prefinish', 'finish', 'unpipe', 'close'
-+  ]
-+
-+  streamEvents.forEach(function (ev) {
-+    parser.on(ev, function () {
-+      var args = [ev]
-+      args.push.apply(args, arguments)
-+      runner.emit.apply(runner, args)
-+    })
-+  })
-+}
-+
-+function emitSuite (parser) {
-+  if (!parser.emittedSuite && parser.name) {
-+    parser.emittedSuite = true
-+    var suite = parser.suite = new Suite(parser)
-+    if (parser.parent && parser.parent.suite)
-+      parser.parent.suite.suites.push(suite)
-+    if (parser.runner.stats)
-+      parser.runner.stats.suites ++
-+
-+    parser.runner.emit('suite', suite)
-+  }
-+}
-+
-+function emitTest (parser, result) {
-+  var runner = parser.runner
-+  var test = new Test(result, parser)
-+
-+  if (parser.suite) {
-+    parser.suite.tests.push(test)
-+    if (!result.ok) {
-+      for (var p = parser; p && p.suite; p = p.parent) {
-+        p.suite.ok = false
-+      }
-+    }
-+    parser.suite.ok = parser.suite.ok && result.ok
-+  }
-+
-+  runner.emit('test', test)
-+  if (result.skip || result.todo) {
-+    runner.emit('pending', test)
-+  } else if (result.ok) {
-+    runner.emit('pass', test)
-+  } else {
-+    var error = getError(result)
-+    runner.emit('fail', test, error)
-+  }
-+  runner.emit('test end', test)
-+}
-+
-+function getError (result) {
-+  var err
-+
-+  function reviveStack (stack) {
-+    if (!stack)
-+      return null
-+
-+    return stack.trim().split('\n').map(function (line) {
-+      return '    at ' + line
-+    }).join('\n')
-+  }
-+
-+  if (result.diag && result.diag.error) {
-+    err = {
-+      name: result.diag.error.name || 'Error',
-+      message: result.diag.error.message,
-+      toString: function () {
-+        return this.name + ': ' + this.message
-+      },
-+      stack: result.diag.error.stack
-+    }
-+  } else {
-+    err = {
-+      message: (result.name || '(unnamed error)').replace(/^Error: /, ''),
-+      toString: function () {
-+        return 'Error: ' + this.message
-+      },
-+      stack: result.diag && result.diag.stack
-+    }
-+  }
-+
-+  var diag = result.diag
-+
-+  if (err.stack)
-+    err.stack = err.toString() + '\n' + reviveStack(err.stack)
-+
-+  if (diag) {
-+    var hasFound = diag.hasOwnProperty('found')
-+    var hasWanted = diag.hasOwnProperty('wanted')
-+
-+    if (hasFound)
-+      err.actual = diag.found
-+
-+    if (hasWanted)
-+      err.expected = diag.wanted
-+
-+    if (hasFound && hasWanted)
-+      err.showDiff = true
-+  }
-+
-+  return err
-+}
-+
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/suite.js
-@@ -0,0 +1,22 @@
-+// minimal mock of mocha's Suite class for formatters
-+
-+module.exports = Suite
-+
-+function Suite (parent) {
-+  if (!parent.parent || !parent.parent.emittedSuite)
-+    this.root = true
-+  else
-+    this.root = false
-+
-+  this.title = parent.name || ''
-+  this.suites = []
-+  this.tests = []
-+  this.ok = true
-+}
-+
-+Suite.prototype.fullTitle = function () {
-+  if (!this.parent)
-+    return (this.title || '').trim()
-+  else
-+    return (this.parent.fullTitle() + ' ' + (this.title || '')).trim()
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/test.js
-@@ -0,0 +1,41 @@
-+// minimal mock of the mocha Test class for formatters
-+
-+module.exports = Test
-+
-+function Test (result, parent) {
-+  this.result = result
-+  this._slow = 75
-+  this.duration = result.time
-+  this.title = result.name
-+  this.state = result.ok ? 'pass' : 'failed'
-+  this.pending = result.todo || result.skip || false
-+  if (result.diag && result.diag.source) {
-+    var source = result.diag.source
-+    this.fn = {
-+      toString: function () {
-+        return 'function(){' + source + '\n}'
-+      }
-+    }
-+  }
-+
-+  Object.defineProperty(this, 'parent', {
-+    value: parent,
-+    writable: true,
-+    configurable: true,
-+    enumerable: false
-+  })
-+}
-+
-+Test.prototype.fullTitle = function () {
-+  return (this.parent.fullTitle() + ' ' + (this.title || '')).trim()
-+}
-+
-+Test.prototype.slow = function (ms){
-+  return 75
-+}
-+
-+Test.prototype.fn = {
-+  toString: function () {
-+    return 'function () {\n}'
-+  }
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/utils.js
-@@ -0,0 +1,699 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var fs = require('fs')
-+  , path = require('path')
-+  , basename = path.basename
-+  , exists = fs.existsSync || path.existsSync
-+  , glob = require('glob')
-+  , join = path.join
-+  , debug = require('debug')('mocha:watch');
-+
-+/**
-+ * Ignored directories.
-+ */
-+
-+var ignore = ['node_modules', '.git'];
-+
-+/**
-+ * Escape special characters in the given string of html.
-+ *
-+ * @param  {String} html
-+ * @return {String}
-+ * @api private
-+ */
-+
-+exports.escape = function(html){
-+  return String(html)
-+    .replace('&', '&')
-+    .replace('"', '"')
-+    .replace('<', '<')
-+    .replace('>', '>');
-+};
-+
-+/**
-+ * Array#forEach (<=IE8)
-+ *
-+ * @param {Array} array
-+ * @param {Function} fn
-+ * @param {Object} scope
-+ * @api private
-+ */
-+
-+exports.forEach = function(arr, fn, scope){
-+  for (var i = 0, l = arr.length; i < l; i++)
-+    fn.call(scope, arr[i], i);
-+};
-+
-+/**
-+ * Array#map (<=IE8)
-+ *
-+ * @param {Array} array
-+ * @param {Function} fn
-+ * @param {Object} scope
-+ * @api private
-+ */
-+
-+exports.map = function(arr, fn, scope){
-+  var result = [];
-+  for (var i = 0, l = arr.length; i < l; i++)
-+    result.push(fn.call(scope, arr[i], i, arr));
-+  return result;
-+};
-+
-+/**
-+ * Array#indexOf (<=IE8)
-+ *
-+ * @parma {Array} arr
-+ * @param {Object} obj to find index of
-+ * @param {Number} start
-+ * @api private
-+ */
-+
-+exports.indexOf = function(arr, obj, start){
-+  for (var i = start || 0, l = arr.length; i < l; i++) {
-+    if (arr[i] === obj)
-+      return i;
-+  }
-+  return -1;
-+};
-+
-+/**
-+ * Array#reduce (<=IE8)
-+ *
-+ * @param {Array} array
-+ * @param {Function} fn
-+ * @param {Object} initial value
-+ * @api private
-+ */
-+
-+exports.reduce = function(arr, fn, val){
-+  var rval = val;
-+
-+  for (var i = 0, l = arr.length; i < l; i++) {
-+    rval = fn(rval, arr[i], i, arr);
-+  }
-+
-+  return rval;
-+};
-+
-+/**
-+ * Array#filter (<=IE8)
-+ *
-+ * @param {Array} array
-+ * @param {Function} fn
-+ * @api private
-+ */
-+
-+exports.filter = function(arr, fn){
-+  var ret = [];
-+
-+  for (var i = 0, l = arr.length; i < l; i++) {
-+    var val = arr[i];
-+    if (fn(val, i, arr)) ret.push(val);
-+  }
-+
-+  return ret;
-+};
-+
-+/**
-+ * Object.keys (<=IE8)
-+ *
-+ * @param {Object} obj
-+ * @return {Array} keys
-+ * @api private
-+ */
-+
-+exports.keys = Object.keys || function(obj) {
-+  var keys = []
-+    , has = Object.prototype.hasOwnProperty; // for `window` on <=IE8
-+
-+  for (var key in obj) {
-+    if (has.call(obj, key)) {
-+      keys.push(key);
-+    }
-+  }
-+
-+  return keys;
-+};
-+
-+/**
-+ * Watch the given `files` for changes
-+ * and invoke `fn(file)` on modification.
-+ *
-+ * @param {Array} files
-+ * @param {Function} fn
-+ * @api private
-+ */
-+
-+exports.watch = function(files, fn){
-+  var options = { interval: 100 };
-+  files.forEach(function(file){
-+    debug('file %s', file);
-+    fs.watchFile(file, options, function(curr, prev){
-+      if (prev.mtime < curr.mtime) fn(file);
-+    });
-+  });
-+};
-+
-+/**
-+ * Array.isArray (<=IE8)
-+ *
-+ * @param {Object} obj
-+ * @return {Boolean}
-+ * @api private
-+ */
-+var isArray = Array.isArray || function (obj) {
-+  return '[object Array]' == {}.toString.call(obj);
-+};
-+
-+/**
-+ * @description
-+ * Buffer.prototype.toJSON polyfill
-+ * @type {Function}
-+ */
-+if(typeof Buffer !== 'undefined' && Buffer.prototype) {
-+  Buffer.prototype.toJSON = Buffer.prototype.toJSON || function () {
-+    return Array.prototype.slice.call(this, 0);
-+  };
-+}
-+
-+/**
-+ * Ignored files.
-+ */
-+
-+function ignored(path){
-+  return !~ignore.indexOf(path);
-+}
-+
-+/**
-+ * Lookup files in the given `dir`.
-+ *
-+ * @return {Array}
-+ * @api private
-+ */
-+
-+exports.files = function(dir, ext, ret){
-+  ret = ret || [];
-+  ext = ext || ['js'];
-+
-+  var re = new RegExp('\\.(' + ext.join('|') + ')$');
-+
-+  fs.readdirSync(dir)
-+    .filter(ignored)
-+    .forEach(function(path){
-+      path = join(dir, path);
-+      if (fs.statSync(path).isDirectory()) {
-+        exports.files(path, ext, ret);
-+      } else if (path.match(re)) {
-+        ret.push(path);
-+      }
-+    });
-+
-+  return ret;
-+};
-+
-+/**
-+ * Compute a slug from the given `str`.
-+ *
-+ * @param {String} str
-+ * @return {String}
-+ * @api private
-+ */
-+
-+exports.slug = function(str){
-+  return str
-+    .toLowerCase()
-+    .replace(/ +/g, '-')
-+    .replace(/[^-\w]/g, '');
-+};
-+
-+/**
-+ * Strip the function definition from `str`,
-+ * and re-indent for pre whitespace.
-+ */
-+
-+exports.clean = function(str) {
-+  str = str
-+    .replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '')
-+    .replace(/^function *\(.*\) *{|\(.*\) *=> *{?/, '')
-+    .replace(/\s+\}$/, '');
-+
-+  var spaces = str.match(/^\n?( *)/)[1].length
-+    , tabs = str.match(/^\n?(\t*)/)[1].length
-+    , re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm');
-+
-+  str = str.replace(re, '');
-+
-+  return exports.trim(str);
-+};
-+
-+/**
-+ * Trim the given `str`.
-+ *
-+ * @param {String} str
-+ * @return {String}
-+ * @api private
-+ */
-+
-+exports.trim = function(str){
-+  return str.replace(/^\s+|\s+$/g, '');
-+};
-+
-+/**
-+ * Parse the given `qs`.
-+ *
-+ * @param {String} qs
-+ * @return {Object}
-+ * @api private
-+ */
-+
-+exports.parseQuery = function(qs){
-+  return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
-+    var i = pair.indexOf('=')
-+      , key = pair.slice(0, i)
-+      , val = pair.slice(++i);
-+
-+    obj[key] = decodeURIComponent(val);
-+    return obj;
-+  }, {});
-+};
-+
-+/**
-+ * Highlight the given string of `js`.
-+ *
-+ * @param {String} js
-+ * @return {String}
-+ * @api private
-+ */
-+
-+function highlight(js) {
-+  return js
-+    .replace(/</g, '<')
-+    .replace(/>/g, '>')
-+    .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
-+    .replace(/('.*?')/gm, '<span class="string">$1</span>')
-+    .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
-+    .replace(/(\d+)/gm, '<span class="number">$1</span>')
-+    .replace(/\bnew[ \t]+(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
-+    .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
-+}
-+
-+/**
-+ * Highlight the contents of tag `name`.
-+ *
-+ * @param {String} name
-+ * @api private
-+ */
-+
-+exports.highlightTags = function(name) {
-+  var code = document.getElementById('mocha').getElementsByTagName(name);
-+  for (var i = 0, len = code.length; i < len; ++i) {
-+    code[i].innerHTML = highlight(code[i].innerHTML);
-+  }
-+};
-+
-+/**
-+ * If a value could have properties, and has none, this function is called, which returns
-+ * a string representation of the empty value.
-+ *
-+ * Functions w/ no properties return `'[Function]'`
-+ * Arrays w/ length === 0 return `'[]'`
-+ * Objects w/ no properties return `'{}'`
-+ * All else: return result of `value.toString()`
-+ *
-+ * @param {*} value Value to inspect
-+ * @param {string} [type] The type of the value, if known.
-+ * @returns {string}
-+ */
-+var emptyRepresentation = function emptyRepresentation(value, type) {
-+  type = type || exports.type(value);
-+
-+  switch(type) {
-+    case 'function':
-+      return '[Function]';
-+    case 'object':
-+      return '{}';
-+    case 'array':
-+      return '[]';
-+    default:
-+      return value.toString();
-+  }
-+};
-+
-+/**
-+ * Takes some variable and asks `{}.toString()` what it thinks it is.
-+ * @param {*} value Anything
-+ * @example
-+ * type({}) // 'object'
-+ * type([]) // 'array'
-+ * type(1) // 'number'
-+ * type(false) // 'boolean'
-+ * type(Infinity) // 'number'
-+ * type(null) // 'null'
-+ * type(new Date()) // 'date'
-+ * type(/foo/) // 'regexp'
-+ * type('type') // 'string'
-+ * type(global) // 'global'
-+ * @api private
-+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
-+ * @returns {string}
-+ */
-+exports.type = function type(value) {
-+  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
-+    return 'buffer';
-+  }
-+  return Object.prototype.toString.call(value)
-+    .replace(/^\[.+\s(.+?)\]$/, '$1')
-+    .toLowerCase();
-+};
-+
-+/**
-+ * @summary Stringify `value`.
-+ * @description Different behavior depending on type of value.
-+ * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.
-+ * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.
-+ * - If `value` is an *empty* object, function, or array, return result of function
-+ *   {@link emptyRepresentation}.
-+ * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of
-+ *   JSON.stringify().
-+ *
-+ * @see exports.type
-+ * @param {*} value
-+ * @return {string}
-+ * @api private
-+ */
-+
-+exports.stringify = function(value) {
-+  var type = exports.type(value);
-+
-+  if (!~exports.indexOf(['object', 'array', 'function'], type)) {
-+    if(type != 'buffer') {
-+      return jsonStringify(value);
-+    }
-+    var json = value.toJSON();
-+    // Based on the toJSON result
-+    return jsonStringify(json.data && json.type ? json.data : json, 2)
-+      .replace(/,(\n|$)/g, '$1');
-+  }
-+
-+  for (var prop in value) {
-+    if (Object.prototype.hasOwnProperty.call(value, prop)) {
-+      return jsonStringify(exports.canonicalize(value), 2)
-+        .replace(/,(\n|$)/g, '$1');
-+    }
-+  }
-+
-+  return emptyRepresentation(value, type);
-+};
-+
-+/**
-+ * @description
-+ * like JSON.stringify but more sense.
-+ * @param {Object}  object
-+ * @param {Number=} spaces
-+ * @param {number=} depth
-+ * @returns {*}
-+ * @private
-+ */
-+function jsonStringify(object, spaces, depth) {
-+  if(typeof spaces == 'undefined') return _stringify(object);  // primitive types
-+
-+  depth = depth || 1;
-+  var space = spaces * depth
-+    , str = isArray(object) ? '[' : '{'
-+    , end = isArray(object) ? ']' : '}'
-+    , length = object.length || exports.keys(object).length
-+    , repeat = function(s, n) { return new Array(n).join(s); }; // `.repeat()` polyfill
-+
-+  function _stringify(val) {
-+    switch (exports.type(val)) {
-+      case 'null':
-+      case 'undefined':
-+        val = '[' + val + ']';
-+        break;
-+      case 'array':
-+      case 'object':
-+        val = jsonStringify(val, spaces, depth + 1);
-+        break;
-+      case 'boolean':
-+      case 'regexp':
-+      case 'number':
-+        val = val === 0 && (1/val) === -Infinity // `-0`
-+          ? '-0'
-+          : val.toString();
-+        break;
-+      case 'date':
-+        val = '[Date: ' + val.toISOString() + ']';
-+        break;
-+      case 'buffer':
-+        var json = val.toJSON();
-+        // Based on the toJSON result
-+        json = json.data && json.type ? json.data : json;
-+        val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']';
-+        break;
-+      default:
-+        val = (val == '[Function]' || val == '[Circular]')
-+          ? val
-+          : '"' + val + '"'; //string
-+    }
-+    return val;
-+  }
-+
-+  for(var i in object) {
-+    if(!Object.prototype.hasOwnProperty.call(object, i)) continue;        // not my business
-+    --length;
-+    str += '\n ' + repeat(' ', space)
-+      + (isArray(object) ? '' : '"' + i + '": ') // key
-+      +  _stringify(object[i])                   // value
-+      + (length ? ',' : '');                     // comma
-+  }
-+
-+  return str + (str.length != 1                    // [], {}
-+    ? '\n' + repeat(' ', --space) + end
-+    : end);
-+}
-+
-+/**
-+ * Return if obj is a Buffer
-+ * @param {Object} arg
-+ * @return {Boolean}
-+ * @api private
-+ */
-+exports.isBuffer = function (arg) {
-+  return typeof Buffer !== 'undefined' && Buffer.isBuffer(arg);
-+};
-+
-+/**
-+ * @summary Return a new Thing that has the keys in sorted order.  Recursive.
-+ * @description If the Thing...
-+ * - has already been seen, return string `'[Circular]'`
-+ * - is `undefined`, return string `'[undefined]'`
-+ * - is `null`, return value `null`
-+ * - is some other primitive, return the value
-+ * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method
-+ * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.
-+ * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`
-+ *
-+ * @param {*} value Thing to inspect.  May or may not have properties.
-+ * @param {Array} [stack=[]] Stack of seen values
-+ * @return {(Object|Array|Function|string|undefined)}
-+ * @see {@link exports.stringify}
-+ * @api private
-+ */
-+
-+exports.canonicalize = function(value, stack) {
-+  var canonicalizedObj,
-+    type = exports.type(value),
-+    prop,
-+    withStack = function withStack(value, fn) {
-+      stack.push(value);
-+      fn();
-+      stack.pop();
-+    };
-+
-+  stack = stack || [];
-+
-+  if (exports.indexOf(stack, value) !== -1) {
-+    return '[Circular]';
-+  }
-+
-+  switch(type) {
-+    case 'undefined':
-+    case 'buffer':
-+    case 'null':
-+      canonicalizedObj = value;
-+      break;
-+    case 'array':
-+      withStack(value, function () {
-+        canonicalizedObj = exports.map(value, function (item) {
-+          return exports.canonicalize(item, stack);
-+        });
-+      });
-+      break;
-+    case 'function':
-+      for (prop in value) {
-+        canonicalizedObj = {};
-+        break;
-+      }
-+      if (!canonicalizedObj) {
-+        canonicalizedObj = emptyRepresentation(value, type);
-+        break;
-+      }
-+    /* falls through */
-+    case 'object':
-+      canonicalizedObj = canonicalizedObj || {};
-+      withStack(value, function () {
-+        exports.forEach(exports.keys(value).sort(), function (key) {
-+          canonicalizedObj[key] = exports.canonicalize(value[key], stack);
-+        });
-+      });
-+      break;
-+    case 'date':
-+    case 'number':
-+    case 'regexp':
-+    case 'boolean':
-+      canonicalizedObj = value;
-+      break;
-+    default:
-+      canonicalizedObj = value.toString();
-+  }
-+
-+  return canonicalizedObj;
-+};
-+
-+/**
-+ * Lookup file names at the given `path`.
-+ */
-+exports.lookupFiles = function lookupFiles(path, extensions, recursive) {
-+  var files = [];
-+  var re = new RegExp('\\.(' + extensions.join('|') + ')$');
-+
-+  if (!exists(path)) {
-+    if (exists(path + '.js')) {
-+      path += '.js';
-+    } else {
-+      files = glob.sync(path);
-+      if (!files.length) throw new Error("cannot resolve path (or pattern) '" + path + "'");
-+      return files;
-+    }
-+  }
-+
-+  try {
-+    var stat = fs.statSync(path);
-+    if (stat.isFile()) return path;
-+  }
-+  catch (ignored) {
-+    return;
-+  }
-+
-+  fs.readdirSync(path).forEach(function(file) {
-+    file = join(path, file);
-+    try {
-+      var stat = fs.statSync(file);
-+      if (stat.isDirectory()) {
-+        if (recursive) {
-+          files = files.concat(lookupFiles(file, extensions, recursive));
-+        }
-+        return;
-+      }
-+    }
-+    catch (ignored) {
-+      return;
-+    }
-+    if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') return;
-+    files.push(file);
-+  });
-+
-+  return files;
-+};
-+
-+/**
-+ * Generate an undefined error with a message warning the user.
-+ *
-+ * @return {Error}
-+ */
-+
-+exports.undefinedError = function() {
-+  return new Error('Caught undefined error, did you throw without specifying what?');
-+};
-+
-+/**
-+ * Generate an undefined error if `err` is not defined.
-+ *
-+ * @param {Error} err
-+ * @return {Error}
-+ */
-+
-+exports.getError = function(err) {
-+  return err || exports.undefinedError();
-+};
-+
-+
-+/**
-+ * @summary
-+ * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)
-+ * @description
-+ * When invoking this function you get a filter function that get the Error.stack as an input,
-+ * and return a prettify output.
-+ * (i.e: strip Mocha, node_modules, bower and componentJS from stack trace).
-+ * @returns {Function}
-+ */
-+
-+exports.stackTraceFilter = function() {
-+  var slash = '/'
-+    , is = typeof document === 'undefined'
-+      ? { node: true }
-+      : { browser: true }
-+    , cwd = is.node
-+      ? process.cwd() + slash
-+      : location.href.replace(/\/[^\/]*$/, '/');
-+
-+  function isNodeModule (line) {
-+    return (~line.indexOf('node_modules'));
-+  }
-+
-+  function isMochaInternal (line) {
-+    return (~line.indexOf('node_modules' + slash + 'tap-mocha-reporter'))  ||
-+      (~line.indexOf('components' + slash + 'mochajs'))       ||
-+      (~line.indexOf('components' + slash + 'mocha'));
-+  }
-+
-+  // node_modules, bower, componentJS
-+  function isBrowserModule(line) {
-+    return (~line.indexOf('node_modules')) ||
-+      (~line.indexOf('components'));
-+  }
-+
-+  function isNodeInternal (line) {
-+    return (~line.indexOf('(timers.js:')) ||
-+      (~line.indexOf('(domain.js:'))      ||
-+      (~line.indexOf('(events.js:'))      ||
-+      (~line.indexOf('(node.js:'))        ||
-+      (~line.indexOf('(module.js:'))      ||
-+      (~line.indexOf('at node.js:'))      ||
-+      (~line.indexOf('GeneratorFunctionPrototype.next (native)')) ||
-+      false
-+  }
-+
-+  return function(stack) {
-+    stack = stack.split('\n');
-+
-+    stack = stack.reduce(function (list, line) {
-+      if (is.node && (isNodeModule(line) ||
-+        isMochaInternal(line) ||
-+        isNodeInternal(line)))
-+        return list;
-+
-+      if (is.browser && (isBrowserModule(line)))
-+        return list;
-+
-+      // Clean up cwd(absolute)
-+      list.push(line.replace(cwd, ''));
-+      return list;
-+    }, []);
-+
-+    return stack.join('\n');
-+  }
-+};
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/index.js
-@@ -0,0 +1,106 @@
-+#!/usr/bin/env node
-+
-+module.exports = Formatter
-+
-+var util = require('util')
-+var reporters = require('./lib/reporters/index.js')
-+Formatter.types = Object.keys(reporters).sort()
-+var Writable = require('stream').Writable
-+if (!Writable) {
-+  try {
-+    Writable = require('readable-stream').Writable
-+  } catch (er) {
-+    throw new Error('Please install "readable-stream" to use this module ' +
-+                    'with Node.js v0.8 and before')
-+  }
-+}
-+
-+var Runner = require('./lib/runner.js')
-+var Parser = require('tap-parser')
-+
-+util.inherits(Formatter, Writable)
-+
-+var exitCode
-+function Formatter (type, options) {
-+  if (!(this instanceof Formatter)) {
-+    return new Formatter(type, options)
-+  }
-+  if (!reporters[type]) {
-+    console.error('Unknown format type: %s\n\n%s', type, avail())
-+    type = 'silent'
-+  }
-+
-+  this.writable = true
-+
-+  // don't actually need a reporter to report the tap we're getting
-+  // just parse it so that we exit with the correct code, but otherwise
-+  // dump it straight through to stdout.
-+  if (type === 'tap') {
-+    var p = new Parser()
-+    this.write = function (chunk) {
-+      process.stdout.write(chunk)
-+      return p.write(chunk)
-+    }
-+    this.end = p.end.bind(p)
-+    p.on('complete', function () {
-+      if (!p.ok)
-+        exitCode = 1
-+    })
-+    return this
-+  }
-+
-+  var runner = this.runner = new Runner(options)
-+  this.reporter = new reporters[type](this.runner, {})
-+  Writable.call(this, options)
-+
-+  runner.on('end', function () {
-+    if (!runner.parser.ok)
-+      exitCode = 1
-+  })
-+}
-+
-+process.on('exit', function (code) {
-+  if (!code && exitCode)
-+    process.exit(exitCode)
-+})
-+
-+Formatter.prototype.write = function () {
-+  return this.runner.write.apply(this.runner, arguments)
-+}
-+
-+Formatter.prototype.end = function () {
-+  return this.runner.end.apply(this.runner, arguments)
-+}
-+
-+function avail () {
-+  var types = Formatter.types.reduce(function (str, t) {
-+    var ll = str.split('\n').pop().length + t.length
-+    if (ll < 40)
-+      return str + ' ' + t
-+    else
-+      return str + '\n' + t
-+  }, '').trim()
-+
-+  return 'Available format types:\n\n' + types
-+}
-+
-+
-+function usage (err) {
-+  console[err ? 'error' : 'log'](function () {/*
-+Usage:
-+  tap-mocha-reporter <type>
-+
-+Reads TAP data on stdin, and formats to stdout using the specified
-+reporter.  (Note that some reporters write to files instead of stdout.)
-+
-+%s
-+*/}.toString().split('\n').slice(1, -1).join('\n'), avail())
-+}
-+
-+if (require.main === module) {
-+  var type = process.argv[2]
-+  if (!type)
-+    return usage()
-+
-+  process.stdin.pipe(new Formatter(type))
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/index.js
-@@ -0,0 +1,16 @@
-+exports.dot = require('./dot.js')
-+exports.doc = require('./doc.js')
-+exports.tap = true
-+exports.json = require('./json.js')
-+exports.list = require('./list.js')
-+exports.min = require('./min.js')
-+exports.spec = require('./spec.js')
-+exports.nyan = require('./nyan.js')
-+exports.xunit = require('./xunit.js')
-+exports.markdown = require('./markdown.js')
-+exports.progress = require('./progress.js')
-+exports.landing = require('./landing.js')
-+exports.jsonstream = require('./json-stream.js')
-+exports.dump = require('./dump.js')
-+exports.classic = require('./classic.js')
-+exports.silent = require('./silent.js')
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/doc.js
-@@ -0,0 +1,62 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , utils = require('../utils');
-+
-+/**
-+ * Expose `Doc`.
-+ */
-+
-+exports = module.exports = Doc;
-+
-+/**
-+ * Initialize a new `Doc` reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Doc(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , total = runner.total
-+    , indents = 2;
-+
-+  function indent() {
-+    return Array(indents).join('  ');
-+  }
-+
-+  runner.on('suite', function(suite){
-+    if (suite.root) return;
-+    ++indents;
-+    console.log('%s<section class="suite">', indent());
-+    ++indents;
-+    console.log('%s<h1>%s</h1>', indent(), utils.escape(suite.title));
-+    console.log('%s<dl>', indent());
-+  });
-+
-+  runner.on('suite end', function(suite){
-+    if (suite.root) return;
-+    console.log('%s</dl>', indent());
-+    --indents;
-+    console.log('%s</section>', indent());
-+    --indents;
-+  });
-+
-+  runner.on('pass', function(test){
-+    console.log('%s  <dt>%s</dt>', indent(), utils.escape(test.title));
-+    var code = utils.escape(utils.clean(test.fn.toString()));
-+    console.log('%s  <dd><pre><code>%s</code></pre></dd>', indent(), code);
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    console.log('%s  <dt class="error">%s</dt>', indent(), utils.escape(test.title));
-+    var code = utils.escape(utils.clean(test.fn.toString()));
-+    console.log('%s  <dd class="error"><pre><code>%s</code></pre></dd>', indent(), code);
-+    console.log('%s  <dd class="error">%s</dd>', indent(), utils.escape(err));
-+  });
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/dump.js
-@@ -0,0 +1,50 @@
-+exports = module.exports = Dump
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color
-+  , useColors = Base.useColors
-+  , util = require('util')
-+
-+function Dump(runner) {
-+  Base.call(this, runner);
-+
-+  var events = [
-+    'start',
-+    'version',
-+    'suite',
-+    'suite end',
-+    'test',
-+    'pending',
-+    'pass',
-+    'fail',
-+    'test end',
-+  ];
-+
-+  var i = process.argv.indexOf('dump')
-+  if (i !== -1) {
-+    var args = process.argv.slice(i + 1)
-+    if (args.length)
-+      events = args
-+  }
-+
-+  runner.on('line', function (c) {
-+    if (c.trim())
-+      process.stderr.write(Base.color('bright yellow', c))
-+  })
-+
-+  events.forEach(function (ev) {
-+    runner.on(ev, function (obj) {
-+      console.log(ev)
-+      if (arguments.length) {
-+        console.log(util.inspect(obj, false, Infinity, useColors))
-+        console.log()
-+      }
-+    })
-+  })
-+
-+  runner.on('end', function () {
-+    console.log('end')
-+    console.log(runner.stats)
-+    console.log()
-+  })
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/json-stream.js
-@@ -0,0 +1,62 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , color = Base.color;
-+
-+/**
-+ * Expose `List`.
-+ */
-+
-+exports = module.exports = List;
-+
-+/**
-+ * Initialize a new `List` test reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function List(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , total = runner.total;
-+
-+  runner.on('start', function(){
-+    console.log(JSON.stringify(['start', { total: total }]));
-+  });
-+
-+  runner.on('pass', function(test){
-+    console.log(JSON.stringify(['pass', clean(test)]));
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    test = clean(test);
-+    test.err = err.message;
-+    console.log(JSON.stringify(['fail', test]));
-+  });
-+
-+  runner.on('end', function(){
-+    process.stdout.write(JSON.stringify(['end', self.stats]));
-+  });
-+}
-+
-+/**
-+ * Return a plain-object representation of `test`
-+ * free of cyclic properties etc.
-+ *
-+ * @param {Object} test
-+ * @return {Object}
-+ * @api private
-+ */
-+
-+function clean(test) {
-+  return {
-+      title: test.title
-+    , fullTitle: test.fullTitle()
-+    , duration: test.duration
-+  }
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/json.js
-@@ -0,0 +1,92 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color;
-+
-+/**
-+ * Expose `JSON`.
-+ */
-+
-+exports = module.exports = JSONReporter;
-+
-+/**
-+ * Initialize a new `JSON` reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function JSONReporter(runner) {
-+  var self = this;
-+  Base.call(this, runner);
-+
-+  var tests = []
-+    , pending = []
-+    , failures = []
-+    , passes = [];
-+
-+  runner.on('test end', function(test){
-+    tests.push(test);
-+  });
-+
-+  runner.on('pass', function(test){
-+    passes.push(test);
-+  });
-+
-+  runner.on('fail', function(test){
-+    failures.push(test);
-+  });
-+
-+  runner.on('pending', function(test){
-+    pending.push(test);
-+  });
-+
-+  runner.on('end', function(){
-+    var obj = {
-+      stats: self.stats,
-+      tests: tests.map(clean),
-+      pending: pending.map(clean),
-+      failures: failures.map(clean),
-+      passes: passes.map(clean)
-+    };
-+
-+    runner.testResults = obj;
-+
-+    process.stdout.write(JSON.stringify(obj, null, 2));
-+  });
-+}
-+
-+/**
-+ * Return a plain-object representation of `test`
-+ * free of cyclic properties etc.
-+ *
-+ * @param {Object} test
-+ * @return {Object}
-+ * @api private
-+ */
-+
-+function clean(test) {
-+  return {
-+    title: test.title,
-+    fullTitle: test.fullTitle(),
-+    duration: test.duration,
-+    err: errorJSON(test.err || {})
-+  }
-+}
-+
-+/**
-+ * Transform `error` into a JSON object.
-+ * @param {Error} err
-+ * @return {Object}
-+ */
-+
-+function errorJSON(err) {
-+  var res = {};
-+  Object.getOwnPropertyNames(err).forEach(function(key) {
-+    res[key] = err[key];
-+  }, err);
-+  return res;
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/landing.js
-@@ -0,0 +1,96 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color;
-+
-+/**
-+ * Expose `Landing`.
-+ */
-+
-+exports = module.exports = Landing;
-+
-+/**
-+ * Airplane color.
-+ */
-+
-+Base.colors.plane = 0;
-+
-+/**
-+ * Airplane crash color.
-+ */
-+
-+Base.colors['plane crash'] = 31;
-+
-+/**
-+ * Runway color.
-+ */
-+
-+Base.colors.runway = 90;
-+
-+/**
-+ * Initialize a new `Landing` reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Landing(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , width = Base.window.width * .75 | 0
-+    , total = runner.total
-+    , stream = process.stdout
-+    , plane = color('plane', '✈')
-+    , crashed = -1
-+    , n = 0;
-+
-+  function runway() {
-+    var buf = Array(width).join('-');
-+    return '  ' + color('runway', buf);
-+  }
-+
-+  runner.on('start', function(){
-+    stream.write('\n\n\n  ');
-+    cursor.hide();
-+  });
-+
-+  runner.on('test end', function(test){
-+    // check if the plane crashed
-+    var col = -1 == crashed
-+      ? width * ++n / total | 0
-+      : crashed;
-+
-+    // show the crash
-+    if ('failed' == test.state) {
-+      plane = color('plane crash', '✈');
-+      crashed = col;
-+    }
-+
-+    // render landing strip
-+    stream.write('\u001b['+(width+1)+'D\u001b[2A');
-+    stream.write(runway());
-+    stream.write('\n  ');
-+    stream.write(color('runway', Array(col).join('⋅')));
-+    stream.write(plane)
-+    stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
-+    stream.write(runway());
-+    stream.write('\u001b[0m');
-+  });
-+
-+  runner.on('end', function(){
-+    cursor.show();
-+    console.log();
-+    self.epilogue();
-+  });
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+Landing.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/list.js
-@@ -0,0 +1,63 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , cursor = Base.cursor
-+  , color = Base.color;
-+
-+/**
-+ * Expose `List`.
-+ */
-+
-+exports = module.exports = List;
-+
-+/**
-+ * Initialize a new `List` test reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function List(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , n = 0;
-+
-+  runner.on('start', function(){
-+    console.log();
-+  });
-+
-+  runner.on('test', function(test){
-+    process.stdout.write(color('pass', '    ' + test.fullTitle() + ': '));
-+  });
-+
-+  runner.on('pending', function(test){
-+    var fmt = color('checkmark', '  -')
-+      + color('pending', ' %s');
-+    console.log(fmt, test.fullTitle());
-+  });
-+
-+  runner.on('pass', function(test){
-+    var fmt = color('checkmark', '  '+Base.symbols.dot)
-+      + color('pass', ' %s: ')
-+      + color(test.speed, '%dms');
-+    cursor.CR();
-+    console.log(fmt, test.fullTitle(), test.duration);
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    cursor.CR();
-+    console.log(color('fail', '  %d) %s'), ++n, test.fullTitle());
-+  });
-+
-+  runner.on('end', self.epilogue.bind(self));
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+List.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/markdown.js
-@@ -0,0 +1,126 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , utils = require('../utils');
-+
-+/**
-+ * Constants
-+ */
-+
-+var SUITE_PREFIX = '$';
-+
-+/**
-+ * Expose `Markdown`.
-+ */
-+
-+exports = module.exports = Markdown;
-+
-+/**
-+ * Initialize a new `Markdown` reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function Markdown(runner) {
-+  Base.call(this, runner);
-+
-+  var self = this
-+    , stats = this.stats
-+    , level = 0
-+    , buf = '';
-+
-+  function title(str) {
-+    return Array(level + 1).join('#') + ' ' + str;
-+  }
-+
-+  function indent() {
-+    return Array(level).join('  ');
-+  }
-+
-+  function mapTOC(suite, obj) {
-+    var ret = obj,
-+        key = SUITE_PREFIX + suite.title;
-+    obj = obj[key] = obj[key] || { suite: suite };
-+    suite.suites.forEach(function(suite){
-+      mapTOC(suite, obj);
-+    });
-+    return ret;
-+  }
-+
-+  function stringifyTOC(obj, level) {
-+    ++level;
-+    var buf = '';
-+    var link;
-+    for (var key in obj) {
-+      if ('suite' == key) continue;
-+      if (key !== SUITE_PREFIX) {
-+        link = ' - [' + key.substring(1) + ']';
-+        link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
-+        buf += Array(level).join('  ') + link;
-+      }
-+      buf += stringifyTOC(obj[key], level);
-+    }
-+    return buf;
-+  }
-+
-+  function generateTOC() {
-+    return suites.map(generateTOC_).join('')
-+  }
-+
-+  function generateTOC_(suite) {
-+    var obj = mapTOC(suite, {});
-+    return stringifyTOC(obj, 0);
-+  }
-+
-+  var suites = []
-+  var currentSuite = null
-+  runner.on('suite', function(suite){
-+    currentSuite = suite
-+    if (suite.root) {
-+      suites.push(suite)
-+    }
-+    ++level;
-+    var slug = utils.slug(suite.fullTitle());
-+    buf += '<a name="' + slug + '"></a>' + '\n';
-+    buf += title(suite.title) + '\n';
-+  });
-+
-+  runner.on('suite end', function(suite){
-+    if (suite.ok) {
-+      buf += '\nok - ' + suite.title + '\n'
-+    } else {
-+      buf += '\nnot ok - ' + suite.title + '\n'
-+    }
-+    --level;
-+  });
-+
-+  runner.on('test', function(test){
-+    if (!test.ok || test.pending) {
-+      var code = utils.clean(test.fn.toString());
-+      buf += test.title + '.\n';
-+      if (code) {
-+        buf += '\n```js\n';
-+        buf += code + '\n';
-+        buf += '```\n';
-+      }
-+      var stack = test.err && test.err.stack
-+      if (!stack) {
-+        stack = test.result && test.result.diag && test.result.diag.stack
-+      }
-+      if (stack) {
-+        buf += '\n```\n' + stack + '\n```\n';
-+      }
-+      buf += '\n\n';
-+    }
-+  });
-+
-+  runner.on('end', function(){
-+    process.stdout.write('# TOC\n');
-+    process.stdout.write(generateTOC());
-+    process.stdout.write('\n\n');
-+    process.stdout.write(buf);
-+  });
-+}
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/nyan.js
-@@ -0,0 +1,260 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base');
-+
-+/**
-+ * Expose `Dot`.
-+ */
-+
-+exports = module.exports = NyanCat;
-+
-+/**
-+ * Initialize a new `Dot` matrix test reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function NyanCat(runner) {
-+  Base.call(this, runner);
-+  var self = this
-+    , stats = this.stats
-+    , width = Base.window.width * .75 | 0
-+    , rainbowColors = this.rainbowColors = self.generateColors()
-+    , colorIndex = this.colorIndex = 0
-+    , numerOfLines = this.numberOfLines = 4
-+    , trajectories = this.trajectories = [[], [], [], []]
-+    , nyanCatWidth = this.nyanCatWidth = 11
-+    , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
-+    , scoreboardWidth = this.scoreboardWidth = 5
-+    , tick = this.tick = 0
-+    , n = 0;
-+
-+  runner.on('start', function(){
-+    Base.cursor.hide();
-+    self.draw();
-+  });
-+
-+  runner.on('pending', function(test){
-+    self.draw();
-+  });
-+
-+  runner.on('pass', function(test){
-+    self.draw();
-+  });
-+
-+  runner.on('fail', function(test, err){
-+    self.draw();
-+  });
-+
-+  runner.on('end', function(){
-+    Base.cursor.show();
-+    for (var i = 0; i < self.numberOfLines; i++) write('\n');
-+    self.epilogue();
-+  });
-+}
-+
-+/**
-+ * Draw the nyan cat
-+ *
-+ * @api private
-+ */
-+
-+NyanCat.prototype.draw = function(){
-+  this.appendRainbow();
-+  this.drawScoreboard();
-+  this.drawRainbow();
-+  this.drawNyanCat();
-+  this.tick = !this.tick;
-+};
-+
-+/**
-+ * Draw the "scoreboard" showing the number
-+ * of passes, failures and pending tests.
-+ *
-+ * @api private
-+ */
-+
-+NyanCat.prototype.drawScoreboard = function(){
-+  var stats = this.stats;
-+
-+  function draw(type, n) {
-+    write(' ');
-+    write(Base.color(type, n));
-+    write('\n');
-+  }
-+
-+  draw('green', stats.passes);
-+  draw('fail', stats.failures);
-+  draw('pending', stats.pending);
-+  write('\n');
-+
-+  this.cursorUp(this.numberOfLines);
-+};
-+
-+/**
-+ * Append the rainbow.
-+ *
-+ * @api private
-+ */
-+
-+NyanCat.prototype.appendRainbow = function(){
-+  var segment = this.tick ? '_' : '-';
-+  var rainbowified = this.rainbowify(segment);
-+
-+  for (var index = 0; index < this.numberOfLines; index++) {
-+    var trajectory = this.trajectories[index];
-+    if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
-+    trajectory.push(rainbowified);
-+  }
-+};
-+
-+/**
-+ * Draw the rainbow.
-+ *
-+ * @api private
-+ */
-+
-+NyanCat.prototype.drawRainbow = function(){
-+  var self = this;
-+
-+  this.trajectories.forEach(function(line, index) {
-+    write('\u001b[' + self.scoreboardWidth + 'C');
-+    write(line.join(''));
-+    write('\n');
-+  });
-+
-+  this.cursorUp(this.numberOfLines);
-+};
-+
-+/**
-+ * Draw the nyan cat
-+ *
-+ * @api private
-+ */
-+
-+NyanCat.prototype.drawNyanCat = function() {
-+  var self = this;
-+  var startWidth = this.scoreboardWidth + this.trajectories[0].length;
-+  var dist = '\u001b[' + startWidth + 'C';
-+  var padding = '';
-+
-+  write(dist);
-+  write('_,------,');
-+  write('\n');
-+
-+  write(dist);
-+  padding = self.tick ? '  ' : '   ';
-+  write('_|' + padding + '/\\_/\\ ');
-+  write('\n');
-+
-+  write(dist);
-+  padding = self.tick ? '_' : '__';
-+  var tail = self.tick ? '~' : '^';
-+  var face;
-+  write(tail + '|' + padding + this.face() + ' ');
-+  write('\n');
-+
-+  write(dist);
-+  padding = self.tick ? ' ' : '  ';
-+  write(padding + '""  "" ');
-+  write('\n');
-+
-+  this.cursorUp(this.numberOfLines);
-+};
-+
-+/**
-+ * Draw nyan cat face.
-+ *
-+ * @return {String}
-+ * @api private
-+ */
-+
-+NyanCat.prototype.face = function() {
-+  var stats = this.stats;
-+  if (stats.failures) {
-+    return '( x .x)';
-+  } else if (stats.pending) {
-+    return '( o .o)';
-+  } else if(stats.passes) {
-+    return '( ^ .^)';
-+  } else {
-+    return '( - .-)';
-+  }
-+};
-+
-+/**
-+ * Move cursor up `n`.
-+ *
-+ * @param {Number} n
-+ * @api private
-+ */
-+
-+NyanCat.prototype.cursorUp = function(n) {
-+  write('\u001b[' + n + 'A');
-+};
-+
-+/**
-+ * Move cursor down `n`.
-+ *
-+ * @param {Number} n
-+ * @api private
-+ */
-+
-+NyanCat.prototype.cursorDown = function(n) {
-+  write('\u001b[' + n + 'B');
-+};
-+
-+/**
-+ * Generate rainbow colors.
-+ *
-+ * @return {Array}
-+ * @api private
-+ */
-+
-+NyanCat.prototype.generateColors = function(){
-+  var colors = [];
-+
-+  for (var i = 0; i < (6 * 7); i++) {
-+    var pi3 = Math.floor(Math.PI / 3);
-+    var n = (i * (1.0 / 6));
-+    var r = Math.floor(3 * Math.sin(n) + 3);
-+    var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
-+    var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
-+    colors.push(36 * r + 6 * g + b + 16);
-+  }
-+
-+  return colors;
-+};
-+
-+/**
-+ * Apply rainbow to the given `str`.
-+ *
-+ * @param {String} str
-+ * @return {String}
-+ * @api private
-+ */
-+
-+NyanCat.prototype.rainbowify = function(str){
-+  if (!Base.useColors)
-+    return str;
-+  var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
-+  this.colorIndex += 1;
-+  return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
-+};
-+
-+/**
-+ * Stdout helper.
-+ */
-+
-+function write(string) {
-+  process.stdout.write(string);
-+}
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+NyanCat.prototype.__proto__ = Base.prototype;
---- /dev/null
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/xunit.js
-@@ -0,0 +1,149 @@
-+/**
-+ * Module dependencies.
-+ */
-+
-+var Base = require('./base')
-+  , utils = require('../utils')
-+  , fs = require('fs')
-+  , escape = utils.escape;
-+
-+/**
-+ * Save timer references to avoid Sinon interfering (see GH-237).
-+ */
-+
-+var Date = global.Date
-+  , setTimeout = global.setTimeout
-+  , setInterval = global.setInterval
-+  , clearTimeout = global.clearTimeout
-+  , clearInterval = global.clearInterval;
-+
-+/**
-+ * Expose `XUnit`.
-+ */
-+
-+exports = module.exports = XUnit;
-+
-+/**
-+ * Initialize a new `XUnit` reporter.
-+ *
-+ * @param {Runner} runner
-+ * @api public
-+ */
-+
-+function XUnit(runner, options) {
-+  Base.call(this, runner);
-+  var stats = this.stats
-+    , tests = []
-+    , self = this;
-+
-+  if (options.reporterOptions && options.reporterOptions.output) {
-+      if (! fs.createWriteStream) {
-+          throw new Error('file output not supported in browser');
-+      }
-+      self.fileStream = fs.createWriteStream(options.reporterOptions.output);
-+  }
-+
-+  runner.on('pending', function(test){
-+    tests.push(test);
-+  });
-+
-+  runner.on('pass', function(test){
-+    tests.push(test);
-+  });
-+
-+  runner.on('fail', function(test){
-+    tests.push(test);
-+  });
-+
-+  runner.on('end', function(){
-+    self.write(tag('testsuite', {
-+        name: 'TAP Tests'
-+      , tests: stats.tests
-+      , failures: stats.failures
-+      , errors: stats.failures
-+      , skipped: stats.tests - stats.failures - stats.passes
-+      , timestamp: (new Date).toUTCString()
-+      , time: (stats.duration / 1000) || 0
-+    }, false));
-+
-+    tests.forEach(function(t) { self.test(t); });
-+    self.write('</testsuite>');
-+  });
-+}
-+
-+/**
-+ * Override done to close the stream (if it's a file).
-+ */
-+XUnit.prototype.done = function(failures, fn) {
-+    if (this.fileStream) {
-+        this.fileStream.end(function() {
-+            fn(failures);
-+        });
-+    } else {
-+        fn(failures);
-+    }
-+};
-+
-+/**
-+ * Inherit from `Base.prototype`.
-+ */
-+
-+XUnit.prototype.__proto__ = Base.prototype;
-+
-+/**
-+ * Write out the given line
-+ */
-+XUnit.prototype.write = function(line) {
-+    if (this.fileStream) {
-+        this.fileStream.write(line + '\n');
-+    } else {
-+        console.log(line);
-+    }
-+};
-+
-+/**
-+ * Output tag for the given `test.`
-+ */
-+
-+XUnit.prototype.test = function(test, ostream) {
-+  var attrs = {
-+      classname: test.parent.fullTitle()
-+    , name: test.title
-+    , time: (test.duration / 1000) || 0
-+  };
-+
-+  if ('failed' == test.state) {
-+    var err = test.err;
-+    this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + "\n" + err.stack))));
-+  } else if (test.pending) {
-+    this.write(tag('testcase', attrs, false, tag('skipped', {}, true)));
-+  } else {
-+    this.write(tag('testcase', attrs, true) );
-+  }
-+};
-+
-+/**
-+ * HTML tag helper.
-+ */
-+
-+function tag(name, attrs, close, content) {
-+  var end = close ? '/>' : '>'
-+    , pairs = []
-+    , tag;
-+
-+  for (var key in attrs) {
-+    pairs.push(key + '="' + escape(attrs[key]) + '"');
-+  }
-+
-+  tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
-+  if (content) tag += content + '</' + name + end;
-+  return tag;
-+}
-+
-+/**
-+ * Return cdata escaped CDATA `str`.
-+ */
-+
-+function cdata(str) {
-+  return '<![CDATA[' + escape(str) + ']]>';
-+}
diff --git a/debian/patches/script-not-executable.patch b/debian/patches/script-not-executable.patch
deleted file mode 100644
index 28fb44b..0000000
--- a/debian/patches/script-not-executable.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Description: remove shebang from not installed script
-Last-Update: 2016-11-13
-Forwarded: not-needed
-Author: Jérémy Lal <kapouer at melix.org>
---- a/node_modules/tap-mocha-reporter/index.js
-+++ b/node_modules/tap-mocha-reporter/index.js
-@@ -1,5 +1,3 @@
--#!/usr/bin/env node
--
- module.exports = Formatter
- 
- var util = require('util')
diff --git a/debian/patches/series b/debian/patches/series
index 861c4c0..f9b3945 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,6 +1,4 @@
-module-tap-mocha-reporter.patch
 module-stack-utils.patch
 nodejs_rename.patch
 use_available_modules.patch
-script-not-executable.patch
 tests.patch
diff --git a/debian/patches/use_available_modules.patch b/debian/patches/use_available_modules.patch
index 0dd65d1..e306352 100644
--- a/debian/patches/use_available_modules.patch
+++ b/debian/patches/use_available_modules.patch
@@ -151,17 +151,6 @@ Last-Update: 2014-10-20
  }
  
  function nycVersion () {
---- a/node_modules/tap-mocha-reporter/lib/reporters/base.js
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/base.js
-@@ -6,7 +6,7 @@
-   , diff = require('diff')
-   , ms = require('../ms')
-   , utils = require('../utils')
--  , supportsColor = require('color-support')()
-+  , supportsColor = require('supports-color')
- 
- /**
-  * Save timer references to avoid Sinon interfering (see GH-237).
 --- a/lib/test.js
 +++ b/lib/test.js
 @@ -6,8 +6,6 @@
@@ -173,20 +162,6 @@ Last-Update: 2014-10-20
  function Deferred () {
    this.resolve = null
    this.reject = null
---- a/node_modules/tap-mocha-reporter/lib/reporters/classic.js
-+++ b/node_modules/tap-mocha-reporter/lib/reporters/classic.js
-@@ -9,8 +9,9 @@
-   , ms = require('../ms.js')
-   , diff = require('diff')
-   , utils = require('../utils.js')
--  , uclen = require('unicode-length').get
--  , colorSupport = require('color-support')()
-+  , stripAnsi = require('strip-ansi')
-+  , uclen = function(str) { return stripAnsi(str).length }
-+  , colorSupport = require('supports-color')
- 
- function hasOwnProperty (obj, key) {
-   return Object.prototype.hasOwnProperty.call(obj, key)
 --- a/test/rcfiles.js
 +++ b/test/rcfiles.js
 @@ -7,7 +7,7 @@

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-tap.git



More information about the Pkg-javascript-commits mailing list