;_mocha_version = “2.1.0”; ;(function(){

// CommonJS require()

function require(p){

  var path = require.resolve(p)
    , mod = require.modules[path];
  if (!mod) throw new Error('failed to require "' + p + '"');
  if (!mod.exports) {
    mod.exports = {};
    mod.call(mod.exports, mod, mod.exports, require.relative(path));
  }
  return mod.exports;
}

require.modules = {};

require.resolve = function (path){

  var orig = path
    , reg = path + '.js'
    , index = path + '/index.js';
  return require.modules[reg] && reg
    || require.modules[index] && index
    || orig;
};

require.register = function (path, fn){

  require.modules[path] = fn;
};

require.relative = function (parent) {

  return function(p){
    if ('.' != p.charAt(0)) return require(p);

    var path = parent.split('/')
      , segs = p.split('/');
    path.pop();

    for (var i = 0; i < segs.length; i++) {
      var seg = segs[i];
      if ('..' == seg) path.pop();
      else if ('.' != seg) path.push(seg);
    }

    return require(path.join('/'));
  };
};

require.register(“browser/debug.js”, function(module, exports, require){ module.exports = function(type){

return function(){
}

};

}); // module: browser/debug.js

require.register(“browser/diff.js”, function(module, exports, require){ /* See LICENSE file for terms of use */

/*

* Text diff implementation.
*
* This library supports the following APIS:
* JsDiff.diffChars: Character by character diff
* JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
* JsDiff.diffLines: Line based diff
*
* JsDiff.diffCss: Diff targeted at CSS content
*
* These methods are based on the implementation proposed in
* "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
*/

var JsDiff = (function() {

/*jshint maxparams: 5*/
function clonePath(path) {
  return { newPos: path.newPos, components: path.components.slice(0) };
}
function removeEmpty(array) {
  var ret = [];
  for (var i = 0; i < array.length; i++) {
    if (array[i]) {
      ret.push(array[i]);
    }
  }
  return ret;
}
function escapeHTML(s) {
  var n = s;
  n = n.replace(/&/g, '&amp;');
  n = n.replace(/</g, '&lt;');
  n = n.replace(/>/g, '&gt;');
  n = n.replace(/"/g, '&quot;');

  return n;
}

var Diff = function(ignoreWhitespace) {
  this.ignoreWhitespace = ignoreWhitespace;
};
Diff.prototype = {
    diff: function(oldString, newString) {
      // Handle the identity case (this is due to unrolling editLength == 0
      if (newString === oldString) {
        return [{ value: newString }];
      }
      if (!newString) {
        return [{ value: oldString, removed: true }];
      }
      if (!oldString) {
        return [{ value: newString, added: true }];
      }

      newString = this.tokenize(newString);
      oldString = this.tokenize(oldString);

      var newLen = newString.length, oldLen = oldString.length;
      var maxEditLength = newLen + oldLen;
      var bestPath = [{ newPos: -1, components: [] }];

      // Seed editLength = 0
      var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
      if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
        return bestPath[0].components;
      }

      for (var editLength = 1; editLength <= maxEditLength; editLength++) {
        for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
          var basePath;
          var addPath = bestPath[diagonalPath-1],
              removePath = bestPath[diagonalPath+1];
          oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
          if (addPath) {
            // No one else is going to attempt to use this value, clear it
            bestPath[diagonalPath-1] = undefined;
          }

          var canAdd = addPath && addPath.newPos+1 < newLen;
          var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
          if (!canAdd && !canRemove) {
            bestPath[diagonalPath] = undefined;
            continue;
          }

          // Select the diagonal that we want to branch from. We select the prior
          // path whose position in the new string is the farthest from the origin
          // and does not pass the bounds of the diff graph
          if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
            basePath = clonePath(removePath);
            this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
          } else {
            basePath = clonePath(addPath);
            basePath.newPos++;
            this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
          }

          var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);

          if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
            return basePath.components;
          } else {
            bestPath[diagonalPath] = basePath;
          }
        }
      }
    },

    pushComponent: function(components, value, added, removed) {
      var last = components[components.length-1];
      if (last && last.added === added && last.removed === removed) {
        // We need to clone here as the component clone operation is just
        // as shallow array clone
        components[components.length-1] =
          {value: this.join(last.value, value), added: added, removed: removed };
      } else {
        components.push({value: value, added: added, removed: removed });
      }
    },
    extractCommon: function(basePath, newString, oldString, diagonalPath) {
      var newLen = newString.length,
          oldLen = oldString.length,
          newPos = basePath.newPos,
          oldPos = newPos - diagonalPath;
      while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
        newPos++;
        oldPos++;

        this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
      }
      basePath.newPos = newPos;
      return oldPos;
    },

    equals: function(left, right) {
      var reWhitespace = /\S/;
      if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
        return true;
      } else {
        return left === right;
      }
    },
    join: function(left, right) {
      return left + right;
    },
    tokenize: function(value) {
      return value;
    }
};

var CharDiff = new Diff();

var WordDiff = new Diff(true);
var WordWithSpaceDiff = new Diff();
WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
  return removeEmpty(value.split(/(\s+|\b)/));
};

var CssDiff = new Diff(true);
CssDiff.tokenize = function(value) {
  return removeEmpty(value.split(/([{}:;,]|\s+)/));
};

var LineDiff = new Diff();
LineDiff.tokenize = function(value) {
  var retLines = [],
      lines = value.split(/^/m);

  for(var i = 0; i < lines.length; i++) {
    var line = lines[i],
        lastLine = lines[i - 1];

    // Merge lines that may contain windows new lines
    if (line == '\n' && lastLine && lastLine[lastLine.length - 1] === '\r') {
      retLines[retLines.length - 1] += '\n';
    } else if (line) {
      retLines.push(line);
    }
  }

  return retLines;
};

return {
  Diff: Diff,

  diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
  diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
  diffWordsWithSpace: function(oldStr, newStr) { return WordWithSpaceDiff.diff(oldStr, newStr); },
  diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },

  diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },

  createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
    var ret = [];

    ret.push('Index: ' + fileName);
    ret.push('===================================================================');
    ret.push('--- ' + fileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader));
    ret.push('+++ ' + fileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader));

    var diff = LineDiff.diff(oldStr, newStr);
    if (!diff[diff.length-1].value) {
      diff.pop();   // Remove trailing newline add
    }
    diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier

    function contextLines(lines) {
      return lines.map(function(entry) { return ' ' + entry; });
    }
    function eofNL(curRange, i, current) {
      var last = diff[diff.length-2],
          isLast = i === diff.length-2,
          isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);

      // Figure out if this is the last line for the given file and missing NL
      if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
        curRange.push('\\ No newline at end of file');
      }
    }

    var oldRangeStart = 0, newRangeStart = 0, curRange = [],
        oldLine = 1, newLine = 1;
    for (var i = 0; i < diff.length; i++) {
      var current = diff[i],
          lines = current.lines || current.value.replace(/\n$/, '').split('\n');
      current.lines = lines;

      if (current.added || current.removed) {
        if (!oldRangeStart) {
          var prev = diff[i-1];
          oldRangeStart = oldLine;
          newRangeStart = newLine;

          if (prev) {
            curRange = contextLines(prev.lines.slice(-4));
            oldRangeStart -= curRange.length;
            newRangeStart -= curRange.length;
          }
        }
        curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?'+':'-') + entry; }));
        eofNL(curRange, i, current);

        if (current.added) {
          newLine += lines.length;
        } else {
          oldLine += lines.length;
        }
      } else {
        if (oldRangeStart) {
          // Close out any changes that have been output (or join overlapping)
          if (lines.length <= 8 && i < diff.length-2) {
            // Overlapping
            curRange.push.apply(curRange, contextLines(lines));
          } else {
            // end the range and output
            var contextSize = Math.min(lines.length, 4);
            ret.push(
                '@@ -' + oldRangeStart + ',' + (oldLine-oldRangeStart+contextSize)
                + ' +' + newRangeStart + ',' + (newLine-newRangeStart+contextSize)
                + ' @@');
            ret.push.apply(ret, curRange);
            ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
            if (lines.length <= 4) {
              eofNL(ret, i, current);
            }

            oldRangeStart = 0;  newRangeStart = 0; curRange = [];
          }
        }
        oldLine += lines.length;
        newLine += lines.length;
      }
    }

    return ret.join('\n') + '\n';
  },

  applyPatch: function(oldStr, uniDiff) {
    var diffstr = uniDiff.split('\n');
    var diff = [];
    var remEOFNL = false,
        addEOFNL = false;

    for (var i = (diffstr[0][0]==='I'?4:0); i < diffstr.length; i++) {
      if(diffstr[i][0] === '@') {
        var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
        diff.unshift({
          start:meh[3],
          oldlength:meh[2],
          oldlines:[],
          newlength:meh[4],
          newlines:[]
        });
      } else if(diffstr[i][0] === '+') {
        diff[0].newlines.push(diffstr[i].substr(1));
      } else if(diffstr[i][0] === '-') {
        diff[0].oldlines.push(diffstr[i].substr(1));
      } else if(diffstr[i][0] === ' ') {
        diff[0].newlines.push(diffstr[i].substr(1));
        diff[0].oldlines.push(diffstr[i].substr(1));
      } else if(diffstr[i][0] === '\\') {
        if (diffstr[i-1][0] === '+') {
          remEOFNL = true;
        } else if(diffstr[i-1][0] === '-') {
          addEOFNL = true;
        }
      }
    }

    var str = oldStr.split('\n');
    for (var i = diff.length - 1; i >= 0; i--) {
      var d = diff[i];
      for (var j = 0; j < d.oldlength; j++) {
        if(str[d.start-1+j] !== d.oldlines[j]) {
          return false;
        }
      }
      Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
    }

    if (remEOFNL) {
      while (!str[str.length-1]) {
        str.pop();
      }
    } else if (addEOFNL) {
      str.push('');
    }
    return str.join('\n');
  },

  convertChangesToXML: function(changes){
    var ret = [];
    for ( var i = 0; i < changes.length; i++) {
      var change = changes[i];
      if (change.added) {
        ret.push('<ins>');
      } else if (change.removed) {
        ret.push('<del>');
      }

      ret.push(escapeHTML(change.value));

      if (change.added) {
        ret.push('</ins>');
      } else if (change.removed) {
        ret.push('</del>');
      }
    }
    return ret.join('');
  },

  // See: http://code.google.com/p/google-diff-match-patch/wiki/API
  convertChangesToDMP: function(changes){
    var ret = [], change;
    for ( var i = 0; i < changes.length; i++) {
      change = changes[i];
      ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
    }
    return ret;
  }
};

})();

