...

среда, 30 декабря 2015 г.

Sinon.js — mock-библиотека для JavaScript

(function (root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define('sinon', [], function () {
return (root.sinon = factory());
});
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.sinon = factory();
}
}(this, function () {
'use strict';
var samsam, formatio, lolex;
(function () {
function define(mod, deps, fn) {
if (mod == «samsam») {
samsam = deps();
} else if (typeof deps === «function» && mod.length === 0) {
lolex = deps();
} else if (typeof fn === «function») {
formatio = fn(samsam);
}
}
define.amd = {};
((typeof define === «function» && define.amd && function (m) { define(«samsam», m); }) ||
(typeof module === «object» &&
function (m) { module.exports = m(); }) || // Node
function (m) { this.samsam = m(); } // Browser globals
)(function () {
var o = Object.prototype;
var div = typeof document !== «undefined» && document.createElement(«div»);

function isNaN(value) {
// Unlike global isNaN, this avoids type coercion
// typeof check avoids IE host object issues, hat tip to
// lodash
var val = value; // JsLint thinks value !== value is «weird»
return typeof value === «number» && value !== val;
}

function getClass(value) {
// Returns the internal [[Class]] by calling Object.prototype.toString
// with the provided value as this. Return value is a string, naming the
// internal class, e.g. «Array»
return o.toString.call(value).split(/[ \]]/)[1];
}

/**
* name samsam.isArguments
* param Object object
*
* Returns ``true`` if ``object`` is an ``arguments`` object,
* ``false`` otherwise.
*/
function isArguments(object) {
if (getClass(object) === 'Arguments') { return true; }
if (typeof object !== «object» || typeof object.length !== «number» ||
getClass(object) === «Array») {
return false;
}
if (typeof object.callee == «function») { return true; }
try {
object[object.length] = 6;
delete object[object.length];
} catch (e) {
return true;
}
return false;
}

/**
* name samsam.isElement
* param Object object
*
* Returns ``true`` if ``object`` is a DOM element node. Unlike
* Underscore.js/lodash, this function will return ``false`` if ``object``
* is an *element-like* object, i.e. a regular object with a ``nodeType``
* property that holds the value ``1``.
*/
function isElement(object) {
if (!object || object.nodeType !== 1 || !div) { return false; }
try {
object.appendChild(div);
object.removeChild(div);
} catch (e) {
return false;
}
return true;
}

/**
* name samsam.keys
* param Object object
*
* Return an array of own property names.
*/
function keys(object) {
var ks = [], prop;
for (prop in object) {
if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
}
return ks;
}

/**
* name samsam.isDate
* param Object value
*
* Returns true if the object is a ``Date``, or *date-like*. Duck typing
* of date objects work by checking that the object has a ``getTime``
* function whose return value equals the return value from the object's
* ``valueOf``.
*/
function isDate(value) {
return typeof value.getTime == «function» &&
value.getTime() == value.valueOf();
}

/**
* name samsam.isNegZero
* param Object value
*
* Returns ``true`` if ``value`` is ``-0``.
*/
function isNegZero(value) {
return value === 0 && 1 / value === -Infinity;
}

/**
* name samsam.equal
* param Object obj1
* param Object obj2
*
* Returns ``true`` if two objects are strictly equal. Compared to
* ``===`` there are two exceptions:
*
* — NaN is considered equal to NaN
* — -0 and +0 are not considered equal
*/
function identical(obj1, obj2) {
if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
}
}

/**
* name samsam.deepEqual
* param Object obj1
* param Object obj2
*
* Deep equal comparison. Two values are «deep equal» if:
*
* — They are equal, according to samsam.identical
* — They are both date objects representing the same time
* — They are both arrays containing elements that are all deepEqual
* — They are objects with the same set of properties, and each property
* in ``obj1`` is deepEqual to the corresponding property in ``obj2``
*
* Supports cyclic objects.
*/
function deepEqualCyclic(obj1, obj2) {

// used for cyclic comparison
// contain already visited objects
var objects1 = [],
objects2 = [],
// contain pathes (position in the object structure)
// of the already visited objects
// indexes same as in objects arrays
paths1 = [],
paths2 = [],
// contains combinations of already compared objects
// in the manner: { "$1['ref']$2['ref']": true }
compared = {};

/**
* used to check, if the value of a property is an object
* (cyclic logic is only needed for objects)
* only needed for cyclic logic
*/
function isObject(value) {

if (typeof value === 'object' && value !== null &&
!(value instanceof Boolean) &&
!(value instanceof Date) &&
!(value instanceof Number) &&
!(value instanceof RegExp) &&
!(value instanceof String)) {

return true;
}

return false;
}

/**
* returns the index of the given object in the
* given objects array, -1 if not contained
* only needed for cyclic logic
*/
function getIndex(objects, obj) {

var i;
for (i = 0; i < objects.length; i++) {
if (objects[i] === obj) {
return i;
}
}

return -1;
}

// does the recursion for the deep equal check
return (function deepEqual(obj1, obj2, path1, path2) {
var type1 = typeof obj1;
var type2 = typeof obj2;

// == null also matches undefined
if (obj1 === obj2 ||
isNaN(obj1) || isNaN(obj2) ||
obj1 == null || obj2 == null ||
type1 !== «object» || type2 !== «object») {

return identical(obj1, obj2);
}

// Elements are only equal if identical(expected, actual)
if (isElement(obj1) || isElement(obj2)) { return false; }

var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
if (isDate1 || isDate2) {
if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
return false;
}
}

if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
if (obj1.toString() !== obj2.toString()) { return false; }
}

var class1 = getClass(obj1);
var class2 = getClass(obj2);
var keys1 = keys(obj1);
var keys2 = keys(obj2);

if (isArguments(obj1) || isArguments(obj2)) {
if (obj1.length !== obj2.length) { return false; }
} else {
if (type1 !== type2 || class1 !== class2 ||
keys1.length !== keys2.length) {
return false;
}
}

var key, i, l,
// following vars are used for the cyclic logic
value1, value2,
isObject1, isObject2,
index1, index2,
newPath1, newPath2;

for (i = 0, l = keys1.length; i < l; i++) {
key = keys1[i];
if (!o.hasOwnProperty.call(obj2, key)) {
return false;
}

// Start of the cyclic logic

value1 = obj1[key];
value2 = obj2[key];

isObject1 = isObject(value1);
isObject2 = isObject(value2);

// determine, if the objects were already visited
// (it's faster to check for isObject first, than to
// get -1 from getIndex for non objects)
index1 = isObject1? getIndex(objects1, value1): -1;
index2 = isObject2? getIndex(objects2, value2): -1;

// determine the new pathes of the objects
// — for non cyclic objects the current path will be extended
// by current property name
// — for cyclic objects the stored path is taken
newPath1 = index1 !== -1
? paths1[index1]
: path1 + '[' + JSON.stringify(key) + ']';
newPath2 = index2 !== -1
? paths2[index2]
: path2 + '[' + JSON.stringify(key) + ']';

// stop recursion if current objects are already compared
if (compared[newPath1 + newPath2]) {
return true;
}

// remember the current objects and their pathes
if (index1 === -1 && isObject1) {
objects1.push(value1);
paths1.push(newPath1);
}
if (index2 === -1 && isObject2) {
objects2.push(value2);
paths2.push(newPath2);
}

// remember that the current objects are already compared
if (isObject1 && isObject2) {
compared[newPath1 + newPath2] = true;
}

// End of cyclic logic

// neither value1 nor value2 is a cycle
// continue with next level
if (!deepEqual(value1, value2, newPath1, newPath2)) {
return false;
}
}

return true;

}(obj1, obj2, '$1', '$2'));
}

var match;

function arrayContains(array, subset) {
if (subset.length === 0) { return true; }
var i, l, j, k;
for (i = 0, l = array.length; i < l; ++i) {
if (match(array[i], subset[0])) {
for (j = 0, k = subset.length; j < k; ++j) {
if (!match(array[i + j], subset[j])) { return false; }
}
return true;
}
}
return false;
}

/**
* name samsam.match
* param Object object
* param Object matcher
*
* Compare arbitrary value ``object`` with matcher.
*/
match = function match(object, matcher) {
if (matcher && typeof matcher.test === «function») {
return matcher.test(object);
}

if (typeof matcher === «function») {
return matcher(object) === true;
}

if (typeof matcher === «string») {
matcher = matcher.toLowerCase();
var notNull = typeof object === «string» || !!object;
return notNull &&
(String(object)).toLowerCase().indexOf(matcher) >= 0;
}

if (typeof matcher === «number») {
return matcher === object;
}

if (typeof matcher === «boolean») {
return matcher === object;
}

if (typeof(matcher) === «undefined») {
return typeof(object) === «undefined»;
}

if (matcher === null) {
return object === null;
}

if (getClass(object) === «Array» && getClass(matcher) === «Array») {
return arrayContains(object, matcher);
}

if (matcher && typeof matcher === «object») {
if (matcher === object) {
return true;
}
var prop;
for (prop in matcher) {
var value = object[prop];
if (typeof value === «undefined» &&
typeof object.getAttribute === «function») {
value = object.getAttribute(prop);
}
if (matcher[prop] === null || typeof matcher[prop] === 'undefined') {
if (value !== matcher[prop]) {
return false;
}
} else if (typeof value === «undefined» || !match(value, matcher[prop])) {
return false;
}
}
return true;
}

throw new Error(«Matcher was not a string, a number, a » +
«function, a boolean or an object»);
};

return {
isArguments: isArguments,
isElement: isElement,
isDate: isDate,
isNegZero: isNegZero,
identical: identical,
deepEqual: deepEqualCyclic,
match: match,
keys: keys
};
});
((typeof define === «function» && define.amd && function (m) {
define(«formatio», [«samsam»], m);
}) || (typeof module === «object» && function (m) {
module.exports = m(require(«samsam»));
}) || function (m) { this.formatio = m(this.samsam); }
)(function (samsam) {

var formatio = {
excludeConstructors: [«Object», /^.$/],
quoteStrings: true,
limitChildrenCount: 0
};

var hasOwn = Object.prototype.hasOwnProperty;

var specialObjects = [];
if (typeof global !== «undefined») {
specialObjects.push({ object: global, value: "[object global]" });
}
if (typeof document !== «undefined») {
specialObjects.push({
object: document,
value: "[object HTMLDocument]"
});
}
if (typeof window !== «undefined») {
specialObjects.push({ object: window, value: "[object Window]" });
}

function functionName(func) {
if (!func) { return ""; }
if (func.displayName) { return func.displayName; }
if (func.name) { return func.name; }
var matches = func.toString().match(/function\s+([^\(]+)/m);
return (matches && matches[1]) || "";
}

function constructorName(f, object) {
var name = functionName(object && object.constructor);
var excludes = f.excludeConstructors ||
formatio.excludeConstructors || [];

var i, l;
for (i = 0, l = excludes.length; i < l; ++i) {
if (typeof excludes[i] === «string» && excludes[i] === name) {
return "";
} else if (excludes[i].test && excludes[i].test(name)) {
return "";
}
}

return name;
}

function isCircular(object, objects) {
if (typeof object !== «object») { return false; }
var i, l;
for (i = 0, l = objects.length; i < l; ++i) {
if (objects[i] === object) { return true; }
}
return false;
}

function ascii(f, object, processed, indent) {
if (typeof object === «string») {
var qs = f.quoteStrings;
var quote = typeof qs !== «boolean» || qs;
return processed || quote? '"' + object + '"': object;
}

if (typeof object === «function» && !(object instanceof RegExp)) {
return ascii.func(object);
}

processed = processed || [];

if (isCircular(object, processed)) { return "[Circular]"; }

if (Object.prototype.toString.call(object) === "[object Array]") {
return ascii.array.call(f, object, processed);
}

if (!object) { return String((1/object) === -Infinity? "-0": object); }
if (samsam.isElement(object)) { return ascii.element(object); }

if (typeof object.toString === «function» &&
object.toString !== Object.prototype.toString) {
return object.toString();
}

var i, l;
for (i = 0, l = specialObjects.length; i < l; i++) {
if (object === specialObjects[i].object) {
return specialObjects[i].value;
}
}

return ascii.object.call(f, object, processed, indent);
}

ascii.func = function (func) {
return «function » + functionName(func) + "() {}";
};

ascii.array = function (array, processed) {
processed = processed || [];
processed.push(array);
var pieces = [];
var i, l;
l = (this.limitChildrenCount > 0)?
Math.min(this.limitChildrenCount, array.length): array.length;

for (i = 0; i < l; ++i) {
pieces.push(ascii(this, array[i], processed));
}

if(l < array.length)
pieces.push("[… " + (array.length — l) + " more elements]");

return "[" + pieces.join(", ") + "]";
};

ascii.object = function (object, processed, indent) {
processed = processed || [];
processed.push(object);
indent = indent || 0;
var pieces = [], properties = samsam.keys(object).sort();
var length = 3;
var prop, str, obj, i, k, l;
l = (this.limitChildrenCount > 0)?
Math.min(this.limitChildrenCount, properties.length): properties.length;

for (i = 0; i < l; ++i) {
prop = properties[i];
obj = object[prop];

if (isCircular(obj, processed)) {
str = "[Circular]";
} else {
str = ascii(this, obj, processed, indent + 2);
}

str = (/\s/.test(prop)? '"' + prop + '"': prop) + ": " + str;
length += str.length;
pieces.push(str);
}

var cons = constructorName(this, object);
var prefix = cons? "[" + cons + "] ": "";
var is = "";
for (i = 0, k = indent; i < k; ++i) { is += " "; }

if(l < properties.length)
pieces.push("[… " + (properties.length — l) + " more elements]");

if (length + indent > 80) {
return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
is + "}";
}
return prefix + "{ " + pieces.join(", ") + " }";
};

ascii.element = function (element) {
var tagName = element.tagName.toLowerCase();
var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;

for (i = 0, l = attrs.length; i < l; ++i) {
attr = attrs.item(i);
attrName = attr.nodeName.toLowerCase().replace(«html:», "");
val = attr.nodeValue;
if (attrName !== «contenteditable» || val !== «inherit») {
if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
}
}

var formatted = "<" + tagName + (pairs.length > 0? " ": "");
var content = element.innerHTML;

if (content.length > 20) {
content = content.substr(0, 20) + "[...]";
}

var res = formatted + pairs.join(" ") + ">" + content +
"</" + tagName + ">";

return res.replace(/ contentEditable=«inherit»/, "");
};

function Formatio(options) {
for (var opt in options) {
this[opt] = options[opt];
}
}

Formatio.prototype = {
functionName: functionName,

configure: function (options) {
return new Formatio(options);
},

constructorName: function (object) {
return constructorName(this, object);
},

ascii: function (object, processed, indent) {
return ascii(this, object, processed, indent);
}
};

return Formatio.prototype;
});
!function(e){if(«object»==typeof exports&&«undefined»!=typeof module)module.exports=e();else if(«function»==typeof define&&define.amd)define([],e);else{var f;«undefined»!=typeof window?f=window:«undefined»!=typeof global?f=global:«undefined»!=typeof self&&(f=self),f.lolex=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==«function»&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(«Cannot find module '»+o+"'");throw f.code=«MODULE_NOT_FOUND»,f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==«function»&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (global){
/*global global, window*/
/**
* author Christian Johansen (christian@cjohansen.no) and contributors
* @license BSD
*
* Copyright 2010-2014 Christian Johansen
*/

(function (global) {

// Make properties writable in IE, as per
// http://ift.tt/1onKDPu
// JSLint being anal
var glbl = global;

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

// setImmediate is not a standard function
// avoid adding the prop to the window object if not present
if('setImmediate' in global) {
global.setImmediate = glbl.setImmediate;
global.clearImmediate = glbl.clearImmediate;
}

// node expects setTimeout/setInterval to return a fn object w/ .ref()/.unref()
// browsers, a number.
// see http://ift.tt/1OxLagj

var NOOP = function () { return undefined; };
var timeoutResult = setTimeout(NOOP, 0);
var addTimerReturnsObject = typeof timeoutResult === «object»;
clearTimeout(timeoutResult);

var NativeDate = Date;
var uniqueTimerId = 1;

/**
* Parse strings like «01:10:00» (meaning 1 hour, 10 minutes, 0 seconds) into
* number of milliseconds. This is used to support human-readable strings passed
* to clock.tick()
*/
function parseTime(str) {
if (!str) {
return 0;
}

var strings = str.split(":");
var l = strings.length, i = l;
var ms = 0, parsed;

if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
throw new Error(«tick only understands numbers and 'h:m:s'»);
}

while (i--) {
parsed = parseInt(strings[i], 10);

if (parsed >= 60) {
throw new Error(«Invalid time » + str);
}

ms += parsed * Math.pow(60, (l — i — 1));
}

return ms * 1000;
}

/**
* Used to grok the `now` parameter to createClock.
*/
function getEpoch(epoch) {
if (!epoch) { return 0; }
if (typeof epoch.getTime === «function») { return epoch.getTime(); }
if (typeof epoch === «number») { return epoch; }
throw new TypeError(«now should be milliseconds since UNIX epoch»);
}

function inRange(from, to, timer) {
return timer && timer.callAt >= from && timer.callAt <= to;
}

function mirrorDateProperties(target, source) {
var prop;
for (prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}

// set special now implementation
if (source.now) {
target.now = function now() {
return target.clock.now;
};
} else {
delete target.now;
}

// set special toSource implementation
if (source.toSource) {
target.toSource = function toSource() {
return source.toSource();
};
} else {
delete target.toSource;
}

// set special toString implementation
target.toString = function toString() {
return source.toString();
};

target.prototype = source.prototype;
target.parse = source.parse;
target.UTC = source.UTC;
target.prototype.toUTCString = source.prototype.toUTCString;

return target;
}

function createDate() {
function ClockDate(year, month, date, hour, minute, second, ms) {
// Defensive and verbose to avoid potential harm in passing
// explicit undefined when user does not pass argument
switch (arguments.length) {
case 0:
return new NativeDate(ClockDate.clock.now);
case 1:
return new NativeDate(year);
case 2:
return new NativeDate(year, month);
case 3:
return new NativeDate(year, month, date);
case 4:
return new NativeDate(year, month, date, hour);
case 5:
return new NativeDate(year, month, date, hour, minute);
case 6:
return new NativeDate(year, month, date, hour, minute, second);
default:
return new NativeDate(year, month, date, hour, minute, second, ms);
}
}

return mirrorDateProperties(ClockDate, NativeDate);
}

function addTimer(clock, timer) {
if (timer.func === undefined) {
throw new Error(«Callback must be provided to timer calls»);
}

if (!clock.timers) {
clock.timers = {};
}

timer.id = uniqueTimerId++;
timer.createdAt = clock.now;
timer.callAt = clock.now + (timer.delay || (clock.duringTick? 1: 0));

clock.timers[timer.id] = timer;

if (addTimerReturnsObject) {
return {
id: timer.id,
ref: NOOP,
unref: NOOP
};
}

return timer.id;
}

function compareTimers(a, b) {
// Sort first by absolute timing
if (a.callAt < b.callAt) {
return -1;
}
if (a.callAt > b.callAt) {
return 1;
}

// Sort next by immediate, immediate timers take precedence
if (a.immediate && !b.immediate) {
return -1;
}
if (!a.immediate && b.immediate) {
return 1;
}

// Sort next by creation time, earlier-created timers take precedence
if (a.createdAt < b.createdAt) {
return -1;
}
if (a.createdAt > b.createdAt) {
return 1;
}

// Sort next by id, lower-id timers take precedence
if (a.id < b.id) {
return -1;
}
if (a.id > b.id) {
return 1;
}

// As timer ids are unique, no fallback `0` is necessary
}

function firstTimerInRange(clock, from, to) {
var timers = clock.timers,
timer = null,
id,
isInRange;

for (id in timers) {
if (timers.hasOwnProperty(id)) {
isInRange = inRange(from, to, timers[id]);

if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) {
timer = timers[id];
}
}
}

return timer;
}

function callTimer(clock, timer) {
var exception;

if (typeof timer.interval === «number») {
clock.timers[timer.id].callAt += timer.interval;
} else {
delete clock.timers[timer.id];
}

try {
if (typeof timer.func === «function») {
timer.func.apply(null, timer.args);
} else {
eval(timer.func);
}
} catch (e) {
exception = e;
}

if (!clock.timers[timer.id]) {
if (exception) {
throw exception;
}
return;
}

if (exception) {
throw exception;
}
}

function timerType(timer) {
if (timer.immediate) {
return «Immediate»;
} else if (typeof timer.interval !== «undefined») {
return «Interval»;
} else {
return «Timeout»;
}
}

function clearTimer(clock, timerId, ttype) {
if (!timerId) {
// null appears to be allowed in most browsers, and appears to be
// relied upon by some libraries, like Bootstrap carousel
return;
}

if (!clock.timers) {
clock.timers = [];
}

// in Node, timerId is an object with .ref()/.unref(), and
// its .id field is the actual timer id.
if (typeof timerId === «object») {
timerId = timerId.id;
}

if (clock.timers.hasOwnProperty(timerId)) {
// check that the ID matches a timer of the correct type
var timer = clock.timers[timerId];
if (timerType(timer) === ttype) {
delete clock.timers[timerId];
} else {
throw new Error(«Cannot clear timer: timer created with set» + ttype + "() but cleared with clear" + timerType(timer) + "()");
}
}
}

function uninstall(clock, target) {
var method,
i,
l;

for (i = 0, l = clock.methods.length; i < l; i++) {
method = clock.methods[i];

if (target[method].hadOwnProperty) {
target[method] = clock["_" + method];
} else {
try {
delete target[method];
} catch (ignore) {}
}
}

// Prevent multiple executions which will completely remove these props
clock.methods = [];
}

function hijackMethod(target, method, clock) {
var prop;

clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
clock["_" + method] = target[method];

if (method === «Date») {
var date = mirrorDateProperties(clock[method], target[method]);
target[method] = date;
} else {
target[method] = function () {
return clock[method].apply(clock, arguments);
};

for (prop in clock[method]) {
if (clock[method].hasOwnProperty(prop)) {
target[method][prop] = clock[method][prop];
}
}
}

target[method].clock = clock;
}

var timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setImmediate: global.setImmediate,
clearImmediate: global.clearImmediate,
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};

var keys = Object.keys || function (obj) {
var ks = [],
key;

for (key in obj) {
if (obj.hasOwnProperty(key)) {
ks.push(key);
}
}

return ks;
};

exports.timers = timers;

function createClock(now) {
var clock = {
now: getEpoch(now),
timeouts: {},
Date: createDate()
};

clock.Date.clock = clock;

clock.setTimeout = function setTimeout(func, timeout) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay: timeout
});
};

clock.clearTimeout = function clearTimeout(timerId) {
return clearTimer(clock, timerId, «Timeout»);
};

clock.setInterval = function setInterval(func, timeout) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 2),
delay: timeout,
interval: timeout
});
};