if (typeof module !== 'undefined') {

module.exports = JsDiff;

}

}); // module: browser/diff.js

require.register(“browser/escape-string-regexp.js”, function(module, exports, require){ 'use strict';

var matchOperatorsRe = /[|\{}()[]^$+*?.]/g;

module.exports = function (str) {

if (typeof str !== 'string') {
  throw new TypeError('Expected a string');
}

return str.replace(matchOperatorsRe,  '\\$&');

};

}); // module: browser/escape-string-regexp.js

require.register(“browser/events.js”, function(module, exports, require){ /**

* Module exports.
*/

exports.EventEmitter = EventEmitter;

/**

* Check if `obj` is an array.
*/

function isArray(obj) {

return '[object Array]' == {}.toString.call(obj);

}

/**

* Event emitter constructor.
*
* @api public
*/

function EventEmitter(){};

/**

* Adds a listener.
*
* @api public
*/

EventEmitter.prototype.on = function (name, fn) {

if (!this.$events) {
  this.$events = {};
}

if (!this.$events[name]) {
  this.$events[name] = fn;
} else if (isArray(this.$events[name])) {
  this.$events[name].push(fn);
} else {
  this.$events[name] = [this.$events[name], fn];
}

return this;

};

EventEmitter.prototype.addListener = EventEmitter.prototype.on;

/**

* Adds a volatile listener.
*
* @api public
*/

EventEmitter.prototype.once = function (name, fn) {

var self = this;

function on () {
  self.removeListener(name, on);
  fn.apply(this, arguments);
};

on.listener = fn;
this.on(name, on);

return this;

};

/**

* Removes a listener.
*
* @api public
*/

EventEmitter.prototype.removeListener = function (name, fn) {

if (this.$events && this.$events[name]) {
  var list = this.$events[name];

  if (isArray(list)) {
    var pos = -1;

    for (var i = 0, l = list.length; i < l; i++) {
      if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
        pos = i;
        break;
      }
    }

    if (pos < 0) {
      return this;
    }

    list.splice(pos, 1);

    if (!list.length) {
      delete this.$events[name];
    }
  } else if (list === fn || (list.listener && list.listener === fn)) {
    delete this.$events[name];
  }
}

return this;

};

/**

* Removes all listeners for an event.
*
* @api public
*/

EventEmitter.prototype.removeAllListeners = function (name) {

if (name === undefined) {
  this.$events = {};
  return this;
}

if (this.$events && this.$events[name]) {
  this.$events[name] = null;
}

return this;

};

/**

* Gets all listeners for a certain event.
*
* @api public
*/

EventEmitter.prototype.listeners = function (name) {

if (!this.$events) {
  this.$events = {};
}

if (!this.$events[name]) {
  this.$events[name] = [];
}

if (!isArray(this.$events[name])) {
  this.$events[name] = [this.$events[name]];
}

return this.$events[name];

};

/**

* Emits an event.
*
* @api public
*/

EventEmitter.prototype.emit = function (name) {

if (!this.$events) {
  return false;
}

var handler = this.$events[name];

if (!handler) {
  return false;
}

var args = [].slice.call(arguments, 1);

if ('function' == typeof handler) {
  handler.apply(this, args);
} else if (isArray(handler)) {
  var listeners = handler.slice();

  for (var i = 0, l = listeners.length; i < l; i++) {
    listeners[i].apply(this, args);
  }
} else {
  return false;
}

return true;

};

}); // module: browser/events.js

require.register(“browser/fs.js”, function(module, exports, require){

}); // module: browser/fs.js

require.register(“browser/glob.js”, function(module, exports, require){

}); // module: browser/glob.js

require.register(“browser/path.js”, function(module, exports, require){

}); // module: browser/path.js

require.register(“browser/progress.js”, function(module, exports, require){ /**

* Expose `Progress`.
*/

module.exports = Progress;

/**

* Initialize a new `Progress` indicator.
*/

function Progress() {

this.percent = 0;
this.size(0);
this.fontSize(11);
this.font('helvetica, arial, sans-serif');

}

/**

* Set progress size to `n`.
*
* @param {Number} n
* @return {Progress} for chaining
* @api public
*/

Progress.prototype.size = function(n){

this._size = n;
return this;

};

/**

* Set text to `str`.
*
* @param {String} str
* @return {Progress} for chaining
* @api public
*/

Progress.prototype.text = function(str){

this._text = str;
return this;

};

/**

* Set font size to `n`.
*
* @param {Number} n
* @return {Progress} for chaining
* @api public
*/

Progress.prototype.fontSize = function(n){

this._fontSize = n;
return this;

};

/**

* Set font `family`.
*
* @param {String} family
* @return {Progress} for chaining
*/

Progress.prototype.font = function(family){

this._font = family;
return this;

};

/**

* Update percentage to `n`.
*
* @param {Number} n
* @return {Progress} for chaining
*/

Progress.prototype.update = function(n){

this.percent = n;
return this;

};

/**

* Draw on `ctx`.
*
* @param {CanvasRenderingContext2d} ctx
* @return {Progress} for chaining
*/

Progress.prototype.draw = function(ctx){

try {
  var percent = Math.min(this.percent, 100)
    , size = this._size
    , half = size / 2
    , x = half
    , y = half
    , rad = half - 1
    , fontSize = this._fontSize;

  ctx.font = fontSize + 'px ' + this._font;

  var angle = Math.PI * 2 * (percent / 100);
  ctx.clearRect(0, 0, size, size);

  // outer circle
  ctx.strokeStyle = '#9f9f9f';
  ctx.beginPath();
  ctx.arc(x, y, rad, 0, angle, false);
  ctx.stroke();

  // inner circle
  ctx.strokeStyle = '#eee';
  ctx.beginPath();
  ctx.arc(x, y, rad - 1, 0, angle, true);
  ctx.stroke();

  // text
  var text = this._text || (percent | 0) + '%'
    , w = ctx.measureText(text).width;

  ctx.fillText(
      text
    , x - w / 2 + 1
    , y + fontSize / 2 - 1);
} catch (ex) {} //don't fail if we can't render progress
return this;

};

}); // module: browser/progress.js

require.register(“browser/tty.js”, function(module, exports, require){ exports.isatty = function(){

return true;

};

exports.getWindowSize = function(){

if ('innerHeight' in global) {
  return [global.innerHeight, global.innerWidth];
} else {
  // In a Web Worker, the DOM Window is not available.
  return [640, 480];
}

};

}); // module: browser/tty.js

require.register(“context.js”, function(module, exports, require){ /**

* Expose `Context`.
*/

module.exports = Context;

/**

* Initialize a new `Context`.
*
* @api private
*/

function Context(){}

/**

* Set or get the context `Runnable` to `runnable`.
*
* @param {Runnable} runnable
* @return {Context}
* @api private
*/

Context.prototype.runnable = function(runnable){

if (0 == arguments.length) return this._runnable;
this.test = this._runnable = runnable;
return this;

};

/**

* Set test timeout `ms`.
*
* @param {Number} ms
* @return {Context} self
* @api private
*/

Context.prototype.timeout = function(ms){

if (arguments.length === 0) return this.runnable().timeout();
this.runnable().timeout(ms);
return this;

};

/**

* Set test timeout `enabled`.
*
* @param {Boolean} enabled
* @return {Context} self
* @api private
*/

Context.prototype.enableTimeouts = function (enabled) {

this.runnable().enableTimeouts(enabled);
return this;

};

/**

* Set test slowness threshold `ms`.
*
* @param {Number} ms
* @return {Context} self
* @api private
*/

Context.prototype.slow = function(ms){

this.runnable().slow(ms);
return this;

};

/**

* Inspect the context void of `._runnable`.
*
* @return {String}
* @api private
*/

Context.prototype.inspect = function(){

return JSON.stringify(this, function(key, val){
  if ('_runnable' == key) return;
  if ('test' == key) return;
  return val;
}, 2);

};

}); // module: context.js

require.register(“hook.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Runnable = require('./runnable');

/**

* Expose `Hook`.
*/

module.exports = Hook;

/**

* Initialize a new `Hook` with the given `title` and callback `fn`.
*
* @param {String} title
* @param {Function} fn
* @api private
*/

function Hook(title, fn) {

Runnable.call(this, title, fn);
this.type = 'hook';

}

/**

* Inherit from `Runnable.prototype`.
*/

function F(){}; F.prototype = Runnable.prototype; Hook.prototype = new F; Hook.prototype.constructor = Hook;

/**

* Get or set the test `err`.
*
* @param {Error} err
* @return {Error}
* @api public
*/

Hook.prototype.error = function(err){

if (0 == arguments.length) {
  var err = this._error;
  this._error = null;
  return err;
}

this._error = err;

};

}); // module: hook.js

require.register(“interfaces/bdd.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Suite = require('../suite')

, Test = require('../test')
, utils = require('../utils')
, escapeRe = require('browser/escape-string-regexp');

/**

* BDD-style interface:
*
*      describe('Array', function(){
*        describe('#indexOf()', function(){
*          it('should return -1 when not present', function(){
*
*          });
*
*          it('should return the index when present', function(){
*
*          });
*        });
*      });
*
*/

module.exports = function(suite){

var suites = [suite];

suite.on('pre-require', function(context, file, mocha){

  /**
   * Execute before running tests.
   */

  context.before = function(name, fn){
    suites[0].beforeAll(name, fn);
  };

  /**
   * Execute after running tests.
   */

  context.after = function(name, fn){
    suites[0].afterAll(name, fn);
  };

  /**
   * Execute before each test case.
   */

  context.beforeEach = function(name, fn){
    suites[0].beforeEach(name, fn);
  };

  /**
   * Execute after each test case.
   */

  context.afterEach = function(name, fn){
    suites[0].afterEach(name, fn);
  };

  /**
   * Describe a "suite" with the given `title`
   * and callback `fn` containing nested suites
   * and/or tests.
   */

  context.describe = context.context = function(title, fn){
    var suite = Suite.create(suites[0], title);
    suite.file = file;
    suites.unshift(suite);
    fn.call(suite);
    suites.shift();
    return suite;
  };

  /**
   * Pending describe.
   */

  context.xdescribe =
  context.xcontext =
  context.describe.skip = function(title, fn){
    var suite = Suite.create(suites[0], title);
    suite.pending = true;
    suites.unshift(suite);
    fn.call(suite);
    suites.shift();
  };

  /**
   * Exclusive suite.
   */

  context.describe.only = function(title, fn){
    var suite = context.describe(title, fn);
    mocha.grep(suite.fullTitle());
    return suite;
  };

  /**
   * Describe a specification or test-case
   * with the given `title` and callback `fn`
   * acting as a thunk.
   */

  context.it = context.specify = function(title, fn){
    var suite = suites[0];
    if (suite.pending) fn = null;
    var test = new Test(title, fn);
    test.file = file;
    suite.addTest(test);
    return test;
  };

  /**
   * Exclusive test-case.
   */

  context.it.only = function(title, fn){
    var test = context.it(title, fn);
    var reString = '^' + escapeRe(test.fullTitle()) + '$';
    mocha.grep(new RegExp(reString));
    return test;
  };

  /**
   * Pending test case.
   */

  context.xit =
  context.xspecify =
  context.it.skip = function(title){
    context.it(title);
  };
});

};

}); // module: interfaces/bdd.js

require.register(“interfaces/exports.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Suite = require('../suite')

, Test = require('../test');

/**

* TDD-style interface:
*
*     exports.Array = {
*       '#indexOf()': {
*         'should return -1 when the value is not present': function(){
*
*         },
*
*         'should return the correct index when the value is present': function(){
*
*         }
*       }
*     };
*
*/

module.exports = function(suite){

var suites = [suite];

suite.on('require', visit);

function visit(obj, file) {
  var suite;
  for (var key in obj) {
    if ('function' == typeof obj[key]) {
      var fn = obj[key];
      switch (key) {
        case 'before':
          suites[0].beforeAll(fn);
          break;
        case 'after':
          suites[0].afterAll(fn);
          break;
        case 'beforeEach':
          suites[0].beforeEach(fn);
          break;
        case 'afterEach':
          suites[0].afterEach(fn);
          break;
        default:
          var test = new Test(key, fn);
          test.file = file;
          suites[0].addTest(test);
      }
    } else {
      suite = Suite.create(suites[0], key);
      suites.unshift(suite);
      visit(obj[key]);
      suites.shift();
    }
  }
}

};

}); // module: interfaces/exports.js

require.register(“interfaces/index.js”, function(module, exports, require){ exports.bdd = require('./bdd'); exports.tdd = require('./tdd'); exports.qunit = require('./qunit'); exports.exports = require('./exports');

}); // module: interfaces/index.js

require.register(“interfaces/qunit.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Suite = require('../suite')

, Test = require('../test')
, escapeRe = require('browser/escape-string-regexp')
, utils = require('../utils');

/**

* QUnit-style interface:
*
*     suite('Array');
*
*     test('#length', function(){
*       var arr = [1,2,3];
*       ok(arr.length == 3);
*     });
*
*     test('#indexOf()', function(){
*       var arr = [1,2,3];
*       ok(arr.indexOf(1) == 0);
*       ok(arr.indexOf(2) == 1);
*       ok(arr.indexOf(3) == 2);
*     });
*
*     suite('String');
*
*     test('#length', function(){
*       ok('foo'.length == 3);
*     });
*
*/

module.exports = function(suite){

var suites = [suite];

suite.on('pre-require', function(context, file, mocha){

  /**
   * Execute before running tests.
   */

  context.before = function(name, fn){
    suites[0].beforeAll(name, fn);
  };

  /**
   * Execute after running tests.
   */

  context.after = function(name, fn){
    suites[0].afterAll(name, fn);
  };

  /**
   * Execute before each test case.
   */

  context.beforeEach = function(name, fn){
    suites[0].beforeEach(name, fn);
  };

  /**
   * Execute after each test case.
   */

  context.afterEach = function(name, fn){
    suites[0].afterEach(name, fn);
  };

  /**
   * Describe a "suite" with the given `title`.
   */

  context.suite = function(title){
    if (suites.length > 1) suites.shift();
    var suite = Suite.create(suites[0], title);
    suite.file = file;
    suites.unshift(suite);
    return suite;
  };

  /**
   * Exclusive test-case.
   */

  context.suite.only = function(title, fn){
    var suite = context.suite(title, fn);
    mocha.grep(suite.fullTitle());
  };

  /**
   * Describe a specification or test-case
   * with the given `title` and callback `fn`
   * acting as a thunk.
   */

  context.test = function(title, fn){
    var test = new Test(title, fn);
    test.file = file;
    suites[0].addTest(test);
    return test;
  };

  /**
   * Exclusive test-case.
   */

  context.test.only = function(title, fn){
    var test = context.test(title, fn);
    var reString = '^' + escapeRe(test.fullTitle()) + '$';
    mocha.grep(new RegExp(reString));
  };

  /**
   * Pending test case.
   */

  context.test.skip = function(title){
    context.test(title);
  };
});

};

}); // module: interfaces/qunit.js

require.register(“interfaces/tdd.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Suite = require('../suite')

, Test = require('../test')
, escapeRe = require('browser/escape-string-regexp')
, utils = require('../utils');

/**

* TDD-style interface:
*
*      suite('Array', function(){
*        suite('#indexOf()', function(){
*          suiteSetup(function(){
*
*          });
*
*          test('should return -1 when not present', function(){
*
*          });
*
*          test('should return the index when present', function(){
*
*          });
*
*          suiteTeardown(function(){
*
*          });
*        });
*      });
*
*/

module.exports = function(suite){

var suites = [suite];

suite.on('pre-require', function(context, file, mocha){

  /**
   * Execute before each test case.
   */

  context.setup = function(name, fn){
    suites[0].beforeEach(name, fn);
  };

  /**
   * Execute after each test case.
   */

  context.teardown = function(name, fn){
    suites[0].afterEach(name, fn);
  };

  /**
   * Execute before the suite.
   */

  context.suiteSetup = function(name, fn){
    suites[0].beforeAll(name, fn);
  };

  /**
   * Execute after the suite.
   */

  context.suiteTeardown = function(name, fn){
    suites[0].afterAll(name, fn);
  };

  /**
   * Describe a "suite" with the given `title`
   * and callback `fn` containing nested suites
   * and/or tests.
   */

  context.suite = function(title, fn){
    var suite = Suite.create(suites[0], title);
    suite.file = file;
    suites.unshift(suite);
    fn.call(suite);
    suites.shift();
    return suite;
  };

  /**
   * Pending suite.
   */
  context.suite.skip = function(title, fn) {
    var suite = Suite.create(suites[0], title);
    suite.pending = true;
    suites.unshift(suite);
    fn.call(suite);
    suites.shift();
  };

  /**
   * Exclusive test-case.
   */

  context.suite.only = function(title, fn){
    var suite = context.suite(title, fn);
    mocha.grep(suite.fullTitle());
  };

  /**
   * Describe a specification or test-case
   * with the given `title` and callback `fn`
   * acting as a thunk.
   */

  context.test = function(title, fn){
    var suite = suites[0];
    if (suite.pending) fn = null;
    var test = new Test(title, fn);
    test.file = file;
    suite.addTest(test);
    return test;
  };

  /**
   * Exclusive test-case.
   */

  context.test.only = function(title, fn){
    var test = context.test(title, fn);
    var reString = '^' + escapeRe(test.fullTitle()) + '$';
    mocha.grep(new RegExp(reString));
  };

  /**
   * Pending test case.
   */

  context.test.skip = function(title){
    context.test(title);
  };
});

};

}); // module: interfaces/tdd.js

require.register(“mocha.js”, function(module, exports, require){ /*!

* mocha
* Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
* MIT Licensed
*/

/**

* Module dependencies.
*/

var path = require('browser/path')

, escapeRe = require('browser/escape-string-regexp')
, utils = require('./utils');

/**

* Expose `Mocha`.
*/

exports = module.exports = Mocha;

/**

* To require local UIs and reporters when running in node.
*/

if (typeof process !== 'undefined' && typeof process.cwd === 'function') {

var join = path.join
  , cwd = process.cwd();
module.paths.push(cwd, join(cwd, 'node_modules'));

}

/**

* Expose internals.
*/

exports.utils = utils; exports.interfaces = require('./interfaces'); exports.reporters = require('./reporters'); exports.Runnable = require('./runnable'); exports.Context = require('./context'); exports.Runner = require('./runner'); exports.Suite = require('./suite'); exports.Hook = require('./hook'); exports.Test = require('./test');

/**

* Return image `name` path.
*
* @param {String} name
* @return {String}
* @api private
*/

function image(name) {

return __dirname + '/../images/' + name + '.png';

}

/**

* Setup mocha with `options`.
*
* Options:
*
*   - `ui` name "bdd", "tdd", "exports" etc
*   - `reporter` reporter instance, defaults to `mocha.reporters.spec`
*   - `globals` array of accepted globals
*   - `timeout` timeout in milliseconds
*   - `bail` bail on the first test failure
*   - `slow` milliseconds to wait before considering a test slow
*   - `ignoreLeaks` ignore global leaks
*   - `grep` string or regexp to filter tests with
*
* @param {Object} options
* @api public
*/

function Mocha(options) {

options = options || {};
this.files = [];
this.options = options;
this.grep(options.grep);
this.suite = new exports.Suite('', new exports.Context);
this.ui(options.ui);
this.bail(options.bail);
this.reporter(options.reporter, options.reporterOptions);
if (null != options.timeout) this.timeout(options.timeout);
this.useColors(options.useColors)
if (options.enableTimeouts !== null) this.enableTimeouts(options.enableTimeouts);
if (options.slow) this.slow(options.slow);

this.suite.on('pre-require', function (context) {
  exports.afterEach = context.afterEach || context.teardown;
  exports.after = context.after || context.suiteTeardown;
  exports.beforeEach = context.beforeEach || context.setup;
  exports.before = context.before || context.suiteSetup;
  exports.describe = context.describe || context.suite;
  exports.it = context.it || context.test;
  exports.setup = context.setup || context.beforeEach;
  exports.suiteSetup = context.suiteSetup || context.before;
  exports.suiteTeardown = context.suiteTeardown || context.after;
  exports.suite = context.suite || context.describe;
  exports.teardown = context.teardown || context.afterEach;
  exports.test = context.test || context.it;
});

}

/**

* Enable or disable bailing on the first failure.
*
* @param {Boolean} [bail]
* @api public
*/

Mocha.prototype.bail = function(bail){

if (0 == arguments.length) bail = true;
this.suite.bail(bail);
return this;

};

/**

* Add test `file`.
*
* @param {String} file
* @api public
*/

Mocha.prototype.addFile = function(file){

this.files.push(file);
return this;

};

/**

* Set reporter to `reporter`, defaults to "spec".
*
* @param {String|Function} reporter name or constructor
* @param {Object} reporterOptions optional options
* @api public
*/

Mocha.prototype.reporter = function(reporter, reporterOptions){

if ('function' == typeof reporter) {
  this._reporter = reporter;
} else {
  reporter = reporter || 'spec';
  var _reporter;
  try { _reporter = require('./reporters/' + reporter); } catch (err) {};
  if (!_reporter) try { _reporter = require(reporter); } catch (err) {};
  if (!_reporter && reporter === 'teamcity')
    console.warn('The Teamcity reporter was moved to a package named ' +
      'mocha-teamcity-reporter ' +
      '(https://npmjs.org/package/mocha-teamcity-reporter).');
  if (!_reporter) throw new Error('invalid reporter "' + reporter + '"');
  this._reporter = _reporter;
}
this.options.reporterOptions = reporterOptions;
return this;

};

/**

* Set test UI `name`, defaults to "bdd".
*
* @param {String} bdd
* @api public
*/

Mocha.prototype.ui = function(name){

name = name || 'bdd';
this._ui = exports.interfaces[name];
if (!this._ui) try { this._ui = require(name); } catch (err) {};
if (!this._ui) throw new Error('invalid interface "' + name + '"');
this._ui = this._ui(this.suite);
return this;

};

/**

* Load registered files.
*
* @api private
*/

Mocha.prototype.loadFiles = function(fn){

var self = this;
var suite = this.suite;
var pending = this.files.length;
this.files.forEach(function(file){
  file = path.resolve(file);
  suite.emit('pre-require', global, file, self);
  suite.emit('require', require(file), file, self);
  suite.emit('post-require', global, file, self);
  --pending || (fn && fn());
});

};

/**

* Enable growl support.
*
* @api private
*/

Mocha.prototype._growl = function(runner, reporter) {

var notify = require('growl');

runner.on('end', function(){
  var stats = reporter.stats;
  if (stats.failures) {
    var msg = stats.failures + ' of ' + runner.total + ' tests failed';
    notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
  } else {
    notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
        name: 'mocha'
      , title: 'Passed'
      , image: image('ok')
    });
  }
});

};