clock.clearInterval = function clearInterval(timerId) {
return clearTimer(clock, timerId, «Interval»);
};

clock.setImmediate = function setImmediate(func) {
return addTimer(clock, {
func: func,
args: Array.prototype.slice.call(arguments, 1),
immediate: true
});
};

clock.clearImmediate = function clearImmediate(timerId) {
return clearTimer(clock, timerId, «Immediate»);
};

clock.tick = function tick(ms) {
ms = typeof ms === «number»? ms: parseTime(ms);
var tickFrom = clock.now, tickTo = clock.now + ms, previous = clock.now;
var timer = firstTimerInRange(clock, tickFrom, tickTo);
var oldNow;

clock.duringTick = true;

var firstException;
while (timer && tickFrom <= tickTo) {
if (clock.timers[timer.id]) {
tickFrom = clock.now = timer.callAt;
try {
oldNow = clock.now;
callTimer(clock, timer);
// compensate for any setSystemTime() call during timer callback
if (oldNow !== clock.now) {
tickFrom += clock.now — oldNow;
tickTo += clock.now — oldNow;
previous += clock.now — oldNow;
}
} catch (e) {
firstException = firstException || e;
}
}

timer = firstTimerInRange(clock, previous, tickTo);
previous = tickFrom;
}

clock.duringTick = false;
clock.now = tickTo;

if (firstException) {
throw firstException;
}

return clock.now;
};

clock.reset = function reset() {
clock.timers = {};
};

clock.setSystemTime = function setSystemTime(now) {
// determine time difference
var newNow = getEpoch(now);
var difference = newNow — clock.now;

// update 'system clock'
clock.now = newNow;

// update timers and intervals to keep them stable
for (var id in clock.timers) {
if (clock.timers.hasOwnProperty(id)) {
var timer = clock.timers[id];
timer.createdAt += difference;
timer.callAt += difference;
}
}
};

return clock;
}
exports.createClock = createClock;