/**

* Add regexp to grep, if `re` is a string it is escaped.
*
* @param {RegExp|String} re
* @return {Mocha}
* @api public
*/

Mocha.prototype.grep = function(re){

this.options.grep = 'string' == typeof re
  ? new RegExp(escapeRe(re))
  : re;
return this;

};

/**

* Invert `.grep()` matches.
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.invert = function(){

this.options.invert = true;
return this;

};

/**

* Ignore global leaks.
*
* @param {Boolean} ignore
* @return {Mocha}
* @api public
*/

Mocha.prototype.ignoreLeaks = function(ignore){

this.options.ignoreLeaks = !!ignore;
return this;

};

/**

* Enable global leak checking.
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.checkLeaks = function(){

this.options.ignoreLeaks = false;
return this;

};

/**

* Enable growl support.
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.growl = function(){

this.options.growl = true;
return this;

};

/**

* Ignore `globals` array or string.
*
* @param {Array|String} globals
* @return {Mocha}
* @api public
*/

Mocha.prototype.globals = function(globals){

this.options.globals = (this.options.globals || []).concat(globals);
return this;

};

/**

* Emit color output.
*
* @param {Boolean} colors
* @return {Mocha}
* @api public
*/

Mocha.prototype.useColors = function(colors){

if (colors !== undefined) {
  this.options.useColors = colors;
}
return this;

};

/**

* Use inline diffs rather than +/-.
*
* @param {Boolean} inlineDiffs
* @return {Mocha}
* @api public
*/

Mocha.prototype.useInlineDiffs = function(inlineDiffs) {

this.options.useInlineDiffs = arguments.length && inlineDiffs != undefined
? inlineDiffs
: false;
return this;

};

/**

* Set the timeout in milliseconds.
*
* @param {Number} timeout
* @return {Mocha}
* @api public
*/

Mocha.prototype.timeout = function(timeout){

this.suite.timeout(timeout);
return this;

};

/**

* Set slowness threshold in milliseconds.
*
* @param {Number} slow
* @return {Mocha}
* @api public
*/

Mocha.prototype.slow = function(slow){

this.suite.slow(slow);
return this;

};

/**

* Enable timeouts.
*
* @param {Boolean} enabled
* @return {Mocha}
* @api public
*/

Mocha.prototype.enableTimeouts = function(enabled) {

this.suite.enableTimeouts(arguments.length && enabled !== undefined
  ? enabled
  : true);
return this

};

/**

* Makes all tests async (accepting a callback)
*
* @return {Mocha}
* @api public
*/

Mocha.prototype.asyncOnly = function(){

this.options.asyncOnly = true;
return this;

};

/**

* Disable syntax highlighting (in browser).
* @returns {Mocha}
* @api public
*/

Mocha.prototype.noHighlighting = function() {

this.options.noHighlighting = true;
return this;

};

/**

* Run tests and invoke `fn()` when complete.
*
* @param {Function} fn
* @return {Runner}
* @api public
*/

Mocha.prototype.run = function(fn){

if (this.files.length) this.loadFiles();
var suite = this.suite;
var options = this.options;
options.files = this.files;
var runner = new exports.Runner(suite);
var reporter = new this._reporter(runner, options);
runner.ignoreLeaks = false !== options.ignoreLeaks;
runner.asyncOnly = options.asyncOnly;
if (options.grep) runner.grep(options.grep, options.invert);
if (options.globals) runner.globals(options.globals);
if (options.growl) this._growl(runner, reporter);
if (options.useColors !== undefined) {
  exports.reporters.Base.useColors = options.useColors;
}
exports.reporters.Base.inlineDiffs = options.useInlineDiffs;

function done(failures) {
    if (reporter.done) {
        reporter.done(failures, fn);
    } else {
        fn(failures);
    }
}

return runner.run(done);

};

}); // module: mocha.js

require.register(“ms.js”, function(module, exports, require){ /**

* 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';

}

}); // module: ms.js

require.register(“reporters/base.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var tty = require('browser/tty')

, diff = require('browser/diff')
, ms = require('../ms')
, utils = require('../utils');

/**

* 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) && tty.isatty(2);

/**

* Expose `Base`.
*/

exports = module.exports = Base;

/**

* Enable coloring by default.
*/

exports.useColors = isatty || (process.env.MOCHA_COLORS !== undefined);

/**

* 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': 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
    , 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 = 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;
  stats.duration = new Date - 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);
  console.log();
}

console.log();

};

/**

* 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;
}
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;

}

}); // module: reporters/base.js

require.register(“reporters/doc.js”, function(module, exports, require){ /**

* 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));
});

}

}); // module: reporters/doc.js

require.register(“reporters/dot.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; Dot.prototype = new F; Dot.prototype.constructor = Dot;

}); // module: reporters/dot.js

require.register(“reporters/html-cov.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var JSONCov = require('./json-cov')

, fs = require('browser/fs');

/**

* Expose `HTMLCov`.
*/

exports = module.exports = HTMLCov;

/**

* Initialize a new `JsCoverage` reporter.
*
* @param {Runner} runner
* @api public
*/

function HTMLCov(runner) {

var jade = require('jade')
  , file = __dirname + '/templates/coverage.jade'
  , str = fs.readFileSync(file, 'utf8')
  , fn = jade.compile(str, { filename: file })
  , self = this;

JSONCov.call(this, runner, false);

runner.on('end', function(){
  process.stdout.write(fn({
      cov: self.cov
    , coverageClass: coverageClass
  }));
});

}

/**

* Return coverage class for `n`.
*
* @return {String}
* @api private
*/

function coverageClass(n) {

if (n >= 75) return 'high';
if (n >= 50) return 'medium';
if (n >= 25) return 'low';
return 'terrible';

}

}); // module: reporters/html-cov.js

require.register(“reporters/html.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Base = require('./base')

, utils = require('../utils')
, Progress = require('../browser/progress')
, 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 `HTML`.
*/

exports = module.exports = HTML;

/**

* Stats template.
*/

var statsTemplate = '<ul id=“mocha-stats”>'

+ '<li class="progress"><canvas width="40" height="40"></canvas></li>'
+ '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
+ '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
+ '<li class="duration">duration: <em>0</em>s</li>'
+ '</ul>';

/**

* Initialize a new `HTML` reporter.
*
* @param {Runner} runner
* @api public
*/

function HTML(runner) {

Base.call(this, runner);

var self = this
  , stats = this.stats
  , total = runner.total
  , stat = fragment(statsTemplate)
  , items = stat.getElementsByTagName('li')
  , passes = items[1].getElementsByTagName('em')[0]
  , passesLink = items[1].getElementsByTagName('a')[0]
  , failures = items[2].getElementsByTagName('em')[0]
  , failuresLink = items[2].getElementsByTagName('a')[0]
  , duration = items[3].getElementsByTagName('em')[0]
  , canvas = stat.getElementsByTagName('canvas')[0]
  , report = fragment('<ul id="mocha-report"></ul>')
  , stack = [report]
  , progress
  , ctx
  , root = document.getElementById('mocha');

if (canvas.getContext) {
  var ratio = window.devicePixelRatio || 1;
  canvas.style.width = canvas.width;
  canvas.style.height = canvas.height;
  canvas.width *= ratio;
  canvas.height *= ratio;
  ctx = canvas.getContext('2d');
  ctx.scale(ratio, ratio);
  progress = new Progress;
}

if (!root) return error('#mocha div missing, add it to your document');

// pass toggle
on(passesLink, 'click', function(){
  unhide();
  var name = /pass/.test(report.className) ? '' : ' pass';
  report.className = report.className.replace(/fail|pass/g, '') + name;
  if (report.className.trim()) hideSuitesWithout('test pass');
});

// failure toggle
on(failuresLink, 'click', function(){
  unhide();
  var name = /fail/.test(report.className) ? '' : ' fail';
  report.className = report.className.replace(/fail|pass/g, '') + name;
  if (report.className.trim()) hideSuitesWithout('test fail');
});

root.appendChild(stat);
root.appendChild(report);

if (progress) progress.size(40);

runner.on('suite', function(suite){
  if (suite.root) return;

  // suite
  var url = self.suiteURL(suite);
  var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));

  // container
  stack[0].appendChild(el);
  stack.unshift(document.createElement('ul'));
  el.appendChild(stack[0]);
});

runner.on('suite end', function(suite){
  if (suite.root) return;
  stack.shift();
});

runner.on('fail', function(test, err){
  if ('hook' == test.type) runner.emit('test end', test);
});

runner.on('test end', function(test){
  // TODO: add to stats
  var percent = stats.tests / this.total * 100 | 0;
  if (progress) progress.update(percent).draw(ctx);

  // update stats
  var ms = new Date - stats.start;
  text(passes, stats.passes);
  text(failures, stats.failures);
  text(duration, (ms / 1000).toFixed(2));

  // test
  if ('passed' == test.state) {
    var url = self.testURL(test);
    var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
  } else if (test.pending) {
    var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
  } else {
    var el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>', test.title, self.testURL(test));
    var str = test.err.stack || test.err.toString();

    // FF / Opera do not add the message
    if (!~str.indexOf(test.err.message)) {
      str = test.err.message + '\n' + str;
    }

    // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
    // check for the result of the stringifying.
    if ('[object Error]' == str) str = test.err.message;

    // Safari doesn't give you a stack. Let's at least provide a source line.
    if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
      str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
    }

    el.appendChild(fragment('<pre class="error">%e</pre>', str));
  }

  // toggle code
  // TODO: defer
  if (!test.pending) {
    var h2 = el.getElementsByTagName('h2')[0];

    on(h2, 'click', function(){
      pre.style.display = 'none' == pre.style.display
        ? 'block'
        : 'none';
    });

    var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
    el.appendChild(pre);
    pre.style.display = 'none';
  }

  // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
  if (stack[0]) stack[0].appendChild(el);
});

}

/**

* Makes a URL, preserving querystring ("search") parameters.
* @param {string} s
* @returns {string} your new URL
*/

var makeUrl = function makeUrl(s) {

var search = window.location.search;
return window.location.pathname + (search ? search + '&' : '?' ) + 'grep=' + encodeURIComponent(s);

};

/**

* Provide suite URL
*
* @param {Object} [suite]
*/

HTML.prototype.suiteURL = function(suite){

return makeUrl(suite.fullTitle());

};

/**

* Provide test URL
*
* @param {Object} [test]
*/

HTML.prototype.testURL = function(test){

return makeUrl(test.fullTitle());

};

/**

* Display error `msg`.
*/

function error(msg) {

document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));

}

/**

* Return a DOM fragment from `html`.
*/

function fragment(html) {

var args = arguments
  , div = document.createElement('div')
  , i = 1;

div.innerHTML = html.replace(/%([se])/g, function(_, type){
  switch (type) {
    case 's': return String(args[i++]);
    case 'e': return escape(args[i++]);
  }
});

return div.firstChild;

}

/**

* Check for suites that do not have elements
* with `classname`, and hide them.
*/

function hideSuitesWithout(classname) {

var suites = document.getElementsByClassName('suite');
for (var i = 0; i < suites.length; i++) {
  var els = suites[i].getElementsByClassName(classname);
  if (0 == els.length) suites[i].className += ' hidden';
}

}

/**

* Unhide .hidden suites.
*/

function unhide() {

var els = document.getElementsByClassName('suite hidden');
for (var i = 0; i < els.length; ++i) {
  els[i].className = els[i].className.replace('suite hidden', 'suite');
}

}

/**

* Set `el` text to `str`.
*/

function text(el, str) {

if (el.textContent) {
  el.textContent = str;
} else {
  el.innerText = str;
}

}

/**

* Listen on `event` with callback `fn`.
*/

function on(el, event, fn) {

if (el.addEventListener) {
  el.addEventListener(event, fn, false);
} else {
  el.attachEvent('on' + event, fn);
}

}

}); // module: reporters/html.js

require.register(“reporters/index.js”, function(module, exports, require){ exports.Base = require('./base'); exports.Dot = require('./dot'); exports.Doc = require('./doc'); exports.TAP = require('./tap'); exports.JSON = require('./json'); exports.HTML = require('./html'); exports.List = require('./list'); exports.Min = require('./min'); exports.Spec = require('./spec'); exports.Nyan = require('./nyan'); exports.XUnit = require('./xunit'); exports.Markdown = require('./markdown'); exports.Progress = require('./progress'); exports.Landing = require('./landing'); exports.JSONCov = require('./json-cov'); exports.HTMLCov = require('./html-cov'); exports.JSONStream = require('./json-stream');

}); // module: reporters/index.js

require.register(“reporters/json-cov.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Base = require('./base');

/**

* Expose `JSONCov`.
*/

exports = module.exports = JSONCov;

/**

* Initialize a new `JsCoverage` reporter.
*
* @param {Runner} runner
* @param {Boolean} output
* @api public
*/

function JSONCov(runner, output) {

var self = this
  , output = 1 == arguments.length ? true : output;

Base.call(this, runner);

var tests = []
  , 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('end', function(){
  var cov = global._$jscoverage || {};
  var result = self.cov = map(cov);
  result.stats = self.stats;
  result.tests = tests.map(clean);
  result.failures = failures.map(clean);
  result.passes = passes.map(clean);
  if (!output) return;
  process.stdout.write(JSON.stringify(result, null, 2 ));
});

}

/**

* Map jscoverage data to a JSON structure
* suitable for reporting.
*
* @param {Object} cov
* @return {Object}
* @api private
*/

function map(cov) {

var ret = {
    instrumentation: 'node-jscoverage'
  , sloc: 0
  , hits: 0
  , misses: 0
  , coverage: 0
  , files: []
};

for (var filename in cov) {
  var data = coverage(filename, cov[filename]);
  ret.files.push(data);
  ret.hits += data.hits;
  ret.misses += data.misses;
  ret.sloc += data.sloc;
}

ret.files.sort(function(a, b) {
  return a.filename.localeCompare(b.filename);
});

if (ret.sloc > 0) {
  ret.coverage = (ret.hits / ret.sloc) * 100;
}

return ret;

}

/**

* Map jscoverage data for a single source file
* to a JSON structure suitable for reporting.
*
* @param {String} filename name of the source file
* @param {Object} data jscoverage coverage data
* @return {Object}
* @api private
*/

function coverage(filename, data) {

var ret = {
  filename: filename,
  coverage: 0,
  hits: 0,
  misses: 0,
  sloc: 0,
  source: {}
};

data.source.forEach(function(line, num){
  num++;

  if (data[num] === 0) {
    ret.misses++;
    ret.sloc++;
  } else if (data[num] !== undefined) {
    ret.hits++;
    ret.sloc++;
  }

  ret.source[num] = {
      source: line
    , coverage: data[num] === undefined
      ? ''
      : data[num]
  };
});

ret.coverage = ret.hits / ret.sloc * 100;

return ret;

}

/**

* 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
}

}

}); // module: reporters/json-cov.js

require.register(“reporters/json-stream.js”, function(module, exports, require){ /**

* 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
}

}

}); // module: reporters/json-stream.js

require.register(“reporters/json.js”, function(module, exports, require){ /**

* 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;

}

}); // module: reporters/json.js

require.register(“reporters/landing.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; Landing.prototype = new F; Landing.prototype.constructor = Landing;

}); // module: reporters/landing.js

require.register(“reporters/list.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; List.prototype = new F; List.prototype.constructor = List;

}); // module: reporters/list.js

require.register(“reporters/markdown.js”, function(module, exports, require){ /**

* 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).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(suite) {
  var obj = mapTOC(suite, {});
  return stringifyTOC(obj, 0);
}

generateTOC(runner.suite);

runner.on('suite', function(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){
  --level;
});

runner.on('pass', function(test){
  var code = utils.clean(test.fn.toString());
  buf += test.title + '.\n';
  buf += '\n```js\n';
  buf += code + '\n';
  buf += '```\n\n';
});

runner.on('end', function(){
  process.stdout.write('# TOC\n');
  process.stdout.write(generateTOC(runner.suite));
  process.stdout.write(buf);
});

}

}); // module: reporters/markdown.js

require.register(“reporters/min.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; Min.prototype = new F; Min.prototype.constructor = Min;

}); // module: reporters/min.js

require.register(“reporters/nyan.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; NyanCat.prototype = new F; NyanCat.prototype.constructor = NyanCat;

}); // module: reporters/nyan.js

require.register(“reporters/progress.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; Progress.prototype = new F; Progress.prototype.constructor = Progress;

}); // module: reporters/progress.js

require.register(“reporters/spec.js”, function(module, exports, require){ /**

* 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`.
*/

function F(){}; F.prototype = Base.prototype; Spec.prototype = new F; Spec.prototype.constructor = Spec;

}); // module: reporters/spec.js

require.register(“reporters/tap.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Base = require('./base')

, cursor = Base.cursor
, color = Base.color;

/**

* Expose `TAP`.
*/

exports = module.exports = TAP;

/**

* Initialize a new `TAP` reporter.
*
* @param {Runner} runner
* @api public
*/

function TAP(runner) {

Base.call(this, runner);

var self = this
  , stats = this.stats
  , n = 1
  , passes = 0
  , failures = 0;

runner.on('start', function(){
  var total = runner.grepTotal(runner.suite);
  console.log('%d..%d', 1, total);
});

runner.on('test end', function(){
  ++n;
});

runner.on('pending', function(test){
  console.log('ok %d %s # SKIP -', n, title(test));
});

runner.on('pass', function(test){
  passes++;
  console.log('ok %d %s', n, title(test));
});

runner.on('fail', function(test, err){
  failures++;
  console.log('not ok %d %s', n, title(test));
  if (err.stack) console.log(err.stack.replace(/^/gm, '  '));
});

runner.on('end', function(){
  console.log('# tests ' + (passes + failures));
  console.log('# pass ' + passes);
  console.log('# fail ' + failures);
});

}

/**

* Return a TAP-safe title of `test`
*
* @param {Object} test
* @return {String}
* @api private
*/

function title(test) {

return test.fullTitle().replace(/#/g, '');

}

}); // module: reporters/tap.js