exports.install = function install(target, now, toFake) {
var i,
l;

if (typeof target === «number») {
toFake = now;
now = target;
target = null;
}

if (!target) {
target = global;
}

var clock = createClock(now);

clock.uninstall = function () {
uninstall(clock, target);
};

clock.methods = toFake || [];

if (clock.methods.length === 0) {
clock.methods = keys(timers);
}

for (i = 0, l = clock.methods.length; i < l; i++) {
hijackMethod(target, clock.methods[i], clock);
}

return clock;
};

}(global || this));

}).call(this,typeof global !== «undefined»? global: typeof self !== «undefined»? self: typeof window !== «undefined»? window: {})
},{}]},{},[1])(1)
});
})();
var define;
/**
* Sinon core utilities. For internal use only.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
var sinon = (function () {
«use strict»;
// eslint-disable-line no-unused-vars

var sinonModule;
var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
sinonModule = module.exports = require("./sinon/util/core");
require("./sinon/extend");
require("./sinon/walk");
require("./sinon/typeOf");
require("./sinon/times_in_words");
require("./sinon/spy");
require("./sinon/call");
require("./sinon/behavior");
require("./sinon/stub");
require("./sinon/mock");
require("./sinon/collection");
require("./sinon/assert");
require("./sinon/sandbox");
require("./sinon/test");
require("./sinon/test_case");
require("./sinon/match");
require("./sinon/format");
require("./sinon/log_error");
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require, module.exports, module);
sinonModule = module.exports;
} else {
sinonModule = {};
}

return sinonModule;
}());

/**
* depend ../../sinon.js
*/
/**
* Sinon core utilities. For internal use only.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

var div = typeof document !== «undefined» && document.createElement(«div»);
var hasOwn = Object.prototype.hasOwnProperty;

function isDOMNode(obj) {
var success = false;

try {
obj.appendChild(div);
success = div.parentNode === obj;
} catch (e) {
return false;
} finally {
try {
obj.removeChild(div);
} catch (e) {
// Remove failed, not much we can do about that
}
}

return success;
}

function isElement(obj) {
return div && obj && obj.nodeType === 1 && isDOMNode(obj);
}

function isFunction(obj) {
return typeof obj === «function» || !!(obj && obj.constructor && obj.call && obj.apply);
}

function isReallyNaN(val) {
return typeof val === «number» && isNaN(val);
}

function mirrorProperties(target, source) {
for (var prop in source) {
if (!hasOwn.call(target, prop)) {
target[prop] = source[prop];
}
}
}

function isRestorable(obj) {
return typeof obj === «function» && typeof obj.restore === «function» && obj.restore.sinon;
}

// Cheap way to detect if we have ES5 support.
var hasES5Support = «keys» in Object;

function makeApi(sinon) {
sinon.wrapMethod = function wrapMethod(object, property, method) {
if (!object) {
throw new TypeError(«Should wrap property of object»);
}

if (typeof method !== «function» && typeof method !== «object») {
throw new TypeError(«Method wrapper should be a function or a property descriptor»);
}

function checkWrappedMethod(wrappedMethod) {
var error;

if (!isFunction(wrappedMethod)) {
error = new TypeError(«Attempted to wrap » + (typeof wrappedMethod) + " property " +
property + " as function");
} else if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
error = new TypeError(«Attempted to wrap » + property + " which is already wrapped");
} else if (wrappedMethod.calledBefore) {
var verb = wrappedMethod.returns? «stubbed»: «spied on»;
error = new TypeError(«Attempted to wrap » + property + " which is already " + verb);
}

if (error) {
if (wrappedMethod && wrappedMethod.stackTrace) {
error.stack += "\n--------------\n" + wrappedMethod.stackTrace;
}
throw error;
}
}

var error, wrappedMethod, i;

// IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
// when using hasOwn.call on objects from other frames.
var owned = object.hasOwnProperty? object.hasOwnProperty(property): hasOwn.call(object, property);

if (hasES5Support) {
var methodDesc = (typeof method === «function»)? {value: method}: method;
var wrappedMethodDesc = sinon.getPropertyDescriptor(object, property);

if (!wrappedMethodDesc) {
error = new TypeError(«Attempted to wrap » + (typeof wrappedMethod) + " property " +
property + " as function");
} else if (wrappedMethodDesc.restore && wrappedMethodDesc.restore.sinon) {
error = new TypeError(«Attempted to wrap » + property + " which is already wrapped");
}
if (error) {
if (wrappedMethodDesc && wrappedMethodDesc.stackTrace) {
error.stack += "\n--------------\n" + wrappedMethodDesc.stackTrace;
}
throw error;
}

var types = sinon.objectKeys(methodDesc);
for (i = 0; i < types.length; i++) {
wrappedMethod = wrappedMethodDesc[types[i]];
checkWrappedMethod(wrappedMethod);
}

mirrorProperties(methodDesc, wrappedMethodDesc);
for (i = 0; i < types.length; i++) {
mirrorProperties(methodDesc[types[i]], wrappedMethodDesc[types[i]]);
}
Object.defineProperty(object, property, methodDesc);
} else {
wrappedMethod = object[property];
checkWrappedMethod(wrappedMethod);
object[property] = method;
method.displayName = property;
}

method.displayName = property;

// Set up a stack trace which can be used later to find what line of
// code the original method was created on.
method.stackTrace = (new Error(«Stack Trace for original»)).stack;

method.restore = function () {
// For prototype properties try to reset by delete first.
// If this fails (ex: localStorage on mobile safari) then force a reset
// via direct assignment.
if (!owned) {
// In some cases `delete` may throw an error
try {
delete object[property];
} catch (e) {} // eslint-disable-line no-empty
// For native code functions `delete` fails without throwing an error
// on Chrome < 43, PhantomJS, etc.
} else if (hasES5Support) {
Object.defineProperty(object, property, wrappedMethodDesc);
}

// Use strict equality comparison to check failures then force a reset
// via direct assignment.
if (object[property] === method) {
object[property] = wrappedMethod;
}
};

method.restore.sinon = true;

if (!hasES5Support) {
mirrorProperties(method, wrappedMethod);
}

return method;
};

sinon.create = function create(proto) {
var F = function () {};
F.prototype = proto;
return new F();
};

sinon.deepEqual = function deepEqual(a, b) {
if (sinon.match && sinon.match.isMatcher(a)) {
return a.test(b);
}

if (typeof a !== «object» || typeof b !== «object») {
return isReallyNaN(a) && isReallyNaN(b) || a === b;
}

if (isElement(a) || isElement(b)) {
return a === b;
}

if (a === b) {
return true;
}

if ((a === null && b !== null) || (a !== null && b === null)) {
return false;
}

if (a instanceof RegExp && b instanceof RegExp) {
return (a.source === b.source) && (a.global === b.global) &&
(a.ignoreCase === b.ignoreCase) && (a.multiline === b.multiline);
}

var aString = Object.prototype.toString.call(a);
if (aString !== Object.prototype.toString.call(b)) {
return false;
}

if (aString === "[object Date]") {
return a.valueOf() === b.valueOf();
}

var prop;
var aLength = 0;
var bLength = 0;

if (aString === "[object Array]" && a.length !== b.length) {
return false;
}

for (prop in a) {
if (a.hasOwnProperty(prop)) {
aLength += 1;

if (!(prop in b)) {
return false;
}

if (!deepEqual(a[prop], b[prop])) {
return false;
}
}
}

for (prop in b) {
if (b.hasOwnProperty(prop)) {
bLength += 1;
}
}

return aLength === bLength;
};

sinon.functionName = function functionName(func) {
var name = func.displayName || func.name;

// Use function decomposition as a last resort to get function
// name. Does not rely on function decomposition to work — if it
// doesn't debugging will be slightly less informative
// (i.e. toString will say 'spy' rather than 'myFunc').
if (!name) {
var matches = func.toString().match(/function ([^\s\(]+)/);
name = matches && matches[1];
}

return name;
};

sinon.functionToString = function toString() {
if (this.getCall && this.callCount) {
var thisValue,
prop;
var i = this.callCount;

while (i--) {
thisValue = this.getCall(i).thisValue;

for (prop in thisValue) {
if (thisValue[prop] === this) {
return prop;
}
}
}
}

return this.displayName || «sinon fake»;
};

sinon.objectKeys = function objectKeys(obj) {
if (obj !== Object(obj)) {
throw new TypeError(«sinon.objectKeys called on a non-object»);
}

var keys = [];
var key;
for (key in obj) {
if (hasOwn.call(obj, key)) {
keys.push(key);
}
}

return keys;
};

sinon.getPropertyDescriptor = function getPropertyDescriptor(object, property) {
var proto = object;
var descriptor;

while (proto && !(descriptor = Object.getOwnPropertyDescriptor(proto, property))) {
proto = Object.getPrototypeOf(proto);
}
return descriptor;
};

sinon.getConfig = function (custom) {
var config = {};
custom = custom || {};
var defaults = sinon.defaultConfig;

for (var prop in defaults) {
if (defaults.hasOwnProperty(prop)) {
config[prop] = custom.hasOwnProperty(prop)? custom[prop]: defaults[prop];
}
}

return config;
};

sinon.defaultConfig = {
injectIntoThis: true,
injectInto: null,
properties: [«spy», «stub», «mock», «clock», «server», «requests»],
useFakeTimers: true,
useFakeServer: true
};

sinon.timesInWords = function timesInWords(count) {
return count === 1 && «once» ||
count === 2 && «twice» ||
count === 3 && «thrice» ||
(count || 0) + " times";
};

sinon.calledInOrder = function (spies) {
for (var i = 1, l = spies.length; i < l; i++) {
if (!spies[i — 1].calledBefore(spies[i]) || !spies[i].called) {
return false;
}
}

return true;
};

sinon.orderByFirstCall = function (spies) {
return spies.sort(function (a, b) {
// uuid, won't ever be equal
var aCall = a.getCall(0);
var bCall = b.getCall(0);
var aId = aCall && aCall.callId || -1;
var bId = bCall && bCall.callId || -1;

return aId < bId? -1: 1;
});
};

sinon.createStubInstance = function (constructor) {
if (typeof constructor !== «function») {
throw new TypeError(«The constructor should be a function.»);
}
return sinon.stub(sinon.create(constructor.prototype));
};

sinon.restore = function (object) {
if (object !== null && typeof object === «object») {
for (var prop in object) {
if (isRestorable(object[prop])) {
object[prop].restore();
}
}
} else if (isRestorable(object)) {
object.restore();
}
};

return sinon;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports) {
makeApi(exports);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
*/
(function (sinonGlobal) {

function makeApi(sinon) {

// Adapted from http://ift.tt/1NRijjA
var hasDontEnumBug = (function () {
var obj = {
constructor: function () {
return «0»;
},
toString: function () {
return «1»;
},
valueOf: function () {
return «2»;
},
toLocaleString: function () {
return «3»;
},
prototype: function () {
return «4»;
},
isPrototypeOf: function () {
return «5»;
},
propertyIsEnumerable: function () {
return «6»;
},
hasOwnProperty: function () {
return «7»;
},
length: function () {
return «8»;
},
unique: function () {
return «9»;
}
};

var result = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
result.push(obj[prop]());
}
}
return result.join("") !== «0123456789»;
})();

/* Public: Extend target in place with all (own) properties from sources in-order. Thus, last source will
* override properties in previous sources.
*
* target — The Object to extend
* sources — Objects to copy properties from.
*
* Returns the extended target
*/
function extend(target /*, sources */) {
var sources = Array.prototype.slice.call(arguments, 1);
var source, i, prop;

for (i = 0; i < sources.length; i++) {
source = sources[i];

for (prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}

// Make sure we copy (own) toString method even when in JScript with DontEnum bug
// See http://ift.tt/1NRijjA
if (hasDontEnumBug && source.hasOwnProperty(«toString») && source.toString !== target.toString) {
target.toString = source.toString;
}
}

return target;
}

sinon.extend = extend;
return sinon.extend;
}

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
module.exports = makeApi(sinon);
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
*/
(function (sinonGlobal) {

function makeApi(sinon) {

function timesInWords(count) {
switch (count) {
case 1:
return «once»;
case 2:
return «twice»;
case 3:
return «thrice»;
default:
return (count || 0) + " times";
}
}

sinon.timesInWords = timesInWords;
return sinon.timesInWords;
}

function loadDependencies(require, exports, module) {
var core = require("./util/core");
module.exports = makeApi(core);
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
*/
/**
* Format functions
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2014 Christian Johansen
*/
(function (sinonGlobal) {

function makeApi(sinon) {
function typeOf(value) {
if (value === null) {
return «null»;
} else if (value === undefined) {
return «undefined»;
}
var string = Object.prototype.toString.call(value);
return string.substring(8, string.length — 1).toLowerCase();
}

sinon.typeOf = typeOf;
return sinon.typeOf;
}

function loadDependencies(require, exports, module) {
var core = require("./util/core");
module.exports = makeApi(core);
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
* depend typeOf.js
*/
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
/*global module, require, sinon*/
/**
* Match functions
*
* author Maximilian Antoni (mail@maxantoni.de)
* @license BSD
*
* Copyright 2012 Maximilian Antoni
*/
(function (sinonGlobal) {

function makeApi(sinon) {
function assertType(value, type, name) {
var actual = sinon.typeOf(value);
if (actual !== type) {
throw new TypeError(«Expected type of » + name + " to be " +
type + ", but was " + actual);
}
}

var matcher = {
toString: function () {
return this.message;
}
};

function isMatcher(object) {
return matcher.isPrototypeOf(object);
}

function matchObject(expectation, actual) {
if (actual === null || actual === undefined) {
return false;
}
for (var key in expectation) {
if (expectation.hasOwnProperty(key)) {
var exp = expectation[key];
var act = actual[key];
if (isMatcher(exp)) {
if (!exp.test(act)) {
return false;
}
} else if (sinon.typeOf(exp) === «object») {
if (!matchObject(exp, act)) {
return false;
}
} else if (!sinon.deepEqual(exp, act)) {
return false;
}
}
}
return true;
}

function match(expectation, message) {
var m = sinon.create(matcher);
var type = sinon.typeOf(expectation);
switch (type) {
case «object»:
if (typeof expectation.test === «function») {
m.test = function (actual) {
return expectation.test(actual) === true;
};
m.message = «match(» + sinon.functionName(expectation.test) + ")";
return m;
}
var str = [];
for (var key in expectation) {
if (expectation.hasOwnProperty(key)) {
str.push(key + ": " + expectation[key]);
}
}
m.test = function (actual) {
return matchObject(expectation, actual);
};
m.message = «match(» + str.join(", ") + ")";
break;
case «number»:
m.test = function (actual) {
// we need type coercion here
return expectation == actual; // eslint-disable-line eqeqeq
};
break;
case «string»:
m.test = function (actual) {
if (typeof actual !== «string») {
return false;
}
return actual.indexOf(expectation) !== -1;
};
m.message = «match(\»" + expectation + "\")";
break;
case «regexp»:
m.test = function (actual) {
if (typeof actual !== «string») {
return false;
}
return expectation.test(actual);
};
break;
case «function»:
m.test = expectation;
if (message) {
m.message = message;
} else {
m.message = «match(» + sinon.functionName(expectation) + ")";
}
break;
default:
m.test = function (actual) {
return sinon.deepEqual(expectation, actual);
};
}
if (!m.message) {
m.message = «match(» + expectation + ")";
}
return m;
}

matcher.or = function (m2) {
if (!arguments.length) {
throw new TypeError(«Matcher expected»);
} else if (!isMatcher(m2)) {
m2 = match(m2);
}
var m1 = this;
var or = sinon.create(matcher);
or.test = function (actual) {
return m1.test(actual) || m2.test(actual);
};
or.message = m1.message + ".or(" + m2.message + ")";
return or;
};

matcher.and = function (m2) {
if (!arguments.length) {
throw new TypeError(«Matcher expected»);
} else if (!isMatcher(m2)) {
m2 = match(m2);
}
var m1 = this;
var and = sinon.create(matcher);
and.test = function (actual) {
return m1.test(actual) && m2.test(actual);
};
and.message = m1.message + ".and(" + m2.message + ")";
return and;
};

match.isMatcher = isMatcher;

match.any = match(function () {
return true;
}, «any»);

match.defined = match(function (actual) {
return actual !== null && actual !== undefined;
}, «defined»);

match.truthy = match(function (actual) {
return !!actual;
}, «truthy»);

match.falsy = match(function (actual) {
return !actual;
}, «falsy»);

match.same = function (expectation) {
return match(function (actual) {
return expectation === actual;
}, «same(» + expectation + ")");
};

match.typeOf = function (type) {
assertType(type, «string», «type»);
return match(function (actual) {
return sinon.typeOf(actual) === type;
}, «typeOf(\»" + type + "\")");
};

match.instanceOf = function (type) {
assertType(type, «function», «type»);
return match(function (actual) {
return actual instanceof type;
}, «instanceOf(» + sinon.functionName(type) + ")");
};

function createPropertyMatcher(propertyTest, messagePrefix) {
return function (property, value) {
assertType(property, «string», «property»);
var onlyProperty = arguments.length === 1;
var message = messagePrefix + "(\"" + property + "\"";
if (!onlyProperty) {
message += ", " + value;
}
message += ")";
return match(function (actual) {
if (actual === undefined || actual === null ||
!propertyTest(actual, property)) {
return false;
}
return onlyProperty || sinon.deepEqual(value, actual[property]);
}, message);
};
}

match.has = createPropertyMatcher(function (actual, property) {
if (typeof actual === «object») {
return property in actual;
}
return actual[property] !== undefined;
}, «has»);

match.hasOwn = createPropertyMatcher(function (actual, property) {
return actual.hasOwnProperty(property);
}, «hasOwn»);

match.bool = match.typeOf(«boolean»);
match.number = match.typeOf(«number»);
match.string = match.typeOf(«string»);
match.object = match.typeOf(«object»);
match.func = match.typeOf(«function»);
match.array = match.typeOf(«array»);
match.regexp = match.typeOf(«regexp»);
match.date = match.typeOf(«date»);

sinon.match = match;
return match;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./typeOf");
module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
*/
/**
* Format functions
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2014 Christian Johansen
*/
(function (sinonGlobal, formatio) {

function makeApi(sinon) {
function valueFormatter(value) {
return "" + value;
}

function getFormatioFormatter() {
var formatter = formatio.configure({
quoteStrings: false,
limitChildrenCount: 250
});

function format() {
return formatter.ascii.apply(formatter, arguments);
}

return format;
}

function getNodeFormatter() {
try {
var util = require(«util»);
} catch (e) {
/* Node, but no util module — would be very old, but better safe than sorry */
}

function format(v) {
var isObjectWithNativeToString = typeof v === «object» && v.toString === Object.prototype.toString;
return isObjectWithNativeToString? util.inspect(v): v;
}

return util? format: valueFormatter;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var formatter;

if (isNode) {
try {
formatio = require(«formatio»);
}
catch (e) {} // eslint-disable-line no-empty
}

if (formatio) {
formatter = getFormatioFormatter();
} else if (isNode) {
formatter = getNodeFormatter();
} else {
formatter = valueFormatter;
}

sinon.format = formatter;
return sinon.format;
}

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
module.exports = makeApi(sinon);
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon, // eslint-disable-line no-undef
typeof formatio === «object» && formatio // eslint-disable-line no-undef
));

/**
* depend util/core.js
* depend match.js
* depend format.js
*/
/**
* Spy calls
*
* author Christian Johansen (christian@cjohansen.no)
* author Maximilian Antoni (mail@maxantoni.de)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
* Copyright 2013 Maximilian Antoni
*/
(function (sinonGlobal) {

var slice = Array.prototype.slice;

function makeApi(sinon) {
function throwYieldError(proxy, text, args) {
var msg = sinon.functionName(proxy) + text;
if (args.length) {
msg += " Received [" + slice.call(args).join(", ") + "]";
}
throw new Error(msg);
}

var callProto = {
calledOn: function calledOn(thisValue) {
if (sinon.match && sinon.match.isMatcher(thisValue)) {
return thisValue.test(this.thisValue);
}
return this.thisValue === thisValue;
},

calledWith: function calledWith() {
var l = arguments.length;
if (l > this.args.length) {
return false;
}
for (var i = 0; i < l; i += 1) {
if (!sinon.deepEqual(arguments[i], this.args[i])) {
return false;
}
}

return true;
},

calledWithMatch: function calledWithMatch() {
var l = arguments.length;
if (l > this.args.length) {
return false;
}
for (var i = 0; i < l; i += 1) {
var actual = this.args[i];
var expectation = arguments[i];
if (!sinon.match || !sinon.match(expectation).test(actual)) {
return false;
}
}
return true;
},

calledWithExactly: function calledWithExactly() {
return arguments.length === this.args.length &&
this.calledWith.apply(this, arguments);
},

notCalledWith: function notCalledWith() {
return !this.calledWith.apply(this, arguments);
},

notCalledWithMatch: function notCalledWithMatch() {
return !this.calledWithMatch.apply(this, arguments);
},

returned: function returned(value) {
return sinon.deepEqual(value, this.returnValue);
},

threw: function threw(error) {
if (typeof error === «undefined» || !this.exception) {
return !!this.exception;
}

return this.exception === error || this.exception.name === error;
},

calledWithNew: function calledWithNew() {
return this.proxy.prototype && this.thisValue instanceof this.proxy;
},

calledBefore: function (other) {
return this.callId < other.callId;
},

calledAfter: function (other) {
return this.callId > other.callId;
},

callArg: function (pos) {
this.args[pos]();
},

callArgOn: function (pos, thisValue) {
this.args[pos].apply(thisValue);
},

callArgWith: function (pos) {
this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
},

callArgOnWith: function (pos, thisValue) {
var args = slice.call(arguments, 2);
this.args[pos].apply(thisValue, args);
},

«yield»: function () {
this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
},

yieldOn: function (thisValue) {
var args = this.args;
for (var i = 0, l = args.length; i < l; ++i) {
if (typeof args[i] === «function») {
args[i].apply(thisValue, slice.call(arguments, 1));
return;
}
}
throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
},

yieldTo: function (prop) {
this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
},

yieldToOn: function (prop, thisValue) {
var args = this.args;
for (var i = 0, l = args.length; i < l; ++i) {
if (args[i] && typeof args[i][prop] === «function») {
args[i][prop].apply(thisValue, slice.call(arguments, 2));
return;
}
}
throwYieldError(this.proxy, " cannot yield to '" + prop +
"' since no callback was passed.", args);
},

getStackFrames: function () {
// Omit the error message and the two top stack frames in sinon itself:
return this.stack && this.stack.split("\n").slice(3);
},

toString: function () {
var callStr = this.proxy.toString() + "(";
var args = [];

for (var i = 0, l = this.args.length; i < l; ++i) {
args.push(sinon.format(this.args[i]));
}

callStr = callStr + args.join(", ") + ")";

if (typeof this.returnValue !== «undefined») {
callStr += " => " + sinon.format(this.returnValue);
}

if (this.exception) {
callStr += " !" + this.exception.name;

if (this.exception.message) {
callStr += "(" + this.exception.message + ")";
}
}
if (this.stack) {
callStr += this.getStackFrames()[0].replace(/^\s*(?:at\s+|@)?/, " at ");

}

return callStr;
}
};

callProto.invokeCallback = callProto.yield;

function createSpyCall(spy, thisValue, args, returnValue, exception, id, stack) {
if (typeof id !== «number») {
throw new TypeError(«Call id is not a number»);
}
var proxyCall = sinon.create(callProto);
proxyCall.proxy = spy;
proxyCall.thisValue = thisValue;
proxyCall.args = args;
proxyCall.returnValue = returnValue;
proxyCall.exception = exception;
proxyCall.callId = id;
proxyCall.stack = stack;

return proxyCall;
}
createSpyCall.toString = callProto.toString; // used by mocks

sinon.spyCall = createSpyCall;
return createSpyCall;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./match");
require("./format");
module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend times_in_words.js
* depend util/core.js
* depend extend.js
* depend call.js
* depend format.js
*/
/**
* Spy functions
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

function makeApi(sinon) {
var push = Array.prototype.push;
var slice = Array.prototype.slice;
var callId = 0;

function spy(object, property, types) {
if (!property && typeof object === «function») {
return spy.create(object);
}

if (!object && !property) {
return spy.create(function () { });
}

if (types) {
var methodDesc = sinon.getPropertyDescriptor(object, property);
for (var i = 0; i < types.length; i++) {
methodDesc[types[i]] = spy.create(methodDesc[types[i]]);
}
return sinon.wrapMethod(object, property, methodDesc);
}

return sinon.wrapMethod(object, property, spy.create(object[property]));
}

function matchingFake(fakes, args, strict) {
if (!fakes) {
return undefined;
}

for (var i = 0, l = fakes.length; i < l; i++) {
if (fakes[i].matches(args, strict)) {
return fakes[i];
}
}
}

function incrementCallCount() {
this.called = true;
this.callCount += 1;
this.notCalled = false;
this.calledOnce = this.callCount === 1;
this.calledTwice = this.callCount === 2;
this.calledThrice = this.callCount === 3;
}

function createCallProperties() {
this.firstCall = this.getCall(0);
this.secondCall = this.getCall(1);
this.thirdCall = this.getCall(2);
this.lastCall = this.getCall(this.callCount — 1);
}

var vars = «a,b,c,d,e,f,g,h,i,j,k,l»;
function createProxy(func, proxyLength) {
// Retain the function length:
var p;
if (proxyLength) {
eval(«p = (function proxy(» + vars.substring(0, proxyLength * 2 — 1) + // eslint-disable-line no-eval
") { return p.invoke(func, this, slice.call(arguments)); });");
} else {
p = function proxy() {
return p.invoke(func, this, slice.call(arguments));
};
}
p.isSinonProxy = true;
return p;
}

var uuid = 0;

// Public API
var spyApi = {
reset: function () {
if (this.invoking) {
var err = new Error(«Cannot reset Sinon function while invoking it. » +
«Move the call to .reset outside of the callback.»);
err.name = «InvalidResetException»;
throw err;
}

this.called = false;
this.notCalled = true;
this.calledOnce = false;
this.calledTwice = false;
this.calledThrice = false;
this.callCount = 0;
this.firstCall = null;
this.secondCall = null;
this.thirdCall = null;
this.lastCall = null;
this.args = [];
this.returnValues = [];
this.thisValues = [];
this.exceptions = [];
this.callIds = [];
this.stacks = [];
if (this.fakes) {
for (var i = 0; i < this.fakes.length; i++) {
this.fakes[i].reset();
}
}

return this;
},

create: function create(func, spyLength) {
var name;

if (typeof func !== «function») {
func = function () { };
} else {
name = sinon.functionName(func);
}

if (!spyLength) {
spyLength = func.length;
}

var proxy = createProxy(func, spyLength);

sinon.extend(proxy, spy);
delete proxy.create;
sinon.extend(proxy, func);

proxy.reset();
proxy.prototype = func.prototype;
proxy.displayName = name || «spy»;
proxy.toString = sinon.functionToString;
proxy.instantiateFake = sinon.spy.create;
proxy.id = «spy#» + uuid++;

return proxy;
},

invoke: function invoke(func, thisValue, args) {
var matching = matchingFake(this.fakes, args);
var exception, returnValue;

incrementCallCount.call(this);
push.call(this.thisValues, thisValue);
push.call(this.args, args);
push.call(this.callIds, callId++);

// Make call properties available from within the spied function:
createCallProperties.call(this);

try {
this.invoking = true;

if (matching) {
returnValue = matching.invoke(func, thisValue, args);
} else {
returnValue = (this.func || func).apply(thisValue, args);
}

var thisCall = this.getCall(this.callCount — 1);
if (thisCall.calledWithNew() && typeof returnValue !== «object») {
returnValue = thisValue;
}
} catch (e) {
exception = e;
} finally {
delete this.invoking;
}

push.call(this.exceptions, exception);
push.call(this.returnValues, returnValue);
push.call(this.stacks, new Error().stack);

// Make return value and exception available in the calls:
createCallProperties.call(this);

if (exception !== undefined) {
throw exception;
}

return returnValue;
},

named: function named(name) {
this.displayName = name;
return this;
},

getCall: function getCall(i) {
if (i < 0 || i >= this.callCount) {
return null;
}

return sinon.spyCall(this, this.thisValues[i], this.args[i],
this.returnValues[i], this.exceptions[i],
this.callIds[i], this.stacks[i]);
},

getCalls: function () {
var calls = [];
var i;

for (i = 0; i < this.callCount; i++) {
calls.push(this.getCall(i));
}

return calls;
},

calledBefore: function calledBefore(spyFn) {
if (!this.called) {
return false;
}

if (!spyFn.called) {
return true;
}

return this.callIds[0] < spyFn.callIds[spyFn.callIds.length — 1];
},

calledAfter: function calledAfter(spyFn) {
if (!this.called || !spyFn.called) {
return false;
}

return this.callIds[this.callCount — 1] > spyFn.callIds[spyFn.callCount — 1];
},

withArgs: function () {
var args = slice.call(arguments);

if (this.fakes) {
var match = matchingFake(this.fakes, args, true);

if (match) {
return match;
}
} else {
this.fakes = [];
}

var original = this;
var fake = this.instantiateFake();
fake.matchingAguments = args;
fake.parent = this;
push.call(this.fakes, fake);

fake.withArgs = function () {
return original.withArgs.apply(original, arguments);
};

for (var i = 0; i < this.args.length; i++) {
if (fake.matches(this.args[i])) {
incrementCallCount.call(fake);
push.call(fake.thisValues, this.thisValues[i]);
push.call(fake.args, this.args[i]);
push.call(fake.returnValues, this.returnValues[i]);
push.call(fake.exceptions, this.exceptions[i]);
push.call(fake.callIds, this.callIds[i]);
}
}
createCallProperties.call(fake);

return fake;
},

matches: function (args, strict) {
var margs = this.matchingAguments;

if (margs.length <= args.length &&
sinon.deepEqual(margs, args.slice(0, margs.length))) {
return !strict || margs.length === args.length;
}
},

printf: function (format) {
var spyInstance = this;
var args = slice.call(arguments, 1);
var formatter;

return (format || "").replace(/%(.)/g, function (match, specifyer) {
formatter = spyApi.formatters[specifyer];

if (typeof formatter === «function») {
return formatter.call(null, spyInstance, args);
} else if (!isNaN(parseInt(specifyer, 10))) {
return sinon.format(args[specifyer — 1]);
}

return "%" + specifyer;
});
}
};

function delegateToCalls(method, matchAny, actual, notCalled) {
spyApi[method] = function () {
if (!this.called) {
if (notCalled) {
return notCalled.apply(this, arguments);
}
return false;
}

var currentCall;
var matches = 0;

for (var i = 0, l = this.callCount; i < l; i += 1) {
currentCall = this.getCall(i);

if (currentCall[actual || method].apply(currentCall, arguments)) {
matches += 1;

if (matchAny) {
return true;
}
}
}

return matches === this.callCount;
};
}

delegateToCalls(«calledOn», true);
delegateToCalls(«alwaysCalledOn», false, «calledOn»);
delegateToCalls(«calledWith», true);
delegateToCalls(«calledWithMatch», true);
delegateToCalls(«alwaysCalledWith», false, «calledWith»);
delegateToCalls(«alwaysCalledWithMatch», false, «calledWithMatch»);
delegateToCalls(«calledWithExactly», true);
delegateToCalls(«alwaysCalledWithExactly», false, «calledWithExactly»);
delegateToCalls(«neverCalledWith», false, «notCalledWith», function () {
return true;
});
delegateToCalls(«neverCalledWithMatch», false, «notCalledWithMatch», function () {
return true;
});
delegateToCalls(«threw», true);
delegateToCalls(«alwaysThrew», false, «threw»);
delegateToCalls(«returned», true);
delegateToCalls(«alwaysReturned», false, «returned»);
delegateToCalls(«calledWithNew», true);
delegateToCalls(«alwaysCalledWithNew», false, «calledWithNew»);
delegateToCalls(«callArg», false, «callArgWith», function () {
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
});
spyApi.callArgWith = spyApi.callArg;
delegateToCalls(«callArgOn», false, «callArgOnWith», function () {
throw new Error(this.toString() + " cannot call arg since it was not yet invoked.");
});
spyApi.callArgOnWith = spyApi.callArgOn;
delegateToCalls(«yield», false, «yield», function () {
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
});
// «invokeCallback» is an alias for «yield» since «yield» is invalid in strict mode.
spyApi.invokeCallback = spyApi.yield;
delegateToCalls(«yieldOn», false, «yieldOn», function () {
throw new Error(this.toString() + " cannot yield since it was not yet invoked.");
});
delegateToCalls(«yieldTo», false, «yieldTo», function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});
delegateToCalls(«yieldToOn», false, «yieldToOn», function (property) {
throw new Error(this.toString() + " cannot yield to '" + property +
"' since it was not yet invoked.");
});

spyApi.formatters = {
c: function (spyInstance) {
return sinon.timesInWords(spyInstance.callCount);
},

n: function (spyInstance) {
return spyInstance.toString();
},

C: function (spyInstance) {
var calls = [];

for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
var stringifiedCall = " " + spyInstance.getCall(i).toString();
if (/\n/.test(calls[i — 1])) {
stringifiedCall = "\n" + stringifiedCall;
}
push.call(calls, stringifiedCall);
}

return calls.length > 0? "\n" + calls.join("\n"): "";
},

t: function (spyInstance) {
var objects = [];

for (var i = 0, l = spyInstance.callCount; i < l; ++i) {
push.call(objects, sinon.format(spyInstance.thisValues[i]));
}

return objects.join(", ");
},

"*": function (spyInstance, args) {
var formatted = [];

for (var i = 0, l = args.length; i < l; ++i) {
push.call(formatted, sinon.format(args[i]));
}

return formatted.join(", ");
}
};

sinon.extend(spy, spyApi);

spy.spyCall = sinon.spyCall;
sinon.spy = spy;

return spy;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var core = require("./util/core");
require("./call");
require("./extend");
require("./times_in_words");
require("./format");
module.exports = makeApi(core);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
* depend extend.js
*/
/**
* Stub behavior
*
* author Christian Johansen (christian@cjohansen.no)
* author Tim Fischbach (mail@timfischbach.de)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

var slice = Array.prototype.slice;
var join = Array.prototype.join;
var useLeftMostCallback = -1;
var useRightMostCallback = -2;

var nextTick = (function () {
if (typeof process === «object» && typeof process.nextTick === «function») {
return process.nextTick;
}

if (typeof setImmediate === «function») {
return setImmediate;
}

return function (callback) {
setTimeout(callback, 0);
};
})();

function throwsException(error, message) {
if (typeof error === «string») {
this.exception = new Error(message || "");
this.exception.name = error;
} else if (!error) {
this.exception = new Error(«Error»);
} else {
this.exception = error;
}

return this;
}

function getCallback(behavior, args) {
var callArgAt = behavior.callArgAt;

if (callArgAt >= 0) {
return args[callArgAt];
}

var argumentList;

if (callArgAt === useLeftMostCallback) {
argumentList = args;
}

if (callArgAt === useRightMostCallback) {
argumentList = slice.call(args).reverse();
}

var callArgProp = behavior.callArgProp;

for (var i = 0, l = argumentList.length; i < l; ++i) {
if (!callArgProp && typeof argumentList[i] === «function») {
return argumentList[i];
}

if (callArgProp && argumentList[i] &&
typeof argumentList[i][callArgProp] === «function») {
return argumentList[i][callArgProp];
}
}

return null;
}

function makeApi(sinon) {
function getCallbackError(behavior, func, args) {
if (behavior.callArgAt < 0) {
var msg;

if (behavior.callArgProp) {
msg = sinon.functionName(behavior.stub) +
" expected to yield to '" + behavior.callArgProp +
"', but no object with such a property was passed.";
} else {
msg = sinon.functionName(behavior.stub) +
" expected to yield, but no callback was passed.";
}

if (args.length > 0) {
msg += " Received [" + join.call(args, ", ") + "]";
}

return msg;
}

return «argument at index » + behavior.callArgAt + " is not a function: " + func;
}

function callCallback(behavior, args) {
if (typeof behavior.callArgAt === «number») {
var func = getCallback(behavior, args);

if (typeof func !== «function») {
throw new TypeError(getCallbackError(behavior, func, args));
}

if (behavior.callbackAsync) {
nextTick(function () {
func.apply(behavior.callbackContext, behavior.callbackArguments);
});
} else {
func.apply(behavior.callbackContext, behavior.callbackArguments);
}
}
}

var proto = {
create: function create(stub) {
var behavior = sinon.extend({}, sinon.behavior);
delete behavior.create;
behavior.stub = stub;

return behavior;
},

isPresent: function isPresent() {
return (typeof this.callArgAt === «number» ||
this.exception ||
typeof this.returnArgAt === «number» ||
this.returnThis ||
this.returnValueDefined);
},

invoke: function invoke(context, args) {
callCallback(this, args);

if (this.exception) {
throw this.exception;
} else if (typeof this.returnArgAt === «number») {
return args[this.returnArgAt];
} else if (this.returnThis) {
return context;
}

return this.returnValue;
},

onCall: function onCall(index) {
return this.stub.onCall(index);
},

onFirstCall: function onFirstCall() {
return this.stub.onFirstCall();
},

onSecondCall: function onSecondCall() {
return this.stub.onSecondCall();
},

onThirdCall: function onThirdCall() {
return this.stub.onThirdCall();
},

withArgs: function withArgs(/* arguments */) {
throw new Error(
«Defining a stub by invoking \»stub.onCall(...).withArgs(...)\" " +
«is not supported. Use \»stub.withArgs(...).onCall(...)\" " +
«to define sequential behavior for calls with certain arguments.»
);
},

callsArg: function callsArg(pos) {
if (typeof pos !== «number») {
throw new TypeError(«argument index is not number»);
}

this.callArgAt = pos;
this.callbackArguments = [];
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

callsArgOn: function callsArgOn(pos, context) {
if (typeof pos !== «number») {
throw new TypeError(«argument index is not number»);
}
if (typeof context !== «object») {
throw new TypeError(«argument context is not an object»);
}

this.callArgAt = pos;
this.callbackArguments = [];
this.callbackContext = context;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

callsArgWith: function callsArgWith(pos) {
if (typeof pos !== «number») {
throw new TypeError(«argument index is not number»);
}

this.callArgAt = pos;
this.callbackArguments = slice.call(arguments, 1);
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

callsArgOnWith: function callsArgWith(pos, context) {
if (typeof pos !== «number») {
throw new TypeError(«argument index is not number»);
}
if (typeof context !== «object») {
throw new TypeError(«argument context is not an object»);
}

this.callArgAt = pos;
this.callbackArguments = slice.call(arguments, 2);
this.callbackContext = context;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

yields: function () {
this.callArgAt = useLeftMostCallback;
this.callbackArguments = slice.call(arguments, 0);
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

yieldsRight: function () {
this.callArgAt = useRightMostCallback;
this.callbackArguments = slice.call(arguments, 0);
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

yieldsOn: function (context) {
if (typeof context !== «object») {
throw new TypeError(«argument context is not an object»);
}

this.callArgAt = useLeftMostCallback;
this.callbackArguments = slice.call(arguments, 1);
this.callbackContext = context;
this.callArgProp = undefined;
this.callbackAsync = false;

return this;
},

yieldsTo: function (prop) {
this.callArgAt = useLeftMostCallback;
this.callbackArguments = slice.call(arguments, 1);
this.callbackContext = undefined;
this.callArgProp = prop;
this.callbackAsync = false;

return this;
},

yieldsToOn: function (prop, context) {
if (typeof context !== «object») {
throw new TypeError(«argument context is not an object»);
}

this.callArgAt = useLeftMostCallback;
this.callbackArguments = slice.call(arguments, 2);
this.callbackContext = context;
this.callArgProp = prop;
this.callbackAsync = false;

return this;
},

throws: throwsException,
throwsException: throwsException,

returns: function returns(value) {
this.returnValue = value;
this.returnValueDefined = true;
this.exception = undefined;

return this;
},

returnsArg: function returnsArg(pos) {
if (typeof pos !== «number») {
throw new TypeError(«argument index is not number»);
}

this.returnArgAt = pos;

return this;
},

returnsThis: function returnsThis() {
this.returnThis = true;

return this;
}
};

function createAsyncVersion(syncFnName) {
return function () {
var result = this[syncFnName].apply(this, arguments);
this.callbackAsync = true;
return result;
};
}

// create asynchronous versions of callsArg* and yields* methods
for (var method in proto) {
// need to avoid creating anotherasync versions of the newly added async methods
if (proto.hasOwnProperty(method) && method.match(/^(callsArg|yields)/) && !method.match(/Async/)) {
proto[method + «Async»] = createAsyncVersion(method);
}
}

sinon.behavior = proto;
return proto;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./extend");
module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
*/
(function (sinonGlobal) {

function makeApi(sinon) {
function walkInternal(obj, iterator, context, originalObj, seen) {
var proto, prop;

if (typeof Object.getOwnPropertyNames !== «function») {
// We explicitly want to enumerate through all of the prototype's properties
// in this case, therefore we deliberately leave out an own property check.
/* eslint-disable guard-for-in */
for (prop in obj) {
iterator.call(context, obj[prop], prop, obj);
}
/* eslint-enable guard-for-in */

return;
}

Object.getOwnPropertyNames(obj).forEach(function (k) {
if (!seen[k]) {
seen[k] = true;
var target = typeof Object.getOwnPropertyDescriptor(obj, k).get === «function»?
originalObj: obj;
iterator.call(context, target[k], k, target);
}
});

proto = Object.getPrototypeOf(obj);
if (proto) {
walkInternal(proto, iterator, context, originalObj, seen);
}
}

/* Public: walks the prototype chain of an object and iterates over every own property
* name encountered. The iterator is called in the same fashion that Array.prototype.forEach
* works, where it is passed the value, key, and own object as the 1st, 2nd, and 3rd positional
* argument, respectively. In cases where Object.getOwnPropertyNames is not available, walk will
* default to using a simple for..in loop.
*
* obj — The object to walk the prototype chain for.
* iterator — The function to be called on each pass of the walk.
* context — (Optional) When given, the iterator will be called with this object as the receiver.
*/
function walk(obj, iterator, context) {
return walkInternal(obj, iterator, context, obj, {});
}

sinon.walk = walk;
return sinon.walk;
}

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
module.exports = makeApi(sinon);
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
* depend extend.js
* depend spy.js
* depend behavior.js
* depend walk.js
*/
/**
* Stub functions
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

function makeApi(sinon) {
function stub(object, property, func) {
if (!!func && typeof func !== «function» && typeof func !== «object») {
throw new TypeError(«Custom stub should be a function or a property descriptor»);
}

var wrapper;

if (func) {
if (typeof func === «function») {
wrapper = sinon.spy && sinon.spy.create? sinon.spy.create(func): func;
} else {
wrapper = func;
if (sinon.spy && sinon.spy.create) {
var types = sinon.objectKeys(wrapper);
for (var i = 0; i < types.length; i++) {
wrapper[types[i]] = sinon.spy.create(wrapper[types[i]]);
}
}
}
} else {
var stubLength = 0;
if (typeof object === «object» && typeof object[property] === «function») {
stubLength = object[property].length;
}
wrapper = stub.create(stubLength);
}

if (!object && typeof property === «undefined») {
return sinon.stub.create();
}

if (typeof property === «undefined» && typeof object === «object») {
sinon.walk(object || {}, function (value, prop, propOwner) {
// we don't want to stub things like toString(), valueOf(), etc. so we only stub if the object
// is not Object.prototype
if (
propOwner !== Object.prototype &&
prop !== «constructor» &&
typeof sinon.getPropertyDescriptor(propOwner, prop).value === «function»
) {
stub(object, prop);
}
});

return object;
}

return sinon.wrapMethod(object, property, wrapper);
}

/*eslint-disable no-use-before-define*/
function getParentBehaviour(stubInstance) {
return (stubInstance.parent && getCurrentBehavior(stubInstance.parent));
}

function getDefaultBehavior(stubInstance) {
return stubInstance.defaultBehavior ||
getParentBehaviour(stubInstance) ||
sinon.behavior.create(stubInstance);
}

function getCurrentBehavior(stubInstance) {
var behavior = stubInstance.behaviors[stubInstance.callCount — 1];
return behavior && behavior.isPresent()? behavior: getDefaultBehavior(stubInstance);
}
/*eslint-enable no-use-before-define*/

var uuid = 0;

var proto = {
create: function create(stubLength) {
var functionStub = function () {
return getCurrentBehavior(functionStub).invoke(this, arguments);
};

functionStub.id = «stub#» + uuid++;
var orig = functionStub;
functionStub = sinon.spy.create(functionStub, stubLength);
functionStub.func = orig;

sinon.extend(functionStub, stub);
functionStub.instantiateFake = sinon.stub.create;
functionStub.displayName = «stub»;
functionStub.toString = sinon.functionToString;

functionStub.defaultBehavior = null;
functionStub.behaviors = [];

return functionStub;
},

resetBehavior: function () {
var i;

this.defaultBehavior = null;
this.behaviors = [];

delete this.returnValue;
delete this.returnArgAt;
this.returnThis = false;

if (this.fakes) {
for (i = 0; i < this.fakes.length; i++) {
this.fakes[i].resetBehavior();
}
}
},

onCall: function onCall(index) {
if (!this.behaviors[index]) {
this.behaviors[index] = sinon.behavior.create(this);
}

return this.behaviors[index];
},

onFirstCall: function onFirstCall() {
return this.onCall(0);
},

onSecondCall: function onSecondCall() {
return this.onCall(1);
},

onThirdCall: function onThirdCall() {
return this.onCall(2);
}
};

function createBehavior(behaviorMethod) {
return function () {
this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
return this;
};
}

for (var method in sinon.behavior) {
if (sinon.behavior.hasOwnProperty(method) &&
!proto.hasOwnProperty(method) &&
method !== «create» &&
method !== «withArgs» &&
method !== «invoke») {
proto[method] = createBehavior(method);
}
}

sinon.extend(stub, proto);
sinon.stub = stub;

return stub;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var core = require("./util/core");
require("./behavior");
require("./spy");
require("./extend");
module.exports = makeApi(core);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend times_in_words.js
* depend util/core.js
* depend call.js
* depend extend.js
* depend match.js
* depend spy.js
* depend stub.js
* depend format.js
*/
/**
* Mock functions.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

function makeApi(sinon) {
var push = [].push;
var match = sinon.match;

function mock(object) {
// if (typeof console !== undefined && console.warn) {
// console.warn(«mock will be removed from Sinon.JS v2.0»);
// }

if (!object) {
return sinon.expectation.create(«Anonymous mock»);
}

return mock.create(object);
}

function each(collection, callback) {
if (!collection) {
return;
}

for (var i = 0, l = collection.length; i < l; i += 1) {
callback(collection[i]);
}
}

function arrayEquals(arr1, arr2, compareLength) {
if (compareLength && (arr1.length !== arr2.length)) {
return false;
}

for (var i = 0, l = arr1.length; i < l; i++) {
if (!sinon.deepEqual(arr1[i], arr2[i])) {
return false;
}
}
return true;
}

sinon.extend(mock, {
create: function create(object) {
if (!object) {
throw new TypeError(«object is null»);
}

var mockObject = sinon.extend({}, mock);
mockObject.object = object;
delete mockObject.create;

return mockObject;
},

expects: function expects(method) {
if (!method) {
throw new TypeError(«method is falsy»);
}

if (!this.expectations) {
this.expectations = {};
this.proxies = [];
}

if (!this.expectations[method]) {
this.expectations[method] = [];
var mockObject = this;

sinon.wrapMethod(this.object, method, function () {
return mockObject.invokeMethod(method, this, arguments);
});

push.call(this.proxies, method);
}

var expectation = sinon.expectation.create(method);
push.call(this.expectations[method], expectation);

return expectation;
},

restore: function restore() {
var object = this.object;

each(this.proxies, function (proxy) {
if (typeof object[proxy].restore === «function») {
object[proxy].restore();
}
});
},

verify: function verify() {
var expectations = this.expectations || {};
var messages = [];
var met = [];

each(this.proxies, function (proxy) {
each(expectations[proxy], function (expectation) {
if (!expectation.met()) {
push.call(messages, expectation.toString());
} else {
push.call(met, expectation.toString());
}
});
});

this.restore();

if (messages.length > 0) {
sinon.expectation.fail(messages.concat(met).join("\n"));
} else if (met.length > 0) {
sinon.expectation.pass(messages.concat(met).join("\n"));
}

return true;
},

invokeMethod: function invokeMethod(method, thisValue, args) {
var expectations = this.expectations && this.expectations[method]? this.expectations[method]: [];
var expectationsWithMatchingArgs = [];
var currentArgs = args || [];
var i, available;

for (i = 0; i < expectations.length; i += 1) {
var expectedArgs = expectations[i].expectedArguments || [];
if (arrayEquals(expectedArgs, currentArgs, expectations[i].expectsExactArgCount)) {
expectationsWithMatchingArgs.push(expectations[i]);
}
}

for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
if (!expectationsWithMatchingArgs[i].met() &&
expectationsWithMatchingArgs[i].allowsCall(thisValue, args)) {
return expectationsWithMatchingArgs[i].apply(thisValue, args);
}
}

var messages = [];
var exhausted = 0;

for (i = 0; i < expectationsWithMatchingArgs.length; i += 1) {
if (expectationsWithMatchingArgs[i].allowsCall(thisValue, args)) {
available = available || expectationsWithMatchingArgs[i];
} else {
exhausted += 1;
}
}

if (available && exhausted === 0) {
return available.apply(thisValue, args);
}

for (i = 0; i < expectations.length; i += 1) {
push.call(messages, " " + expectations[i].toString());
}

messages.unshift(«Unexpected call: » + sinon.spyCall.toString.call({
proxy: method,
args: args
}));

sinon.expectation.fail(messages.join("\n"));
}
});

var times = sinon.timesInWords;
var slice = Array.prototype.slice;

function callCountInWords(callCount) {
if (callCount === 0) {
return «never called»;
}

return «called » + times(callCount);
}

function expectedCallCountInWords(expectation) {
var min = expectation.minCalls;
var max = expectation.maxCalls;

if (typeof min === «number» && typeof max === «number») {
var str = times(min);

if (min !== max) {
str = «at least » + str + " and at most " + times(max);
}

return str;
}

if (typeof min === «number») {
return «at least » + times(min);
}

return «at most » + times(max);
}

function receivedMinCalls(expectation) {
var hasMinLimit = typeof expectation.minCalls === «number»;
return !hasMinLimit || expectation.callCount >= expectation.minCalls;
}

function receivedMaxCalls(expectation) {
if (typeof expectation.maxCalls !== «number») {
return false;
}

return expectation.callCount === expectation.maxCalls;
}

function verifyMatcher(possibleMatcher, arg) {
var isMatcher = match && match.isMatcher(possibleMatcher);

return isMatcher && possibleMatcher.test(arg) || true;
}

sinon.expectation = {
minCalls: 1,
maxCalls: 1,

create: function create(methodName) {
var expectation = sinon.extend(sinon.stub.create(), sinon.expectation);
delete expectation.create;
expectation.method = methodName;

return expectation;
},

invoke: function invoke(func, thisValue, args) {
this.verifyCallAllowed(thisValue, args);

return sinon.spy.invoke.apply(this, arguments);
},

atLeast: function atLeast(num) {
if (typeof num !== «number») {
throw new TypeError("'" + num + "' is not number");
}

if (!this.limitsSet) {
this.maxCalls = null;
this.limitsSet = true;
}

this.minCalls = num;

return this;
},

atMost: function atMost(num) {
if (typeof num !== «number») {
throw new TypeError("'" + num + "' is not number");
}

if (!this.limitsSet) {
this.minCalls = null;
this.limitsSet = true;
}

this.maxCalls = num;

return this;
},

never: function never() {
return this.exactly(0);
},

once: function once() {
return this.exactly(1);
},

twice: function twice() {
return this.exactly(2);
},

thrice: function thrice() {
return this.exactly(3);
},

exactly: function exactly(num) {
if (typeof num !== «number») {
throw new TypeError("'" + num + "' is not a number");
}

this.atLeast(num);
return this.atMost(num);
},

met: function met() {
return !this.failed && receivedMinCalls(this);
},

verifyCallAllowed: function verifyCallAllowed(thisValue, args) {
if (receivedMaxCalls(this)) {
this.failed = true;
sinon.expectation.fail(this.method + " already called " + times(this.maxCalls));
}

if («expectedThis» in this && this.expectedThis !== thisValue) {
sinon.expectation.fail(this.method + " called with " + thisValue + " as thisValue, expected " +
this.expectedThis);
}

if (!(«expectedArguments» in this)) {
return;
}

if (!args) {
sinon.expectation.fail(this.method + " received no arguments, expected " +
sinon.format(this.expectedArguments));
}

if (args.length < this.expectedArguments.length) {
sinon.expectation.fail(this.method + " received too few arguments (" + sinon.format(args) +
"), expected " + sinon.format(this.expectedArguments));
}

if (this.expectsExactArgCount &&
args.length !== this.expectedArguments.length) {
sinon.expectation.fail(this.method + " received too many arguments (" + sinon.format(args) +
"), expected " + sinon.format(this.expectedArguments));
}

for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {

if (!verifyMatcher(this.expectedArguments[i], args[i])) {
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
", didn't match " + this.expectedArguments.toString());
}

if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
", expected " + sinon.format(this.expectedArguments));
}
}
},

allowsCall: function allowsCall(thisValue, args) {
if (this.met() && receivedMaxCalls(this)) {
return false;
}

if («expectedThis» in this && this.expectedThis !== thisValue) {
return false;
}

if (!(«expectedArguments» in this)) {
return true;
}

args = args || [];

if (args.length < this.expectedArguments.length) {
return false;
}

if (this.expectsExactArgCount &&
args.length !== this.expectedArguments.length) {
return false;
}

for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
if (!verifyMatcher(this.expectedArguments[i], args[i])) {
return false;
}

if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
return false;
}
}

return true;
},

withArgs: function withArgs() {
this.expectedArguments = slice.call(arguments);
return this;
},

withExactArgs: function withExactArgs() {
this.withArgs.apply(this, arguments);
this.expectsExactArgCount = true;
return this;
},

on: function on(thisValue) {
this.expectedThis = thisValue;
return this;
},

toString: function () {
var args = (this.expectedArguments || []).slice();

if (!this.expectsExactArgCount) {
push.call(args, "[...]");
}

var callStr = sinon.spyCall.toString.call({
proxy: this.method || «anonymous mock expectation»,
args: args
});

var message = callStr.replace(", [...", "[, ...") + " " +
expectedCallCountInWords(this);

if (this.met()) {
return «Expectation met: » + message;
}

return «Expected » + message + " (" +
callCountInWords(this.callCount) + ")";
},

verify: function verify() {
if (!this.met()) {
sinon.expectation.fail(this.toString());
} else {
sinon.expectation.pass(this.toString());
}

return true;
},

pass: function pass(message) {
sinon.assert.pass(message);
},

fail: function fail(message) {
var exception = new Error(message);
exception.name = «ExpectationError»;

throw exception;
}
};

sinon.mock = mock;
return mock;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./times_in_words");
require("./call");
require("./extend");
require("./match");
require("./spy");
require("./stub");
require("./format");

module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
* depend spy.js
* depend stub.js
* depend mock.js
*/
/**
* Collections of stubs, spies and mocks.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

var push = [].push;
var hasOwnProperty = Object.prototype.hasOwnProperty;

function getFakes(fakeCollection) {
if (!fakeCollection.fakes) {
fakeCollection.fakes = [];
}

return fakeCollection.fakes;
}

function each(fakeCollection, method) {
var fakes = getFakes(fakeCollection);

for (var i = 0, l = fakes.length; i < l; i += 1) {
if (typeof fakes[i][method] === «function») {
fakes[i][method]();
}
}
}

function compact(fakeCollection) {
var fakes = getFakes(fakeCollection);
var i = 0;
while (i < fakes.length) {
fakes.splice(i, 1);
}
}

function makeApi(sinon) {
var collection = {
verify: function resolve() {
each(this, «verify»);
},

restore: function restore() {
each(this, «restore»);
compact(this);
},

reset: function restore() {
each(this, «reset»);
},

verifyAndRestore: function verifyAndRestore() {
var exception;

try {
this.verify();
} catch (e) {
exception = e;
}

this.restore();

if (exception) {
throw exception;
}
},

add: function add(fake) {
push.call(getFakes(this), fake);
return fake;
},

spy: function spy() {
return this.add(sinon.spy.apply(sinon, arguments));
},

stub: function stub(object, property, value) {
if (property) {
var original = object[property];

if (typeof original !== «function») {
if (!hasOwnProperty.call(object, property)) {
throw new TypeError(«Cannot stub non-existent own property » + property);
}

object[property] = value;

return this.add({
restore: function () {
object[property] = original;
}
});
}
}
if (!property && !!object && typeof object === «object») {
var stubbedObj = sinon.stub.apply(sinon, arguments);

for (var prop in stubbedObj) {
if (typeof stubbedObj[prop] === «function») {
this.add(stubbedObj[prop]);
}
}

return stubbedObj;
}

return this.add(sinon.stub.apply(sinon, arguments));
},

mock: function mock() {
return this.add(sinon.mock.apply(sinon, arguments));
},

inject: function inject(obj) {
var col = this;

obj.spy = function () {
return col.spy.apply(col, arguments);
};

obj.stub = function () {
return col.stub.apply(col, arguments);
};

obj.mock = function () {
return col.mock.apply(col, arguments);
};

return obj;
}
};

sinon.collection = collection;
return collection;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./mock");
require("./spy");
require("./stub");
module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* Fake timer API
* setTimeout
* setInterval
* clearTimeout
* clearInterval
* tick
* reset
* Date
*
* Inspired by jsUnitMockTimeOut from JsUnit
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function () {

function makeApi(s, lol) {
/*global lolex */
var llx = typeof lolex !== «undefined»? lolex: lol;

s.useFakeTimers = function () {
var now;
var methods = Array.prototype.slice.call(arguments);

if (typeof methods[0] === «string») {
now = 0;
} else {
now = methods.shift();
}

var clock = llx.install(now || 0, methods);
clock.restore = clock.uninstall;
return clock;
};

s.clock = {
create: function (now) {
return llx.createClock(now);
}
};

s.timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setImmediate: (typeof setImmediate !== «undefined»? setImmediate: undefined),
clearImmediate: (typeof clearImmediate !== «undefined»? clearImmediate: undefined),
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, epxorts, module, lolex) {
var core = require("./core");
makeApi(core, lolex);
module.exports = core;
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require, module.exports, module, require(«lolex»));
} else {
makeApi(sinon); // eslint-disable-line no-undef
}
}());

/**
* Minimal Event interface implementation
*
* Original implementation by Sven Fuchs: http://ift.tt/1NRiifj
* Modifications and tests by Christian Johansen.
*
* author Sven Fuchs (svenfuchs@artweb-design.de)
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2011 Sven Fuchs, Christian Johansen
*/
if (typeof sinon === «undefined») {
this.sinon = {};
}

(function () {

var push = [].push;

function makeApi(sinon) {
sinon.Event = function Event(type, bubbles, cancelable, target) {
this.initEvent(type, bubbles, cancelable, target);
};

sinon.Event.prototype = {
initEvent: function (type, bubbles, cancelable, target) {
this.type = type;
this.bubbles = bubbles;
this.cancelable = cancelable;
this.target = target;
},

stopPropagation: function () {},

preventDefault: function () {
this.defaultPrevented = true;
}
};

sinon.ProgressEvent = function ProgressEvent(type, progressEventRaw, target) {
this.initEvent(type, false, false, target);
this.loaded = progressEventRaw.loaded || null;
this.total = progressEventRaw.total || null;
this.lengthComputable = !!progressEventRaw.total;
};

sinon.ProgressEvent.prototype = new sinon.Event();

sinon.ProgressEvent.prototype.constructor = sinon.ProgressEvent;

sinon.CustomEvent = function CustomEvent(type, customData, target) {
this.initEvent(type, false, false, target);
this.detail = customData.detail || null;
};

sinon.CustomEvent.prototype = new sinon.Event();

sinon.CustomEvent.prototype.constructor = sinon.CustomEvent;

sinon.EventTarget = {
addEventListener: function addEventListener(event, listener) {
this.eventListeners = this.eventListeners || {};
this.eventListeners[event] = this.eventListeners[event] || [];
push.call(this.eventListeners[event], listener);
},

removeEventListener: function removeEventListener(event, listener) {
var listeners = this.eventListeners && this.eventListeners[event] || [];

for (var i = 0, l = listeners.length; i < l; ++i) {
if (listeners[i] === listener) {
return listeners.splice(i, 1);
}
}
},

dispatchEvent: function dispatchEvent(event) {
var type = event.type;
var listeners = this.eventListeners && this.eventListeners[type] || [];

for (var i = 0; i < listeners.length; i++) {
if (typeof listeners[i] === «function») {
listeners[i].call(this, event);
} else {
listeners[i].handleEvent(event);
}
}

return !!event.defaultPrevented;
}
};
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require) {
var sinon = require("./core");
makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require);
} else {
makeApi(sinon); // eslint-disable-line no-undef
}
}());

/**
* depend util/core.js
*/
/**
* Logs errors
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2014 Christian Johansen
*/
(function (sinonGlobal) {

// cache a reference to setTimeout, so that our reference won't be stubbed out
// when using fake timers and errors will still get logged
// http://ift.tt/1NRijzV
var realSetTimeout = setTimeout;

function makeApi(sinon) {

function log() {}

function logError(label, err) {
var msg = label + " threw exception: ";

function throwLoggedError() {
err.message = msg + err.message;
throw err;
}

sinon.log(msg + "[" + err.name + "] " + err.message);

if (err.stack) {
sinon.log(err.stack);
}

if (logError.useImmediateExceptions) {
throwLoggedError();
} else {
logError.setTimeout(throwLoggedError, 0);
}
}

// When set to true, any errors logged will be thrown immediately;
// If set to false, the errors will be thrown in separate execution frame.
logError.useImmediateExceptions = false;

// wrap realSetTimeout with something we can stub in tests
logError.setTimeout = function (func, timeout) {
realSetTimeout(func, timeout);
};

var exports = {};
exports.log = sinon.log = log;
exports.logError = sinon.logError = logError;

return exports;
}

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
module.exports = makeApi(sinon);
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend core.js
* depend ../extend.js
* depend event.js
* depend ../log_error.js
*/
/**
* Fake XDomainRequest object
*/
if (typeof sinon === «undefined») {
this.sinon = {};
}

// wrapper for global
(function (global) {

var xdr = { XDomainRequest: global.XDomainRequest };
xdr.GlobalXDomainRequest = global.XDomainRequest;
xdr.supportsXDR = typeof xdr.GlobalXDomainRequest !== «undefined»;
xdr.workingXDR = xdr.supportsXDR? xdr.GlobalXDomainRequest: false;

function makeApi(sinon) {
sinon.xdr = xdr;

function FakeXDomainRequest() {
this.readyState = FakeXDomainRequest.UNSENT;
this.requestBody = null;
this.requestHeaders = {};
this.status = 0;
this.timeout = null;

if (typeof FakeXDomainRequest.onCreate === «function») {
FakeXDomainRequest.onCreate(this);
}
}

function verifyState(x) {
if (x.readyState !== FakeXDomainRequest.OPENED) {
throw new Error(«INVALID_STATE_ERR»);
}

if (x.sendFlag) {
throw new Error(«INVALID_STATE_ERR»);
}
}

function verifyRequestSent(x) {
if (x.readyState === FakeXDomainRequest.UNSENT) {
throw new Error(«Request not sent»);
}
if (x.readyState === FakeXDomainRequest.DONE) {
throw new Error(«Request done»);
}
}

function verifyResponseBodyType(body) {
if (typeof body !== «string») {
var error = new Error(«Attempted to respond to fake XDomainRequest with » +
body + ", which is not a string.");
error.name = «InvalidBodyException»;
throw error;
}
}

sinon.extend(FakeXDomainRequest.prototype, sinon.EventTarget, {
open: function open(method, url) {
this.method = method;
this.url = url;

this.responseText = null;
this.sendFlag = false;

this.readyStateChange(FakeXDomainRequest.OPENED);
},

readyStateChange: function readyStateChange(state) {
this.readyState = state;
var eventName = "";
switch (this.readyState) {
case FakeXDomainRequest.UNSENT:
break;
case FakeXDomainRequest.OPENED:
break;
case FakeXDomainRequest.LOADING:
if (this.sendFlag) {
//raise the progress event
eventName = «onprogress»;
}
break;
case FakeXDomainRequest.DONE:
if (this.isTimeout) {
eventName = «ontimeout»;
} else if (this.errorFlag || (this.status < 200 || this.status > 299)) {
eventName = «onerror»;
} else {
eventName = «onload»;
}
break;
}

// raising event (if defined)
if (eventName) {
if (typeof this[eventName] === «function») {
try {
this[eventName]();
} catch (e) {
sinon.logError(«Fake XHR » + eventName + " handler", e);
}
}
}
},

send: function send(data) {
verifyState(this);

if (!/^(get|head)$/i.test(this.method)) {
this.requestBody = data;
}
this.requestHeaders[«Content-Type»] = «text/plain;charset=utf-8»;

this.errorFlag = false;
this.sendFlag = true;
this.readyStateChange(FakeXDomainRequest.OPENED);

if (typeof this.onSend === «function») {
this.onSend(this);
}
},

abort: function abort() {
this.aborted = true;
this.responseText = null;
this.errorFlag = true;

if (this.readyState > sinon.FakeXDomainRequest.UNSENT && this.sendFlag) {
this.readyStateChange(sinon.FakeXDomainRequest.DONE);
this.sendFlag = false;
}
},

setResponseBody: function setResponseBody(body) {
verifyRequestSent(this);
verifyResponseBodyType(body);

var chunkSize = this.chunkSize || 10;
var index = 0;
this.responseText = "";

do {
this.readyStateChange(FakeXDomainRequest.LOADING);
this.responseText += body.substring(index, index + chunkSize);
index += chunkSize;
} while (index < body.length);

this.readyStateChange(FakeXDomainRequest.DONE);
},

respond: function respond(status, contentType, body) {
// content-type ignored, since XDomainRequest does not carry this
// we keep the same syntax for respond(...) as for FakeXMLHttpRequest to ease
// test integration across browsers
this.status = typeof status === «number»? status: 200;
this.setResponseBody(body || "");
},

simulatetimeout: function simulatetimeout() {
this.status = 0;
this.isTimeout = true;
// Access to this should actually throw an error
this.responseText = undefined;
this.readyStateChange(FakeXDomainRequest.DONE);
}
});

sinon.extend(FakeXDomainRequest, {
UNSENT: 0,
OPENED: 1,
LOADING: 3,
DONE: 4
});

sinon.useFakeXDomainRequest = function useFakeXDomainRequest() {
sinon.FakeXDomainRequest.restore = function restore(keepOnCreate) {
if (xdr.supportsXDR) {
global.XDomainRequest = xdr.GlobalXDomainRequest;
}

delete sinon.FakeXDomainRequest.restore;

if (keepOnCreate !== true) {
delete sinon.FakeXDomainRequest.onCreate;
}
};
if (xdr.supportsXDR) {
global.XDomainRequest = sinon.FakeXDomainRequest;
}
return sinon.FakeXDomainRequest;
};

sinon.FakeXDomainRequest = FakeXDomainRequest;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./core");
require("../extend");
require("./event");
require("../log_error");
makeApi(sinon);
module.exports = sinon;
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require, module.exports, module);
} else {
makeApi(sinon); // eslint-disable-line no-undef
}
})(typeof global !== «undefined»? global: self);

/**
* depend core.js
* depend ../extend.js
* depend event.js
* depend ../log_error.js
*/
/**
* Fake XMLHttpRequest object
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal, global) {

function getWorkingXHR(globalScope) {
var supportsXHR = typeof globalScope.XMLHttpRequest !== «undefined»;
if (supportsXHR) {
return globalScope.XMLHttpRequest;
}

var supportsActiveX = typeof globalScope.ActiveXObject !== «undefined»;
if (supportsActiveX) {
return function () {
return new globalScope.ActiveXObject(«MSXML2.XMLHTTP.3.0»);
};
}

return false;
}

var supportsProgress = typeof ProgressEvent !== «undefined»;
var supportsCustomEvent = typeof CustomEvent !== «undefined»;
var supportsFormData = typeof FormData !== «undefined»;
var supportsArrayBuffer = typeof ArrayBuffer !== «undefined»;
var supportsBlob = typeof Blob === «function»;
var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest };
sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
sinonXhr.GlobalActiveXObject = global.ActiveXObject;
sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject !== «undefined»;
sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest !== «undefined»;
sinonXhr.workingXHR = getWorkingXHR(global);
sinonXhr.supportsCORS = sinonXhr.supportsXHR && «withCredentials» in (new sinonXhr.GlobalXMLHttpRequest());

var unsafeHeaders = {
«Accept-Charset»: true,
«Accept-Encoding»: true,
Connection: true,
«Content-Length»: true,
Cookie: true,
Cookie2: true,
«Content-Transfer-Encoding»: true,
Date: true,
Expect: true,
Host: true,
«Keep-Alive»: true,
Referer: true,
TE: true,
Trailer: true,
«Transfer-Encoding»: true,
Upgrade: true,
«User-Agent»: true,
Via: true
};

// An upload object is created for each
// FakeXMLHttpRequest and allows upload
// events to be simulated using uploadProgress
// and uploadError.
function UploadProgress() {
this.eventListeners = {
progress: [],
load: [],
abort: [],
error: []
};
}

UploadProgress.prototype.addEventListener = function addEventListener(event, listener) {
this.eventListeners[event].push(listener);
};

UploadProgress.prototype.removeEventListener = function removeEventListener(event, listener) {
var listeners = this.eventListeners[event] || [];

for (var i = 0, l = listeners.length; i < l; ++i) {
if (listeners[i] === listener) {
return listeners.splice(i, 1);
}
}
};

UploadProgress.prototype.dispatchEvent = function dispatchEvent(event) {
var listeners = this.eventListeners[event.type] || [];

for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
listener(event);
}
};

// Note that for FakeXMLHttpRequest to work pre ES5
// we lose some of the alignment with the spec.
// To ensure as close a match as possible,
// set responseType before calling open, send or respond;
function FakeXMLHttpRequest() {
this.readyState = FakeXMLHttpRequest.UNSENT;
this.requestHeaders = {};
this.requestBody = null;
this.status = 0;
this.statusText = "";
this.upload = new UploadProgress();
this.responseType = "";
this.response = "";
if (sinonXhr.supportsCORS) {
this.withCredentials = false;
}

var xhr = this;
var events = [«loadstart», «load», «abort», «loadend»];

function addEventListener(eventName) {
xhr.addEventListener(eventName, function (event) {
var listener = xhr[«on» + eventName];

if (listener && typeof listener === «function») {
listener.call(this, event);
}
});
}

for (var i = events.length — 1; i >= 0; i--) {
addEventListener(events[i]);
}

if (typeof FakeXMLHttpRequest.onCreate === «function») {
FakeXMLHttpRequest.onCreate(this);
}
}

function verifyState(xhr) {
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
throw new Error(«INVALID_STATE_ERR»);
}

if (xhr.sendFlag) {
throw new Error(«INVALID_STATE_ERR»);
}
}

function getHeader(headers, header) {
header = header.toLowerCase();

for (var h in headers) {
if (h.toLowerCase() === header) {
return h;
}
}

return null;
}

// filtering to enable a white-list version of Sinon FakeXhr,
// where whitelisted requests are passed through to real XHR
function each(collection, callback) {
if (!collection) {
return;
}

for (var i = 0, l = collection.length; i < l; i += 1) {
callback(collection[i]);
}
}
function some(collection, callback) {
for (var index = 0; index < collection.length; index++) {
if (callback(collection[index]) === true) {
return true;
}
}
return false;
}
// largest arity in XHR is 5 — XHR#open
var apply = function (obj, method, args) {
switch (args.length) {
case 0: return obj[method]();
case 1: return obj[method](args[0]);
case 2: return obj[method](args[0], args[1]);
case 3: return obj[method](args[0], args[1], args[2]);
case 4: return obj[method](args[0], args[1], args[2], args[3]);
case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]);
}
};

FakeXMLHttpRequest.filters = [];
FakeXMLHttpRequest.addFilter = function addFilter(fn) {
this.filters.push(fn);
};
var IE6Re = /MSIE 6/;
FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) {
var xhr = new sinonXhr.workingXHR(); // eslint-disable-line new-cap

each([
«open»,
«setRequestHeader»,
«send»,
«abort»,
«getResponseHeader»,
«getAllResponseHeaders»,
«addEventListener»,
«overrideMimeType»,
«removeEventListener»
], function (method) {
fakeXhr[method] = function () {
return apply(xhr, method, arguments);
};
});

var copyAttrs = function (args) {
each(args, function (attr) {
try {
fakeXhr[attr] = xhr[attr];
} catch (e) {
if (!IE6Re.test(navigator.userAgent)) {
throw e;
}
}
});
};

var stateChange = function stateChange() {
fakeXhr.readyState = xhr.readyState;
if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) {
copyAttrs([«status», «statusText»]);
}
if (xhr.readyState >= FakeXMLHttpRequest.LOADING) {
copyAttrs([«responseText», «response»]);
}
if (xhr.readyState === FakeXMLHttpRequest.DONE) {
copyAttrs([«responseXML»]);
}
if (fakeXhr.onreadystatechange) {
fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
}
};

if (xhr.addEventListener) {
for (var event in fakeXhr.eventListeners) {
if (fakeXhr.eventListeners.hasOwnProperty(event)) {

/*eslint-disable no-loop-func*/
each(fakeXhr.eventListeners[event], function (handler) {
xhr.addEventListener(event, handler);
});
/*eslint-enable no-loop-func*/
}
}
xhr.addEventListener(«readystatechange», stateChange);
} else {
xhr.onreadystatechange = stateChange;
}
apply(xhr, «open», xhrArgs);
};
FakeXMLHttpRequest.useFilters = false;

function verifyRequestOpened(xhr) {
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
throw new Error(«INVALID_STATE_ERR — » + xhr.readyState);
}
}

function verifyRequestSent(xhr) {
if (xhr.readyState === FakeXMLHttpRequest.DONE) {
throw new Error(«Request done»);
}
}

function verifyHeadersReceived(xhr) {
if (xhr.async && xhr.readyState !== FakeXMLHttpRequest.HEADERS_RECEIVED) {
throw new Error(«No headers received»);
}
}

function verifyResponseBodyType(body) {
if (typeof body !== «string») {
var error = new Error(«Attempted to respond to fake XMLHttpRequest with » +
body + ", which is not a string.");
error.name = «InvalidBodyException»;
throw error;
}
}

function convertToArrayBuffer(body) {
var buffer = new ArrayBuffer(body.length);
var view = new Uint8Array(buffer);
for (var i = 0; i < body.length; i++) {
var charCode = body.charCodeAt(i);
if (charCode >= 256) {
throw new TypeError(«arraybuffer or blob responseTypes require binary string, » +
«invalid character » + body[i] + " found.");
}
view[i] = charCode;
}
return buffer;
}

function isXmlContentType(contentType) {
return !contentType || /(text\/xml)|(application\/xml)|(\+xml)/.test(contentType);
}

function convertResponseBody(responseType, contentType, body) {
if (responseType === "" || responseType === «text») {
return body;
} else if (supportsArrayBuffer && responseType === «arraybuffer») {
return convertToArrayBuffer(body);
} else if (responseType === «json») {
try {
return JSON.parse(body);
} catch (e) {
// Return parsing failure as null
return null;
}
} else if (supportsBlob && responseType === «blob») {
var blobOptions = {};
if (contentType) {
blobOptions.type = contentType;
}
return new Blob([convertToArrayBuffer(body)], blobOptions);
} else if (responseType === «document») {
if (isXmlContentType(contentType)) {
return FakeXMLHttpRequest.parseXML(body);
}
return null;
}
throw new Error(«Invalid responseType » + responseType);
}

function clearResponse(xhr) {
if (xhr.responseType === "" || xhr.responseType === «text») {
xhr.response = xhr.responseText = "";
} else {
xhr.response = xhr.responseText = null;
}
xhr.responseXML = null;
}

FakeXMLHttpRequest.parseXML = function parseXML(text) {
// Treat empty string as parsing failure
if (text !== "") {
try {
if (typeof DOMParser !== «undefined») {
var parser = new DOMParser();
return parser.parseFromString(text, «text/xml»);
}
var xmlDoc = new window.ActiveXObject(«Microsoft.XMLDOM»);
xmlDoc.async = «false»;
xmlDoc.loadXML(text);
return xmlDoc;
} catch (e) {
// Unable to parse XML — no biggie
}
}

return null;
};

FakeXMLHttpRequest.statusCodes = {
100: «Continue»,
101: «Switching Protocols»,
200: «OK»,
201: «Created»,
202: «Accepted»,
203: «Non-Authoritative Information»,
204: «No Content»,
205: «Reset Content»,
206: «Partial Content»,
207: «Multi-Status»,
300: «Multiple Choice»,
301: «Moved Permanently»,
302: «Found»,
303: «See Other»,
304: «Not Modified»,
305: «Use Proxy»,
307: «Temporary Redirect»,
400: «Bad Request»,
401: «Unauthorized»,
402: «Payment Required»,
403: «Forbidden»,
404: «Not Found»,
405: «Method Not Allowed»,
406: «Not Acceptable»,
407: «Proxy Authentication Required»,
408: «Request Timeout»,
409: «Conflict»,
410: «Gone»,
411: «Length Required»,
412: «Precondition Failed»,
413: «Request Entity Too Large»,
414: «Request-URI Too Long»,
415: «Unsupported Media Type»,
416: «Requested Range Not Satisfiable»,
417: «Expectation Failed»,
422: «Unprocessable Entity»,
500: «Internal Server Error»,
501: «Not Implemented»,
502: «Bad Gateway»,
503: «Service Unavailable»,
504: «Gateway Timeout»,
505: «HTTP Version Not Supported»
};

function makeApi(sinon) {
sinon.xhr = sinonXhr;

sinon.extend(FakeXMLHttpRequest.prototype, sinon.EventTarget, {
async: true,

open: function open(method, url, async, username, password) {
this.method = method;
this.url = url;
this.async = typeof async === «boolean»? async: true;
this.username = username;
this.password = password;
clearResponse(this);
this.requestHeaders = {};
this.sendFlag = false;

if (FakeXMLHttpRequest.useFilters === true) {
var xhrArgs = arguments;
var defake = some(FakeXMLHttpRequest.filters, function (filter) {
return filter.apply(this, xhrArgs);
});
if (defake) {
return FakeXMLHttpRequest.defake(this, arguments);
}
}
this.readyStateChange(FakeXMLHttpRequest.OPENED);
},

readyStateChange: function readyStateChange(state) {
this.readyState = state;

var readyStateChangeEvent = new sinon.Event(«readystatechange», false, false, this);

if (typeof this.onreadystatechange === «function») {
try {
this.onreadystatechange(readyStateChangeEvent);
} catch (e) {
sinon.logError(«Fake XHR onreadystatechange handler», e);
}
}

switch (this.readyState) {
case FakeXMLHttpRequest.DONE:
if (supportsProgress) {
this.upload.dispatchEvent(new sinon.ProgressEvent(«progress», {loaded: 100, total: 100}));
this.dispatchEvent(new sinon.ProgressEvent(«progress», {loaded: 100, total: 100}));
}
this.upload.dispatchEvent(new sinon.Event(«load», false, false, this));
this.dispatchEvent(new sinon.Event(«load», false, false, this));
this.dispatchEvent(new sinon.Event(«loadend», false, false, this));
break;
}

this.dispatchEvent(readyStateChangeEvent);
},

setRequestHeader: function setRequestHeader(header, value) {
verifyState(this);

if (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header)) {
throw new Error(«Refused to set unsafe header \»" + header + "\"");
}

if (this.requestHeaders[header]) {
this.requestHeaders[header] += "," + value;
} else {
this.requestHeaders[header] = value;
}
},

// Helps testing
setResponseHeaders: function setResponseHeaders(headers) {
verifyRequestOpened(this);
this.responseHeaders = {};

for (var header in headers) {
if (headers.hasOwnProperty(header)) {
this.responseHeaders[header] = headers[header];
}
}

if (this.async) {
this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
} else {
this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
}
},

// Currently treats ALL data as a DOMString (i.e. no Document)
send: function send(data) {
verifyState(this);

if (!/^(get|head)$/i.test(this.method)) {
var contentType = getHeader(this.requestHeaders, «Content-Type»);
if (this.requestHeaders[contentType]) {
var value = this.requestHeaders[contentType].split(";");
this.requestHeaders[contentType] = value[0] + ";charset=utf-8";
} else if (supportsFormData && !(data instanceof FormData)) {
this.requestHeaders[«Content-Type»] = «text/plain;charset=utf-8»;
}

this.requestBody = data;
}

this.errorFlag = false;
this.sendFlag = this.async;
clearResponse(this);
this.readyStateChange(FakeXMLHttpRequest.OPENED);

if (typeof this.onSend === «function») {
this.onSend(this);
}

this.dispatchEvent(new sinon.Event(«loadstart», false, false, this));
},

abort: function abort() {
this.aborted = true;
clearResponse(this);
this.errorFlag = true;
this.requestHeaders = {};
this.responseHeaders = {};

if (this.readyState > FakeXMLHttpRequest.UNSENT && this.sendFlag) {
this.readyStateChange(FakeXMLHttpRequest.DONE);
this.sendFlag = false;
}

this.readyState = FakeXMLHttpRequest.UNSENT;

this.dispatchEvent(new sinon.Event(«abort», false, false, this));

this.upload.dispatchEvent(new sinon.Event(«abort», false, false, this));

if (typeof this.onerror === «function») {
this.onerror();
}
},

getResponseHeader: function getResponseHeader(header) {
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
return null;
}

if (/^Set-Cookie2?$/i.test(header)) {
return null;
}

header = getHeader(this.responseHeaders, header);

return this.responseHeaders[header] || null;
},

getAllResponseHeaders: function getAllResponseHeaders() {
if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) {
return "";
}

var headers = "";

for (var header in this.responseHeaders) {
if (this.responseHeaders.hasOwnProperty(header) &&
!/^Set-Cookie2?$/i.test(header)) {
headers += header + ": " + this.responseHeaders[header] + "\r\n";
}
}

return headers;
},

setResponseBody: function setResponseBody(body) {
verifyRequestSent(this);
verifyHeadersReceived(this);
verifyResponseBodyType(body);
var contentType = this.getResponseHeader(«Content-Type»);

var isTextResponse = this.responseType === "" || this.responseType === «text»;
clearResponse(this);
if (this.async) {
var chunkSize = this.chunkSize || 10;
var index = 0;

do {
this.readyStateChange(FakeXMLHttpRequest.LOADING);

if (isTextResponse) {
this.responseText = this.response += body.substring(index, index + chunkSize);
}
index += chunkSize;
} while (index < body.length);
}

this.response = convertResponseBody(this.responseType, contentType, body);
if (isTextResponse) {
this.responseText = this.response;
}

if (this.responseType === «document») {
this.responseXML = this.response;
} else if (this.responseType === "" && isXmlContentType(contentType)) {
this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText);
}
this.readyStateChange(FakeXMLHttpRequest.DONE);
},

respond: function respond(status, headers, body) {
this.status = typeof status === «number»? status: 200;
this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
this.setResponseHeaders(headers || {});
this.setResponseBody(body || "");
},

uploadProgress: function uploadProgress(progressEventRaw) {
if (supportsProgress) {
this.upload.dispatchEvent(new sinon.ProgressEvent(«progress», progressEventRaw));
}
},

downloadProgress: function downloadProgress(progressEventRaw) {
if (supportsProgress) {
this.dispatchEvent(new sinon.ProgressEvent(«progress», progressEventRaw));
}
},

uploadError: function uploadError(error) {
if (supportsCustomEvent) {
this.upload.dispatchEvent(new sinon.CustomEvent(«error», {detail: error}));
}
}
});

sinon.extend(FakeXMLHttpRequest, {
UNSENT: 0,
OPENED: 1,
HEADERS_RECEIVED: 2,
LOADING: 3,
DONE: 4
});

sinon.useFakeXMLHttpRequest = function () {
FakeXMLHttpRequest.restore = function restore(keepOnCreate) {
if (sinonXhr.supportsXHR) {
global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest;
}

if (sinonXhr.supportsActiveX) {
global.ActiveXObject = sinonXhr.GlobalActiveXObject;
}

delete FakeXMLHttpRequest.restore;

if (keepOnCreate !== true) {
delete FakeXMLHttpRequest.onCreate;
}
};
if (sinonXhr.supportsXHR) {
global.XMLHttpRequest = FakeXMLHttpRequest;
}

if (sinonXhr.supportsActiveX) {
global.ActiveXObject = function ActiveXObject(objId) {
if (objId === «Microsoft.XMLHTTP» || /^Msxml2\.XMLHTTP/i.test(objId)) {

return new FakeXMLHttpRequest();
}

return new sinonXhr.GlobalActiveXObject(objId);
};
}

return FakeXMLHttpRequest;
};

sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./core");
require("../extend");
require("./event");
require("../log_error");
makeApi(sinon);
module.exports = sinon;
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon, // eslint-disable-line no-undef
typeof global !== «undefined»? global: self
));

/**
* depend fake_xdomain_request.js
* depend fake_xml_http_request.js
* depend ../format.js
* depend ../log_error.js
*/
/**
* The Sinon «server» mimics a web server that receives requests from
* sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
* both synchronously and asynchronously. To respond synchronuously, canned
* answers have to be provided upfront.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function () {

var push = [].push;

function responseArray(handler) {
var response = handler;

if (Object.prototype.toString.call(handler) !== "[object Array]") {
response = [200, {}, handler];
}

if (typeof response[2] !== «string») {
throw new TypeError(«Fake server response body should be string, but was » +
typeof response[2]);
}

return response;
}

var wloc = typeof window !== «undefined»? window.location: {};
var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host);

function matchOne(response, reqMethod, reqUrl) {
var rmeth = response.method;
var matchMethod = !rmeth || rmeth.toLowerCase() === reqMethod.toLowerCase();
var url = response.url;
var matchUrl = !url || url === reqUrl || (typeof url.test === «function» && url.test(reqUrl));

return matchMethod && matchUrl;
}

function match(response, request) {
var requestUrl = request.url;

if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
requestUrl = requestUrl.replace(rCurrLoc, "");
}

if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
if (typeof response.response === «function») {
var ru = response.url;
var args = [request].concat(ru && typeof ru.exec === «function»? ru.exec(requestUrl).slice(1): []);
return response.response.apply(response, args);
}

return true;
}

return false;
}

function makeApi(sinon) {
sinon.fakeServer = {
create: function (config) {
var server = sinon.create(this);
server.configure(config);
if (!sinon.xhr.supportsCORS) {
this.xhr = sinon.useFakeXDomainRequest();
} else {
this.xhr = sinon.useFakeXMLHttpRequest();
}
server.requests = [];

this.xhr.onCreate = function (xhrObj) {
server.addRequest(xhrObj);
};

return server;
},
configure: function (config) {
var whitelist = {
«autoRespond»: true,
«autoRespondAfter»: true,
«respondImmediately»: true,
«fakeHTTPMethods»: true
};
var setting;

config = config || {};
for (setting in config) {
if (whitelist.hasOwnProperty(setting) && config.hasOwnProperty(setting)) {
this[setting] = config[setting];
}
}
},
addRequest: function addRequest(xhrObj) {
var server = this;
push.call(this.requests, xhrObj);

xhrObj.onSend = function () {
server.handleRequest(this);

if (server.respondImmediately) {
server.respond();
} else if (server.autoRespond && !server.responding) {
setTimeout(function () {
server.responding = false;
server.respond();
}, server.autoRespondAfter || 10);

server.responding = true;
}
};
},

getHTTPMethod: function getHTTPMethod(request) {
if (this.fakeHTTPMethods && /post/i.test(request.method)) {
var matches = (request.requestBody || "").match(/_method=([^\b;]+)/);
return matches? matches[1]: request.method;
}

return request.method;
},

handleRequest: function handleRequest(xhr) {
if (xhr.async) {
if (!this.queue) {
this.queue = [];
}

push.call(this.queue, xhr);
} else {
this.processRequest(xhr);
}
},

log: function log(response, request) {
var str;

str = «Request:\n» + sinon.format(request) + "\n\n";
str += «Response:\n» + sinon.format(response) + "\n\n";

sinon.log(str);
},

respondWith: function respondWith(method, url, body) {
if (arguments.length === 1 && typeof method !== «function») {
this.response = responseArray(method);
return;
}

if (!this.responses) {
this.responses = [];
}

if (arguments.length === 1) {
body = method;
url = method = null;
}

if (arguments.length === 2) {
body = url;
url = method;
method = null;
}

push.call(this.responses, {
method: method,
url: url,
response: typeof body === «function»? body: responseArray(body)
});
},

respond: function respond() {
if (arguments.length > 0) {
this.respondWith.apply(this, arguments);
}

var queue = this.queue || [];
var requests = queue.splice(0, queue.length);

for (var i = 0; i < requests.length; i++) {
this.processRequest(requests[i]);
}
},

processRequest: function processRequest(request) {
try {
if (request.aborted) {
return;
}

var response = this.response || [404, {}, ""];

if (this.responses) {
for (var l = this.responses.length, i = l — 1; i >= 0; i--) {
if (match.call(this, this.responses[i], request)) {
response = this.responses[i].response;
break;
}
}
}

if (request.readyState !== 4) {
this.log(response, request);

request.respond(response[0], response[1], response[2]);
}
} catch (e) {
sinon.logError(«Fake server request processing», e);
}
},

restore: function restore() {
return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments);
}
};
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./core");
require("./fake_xdomain_request");
require("./fake_xml_http_request");
require("../format");
makeApi(sinon);
module.exports = sinon;
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require, module.exports, module);
} else {
makeApi(sinon); // eslint-disable-line no-undef
}
}());

/**
* depend fake_server.js
* depend fake_timers.js
*/
/**
* Add-on for sinon.fakeServer that automatically handles a fake timer along with
* the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
* 1.3.x, which does not use xhr object's onreadystatehandler at all — instead,
* it polls the object for completion with setInterval. Dispite the direct
* motivation, there is nothing jQuery-specific in this file, so it can be used
* in any environment where the ajax implementation depends on setInterval or
* setTimeout.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function () {

function makeApi(sinon) {
function Server() {}
Server.prototype = sinon.fakeServer;

sinon.fakeServerWithClock = new Server();

sinon.fakeServerWithClock.addRequest = function addRequest(xhr) {
if (xhr.async) {
if (typeof setTimeout.clock === «object») {
this.clock = setTimeout.clock;
} else {
this.clock = sinon.useFakeTimers();
this.resetClock = true;
}

if (!this.longestTimeout) {
var clockSetTimeout = this.clock.setTimeout;
var clockSetInterval = this.clock.setInterval;
var server = this;

this.clock.setTimeout = function (fn, timeout) {
server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);

return clockSetTimeout.apply(this, arguments);
};

this.clock.setInterval = function (fn, timeout) {
server.longestTimeout = Math.max(timeout, server.longestTimeout || 0);

return clockSetInterval.apply(this, arguments);
};
}
}

return sinon.fakeServer.addRequest.call(this, xhr);
};

sinon.fakeServerWithClock.respond = function respond() {
var returnVal = sinon.fakeServer.respond.apply(this, arguments);

if (this.clock) {
this.clock.tick(this.longestTimeout || 0);
this.longestTimeout = 0;

if (this.resetClock) {
this.clock.restore();
this.resetClock = false;
}
}

return returnVal;
};

sinon.fakeServerWithClock.restore = function restore() {
if (this.clock) {
this.clock.restore();
}

return sinon.fakeServer.restore.apply(this, arguments);
};
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require) {
var sinon = require("./core");
require("./fake_server");
require("./fake_timers");
makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require);
} else {
makeApi(sinon); // eslint-disable-line no-undef
}
}());

/**
* depend util/core.js
* depend extend.js
* depend collection.js
* depend util/fake_timers.js
* depend util/fake_server_with_clock.js
*/
/**
* Manages fake collections as well as fake utilities such as Sinon's
* timers and fake XHR implementation in one convenient object.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

function makeApi(sinon) {
var push = [].push;

function exposeValue(sandbox, config, key, value) {
if (!value) {
return;
}

if (config.injectInto && !(key in config.injectInto)) {
config.injectInto[key] = value;
sandbox.injectedKeys.push(key);
} else {
push.call(sandbox.args, value);
}
}

function prepareSandboxFromConfig(config) {
var sandbox = sinon.create(sinon.sandbox);

if (config.useFakeServer) {
if (typeof config.useFakeServer === «object») {
sandbox.serverPrototype = config.useFakeServer;
}

sandbox.useFakeServer();
}

if (config.useFakeTimers) {
if (typeof config.useFakeTimers === «object») {
sandbox.useFakeTimers.apply(sandbox, config.useFakeTimers);
} else {
sandbox.useFakeTimers();
}
}

return sandbox;
}

sinon.sandbox = sinon.extend(sinon.create(sinon.collection), {
useFakeTimers: function useFakeTimers() {
this.clock = sinon.useFakeTimers.apply(sinon, arguments);

return this.add(this.clock);
},

serverPrototype: sinon.fakeServer,

useFakeServer: function useFakeServer() {
var proto = this.serverPrototype || sinon.fakeServer;

if (!proto || !proto.create) {
return null;
}

this.server = proto.create();
return this.add(this.server);
},

inject: function (obj) {
sinon.collection.inject.call(this, obj);

if (this.clock) {
obj.clock = this.clock;
}

if (this.server) {
obj.server = this.server;
obj.requests = this.server.requests;
}

obj.match = sinon.match;

return obj;
},

restore: function () {
sinon.collection.restore.apply(this, arguments);
this.restoreContext();
},

restoreContext: function () {
if (this.injectedKeys) {
for (var i = 0, j = this.injectedKeys.length; i < j; i++) {
delete this.injectInto[this.injectedKeys[i]];
}
this.injectedKeys = [];
}
},

create: function (config) {
if (!config) {
return sinon.create(sinon.sandbox);
}

var sandbox = prepareSandboxFromConfig(config);
sandbox.args = sandbox.args || [];
sandbox.injectedKeys = [];
sandbox.injectInto = config.injectInto;
var prop,
value;
var exposed = sandbox.inject({});

if (config.properties) {
for (var i = 0, l = config.properties.length; i < l; i++) {
prop = config.properties[i];
value = exposed[prop] || prop === «sandbox» && sandbox;
exposeValue(sandbox, config, prop, value);
}
} else {
exposeValue(sandbox, config, «sandbox», value);
}

return sandbox;
},

match: sinon.match
});

sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;

return sinon.sandbox;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./extend");
require("./util/fake_server_with_clock");
require("./util/fake_timers");
require("./collection");
module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend util/core.js
* depend sandbox.js
*/
/**
* Test function, sandboxes fakes
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

function makeApi(sinon) {
var slice = Array.prototype.slice;

function test(callback) {
var type = typeof callback;

if (type !== «function») {
throw new TypeError(«sinon.test needs to wrap a test function, got » + type);
}

function sinonSandboxedTest() {
var config = sinon.getConfig(sinon.config);
config.injectInto = config.injectIntoThis && this || config.injectInto;
var sandbox = sinon.sandbox.create(config);
var args = slice.call(arguments);
var oldDone = args.length && args[args.length — 1];
var exception, result;

if (typeof oldDone === «function») {
args[args.length — 1] = function sinonDone(res) {
if (res) {
sandbox.restore();
} else {
sandbox.verifyAndRestore();
}
oldDone(res);
};
}

try {
result = callback.apply(this, args.concat(sandbox.args));
} catch (e) {
exception = e;
}

if (typeof oldDone !== «function») {
if (typeof exception !== «undefined») {
sandbox.restore();
throw exception;
} else {
sandbox.verifyAndRestore();
}
}

return result;
}

if (callback.length) {
return function sinonAsyncSandboxedTest(done) { // eslint-disable-line no-unused-vars
return sinonSandboxedTest.apply(this, arguments);
};
}

return sinonSandboxedTest;
}

test.config = {
injectIntoThis: true,
injectInto: null,
properties: [«spy», «stub», «mock», «clock», «server», «requests»],
useFakeTimers: true,
useFakeServer: true
};

sinon.test = test;
return test;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var core = require("./util/core");
require("./sandbox");
module.exports = makeApi(core);
}

if (isAMD) {
define(loadDependencies);
} else if (isNode) {
loadDependencies(require, module.exports, module);
} else if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(typeof sinon === «object» && sinon || null)); // eslint-disable-line no-undef

/**
* depend util/core.js
* depend test.js
*/
/**
* Test case, sandboxes all test functions
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal) {

function createTest(property, setUp, tearDown) {
return function () {
if (setUp) {
setUp.apply(this, arguments);
}

var exception, result;

try {
result = property.apply(this, arguments);
} catch (e) {
exception = e;
}

if (tearDown) {
tearDown.apply(this, arguments);
}

if (exception) {
throw exception;
}

return result;
};
}

function makeApi(sinon) {
function testCase(tests, prefix) {
if (!tests || typeof tests !== «object») {
throw new TypeError(«sinon.testCase needs an object with test functions»);
}

prefix = prefix || «test»;
var rPrefix = new RegExp("^" + prefix);
var methods = {};
var setUp = tests.setUp;
var tearDown = tests.tearDown;
var testName,
property,
method;

for (testName in tests) {
if (tests.hasOwnProperty(testName) && !/^(setUp|tearDown)$/.test(testName)) {
property = tests[testName];

if (typeof property === «function» && rPrefix.test(testName)) {
method = property;

if (setUp || tearDown) {
method = createTest(property, setUp, tearDown);
}

methods[testName] = sinon.test(method);
} else {
methods[testName] = tests[testName];
}
}
}

return methods;
}

sinon.testCase = testCase;
return testCase;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var core = require("./util/core");
require("./test");
module.exports = makeApi(core);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon // eslint-disable-line no-undef
));

/**
* depend times_in_words.js
* depend util/core.js
* depend match.js
* depend format.js
*/
/**
* Assertions matching the test spy retrieval interface.
*
* author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright 2010-2013 Christian Johansen
*/
(function (sinonGlobal, global) {

var slice = Array.prototype.slice;

function makeApi(sinon) {
var assert;

function verifyIsStub() {
var method;

for (var i = 0, l = arguments.length; i < l; ++i) {
method = arguments[i];

if (!method) {
assert.fail(«fake is not a spy»);
}

if (method.proxy && method.proxy.isSinonProxy) {
verifyIsStub(method.proxy);
} else {
if (typeof method !== «function») {
assert.fail(method + " is not a function");
}

if (typeof method.getCall !== «function») {
assert.fail(method + " is not stubbed");
}
}

}
}

function failAssertion(object, msg) {
object = object || global;
var failMethod = object.fail || assert.fail;
failMethod.call(object, msg);
}

function mirrorPropAsAssertion(name, method, message) {
if (arguments.length === 2) {
message = method;
method = name;
}

assert[name] = function (fake) {
verifyIsStub(fake);

var args = slice.call(arguments, 1);
var failed = false;

if (typeof method === «function») {
failed = !method(fake);
} else {
failed = typeof fake[method] === «function»?
!fake[method].apply(fake, args): !fake[method];
}

if (failed) {
failAssertion(this, (fake.printf || fake.proxy.printf).apply(fake, [message].concat(args)));
} else {
assert.pass(name);
}
};
}

function exposedName(prefix, prop) {
return !prefix || /^fail/.test(prop)? prop:
prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
}

assert = {
failException: «AssertError»,

fail: function fail(message) {
var error = new Error(message);
error.name = this.failException || assert.failException;

throw error;
},

pass: function pass() {},

callOrder: function assertCallOrder() {
verifyIsStub.apply(null, arguments);
var expected = "";
var actual = "";

if (!sinon.calledInOrder(arguments)) {
try {
expected = [].join.call(arguments, ", ");
var calls = slice.call(arguments);
var i = calls.length;
while (i) {
if (!calls[--i].called) {
calls.splice(i, 1);
}
}
actual = sinon.orderByFirstCall(calls).join(", ");
} catch (e) {
// If this fails, we'll just fall back to the blank string
}

failAssertion(this, «expected » + expected + " to be " +
«called in order but were called as » + actual);
} else {
assert.pass(«callOrder»);
}
},

callCount: function assertCallCount(method, count) {
verifyIsStub(method);

if (method.callCount !== count) {
var msg = «expected %n to be called » + sinon.timesInWords(count) +
" but was called %c%C";
failAssertion(this, method.printf(msg));
} else {
assert.pass(«callCount»);
}
},

expose: function expose(target, options) {
if (!target) {
throw new TypeError(«target is null or undefined»);
}

var o = options || {};
var prefix = typeof o.prefix === «undefined» && «assert» || o.prefix;
var includeFail = typeof o.includeFail === «undefined» || !!o.includeFail;

for (var method in this) {
if (method !== «expose» && (includeFail || !/^(fail)/.test(method))) {
target[exposedName(prefix, method)] = this[method];
}
}

return target;
},

match: function match(actual, expectation) {
var matcher = sinon.match(expectation);
if (matcher.test(actual)) {
assert.pass(«match»);
} else {
var formatted = [
«expected value to match»,
" expected = " + sinon.format(expectation),
" actual = " + sinon.format(actual)
];

failAssertion(this, formatted.join("\n"));
}
}
};

mirrorPropAsAssertion(«called», «expected %n to have been called at least once but was never called»);
mirrorPropAsAssertion(«notCalled», function (spy) {
return !spy.called;
}, «expected %n to not have been called but was called %c%C»);
mirrorPropAsAssertion(«calledOnce», «expected %n to be called once but was called %c%C»);
mirrorPropAsAssertion(«calledTwice», «expected %n to be called twice but was called %c%C»);
mirrorPropAsAssertion(«calledThrice», «expected %n to be called thrice but was called %c%C»);
mirrorPropAsAssertion(«calledOn», «expected %n to be called with %1 as this but was called with %t»);
mirrorPropAsAssertion(
«alwaysCalledOn»,
«expected %n to always be called with %1 as this but was called with %t»
);
mirrorPropAsAssertion(«calledWithNew», «expected %n to be called with new»);
mirrorPropAsAssertion(«alwaysCalledWithNew», «expected %n to always be called with new»);
mirrorPropAsAssertion(«calledWith», «expected %n to be called with arguments %*%C»);
mirrorPropAsAssertion(«calledWithMatch», «expected %n to be called with match %*%C»);
mirrorPropAsAssertion(«alwaysCalledWith», «expected %n to always be called with arguments %*%C»);
mirrorPropAsAssertion(«alwaysCalledWithMatch», «expected %n to always be called with match %*%C»);
mirrorPropAsAssertion(«calledWithExactly», «expected %n to be called with exact arguments %*%C»);
mirrorPropAsAssertion(«alwaysCalledWithExactly», «expected %n to always be called with exact arguments %*%C»);
mirrorPropAsAssertion(«neverCalledWith», «expected %n to never be called with arguments %*%C»);
mirrorPropAsAssertion(«neverCalledWithMatch», «expected %n to never be called with match %*%C»);
mirrorPropAsAssertion(«threw», "%n did not throw exception%C");
mirrorPropAsAssertion(«alwaysThrew», "%n did not always throw exception%C");

sinon.assert = assert;
return assert;
}

var isNode = typeof module !== «undefined» && module.exports && typeof require === «function»;
var isAMD = typeof define === «function» && typeof define.amd === «object» && define.amd;

function loadDependencies(require, exports, module) {
var sinon = require("./util/core");
require("./match");
require("./format");
module.exports = makeApi(sinon);
}

if (isAMD) {
define(loadDependencies);
return;
}

if (isNode) {
loadDependencies(require, module.exports, module);
return;
}

if (sinonGlobal) {
makeApi(sinonGlobal);
}
}(
typeof sinon === «object» && sinon, // eslint-disable-line no-undef
typeof global !== «undefined»? global: self
));

return sinon;
}));

This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.

Комментариев нет:

Отправить комментарий