require.register(“reporters/xunit.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Base = require('./base')

, utils = require('../utils')
, fs = require('browser/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: 'Mocha 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`.
*/

function F(){}; F.prototype = Base.prototype; XUnit.prototype = new F; XUnit.prototype.constructor = XUnit;

/**

* 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) + ']]>';

}

}); // module: reporters/xunit.js

require.register(“runnable.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var EventEmitter = require('browser/events').EventEmitter

, debug = require('browser/debug')('mocha:runnable')
, milliseconds = require('./ms')
, utils = require('./utils');

/**

* 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;

/**

* Object#toString().
*/

var toString = Object.prototype.toString;

/**

* Expose `Runnable`.
*/

module.exports = Runnable;

/**

* Initialize a new `Runnable` with the given `title` and callback `fn`.
*
* @param {String} title
* @param {Function} fn
* @api private
*/

function Runnable(title, fn) {

this.title = title;
this.fn = fn;
this.async = fn && fn.length;
this.sync = ! this.async;
this._timeout = 2000;
this._slow = 75;
this._enableTimeouts = true;
this.timedOut = false;
this._trace = new Error('done() called multiple times')

}

/**

* Inherit from `EventEmitter.prototype`.
*/

function F(){}; F.prototype = EventEmitter.prototype; Runnable.prototype = new F; Runnable.prototype.constructor = Runnable;

/**

* Set & get timeout `ms`.
*
* @param {Number|String} ms
* @return {Runnable|Number} ms or self
* @api private
*/

Runnable.prototype.timeout = function(ms){

if (0 == arguments.length) return this._timeout;
if (ms === 0) this._enableTimeouts = false;
if ('string' == typeof ms) ms = milliseconds(ms);
debug('timeout %d', ms);
this._timeout = ms;
if (this.timer) this.resetTimeout();
return this;

};

/**

* Set & get slow `ms`.
*
* @param {Number|String} ms
* @return {Runnable|Number} ms or self
* @api private
*/

Runnable.prototype.slow = function(ms){

if (0 === arguments.length) return this._slow;
if ('string' == typeof ms) ms = milliseconds(ms);
debug('timeout %d', ms);
this._slow = ms;
return this;

};

/**

* Set and & get timeout `enabled`.
*
* @param {Boolean} enabled
* @return {Runnable|Boolean} enabled or self
* @api private
*/

Runnable.prototype.enableTimeouts = function(enabled){

if (arguments.length === 0) return this._enableTimeouts;
debug('enableTimeouts %s', enabled);
this._enableTimeouts = enabled;
return this;

};

/**

* Return the full title generated by recursively
* concatenating the parent's full title.
*
* @return {String}
* @api public
*/

Runnable.prototype.fullTitle = function(){

return this.parent.fullTitle() + ' ' + this.title;

};

/**

* Clear the timeout.
*
* @api private
*/

Runnable.prototype.clearTimeout = function(){

clearTimeout(this.timer);

};

/**

* Inspect the runnable void of private properties.
*
* @return {String}
* @api private
*/

Runnable.prototype.inspect = function(){

return JSON.stringify(this, function(key, val){
  if ('_' == key[0]) return;
  if ('parent' == key) return '#<Suite>';
  if ('ctx' == key) return '#<Context>';
  return val;
}, 2);

};

/**

* Reset the timeout.
*
* @api private
*/

Runnable.prototype.resetTimeout = function(){

var self = this;
var ms = this.timeout() || 1e9;

if (!this._enableTimeouts) return;
this.clearTimeout();
this.timer = setTimeout(function(){
  if (!self._enableTimeouts) return;
  self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
  self.timedOut = true;
}, ms);

};

/**

* Whitelist these globals for this test run
*
* @api private
*/

Runnable.prototype.globals = function(arr){

var self = this;
this._allowedGlobals = arr;

};

/**

* Run the test and invoke `fn(err)`.
*
* @param {Function} fn
* @api private
*/

Runnable.prototype.run = function(fn){

var self = this
  , start = new Date
  , ctx = this.ctx
  , finished
  , emitted;

// Some times the ctx exists but it is not runnable
if (ctx && ctx.runnable) ctx.runnable(this);

// called multiple times
function multiple(err) {
  if (emitted) return;
  emitted = true;
  self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate'));
}

// finished
function done(err) {
  var ms = self.timeout();
  if (self.timedOut) return;
  if (finished) return multiple(err || self._trace);
  self.clearTimeout();
  self.duration = new Date - start;
  finished = true;
  if (!err && self.duration > ms && self._enableTimeouts) err = new Error('timeout of ' + ms + 'ms exceeded');
  fn(err);
}

// for .resetTimeout()
this.callback = done;

// explicit async with `done` argument
if (this.async) {
  this.resetTimeout();

  try {
    this.fn.call(ctx, function(err){
      if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
      if (null != err) {
        if (Object.prototype.toString.call(err) === '[object Object]') {
          return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
        } else {
          return done(new Error('done() invoked with non-Error: ' + err));
        }
      }
      done();
    });
  } catch (err) {
    done(utils.getError(err));
  }
  return;
}

if (this.asyncOnly) {
  return done(new Error('--async-only option in use without declaring `done()`'));
}

// sync or promise-returning
try {
  if (this.pending) {
    done();
  } else {
    callFn(this.fn);
  }
} catch (err) {
  done(utils.getError(err));
}

function callFn(fn) {
  var result = fn.call(ctx);
  if (result && typeof result.then === 'function') {
    self.resetTimeout();
    result
      .then(function() {
        done()
      },
      function(reason) {
        done(reason || new Error('Promise rejected with no or falsy reason'))
      });
  } else {
    done();
  }
}

};

}); // module: runnable.js

require.register(“runner.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var EventEmitter = require('browser/events').EventEmitter

, debug = require('browser/debug')('mocha:runner')
, Test = require('./test')
, utils = require('./utils')
, filter = utils.filter
, keys = utils.keys;

/**

* Non-enumerable globals.
*/

var globals = [

'setTimeout',
'clearTimeout',
'setInterval',
'clearInterval',
'XMLHttpRequest',
'Date',
'setImmediate',
'clearImmediate'

];

/**

* Expose `Runner`.
*/

module.exports = Runner;

/**

* Initialize a `Runner` for the given `suite`.
*
* Events:
*
*   - `start`  execution started
*   - `end`  execution complete
*   - `suite`  (suite) test suite execution started
*   - `suite end`  (suite) all tests (and sub-suites) have finished
*   - `test`  (test) test execution started
*   - `test end`  (test) test completed
*   - `hook`  (hook) hook execution started
*   - `hook end`  (hook) hook complete
*   - `pass`  (test) test passed
*   - `fail`  (test, err) test failed
*   - `pending`  (test) test pending
*
* @api public
*/

function Runner(suite) {

var self = this;
this._globals = [];
this._abort = false;
this.suite = suite;
this.total = suite.total();
this.failures = 0;
this.on('test end', function(test){ self.checkGlobals(test); });
this.on('hook end', function(hook){ self.checkGlobals(hook); });
this.grep(/.*/);
this.globals(this.globalProps().concat(extraGlobals()));

}

/**

* Wrapper for setImmediate, process.nextTick, or browser polyfill.
*
* @param {Function} fn
* @api private
*/

Runner.immediately = global.setImmediate || process.nextTick;

/**

* Inherit from `EventEmitter.prototype`.
*/

function F(){}; F.prototype = EventEmitter.prototype; Runner.prototype = new F; Runner.prototype.constructor = Runner;

/**

* Run tests with full titles matching `re`. Updates runner.total
* with number of tests matched.
*
* @param {RegExp} re
* @param {Boolean} invert
* @return {Runner} for chaining
* @api public
*/

Runner.prototype.grep = function(re, invert){

debug('grep %s', re);
this._grep = re;
this._invert = invert;
this.total = this.grepTotal(this.suite);
return this;

};

/**

* Returns the number of tests matching the grep search for the
* given suite.
*
* @param {Suite} suite
* @return {Number}
* @api public
*/

Runner.prototype.grepTotal = function(suite) {

var self = this;
var total = 0;

suite.eachTest(function(test){
  var match = self._grep.test(test.fullTitle());
  if (self._invert) match = !match;
  if (match) total++;
});

return total;

};

/**

* Return a list of global properties.
*
* @return {Array}
* @api private
*/

Runner.prototype.globalProps = function() {

var props = utils.keys(global);

// non-enumerables
for (var i = 0; i < globals.length; ++i) {
  if (~utils.indexOf(props, globals[i])) continue;
  props.push(globals[i]);
}

return props;

};

/**

* Allow the given `arr` of globals.
*
* @param {Array} arr
* @return {Runner} for chaining
* @api public
*/

Runner.prototype.globals = function(arr){

if (0 == arguments.length) return this._globals;
debug('globals %j', arr);
this._globals = this._globals.concat(arr);
return this;

};

/**

* Check for global variable leaks.
*
* @api private
*/

Runner.prototype.checkGlobals = function(test){

if (this.ignoreLeaks) return;
var ok = this._globals;

var globals = this.globalProps();
var leaks;

if (test) {
  ok = ok.concat(test._allowedGlobals || []);
}

if(this.prevGlobalsLength == globals.length) return;
this.prevGlobalsLength = globals.length;

leaks = filterLeaks(ok, globals);
this._globals = this._globals.concat(leaks);

if (leaks.length > 1) {
  this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
} else if (leaks.length) {
  this.fail(test, new Error('global leak detected: ' + leaks[0]));
}

};

/**

* Fail the given `test`.
*
* @param {Test} test
* @param {Error} err
* @api private
*/

Runner.prototype.fail = function(test, err){

++this.failures;
test.state = 'failed';

if ('string' == typeof err) {
  err = new Error('the string "' + err + '" was thrown, throw an Error :)');
}

this.emit('fail', test, err);

};

/**

* Fail the given `hook` with `err`.
*
* Hook failures work in the following pattern:
* - If bail, then exit
* - Failed `before` hook skips all tests in a suite and subsuites,
*   but jumps to corresponding `after` hook
* - Failed `before each` hook skips remaining tests in a
*   suite and jumps to corresponding `after each` hook,
*   which is run only once
* - Failed `after` hook does not alter
*   execution order
* - Failed `after each` hook skips remaining tests in a
*   suite and subsuites, but executes other `after each`
*   hooks
*
* @param {Hook} hook
* @param {Error} err
* @api private
*/

Runner.prototype.failHook = function(hook, err){

this.fail(hook, err);
if (this.suite.bail()) {
  this.emit('end');
}

};

/**

* Run hook `name` callbacks and then invoke `fn()`.
*
* @param {String} name
* @param {Function} function
* @api private
*/

Runner.prototype.hook = function(name, fn){

var suite = this.suite
  , hooks = suite['_' + name]
  , self = this
  , timer;

function next(i) {
  var hook = hooks[i];
  if (!hook) return fn();
  self.currentRunnable = hook;

  hook.ctx.currentTest = self.test;

  self.emit('hook', hook);

  hook.on('error', function(err){
    self.failHook(hook, err);
  });

  hook.run(function(err){
    hook.removeAllListeners('error');
    var testError = hook.error();
    if (testError) self.fail(self.test, testError);
    if (err) {
      self.failHook(hook, err);

      // stop executing hooks, notify callee of hook err
      return fn(err);
    }
    self.emit('hook end', hook);
    delete hook.ctx.currentTest;
    next(++i);
  });
}

Runner.immediately(function(){
  next(0);
});

};

/**

* Run hook `name` for the given array of `suites`
* in order, and callback `fn(err, errSuite)`.
*
* @param {String} name
* @param {Array} suites
* @param {Function} fn
* @api private
*/

Runner.prototype.hooks = function(name, suites, fn){

var self = this
  , orig = this.suite;

function next(suite) {
  self.suite = suite;

  if (!suite) {
    self.suite = orig;
    return fn();
  }

  self.hook(name, function(err){
    if (err) {
      var errSuite = self.suite;
      self.suite = orig;
      return fn(err, errSuite);
    }

    next(suites.pop());
  });
}

next(suites.pop());

};

/**

* Run hooks from the top level down.
*
* @param {String} name
* @param {Function} fn
* @api private
*/

Runner.prototype.hookUp = function(name, fn){

var suites = [this.suite].concat(this.parents()).reverse();
this.hooks(name, suites, fn);

};

/**

* Run hooks from the bottom up.
*
* @param {String} name
* @param {Function} fn
* @api private
*/

Runner.prototype.hookDown = function(name, fn){

var suites = [this.suite].concat(this.parents());
this.hooks(name, suites, fn);

};

/**

* Return an array of parent Suites from
* closest to furthest.
*
* @return {Array}
* @api private
*/

Runner.prototype.parents = function(){

var suite = this.suite
  , suites = [];
while (suite = suite.parent) suites.push(suite);
return suites;

};

/**

* Run the current test and callback `fn(err)`.
*
* @param {Function} fn
* @api private
*/

Runner.prototype.runTest = function(fn){

var test = this.test
  , self = this;

if (this.asyncOnly) test.asyncOnly = true;

try {
  test.on('error', function(err){
    self.fail(test, err);
  });
  test.run(fn);
} catch (err) {
  fn(err);
}

};

/**

* Run tests in the given `suite` and invoke
* the callback `fn()` when complete.
*
* @param {Suite} suite
* @param {Function} fn
* @api private
*/

Runner.prototype.runTests = function(suite, fn){

var self = this
  , tests = suite.tests.slice()
  , test;

function hookErr(err, errSuite, after) {
  // before/after Each hook for errSuite failed:
  var orig = self.suite;

  // for failed 'after each' hook start from errSuite parent,
  // otherwise start from errSuite itself
  self.suite = after ? errSuite.parent : errSuite;

  if (self.suite) {
    // call hookUp afterEach
    self.hookUp('afterEach', function(err2, errSuite2) {
      self.suite = orig;
      // some hooks may fail even now
      if (err2) return hookErr(err2, errSuite2, true);
      // report error suite
      fn(errSuite);
    });
  } else {
    // there is no need calling other 'after each' hooks
    self.suite = orig;
    fn(errSuite);
  }
}

function next(err, errSuite) {
  // if we bail after first err
  if (self.failures && suite._bail) return fn();

  if (self._abort) return fn();

  if (err) return hookErr(err, errSuite, true);

  // next test
  test = tests.shift();

  // all done
  if (!test) return fn();

  // grep
  var match = self._grep.test(test.fullTitle());
  if (self._invert) match = !match;
  if (!match) return next();

  // pending
  if (test.pending) {
    self.emit('pending', test);
    self.emit('test end', test);
    return next();
  }

  // execute test and hook(s)
  self.emit('test', self.test = test);
  self.hookDown('beforeEach', function(err, errSuite){

    if (err) return hookErr(err, errSuite, false);

    self.currentRunnable = self.test;
    self.runTest(function(err){
      test = self.test;

      if (err) {
        self.fail(test, err);
        self.emit('test end', test);
        return self.hookUp('afterEach', next);
      }

      test.state = 'passed';
      self.emit('pass', test);
      self.emit('test end', test);
      self.hookUp('afterEach', next);
    });
  });
}

this.next = next;
next();

};

/**

* Run the given `suite` and invoke the
* callback `fn()` when complete.
*
* @param {Suite} suite
* @param {Function} fn
* @api private
*/

Runner.prototype.runSuite = function(suite, fn){

var total = this.grepTotal(suite)
  , self = this
  , i = 0;

debug('run suite %s', suite.fullTitle());

if (!total) return fn();

this.emit('suite', this.suite = suite);

function next(errSuite) {
  if (errSuite) {
    // current suite failed on a hook from errSuite
    if (errSuite == suite) {
      // if errSuite is current suite
      // continue to the next sibling suite
      return done();
    } else {
      // errSuite is among the parents of current suite
      // stop execution of errSuite and all sub-suites
      return done(errSuite);
    }
  }

  if (self._abort) return done();

  var curr = suite.suites[i++];
  if (!curr) return done();
  self.runSuite(curr, next);
}

function done(errSuite) {
  self.suite = suite;
  self.hook('afterAll', function(){
    self.emit('suite end', suite);
    fn(errSuite);
  });
}

this.hook('beforeAll', function(err){
  if (err) return done();
  self.runTests(suite, next);
});

};

/**

* Handle uncaught exceptions.
*
* @param {Error} err
* @api private
*/

Runner.prototype.uncaught = function(err){

if (err) {
  debug('uncaught exception %s', err !== function () {
    return this;
  }.call(err) ? err : ( err.message || err ));
} else {
  debug('uncaught undefined exception');
  err = utils.undefinedError();
}
err.uncaught = true;

var runnable = this.currentRunnable;
if (!runnable) return;

var wasAlreadyDone = runnable.state;
this.fail(runnable, err);

runnable.clearTimeout();

if (wasAlreadyDone) return;

// recover from test
if ('test' == runnable.type) {
  this.emit('test end', runnable);
  this.hookUp('afterEach', this.next);
  return;
}

// bail on hooks
this.emit('end');

};

/**

* Run the root suite and invoke `fn(failures)`
* on completion.
*
* @param {Function} fn
* @return {Runner} for chaining
* @api public
*/

Runner.prototype.run = function(fn){

var self = this
  , fn = fn || function(){};

function uncaught(err){
  self.uncaught(err);
}

debug('start');

// callback
this.on('end', function(){
  debug('end');
  process.removeListener('uncaughtException', uncaught);
  fn(self.failures);
});

// run suites
this.emit('start');
this.runSuite(this.suite, function(){
  debug('finished running');
  self.emit('end');
});

// uncaught exception
process.on('uncaughtException', uncaught);

return this;

};

/**

* Cleanly abort execution
*
* @return {Runner} for chaining
* @api public
*/

Runner.prototype.abort = function(){

debug('aborting');
this._abort = true;

};

/**

* Filter leaks with the given globals flagged as `ok`.
*
* @param {Array} ok
* @param {Array} globals
* @return {Array}
* @api private
*/

function filterLeaks(ok, globals) {

return filter(globals, function(key){
  // Firefox and Chrome exposes iframes as index inside the window object
  if (/^d+/.test(key)) return false;

  // in firefox
  // if runner runs in an iframe, this iframe's window.getInterface method not init at first
  // it is assigned in some seconds
  if (global.navigator && /^getInterface/.test(key)) return false;

  // an iframe could be approached by window[iframeIndex]
  // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak
  if (global.navigator && /^\d+/.test(key)) return false;

  // Opera and IE expose global variables for HTML element IDs (issue #243)
  if (/^mocha-/.test(key)) return false;

  var matched = filter(ok, function(ok){
    if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
    return key == ok;
  });
  return matched.length == 0 && (!global.navigator || 'onerror' !== key);
});

}

/**

* Array of globals dependent on the environment.
*
* @return {Array}
* @api private
*/

function extraGlobals() {
 if (typeof(process) === 'object' &&
     typeof(process.version) === 'string') {

   var nodeVersion = process.version.split('.').reduce(function(a, v) {
     return a << 8 | v;
   });

   // 'errno' was renamed to process._errno in v0.9.11.

   if (nodeVersion < 0x00090B) {
     return ['errno'];
   }
 }

 return [];
}

}); // module: runner.js

require.register(“suite.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var EventEmitter = require('browser/events').EventEmitter

, debug = require('browser/debug')('mocha:suite')
, milliseconds = require('./ms')
, utils = require('./utils')
, Hook = require('./hook');

/**

* Expose `Suite`.
*/

exports = module.exports = Suite;

/**

* Create a new `Suite` with the given `title`
* and parent `Suite`. When a suite with the
* same title is already present, that suite
* is returned to provide nicer reporter
* and more flexible meta-testing.
*
* @param {Suite} parent
* @param {String} title
* @return {Suite}
* @api public
*/

exports.create = function(parent, title){

var suite = new Suite(title, parent.ctx);
suite.parent = parent;
if (parent.pending) suite.pending = true;
title = suite.fullTitle();
parent.addSuite(suite);
return suite;

};

/**

* Initialize a new `Suite` with the given
* `title` and `ctx`.
*
* @param {String} title
* @param {Context} ctx
* @api private
*/

function Suite(title, parentContext) {

this.title = title;
var context = function() {};
context.prototype = parentContext;
this.ctx = new context();
this.suites = [];
this.tests = [];
this.pending = false;
this._beforeEach = [];
this._beforeAll = [];
this._afterEach = [];
this._afterAll = [];
this.root = !title;
this._timeout = 2000;
this._enableTimeouts = true;
this._slow = 75;
this._bail = false;

}

/**

* Inherit from `EventEmitter.prototype`.
*/

function F(){}; F.prototype = EventEmitter.prototype; Suite.prototype = new F; Suite.prototype.constructor = Suite;

/**

* Return a clone of this `Suite`.
*
* @return {Suite}
* @api private
*/

Suite.prototype.clone = function(){

var suite = new Suite(this.title);
debug('clone');
suite.ctx = this.ctx;
suite.timeout(this.timeout());
suite.enableTimeouts(this.enableTimeouts());
suite.slow(this.slow());
suite.bail(this.bail());
return suite;

};

/**

* Set timeout `ms` or short-hand such as "2s".
*
* @param {Number|String} ms
* @return {Suite|Number} for chaining
* @api private
*/

Suite.prototype.timeout = function(ms){

if (0 == arguments.length) return this._timeout;
if (ms.toString() === '0') this._enableTimeouts = false;
if ('string' == typeof ms) ms = milliseconds(ms);
debug('timeout %d', ms);
this._timeout = parseInt(ms, 10);
return this;

};

/**

* Set timeout `enabled`.
*
* @param {Boolean} enabled
* @return {Suite|Boolean} self or enabled
* @api private
*/

Suite.prototype.enableTimeouts = function(enabled){

if (arguments.length === 0) return this._enableTimeouts;
debug('enableTimeouts %s', enabled);
this._enableTimeouts = enabled;
return this;

};

/**

* Set slow `ms` or short-hand such as "2s".
*
* @param {Number|String} ms
* @return {Suite|Number} for chaining
* @api private
*/

Suite.prototype.slow = function(ms){

if (0 === arguments.length) return this._slow;
if ('string' == typeof ms) ms = milliseconds(ms);
debug('slow %d', ms);
this._slow = ms;
return this;

};

/**

* Sets whether to bail after first error.
*
* @param {Boolean} bail
* @return {Suite|Number} for chaining
* @api private
*/

Suite.prototype.bail = function(bail){

if (0 == arguments.length) return this._bail;
debug('bail %s', bail);
this._bail = bail;
return this;

};

/**

* Run `fn(test[, done])` before running tests.
*
* @param {Function} fn
* @return {Suite} for chaining
* @api private
*/

Suite.prototype.beforeAll = function(title, fn){

if (this.pending) return this;
if ('function' === typeof title) {
  fn = title;
  title = fn.name;
}
title = '"before all" hook' + (title ? ': ' + title : '');

var hook = new Hook(title, fn);
hook.parent = this;
hook.timeout(this.timeout());
hook.enableTimeouts(this.enableTimeouts());
hook.slow(this.slow());
hook.ctx = this.ctx;
this._beforeAll.push(hook);
this.emit('beforeAll', hook);
return this;

};

/**

* Run `fn(test[, done])` after running tests.
*
* @param {Function} fn
* @return {Suite} for chaining
* @api private
*/

Suite.prototype.afterAll = function(title, fn){

if (this.pending) return this;
if ('function' === typeof title) {
  fn = title;
  title = fn.name;
}
title = '"after all" hook' + (title ? ': ' + title : '');

var hook = new Hook(title, fn);
hook.parent = this;
hook.timeout(this.timeout());
hook.enableTimeouts(this.enableTimeouts());
hook.slow(this.slow());
hook.ctx = this.ctx;
this._afterAll.push(hook);
this.emit('afterAll', hook);
return this;

};

/**

* Run `fn(test[, done])` before each test case.
*
* @param {Function} fn
* @return {Suite} for chaining
* @api private
*/

Suite.prototype.beforeEach = function(title, fn){

if (this.pending) return this;
if ('function' === typeof title) {
  fn = title;
  title = fn.name;
}
title = '"before each" hook' + (title ? ': ' + title : '');

var hook = new Hook(title, fn);
hook.parent = this;
hook.timeout(this.timeout());
hook.enableTimeouts(this.enableTimeouts());
hook.slow(this.slow());
hook.ctx = this.ctx;
this._beforeEach.push(hook);
this.emit('beforeEach', hook);
return this;

};

/**

* Run `fn(test[, done])` after each test case.
*
* @param {Function} fn
* @return {Suite} for chaining
* @api private
*/

Suite.prototype.afterEach = function(title, fn){

if (this.pending) return this;
if ('function' === typeof title) {
  fn = title;
  title = fn.name;
}
title = '"after each" hook' + (title ? ': ' + title : '');

var hook = new Hook(title, fn);
hook.parent = this;
hook.timeout(this.timeout());
hook.enableTimeouts(this.enableTimeouts());
hook.slow(this.slow());
hook.ctx = this.ctx;
this._afterEach.push(hook);
this.emit('afterEach', hook);
return this;

};

/**

* Add a test `suite`.
*
* @param {Suite} suite
* @return {Suite} for chaining
* @api private
*/

Suite.prototype.addSuite = function(suite){

suite.parent = this;
suite.timeout(this.timeout());
suite.enableTimeouts(this.enableTimeouts());
suite.slow(this.slow());
suite.bail(this.bail());
this.suites.push(suite);
this.emit('suite', suite);
return this;

};

/**

* Add a `test` to this suite.
*
* @param {Test} test
* @return {Suite} for chaining
* @api private
*/

Suite.prototype.addTest = function(test){

test.parent = this;
test.timeout(this.timeout());
test.enableTimeouts(this.enableTimeouts());
test.slow(this.slow());
test.ctx = this.ctx;
this.tests.push(test);
this.emit('test', test);
return this;

};

/**

* Return the full title generated by recursively
* concatenating the parent's full title.
*
* @return {String}
* @api public
*/

Suite.prototype.fullTitle = function(){

if (this.parent) {
  var full = this.parent.fullTitle();
  if (full) return full + ' ' + this.title;
}
return this.title;

};

/**

* Return the total number of tests.
*
* @return {Number}
* @api public
*/

Suite.prototype.total = function(){

return utils.reduce(this.suites, function(sum, suite){
  return sum + suite.total();
}, 0) + this.tests.length;

};

/**

* Iterates through each suite recursively to find
* all tests. Applies a function in the format
* `fn(test)`.
*
* @param {Function} fn
* @return {Suite}
* @api private
*/

Suite.prototype.eachTest = function(fn){

utils.forEach(this.tests, fn);
utils.forEach(this.suites, function(suite){
  suite.eachTest(fn);
});
return this;

};

}); // module: suite.js

require.register(“test.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var Runnable = require('./runnable');

/**

* Expose `Test`.
*/

module.exports = Test;

/**

* Initialize a new `Test` with the given `title` and callback `fn`.
*
* @param {String} title
* @param {Function} fn
* @api private
*/

function Test(title, fn) {

Runnable.call(this, title, fn);
this.pending = !fn;
this.type = 'test';

}

/**

* Inherit from `Runnable.prototype`.
*/

function F(){}; F.prototype = Runnable.prototype; Test.prototype = new F; Test.prototype.constructor = Test;

}); // module: test.js

require.register(“utils.js”, function(module, exports, require){ /**

* Module dependencies.
*/

var fs = require('browser/fs')

, path = require('browser/path')
, basename = path.basename
, exists = fs.existsSync || path.existsSync
, glob = require('browser/glob')
, join = path.join
, debug = require('browser/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(/&/g, '&amp;')
  .replace(/"/g, '&quot;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;');

};

/**

* 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));
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);
  });
});

};

/**

* 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, '&lt;')
  .replace(/>/g, '&gt;')
  .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 prop,
  type = exports.type(value);

if (type === 'null' || type === 'undefined') {
  return '[' + type + ']';
}

if (type === 'date') {
  return '[Date: ' + value.toISOString() + ']';
}

if (!~exports.indexOf(['object', 'array', 'function'], type)) {
  return value.toString();
}

for (prop in value) {
  if (value.hasOwnProperty(prop)) {
    return JSON.stringify(exports.canonicalize(value), null, 2).replace(/,(\n|$)/g, '$1');
  }
}

return emptyRepresentation(value, type);

};

/**

* 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':
    canonicalizedObj = '[undefined]';
    break;
  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 'date':
    canonicalizedObj = '[Date: ' + value.toISOString() + ']';
    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 'number':
  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();

};

}); // module: utils.js // The global object is “self” in Web Workers. var global = (function() { return this; })();

/**

* Save timer references to avoid Sinon interfering (see GH-237).
*/

var Date = global.Date; var setTimeout = global.setTimeout; var setInterval = global.setInterval; var clearTimeout = global.clearTimeout; var clearInterval = global.clearInterval;

/**

* Node shims.
*
* These are meant only to allow
* mocha.js to run untouched, not
* to allow running node code in
* the browser.
*/

var process = {}; process.exit = function(status){}; process.stdout = {};

var uncaughtExceptionHandlers = [];

var originalOnerrorHandler = global.onerror;

/**

* Remove uncaughtException listener.
* Revert to original onerror handler if previously defined.
*/

process.removeListener = function(e, fn){

if ('uncaughtException' == e) {
  if (originalOnerrorHandler) {
    global.onerror = originalOnerrorHandler;
  } else {
    global.onerror = function() {};
  }
  var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn);
  if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); }
}

};

/**

* Implements uncaughtException listener.
*/

process.on = function(e, fn){

if ('uncaughtException' == e) {
  global.onerror = function(err, url, line){
    fn(new Error(err + ' (' + url + ':' + line + ')'));
    return true;
  };
  uncaughtExceptionHandlers.push(fn);
}

};

/**

* Expose mocha.
*/

var Mocha = global.Mocha = require('mocha'),

mocha = global.mocha = new Mocha({ reporter: 'html' });

// The BDD UI is registered by default, but no UI will be functional in the // browser without an explicit call to the overridden `mocha.ui` (see below). // Ensure that this default UI does not expose its methods to the global scope. mocha.suite.removeAllListeners('pre-require');

var immediateQueue = []

, immediateTimeout;

function timeslice() {

var immediateStart = new Date().getTime();
while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) {
  immediateQueue.shift()();
}
if (immediateQueue.length) {
  immediateTimeout = setTimeout(timeslice, 0);
} else {
  immediateTimeout = null;
}

}

/**

* High-performance override of Runner.immediately.
*/

Mocha.Runner.immediately = function(callback) {

immediateQueue.push(callback);
if (!immediateTimeout) {
  immediateTimeout = setTimeout(timeslice, 0);
}

};

/**

* Function to allow assertion libraries to throw errors directly into mocha.
* This is useful when running tests in a browser because window.onerror will
* only receive the 'message' attribute of the Error.
*/

mocha.throwError = function(err) {

Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) {
  fn(err);
});
throw err;

};

/**

* Override ui to ensure that the ui functions are initialized.
* Normally this would happen in Mocha.prototype.loadFiles.
*/

mocha.ui = function(ui){

Mocha.prototype.ui.call(this, ui);
this.suite.emit('pre-require', global, null, this);
return this;

};

/**

* Setup mocha with the given setting options.
*/

mocha.setup = function(opts){

if ('string' == typeof opts) opts = { ui: opts };
for (var opt in opts) this[opt](opts[opt]);
return this;

};

/**

* Run mocha, returning the Runner.
*/

mocha.run = function(fn){

var options = mocha.options;
mocha.globals('location');

var query = Mocha.utils.parseQuery(global.location.search || '');
if (query.grep) mocha.grep(query.grep);
if (query.invert) mocha.invert();

return Mocha.prototype.run.call(mocha, function(err){
  // The DOM Document is not available in Web Workers.
  var document = global.document;
  if (document && document.getElementById('mocha') && options.noHighlighting !== true) {
    Mocha.utils.highlightTags('code');
  }
  if (fn) fn(err);
});

};

/**

* Expose the process shim.
*/

Mocha.process = process; })();