Commit 866c258c authored by JC Brand's avatar JC Brand

Created new builds. Updates #339.

parent 7cd27a71
/**
* @license almond 0.3.0 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/almond for details
*/
......@@ -44,12 +44,6 @@ var requirejs, require, define;
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
//Convert baseName to array, and lop off the last part,
//so that . matches that "directory" and not name of the baseName's
//module. For instance, baseName of "one/two/three", maps to
//"one/two/three.js", but we want the directory, "one/two" for
//this normalization.
baseParts = baseParts.slice(0, baseParts.length - 1);
name = name.split('/');
lastIndex = name.length - 1;
......@@ -58,7 +52,11 @@ var requirejs, require, define;
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
}
name = baseParts.concat(name);
//Lop off the last part of baseParts, so that . matches the
//"directory" and not name of the baseName's module. For instance,
//baseName of "one/two/three", maps to "one/two/three.js", but we
//want the directory, "one/two" for this normalization.
name = baseParts.slice(0, baseParts.length - 1).concat(name);
//start trimDots
for (i = 0; i < name.length; i += 1) {
......@@ -408,6 +406,9 @@ var requirejs, require, define;
requirejs._defined = defined;
define = function (name, deps, callback) {
if (typeof name !== 'string') {
throw new Error('See almond README: incorrect module build, no module name');
}
//This module may not have dependencies
if (!deps.splice) {
......@@ -11164,9 +11165,9 @@ define('text',['module'], function (module) {
return text;
});
// Underscore.js 1.6.0
// Underscore.js 1.8.2
// http://underscorejs.org
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
......@@ -11180,9 +11181,6 @@ define('text',['module'], function (module) {
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
......@@ -11190,25 +11188,19 @@ define('text',['module'], function (module) {
var
push = ArrayProto.push,
slice = ArrayProto.slice,
concat = ArrayProto.concat,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
nativeBind = FuncProto.bind,
nativeCreate = Object.create;
// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
......@@ -11219,8 +11211,7 @@ define('text',['module'], function (module) {
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
// the browser, add `_` as a global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
......@@ -11231,161 +11222,208 @@ define('text',['module'], function (module) {
}
// Current version.
_.VERSION = '1.6.0';
_.VERSION = '1.8.2';
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var optimizeCb = function(func, context, argCount) {
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function(value) {
return func.call(context, value);
};
case 2: return function(value, other) {
return func.call(context, value, other);
};
case 3: return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
// A mostly-internal function to generate callbacks that can be applied
// to each element in a collection, returning the desired result — either
// identity, an arbitrary callback, a property matcher, or a property accessor.
var cb = function(value, context, argCount) {
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value)) return _.matcher(value);
return _.property(value);
};
_.iteratee = function(value, context) {
return cb(value, context, Infinity);
};
// An internal function for creating assigner functions.
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var isArrayLike = function(collection) {
var length = collection && collection.length;
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results.push(iterator.call(context, value, index, list));
});
// Return the results of applying the iteratee to each element.
_.map = _.collect = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
results = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
var reduceError = 'Reduce of empty array with no initial value';
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
// Create a reducing function iterating left or right.
function createReduce(dir) {
// Optimized iterator function as using arguments.length
// in the main function will deoptimize the, see #1991.
function iterator(obj, iteratee, memo, keys, index, length) {
for (; index >= 0 && index < length; index += dir) {
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var length = obj.length;
if (length !== +length) {
var keys = _.keys(obj);
length = keys.length;
}
each(obj, function(value, index, list) {
index = keys ? keys[--length] : --length;
if (!initial) {
memo = obj[index];
initial = true;
} else {
memo = iterator.call(context, memo, obj[index], index, list);
return function(obj, iteratee, memo, context) {
iteratee = optimizeCb(iteratee, context, 4);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
index = dir > 0 ? 0 : length - 1;
// Determine the initial value if none is provided.
if (arguments.length < 3) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
return iterator(obj, iteratee, memo, keys, index, length);
};
}
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`.
_.reduce = _.foldl = _.inject = createReduce(1);
// The right-associative version of reduce, also known as `foldr`.
_.reduceRight = _.foldr = createReduce(-1);
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, predicate, context) {
var result;
any(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) {
result = value;
return true;
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
});
return result;
if (key !== void 0 && key !== -1) return obj[key];
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) results.push(value);
predicate = cb(predicate, context);
_.each(obj, function(value, index, list) {
if (predicate(value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) {
return !predicate.call(context, value, index, list);
}, context);
return _.filter(obj, _.negate(cb(predicate)), context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) {
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});
return !!result;
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (!predicate(obj[currentKey], currentKey, obj)) return false;
}
return true;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
_.some = _.any = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (predicate(obj[currentKey], currentKey, obj)) return true;
}
return false;
};
// Determine if the array or object contains a given value (using `===`).
// Aliased as `include`.
_.contains = _.include = function(obj, target) {
if (obj == null) return false;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
return any(obj, function(value) {
return value === target;
});
// Aliased as `includes` and `include`.
_.contains = _.includes = _.include = function(obj, target, fromIndex) {
if (!isArrayLike(obj)) obj = _.values(obj);
return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0;
};
// Invoke a method (with arguments) on every item in a collection.
......@@ -11393,7 +11431,8 @@ define('text',['module'], function (module) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
return (isFunc ? method : value[method]).apply(value, args);
var func = isFunc ? method : value[method];
return func == null ? func : func.apply(value, args);
});
};
......@@ -11405,60 +11444,76 @@ define('text',['module'], function (module) {
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs) {
return _.filter(obj, _.matches(attrs));
return _.filter(obj, _.matcher(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.find(obj, _.matches(attrs));
return _.find(obj, _.matcher(attrs));
};
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
// Return the maximum element (or element-based computation).
_.max = function(obj, iteratee, context) {
var result = -Infinity, lastComputed = -Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value > result) {
result = value;
}
}
var result = -Infinity, lastComputed = -Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed > lastComputed) {
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj);
}
var result = Infinity, lastComputed = Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed < lastComputed) {
_.min = function(obj, iteratee, context) {
var result = Infinity, lastComputed = Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value < result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed < lastComputed || computed === Infinity && result === Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Shuffle an array, using the modern version of the
// Shuffle a collection, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
var shuffled = [];
each(obj, function(value) {
rand = _.random(index++);
shuffled[index - 1] = shuffled[rand];
shuffled[rand] = value;
});
var set = isArrayLike(obj) ? obj : _.values(obj);
var length = set.length;
var shuffled = Array(length);
for (var index = 0, rand; index < length; index++) {
rand = _.random(0, index);
if (rand !== index) shuffled[index] = shuffled[rand];
shuffled[rand] = set[index];
}
return shuffled;
};
......@@ -11467,27 +11522,20 @@ define('text',['module'], function (module) {
// The internal `guard` argument allows it to work with `map`.
_.sample = function(obj, n, guard) {
if (n == null || guard) {
if (obj.length !== +obj.length) obj = _.values(obj);
if (!isArrayLike(obj)) obj = _.values(obj);
return obj[_.random(obj.length - 1)];
}
return _.shuffle(obj).slice(0, Math.max(0, n));
};
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
if (value == null) return _.identity;
if (_.isFunction(value)) return value;
return _.property(value);
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
iterator = lookupIterator(iterator);
// Sort the object's values by a criterion produced by an iteratee.
_.sortBy = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value: value,
index: index,
criteria: iterator.call(context, value, index, list)
criteria: iteratee(value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
......@@ -11502,12 +11550,12 @@ define('text',['module'], function (module) {
// An internal function used for aggregate "group by" operations.
var group = function(behavior) {
return function(obj, iterator, context) {
return function(obj, iteratee, context) {
var result = {};
iterator = lookupIterator(iterator);
each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj);
behavior(result, key, value);
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
......@@ -11515,48 +11563,46 @@ define('text',['module'], function (module) {
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, key, value) {
_.has(result, key) ? result[key].push(value) : result[key] = [value];
_.groupBy = group(function(result, value, key) {
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_.indexBy = group(function(result, key, value) {
_.indexBy = group(function(result, value, key) {
result[key] = value;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_.countBy = group(function(result, key) {
_.has(result, key) ? result[key]++ : result[key] = 1;
_.countBy = group(function(result, value, key) {
if (_.has(result, key)) result[key]++; else result[key] = 1;
});
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) {
iterator = lookupIterator(iterator);
var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >>> 1;
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
}
return low;
};
// Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) return _.map(obj, _.identity);
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
if (obj == null) return 0;
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(obj, predicate, context) {
predicate = cb(predicate, context);
var pass = [], fail = [];
_.each(obj, function(value, key, obj) {
(predicate(value, key, obj) ? pass : fail).push(value);
});
return [pass, fail];
};
// Array Functions
......@@ -11567,33 +11613,30 @@ define('text',['module'], function (module) {
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[0];
if (n < 0) return [];
return slice.call(array, 0, n);
if (n == null || guard) return array[0];
return _.initial(array, array.length - n);
};
// Returns everything but the last entry of the array. Especially useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
// the array, excluding the last N.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
// values in the array.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[array.length - 1];
return slice.call(array, Math.max(array.length - n, 0));
if (n == null || guard) return array[array.length - 1];
return _.rest(array, Math.max(0, array.length - n));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Especially useful on the arguments object. Passing an **n** will return
// the rest N values in the array. The **guard**
// check allows it to work with `_.map`.
// the rest N values in the array.
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, (n == null) || guard ? 1 : n);
return slice.call(array, n == null || guard ? 1 : n);
};
// Trim out all falsy values from an array.
......@@ -11602,23 +11645,28 @@ define('text',['module'], function (module) {
};
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
if (shallow && _.every(input, _.isArray)) {
return concat.apply(output, input);
var flatten = function(input, shallow, strict, startIndex) {
var output = [], idx = 0;
for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
//flatten current level of array or arguments object
if (!shallow) value = flatten(value, shallow, strict);
var j = 0, len = value.length;
output.length += len;
while (j < len) {
output[idx++] = value[j++];
}
} else if (!strict) {
output[idx++] = value;
}
each(input, function(value) {
if (_.isArray(value) || _.isArguments(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
}
});
return output;
};
// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
return flatten(array, shallow, false);
};
// Return a version of the array that does not contain the specified value(s).
......@@ -11626,79 +11674,93 @@ define('text',['module'], function (module) {
return _.difference(array, slice.call(arguments, 1));
};
// Split an array into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(array, predicate) {
var pass = [], fail = [];
each(array, function(elem) {
(predicate(elem) ? pass : fail).push(elem);
});
return [pass, fail];
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator, context) {
if (_.isFunction(isSorted)) {
context = iterator;
iterator = isSorted;
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (array == null) return [];
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array;
var results = [];
if (iteratee != null) iteratee = cb(iteratee, context);
var result = [];
var seen = [];
each(initial, function(value, index) {
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
seen.push(value);
results.push(array[index]);
for (var i = 0, length = array.length; i < length; i++) {
var value = array[i],
computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== computed) result.push(value);
seen = computed;
} else if (iteratee) {
if (!_.contains(seen, computed)) {
seen.push(computed);
result.push(value);
}
});
return results;
} else if (!_.contains(result, value)) {
result.push(value);
}
}
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
return _.uniq(flatten(arguments, true, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersection = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.contains(other, item);
});
});
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
return _.filter(array, function(value){ return !_.contains(rest, value); });
var rest = flatten(arguments, true, true, 1);
return _.filter(array, function(value){
return !_.contains(rest, value);
});
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(arguments, '' + i);
return _.unzip(arguments);
};
// Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices
_.unzip = function(array) {
var length = array && _.max(array, 'length').length || 0;
var result = Array(length);
for (var index = 0; index < length; index++) {
result[index] = _.pluck(array, index);
}
return results;
return result;
};
// Converts lists into objects. Pass either a single array of `[key, value]`
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values.
_.object = function(list, values) {
if (list == null) return {};
var result = {};
for (var i = 0, length = list.length; i < length; i++) {
for (var i = 0, length = list && list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
......@@ -11708,40 +11770,68 @@ define('text',['module'], function (module) {
return result;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// Return the position of the first occurrence of an item in an array,
// or -1 if the item is not included in the array.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i = 0, length = array.length;
if (isSorted) {
var i = 0, length = array && array.length;
if (typeof isSorted == 'number') {
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
} else if (isSorted && length) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (item !== item) {
return _.findIndex(slice.call(array, i), _.isNaN);
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item, from) {
if (array == null) return -1;
var hasIndex = from != null;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
var idx = array ? array.length : 0;
if (typeof from == 'number') {
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
}
if (item !== item) {
return _.findLastIndex(slice.call(array, 0, idx), _.isNaN);
}
var i = (hasIndex ? from : array.length);
while (i--) if (array[i] === item) return i;
while (--idx >= 0) if (array[idx] === item) return idx;
return -1;
};
// Generator function to create the findIndex and findLastIndex functions
function createIndexFinder(dir) {
return function(array, predicate, context) {
predicate = cb(predicate, context);
var length = array != null && array.length;
var index = dir > 0 ? 0 : length - 1;
for (; index >= 0 && index < length; index += dir) {
if (predicate(array[index], index, array)) return index;
}
return -1;
};
}
// Returns the first index on an array-like that passes a predicate test
_.findIndex = createIndexFinder(1);
_.findLastIndex = createIndexFinder(-1);
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = array.length;
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
}
return low;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
......@@ -11750,15 +11840,13 @@ define('text',['module'], function (module) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
step = step || 1;
var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(length);
var range = Array(length);
while(idx < length) {
range[idx++] = start;
start += step;
for (var idx = 0; idx < length; idx++, start += step) {
range[idx] = start;
}
return range;
......@@ -11767,26 +11855,27 @@ define('text',['module'], function (module) {
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
if (_.isObject(result)) return result;
return self;
};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
var args, bound;
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
ctor.prototype = null;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
var args = slice.call(arguments, 2);
var bound = function() {
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
};
return bound;
};
// Partially apply a function by creating a version that has had some of its
......@@ -11794,49 +11883,55 @@ define('text',['module'], function (module) {
// as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
var boundArgs = slice.call(arguments, 1);
return function() {
var position = 0;
var args = boundArgs.slice();
for (var i = 0, length = args.length; i < length; i++) {
if (args[i] === _) args[i] = arguments[position++];
var bound = function() {
var position = 0, length = boundArgs.length;
var args = Array(length);
for (var i = 0; i < length; i++) {
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
}
while (position < arguments.length) args.push(arguments[position++]);
return func.apply(this, args);
return executeBound(func, bound, this, this, args);
};
return bound;
};
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
var i, length = arguments.length, key;
if (length <= 1) throw new Error('bindAll must be passed function names');
for (i = 1; i < length; i++) {
key = arguments[i];
obj[key] = _.bind(obj[key], obj);
}
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
var memoize = function(key) {
var cache = memoize.cache;
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
return cache[address];
};
memoize.cache = {};
return memoize;
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(null, args); }, wait);
return setTimeout(function(){
return func.apply(null, args);
}, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
_.defer = _.partial(_.delay, _, 1);
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
......@@ -11847,12 +11942,12 @@ define('text',['module'], function (module) {
var context, args, result;
var timeout = null;
var previous = 0;
options || (options = {});
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
......@@ -11860,12 +11955,14 @@ define('text',['module'], function (module) {
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
......@@ -11882,13 +11979,14 @@ define('text',['module'], function (module) {
var later = function() {
var last = _.now() - timestamp;
if (last < wait) {
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
}
}
};
......@@ -11898,9 +11996,7 @@ define('text',['module'], function (module) {
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
......@@ -11910,19 +12006,6 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
......@@ -11930,20 +12013,27 @@ define('text',['module'], function (module) {
return _.partial(wrapper, func);
};
// Returns a negated version of the passed-in predicate.
_.negate = function(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
// Returns a function that will only be executed after being called N times.
// Returns a function that will only be executed on and after the Nth call.
_.after = function(times, func) {
return function() {
if (--times < 1) {
......@@ -11952,16 +12042,66 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will only be executed up to (but not including) the Nth call.
_.before = function(times, func) {
var memo;
return function() {
if (--times > 0) {
memo = func.apply(this, arguments);
}
if (times <= 1) func = null;
return memo;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = _.partial(_.before, 2);
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
function collectNonEnumProps(obj, keys) {
var nonEnumIdx = nonEnumerableProps.length;
var constructor = obj.constructor;
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
// Constructor is a special case.
var prop = 'constructor';
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
while (nonEnumIdx--) {
prop = nonEnumerableProps[nonEnumIdx];
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
keys.push(prop);
}
}
}
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
// Retrieve all the property names of an object.
_.allKeys = function(obj) {
if (!_.isObject(obj)) return [];
var keys = [];
for (var key in obj) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
......@@ -11969,18 +12109,33 @@ define('text',['module'], function (module) {
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = new Array(length);
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
// Returns the results of applying the iteratee to each element of the object
// In contrast to _.map it returns an object
_.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = _.keys(obj),
length = keys.length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys[index];
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var pairs = new Array(length);
var pairs = Array(length);
for (var i = 0; i < length; i++) {
pairs[i] = [keys[i], obj[keys[i]]];
}
......@@ -12008,48 +12163,57 @@ define('text',['module'], function (module) {
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
_.extend = createAssigner(_.allKeys);
// Assigns a given object with all the own properties in the passed-in object(s)
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_.extendOwn = _.assign = createAssigner(_.keys);
// Returns the first key on an object that passes a predicate test
_.findKey = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = _.keys(obj), key;
for (var i = 0, length = keys.length; i < length; i++) {
key = keys[i];
if (predicate(obj[key], key, obj)) return key;
}
});
return obj;
};
// Return a copy of the object only containing the whitelisted properties.
_.pick = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
each(keys, function(key) {
if (key in obj) copy[key] = obj[key];
});
return copy;
_.pick = function(object, oiteratee, context) {
var result = {}, obj = object, iteratee, keys;
if (obj == null) return result;
if (_.isFunction(oiteratee)) {
keys = _.allKeys(obj);
iteratee = optimizeCb(oiteratee, context);
} else {
keys = flatten(arguments, false, false, 1);
iteratee = function(value, key, obj) { return key in obj; };
obj = Object(obj);
}
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = obj[key];
if (iteratee(value, key, obj)) result[key] = value;
}
return result;
};
// Return a copy of the object without the blacklisted properties.
_.omit = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
for (var key in obj) {
if (!_.contains(keys, key)) copy[key] = obj[key];
_.omit = function(obj, iteratee, context) {
if (_.isFunction(iteratee)) {
iteratee = _.negate(iteratee);
} else {
var keys = _.map(flatten(arguments, false, false, 1), String);
iteratee = function(value, key) {
return !_.contains(keys, key);
};
}
return copy;
return _.pick(obj, iteratee, context);
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
if (obj[prop] === void 0) obj[prop] = source[prop];
}
}
});
return obj;
};
_.defaults = createAssigner(_.allKeys, true);
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
......@@ -12065,11 +12229,24 @@ define('text',['module'], function (module) {
return obj;
};
// Returns whether an object has a given set of `key:value` pairs.
_.isMatch = function(object, attrs) {
var keys = _.keys(attrs), length = keys.length;
if (object == null) return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = keys[i];
if (attrs[key] !== obj[key] || !(key in obj)) return false;
}
return true;
};
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a == 1 / b;
if (a === b) return a !== 0 || 1 / a === 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
......@@ -12077,98 +12254,98 @@ define('text',['module'], function (module) {
if (b instanceof _) b = b._wrapped;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
if (className !== toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case '[object RegExp]':
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(b);
return '' + a === '' + b;
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
return +a === +b;
}
var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
_.isFunction(bCtor) && bCtor instanceof bCtor)
&& ('constructor' in a && 'constructor' in b)) {
return false;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (aStack[length] == a) return bStack[length] == b;
}
// Objects with different constructors are not equivalent, but `Object`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
_.isFunction(bCtor) && (bCtor instanceof bCtor))
&& ('constructor' in a && 'constructor' in b)) {
return false;
if (aStack[length] === a) return bStack[length] === b;
}
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
}
while (length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (_.has(b, key) && !(size--)) break;
}
result = !size;
var keys = _.keys(a), key;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (_.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return result;
return true;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, [], []);
return eq(a, b);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (obj == null) return true;
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (_.has(obj, key)) return false;
return true;
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
return _.keys(obj).length === 0;
};
// Is a given value a DOM element?
......@@ -12179,33 +12356,35 @@ define('text',['module'], function (module) {
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
return toString.call(obj) === '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
return toString.call(obj) === '[object ' + name + ']';
};
});
// Define a fallback version of the method in browsers (ahem, IE), where
// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
return _.has(obj, 'callee');
};
}
// Optimize `isFunction` if appropriate.
if (typeof (/./) !== 'function') {
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
// IE 11 (#1621), and in Safari 8 (#1929).
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
_.isFunction = function(obj) {
return typeof obj === 'function';
return typeof obj == 'function' || false;
};
}
......@@ -12216,12 +12395,12 @@ define('text',['module'], function (module) {
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(obj) {
return _.isNumber(obj) && obj != +obj;
return _.isNumber(obj) && obj !== +obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
};
// Is a given value equal to null?
......@@ -12237,7 +12416,7 @@ define('text',['module'], function (module) {
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
return obj != null && hasOwnProperty.call(obj, key);
};
// Utility Functions
......@@ -12250,39 +12429,47 @@ define('text',['module'], function (module) {
return this;
};
// Keep the identity function around for default iterators.
// Keep the identity function around for default iteratees.
_.identity = function(value) {
return value;
};
// Predicate-generating functions. Often useful outside of Underscore.
_.constant = function(value) {
return function () {
return function() {
return value;
};
};
_.noop = function(){};
_.property = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
// Generates a function for a given object that returns a given property.
_.propertyOf = function(obj) {
return obj == null ? function(){} : function(key) {
return obj[key];
};
};
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
_.matches = function(attrs) {
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
_.matcher = _.matches = function(attrs) {
attrs = _.extendOwn({}, attrs);
return function(obj) {
if (obj === attrs) return true; //avoid comparing an object to itself.
for (var key in attrs) {
if (attrs[key] !== obj[key])
return false;
}
return true;
}
return _.isMatch(obj, attrs);
};
};
// Run a function **n** times.
_.times = function(n, iterator, context) {
_.times = function(n, iteratee, context) {
var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
iteratee = optimizeCb(iteratee, context, 1);
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
return accum;
};
......@@ -12296,56 +12483,48 @@ define('text',['module'], function (module) {
};
// A (possibly faster) way to get the current timestamp as an integer.
_.now = Date.now || function() { return new Date().getTime(); };
_.now = Date.now || function() {
return new Date().getTime();
};
// List of HTML entities for escaping.
var entityMap = {
escape: {
var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;'
}
};
entityMap.unescape = _.invert(entityMap.escape);
// Regexes containing the keys and values listed immediately above.
var entityRegexes = {
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
"'": '&#x27;',
'`': '&#x60;'
};
var unescapeMap = _.invert(escapeMap);
// Functions for escaping and unescaping strings to/from HTML interpolation.
_.each(['escape', 'unescape'], function(method) {
_[method] = function(string) {
if (string == null) return '';
return ('' + string).replace(entityRegexes[method], function(match) {
return entityMap[method][match];
});
var createEscaper = function(map) {
var escaper = function(match) {
return map[match];
};
});
// Regexes for identifying a key that needs to be escaped
var source = '(?:' + _.keys(map).join('|') + ')';
var testRegexp = RegExp(source);
var replaceRegexp = RegExp(source, 'g');
return function(string) {
string = string == null ? '' : '' + string;
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
};
};
_.escape = createEscaper(escapeMap);
_.unescape = createEscaper(unescapeMap);
// If the value of the named `property` is a function then invoke it with the
// `object` as context; otherwise, return it.
_.result = function(object, property) {
if (object == null) return void 0;
var value = object[property];
_.result = function(object, property, fallback) {
var value = object == null ? void 0 : object[property];
if (value === void 0) {
value = fallback;
}
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result.call(this, func.apply(_, args));
};
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
......@@ -12374,22 +12553,26 @@ define('text',['module'], function (module) {
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
// NB: `oldSettings` only exists for backwards compatibility.
_.template = function(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
......@@ -12399,19 +12582,18 @@ define('text',['module'], function (module) {
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
source += text.slice(index, offset).replace(escaper, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
// Adobe VMs need the match returned to produce the correct offest.
return match;
});
source += "';\n";
......@@ -12421,29 +12603,31 @@ define('text',['module'], function (module) {
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
source + 'return __p;\n';
try {
render = new Function(settings.variable || 'obj', '_', source);
var render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
// Provide the compiled source as a convenience for precompilation.
var argument = settings.variable || 'obj';
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
};
// Add a "chain" function, which will delegate to the wrapper.
// Add a "chain" function. Start chaining a wrapped Underscore object.
_.chain = function(obj) {
return _(obj).chain();
var instance = _(obj);
instance._chain = true;
return instance;
};
// OOP
......@@ -12453,46 +12637,56 @@ define('text',['module'], function (module) {
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var result = function(obj) {
return this._chain ? _(obj).chain() : obj;
var result = function(instance, obj) {
return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
});
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
var obj = this._wrapped;
method.apply(obj, arguments);
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
return result.call(this, obj);
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
return result(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
_.each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
return result.call(this, method.apply(this._wrapped, arguments));
return result(this, method.apply(this._wrapped, arguments));
};
});
_.extend(_.prototype, {
// Start chaining a wrapped Underscore object.
chain: function() {
this._chain = true;
return this;
},
// Extracts the result from a wrapped and chained object.
value: function() {
_.prototype.value = function() {
return this._wrapped;
}
};
});
// Provide unwrapping proxy for some methods used in engine operations
// such as arithmetic and JSON stringification.
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
_.prototype.toString = function() {
return '' + this._wrapped;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
......@@ -12506,7 +12700,7 @@ define('text',['module'], function (module) {
return _;
});
}
}).call(this);
}.call(this));
// RequireJS UnderscoreJS template plugin
// http://github.com/jfparadis/requirejs-tpl
......@@ -13031,7 +13225,7 @@ var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments
with(obj||{}){
__p+='<form id="converse-login" method="post">\n <label>'+
((__t=(label_username))==null?'':__t)+
'</label>\n <input type="username" name="jid" placeholder="user@server">\n <label>'+
'</label>\n <input type="email" name="jid" placeholder="user@server">\n <label>'+
((__t=(label_password))==null?'':__t)+
'</label>\n <input type="password" name="password" placeholder="password">\n <input class="submit" type="submit" value="'+
((__t=(label_login))==null?'':__t)+
......@@ -13360,7 +13554,9 @@ __p+='<form class="add-chatroom" action="" method="post">\n <label>'+
((__t=(label_nickname))==null?'':__t)+
'</label>\n <input type="text" name="nick" class="new-chatroom-nick"\n placeholder="'+
((__t=(label_nickname))==null?'':__t)+
'"/>\n <label>'+
'"/>\n <label'+
((__t=(server_label_global_attr))==null?'':__t)+
'>'+
((__t=(label_server))==null?'':__t)+
'</label>\n <input type="'+
((__t=(server_input_type))==null?'':__t)+
......@@ -13406,9 +13602,13 @@ __p+='<a class="open-chat" title="Name: '+
((__t=(desc_status))==null?'':__t)+
'"></span>'+
((__t=(fullname))==null?'':__t)+
'</a>\n<a class="remove-xmpp-contact icon-remove" title="'+
'</a>\n';
if (allow_contact_removal) {
__p+='\n<a class="remove-xmpp-contact icon-remove" title="'+
((__t=(desc_remove))==null?'':__t)+
'" href="#"></a>\n';
}
__p+='\n';
}
return __p;
}; });
......@@ -26939,19 +27139,6 @@ define("converse-dependencies", [
return this;
};
var playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
var converse = {
plugins: {},
templates: templates,
......@@ -27058,6 +27245,7 @@ define("converse-dependencies", [
// Default configuration values
// ----------------------------
this.default_settings = {
allow_contact_removal: true,
allow_contact_requests: true,
allow_dragresize: true,
allow_logout: true,
......@@ -27172,6 +27360,19 @@ define("converse-dependencies", [
// Module-level functions
// ----------------------
this.playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
this.giveFeedback = function (message, klass) {
$('.conn-feedback').each(function (idx, el) {
var $el = $(el);
......@@ -27244,7 +27445,6 @@ define("converse-dependencies", [
this.reconnect = function () {
converse.giveFeedback(__('Reconnecting'), 'error');
converse.emit('reconnect');
if (!converse.prebind) {
this.connection.connect(
this.connection.jid,
......@@ -27256,6 +27456,10 @@ define("converse-dependencies", [
this.connection.hold,
this.connection.route
);
} else if (converse.prebind_url) {
this.clearSession();
this._tearDown();
this.startNewBOSHSession();
}
};
......@@ -27292,6 +27496,7 @@ define("converse-dependencies", [
converse.giveFeedback(__('Authentication Failed'), 'error');
converse.connection.disconnect(__('Authentication Failed'));
} else if (status === Strophe.Status.DISCONNECTING) {
// FIXME: what about prebind?
if (!converse.connection.connected) {
converse.renderLoginPanel();
}
......@@ -27367,8 +27572,8 @@ define("converse-dependencies", [
this.clearSession = function () {
this.roster.browserStorage._clear();
this.session.browserStorage._clear();
// XXX: this should perhaps go into the beforeunload handler
converse.chatboxes.get('controlbox').save({'connected': false});
var controlbox = converse.chatboxes.get('controlbox');
controlbox.save({'connected': false});
};
this.setSession = function () {
......@@ -28573,6 +28778,7 @@ define("converse-dependencies", [
this.$el.html(
converse.templates.room_panel({
'server_input_type': converse.hide_muc_server && 'hidden' || 'text',
'server_label_global_attr': converse.hide_muc_server && ' hidden' || '',
'label_room_name': __('Room name'),
'label_nickname': __('Nickname'),
'label_server': __('Server'),
......@@ -29785,7 +29991,7 @@ define("converse-dependencies", [
}
this.model.createMessage($message);
if (!delayed && sender !== this.model.get('nick') && (new RegExp("\\b"+this.model.get('nick')+"\\b")).test(body)) {
playNotification();
converse.playNotification();
}
if (sender !== this.model.get('nick')) {
// We only emit an event if it's not our own message
......@@ -29955,7 +30161,7 @@ define("converse-dependencies", [
return true; // We already have this message stored.
}
if (!this.isOnlyChatStateNotification($message) && from !== converse.bare_jid) {
playNotification();
converse.playNotification();
}
chatbox.receiveMessage($message);
converse.roster.addResource(contact_jid, resource);
......@@ -30386,7 +30592,8 @@ define("converse-dependencies", [
_.extend(item.toJSON(), {
'desc_status': STATUSES[chat_status||'offline'],
'desc_chat': __('Click to chat with this contact'),
'desc_remove': __('Click to remove this contact')
'desc_remove': __('Click to remove this contact'),
'allow_contact_removal': converse.allow_contact_removal
})
));
}
......@@ -30400,6 +30607,7 @@ define("converse-dependencies", [
removeContact: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (!converse.allow_contact_removal) { return; }
var result = confirm(__("Are you sure you want to remove this contact?"));
if (result === true) {
var bare_jid = this.model.get('jid');
......@@ -32100,20 +32308,32 @@ define("converse-dependencies", [
}
};
this.startNewBOSHSession = function () {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: response.rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
};
this.initConnection = function () {
var rid, sid, jid;
if (this.connection && this.connection.connected) {
this.setUpXMLLogging();
this.onConnected();
} else {
// XXX: it's not yet clear what the order of preference should
// be between RID and SID received via the initialize method or
// those received from sessionStorage.
//
// What do you we if we receive values from both avenues?
//
// Also, what do we do when the keepalive session values are
// expired? Do we try to fall back?
if (!this.bosh_service_url && ! this.websocket_url) {
throw("Error: you must supply a value for the bosh_service_url or websocket_url");
}
......@@ -32139,33 +32359,25 @@ define("converse-dependencies", [
rid = this.session.get('rid');
sid = this.session.get('sid');
jid = this.session.get('jid');
if (rid && jid && sid) {
// The RID needs to be increased with each request.
this.session.save({rid: rid});
if (this.prebind) {
if (!this.jid) {
throw("When using 'keepalive' with 'prebind, you must supply the JID of the current user.");
}
if (rid && sid && jid && Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(this.jid)) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
} else if (this.prebind) {
if (this.prebind_url) {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
} else if (this.prebind_url) {
this.startNewBOSHSession();
} else {
delete this.connection;
this.emit('noResumeableSession');
}
} else {
// Non-prebind case.
if (rid && sid && jid) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
}
}
}
}
......@@ -32245,6 +32457,14 @@ define("converse-dependencies", [
'initialize': function (settings, callback) {
converse.initialize(settings, callback);
},
'disconnect': function () {
converse.connection.disconnect();
},
'account': {
'logout': function () {
converse.logOut();
},
},
'settings': {
'get': function (key) {
if (_.contains(Object.keys(converse.default_settings), key)) {
......@@ -32550,7 +32770,6 @@ require.config({
// define module dependencies for modules not using define
shim: {
'underscore': { exports: '_' },
'crypto.aes': { deps: ['crypto.cipher-core'] },
'crypto.cipher-core': { deps: ['crypto.enc-base64', 'crypto.evpkdf'] },
'crypto.enc-base64': { deps: ['crypto.core'] },
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* @license almond 0.3.0 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/almond for details
*/
......@@ -44,12 +44,6 @@ var requirejs, require, define;
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
//Convert baseName to array, and lop off the last part,
//so that . matches that "directory" and not name of the baseName's
//module. For instance, baseName of "one/two/three", maps to
//"one/two/three.js", but we want the directory, "one/two" for
//this normalization.
baseParts = baseParts.slice(0, baseParts.length - 1);
name = name.split('/');
lastIndex = name.length - 1;
......@@ -58,7 +52,11 @@ var requirejs, require, define;
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
}
name = baseParts.concat(name);
//Lop off the last part of baseParts, so that . matches the
//"directory" and not name of the baseName's module. For instance,
//baseName of "one/two/three", maps to "one/two/three.js", but we
//want the directory, "one/two" for this normalization.
name = baseParts.slice(0, baseParts.length - 1).concat(name);
//start trimDots
for (i = 0; i < name.length; i += 1) {
......@@ -408,6 +406,9 @@ var requirejs, require, define;
requirejs._defined = defined;
define = function (name, deps, callback) {
if (typeof name !== 'string') {
throw new Error('See almond README: incorrect module build, no module name');
}
//This module may not have dependencies
if (!deps.splice) {
......@@ -11164,9 +11165,9 @@ define('text',['module'], function (module) {
return text;
});
// Underscore.js 1.6.0
// Underscore.js 1.8.2
// http://underscorejs.org
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
......@@ -11180,9 +11181,6 @@ define('text',['module'], function (module) {
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
......@@ -11190,25 +11188,19 @@ define('text',['module'], function (module) {
var
push = ArrayProto.push,
slice = ArrayProto.slice,
concat = ArrayProto.concat,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
nativeBind = FuncProto.bind,
nativeCreate = Object.create;
// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
......@@ -11219,8 +11211,7 @@ define('text',['module'], function (module) {
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
// the browser, add `_` as a global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
......@@ -11231,161 +11222,208 @@ define('text',['module'], function (module) {
}
// Current version.
_.VERSION = '1.6.0';
_.VERSION = '1.8.2';
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var optimizeCb = function(func, context, argCount) {
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function(value) {
return func.call(context, value);
};
case 2: return function(value, other) {
return func.call(context, value, other);
};
case 3: return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
// A mostly-internal function to generate callbacks that can be applied
// to each element in a collection, returning the desired result — either
// identity, an arbitrary callback, a property matcher, or a property accessor.
var cb = function(value, context, argCount) {
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value)) return _.matcher(value);
return _.property(value);
};
_.iteratee = function(value, context) {
return cb(value, context, Infinity);
};
// An internal function for creating assigner functions.
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var isArrayLike = function(collection) {
var length = collection && collection.length;
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results.push(iterator.call(context, value, index, list));
});
// Return the results of applying the iteratee to each element.
_.map = _.collect = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
results = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
var reduceError = 'Reduce of empty array with no initial value';
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
// Create a reducing function iterating left or right.
function createReduce(dir) {
// Optimized iterator function as using arguments.length
// in the main function will deoptimize the, see #1991.
function iterator(obj, iteratee, memo, keys, index, length) {
for (; index >= 0 && index < length; index += dir) {
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var length = obj.length;
if (length !== +length) {
var keys = _.keys(obj);
length = keys.length;
}
each(obj, function(value, index, list) {
index = keys ? keys[--length] : --length;
if (!initial) {
memo = obj[index];
initial = true;
} else {
memo = iterator.call(context, memo, obj[index], index, list);
return function(obj, iteratee, memo, context) {
iteratee = optimizeCb(iteratee, context, 4);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
index = dir > 0 ? 0 : length - 1;
// Determine the initial value if none is provided.
if (arguments.length < 3) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
return iterator(obj, iteratee, memo, keys, index, length);
};
}
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`.
_.reduce = _.foldl = _.inject = createReduce(1);
// The right-associative version of reduce, also known as `foldr`.
_.reduceRight = _.foldr = createReduce(-1);
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, predicate, context) {
var result;
any(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) {
result = value;
return true;
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
});
return result;
if (key !== void 0 && key !== -1) return obj[key];
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) results.push(value);
predicate = cb(predicate, context);
_.each(obj, function(value, index, list) {
if (predicate(value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) {
return !predicate.call(context, value, index, list);
}, context);
return _.filter(obj, _.negate(cb(predicate)), context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) {
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});
return !!result;
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (!predicate(obj[currentKey], currentKey, obj)) return false;
}
return true;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
_.some = _.any = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (predicate(obj[currentKey], currentKey, obj)) return true;
}
return false;
};
// Determine if the array or object contains a given value (using `===`).
// Aliased as `include`.
_.contains = _.include = function(obj, target) {
if (obj == null) return false;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
return any(obj, function(value) {
return value === target;
});
// Aliased as `includes` and `include`.
_.contains = _.includes = _.include = function(obj, target, fromIndex) {
if (!isArrayLike(obj)) obj = _.values(obj);
return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0;
};
// Invoke a method (with arguments) on every item in a collection.
......@@ -11393,7 +11431,8 @@ define('text',['module'], function (module) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
return (isFunc ? method : value[method]).apply(value, args);
var func = isFunc ? method : value[method];
return func == null ? func : func.apply(value, args);
});
};
......@@ -11405,60 +11444,76 @@ define('text',['module'], function (module) {
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs) {
return _.filter(obj, _.matches(attrs));
return _.filter(obj, _.matcher(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.find(obj, _.matches(attrs));
return _.find(obj, _.matcher(attrs));
};
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
// Return the maximum element (or element-based computation).
_.max = function(obj, iteratee, context) {
var result = -Infinity, lastComputed = -Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value > result) {
result = value;
}
}
var result = -Infinity, lastComputed = -Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed > lastComputed) {
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj);
}
var result = Infinity, lastComputed = Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed < lastComputed) {
_.min = function(obj, iteratee, context) {
var result = Infinity, lastComputed = Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value < result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed < lastComputed || computed === Infinity && result === Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Shuffle an array, using the modern version of the
// Shuffle a collection, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
var shuffled = [];
each(obj, function(value) {
rand = _.random(index++);
shuffled[index - 1] = shuffled[rand];
shuffled[rand] = value;
});
var set = isArrayLike(obj) ? obj : _.values(obj);
var length = set.length;
var shuffled = Array(length);
for (var index = 0, rand; index < length; index++) {
rand = _.random(0, index);
if (rand !== index) shuffled[index] = shuffled[rand];
shuffled[rand] = set[index];
}
return shuffled;
};
......@@ -11467,27 +11522,20 @@ define('text',['module'], function (module) {
// The internal `guard` argument allows it to work with `map`.
_.sample = function(obj, n, guard) {
if (n == null || guard) {
if (obj.length !== +obj.length) obj = _.values(obj);
if (!isArrayLike(obj)) obj = _.values(obj);
return obj[_.random(obj.length - 1)];
}
return _.shuffle(obj).slice(0, Math.max(0, n));
};
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
if (value == null) return _.identity;
if (_.isFunction(value)) return value;
return _.property(value);
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
iterator = lookupIterator(iterator);
// Sort the object's values by a criterion produced by an iteratee.
_.sortBy = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value: value,
index: index,
criteria: iterator.call(context, value, index, list)
criteria: iteratee(value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
......@@ -11502,12 +11550,12 @@ define('text',['module'], function (module) {
// An internal function used for aggregate "group by" operations.
var group = function(behavior) {
return function(obj, iterator, context) {
return function(obj, iteratee, context) {
var result = {};
iterator = lookupIterator(iterator);
each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj);
behavior(result, key, value);
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
......@@ -11515,48 +11563,46 @@ define('text',['module'], function (module) {
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, key, value) {
_.has(result, key) ? result[key].push(value) : result[key] = [value];
_.groupBy = group(function(result, value, key) {
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_.indexBy = group(function(result, key, value) {
_.indexBy = group(function(result, value, key) {
result[key] = value;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_.countBy = group(function(result, key) {
_.has(result, key) ? result[key]++ : result[key] = 1;
_.countBy = group(function(result, value, key) {
if (_.has(result, key)) result[key]++; else result[key] = 1;
});
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) {
iterator = lookupIterator(iterator);
var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >>> 1;
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
}
return low;
};
// Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) return _.map(obj, _.identity);
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
if (obj == null) return 0;
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(obj, predicate, context) {
predicate = cb(predicate, context);
var pass = [], fail = [];
_.each(obj, function(value, key, obj) {
(predicate(value, key, obj) ? pass : fail).push(value);
});
return [pass, fail];
};
// Array Functions
......@@ -11567,33 +11613,30 @@ define('text',['module'], function (module) {
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[0];
if (n < 0) return [];
return slice.call(array, 0, n);
if (n == null || guard) return array[0];
return _.initial(array, array.length - n);
};
// Returns everything but the last entry of the array. Especially useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
// the array, excluding the last N.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
// values in the array.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[array.length - 1];
return slice.call(array, Math.max(array.length - n, 0));
if (n == null || guard) return array[array.length - 1];
return _.rest(array, Math.max(0, array.length - n));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Especially useful on the arguments object. Passing an **n** will return
// the rest N values in the array. The **guard**
// check allows it to work with `_.map`.
// the rest N values in the array.
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, (n == null) || guard ? 1 : n);
return slice.call(array, n == null || guard ? 1 : n);
};
// Trim out all falsy values from an array.
......@@ -11602,23 +11645,28 @@ define('text',['module'], function (module) {
};
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
if (shallow && _.every(input, _.isArray)) {
return concat.apply(output, input);
var flatten = function(input, shallow, strict, startIndex) {
var output = [], idx = 0;
for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
//flatten current level of array or arguments object
if (!shallow) value = flatten(value, shallow, strict);
var j = 0, len = value.length;
output.length += len;
while (j < len) {
output[idx++] = value[j++];
}
} else if (!strict) {
output[idx++] = value;
}
each(input, function(value) {
if (_.isArray(value) || _.isArguments(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
}
});
return output;
};
// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
return flatten(array, shallow, false);
};
// Return a version of the array that does not contain the specified value(s).
......@@ -11626,79 +11674,93 @@ define('text',['module'], function (module) {
return _.difference(array, slice.call(arguments, 1));
};
// Split an array into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(array, predicate) {
var pass = [], fail = [];
each(array, function(elem) {
(predicate(elem) ? pass : fail).push(elem);
});
return [pass, fail];
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator, context) {
if (_.isFunction(isSorted)) {
context = iterator;
iterator = isSorted;
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (array == null) return [];
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array;
var results = [];
if (iteratee != null) iteratee = cb(iteratee, context);
var result = [];
var seen = [];
each(initial, function(value, index) {
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
seen.push(value);
results.push(array[index]);
for (var i = 0, length = array.length; i < length; i++) {
var value = array[i],
computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== computed) result.push(value);
seen = computed;
} else if (iteratee) {
if (!_.contains(seen, computed)) {
seen.push(computed);
result.push(value);
}
});
return results;
} else if (!_.contains(result, value)) {
result.push(value);
}
}
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
return _.uniq(flatten(arguments, true, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersection = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.contains(other, item);
});
});
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
return _.filter(array, function(value){ return !_.contains(rest, value); });
var rest = flatten(arguments, true, true, 1);
return _.filter(array, function(value){
return !_.contains(rest, value);
});
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(arguments, '' + i);
return _.unzip(arguments);
};
// Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices
_.unzip = function(array) {
var length = array && _.max(array, 'length').length || 0;
var result = Array(length);
for (var index = 0; index < length; index++) {
result[index] = _.pluck(array, index);
}
return results;
return result;
};
// Converts lists into objects. Pass either a single array of `[key, value]`
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values.
_.object = function(list, values) {
if (list == null) return {};
var result = {};
for (var i = 0, length = list.length; i < length; i++) {
for (var i = 0, length = list && list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
......@@ -11708,40 +11770,68 @@ define('text',['module'], function (module) {
return result;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// Return the position of the first occurrence of an item in an array,
// or -1 if the item is not included in the array.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i = 0, length = array.length;
if (isSorted) {
var i = 0, length = array && array.length;
if (typeof isSorted == 'number') {
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
} else if (isSorted && length) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (item !== item) {
return _.findIndex(slice.call(array, i), _.isNaN);
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item, from) {
if (array == null) return -1;
var hasIndex = from != null;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
var idx = array ? array.length : 0;
if (typeof from == 'number') {
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
}
if (item !== item) {
return _.findLastIndex(slice.call(array, 0, idx), _.isNaN);
}
var i = (hasIndex ? from : array.length);
while (i--) if (array[i] === item) return i;
while (--idx >= 0) if (array[idx] === item) return idx;
return -1;
};
// Generator function to create the findIndex and findLastIndex functions
function createIndexFinder(dir) {
return function(array, predicate, context) {
predicate = cb(predicate, context);
var length = array != null && array.length;
var index = dir > 0 ? 0 : length - 1;
for (; index >= 0 && index < length; index += dir) {
if (predicate(array[index], index, array)) return index;
}
return -1;
};
}
// Returns the first index on an array-like that passes a predicate test
_.findIndex = createIndexFinder(1);
_.findLastIndex = createIndexFinder(-1);
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = array.length;
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
}
return low;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
......@@ -11750,15 +11840,13 @@ define('text',['module'], function (module) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
step = step || 1;
var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(length);
var range = Array(length);
while(idx < length) {
range[idx++] = start;
start += step;
for (var idx = 0; idx < length; idx++, start += step) {
range[idx] = start;
}
return range;
......@@ -11767,26 +11855,27 @@ define('text',['module'], function (module) {
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
if (_.isObject(result)) return result;
return self;
};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
var args, bound;
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
ctor.prototype = null;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
var args = slice.call(arguments, 2);
var bound = function() {
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
};
return bound;
};
// Partially apply a function by creating a version that has had some of its
......@@ -11794,49 +11883,55 @@ define('text',['module'], function (module) {
// as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
var boundArgs = slice.call(arguments, 1);
return function() {
var position = 0;
var args = boundArgs.slice();
for (var i = 0, length = args.length; i < length; i++) {
if (args[i] === _) args[i] = arguments[position++];
var bound = function() {
var position = 0, length = boundArgs.length;
var args = Array(length);
for (var i = 0; i < length; i++) {
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
}
while (position < arguments.length) args.push(arguments[position++]);
return func.apply(this, args);
return executeBound(func, bound, this, this, args);
};
return bound;
};
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
var i, length = arguments.length, key;
if (length <= 1) throw new Error('bindAll must be passed function names');
for (i = 1; i < length; i++) {
key = arguments[i];
obj[key] = _.bind(obj[key], obj);
}
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
var memoize = function(key) {
var cache = memoize.cache;
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
return cache[address];
};
memoize.cache = {};
return memoize;
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(null, args); }, wait);
return setTimeout(function(){
return func.apply(null, args);
}, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
_.defer = _.partial(_.delay, _, 1);
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
......@@ -11847,12 +11942,12 @@ define('text',['module'], function (module) {
var context, args, result;
var timeout = null;
var previous = 0;
options || (options = {});
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
......@@ -11860,12 +11955,14 @@ define('text',['module'], function (module) {
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
......@@ -11882,13 +11979,14 @@ define('text',['module'], function (module) {
var later = function() {
var last = _.now() - timestamp;
if (last < wait) {
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
}
}
};
......@@ -11898,9 +11996,7 @@ define('text',['module'], function (module) {
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
......@@ -11910,19 +12006,6 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
......@@ -11930,20 +12013,27 @@ define('text',['module'], function (module) {
return _.partial(wrapper, func);
};
// Returns a negated version of the passed-in predicate.
_.negate = function(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
// Returns a function that will only be executed after being called N times.
// Returns a function that will only be executed on and after the Nth call.
_.after = function(times, func) {
return function() {
if (--times < 1) {
......@@ -11952,16 +12042,66 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will only be executed up to (but not including) the Nth call.
_.before = function(times, func) {
var memo;
return function() {
if (--times > 0) {
memo = func.apply(this, arguments);
}
if (times <= 1) func = null;
return memo;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = _.partial(_.before, 2);
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
function collectNonEnumProps(obj, keys) {
var nonEnumIdx = nonEnumerableProps.length;
var constructor = obj.constructor;
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
// Constructor is a special case.
var prop = 'constructor';
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
while (nonEnumIdx--) {
prop = nonEnumerableProps[nonEnumIdx];
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
keys.push(prop);
}
}
}
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
// Retrieve all the property names of an object.
_.allKeys = function(obj) {
if (!_.isObject(obj)) return [];
var keys = [];
for (var key in obj) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
......@@ -11969,18 +12109,33 @@ define('text',['module'], function (module) {
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = new Array(length);
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
// Returns the results of applying the iteratee to each element of the object
// In contrast to _.map it returns an object
_.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = _.keys(obj),
length = keys.length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys[index];
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var pairs = new Array(length);
var pairs = Array(length);
for (var i = 0; i < length; i++) {
pairs[i] = [keys[i], obj[keys[i]]];
}
......@@ -12008,48 +12163,57 @@ define('text',['module'], function (module) {
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
_.extend = createAssigner(_.allKeys);
// Assigns a given object with all the own properties in the passed-in object(s)
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_.extendOwn = _.assign = createAssigner(_.keys);
// Returns the first key on an object that passes a predicate test
_.findKey = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = _.keys(obj), key;
for (var i = 0, length = keys.length; i < length; i++) {
key = keys[i];
if (predicate(obj[key], key, obj)) return key;
}
});
return obj;
};
// Return a copy of the object only containing the whitelisted properties.
_.pick = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
each(keys, function(key) {
if (key in obj) copy[key] = obj[key];
});
return copy;
_.pick = function(object, oiteratee, context) {
var result = {}, obj = object, iteratee, keys;
if (obj == null) return result;
if (_.isFunction(oiteratee)) {
keys = _.allKeys(obj);
iteratee = optimizeCb(oiteratee, context);
} else {
keys = flatten(arguments, false, false, 1);
iteratee = function(value, key, obj) { return key in obj; };
obj = Object(obj);
}
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = obj[key];
if (iteratee(value, key, obj)) result[key] = value;
}
return result;
};
// Return a copy of the object without the blacklisted properties.
_.omit = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
for (var key in obj) {
if (!_.contains(keys, key)) copy[key] = obj[key];
_.omit = function(obj, iteratee, context) {
if (_.isFunction(iteratee)) {
iteratee = _.negate(iteratee);
} else {
var keys = _.map(flatten(arguments, false, false, 1), String);
iteratee = function(value, key) {
return !_.contains(keys, key);
};
}
return copy;
return _.pick(obj, iteratee, context);
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
if (obj[prop] === void 0) obj[prop] = source[prop];
}
}
});
return obj;
};
_.defaults = createAssigner(_.allKeys, true);
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
......@@ -12065,11 +12229,24 @@ define('text',['module'], function (module) {
return obj;
};
// Returns whether an object has a given set of `key:value` pairs.
_.isMatch = function(object, attrs) {
var keys = _.keys(attrs), length = keys.length;
if (object == null) return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = keys[i];
if (attrs[key] !== obj[key] || !(key in obj)) return false;
}
return true;
};
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a == 1 / b;
if (a === b) return a !== 0 || 1 / a === 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
......@@ -12077,98 +12254,98 @@ define('text',['module'], function (module) {
if (b instanceof _) b = b._wrapped;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
if (className !== toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case '[object RegExp]':
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(b);
return '' + a === '' + b;
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
return +a === +b;
}
var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
_.isFunction(bCtor) && bCtor instanceof bCtor)
&& ('constructor' in a && 'constructor' in b)) {
return false;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (aStack[length] == a) return bStack[length] == b;
}
// Objects with different constructors are not equivalent, but `Object`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
_.isFunction(bCtor) && (bCtor instanceof bCtor))
&& ('constructor' in a && 'constructor' in b)) {
return false;
if (aStack[length] === a) return bStack[length] === b;
}
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
}
while (length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (_.has(b, key) && !(size--)) break;
}
result = !size;
var keys = _.keys(a), key;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (_.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return result;
return true;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, [], []);
return eq(a, b);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (obj == null) return true;
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (_.has(obj, key)) return false;
return true;
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
return _.keys(obj).length === 0;
};
// Is a given value a DOM element?
......@@ -12179,33 +12356,35 @@ define('text',['module'], function (module) {
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
return toString.call(obj) === '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
return toString.call(obj) === '[object ' + name + ']';
};
});
// Define a fallback version of the method in browsers (ahem, IE), where
// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
return _.has(obj, 'callee');
};
}
// Optimize `isFunction` if appropriate.
if (typeof (/./) !== 'function') {
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
// IE 11 (#1621), and in Safari 8 (#1929).
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
_.isFunction = function(obj) {
return typeof obj === 'function';
return typeof obj == 'function' || false;
};
}
......@@ -12216,12 +12395,12 @@ define('text',['module'], function (module) {
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(obj) {
return _.isNumber(obj) && obj != +obj;
return _.isNumber(obj) && obj !== +obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
};
// Is a given value equal to null?
......@@ -12237,7 +12416,7 @@ define('text',['module'], function (module) {
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
return obj != null && hasOwnProperty.call(obj, key);
};
// Utility Functions
......@@ -12250,39 +12429,47 @@ define('text',['module'], function (module) {
return this;
};
// Keep the identity function around for default iterators.
// Keep the identity function around for default iteratees.
_.identity = function(value) {
return value;
};
// Predicate-generating functions. Often useful outside of Underscore.
_.constant = function(value) {
return function () {
return function() {
return value;
};
};
_.noop = function(){};
_.property = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
// Generates a function for a given object that returns a given property.
_.propertyOf = function(obj) {
return obj == null ? function(){} : function(key) {
return obj[key];
};
};
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
_.matches = function(attrs) {
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
_.matcher = _.matches = function(attrs) {
attrs = _.extendOwn({}, attrs);
return function(obj) {
if (obj === attrs) return true; //avoid comparing an object to itself.
for (var key in attrs) {
if (attrs[key] !== obj[key])
return false;
}
return true;
}
return _.isMatch(obj, attrs);
};
};
// Run a function **n** times.
_.times = function(n, iterator, context) {
_.times = function(n, iteratee, context) {
var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
iteratee = optimizeCb(iteratee, context, 1);
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
return accum;
};
......@@ -12296,56 +12483,48 @@ define('text',['module'], function (module) {
};
// A (possibly faster) way to get the current timestamp as an integer.
_.now = Date.now || function() { return new Date().getTime(); };
_.now = Date.now || function() {
return new Date().getTime();
};
// List of HTML entities for escaping.
var entityMap = {
escape: {
var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;'
}
};
entityMap.unescape = _.invert(entityMap.escape);
// Regexes containing the keys and values listed immediately above.
var entityRegexes = {
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
"'": '&#x27;',
'`': '&#x60;'
};
var unescapeMap = _.invert(escapeMap);
// Functions for escaping and unescaping strings to/from HTML interpolation.
_.each(['escape', 'unescape'], function(method) {
_[method] = function(string) {
if (string == null) return '';
return ('' + string).replace(entityRegexes[method], function(match) {
return entityMap[method][match];
});
var createEscaper = function(map) {
var escaper = function(match) {
return map[match];
};
});
// Regexes for identifying a key that needs to be escaped
var source = '(?:' + _.keys(map).join('|') + ')';
var testRegexp = RegExp(source);
var replaceRegexp = RegExp(source, 'g');
return function(string) {
string = string == null ? '' : '' + string;
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
};
};
_.escape = createEscaper(escapeMap);
_.unescape = createEscaper(unescapeMap);
// If the value of the named `property` is a function then invoke it with the
// `object` as context; otherwise, return it.
_.result = function(object, property) {
if (object == null) return void 0;
var value = object[property];
_.result = function(object, property, fallback) {
var value = object == null ? void 0 : object[property];
if (value === void 0) {
value = fallback;
}
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result.call(this, func.apply(_, args));
};
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
......@@ -12374,22 +12553,26 @@ define('text',['module'], function (module) {
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
// NB: `oldSettings` only exists for backwards compatibility.
_.template = function(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
......@@ -12399,19 +12582,18 @@ define('text',['module'], function (module) {
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
source += text.slice(index, offset).replace(escaper, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
// Adobe VMs need the match returned to produce the correct offest.
return match;
});
source += "';\n";
......@@ -12421,29 +12603,31 @@ define('text',['module'], function (module) {
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
source + 'return __p;\n';
try {
render = new Function(settings.variable || 'obj', '_', source);
var render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
// Provide the compiled source as a convenience for precompilation.
var argument = settings.variable || 'obj';
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
};
// Add a "chain" function, which will delegate to the wrapper.
// Add a "chain" function. Start chaining a wrapped Underscore object.
_.chain = function(obj) {
return _(obj).chain();
var instance = _(obj);
instance._chain = true;
return instance;
};
// OOP
......@@ -12453,46 +12637,56 @@ define('text',['module'], function (module) {
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var result = function(obj) {
return this._chain ? _(obj).chain() : obj;
var result = function(instance, obj) {
return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
});
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
var obj = this._wrapped;
method.apply(obj, arguments);
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
return result.call(this, obj);
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
return result(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
_.each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
return result.call(this, method.apply(this._wrapped, arguments));
return result(this, method.apply(this._wrapped, arguments));
};
});
_.extend(_.prototype, {
// Start chaining a wrapped Underscore object.
chain: function() {
this._chain = true;
return this;
},
// Extracts the result from a wrapped and chained object.
value: function() {
_.prototype.value = function() {
return this._wrapped;
}
};
});
// Provide unwrapping proxy for some methods used in engine operations
// such as arithmetic and JSON stringification.
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
_.prototype.toString = function() {
return '' + this._wrapped;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
......@@ -12506,7 +12700,7 @@ define('text',['module'], function (module) {
return _;
});
}
}).call(this);
}.call(this));
// RequireJS UnderscoreJS template plugin
// http://github.com/jfparadis/requirejs-tpl
......@@ -13031,7 +13225,7 @@ var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments
with(obj||{}){
__p+='<form id="converse-login" method="post">\n <label>'+
((__t=(label_username))==null?'':__t)+
'</label>\n <input type="username" name="jid" placeholder="user@server">\n <label>'+
'</label>\n <input type="email" name="jid" placeholder="user@server">\n <label>'+
((__t=(label_password))==null?'':__t)+
'</label>\n <input type="password" name="password" placeholder="password">\n <input class="submit" type="submit" value="'+
((__t=(label_login))==null?'':__t)+
......@@ -13360,7 +13554,9 @@ __p+='<form class="add-chatroom" action="" method="post">\n <label>'+
((__t=(label_nickname))==null?'':__t)+
'</label>\n <input type="text" name="nick" class="new-chatroom-nick"\n placeholder="'+
((__t=(label_nickname))==null?'':__t)+
'"/>\n <label>'+
'"/>\n <label'+
((__t=(server_label_global_attr))==null?'':__t)+
'>'+
((__t=(label_server))==null?'':__t)+
'</label>\n <input type="'+
((__t=(server_input_type))==null?'':__t)+
......@@ -13406,9 +13602,13 @@ __p+='<a class="open-chat" title="Name: '+
((__t=(desc_status))==null?'':__t)+
'"></span>'+
((__t=(fullname))==null?'':__t)+
'</a>\n<a class="remove-xmpp-contact icon-remove" title="'+
'</a>\n';
if (allow_contact_removal) {
__p+='\n<a class="remove-xmpp-contact icon-remove" title="'+
((__t=(desc_remove))==null?'':__t)+
'" href="#"></a>\n';
}
__p+='\n';
}
return __p;
}; });
......@@ -27013,19 +27213,6 @@ define("converse-dependencies", [
return this;
};
var playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
var converse = {
plugins: {},
templates: templates,
......@@ -27132,6 +27319,7 @@ define("converse-dependencies", [
// Default configuration values
// ----------------------------
this.default_settings = {
allow_contact_removal: true,
allow_contact_requests: true,
allow_dragresize: true,
allow_logout: true,
......@@ -27246,6 +27434,19 @@ define("converse-dependencies", [
// Module-level functions
// ----------------------
this.playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
this.giveFeedback = function (message, klass) {
$('.conn-feedback').each(function (idx, el) {
var $el = $(el);
......@@ -27318,7 +27519,6 @@ define("converse-dependencies", [
this.reconnect = function () {
converse.giveFeedback(__('Reconnecting'), 'error');
converse.emit('reconnect');
if (!converse.prebind) {
this.connection.connect(
this.connection.jid,
......@@ -27330,6 +27530,10 @@ define("converse-dependencies", [
this.connection.hold,
this.connection.route
);
} else if (converse.prebind_url) {
this.clearSession();
this._tearDown();
this.startNewBOSHSession();
}
};
......@@ -27366,6 +27570,7 @@ define("converse-dependencies", [
converse.giveFeedback(__('Authentication Failed'), 'error');
converse.connection.disconnect(__('Authentication Failed'));
} else if (status === Strophe.Status.DISCONNECTING) {
// FIXME: what about prebind?
if (!converse.connection.connected) {
converse.renderLoginPanel();
}
......@@ -27441,8 +27646,8 @@ define("converse-dependencies", [
this.clearSession = function () {
this.roster.browserStorage._clear();
this.session.browserStorage._clear();
// XXX: this should perhaps go into the beforeunload handler
converse.chatboxes.get('controlbox').save({'connected': false});
var controlbox = converse.chatboxes.get('controlbox');
controlbox.save({'connected': false});
};
this.setSession = function () {
......@@ -28647,6 +28852,7 @@ define("converse-dependencies", [
this.$el.html(
converse.templates.room_panel({
'server_input_type': converse.hide_muc_server && 'hidden' || 'text',
'server_label_global_attr': converse.hide_muc_server && ' hidden' || '',
'label_room_name': __('Room name'),
'label_nickname': __('Nickname'),
'label_server': __('Server'),
......@@ -29859,7 +30065,7 @@ define("converse-dependencies", [
}
this.model.createMessage($message);
if (!delayed && sender !== this.model.get('nick') && (new RegExp("\\b"+this.model.get('nick')+"\\b")).test(body)) {
playNotification();
converse.playNotification();
}
if (sender !== this.model.get('nick')) {
// We only emit an event if it's not our own message
......@@ -30029,7 +30235,7 @@ define("converse-dependencies", [
return true; // We already have this message stored.
}
if (!this.isOnlyChatStateNotification($message) && from !== converse.bare_jid) {
playNotification();
converse.playNotification();
}
chatbox.receiveMessage($message);
converse.roster.addResource(contact_jid, resource);
......@@ -30460,7 +30666,8 @@ define("converse-dependencies", [
_.extend(item.toJSON(), {
'desc_status': STATUSES[chat_status||'offline'],
'desc_chat': __('Click to chat with this contact'),
'desc_remove': __('Click to remove this contact')
'desc_remove': __('Click to remove this contact'),
'allow_contact_removal': converse.allow_contact_removal
})
));
}
......@@ -30474,6 +30681,7 @@ define("converse-dependencies", [
removeContact: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (!converse.allow_contact_removal) { return; }
var result = confirm(__("Are you sure you want to remove this contact?"));
if (result === true) {
var bare_jid = this.model.get('jid');
......@@ -32174,20 +32382,32 @@ define("converse-dependencies", [
}
};
this.startNewBOSHSession = function () {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: response.rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
};
this.initConnection = function () {
var rid, sid, jid;
if (this.connection && this.connection.connected) {
this.setUpXMLLogging();
this.onConnected();
} else {
// XXX: it's not yet clear what the order of preference should
// be between RID and SID received via the initialize method or
// those received from sessionStorage.
//
// What do you we if we receive values from both avenues?
//
// Also, what do we do when the keepalive session values are
// expired? Do we try to fall back?
if (!this.bosh_service_url && ! this.websocket_url) {
throw("Error: you must supply a value for the bosh_service_url or websocket_url");
}
......@@ -32213,33 +32433,25 @@ define("converse-dependencies", [
rid = this.session.get('rid');
sid = this.session.get('sid');
jid = this.session.get('jid');
if (rid && jid && sid) {
// The RID needs to be increased with each request.
this.session.save({rid: rid});
if (this.prebind) {
if (!this.jid) {
throw("When using 'keepalive' with 'prebind, you must supply the JID of the current user.");
}
if (rid && sid && jid && Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(this.jid)) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
} else if (this.prebind) {
if (this.prebind_url) {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
} else if (this.prebind_url) {
this.startNewBOSHSession();
} else {
delete this.connection;
this.emit('noResumeableSession');
}
} else {
// Non-prebind case.
if (rid && sid && jid) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
}
}
}
}
......@@ -32319,6 +32531,14 @@ define("converse-dependencies", [
'initialize': function (settings, callback) {
converse.initialize(settings, callback);
},
'disconnect': function () {
converse.connection.disconnect();
},
'account': {
'logout': function () {
converse.logOut();
},
},
'settings': {
'get': function (key) {
if (_.contains(Object.keys(converse.default_settings), key)) {
......@@ -32624,7 +32844,6 @@ require.config({
// define module dependencies for modules not using define
shim: {
'underscore': { exports: '_' },
'crypto.aes': { deps: ['crypto.cipher-core'] },
'crypto.cipher-core': { deps: ['crypto.enc-base64', 'crypto.evpkdf'] },
'crypto.enc-base64': { deps: ['crypto.core'] },
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* @license almond 0.3.0 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/almond for details
*/
......@@ -44,12 +44,6 @@ var requirejs, require, define;
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
//Convert baseName to array, and lop off the last part,
//so that . matches that "directory" and not name of the baseName's
//module. For instance, baseName of "one/two/three", maps to
//"one/two/three.js", but we want the directory, "one/two" for
//this normalization.
baseParts = baseParts.slice(0, baseParts.length - 1);
name = name.split('/');
lastIndex = name.length - 1;
......@@ -58,7 +52,11 @@ var requirejs, require, define;
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
}
name = baseParts.concat(name);
//Lop off the last part of baseParts, so that . matches the
//"directory" and not name of the baseName's module. For instance,
//baseName of "one/two/three", maps to "one/two/three.js", but we
//want the directory, "one/two" for this normalization.
name = baseParts.slice(0, baseParts.length - 1).concat(name);
//start trimDots
for (i = 0; i < name.length; i += 1) {
......@@ -408,6 +406,9 @@ var requirejs, require, define;
requirejs._defined = defined;
define = function (name, deps, callback) {
if (typeof name !== 'string') {
throw new Error('See almond README: incorrect module build, no module name');
}
//This module may not have dependencies
if (!deps.splice) {
......@@ -11164,9 +11165,9 @@ define('text',['module'], function (module) {
return text;
});
// Underscore.js 1.6.0
// Underscore.js 1.8.2
// http://underscorejs.org
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
......@@ -11180,9 +11181,6 @@ define('text',['module'], function (module) {
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
......@@ -11190,25 +11188,19 @@ define('text',['module'], function (module) {
var
push = ArrayProto.push,
slice = ArrayProto.slice,
concat = ArrayProto.concat,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
nativeBind = FuncProto.bind,
nativeCreate = Object.create;
// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
......@@ -11219,8 +11211,7 @@ define('text',['module'], function (module) {
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
// the browser, add `_` as a global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
......@@ -11231,161 +11222,208 @@ define('text',['module'], function (module) {
}
// Current version.
_.VERSION = '1.6.0';
_.VERSION = '1.8.2';
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var optimizeCb = function(func, context, argCount) {
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function(value) {
return func.call(context, value);
};
case 2: return function(value, other) {
return func.call(context, value, other);
};
case 3: return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
// A mostly-internal function to generate callbacks that can be applied
// to each element in a collection, returning the desired result — either
// identity, an arbitrary callback, a property matcher, or a property accessor.
var cb = function(value, context, argCount) {
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value)) return _.matcher(value);
return _.property(value);
};
_.iteratee = function(value, context) {
return cb(value, context, Infinity);
};
// An internal function for creating assigner functions.
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var isArrayLike = function(collection) {
var length = collection && collection.length;
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results.push(iterator.call(context, value, index, list));
});
// Return the results of applying the iteratee to each element.
_.map = _.collect = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
results = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
var reduceError = 'Reduce of empty array with no initial value';
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
// Create a reducing function iterating left or right.
function createReduce(dir) {
// Optimized iterator function as using arguments.length
// in the main function will deoptimize the, see #1991.
function iterator(obj, iteratee, memo, keys, index, length) {
for (; index >= 0 && index < length; index += dir) {
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var length = obj.length;
if (length !== +length) {
var keys = _.keys(obj);
length = keys.length;
}
each(obj, function(value, index, list) {
index = keys ? keys[--length] : --length;
if (!initial) {
memo = obj[index];
initial = true;
} else {
memo = iterator.call(context, memo, obj[index], index, list);
return function(obj, iteratee, memo, context) {
iteratee = optimizeCb(iteratee, context, 4);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
index = dir > 0 ? 0 : length - 1;
// Determine the initial value if none is provided.
if (arguments.length < 3) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
return iterator(obj, iteratee, memo, keys, index, length);
};
}
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`.
_.reduce = _.foldl = _.inject = createReduce(1);
// The right-associative version of reduce, also known as `foldr`.
_.reduceRight = _.foldr = createReduce(-1);
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, predicate, context) {
var result;
any(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) {
result = value;
return true;
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
});
return result;
if (key !== void 0 && key !== -1) return obj[key];
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) results.push(value);
predicate = cb(predicate, context);
_.each(obj, function(value, index, list) {
if (predicate(value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) {
return !predicate.call(context, value, index, list);
}, context);
return _.filter(obj, _.negate(cb(predicate)), context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) {
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});
return !!result;
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (!predicate(obj[currentKey], currentKey, obj)) return false;
}
return true;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
_.some = _.any = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (predicate(obj[currentKey], currentKey, obj)) return true;
}
return false;
};
// Determine if the array or object contains a given value (using `===`).
// Aliased as `include`.
_.contains = _.include = function(obj, target) {
if (obj == null) return false;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
return any(obj, function(value) {
return value === target;
});
// Aliased as `includes` and `include`.
_.contains = _.includes = _.include = function(obj, target, fromIndex) {
if (!isArrayLike(obj)) obj = _.values(obj);
return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0;
};
// Invoke a method (with arguments) on every item in a collection.
......@@ -11393,7 +11431,8 @@ define('text',['module'], function (module) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
return (isFunc ? method : value[method]).apply(value, args);
var func = isFunc ? method : value[method];
return func == null ? func : func.apply(value, args);
});
};
......@@ -11405,60 +11444,76 @@ define('text',['module'], function (module) {
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs) {
return _.filter(obj, _.matches(attrs));
return _.filter(obj, _.matcher(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.find(obj, _.matches(attrs));
return _.find(obj, _.matcher(attrs));
};
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
// Return the maximum element (or element-based computation).
_.max = function(obj, iteratee, context) {
var result = -Infinity, lastComputed = -Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value > result) {
result = value;
}
}
var result = -Infinity, lastComputed = -Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed > lastComputed) {
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj);
}
var result = Infinity, lastComputed = Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed < lastComputed) {
_.min = function(obj, iteratee, context) {
var result = Infinity, lastComputed = Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value < result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed < lastComputed || computed === Infinity && result === Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Shuffle an array, using the modern version of the
// Shuffle a collection, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
var shuffled = [];
each(obj, function(value) {
rand = _.random(index++);
shuffled[index - 1] = shuffled[rand];
shuffled[rand] = value;
});
var set = isArrayLike(obj) ? obj : _.values(obj);
var length = set.length;
var shuffled = Array(length);
for (var index = 0, rand; index < length; index++) {
rand = _.random(0, index);
if (rand !== index) shuffled[index] = shuffled[rand];
shuffled[rand] = set[index];
}
return shuffled;
};
......@@ -11467,27 +11522,20 @@ define('text',['module'], function (module) {
// The internal `guard` argument allows it to work with `map`.
_.sample = function(obj, n, guard) {
if (n == null || guard) {
if (obj.length !== +obj.length) obj = _.values(obj);
if (!isArrayLike(obj)) obj = _.values(obj);
return obj[_.random(obj.length - 1)];
}
return _.shuffle(obj).slice(0, Math.max(0, n));
};
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
if (value == null) return _.identity;
if (_.isFunction(value)) return value;
return _.property(value);
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
iterator = lookupIterator(iterator);
// Sort the object's values by a criterion produced by an iteratee.
_.sortBy = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value: value,
index: index,
criteria: iterator.call(context, value, index, list)
criteria: iteratee(value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
......@@ -11502,12 +11550,12 @@ define('text',['module'], function (module) {
// An internal function used for aggregate "group by" operations.
var group = function(behavior) {
return function(obj, iterator, context) {
return function(obj, iteratee, context) {
var result = {};
iterator = lookupIterator(iterator);
each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj);
behavior(result, key, value);
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
......@@ -11515,48 +11563,46 @@ define('text',['module'], function (module) {
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, key, value) {
_.has(result, key) ? result[key].push(value) : result[key] = [value];
_.groupBy = group(function(result, value, key) {
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_.indexBy = group(function(result, key, value) {
_.indexBy = group(function(result, value, key) {
result[key] = value;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_.countBy = group(function(result, key) {
_.has(result, key) ? result[key]++ : result[key] = 1;
_.countBy = group(function(result, value, key) {
if (_.has(result, key)) result[key]++; else result[key] = 1;
});
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) {
iterator = lookupIterator(iterator);
var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >>> 1;
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
}
return low;
};
// Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) return _.map(obj, _.identity);
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
if (obj == null) return 0;
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(obj, predicate, context) {
predicate = cb(predicate, context);
var pass = [], fail = [];
_.each(obj, function(value, key, obj) {
(predicate(value, key, obj) ? pass : fail).push(value);
});
return [pass, fail];
};
// Array Functions
......@@ -11567,33 +11613,30 @@ define('text',['module'], function (module) {
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[0];
if (n < 0) return [];
return slice.call(array, 0, n);
if (n == null || guard) return array[0];
return _.initial(array, array.length - n);
};
// Returns everything but the last entry of the array. Especially useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
// the array, excluding the last N.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
// values in the array.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[array.length - 1];
return slice.call(array, Math.max(array.length - n, 0));
if (n == null || guard) return array[array.length - 1];
return _.rest(array, Math.max(0, array.length - n));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Especially useful on the arguments object. Passing an **n** will return
// the rest N values in the array. The **guard**
// check allows it to work with `_.map`.
// the rest N values in the array.
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, (n == null) || guard ? 1 : n);
return slice.call(array, n == null || guard ? 1 : n);
};
// Trim out all falsy values from an array.
......@@ -11602,23 +11645,28 @@ define('text',['module'], function (module) {
};
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
if (shallow && _.every(input, _.isArray)) {
return concat.apply(output, input);
var flatten = function(input, shallow, strict, startIndex) {
var output = [], idx = 0;
for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
//flatten current level of array or arguments object
if (!shallow) value = flatten(value, shallow, strict);
var j = 0, len = value.length;
output.length += len;
while (j < len) {
output[idx++] = value[j++];
}
} else if (!strict) {
output[idx++] = value;
}
each(input, function(value) {
if (_.isArray(value) || _.isArguments(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
}
});
return output;
};
// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
return flatten(array, shallow, false);
};
// Return a version of the array that does not contain the specified value(s).
......@@ -11626,79 +11674,93 @@ define('text',['module'], function (module) {
return _.difference(array, slice.call(arguments, 1));
};
// Split an array into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(array, predicate) {
var pass = [], fail = [];
each(array, function(elem) {
(predicate(elem) ? pass : fail).push(elem);
});
return [pass, fail];
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator, context) {
if (_.isFunction(isSorted)) {
context = iterator;
iterator = isSorted;
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (array == null) return [];
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array;
var results = [];
if (iteratee != null) iteratee = cb(iteratee, context);
var result = [];
var seen = [];
each(initial, function(value, index) {
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
seen.push(value);
results.push(array[index]);
for (var i = 0, length = array.length; i < length; i++) {
var value = array[i],
computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== computed) result.push(value);
seen = computed;
} else if (iteratee) {
if (!_.contains(seen, computed)) {
seen.push(computed);
result.push(value);
}
});
return results;
} else if (!_.contains(result, value)) {
result.push(value);
}
}
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
return _.uniq(flatten(arguments, true, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersection = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.contains(other, item);
});
});
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
return _.filter(array, function(value){ return !_.contains(rest, value); });
var rest = flatten(arguments, true, true, 1);
return _.filter(array, function(value){
return !_.contains(rest, value);
});
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(arguments, '' + i);
return _.unzip(arguments);
};
// Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices
_.unzip = function(array) {
var length = array && _.max(array, 'length').length || 0;
var result = Array(length);
for (var index = 0; index < length; index++) {
result[index] = _.pluck(array, index);
}
return results;
return result;
};
// Converts lists into objects. Pass either a single array of `[key, value]`
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values.
_.object = function(list, values) {
if (list == null) return {};
var result = {};
for (var i = 0, length = list.length; i < length; i++) {
for (var i = 0, length = list && list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
......@@ -11708,40 +11770,68 @@ define('text',['module'], function (module) {
return result;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// Return the position of the first occurrence of an item in an array,
// or -1 if the item is not included in the array.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i = 0, length = array.length;
if (isSorted) {
var i = 0, length = array && array.length;
if (typeof isSorted == 'number') {
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
} else if (isSorted && length) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (item !== item) {
return _.findIndex(slice.call(array, i), _.isNaN);
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item, from) {
if (array == null) return -1;
var hasIndex = from != null;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
var idx = array ? array.length : 0;
if (typeof from == 'number') {
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
}
if (item !== item) {
return _.findLastIndex(slice.call(array, 0, idx), _.isNaN);
}
var i = (hasIndex ? from : array.length);
while (i--) if (array[i] === item) return i;
while (--idx >= 0) if (array[idx] === item) return idx;
return -1;
};
// Generator function to create the findIndex and findLastIndex functions
function createIndexFinder(dir) {
return function(array, predicate, context) {
predicate = cb(predicate, context);
var length = array != null && array.length;
var index = dir > 0 ? 0 : length - 1;
for (; index >= 0 && index < length; index += dir) {
if (predicate(array[index], index, array)) return index;
}
return -1;
};
}
// Returns the first index on an array-like that passes a predicate test
_.findIndex = createIndexFinder(1);
_.findLastIndex = createIndexFinder(-1);
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = array.length;
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
}
return low;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
......@@ -11750,15 +11840,13 @@ define('text',['module'], function (module) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
step = step || 1;
var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(length);
var range = Array(length);
while(idx < length) {
range[idx++] = start;
start += step;
for (var idx = 0; idx < length; idx++, start += step) {
range[idx] = start;
}
return range;
......@@ -11767,26 +11855,27 @@ define('text',['module'], function (module) {
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
if (_.isObject(result)) return result;
return self;
};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
var args, bound;
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
ctor.prototype = null;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
var args = slice.call(arguments, 2);
var bound = function() {
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
};
return bound;
};
// Partially apply a function by creating a version that has had some of its
......@@ -11794,49 +11883,55 @@ define('text',['module'], function (module) {
// as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
var boundArgs = slice.call(arguments, 1);
return function() {
var position = 0;
var args = boundArgs.slice();
for (var i = 0, length = args.length; i < length; i++) {
if (args[i] === _) args[i] = arguments[position++];
var bound = function() {
var position = 0, length = boundArgs.length;
var args = Array(length);
for (var i = 0; i < length; i++) {
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
}
while (position < arguments.length) args.push(arguments[position++]);
return func.apply(this, args);
return executeBound(func, bound, this, this, args);
};
return bound;
};
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
var i, length = arguments.length, key;
if (length <= 1) throw new Error('bindAll must be passed function names');
for (i = 1; i < length; i++) {
key = arguments[i];
obj[key] = _.bind(obj[key], obj);
}
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
var memoize = function(key) {
var cache = memoize.cache;
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
return cache[address];
};
memoize.cache = {};
return memoize;
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(null, args); }, wait);
return setTimeout(function(){
return func.apply(null, args);
}, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
_.defer = _.partial(_.delay, _, 1);
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
......@@ -11847,12 +11942,12 @@ define('text',['module'], function (module) {
var context, args, result;
var timeout = null;
var previous = 0;
options || (options = {});
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
......@@ -11860,12 +11955,14 @@ define('text',['module'], function (module) {
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
......@@ -11882,13 +11979,14 @@ define('text',['module'], function (module) {
var later = function() {
var last = _.now() - timestamp;
if (last < wait) {
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
}
}
};
......@@ -11898,9 +11996,7 @@ define('text',['module'], function (module) {
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
......@@ -11910,19 +12006,6 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
......@@ -11930,20 +12013,27 @@ define('text',['module'], function (module) {
return _.partial(wrapper, func);
};
// Returns a negated version of the passed-in predicate.
_.negate = function(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
// Returns a function that will only be executed after being called N times.
// Returns a function that will only be executed on and after the Nth call.
_.after = function(times, func) {
return function() {
if (--times < 1) {
......@@ -11952,16 +12042,66 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will only be executed up to (but not including) the Nth call.
_.before = function(times, func) {
var memo;
return function() {
if (--times > 0) {
memo = func.apply(this, arguments);
}
if (times <= 1) func = null;
return memo;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = _.partial(_.before, 2);
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
function collectNonEnumProps(obj, keys) {
var nonEnumIdx = nonEnumerableProps.length;
var constructor = obj.constructor;
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
// Constructor is a special case.
var prop = 'constructor';
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
while (nonEnumIdx--) {
prop = nonEnumerableProps[nonEnumIdx];
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
keys.push(prop);
}
}
}
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
// Retrieve all the property names of an object.
_.allKeys = function(obj) {
if (!_.isObject(obj)) return [];
var keys = [];
for (var key in obj) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
......@@ -11969,18 +12109,33 @@ define('text',['module'], function (module) {
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = new Array(length);
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
// Returns the results of applying the iteratee to each element of the object
// In contrast to _.map it returns an object
_.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = _.keys(obj),
length = keys.length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys[index];
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var pairs = new Array(length);
var pairs = Array(length);
for (var i = 0; i < length; i++) {
pairs[i] = [keys[i], obj[keys[i]]];
}
......@@ -12008,48 +12163,57 @@ define('text',['module'], function (module) {
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
_.extend = createAssigner(_.allKeys);
// Assigns a given object with all the own properties in the passed-in object(s)
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_.extendOwn = _.assign = createAssigner(_.keys);
// Returns the first key on an object that passes a predicate test
_.findKey = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = _.keys(obj), key;
for (var i = 0, length = keys.length; i < length; i++) {
key = keys[i];
if (predicate(obj[key], key, obj)) return key;
}
});
return obj;
};
// Return a copy of the object only containing the whitelisted properties.
_.pick = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
each(keys, function(key) {
if (key in obj) copy[key] = obj[key];
});
return copy;
_.pick = function(object, oiteratee, context) {
var result = {}, obj = object, iteratee, keys;
if (obj == null) return result;
if (_.isFunction(oiteratee)) {
keys = _.allKeys(obj);
iteratee = optimizeCb(oiteratee, context);
} else {
keys = flatten(arguments, false, false, 1);
iteratee = function(value, key, obj) { return key in obj; };
obj = Object(obj);
}
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = obj[key];
if (iteratee(value, key, obj)) result[key] = value;
}
return result;
};
// Return a copy of the object without the blacklisted properties.
_.omit = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
for (var key in obj) {
if (!_.contains(keys, key)) copy[key] = obj[key];
_.omit = function(obj, iteratee, context) {
if (_.isFunction(iteratee)) {
iteratee = _.negate(iteratee);
} else {
var keys = _.map(flatten(arguments, false, false, 1), String);
iteratee = function(value, key) {
return !_.contains(keys, key);
};
}
return copy;
return _.pick(obj, iteratee, context);
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
if (obj[prop] === void 0) obj[prop] = source[prop];
}
}
});
return obj;
};
_.defaults = createAssigner(_.allKeys, true);
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
......@@ -12065,11 +12229,24 @@ define('text',['module'], function (module) {
return obj;
};
// Returns whether an object has a given set of `key:value` pairs.
_.isMatch = function(object, attrs) {
var keys = _.keys(attrs), length = keys.length;
if (object == null) return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = keys[i];
if (attrs[key] !== obj[key] || !(key in obj)) return false;
}
return true;
};
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a == 1 / b;
if (a === b) return a !== 0 || 1 / a === 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
......@@ -12077,98 +12254,98 @@ define('text',['module'], function (module) {
if (b instanceof _) b = b._wrapped;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
if (className !== toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case '[object RegExp]':
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(b);
return '' + a === '' + b;
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
return +a === +b;
}
var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
_.isFunction(bCtor) && bCtor instanceof bCtor)
&& ('constructor' in a && 'constructor' in b)) {
return false;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (aStack[length] == a) return bStack[length] == b;
}
// Objects with different constructors are not equivalent, but `Object`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
_.isFunction(bCtor) && (bCtor instanceof bCtor))
&& ('constructor' in a && 'constructor' in b)) {
return false;
if (aStack[length] === a) return bStack[length] === b;
}
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
}
while (length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (_.has(b, key) && !(size--)) break;
}
result = !size;
var keys = _.keys(a), key;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (_.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return result;
return true;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, [], []);
return eq(a, b);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (obj == null) return true;
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (_.has(obj, key)) return false;
return true;
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
return _.keys(obj).length === 0;
};
// Is a given value a DOM element?
......@@ -12179,33 +12356,35 @@ define('text',['module'], function (module) {
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
return toString.call(obj) === '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
return toString.call(obj) === '[object ' + name + ']';
};
});
// Define a fallback version of the method in browsers (ahem, IE), where
// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
return _.has(obj, 'callee');
};
}
// Optimize `isFunction` if appropriate.
if (typeof (/./) !== 'function') {
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
// IE 11 (#1621), and in Safari 8 (#1929).
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
_.isFunction = function(obj) {
return typeof obj === 'function';
return typeof obj == 'function' || false;
};
}
......@@ -12216,12 +12395,12 @@ define('text',['module'], function (module) {
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(obj) {
return _.isNumber(obj) && obj != +obj;
return _.isNumber(obj) && obj !== +obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
};
// Is a given value equal to null?
......@@ -12237,7 +12416,7 @@ define('text',['module'], function (module) {
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
return obj != null && hasOwnProperty.call(obj, key);
};
// Utility Functions
......@@ -12250,39 +12429,47 @@ define('text',['module'], function (module) {
return this;
};
// Keep the identity function around for default iterators.
// Keep the identity function around for default iteratees.
_.identity = function(value) {
return value;
};
// Predicate-generating functions. Often useful outside of Underscore.
_.constant = function(value) {
return function () {
return function() {
return value;
};
};
_.noop = function(){};
_.property = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
// Generates a function for a given object that returns a given property.
_.propertyOf = function(obj) {
return obj == null ? function(){} : function(key) {
return obj[key];
};
};
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
_.matches = function(attrs) {
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
_.matcher = _.matches = function(attrs) {
attrs = _.extendOwn({}, attrs);
return function(obj) {
if (obj === attrs) return true; //avoid comparing an object to itself.
for (var key in attrs) {
if (attrs[key] !== obj[key])
return false;
}
return true;
}
return _.isMatch(obj, attrs);
};
};
// Run a function **n** times.
_.times = function(n, iterator, context) {
_.times = function(n, iteratee, context) {
var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
iteratee = optimizeCb(iteratee, context, 1);
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
return accum;
};
......@@ -12296,56 +12483,48 @@ define('text',['module'], function (module) {
};
// A (possibly faster) way to get the current timestamp as an integer.
_.now = Date.now || function() { return new Date().getTime(); };
_.now = Date.now || function() {
return new Date().getTime();
};
// List of HTML entities for escaping.
var entityMap = {
escape: {
var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;'
}
};
entityMap.unescape = _.invert(entityMap.escape);
// Regexes containing the keys and values listed immediately above.
var entityRegexes = {
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
"'": '&#x27;',
'`': '&#x60;'
};
var unescapeMap = _.invert(escapeMap);
// Functions for escaping and unescaping strings to/from HTML interpolation.
_.each(['escape', 'unescape'], function(method) {
_[method] = function(string) {
if (string == null) return '';
return ('' + string).replace(entityRegexes[method], function(match) {
return entityMap[method][match];
});
var createEscaper = function(map) {
var escaper = function(match) {
return map[match];
};
});
// Regexes for identifying a key that needs to be escaped
var source = '(?:' + _.keys(map).join('|') + ')';
var testRegexp = RegExp(source);
var replaceRegexp = RegExp(source, 'g');
return function(string) {
string = string == null ? '' : '' + string;
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
};
};
_.escape = createEscaper(escapeMap);
_.unescape = createEscaper(unescapeMap);
// If the value of the named `property` is a function then invoke it with the
// `object` as context; otherwise, return it.
_.result = function(object, property) {
if (object == null) return void 0;
var value = object[property];
_.result = function(object, property, fallback) {
var value = object == null ? void 0 : object[property];
if (value === void 0) {
value = fallback;
}
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result.call(this, func.apply(_, args));
};
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
......@@ -12374,22 +12553,26 @@ define('text',['module'], function (module) {
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
// NB: `oldSettings` only exists for backwards compatibility.
_.template = function(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
......@@ -12399,19 +12582,18 @@ define('text',['module'], function (module) {
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
source += text.slice(index, offset).replace(escaper, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
// Adobe VMs need the match returned to produce the correct offest.
return match;
});
source += "';\n";
......@@ -12421,29 +12603,31 @@ define('text',['module'], function (module) {
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
source + 'return __p;\n';
try {
render = new Function(settings.variable || 'obj', '_', source);
var render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
// Provide the compiled source as a convenience for precompilation.
var argument = settings.variable || 'obj';
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
};
// Add a "chain" function, which will delegate to the wrapper.
// Add a "chain" function. Start chaining a wrapped Underscore object.
_.chain = function(obj) {
return _(obj).chain();
var instance = _(obj);
instance._chain = true;
return instance;
};
// OOP
......@@ -12453,46 +12637,56 @@ define('text',['module'], function (module) {
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var result = function(obj) {
return this._chain ? _(obj).chain() : obj;
var result = function(instance, obj) {
return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
});
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
var obj = this._wrapped;
method.apply(obj, arguments);
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
return result.call(this, obj);
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
return result(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
_.each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
return result.call(this, method.apply(this._wrapped, arguments));
return result(this, method.apply(this._wrapped, arguments));
};
});
_.extend(_.prototype, {
// Start chaining a wrapped Underscore object.
chain: function() {
this._chain = true;
return this;
},
// Extracts the result from a wrapped and chained object.
value: function() {
_.prototype.value = function() {
return this._wrapped;
}
};
});
// Provide unwrapping proxy for some methods used in engine operations
// such as arithmetic and JSON stringification.
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
_.prototype.toString = function() {
return '' + this._wrapped;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
......@@ -12506,7 +12700,7 @@ define('text',['module'], function (module) {
return _;
});
}
}).call(this);
}.call(this));
// RequireJS UnderscoreJS template plugin
// http://github.com/jfparadis/requirejs-tpl
......@@ -13031,7 +13225,7 @@ var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments
with(obj||{}){
__p+='<form id="converse-login" method="post">\n <label>'+
((__t=(label_username))==null?'':__t)+
'</label>\n <input type="username" name="jid" placeholder="user@server">\n <label>'+
'</label>\n <input type="email" name="jid" placeholder="user@server">\n <label>'+
((__t=(label_password))==null?'':__t)+
'</label>\n <input type="password" name="password" placeholder="password">\n <input class="submit" type="submit" value="'+
((__t=(label_login))==null?'':__t)+
......@@ -13360,7 +13554,9 @@ __p+='<form class="add-chatroom" action="" method="post">\n <label>'+
((__t=(label_nickname))==null?'':__t)+
'</label>\n <input type="text" name="nick" class="new-chatroom-nick"\n placeholder="'+
((__t=(label_nickname))==null?'':__t)+
'"/>\n <label>'+
'"/>\n <label'+
((__t=(server_label_global_attr))==null?'':__t)+
'>'+
((__t=(label_server))==null?'':__t)+
'</label>\n <input type="'+
((__t=(server_input_type))==null?'':__t)+
......@@ -13406,9 +13602,13 @@ __p+='<a class="open-chat" title="Name: '+
((__t=(desc_status))==null?'':__t)+
'"></span>'+
((__t=(fullname))==null?'':__t)+
'</a>\n<a class="remove-xmpp-contact icon-remove" title="'+
'</a>\n';
if (allow_contact_removal) {
__p+='\n<a class="remove-xmpp-contact icon-remove" title="'+
((__t=(desc_remove))==null?'':__t)+
'" href="#"></a>\n';
}
__p+='\n';
}
return __p;
}; });
......@@ -34610,19 +34810,6 @@ define("converse-dependencies", [
return this;
};
var playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
var converse = {
plugins: {},
templates: templates,
......@@ -34729,6 +34916,7 @@ define("converse-dependencies", [
// Default configuration values
// ----------------------------
this.default_settings = {
allow_contact_removal: true,
allow_contact_requests: true,
allow_dragresize: true,
allow_logout: true,
......@@ -34843,6 +35031,19 @@ define("converse-dependencies", [
// Module-level functions
// ----------------------
this.playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
this.giveFeedback = function (message, klass) {
$('.conn-feedback').each(function (idx, el) {
var $el = $(el);
......@@ -34915,7 +35116,6 @@ define("converse-dependencies", [
this.reconnect = function () {
converse.giveFeedback(__('Reconnecting'), 'error');
converse.emit('reconnect');
if (!converse.prebind) {
this.connection.connect(
this.connection.jid,
......@@ -34927,6 +35127,10 @@ define("converse-dependencies", [
this.connection.hold,
this.connection.route
);
} else if (converse.prebind_url) {
this.clearSession();
this._tearDown();
this.startNewBOSHSession();
}
};
......@@ -34963,6 +35167,7 @@ define("converse-dependencies", [
converse.giveFeedback(__('Authentication Failed'), 'error');
converse.connection.disconnect(__('Authentication Failed'));
} else if (status === Strophe.Status.DISCONNECTING) {
// FIXME: what about prebind?
if (!converse.connection.connected) {
converse.renderLoginPanel();
}
......@@ -35038,8 +35243,8 @@ define("converse-dependencies", [
this.clearSession = function () {
this.roster.browserStorage._clear();
this.session.browserStorage._clear();
// XXX: this should perhaps go into the beforeunload handler
converse.chatboxes.get('controlbox').save({'connected': false});
var controlbox = converse.chatboxes.get('controlbox');
controlbox.save({'connected': false});
};
this.setSession = function () {
......@@ -36244,6 +36449,7 @@ define("converse-dependencies", [
this.$el.html(
converse.templates.room_panel({
'server_input_type': converse.hide_muc_server && 'hidden' || 'text',
'server_label_global_attr': converse.hide_muc_server && ' hidden' || '',
'label_room_name': __('Room name'),
'label_nickname': __('Nickname'),
'label_server': __('Server'),
......@@ -37456,7 +37662,7 @@ define("converse-dependencies", [
}
this.model.createMessage($message);
if (!delayed && sender !== this.model.get('nick') && (new RegExp("\\b"+this.model.get('nick')+"\\b")).test(body)) {
playNotification();
converse.playNotification();
}
if (sender !== this.model.get('nick')) {
// We only emit an event if it's not our own message
......@@ -37626,7 +37832,7 @@ define("converse-dependencies", [
return true; // We already have this message stored.
}
if (!this.isOnlyChatStateNotification($message) && from !== converse.bare_jid) {
playNotification();
converse.playNotification();
}
chatbox.receiveMessage($message);
converse.roster.addResource(contact_jid, resource);
......@@ -38057,7 +38263,8 @@ define("converse-dependencies", [
_.extend(item.toJSON(), {
'desc_status': STATUSES[chat_status||'offline'],
'desc_chat': __('Click to chat with this contact'),
'desc_remove': __('Click to remove this contact')
'desc_remove': __('Click to remove this contact'),
'allow_contact_removal': converse.allow_contact_removal
})
));
}
......@@ -38071,6 +38278,7 @@ define("converse-dependencies", [
removeContact: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (!converse.allow_contact_removal) { return; }
var result = confirm(__("Are you sure you want to remove this contact?"));
if (result === true) {
var bare_jid = this.model.get('jid');
......@@ -39771,20 +39979,32 @@ define("converse-dependencies", [
}
};
this.startNewBOSHSession = function () {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: response.rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
};
this.initConnection = function () {
var rid, sid, jid;
if (this.connection && this.connection.connected) {
this.setUpXMLLogging();
this.onConnected();
} else {
// XXX: it's not yet clear what the order of preference should
// be between RID and SID received via the initialize method or
// those received from sessionStorage.
//
// What do you we if we receive values from both avenues?
//
// Also, what do we do when the keepalive session values are
// expired? Do we try to fall back?
if (!this.bosh_service_url && ! this.websocket_url) {
throw("Error: you must supply a value for the bosh_service_url or websocket_url");
}
......@@ -39810,33 +40030,25 @@ define("converse-dependencies", [
rid = this.session.get('rid');
sid = this.session.get('sid');
jid = this.session.get('jid');
if (rid && jid && sid) {
// The RID needs to be increased with each request.
this.session.save({rid: rid});
if (this.prebind) {
if (!this.jid) {
throw("When using 'keepalive' with 'prebind, you must supply the JID of the current user.");
}
if (rid && sid && jid && Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(this.jid)) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
} else if (this.prebind) {
if (this.prebind_url) {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
} else if (this.prebind_url) {
this.startNewBOSHSession();
} else {
delete this.connection;
this.emit('noResumeableSession');
}
} else {
// Non-prebind case.
if (rid && sid && jid) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
}
}
}
}
......@@ -39916,6 +40128,14 @@ define("converse-dependencies", [
'initialize': function (settings, callback) {
converse.initialize(settings, callback);
},
'disconnect': function () {
converse.connection.disconnect();
},
'account': {
'logout': function () {
converse.logOut();
},
},
'settings': {
'get': function (key) {
if (_.contains(Object.keys(converse.default_settings), key)) {
......@@ -40221,7 +40441,6 @@ require.config({
// define module dependencies for modules not using define
shim: {
'underscore': { exports: '_' },
'crypto.aes': { deps: ['crypto.cipher-core'] },
'crypto.cipher-core': { deps: ['crypto.enc-base64', 'crypto.evpkdf'] },
'crypto.enc-base64': { deps: ['crypto.core'] },
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* @license almond 0.3.0 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/almond for details
*/
......@@ -44,12 +44,6 @@ var requirejs, require, define;
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
//Convert baseName to array, and lop off the last part,
//so that . matches that "directory" and not name of the baseName's
//module. For instance, baseName of "one/two/three", maps to
//"one/two/three.js", but we want the directory, "one/two" for
//this normalization.
baseParts = baseParts.slice(0, baseParts.length - 1);
name = name.split('/');
lastIndex = name.length - 1;
......@@ -58,7 +52,11 @@ var requirejs, require, define;
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
}
name = baseParts.concat(name);
//Lop off the last part of baseParts, so that . matches the
//"directory" and not name of the baseName's module. For instance,
//baseName of "one/two/three", maps to "one/two/three.js", but we
//want the directory, "one/two" for this normalization.
name = baseParts.slice(0, baseParts.length - 1).concat(name);
//start trimDots
for (i = 0; i < name.length; i += 1) {
......@@ -408,6 +406,9 @@ var requirejs, require, define;
requirejs._defined = defined;
define = function (name, deps, callback) {
if (typeof name !== 'string') {
throw new Error('See almond README: incorrect module build, no module name');
}
//This module may not have dependencies
if (!deps.splice) {
......@@ -830,9 +831,9 @@ define('text',['module'], function (module) {
return text;
});
// Underscore.js 1.6.0
// Underscore.js 1.8.2
// http://underscorejs.org
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
......@@ -846,9 +847,6 @@ define('text',['module'], function (module) {
// Save the previous value of the `_` variable.
var previousUnderscore = root._;
// Establish the object that gets returned to break out of a loop iteration.
var breaker = {};
// Save bytes in the minified (but not gzipped) version:
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
......@@ -856,25 +854,19 @@ define('text',['module'], function (module) {
var
push = ArrayProto.push,
slice = ArrayProto.slice,
concat = ArrayProto.concat,
toString = ObjProto.toString,
hasOwnProperty = ObjProto.hasOwnProperty;
// All **ECMAScript 5** native function implementations that we hope to use
// are declared here.
var
nativeForEach = ArrayProto.forEach,
nativeMap = ArrayProto.map,
nativeReduce = ArrayProto.reduce,
nativeReduceRight = ArrayProto.reduceRight,
nativeFilter = ArrayProto.filter,
nativeEvery = ArrayProto.every,
nativeSome = ArrayProto.some,
nativeIndexOf = ArrayProto.indexOf,
nativeLastIndexOf = ArrayProto.lastIndexOf,
nativeIsArray = Array.isArray,
nativeKeys = Object.keys,
nativeBind = FuncProto.bind;
nativeBind = FuncProto.bind,
nativeCreate = Object.create;
// Naked function reference for surrogate-prototype-swapping.
var Ctor = function(){};
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
......@@ -885,8 +877,7 @@ define('text',['module'], function (module) {
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
// the browser, add `_` as a global object via a string identifier,
// for Closure Compiler "advanced" mode.
// the browser, add `_` as a global object.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
......@@ -897,161 +888,208 @@ define('text',['module'], function (module) {
}
// Current version.
_.VERSION = '1.6.0';
_.VERSION = '1.8.2';
// Internal function that returns an efficient (for current engines) version
// of the passed-in callback, to be repeatedly applied in other Underscore
// functions.
var optimizeCb = function(func, context, argCount) {
if (context === void 0) return func;
switch (argCount == null ? 3 : argCount) {
case 1: return function(value) {
return func.call(context, value);
};
case 2: return function(value, other) {
return func.call(context, value, other);
};
case 3: return function(value, index, collection) {
return func.call(context, value, index, collection);
};
case 4: return function(accumulator, value, index, collection) {
return func.call(context, accumulator, value, index, collection);
};
}
return function() {
return func.apply(context, arguments);
};
};
// A mostly-internal function to generate callbacks that can be applied
// to each element in a collection, returning the desired result — either
// identity, an arbitrary callback, a property matcher, or a property accessor.
var cb = function(value, context, argCount) {
if (value == null) return _.identity;
if (_.isFunction(value)) return optimizeCb(value, context, argCount);
if (_.isObject(value)) return _.matcher(value);
return _.property(value);
};
_.iteratee = function(value, context) {
return cb(value, context, Infinity);
};
// An internal function for creating assigner functions.
var createAssigner = function(keysFunc, undefinedOnly) {
return function(obj) {
var length = arguments.length;
if (length < 2 || obj == null) return obj;
for (var index = 1; index < length; index++) {
var source = arguments[index],
keys = keysFunc(source),
l = keys.length;
for (var i = 0; i < l; i++) {
var key = keys[i];
if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
}
}
return obj;
};
};
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (!_.isObject(prototype)) return {};
if (nativeCreate) return nativeCreate(prototype);
Ctor.prototype = prototype;
var result = new Ctor;
Ctor.prototype = null;
return result;
};
// Helper for collection methods to determine whether a collection
// should be iterated as an array or as an object
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
var isArrayLike = function(collection) {
var length = collection && collection.length;
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
};
// Collection Functions
// --------------------
// The cornerstone, an `each` implementation, aka `forEach`.
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
// Handles raw objects in addition to array-likes. Treats all
// sparse array-likes as if they were dense.
_.each = _.forEach = function(obj, iteratee, context) {
iteratee = optimizeCb(iteratee, context);
var i, length;
if (isArrayLike(obj)) {
for (i = 0, length = obj.length; i < length; i++) {
iteratee(obj[i], i, obj);
}
} else {
var keys = _.keys(obj);
for (var i = 0, length = keys.length; i < length; i++) {
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
for (i = 0, length = keys.length; i < length; i++) {
iteratee(obj[keys[i]], keys[i], obj);
}
}
return obj;
};
// Return the results of applying the iterator to each element.
// Delegates to **ECMAScript 5**'s native `map` if available.
_.map = _.collect = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
each(obj, function(value, index, list) {
results.push(iterator.call(context, value, index, list));
});
// Return the results of applying the iteratee to each element.
_.map = _.collect = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
results = Array(length);
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
results[index] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
var reduceError = 'Reduce of empty array with no initial value';
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduce && obj.reduce === nativeReduce) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
}
each(obj, function(value, index, list) {
if (!initial) {
memo = value;
initial = true;
} else {
memo = iterator.call(context, memo, value, index, list);
// Create a reducing function iterating left or right.
function createReduce(dir) {
// Optimized iterator function as using arguments.length
// in the main function will deoptimize the, see #1991.
function iterator(obj, iteratee, memo, keys, index, length) {
for (; index >= 0 && index < length; index += dir) {
var currentKey = keys ? keys[index] : index;
memo = iteratee(memo, obj[currentKey], currentKey, obj);
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
};
// The right-associative version of reduce, also known as `foldr`.
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
var initial = arguments.length > 2;
if (obj == null) obj = [];
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
if (context) iterator = _.bind(iterator, context);
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
}
var length = obj.length;
if (length !== +length) {
var keys = _.keys(obj);
length = keys.length;
}
each(obj, function(value, index, list) {
index = keys ? keys[--length] : --length;
if (!initial) {
memo = obj[index];
initial = true;
} else {
memo = iterator.call(context, memo, obj[index], index, list);
return function(obj, iteratee, memo, context) {
iteratee = optimizeCb(iteratee, context, 4);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length,
index = dir > 0 ? 0 : length - 1;
// Determine the initial value if none is provided.
if (arguments.length < 3) {
memo = obj[keys ? keys[index] : index];
index += dir;
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
return iterator(obj, iteratee, memo, keys, index, length);
};
}
// **Reduce** builds up a single result from a list of values, aka `inject`,
// or `foldl`.
_.reduce = _.foldl = _.inject = createReduce(1);
// The right-associative version of reduce, also known as `foldr`.
_.reduceRight = _.foldr = createReduce(-1);
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, predicate, context) {
var result;
any(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) {
result = value;
return true;
var key;
if (isArrayLike(obj)) {
key = _.findIndex(obj, predicate, context);
} else {
key = _.findKey(obj, predicate, context);
}
});
return result;
if (key !== void 0 && key !== -1) return obj[key];
};
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
_.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) results.push(value);
predicate = cb(predicate, context);
_.each(obj, function(value, index, list) {
if (predicate(value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) {
return !predicate.call(context, value, index, list);
}, context);
return _.filter(obj, _.negate(cb(predicate)), context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
_.every = _.all = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) {
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});
return !!result;
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (!predicate(obj[currentKey], currentKey, obj)) return false;
}
return true;
};
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
var any = _.some = _.any = function(obj, predicate, context) {
predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
_.some = _.any = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = !isArrayLike(obj) && _.keys(obj),
length = (keys || obj).length;
for (var index = 0; index < length; index++) {
var currentKey = keys ? keys[index] : index;
if (predicate(obj[currentKey], currentKey, obj)) return true;
}
return false;
};
// Determine if the array or object contains a given value (using `===`).
// Aliased as `include`.
_.contains = _.include = function(obj, target) {
if (obj == null) return false;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
return any(obj, function(value) {
return value === target;
});
// Aliased as `includes` and `include`.
_.contains = _.includes = _.include = function(obj, target, fromIndex) {
if (!isArrayLike(obj)) obj = _.values(obj);
return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0;
};
// Invoke a method (with arguments) on every item in a collection.
......@@ -1059,7 +1097,8 @@ define('text',['module'], function (module) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
return (isFunc ? method : value[method]).apply(value, args);
var func = isFunc ? method : value[method];
return func == null ? func : func.apply(value, args);
});
};
......@@ -1071,60 +1110,76 @@ define('text',['module'], function (module) {
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs) {
return _.filter(obj, _.matches(attrs));
return _.filter(obj, _.matcher(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.find(obj, _.matches(attrs));
return _.find(obj, _.matcher(attrs));
};
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
// Return the maximum element (or element-based computation).
_.max = function(obj, iteratee, context) {
var result = -Infinity, lastComputed = -Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value > result) {
result = value;
}
}
var result = -Infinity, lastComputed = -Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed > lastComputed) {
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj);
}
var result = Infinity, lastComputed = Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
if (computed < lastComputed) {
_.min = function(obj, iteratee, context) {
var result = Infinity, lastComputed = Infinity,
value, computed;
if (iteratee == null && obj != null) {
obj = isArrayLike(obj) ? obj : _.values(obj);
for (var i = 0, length = obj.length; i < length; i++) {
value = obj[i];
if (value < result) {
result = value;
}
}
} else {
iteratee = cb(iteratee, context);
_.each(obj, function(value, index, list) {
computed = iteratee(value, index, list);
if (computed < lastComputed || computed === Infinity && result === Infinity) {
result = value;
lastComputed = computed;
}
});
}
return result;
};
// Shuffle an array, using the modern version of the
// Shuffle a collection, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
var shuffled = [];
each(obj, function(value) {
rand = _.random(index++);
shuffled[index - 1] = shuffled[rand];
shuffled[rand] = value;
});
var set = isArrayLike(obj) ? obj : _.values(obj);
var length = set.length;
var shuffled = Array(length);
for (var index = 0, rand; index < length; index++) {
rand = _.random(0, index);
if (rand !== index) shuffled[index] = shuffled[rand];
shuffled[rand] = set[index];
}
return shuffled;
};
......@@ -1133,27 +1188,20 @@ define('text',['module'], function (module) {
// The internal `guard` argument allows it to work with `map`.
_.sample = function(obj, n, guard) {
if (n == null || guard) {
if (obj.length !== +obj.length) obj = _.values(obj);
if (!isArrayLike(obj)) obj = _.values(obj);
return obj[_.random(obj.length - 1)];
}
return _.shuffle(obj).slice(0, Math.max(0, n));
};
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
if (value == null) return _.identity;
if (_.isFunction(value)) return value;
return _.property(value);
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, iterator, context) {
iterator = lookupIterator(iterator);
// Sort the object's values by a criterion produced by an iteratee.
_.sortBy = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value: value,
index: index,
criteria: iterator.call(context, value, index, list)
criteria: iteratee(value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
......@@ -1168,12 +1216,12 @@ define('text',['module'], function (module) {
// An internal function used for aggregate "group by" operations.
var group = function(behavior) {
return function(obj, iterator, context) {
return function(obj, iteratee, context) {
var result = {};
iterator = lookupIterator(iterator);
each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj);
behavior(result, key, value);
iteratee = cb(iteratee, context);
_.each(obj, function(value, index) {
var key = iteratee(value, index, obj);
behavior(result, value, key);
});
return result;
};
......@@ -1181,48 +1229,46 @@ define('text',['module'], function (module) {
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = group(function(result, key, value) {
_.has(result, key) ? result[key].push(value) : result[key] = [value];
_.groupBy = group(function(result, value, key) {
if (_.has(result, key)) result[key].push(value); else result[key] = [value];
});
// Indexes the object's values by a criterion, similar to `groupBy`, but for
// when you know that your index values will be unique.
_.indexBy = group(function(result, key, value) {
_.indexBy = group(function(result, value, key) {
result[key] = value;
});
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
_.countBy = group(function(result, key) {
_.has(result, key) ? result[key]++ : result[key] = 1;
_.countBy = group(function(result, value, key) {
if (_.has(result, key)) result[key]++; else result[key] = 1;
});
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) {
iterator = lookupIterator(iterator);
var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >>> 1;
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
}
return low;
};
// Safely create a real, live array from anything iterable.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) return _.map(obj, _.identity);
if (isArrayLike(obj)) return _.map(obj, _.identity);
return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
if (obj == null) return 0;
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
};
// Split a collection into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(obj, predicate, context) {
predicate = cb(predicate, context);
var pass = [], fail = [];
_.each(obj, function(value, key, obj) {
(predicate(value, key, obj) ? pass : fail).push(value);
});
return [pass, fail];
};
// Array Functions
......@@ -1233,33 +1279,30 @@ define('text',['module'], function (module) {
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[0];
if (n < 0) return [];
return slice.call(array, 0, n);
if (n == null || guard) return array[0];
return _.initial(array, array.length - n);
};
// Returns everything but the last entry of the array. Especially useful on
// the arguments object. Passing **n** will return all the values in
// the array, excluding the last N. The **guard** check allows it to work with
// `_.map`.
// the array, excluding the last N.
_.initial = function(array, n, guard) {
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
};
// Get the last element of an array. Passing **n** will return the last N
// values in the array. The **guard** check allows it to work with `_.map`.
// values in the array.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n == null) || guard) return array[array.length - 1];
return slice.call(array, Math.max(array.length - n, 0));
if (n == null || guard) return array[array.length - 1];
return _.rest(array, Math.max(0, array.length - n));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
// Especially useful on the arguments object. Passing an **n** will return
// the rest N values in the array. The **guard**
// check allows it to work with `_.map`.
// the rest N values in the array.
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, (n == null) || guard ? 1 : n);
return slice.call(array, n == null || guard ? 1 : n);
};
// Trim out all falsy values from an array.
......@@ -1268,23 +1311,28 @@ define('text',['module'], function (module) {
};
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
if (shallow && _.every(input, _.isArray)) {
return concat.apply(output, input);
var flatten = function(input, shallow, strict, startIndex) {
var output = [], idx = 0;
for (var i = startIndex || 0, length = input && input.length; i < length; i++) {
var value = input[i];
if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
//flatten current level of array or arguments object
if (!shallow) value = flatten(value, shallow, strict);
var j = 0, len = value.length;
output.length += len;
while (j < len) {
output[idx++] = value[j++];
}
} else if (!strict) {
output[idx++] = value;
}
each(input, function(value) {
if (_.isArray(value) || _.isArguments(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
}
});
return output;
};
// Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
return flatten(array, shallow, false);
};
// Return a version of the array that does not contain the specified value(s).
......@@ -1292,79 +1340,93 @@ define('text',['module'], function (module) {
return _.difference(array, slice.call(arguments, 1));
};
// Split an array into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(array, predicate) {
var pass = [], fail = [];
each(array, function(elem) {
(predicate(elem) ? pass : fail).push(elem);
});
return [pass, fail];
};
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
_.uniq = _.unique = function(array, isSorted, iterator, context) {
if (_.isFunction(isSorted)) {
context = iterator;
iterator = isSorted;
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (array == null) return [];
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array;
var results = [];
if (iteratee != null) iteratee = cb(iteratee, context);
var result = [];
var seen = [];
each(initial, function(value, index) {
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
seen.push(value);
results.push(array[index]);
for (var i = 0, length = array.length; i < length; i++) {
var value = array[i],
computed = iteratee ? iteratee(value, i, array) : value;
if (isSorted) {
if (!i || seen !== computed) result.push(value);
seen = computed;
} else if (iteratee) {
if (!_.contains(seen, computed)) {
seen.push(computed);
result.push(value);
}
});
return results;
} else if (!_.contains(result, value)) {
result.push(value);
}
}
return result;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
return _.uniq(flatten(arguments, true, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays.
_.intersection = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.contains(other, item);
});
});
if (array == null) return [];
var result = [];
var argsLength = arguments.length;
for (var i = 0, length = array.length; i < length; i++) {
var item = array[i];
if (_.contains(result, item)) continue;
for (var j = 1; j < argsLength; j++) {
if (!_.contains(arguments[j], item)) break;
}
if (j === argsLength) result.push(item);
}
return result;
};
// Take the difference between one array and a number of other arrays.
// Only the elements present in just the first array will remain.
_.difference = function(array) {
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
return _.filter(array, function(value){ return !_.contains(rest, value); });
var rest = flatten(arguments, true, true, 1);
return _.filter(array, function(value){
return !_.contains(rest, value);
});
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(arguments, '' + i);
return _.unzip(arguments);
};
// Complement of _.zip. Unzip accepts an array of arrays and groups
// each array's elements on shared indices
_.unzip = function(array) {
var length = array && _.max(array, 'length').length || 0;
var result = Array(length);
for (var index = 0; index < length; index++) {
result[index] = _.pluck(array, index);
}
return results;
return result;
};
// Converts lists into objects. Pass either a single array of `[key, value]`
// pairs, or two parallel arrays of the same length -- one of keys, and one of
// the corresponding values.
_.object = function(list, values) {
if (list == null) return {};
var result = {};
for (var i = 0, length = list.length; i < length; i++) {
for (var i = 0, length = list && list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
......@@ -1374,40 +1436,68 @@ define('text',['module'], function (module) {
return result;
};
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
// we need this function. Return the position of the first occurrence of an
// item in an array, or -1 if the item is not included in the array.
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
// Return the position of the first occurrence of an item in an array,
// or -1 if the item is not included in the array.
// If the array is large and already in sort order, pass `true`
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
var i = 0, length = array.length;
if (isSorted) {
var i = 0, length = array && array.length;
if (typeof isSorted == 'number') {
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted;
} else if (isSorted && length) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (item !== item) {
return _.findIndex(slice.call(array, i), _.isNaN);
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item, from) {
if (array == null) return -1;
var hasIndex = from != null;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
var idx = array ? array.length : 0;
if (typeof from == 'number') {
idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1);
}
if (item !== item) {
return _.findLastIndex(slice.call(array, 0, idx), _.isNaN);
}
var i = (hasIndex ? from : array.length);
while (i--) if (array[i] === item) return i;
while (--idx >= 0) if (array[idx] === item) return idx;
return -1;
};
// Generator function to create the findIndex and findLastIndex functions
function createIndexFinder(dir) {
return function(array, predicate, context) {
predicate = cb(predicate, context);
var length = array != null && array.length;
var index = dir > 0 ? 0 : length - 1;
for (; index >= 0 && index < length; index += dir) {
if (predicate(array[index], index, array)) return index;
}
return -1;
};
}
// Returns the first index on an array-like that passes a predicate test
_.findIndex = createIndexFinder(1);
_.findLastIndex = createIndexFinder(-1);
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iteratee, context) {
iteratee = cb(iteratee, context, 1);
var value = iteratee(obj);
var low = 0, high = array.length;
while (low < high) {
var mid = Math.floor((low + high) / 2);
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
}
return low;
};
// Generate an integer Array containing an arithmetic progression. A port of
// the native Python `range()` function. See
// [the Python documentation](http://docs.python.org/library/functions.html#range).
......@@ -1416,15 +1506,13 @@ define('text',['module'], function (module) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
step = step || 1;
var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(length);
var range = Array(length);
while(idx < length) {
range[idx++] = start;
start += step;
for (var idx = 0; idx < length; idx++, start += step) {
range[idx] = start;
}
return range;
......@@ -1433,26 +1521,27 @@ define('text',['module'], function (module) {
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Determines whether to execute a function as a constructor
// or a normal function with the provided arguments
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
if (_.isObject(result)) return result;
return self;
};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
// available.
_.bind = function(func, context) {
var args, bound;
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
ctor.prototype = null;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
var args = slice.call(arguments, 2);
var bound = function() {
return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
};
return bound;
};
// Partially apply a function by creating a version that has had some of its
......@@ -1460,49 +1549,55 @@ define('text',['module'], function (module) {
// as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
var boundArgs = slice.call(arguments, 1);
return function() {
var position = 0;
var args = boundArgs.slice();
for (var i = 0, length = args.length; i < length; i++) {
if (args[i] === _) args[i] = arguments[position++];
var bound = function() {
var position = 0, length = boundArgs.length;
var args = Array(length);
for (var i = 0; i < length; i++) {
args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
}
while (position < arguments.length) args.push(arguments[position++]);
return func.apply(this, args);
return executeBound(func, bound, this, this, args);
};
return bound;
};
// Bind a number of an object's methods to that object. Remaining arguments
// are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
var i, length = arguments.length, key;
if (length <= 1) throw new Error('bindAll must be passed function names');
for (i = 1; i < length; i++) {
key = arguments[i];
obj[key] = _.bind(obj[key], obj);
}
return obj;
};
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
var memoize = function(key) {
var cache = memoize.cache;
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
return cache[address];
};
memoize.cache = {};
return memoize;
};
// Delays a function for the given number of milliseconds, and then calls
// it with the arguments supplied.
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(null, args); }, wait);
return setTimeout(function(){
return func.apply(null, args);
}, wait);
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = function(func) {
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
};
_.defer = _.partial(_.delay, _, 1);
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time. Normally, the throttled function will run
......@@ -1513,12 +1608,12 @@ define('text',['module'], function (module) {
var context, args, result;
var timeout = null;
var previous = 0;
options || (options = {});
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
};
return function() {
var now = _.now();
......@@ -1526,12 +1621,14 @@ define('text',['module'], function (module) {
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
......@@ -1548,13 +1645,14 @@ define('text',['module'], function (module) {
var later = function() {
var last = _.now() - timestamp;
if (last < wait) {
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
context = args = null;
if (!timeout) context = args = null;
}
}
};
......@@ -1564,9 +1662,7 @@ define('text',['module'], function (module) {
args = arguments;
timestamp = _.now();
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (!timeout) timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
......@@ -1576,19 +1672,6 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = function(func) {
var ran = false, memo;
return function() {
if (ran) return memo;
ran = true;
memo = func.apply(this, arguments);
func = null;
return memo;
};
};
// Returns the first function passed as an argument to the second,
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
......@@ -1596,20 +1679,27 @@ define('text',['module'], function (module) {
return _.partial(wrapper, func);
};
// Returns a negated version of the passed-in predicate.
_.negate = function(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
};
// Returns a function that is the composition of a list of functions, each
// consuming the return value of the function that follows.
_.compose = function() {
var funcs = arguments;
return function() {
var args = arguments;
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
return args[0];
var start = args.length - 1;
return function() {
var i = start;
var result = args[start].apply(this, arguments);
while (i--) result = args[i].call(this, result);
return result;
};
};
// Returns a function that will only be executed after being called N times.
// Returns a function that will only be executed on and after the Nth call.
_.after = function(times, func) {
return function() {
if (--times < 1) {
......@@ -1618,16 +1708,66 @@ define('text',['module'], function (module) {
};
};
// Returns a function that will only be executed up to (but not including) the Nth call.
_.before = function(times, func) {
var memo;
return function() {
if (--times > 0) {
memo = func.apply(this, arguments);
}
if (times <= 1) func = null;
return memo;
};
};
// Returns a function that will be executed at most one time, no matter how
// often you call it. Useful for lazy initialization.
_.once = _.partial(_.before, 2);
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
function collectNonEnumProps(obj, keys) {
var nonEnumIdx = nonEnumerableProps.length;
var constructor = obj.constructor;
var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
// Constructor is a special case.
var prop = 'constructor';
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
while (nonEnumIdx--) {
prop = nonEnumerableProps[nonEnumIdx];
if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
keys.push(prop);
}
}
}
// Retrieve the names of an object's own properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
// Retrieve all the property names of an object.
_.allKeys = function(obj) {
if (!_.isObject(obj)) return [];
var keys = [];
for (var key in obj) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
......@@ -1635,18 +1775,33 @@ define('text',['module'], function (module) {
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = new Array(length);
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
// Returns the results of applying the iteratee to each element of the object
// In contrast to _.map it returns an object
_.mapObject = function(obj, iteratee, context) {
iteratee = cb(iteratee, context);
var keys = _.keys(obj),
length = keys.length,
results = {},
currentKey;
for (var index = 0; index < length; index++) {
currentKey = keys[index];
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
}
return results;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var pairs = new Array(length);
var pairs = Array(length);
for (var i = 0; i < length; i++) {
pairs[i] = [keys[i], obj[keys[i]]];
}
......@@ -1674,48 +1829,57 @@ define('text',['module'], function (module) {
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
obj[prop] = source[prop];
}
_.extend = createAssigner(_.allKeys);
// Assigns a given object with all the own properties in the passed-in object(s)
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
_.extendOwn = _.assign = createAssigner(_.keys);
// Returns the first key on an object that passes a predicate test
_.findKey = function(obj, predicate, context) {
predicate = cb(predicate, context);
var keys = _.keys(obj), key;
for (var i = 0, length = keys.length; i < length; i++) {
key = keys[i];
if (predicate(obj[key], key, obj)) return key;
}
});
return obj;
};
// Return a copy of the object only containing the whitelisted properties.
_.pick = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
each(keys, function(key) {
if (key in obj) copy[key] = obj[key];
});
return copy;
_.pick = function(object, oiteratee, context) {
var result = {}, obj = object, iteratee, keys;
if (obj == null) return result;
if (_.isFunction(oiteratee)) {
keys = _.allKeys(obj);
iteratee = optimizeCb(oiteratee, context);
} else {
keys = flatten(arguments, false, false, 1);
iteratee = function(value, key, obj) { return key in obj; };
obj = Object(obj);
}
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = obj[key];
if (iteratee(value, key, obj)) result[key] = value;
}
return result;
};
// Return a copy of the object without the blacklisted properties.
_.omit = function(obj) {
var copy = {};
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
for (var key in obj) {
if (!_.contains(keys, key)) copy[key] = obj[key];
_.omit = function(obj, iteratee, context) {
if (_.isFunction(iteratee)) {
iteratee = _.negate(iteratee);
} else {
var keys = _.map(flatten(arguments, false, false, 1), String);
iteratee = function(value, key) {
return !_.contains(keys, key);
};
}
return copy;
return _.pick(obj, iteratee, context);
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
if (source) {
for (var prop in source) {
if (obj[prop] === void 0) obj[prop] = source[prop];
}
}
});
return obj;
};
_.defaults = createAssigner(_.allKeys, true);
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
......@@ -1731,11 +1895,24 @@ define('text',['module'], function (module) {
return obj;
};
// Returns whether an object has a given set of `key:value` pairs.
_.isMatch = function(object, attrs) {
var keys = _.keys(attrs), length = keys.length;
if (object == null) return !length;
var obj = Object(object);
for (var i = 0; i < length; i++) {
var key = keys[i];
if (attrs[key] !== obj[key] || !(key in obj)) return false;
}
return true;
};
// Internal recursive comparison function for `isEqual`.
var eq = function(a, b, aStack, bStack) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if (a === b) return a !== 0 || 1 / a == 1 / b;
if (a === b) return a !== 0 || 1 / a === 1 / b;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
......@@ -1743,98 +1920,98 @@ define('text',['module'], function (module) {
if (b instanceof _) b = b._wrapped;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
if (className !== toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
case '[object RegExp]':
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(b);
return '' + a === '' + b;
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return +a == +b;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
return +a === +b;
}
var areArrays = className === '[object Array]';
if (!areArrays) {
if (typeof a != 'object' || typeof b != 'object') return false;
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
_.isFunction(bCtor) && bCtor instanceof bCtor)
&& ('constructor' in a && 'constructor' in b)) {
return false;
}
}
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
// Initializing stack of traversed objects.
// It's done here since we only need them for objects and arrays comparison.
aStack = aStack || [];
bStack = bStack || [];
var length = aStack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (aStack[length] == a) return bStack[length] == b;
}
// Objects with different constructors are not equivalent, but `Object`s
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
_.isFunction(bCtor) && (bCtor instanceof bCtor))
&& ('constructor' in a && 'constructor' in b)) {
return false;
if (aStack[length] === a) return bStack[length] === b;
}
// Add the first object to the stack of traversed objects.
aStack.push(a);
bStack.push(b);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
if (areArrays) {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
length = a.length;
if (length !== b.length) return false;
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
}
while (length--) {
if (!eq(a[length], b[length], aStack, bStack)) return false;
}
} else {
// Deep compare objects.
for (var key in a) {
if (_.has(a, key)) {
// Count the expected number of properties.
size++;
// Deep compare each member.
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
}
}
// Ensure that both objects contain the same number of properties.
if (result) {
for (key in b) {
if (_.has(b, key) && !(size--)) break;
}
result = !size;
var keys = _.keys(a), key;
length = keys.length;
// Ensure that both objects contain the same number of properties before comparing deep equality.
if (_.keys(b).length !== length) return false;
while (length--) {
// Deep compare each member
key = keys[length];
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return result;
return true;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(a, b) {
return eq(a, b, [], []);
return eq(a, b);
};
// Is a given array, string, or object empty?
// An "empty" object has no enumerable own-properties.
_.isEmpty = function(obj) {
if (obj == null) return true;
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
for (var key in obj) if (_.has(obj, key)) return false;
return true;
if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
return _.keys(obj).length === 0;
};
// Is a given value a DOM element?
......@@ -1845,33 +2022,35 @@ define('text',['module'], function (module) {
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
return toString.call(obj) === '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
_.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
return toString.call(obj) === '[object ' + name + ']';
};
});
// Define a fallback version of the method in browsers (ahem, IE), where
// Define a fallback version of the method in browsers (ahem, IE < 9), where
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
return _.has(obj, 'callee');
};
}
// Optimize `isFunction` if appropriate.
if (typeof (/./) !== 'function') {
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
// IE 11 (#1621), and in Safari 8 (#1929).
if (typeof /./ != 'function' && typeof Int8Array != 'object') {
_.isFunction = function(obj) {
return typeof obj === 'function';
return typeof obj == 'function' || false;
};
}
......@@ -1882,12 +2061,12 @@ define('text',['module'], function (module) {
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(obj) {
return _.isNumber(obj) && obj != +obj;
return _.isNumber(obj) && obj !== +obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
};
// Is a given value equal to null?
......@@ -1903,7 +2082,7 @@ define('text',['module'], function (module) {
// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
return obj != null && hasOwnProperty.call(obj, key);
};
// Utility Functions
......@@ -1916,39 +2095,47 @@ define('text',['module'], function (module) {
return this;
};
// Keep the identity function around for default iterators.
// Keep the identity function around for default iteratees.
_.identity = function(value) {
return value;
};
// Predicate-generating functions. Often useful outside of Underscore.
_.constant = function(value) {
return function () {
return function() {
return value;
};
};
_.noop = function(){};
_.property = function(key) {
return function(obj) {
return obj == null ? void 0 : obj[key];
};
};
// Generates a function for a given object that returns a given property.
_.propertyOf = function(obj) {
return obj == null ? function(){} : function(key) {
return obj[key];
};
};
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
_.matches = function(attrs) {
// Returns a predicate for checking whether an object has a given set of
// `key:value` pairs.
_.matcher = _.matches = function(attrs) {
attrs = _.extendOwn({}, attrs);
return function(obj) {
if (obj === attrs) return true; //avoid comparing an object to itself.
for (var key in attrs) {
if (attrs[key] !== obj[key])
return false;
}
return true;
}
return _.isMatch(obj, attrs);
};
};
// Run a function **n** times.
_.times = function(n, iterator, context) {
_.times = function(n, iteratee, context) {
var accum = Array(Math.max(0, n));
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
iteratee = optimizeCb(iteratee, context, 1);
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
return accum;
};
......@@ -1962,56 +2149,48 @@ define('text',['module'], function (module) {
};
// A (possibly faster) way to get the current timestamp as an integer.
_.now = Date.now || function() { return new Date().getTime(); };
_.now = Date.now || function() {
return new Date().getTime();
};
// List of HTML entities for escaping.
var entityMap = {
escape: {
var escapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;'
}
};
entityMap.unescape = _.invert(entityMap.escape);
// Regexes containing the keys and values listed immediately above.
var entityRegexes = {
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
"'": '&#x27;',
'`': '&#x60;'
};
var unescapeMap = _.invert(escapeMap);
// Functions for escaping and unescaping strings to/from HTML interpolation.
_.each(['escape', 'unescape'], function(method) {
_[method] = function(string) {
if (string == null) return '';
return ('' + string).replace(entityRegexes[method], function(match) {
return entityMap[method][match];
});
var createEscaper = function(map) {
var escaper = function(match) {
return map[match];
};
});
// Regexes for identifying a key that needs to be escaped
var source = '(?:' + _.keys(map).join('|') + ')';
var testRegexp = RegExp(source);
var replaceRegexp = RegExp(source, 'g');
return function(string) {
string = string == null ? '' : '' + string;
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
};
};
_.escape = createEscaper(escapeMap);
_.unescape = createEscaper(unescapeMap);
// If the value of the named `property` is a function then invoke it with the
// `object` as context; otherwise, return it.
_.result = function(object, property) {
if (object == null) return void 0;
var value = object[property];
_.result = function(object, property, fallback) {
var value = object == null ? void 0 : object[property];
if (value === void 0) {
value = fallback;
}
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result.call(this, func.apply(_, args));
};
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
......@@ -2040,22 +2219,26 @@ define('text',['module'], function (module) {
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
// NB: `oldSettings` only exists for backwards compatibility.
_.template = function(text, settings, oldSettings) {
if (!settings && oldSettings) settings = oldSettings;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
var matcher = RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
......@@ -2065,19 +2248,18 @@ define('text',['module'], function (module) {
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
source += text.slice(index, offset).replace(escaper, escapeChar);
index = offset + match.length;
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
} else if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
// Adobe VMs need the match returned to produce the correct offest.
return match;
});
source += "';\n";
......@@ -2087,29 +2269,31 @@ define('text',['module'], function (module) {
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
source + 'return __p;\n';
try {
render = new Function(settings.variable || 'obj', '_', source);
var render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
// Provide the compiled source as a convenience for precompilation.
var argument = settings.variable || 'obj';
template.source = 'function(' + argument + '){\n' + source + '}';
return template;
};
// Add a "chain" function, which will delegate to the wrapper.
// Add a "chain" function. Start chaining a wrapped Underscore object.
_.chain = function(obj) {
return _(obj).chain();
var instance = _(obj);
instance._chain = true;
return instance;
};
// OOP
......@@ -2119,46 +2303,56 @@ define('text',['module'], function (module) {
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var result = function(obj) {
return this._chain ? _(obj).chain() : obj;
var result = function(instance, obj) {
return instance._chain ? _(obj).chain() : obj;
};
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
_.each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
push.apply(args, arguments);
return result(this, func.apply(_, args));
};
});
};
// Add all of the Underscore functions to the wrapper object.
_.mixin(_);
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
_.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
var obj = this._wrapped;
method.apply(obj, arguments);
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
return result.call(this, obj);
if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
return result(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
_.each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
return result.call(this, method.apply(this._wrapped, arguments));
return result(this, method.apply(this._wrapped, arguments));
};
});
_.extend(_.prototype, {
// Start chaining a wrapped Underscore object.
chain: function() {
this._chain = true;
return this;
},
// Extracts the result from a wrapped and chained object.
value: function() {
_.prototype.value = function() {
return this._wrapped;
}
};
});
// Provide unwrapping proxy for some methods used in engine operations
// such as arithmetic and JSON stringification.
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
_.prototype.toString = function() {
return '' + this._wrapped;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
......@@ -2172,7 +2366,7 @@ define('text',['module'], function (module) {
return _;
});
}
}).call(this);
}.call(this));
// RequireJS UnderscoreJS template plugin
// http://github.com/jfparadis/requirejs-tpl
......@@ -2697,7 +2891,7 @@ var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments
with(obj||{}){
__p+='<form id="converse-login" method="post">\n <label>'+
((__t=(label_username))==null?'':__t)+
'</label>\n <input type="username" name="jid" placeholder="user@server">\n <label>'+
'</label>\n <input type="email" name="jid" placeholder="user@server">\n <label>'+
((__t=(label_password))==null?'':__t)+
'</label>\n <input type="password" name="password" placeholder="password">\n <input class="submit" type="submit" value="'+
((__t=(label_login))==null?'':__t)+
......@@ -3026,7 +3220,9 @@ __p+='<form class="add-chatroom" action="" method="post">\n <label>'+
((__t=(label_nickname))==null?'':__t)+
'</label>\n <input type="text" name="nick" class="new-chatroom-nick"\n placeholder="'+
((__t=(label_nickname))==null?'':__t)+
'"/>\n <label>'+
'"/>\n <label'+
((__t=(server_label_global_attr))==null?'':__t)+
'>'+
((__t=(label_server))==null?'':__t)+
'</label>\n <input type="'+
((__t=(server_input_type))==null?'':__t)+
......@@ -3072,9 +3268,13 @@ __p+='<a class="open-chat" title="Name: '+
((__t=(desc_status))==null?'':__t)+
'"></span>'+
((__t=(fullname))==null?'':__t)+
'</a>\n<a class="remove-xmpp-contact icon-remove" title="'+
'</a>\n';
if (allow_contact_removal) {
__p+='\n<a class="remove-xmpp-contact icon-remove" title="'+
((__t=(desc_remove))==null?'':__t)+
'" href="#"></a>\n';
}
__p+='\n';
}
return __p;
}; });
......@@ -24276,19 +24476,6 @@ define("converse-dependencies", [
return this;
};
var playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
var converse = {
plugins: {},
templates: templates,
......@@ -24395,6 +24582,7 @@ define("converse-dependencies", [
// Default configuration values
// ----------------------------
this.default_settings = {
allow_contact_removal: true,
allow_contact_requests: true,
allow_dragresize: true,
allow_logout: true,
......@@ -24509,6 +24697,19 @@ define("converse-dependencies", [
// Module-level functions
// ----------------------
this.playNotification = function () {
var audio;
if (converse.play_sounds && typeof Audio !== "undefined"){
audio = new Audio("sounds/msg_received.ogg");
if (audio.canPlayType('/audio/ogg')) {
audio.play();
} else {
audio = new Audio("/sounds/msg_received.mp3");
audio.play();
}
}
};
this.giveFeedback = function (message, klass) {
$('.conn-feedback').each(function (idx, el) {
var $el = $(el);
......@@ -24581,7 +24782,6 @@ define("converse-dependencies", [
this.reconnect = function () {
converse.giveFeedback(__('Reconnecting'), 'error');
converse.emit('reconnect');
if (!converse.prebind) {
this.connection.connect(
this.connection.jid,
......@@ -24593,6 +24793,10 @@ define("converse-dependencies", [
this.connection.hold,
this.connection.route
);
} else if (converse.prebind_url) {
this.clearSession();
this._tearDown();
this.startNewBOSHSession();
}
};
......@@ -24629,6 +24833,7 @@ define("converse-dependencies", [
converse.giveFeedback(__('Authentication Failed'), 'error');
converse.connection.disconnect(__('Authentication Failed'));
} else if (status === Strophe.Status.DISCONNECTING) {
// FIXME: what about prebind?
if (!converse.connection.connected) {
converse.renderLoginPanel();
}
......@@ -24704,8 +24909,8 @@ define("converse-dependencies", [
this.clearSession = function () {
this.roster.browserStorage._clear();
this.session.browserStorage._clear();
// XXX: this should perhaps go into the beforeunload handler
converse.chatboxes.get('controlbox').save({'connected': false});
var controlbox = converse.chatboxes.get('controlbox');
controlbox.save({'connected': false});
};
this.setSession = function () {
......@@ -25910,6 +26115,7 @@ define("converse-dependencies", [
this.$el.html(
converse.templates.room_panel({
'server_input_type': converse.hide_muc_server && 'hidden' || 'text',
'server_label_global_attr': converse.hide_muc_server && ' hidden' || '',
'label_room_name': __('Room name'),
'label_nickname': __('Nickname'),
'label_server': __('Server'),
......@@ -27122,7 +27328,7 @@ define("converse-dependencies", [
}
this.model.createMessage($message);
if (!delayed && sender !== this.model.get('nick') && (new RegExp("\\b"+this.model.get('nick')+"\\b")).test(body)) {
playNotification();
converse.playNotification();
}
if (sender !== this.model.get('nick')) {
// We only emit an event if it's not our own message
......@@ -27292,7 +27498,7 @@ define("converse-dependencies", [
return true; // We already have this message stored.
}
if (!this.isOnlyChatStateNotification($message) && from !== converse.bare_jid) {
playNotification();
converse.playNotification();
}
chatbox.receiveMessage($message);
converse.roster.addResource(contact_jid, resource);
......@@ -27723,7 +27929,8 @@ define("converse-dependencies", [
_.extend(item.toJSON(), {
'desc_status': STATUSES[chat_status||'offline'],
'desc_chat': __('Click to chat with this contact'),
'desc_remove': __('Click to remove this contact')
'desc_remove': __('Click to remove this contact'),
'allow_contact_removal': converse.allow_contact_removal
})
));
}
......@@ -27737,6 +27944,7 @@ define("converse-dependencies", [
removeContact: function (ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
if (!converse.allow_contact_removal) { return; }
var result = confirm(__("Are you sure you want to remove this contact?"));
if (result === true) {
var bare_jid = this.model.get('jid');
......@@ -29437,20 +29645,32 @@ define("converse-dependencies", [
}
};
this.startNewBOSHSession = function () {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: response.rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
};
this.initConnection = function () {
var rid, sid, jid;
if (this.connection && this.connection.connected) {
this.setUpXMLLogging();
this.onConnected();
} else {
// XXX: it's not yet clear what the order of preference should
// be between RID and SID received via the initialize method or
// those received from sessionStorage.
//
// What do you we if we receive values from both avenues?
//
// Also, what do we do when the keepalive session values are
// expired? Do we try to fall back?
if (!this.bosh_service_url && ! this.websocket_url) {
throw("Error: you must supply a value for the bosh_service_url or websocket_url");
}
......@@ -29476,33 +29696,25 @@ define("converse-dependencies", [
rid = this.session.get('rid');
sid = this.session.get('sid');
jid = this.session.get('jid');
if (rid && jid && sid) {
// The RID needs to be increased with each request.
this.session.save({rid: rid});
if (this.prebind) {
if (!this.jid) {
throw("When using 'keepalive' with 'prebind, you must supply the JID of the current user.");
}
if (rid && sid && jid && Strophe.getBareJidFromJid(jid) === Strophe.getBareJidFromJid(this.jid)) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
} else if (this.prebind) {
if (this.prebind_url) {
$.ajax({
url: this.prebind_url,
type: 'GET',
success: function (response) {
this.session.save({rid: rid});
this.connection.attach(
response.jid,
response.sid,
response.rid,
this.onConnect
);
}.bind(this),
error: function (response) {
delete this.connection;
this.emit('noResumeableSession');
}.bind(this)
});
} else if (this.prebind_url) {
this.startNewBOSHSession();
} else {
delete this.connection;
this.emit('noResumeableSession');
}
} else {
// Non-prebind case.
if (rid && sid && jid) {
this.session.save({rid: rid}); // The RID needs to be increased with each request.
this.connection.attach(jid, sid, rid, this.onConnect);
}
}
}
}
......@@ -29582,6 +29794,14 @@ define("converse-dependencies", [
'initialize': function (settings, callback) {
converse.initialize(settings, callback);
},
'disconnect': function () {
converse.connection.disconnect();
},
'account': {
'logout': function () {
converse.logOut();
},
},
'settings': {
'get': function (key) {
if (_.contains(Object.keys(converse.default_settings), key)) {
......@@ -29887,7 +30107,6 @@ require.config({
// define module dependencies for modules not using define
shim: {
'underscore': { exports: '_' },
'crypto.aes': { deps: ['crypto.cipher-core'] },
'crypto.cipher-core': { deps: ['crypto.enc-base64', 'crypto.evpkdf'] },
'crypto.enc-base64': { deps: ['crypto.core'] },
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -483,7 +483,7 @@ var __t, __p = '', __e = _.escape;
with (obj) {
__p += '<form id="converse-login" method="post">\n <label>' +
((__t = (label_username)) == null ? '' : __t) +
'</label>\n <input type="username" name="jid" placeholder="user@server">\n <label>' +
'</label>\n <input type="email" name="jid" placeholder="user@server">\n <label>' +
((__t = (label_password)) == null ? '' : __t) +
'</label>\n <input type="password" name="password" placeholder="password">\n <input class="submit" type="submit" value="' +
((__t = (label_login)) == null ? '' : __t) +
......@@ -829,7 +829,9 @@ __p += '<form class="add-chatroom" action="" method="post">\n <label>' +
((__t = (label_nickname)) == null ? '' : __t) +
'</label>\n <input type="text" name="nick" class="new-chatroom-nick"\n placeholder="' +
((__t = (label_nickname)) == null ? '' : __t) +
'"/>\n <label>' +
'"/>\n <label' +
((__t = (server_label_global_attr)) == null ? '' : __t) +
'>' +
((__t = (label_server)) == null ? '' : __t) +
'</label>\n <input type="' +
((__t = (server_input_type)) == null ? '' : __t) +
......@@ -863,7 +865,8 @@ return __p
this["templates"]["roster_item"] = function(obj) {
obj || (obj = {});
var __t, __p = '', __e = _.escape;
var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
function print() { __p += __j.call(arguments, '') }
with (obj) {
__p += '<a class="open-chat" title="Name: ' +
((__t = (fullname)) == null ? '' : __t) +
......@@ -877,9 +880,13 @@ __p += '<a class="open-chat" title="Name: ' +
((__t = (desc_status)) == null ? '' : __t) +
'"></span>' +
((__t = (fullname)) == null ? '' : __t) +
'</a>\n<a class="remove-xmpp-contact icon-remove" title="' +
'</a>\n';
if (allow_contact_removal) { ;
__p += '\n<a class="remove-xmpp-contact icon-remove" title="' +
((__t = (desc_remove)) == null ? '' : __t) +
'" href="#"></a>\n';
} ;
__p += '\n';
}
return __p
......
......@@ -9,4 +9,4 @@
*
* Copyright (c) 2012-2014, JC Brand <jc@opkode.com>
* Licensed under the Mozilla Public License
*/@font-face{font-family:Converse-js;src:url(../fonticons/fonts/icomoon.eot?-mnoxh0);src:url(../fonticons/fonts/icomoon.eot?#iefix-mnoxh0) format("embedded-opentype"),url(../fonticons/fonts/icomoon.woff?-mnoxh0) format("woff"),url(../fonticons/fonts/icomoon.ttf?-mnoxh0) format("truetype"),url(../fonticons/fonts/icomoon.svg?-mnoxh0#icomoon) format("svg");font-weight:400;font-style:normal}.icon-conversejs{font-family:Converse-js;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-conversejs:before{content:"\e600"}#conversejs{color:#6C4C44;font-size:14px;bottom:0;direction:ltr;height:35px;left:0;position:fixed;right:0;z-index:30;display:block;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs ::selection{background-color:#E3C9C1}#conversejs *,#conversejs :after,#conversejs :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@media screen and (max-width:480px){#conversejs{margin:5px 10px}}#conversejs a,#conversejs a:visited{text-decoration:none;color:#436F64;text-shadow:none}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs canvas,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs label,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs button,#conversejs input[type=button],#conversejs input[type=password],#conversejs input[type=submit],#conversejs input[type=text],#conversejs textarea{font-size:14px;padding:.25em;min-height:0}#conversejs strong{font-weight:700}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0}#conversejs [data-icon]:before{content:attr(data-icon);font-family:Converse-js;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs [class*=" icon-"],#conversejs [class^=icon-]{font-family:Converse-js;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs .icon-address-book:before{content:"\270f"}#conversejs .icon-angry:before{content:"\e03f"}#conversejs .icon-attachment:before{content:"\e032"}#conversejs .icon-away:before{content:"\25fb"}#conversejs .icon-blocked:before{content:"\2718"}#conversejs .icon-bold:before{content:"\e04d"}#conversejs .icon-bubbles-2:before{content:"\e016"}#conversejs .icon-bubbles-3:before{content:"\e017"}#conversejs .icon-bubbles:before{content:"\e015"}#conversejs .icon-camera-2:before{content:"\2616"}#conversejs .icon-camera:before{content:"\e003"}#conversejs .icon-cancel-circle:before{content:"\e058"}#conversejs .icon-checkbox-checked:before{content:"\2611"}#conversejs .icon-checkbox-partial:before{content:"\2b28"}#conversejs .icon-checkbox-unchecked:before{content:"\2b27"}#conversejs .icon-checkmark:before{content:"\2713"}#conversejs .icon-close:before{content:"\2715"}#conversejs .icon-closed:before{content:"\25ba"}#conversejs .icon-cog:before{content:"\e02f"}#conversejs .icon-cogs:before{content:"\e022"}#conversejs .icon-confused:before{content:"\2368"}#conversejs .icon-cool:before{content:"\e040"}#conversejs .icon-dnd:before{content:"\e004"}#conversejs .icon-envelop:before{content:"\2709"}#conversejs .icon-evil:before{content:"\261f"}#conversejs .icon-eye-blocked:before{content:"\e031"}#conversejs .icon-eye:before{content:"\e030"}#conversejs .icon-globe:before{content:"\e033"}#conversejs .icon-grin:before{content:"\e041"}#conversejs .icon-happy:before{content:"\263b"}#conversejs .icon-headphones:before{content:"\266c"}#conversejs .icon-heart:before{content:"\2764"}#conversejs .icon-hide-users:before{content:"\e01c"}#conversejs .icon-home:before{content:"\e000"}#conversejs .icon-image:before{content:"\2b14"}#conversejs .icon-info:before{content:"\2360"}#conversejs .icon-italic:before{content:"\e04f"}#conversejs .icon-key-2:before{content:"\e029"}#conversejs .icon-key:before{content:"\e028"}#conversejs .icon-lock-2:before{content:"\e027"}#conversejs .icon-lock:before{content:"\e026"}#conversejs .icon-logout:before{content:"\e601"}#conversejs .icon-minus:before{content:"\e05a"}#conversejs .icon-music:before{content:"\266b"}#conversejs .icon-new-tab:before{content:"\e053"}#conversejs .icon-newspaper:before{content:"\e001"}#conversejs .icon-notebook:before{content:"\2710"}#conversejs .icon-notification:before{content:"\e01f"}#conversejs .icon-online:before{content:"\25fc"}#conversejs .icon-opened:before{content:"\25bc"}#conversejs .icon-pencil:before{content:"\270e"}#conversejs .icon-phone-hang-up:before{content:"\260e"}#conversejs .icon-phone:before{content:"\260f"}#conversejs .icon-play:before{content:"\25d9"}#conversejs .icon-plus:before{content:"\271a"}#conversejs .icon-pushpin:before{content:"\e012"}#conversejs .icon-quotes-left:before{content:"\e01d"}#conversejs .icon-radio-checked:before{content:"\2b26"}#conversejs .icon-radio-unchecked:before{content:"\2b25"}#conversejs .icon-remove:before{content:"\e02d"}#conversejs .icon-room-info:before{content:"\e059"}#conversejs .icon-sad:before{content:"\2639"}#conversejs .icon-search:before{content:"\e021"}#conversejs .icon-shocked:before{content:"\2364"}#conversejs .icon-show-users:before{content:"\e01e"}#conversejs .icon-smiley:before{content:"\263a"}#conversejs .icon-spell-check:before{content:"\e045"}#conversejs .icon-spinner:before{content:"\231b"}#conversejs .icon-strikethrough:before{content:"\e050"}#conversejs .icon-thumbs-up:before{content:"\261d"}#conversejs .icon-tongue:before{content:"\e038"}#conversejs .icon-underline:before{content:"\e04e"}#conversejs .icon-unlocked:before{content:"\e025"}#conversejs .icon-user:before{content:"\e01a"}#conversejs .icon-users:before{content:"\e01b"}#conversejs .icon-volume-decrease:before{content:"\e04b"}#conversejs .icon-volume-high:before{content:"\e046"}#conversejs .icon-volume-increase:before{content:"\e04c"}#conversejs .icon-volume-low:before{content:"\e048"}#conversejs .icon-volume-medium:before{content:"\e047"}#conversejs .icon-volume-mute-2:before{content:"\e04a"}#conversejs .icon-volume-mute:before{content:"\e049"}#conversejs .icon-warning:before{content:"\26a0"}#conversejs .icon-wink:before{content:"\e03a"}#conversejs .icon-wondering:before{content:"\2369"}#conversejs .icon-wrench:before{content:"\e024"}#conversejs .icon-offline:before,#conversejs .icon-unavailable:before,#conversejs .icon-xa:before{content:"\e002"}#conversejs .icon-youtube:before{content:"\e055"}#conversejs .icon-zoom-in:before{content:"\e02b"}#conversejs .icon-zoom-out:before{content:"\e02a"}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#conversejs .emoticon{font-size:14px}#conversejs .left{float:left}#conversejs .right{float:right}#conversejs .hidden{display:none}#conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);-moz-transform:rotate(359deg);-ms-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}@-moz-keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);-moz-transform:rotate(359deg);-ms-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);-moz-transform:rotate(359deg);-ms-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}#conversejs .spinner:before{font-size:24px;font-family:Converse-js!important;content:"\231b"}#conversejs .spinner{-webkit-animation:spin 2s infinite,linear;-moz-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;display:block;text-align:center;margin:5px}#conversejs .centered{text-align:center;display:block;margin:5em auto}#conversejs .hor_centered{text-align:center;display:block;margin:0 auto}#conversejs #minimized-chats,#conversejs .toggle-controlbox{border-top-left-radius:4px;border-top-right-radius:4px;float:right;margin:0 7px;font-weight:700}#conversejs .toggle-controlbox{background-color:#436F64;color:#0a0a0a;height:100%;padding:10px 8px 0}#conversejs .toggle-controlbox span{color:#fff}#conversejs .button-group,#conversejs .input-button-group{display:table}#conversejs .button-group{width:100%}#conversejs .input-button-group button,#conversejs .input-button-group input{display:table-cell}#conversejs #minimized-chats{color:#fff;display:none;height:100%;padding:0;width:130px}#conversejs #minimized-chats #toggle-minimized-chats{border-top-left-radius:4px;border-top-right-radius:4px;background-color:ivory;position:relative;padding:10px 0 0;display:block;width:100%;height:100%;text-align:center}#conversejs #minimized-chats .chat-head-message-count,#conversejs #minimized-chats .unread-message-count{font-weight:700;background-color:#f6f6f6;background-image:-webkit-linear-gradient(#f6f6f6 5%,gray 100%);background-image:linear-gradient(#f6f6f6 5%,gray 100%);border:1px solid;text-shadow:1px 1px 0 #FAFAFA;color:#681F2C;border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}#conversejs #minimized-chats .box-flyout{position:absolute;display:block;height:auto;bottom:35px;margin-left:0}#conversejs #minimized-chats .box-flyout .chat-head{font-size:100%;border-radius:4px;padding:3px 0 0 5px;margin:0 0 1px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);height:24px;width:130px}#conversejs .chat-body{background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;height:289px;height:-webkit-calc(100% - 44px);height:calc(100% - 44px);border-top:0}#conversejs .chat-body p{font-size:14px;color:#6C4C44;padding:5px;margin:0}#conversejs .tt-highlight{background-color:#00230F}#conversejs .tt-suggestion p{color:#fff;text-shadow:rgba(0,0,0,.51)0 -1px 0;cursor:pointer;font-size:11px}#conversejs .tt-suggestion p:hover{background-color:#00230F}#conversejs .tt-suggestion p:hover .tt-highlight{background:#27774A}#conversejs .tt-dropdown-menu{margin:0 1px;width:96px;max-height:250px;overflow-x:hidden;overflow-y:auto;text-overflow:ellipsis;background:#27774A;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .chat-blink{background-color:#176679;border-right:1px solid #176679;border-left:1px solid #176679}#conversejs .chat-content{position:relative;padding:8px;font-size:13px;color:#6C4C44;overflow-y:auto;border:0;background-color:#fff;line-height:1.3em;height:206px;height:calc(100% - 84px)}#conversejs .chat-error{color:#681F2C;font-weight:700}#conversejs .chat-error,#conversejs .chat-info,#conversejs .chat-message{padding:2px 0}#conversejs .chat-message-me,#conversejs .chat-message-room,#conversejs .chat-message-them{font-weight:700;white-space:nowrap;max-width:100px;text-overflow:ellipsis;overflow:hidden;display:inline-block;float:left;padding-right:3px}#conversejs .chat-message-content{word-wrap:break-word}#conversejs .chat-message-room,#conversejs .chat-message-them{color:#4B7003}#conversejs .chat-message-me{color:#436F64}#conversejs .chat-date,#conversejs .chat-event,#conversejs .chat-info{color:gray}#conversejs li.chat-info{padding-left:10px}#conversejs .chat-date{display:inline-block;padding-top:10px}#conversejs .not-implemented{margin-top:3em;margin-left:.3em;color:gray}#conversejs .mentioned{font-weight:700}#conversejs .delayed .chat-message-them{color:#FB5D50}#conversejs .delayed .chat-message-me{color:#7EABBB}#conversejs .error{color:red}#conversejs input.error{border:1px solid red}#conversejs #converse-register .form-errors{color:red;display:none}#conversejs #converse-register .provider-title{font-size:115%}#conversejs #converse-register .provider-score{width:178px;margin-bottom:8px}#conversejs #converse-register .form-help .url{font-weight:700;color:#436F64}#conversejs .reg-feedback{font-size:85%}#conversejs #converse-login .conn-feedback,#conversejs .reg-feedback{display:block;text-align:center;width:100%}#conversejs .chat-message-error{color:#76797C;font-size:90%;font-weight:400}#conversejs .chat-title,#conversejs a.restore-chat{padding:1px 0 1px 5px;color:#fff;font-weight:700;line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:rgba(0,0,0,.51)0 -1px 0}#conversejs a.restore-chat:visited{color:#fff}#conversejs .chat-title a{color:#fff;width:100%;text-overflow:ellipsis;white-space:nowrap}#conversejs .chat-head-chatbox,#conversejs .chat-head-chatroom{height:44px;position:relative;padding:5px}#conversejs .chat-head-chatroom{background-color:#0F592F}#conversejs .chat-head-chatbox{background-color:#436F64}#conversejs .chatroom-topic,#conversejs .user-custom-message{color:#fff;font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;padding:1px 0 1px 5px}#conversejs .activated{display:block!important}#conversejs a.subscribe-to-user{padding-left:2em;font-weight:700}#conversejs dl.add-converse-contact{margin:0 .5em .5em}#conversejs .fancy-dropdown{border:1px solid #F1DCD6;height:25px;text-align:left}#conversejs .fancy-dropdown .choose-xmpp-status{width:155px}#conversejs .fancy-dropdown .choose-xmpp-status span{padding-right:5px;padding-left:5px;float:left}#conversejs .fancy-dropdown .choose-xmpp-status,#conversejs .fancy-dropdown .toggle-xmpp-contact-form{text-shadow:0 1px 0 #fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline}#conversejs .fancy-dropdown .toggle-xmpp-contact-form span{float:left}#conversejs #fancy-xmpp-status-select a.change-xmpp-status-message{float:right;clear:right;height:22px;width:12px;margin:0 5px 0 0;color:#436F64}#conversejs ul#found-users{padding:10px 0 5px 5px;border:0}#conversejs form.search-xmpp-contact{margin:0;padding:0 0 5px 5px}#conversejs form.search-xmpp-contact input{width:8em}#conversejs a.close-chatbox-button,#conversejs a.configure-chatroom-button,#conversejs a.toggle-chatbox-button{border-radius:6px;border:1px solid #888;color:#fff;cursor:pointer;display:inline-block;float:right;font-size:10px;margin:0 0 0 3px;padding:3px 3px 2px;text-decoration:none}#conversejs a.close-chatbox-button:active,#conversejs a.configure-chatroom-button:active,#conversejs a.toggle-chatbox-button:active{position:relative;top:1px}#conversejs .chatroom-form-container{height:100%;color:#6C4C44;overflow-y:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .chatroom-form{padding:1em}#conversejs .chatroom-form .instructions{color:gray;font-size:95%}#conversejs .chatroom-form input{width:100%;padding:5px;text-align:center}#conversejs .chatroom-form legend{font-size:16px;font-weight:700;margin:10px 0 15px}#conversejs .chatroom-form label{display:block;clear:both}#conversejs .chatroom-form label label input,#conversejs .chatroom-form label label select{float:right}#conversejs .requesting-xmpp-contact .request-actions{margin-left:.5em;float:right}#conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:.5em 0 0;height:194px;height:calc(100% - 68px);overflow:hidden}#conversejs #converse-roster .filter-type{display:table-cell;float:right;font-size:14px;height:25px;margin:0 0 .5em -1px;padding:0;width:84px}#conversejs #converse-roster .roster-filter{float:left;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg==) no-repeat right -20px center;border:1px solid #999;font-size:14px;height:25px;margin:0 0 .5em 7px;padding:0;padding:2px;width:103px}#conversejs #converse-roster .roster-filter.x{background-position:right 3px center}#conversejs #converse-roster .roster-filter.onX{cursor:pointer}#conversejs #converse-roster .roster-contacts{margin:0;max-height:195px;max-height:calc(100% - 26px);overflow-x:hidden;overflow-y:auto;padding-bottom:15px}#conversejs #converse-roster .group-toggle{color:#6C4C44;display:block;width:100%}#conversejs #converse-roster dt{display:none}#conversejs #converse-roster dd{line-height:16px;padding:4px 2px 0 4px;height:24px}#conversejs #converse-roster dd a,#conversejs #converse-roster dd span{text-shadow:0 1px 0 #FAFAFA;display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-left:3px}#conversejs #converse-roster dd span{padding:0 5px 0 0}#conversejs #converse-roster dd a.decline-xmpp-request{margin-left:5px}#conversejs #converse-roster dd a.remove-xmpp-contact{float:right;width:22px;margin:0;display:none;color:#6C4C44}#conversejs #converse-roster dd:hover a.remove-xmpp-contact{display:inline-block}#conversejs #converse-roster dd.odd{background-color:#DCEAC5}#conversejs #converse-roster dd.current-xmpp-contact span{font-size:16px;float:left;color:#436F64}#conversejs #converse-roster dd a.open-chat,#conversejs #converse-roster span.pending-contact-name{width:80%}#conversejs #converse-roster span.req-contact-name{width:69%;padding:0}#conversejs #available-chatrooms{text-align:left}#conversejs #available-chatrooms dt,#conversejs #converse-roster dt{font-weight:400;color:#6C4C44;border:none;padding:.5em;text-shadow:0 1px 0 #FAFAFA}#conversejs .room-info{font-size:11px;font-style:normal;font-weight:400}#conversejs li.room-info{display:block;margin-left:5px}#conversejs div.room-info{clear:left}#conversejs p.room-info{margin:0;padding:0;display:block;white-space:normal}#conversejs a.room-info{width:15px;display:none;clear:right}#conversejs a.open-room{float:left;white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden}#conversejs dd.available-chatroom{overflow-x:hidden;text-overflow:ellipsis;padding:.25em .5em;white-space:nowrap}#conversejs dd.available-chatroom a.open-room{width:150px}#conversejs dd.available-chatroom:hover a.room-info{display:inline-block;font-size:14px}#conversejs #converse-roster dd,#conversejs dd.available-chatroom{font-weight:700;border:none;display:block;color:#6C4C44;text-shadow:0 1px 0 #FAFAFA;clear:both;overflow-y:hidden}#conversejs #converse-roster dd:hover,#conversejs .roster-group:hover,#conversejs dd.available-chatroom:hover{background-color:#E3C9C1}#conversejs .chatbox,#conversejs .chatroom{height:35px;float:right;margin:0 7px;display:block}@media screen and (max-width:480px){#conversejs .chatbox,#conversejs .chatroom{margin:0}}#conversejs .chatbox{width:200px}@media screen and (max-width:480px){#conversejs .chatbox{width:100%}}#conversejs .chatbox .box-flyout{z-index:1;width:200px}@media screen and (max-width:480px){#conversejs .chatbox .box-flyout{width:100%}}#conversejs .chatbox .dropdown a{width:148px;display:inline-block;line-height:25px}#conversejs .chatbox .dropdown li{list-style:none;padding-left:0}#conversejs .chatbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;border:1px solid #F1DCD6;width:100%;z-index:21;background-color:#F1E2DD}#conversejs .chatbox .dropdown dd ul li:hover{background-color:#E3C9C1}#conversejs .chatbox .dropdown dd.search-xmpp ul{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs .chatbox .dropdown dd.search-xmpp ul li:hover{background-color:#F1E2DD}#conversejs .chatbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}#conversejs .chatroom,#conversejs .chatroom .box-flyout{width:300px}@media screen and (max-width:480px){#conversejs .chatroom,#conversejs .chatroom .box-flyout{width:100%}}#conversejs .chatroom label{margin-left:2px;font-size:12px}#conversejs .chatroom .participant-list{list-style:none}#conversejs .chatroom .participant-list li{cursor:default;display:block;font-size:12px;font-weight:700;overflow:hidden;padding:2px 5px;text-overflow:ellipsis;white-space:nowrap}#conversejs .chatroom .participant-list li.moderator{color:#8f2831}#conversejs .chatroom .chat-textarea{border-bottom-right-radius:0}#conversejs .chatroom .chat-area{float:left;height:100%;width:200px}#conversejs .chatroom .invited-contact{margin:-1px 0 0 -1px;width:100px;border:1px solid #999}#conversejs .chatroom .invited-contact.tt-input{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkBCjE0uzKkOgAAAidJREFUKM+N0k+IEnEUB/D3cyscdagkWpHV0WGWREXm0AgOGkSJ07kh2UXYU5cOewm6Bp0KXG/tpSCv6hyEFQIhMEaE3yERYfwTOoqKGLQxDAbqYadLgu7J7/XxeY/3ez8EACDLsgljfMfj8ZxUKhXXYDAAnueBoqgyAMipVOovXAuSZdnUaDQeDofDs16vFyUIAjRNUwmCoG02G1AUdZ5IJN7GYrHfm3AvEAjcnUwmX0ajUdRqtV74fL6sruufKYoa6bp+fzabPUMI7ZfL5eImNHk8npNerxc1m80XHMe98fv9H3K5XDkSibxjWfb1arWaYoyPMMbCFqxUKi6CIODw8LDmdDq7oigaAACiKK5omv7KcdylpmlIkiTHFlRVFTRNUxVFqa/ROqIoGoqi5A3DgFartfU4Jp7ngSAI2uVyPZIk6dZmUZKk2w6H4xghBPF4HK7vWLbZbDCdTp+rqvpUkiS0RvV6/bTf7x8wDHMViURqm/AGAMgURZ232+1X1Wr102KxuEwmk3lZlo/7/f7BcrkkSZKs2e12tHXH/x/gHsY4jTE+0jQNGYYBCCFgGOaKJMkfjUaDZximGQ6HXzSbzZ+ZTMbY6oIxFgqFgqPT6YAgCMBxXM1ut6N0Op0fj8chi8XyjWXZ98Fg8DuCHZLNZh+USqWP8/n8idvt/hUKhV7u7QK9Xu8fmqanAJBQVXUfAGY7TQQAKBaLN8fjsdDtdh/run72Dzhf7XLe2UevAAAAAElFTkSuQmCC) no-repeat right 3px center}#conversejs .chatroom .participants{float:right;background-color:#fff;overflow-y:auto;overflow-x:hidden;border-left:1px solid #AAA;border-bottom-right-radius:4px;width:100px;height:100%}#conversejs .chatroom .participants label{font-size:12px;font-style:italic;margin:5px;display:block}#conversejs .chatroom-form,#conversejs .controlbox-pane{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;font-size:14px;overflow-y:auto;position:absolute;text-align:center;width:100%;height:289px;height:-webkit-calc(100% - 44px);height:calc(100% - 44px)}#conversejs .controlbox-pane{padding:5px 0;overflow-y:hidden}#conversejs .controlbox-pane dd{margin-left:0;margin-bottom:0}#conversejs .controlbox-pane dd.odd{background-color:#DCEAC5}#conversejs #converse-register .title{font-weight:700}#conversejs #converse-register .info{font-style:italic;color:green;font-size:85%;margin:5px 0}#conversejs #converse-register .instructions,#conversejs .form-help{color:gray;font-size:85%}#conversejs #converse-register .instructions:hover,#conversejs .form-help:hover{color:#6C4C44}#conversejs .form-help{padding-top:5px}#conversejs #converse-login,#conversejs #converse-register{background:#fff;padding:1em}#conversejs #converse-login input,#conversejs #converse-register input{width:100%;height:30px;margin:5px 0 10px;padding-left:.5em}#conversejs #converse-register .input-group{display:table;margin:auto;width:178px}#conversejs #converse-register .input-group input[name=username],#conversejs #converse-register .input-group span{display:table-cell}#conversejs #converse-register .input-group input[name=username]{width:100%}#conversejs .cancel-submit,#conversejs .save-submit{width:45%;margin:5px 3px}#conversejs .cancel,#conversejs .cancel-submit{color:#681F2C}#conversejs .save-submit{color:#436F64}#conversejs #converse-login label,#conversejs #converse-register label,#conversejs .chatroom-form label,#conversejs .controlbox-pane label{font-size:14px;font-weight:700;height:auto;margin:4px}#conversejs #converse-login .login-submit,#conversejs #converse-login .submit,#conversejs #converse-register .login-submit,#conversejs #converse-register .submit{height:30px;padding:0;font-size:14px}#conversejs #converse-login .submit{margin:1em 0}#conversejs form.add-chatroom{background:0 0;padding:.5em}#conversejs form.add-chatroom input[type=button],#conversejs form.add-chatroom input[type=submit],#conversejs form.add-chatroom input[type=text]{margin:0;width:100%;padding:.25em}#conversejs form.add-chatroom input[type=button],#conversejs form.add-chatroom input[type=submit],#conversejs form.add-chatroom span.spinner{margin-top:.5em;display:table-cell;width:auto}#conversejs form.add-chatroom input[type=submit]{color:#436F64}#conversejs select#select-xmpp-status{float:right;margin-right:.5em}#conversejs .chat-head{border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;font-size:100%;margin:0;padding:6px}#conversejs .chat-head.controlbox-head{background-color:#436F64;border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;height:44px;margin:0;padding:6px 6px 6px 0}#conversejs .chat-head .avatar{float:left}#conversejs .chat-head #controlbox-tabs{text-align:center;display:inline;overflow:hidden;font-size:12px;list-style-type:none}#conversejs .chat-head #controlbox-tabs a.current,#conversejs .chat-head #controlbox-tabs a.current:hover{box-shadow:none;border-bottom:0;height:44px;cursor:default;color:#6C4C44}#conversejs .chat-head #controlbox-tabs li{float:left;list-style:none;padding-left:0;text-shadow:#fff 0 1px 0;width:38%}#conversejs .chat-head #controlbox-tabs li a{background-color:#fff;border-bottom:1px solid #CCC;border-top-left-radius:4px;border-top-right-radius:4px;box-shadow:inset 2px -2px 20px rgba(0,0,0,.3);color:#888;display:block;font-size:12px;height:43px;line-height:43px;margin:0;text-align:center;text-decoration:none}#conversejs .chat-head #controlbox-tabs li a:hover{color:#6C4C44}#conversejs div#chatrooms{overflow-y:auto}#conversejs form.sendXMPPMessage{-moz-background-clip:padding;-moz-border-radius:4px;-webkit-background-clip:padding-box;-webkit-border-radius:4px;background:#fff;border-radius:4px;border-top-left-radius:0;border-top-right-radius:0;border:0;margin:0;padding:0;position:relative;height:82px;width:200px}@media screen and (max-width:480px){#conversejs form.sendXMPPMessage{width:100%}}#conversejs form.sendXMPPMessage .chat-textarea{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;height:62px;padding:.5em;width:100%;resize:none}#conversejs .chat-toolbar{font-size:14px;margin:0;padding:0 4px;height:20px;display:block}#conversejs .chat-toolbar a{color:#436F64}#conversejs .chat-toolbar .unencrypted,#conversejs .chat-toolbar .unencrypted a{color:#8f2831}#conversejs .chat-toolbar .unverified,#conversejs .chat-toolbar .unverified a{color:#cf5300}#conversejs .chat-toolbar .private,#conversejs .chat-toolbar .private a{color:#4b7003}#conversejs .chat-toolbar .toggle-clear,#conversejs .chat-toolbar .toggle-otr,#conversejs .chat-toolbar .toggle-participants{float:right}#conversejs .chat-toolbar li{display:inline-block;list-style:none;padding:0 3px;cursor:pointer;margin-top:1px}#conversejs .chat-toolbar li:hover{cursor:pointer}#conversejs .chat-toolbar ul{background:#fff;bottom:100%;box-shadow:0 -1px 2px 0 rgba(0,0,0,.4);display:none;font-size:12px;margin:0 0 1px;position:absolute;right:0}#conversejs .chat-toolbar ul li{cursor:pointer;list-style:none;position:relative}#conversejs .chat-toolbar ul li a:hover{color:#8f2831}#conversejs .chat-toolbar .toggle-smiley{padding-left:5px}#conversejs .chat-toolbar .toggle-smiley ul li{font-size:14px;padding:5px;z-index:98}#conversejs .chat-toolbar .toggle-smiley ul li:hover{background-color:#E3C9C1}#conversejs .chat-toolbar .toggle-otr ul li{background-color:#fff;display:block;z-index:99}#conversejs .chat-toolbar .toggle-otr ul li a{-moz-transition:background-color .2s ease-in-out;-webkit-transition:background-color .2s ease-in-out;transition:background-color .2s ease-in-out;display:block;padding:1px;text-decoration:none}#conversejs .chat-toolbar-text{font-size:12px;padding-right:3px}#conversejs #set-custom-xmpp-status{float:left;padding:0}#conversejs #set-custom-xmpp-status input{height:26px;width:-webkit-calc(100% - 40px);width:calc(100% - 40px);padding:0 0 0 .5em}#conversejs #set-custom-xmpp-status button{height:26px;width:40px;padding:1px}#conversejs .chat-textarea-chatbox-selected{border:1px solid #578308;margin:0}#conversejs .chat-textarea-chatroom-selected{border:2px solid #436F64;margin:0}#conversejs #controlbox{display:none}#conversejs #controlbox div.xmpp-status{display:inline}#conversejs .chatbox .dropdown{background-color:#F1E2DD}#conversejs .chatbox .dropdown dd{position:relative}#conversejs .chatbox .dropdown dd,#conversejs .dropdown dt,#conversejs .dropdown ul{margin:0;padding:0}#conversejs .add-xmpp-contact{background:0 0;padding:5px}#conversejs .add-xmpp-contact input{margin:0 0 1rem;width:100%}#conversejs .add-xmpp-contact button{width:100%}#conversejs .xmpp-status-menu{text-align:left;box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs .xmpp-status-menu li{padding:2px}#conversejs .xmpp-status-menu li a{width:100%;padding:0 8px}#conversejs .xmpp-status-menu li a.logout,#conversejs .xmpp-status-menu li a.logout span{color:#681F2C}#conversejs .set-xmpp-status{background:0 0;padding:.5em}#conversejs .set-xmpp-status .dropdown dd ul{z-index:22}#conversejs .box-flyout,#conversejs .minimized-chats-flyout{border-radius:4px;bottom:6px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;height:400px;position:absolute}@media screen and (max-width:480px){#conversejs .box-flyout,#conversejs .minimized-chats-flyout{height:400px}}#conversejs .minimized-chats-flyout{border-radius:4px;bottom:35px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;position:absolute;height:auto;width:130px}#conversejs .minimized-chats-flyout .chat-head,#conversejs .minimized-chats-flyout .chat-head-chatroom{border-radius:4px;width:130px;height:35px;margin-bottom:1px}#conversejs .minimized-chats-flyout.minimized{height:auto}#conversejs .dragresize{position:absolute;width:200px;height:5px;background:0 0;border:0;top:0;margin-left:0;cursor:n-resize;z-index:20}
\ No newline at end of file
*/@font-face{font-family:Converse-js;src:url(../fonticons/fonts/icomoon.eot?-mnoxh0);src:url(../fonticons/fonts/icomoon.eot?#iefix-mnoxh0) format("embedded-opentype"),url(../fonticons/fonts/icomoon.woff?-mnoxh0) format("woff"),url(../fonticons/fonts/icomoon.ttf?-mnoxh0) format("truetype"),url(../fonticons/fonts/icomoon.svg?-mnoxh0#icomoon) format("svg");font-weight:400;font-style:normal}.icon-conversejs{font-family:Converse-js;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-conversejs:before{content:"\e600"}#conversejs{color:#6C4C44;font-size:14px;bottom:0;direction:ltr;height:35px;left:0;position:fixed;right:0;z-index:30;display:block;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}#conversejs ::selection{background-color:#E3C9C1}#conversejs *,#conversejs :after,#conversejs :before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@media screen and (max-width:480px){#conversejs{margin:5px 10px}}#conversejs a,#conversejs a:visited{text-decoration:none;color:#436F64;text-shadow:none}#conversejs ul li{height:auto}#conversejs a,#conversejs article,#conversejs aside,#conversejs audio,#conversejs blockquote,#conversejs canvas,#conversejs caption,#conversejs dd,#conversejs details,#conversejs div,#conversejs dl,#conversejs dt,#conversejs em,#conversejs embed,#conversejs fieldset,#conversejs figcaption,#conversejs figure,#conversejs footer,#conversejs form,#conversejs h1,#conversejs h2,#conversejs h3,#conversejs h4,#conversejs h5,#conversejs h6,#conversejs header,#conversejs hgroup,#conversejs img,#conversejs label,#conversejs legend,#conversejs li,#conversejs mark,#conversejs menu,#conversejs nav,#conversejs ol,#conversejs output,#conversejs p,#conversejs pre,#conversejs ruby,#conversejs section,#conversejs span,#conversejs strong,#conversejs summary,#conversejs table,#conversejs tbody,#conversejs td,#conversejs tfoot,#conversejs th,#conversejs thead,#conversejs time,#conversejs tr,#conversejs ul,#conversejs video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}#conversejs button,#conversejs input[type=button],#conversejs input[type=password],#conversejs input[type=submit],#conversejs input[type=text],#conversejs textarea{font-size:14px;padding:.25em;min-height:0}#conversejs input[type=text]{height:26px}#conversejs strong{font-weight:700}#conversejs ol,#conversejs ul{list-style:none}#conversejs li{height:10px}#conversejs dl,#conversejs ol,#conversejs ul{font:inherit;margin:0}#conversejs [data-icon]:before{content:attr(data-icon);font-family:Converse-js;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs [class*=" icon-"],#conversejs [class^=icon-]{background-position:14px 14px;background-image:none;font-family:Converse-js;font-style:normal;font-variant:normal;font-weight:400;width:auto;height:auto;line-height:1;speak:none;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}#conversejs .icon-address-book:before{content:"\270f"}#conversejs .icon-angry:before{content:"\e03f"}#conversejs .icon-attachment:before{content:"\e032"}#conversejs .icon-away:before{content:"\25fb"}#conversejs .icon-blocked:before{content:"\2718"}#conversejs .icon-bold:before{content:"\e04d"}#conversejs .icon-bubbles-2:before{content:"\e016"}#conversejs .icon-bubbles-3:before{content:"\e017"}#conversejs .icon-bubbles:before{content:"\e015"}#conversejs .icon-camera-2:before{content:"\2616"}#conversejs .icon-camera:before{content:"\e003"}#conversejs .icon-cancel-circle:before{content:"\e058"}#conversejs .icon-checkbox-checked:before{content:"\2611"}#conversejs .icon-checkbox-partial:before{content:"\2b28"}#conversejs .icon-checkbox-unchecked:before{content:"\2b27"}#conversejs .icon-checkmark:before{content:"\2713"}#conversejs .icon-close:before{content:"\2715"}#conversejs .icon-closed:before{content:"\25ba"}#conversejs .icon-cog:before{content:"\e02f"}#conversejs .icon-cogs:before{content:"\e022"}#conversejs .icon-confused:before{content:"\2368"}#conversejs .icon-cool:before{content:"\e040"}#conversejs .icon-dnd:before{content:"\e004"}#conversejs .icon-envelop:before{content:"\2709"}#conversejs .icon-evil:before{content:"\261f"}#conversejs .icon-eye-blocked:before{content:"\e031"}#conversejs .icon-eye:before{content:"\e030"}#conversejs .icon-globe:before{content:"\e033"}#conversejs .icon-grin:before{content:"\e041"}#conversejs .icon-happy:before{content:"\263b"}#conversejs .icon-headphones:before{content:"\266c"}#conversejs .icon-heart:before{content:"\2764"}#conversejs .icon-hide-users:before{content:"\e01c"}#conversejs .icon-home:before{content:"\e000"}#conversejs .icon-image:before{content:"\2b14"}#conversejs .icon-info:before{content:"\2360"}#conversejs .icon-italic:before{content:"\e04f"}#conversejs .icon-key-2:before{content:"\e029"}#conversejs .icon-key:before{content:"\e028"}#conversejs .icon-lock-2:before{content:"\e027"}#conversejs .icon-lock:before{content:"\e026"}#conversejs .icon-logout:before{content:"\e601"}#conversejs .icon-minus:before{content:"\e05a"}#conversejs .icon-music:before{content:"\266b"}#conversejs .icon-new-tab:before{content:"\e053"}#conversejs .icon-newspaper:before{content:"\e001"}#conversejs .icon-notebook:before{content:"\2710"}#conversejs .icon-notification:before{content:"\e01f"}#conversejs .icon-online:before{content:"\25fc"}#conversejs .icon-opened:before{content:"\25bc"}#conversejs .icon-pencil:before{content:"\270e"}#conversejs .icon-phone-hang-up:before{content:"\260e"}#conversejs .icon-phone:before{content:"\260f"}#conversejs .icon-play:before{content:"\25d9"}#conversejs .icon-plus:before{content:"\271a"}#conversejs .icon-pushpin:before{content:"\e012"}#conversejs .icon-quotes-left:before{content:"\e01d"}#conversejs .icon-radio-checked:before{content:"\2b26"}#conversejs .icon-radio-unchecked:before{content:"\2b25"}#conversejs .icon-remove:before{content:"\e02d"}#conversejs .icon-room-info:before{content:"\e059"}#conversejs .icon-sad:before{content:"\2639"}#conversejs .icon-search:before{content:"\e021"}#conversejs .icon-shocked:before{content:"\2364"}#conversejs .icon-show-users:before{content:"\e01e"}#conversejs .icon-smiley:before{content:"\263a"}#conversejs .icon-spell-check:before{content:"\e045"}#conversejs .icon-spinner:before{content:"\231b"}#conversejs .icon-strikethrough:before{content:"\e050"}#conversejs .icon-thumbs-up:before{content:"\261d"}#conversejs .icon-tongue:before{content:"\e038"}#conversejs .icon-underline:before{content:"\e04e"}#conversejs .icon-unlocked:before{content:"\e025"}#conversejs .icon-user:before{content:"\e01a"}#conversejs .icon-users:before{content:"\e01b"}#conversejs .icon-volume-decrease:before{content:"\e04b"}#conversejs .icon-volume-high:before{content:"\e046"}#conversejs .icon-volume-increase:before{content:"\e04c"}#conversejs .icon-volume-low:before{content:"\e048"}#conversejs .icon-volume-medium:before{content:"\e047"}#conversejs .icon-volume-mute-2:before{content:"\e04a"}#conversejs .icon-volume-mute:before{content:"\e049"}#conversejs .icon-warning:before{content:"\26a0"}#conversejs .icon-wink:before{content:"\e03a"}#conversejs .icon-wondering:before{content:"\2369"}#conversejs .icon-wrench:before{content:"\e024"}#conversejs .icon-offline:before,#conversejs .icon-unavailable:before,#conversejs .icon-xa:before{content:"\e002"}#conversejs .icon-youtube:before{content:"\e055"}#conversejs .icon-zoom-in:before{content:"\e02b"}#conversejs .icon-zoom-out:before{content:"\e02a"}#conversejs .no-text-select{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#conversejs .emoticon{font-size:14px}#conversejs .left{float:left}#conversejs .right{float:right}#conversejs .hidden{display:none}#conversejs .locked{padding-right:22px}@-webkit-keyframes spin{from{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes spin{from{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@keyframes spin{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);-moz-transform:rotate(359deg);-ms-transform:rotate(359deg);-o-transform:rotate(359deg);transform:rotate(359deg)}}#conversejs .spinner:before{font-size:24px;font-family:Converse-js!important;content:"\231b"}#conversejs .spinner{-webkit-animation:spin 2s infinite,linear;-moz-animation:spin 2s infinite,linear;animation:spin 2s infinite,linear;display:block;text-align:center;margin:5px}#conversejs .centered{text-align:center;display:block;margin:5em auto}#conversejs .hor_centered{text-align:center;display:block;margin:0 auto}#conversejs #minimized-chats,#conversejs .toggle-controlbox{border-top-left-radius:4px;border-top-right-radius:4px;float:right;margin:0 7px;font-weight:700}#conversejs .toggle-controlbox{background-color:#436F64;color:#0a0a0a;height:100%;padding:10px 8px 0}#conversejs .toggle-controlbox span{color:#fff}#conversejs .button-group,#conversejs .input-button-group{display:table}#conversejs .button-group{width:100%}#conversejs .input-button-group button,#conversejs .input-button-group input{display:table-cell}#conversejs #minimized-chats{color:#fff;display:none;height:100%;padding:0;width:130px}#conversejs #minimized-chats #toggle-minimized-chats{border-top-left-radius:4px;border-top-right-radius:4px;background-color:ivory;position:relative;padding:10px 0 0;display:block;width:100%;height:100%;text-align:center}#conversejs #minimized-chats .chat-head-message-count,#conversejs #minimized-chats .unread-message-count{font-weight:700;background-color:#f6f6f6;background-image:-webkit-linear-gradient(#f6f6f6 5%,gray 100%);background-image:linear-gradient(#f6f6f6 5%,gray 100%);border:1px solid;text-shadow:1px 1px 0 #FAFAFA;color:#681F2C;border-radius:5px;padding:2px 4px;font-size:16px;text-align:center;position:absolute;right:116px;bottom:10px}#conversejs #minimized-chats .box-flyout{position:absolute;display:block;height:auto;bottom:35px;margin-left:0}#conversejs #minimized-chats .box-flyout .chat-head{font-size:100%;border-radius:4px;padding:3px 0 0 5px;margin:0 0 1px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);height:24px;width:130px}#conversejs .chat-body{background-color:#fff;border-bottom-right-radius:4px;border-bottom-left-radius:4px;height:289px;height:-webkit-calc(100% - 44px);height:calc(100% - 44px);border-top:0}#conversejs .chat-body p{font-size:14px;color:#6C4C44;padding:5px;margin:0}#conversejs .tt-highlight{background-color:#00230F}#conversejs .tt-suggestion p{color:#fff;text-shadow:rgba(0,0,0,.51)0 -1px 0;cursor:pointer;font-size:11px}#conversejs .tt-suggestion p:hover{background-color:#00230F}#conversejs .tt-suggestion p:hover .tt-highlight{background:#27774A}#conversejs .tt-dropdown-menu{margin:0 1px;width:96px;max-height:250px;overflow-x:hidden;overflow-y:auto;text-overflow:ellipsis;background:#27774A;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .chat-blink{background-color:#176679;border-right:1px solid #176679;border-left:1px solid #176679}#conversejs .chat-content{position:relative;padding:8px;font-size:13px;color:#6C4C44;overflow-y:auto;border:0;background-color:#fff;line-height:1.3em;height:206px;height:calc(100% - 84px)}#conversejs .chat-error{color:#681F2C;font-weight:700}#conversejs .chat-error,#conversejs .chat-info,#conversejs .chat-message{padding:2px 0}#conversejs .chat-message-me,#conversejs .chat-message-room,#conversejs .chat-message-them{font-weight:700;white-space:nowrap;max-width:100px;text-overflow:ellipsis;overflow:hidden;display:inline-block;float:left;padding-right:3px}#conversejs .chat-message-content{word-wrap:break-word}#conversejs .chat-message-room,#conversejs .chat-message-them{color:#4B7003}#conversejs .chat-message-me{color:#436F64}#conversejs .chat-date,#conversejs .chat-event,#conversejs .chat-info{color:gray}#conversejs li.chat-info{padding-left:10px}#conversejs .chat-date{display:inline-block;padding-top:10px}#conversejs .not-implemented{margin-top:3em;margin-left:.3em;color:gray}#conversejs .mentioned{font-weight:700}#conversejs .delayed .chat-message-them{color:#FB5D50}#conversejs .delayed .chat-message-me{color:#7EABBB}#conversejs .error{color:red}#conversejs input.error{border:1px solid red}#conversejs #converse-register .form-errors{color:red;display:none}#conversejs #converse-register .provider-title{font-size:115%}#conversejs #converse-register .provider-score{width:178px;margin-bottom:8px}#conversejs #converse-register .form-help .url{font-weight:700;color:#436F64}#conversejs .reg-feedback{font-size:85%}#conversejs #converse-login .conn-feedback,#conversejs .reg-feedback{display:block;text-align:center;width:100%}#conversejs .chat-message-error{color:#76797C;font-size:90%;font-weight:400}#conversejs .chat-title,#conversejs a.restore-chat{padding:1px 0 1px 5px;color:#fff;font-weight:700;line-height:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:rgba(0,0,0,.51)0 -1px 0}#conversejs a.restore-chat:visited{color:#fff}#conversejs .chat-title a{color:#fff;width:100%;text-overflow:ellipsis;white-space:nowrap}#conversejs .chat-head-chatbox,#conversejs .chat-head-chatroom{height:44px;position:relative;padding:5px}#conversejs .chat-head-chatroom{background-color:#0F592F}#conversejs .chat-head-chatbox{background-color:#436F64}#conversejs .chatroom-topic,#conversejs .user-custom-message{color:#fff;font-size:80%;font-style:italic;height:1.3em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin:0;padding:1px 0 1px 5px}#conversejs .activated{display:block!important}#conversejs a.subscribe-to-user{padding-left:2em;font-weight:700}#conversejs dl.add-converse-contact{margin:0 .5em .5em}#conversejs .fancy-dropdown{border:1px solid #F1DCD6;height:25px;text-align:left}#conversejs .fancy-dropdown .choose-xmpp-status{width:155px}#conversejs .fancy-dropdown .choose-xmpp-status span{padding-right:5px;padding-left:5px;float:left}#conversejs .fancy-dropdown .choose-xmpp-status,#conversejs .fancy-dropdown .toggle-xmpp-contact-form{text-shadow:0 1px 0 #fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline}#conversejs .fancy-dropdown .toggle-xmpp-contact-form span{float:left}#conversejs #fancy-xmpp-status-select a.change-xmpp-status-message{float:right;clear:right;height:22px;width:12px;margin:0 5px 0 0;color:#436F64}#conversejs ul#found-users{padding:10px 0 5px 5px;border:0}#conversejs form.search-xmpp-contact{margin:0;padding:0 0 5px 5px}#conversejs form.search-xmpp-contact input{width:8em}#conversejs a.close-chatbox-button,#conversejs a.configure-chatroom-button,#conversejs a.toggle-chatbox-button{border-radius:6px;border:1px solid #888;color:#fff;cursor:pointer;display:inline-block;float:right;font-size:10px;margin:0 0 0 3px;padding:3px 3px 2px;text-decoration:none}#conversejs a.close-chatbox-button:active,#conversejs a.configure-chatroom-button:active,#conversejs a.toggle-chatbox-button:active{position:relative;top:1px}#conversejs .chatroom-form-container{height:100%;color:#6C4C44;overflow-y:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#conversejs .chatroom-form{padding:1em}#conversejs .chatroom-form .instructions{color:gray;font-size:95%}#conversejs .chatroom-form input{width:100%;padding:5px;text-align:center}#conversejs .chatroom-form legend{font-size:16px;font-weight:700;margin:10px 0 15px}#conversejs .chatroom-form label{display:block;clear:both}#conversejs .chatroom-form label label input,#conversejs .chatroom-form label label select{float:right}#conversejs .requesting-xmpp-contact .request-actions{margin-left:.5em;float:right}#conversejs #converse-roster{text-align:left;width:100%;position:relative;margin:.5em 0 0;height:194px;height:calc(100% - 68px);overflow:hidden}#conversejs #converse-roster .filter-type{display:table-cell;float:right;font-size:14px;height:25px;margin:0 0 .5em -1px;padding:0;width:84px}#conversejs #converse-roster .roster-filter{float:left;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAABNSURBVHjaXI7BDcAwCAMvyQjMyQ6dAbZiKfqoUK34g2zJh1dENIC7M8pMAPYdzAVY3d0ajNz9aypS/b5R6o+ZPdqoKgCq6h80KH3xDgBqNR97p8oAGQAAAABJRU5ErkJggg==) no-repeat right -20px center;border:1px solid #999;font-size:14px;height:25px;margin:0 0 .5em 7px;padding:0;padding:2px;width:103px}#conversejs #converse-roster .roster-filter.x{background-position:right 3px center}#conversejs #converse-roster .roster-filter.onX{cursor:pointer}#conversejs #converse-roster .roster-contacts{margin:0;max-height:195px;max-height:calc(100% - 26px);overflow-x:hidden;overflow-y:auto;padding-bottom:15px}#conversejs #converse-roster .group-toggle{color:#6C4C44;display:block;width:100%}#conversejs #converse-roster dt{display:none}#conversejs #converse-roster dd{line-height:16px;padding:4px 2px 0 4px;height:24px}#conversejs #converse-roster dd a,#conversejs #converse-roster dd span{text-shadow:0 1px 0 #FAFAFA;display:inline-block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-left:3px}#conversejs #converse-roster dd span{padding:0 5px 0 0}#conversejs #converse-roster dd a.decline-xmpp-request{margin-left:5px}#conversejs #converse-roster dd a.remove-xmpp-contact{float:right;width:22px;margin:0;display:none;color:#6C4C44}#conversejs #converse-roster dd:hover a.remove-xmpp-contact{display:inline-block}#conversejs #converse-roster dd.odd{background-color:#DCEAC5}#conversejs #converse-roster dd.current-xmpp-contact span{font-size:16px;float:left;color:#436F64}#conversejs #converse-roster dd a.open-chat,#conversejs #converse-roster span.pending-contact-name{width:80%}#conversejs #converse-roster span.req-contact-name{width:69%;padding:0}#conversejs #available-chatrooms{text-align:left}#conversejs #available-chatrooms dt,#conversejs #converse-roster dt{font-weight:400;color:#6C4C44;border:none;padding:.5em;text-shadow:0 1px 0 #FAFAFA}#conversejs .room-info{font-size:11px;font-style:normal;font-weight:400}#conversejs li.room-info{display:block;margin-left:5px}#conversejs div.room-info{clear:left}#conversejs p.room-info{margin:0;padding:0;display:block;white-space:normal}#conversejs a.room-info{width:15px;display:none;clear:right}#conversejs a.open-room{float:left;white-space:nowrap;text-overflow:ellipsis;overflow-x:hidden}#conversejs dd.available-chatroom{overflow-x:hidden;text-overflow:ellipsis;padding:.25em .5em;white-space:nowrap}#conversejs dd.available-chatroom a.open-room{width:150px}#conversejs dd.available-chatroom:hover a.room-info{display:inline-block;font-size:14px}#conversejs #converse-roster dd,#conversejs dd.available-chatroom{font-weight:700;border:none;display:block;color:#6C4C44;text-shadow:0 1px 0 #FAFAFA;clear:both;overflow-y:hidden}#conversejs #converse-roster dd:hover,#conversejs .roster-group:hover,#conversejs dd.available-chatroom:hover{background-color:#E3C9C1}#conversejs .chatbox,#conversejs .chatroom{height:35px;float:right;margin:0 7px;display:block}@media screen and (max-width:480px){#conversejs .chatbox,#conversejs .chatroom{margin:0}}#conversejs .chatbox{width:200px}@media screen and (max-width:480px){#conversejs .chatbox{width:100%}}#conversejs .chatbox .box-flyout{z-index:1;width:200px}@media screen and (max-width:480px){#conversejs .chatbox .box-flyout{width:100%}}#conversejs .chatbox .dropdown a{width:148px;display:inline-block;line-height:25px}#conversejs .chatbox .dropdown li{list-style:none;padding-left:0}#conversejs .chatbox .dropdown dd ul{padding:0;list-style:none;position:absolute;left:0;top:0;border:1px solid #F1DCD6;width:100%;z-index:21;background-color:#F1E2DD}#conversejs .chatbox .dropdown dd ul li:hover{background-color:#E3C9C1}#conversejs .chatbox .dropdown dd.search-xmpp ul{box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs .chatbox .dropdown dd.search-xmpp ul li:hover{background-color:#F1E2DD}#conversejs .chatbox .dropdown dt a span{cursor:pointer;display:block;padding:4px 7px 0 5px}#conversejs .chatroom,#conversejs .chatroom .box-flyout{width:300px}@media screen and (max-width:480px){#conversejs .chatroom,#conversejs .chatroom .box-flyout{width:100%}}#conversejs .chatroom label{margin-left:2px;font-size:12px}#conversejs .chatroom .participant-list{list-style:none}#conversejs .chatroom .participant-list li{cursor:default;display:block;font-size:12px;font-weight:700;overflow:hidden;padding:2px 5px;text-overflow:ellipsis;white-space:nowrap}#conversejs .chatroom .participant-list li.moderator{color:#8f2831}#conversejs .chatroom .chat-textarea{border-bottom-right-radius:0}#conversejs .chatroom .chat-area{float:left;height:100%;width:200px}#conversejs .chatroom .invited-contact{margin:-1px 0 0 -1px;width:100px;border:1px solid #999}#conversejs .chatroom .invited-contact.tt-input{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gkBCjE0uzKkOgAAAidJREFUKM+N0k+IEnEUB/D3cyscdagkWpHV0WGWREXm0AgOGkSJ07kh2UXYU5cOewm6Bp0KXG/tpSCv6hyEFQIhMEaE3yERYfwTOoqKGLQxDAbqYadLgu7J7/XxeY/3ez8EACDLsgljfMfj8ZxUKhXXYDAAnueBoqgyAMipVOovXAuSZdnUaDQeDofDs16vFyUIAjRNUwmCoG02G1AUdZ5IJN7GYrHfm3AvEAjcnUwmX0ajUdRqtV74fL6sruufKYoa6bp+fzabPUMI7ZfL5eImNHk8npNerxc1m80XHMe98fv9H3K5XDkSibxjWfb1arWaYoyPMMbCFqxUKi6CIODw8LDmdDq7oigaAACiKK5omv7KcdylpmlIkiTHFlRVFTRNUxVFqa/ROqIoGoqi5A3DgFartfU4Jp7ngSAI2uVyPZIk6dZmUZKk2w6H4xghBPF4HK7vWLbZbDCdTp+rqvpUkiS0RvV6/bTf7x8wDHMViURqm/AGAMgURZ232+1X1Wr102KxuEwmk3lZlo/7/f7BcrkkSZKs2e12tHXH/x/gHsY4jTE+0jQNGYYBCCFgGOaKJMkfjUaDZximGQ6HXzSbzZ+ZTMbY6oIxFgqFgqPT6YAgCMBxXM1ut6N0Op0fj8chi8XyjWXZ98Fg8DuCHZLNZh+USqWP8/n8idvt/hUKhV7u7QK9Xu8fmqanAJBQVXUfAGY7TQQAKBaLN8fjsdDtdh/run72Dzhf7XLe2UevAAAAAElFTkSuQmCC) no-repeat right 3px center}#conversejs .chatroom .participants{float:right;background-color:#fff;overflow-y:auto;overflow-x:hidden;border-left:1px solid #AAA;border-bottom-right-radius:4px;width:100px;height:100%}#conversejs .chatroom .participants label{font-size:12px;font-style:italic;margin:5px;display:block}#conversejs .chatroom-form,#conversejs .controlbox-pane{background-color:#fff;border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;font-size:14px;overflow-y:auto;position:absolute;text-align:center;width:100%;height:289px;height:-webkit-calc(100% - 44px);height:calc(100% - 44px)}#conversejs .controlbox-pane{padding:5px 0;overflow-y:hidden}#conversejs .controlbox-pane dd{margin-left:0;margin-bottom:0}#conversejs .controlbox-pane dd.odd{background-color:#DCEAC5}#conversejs #converse-register .title{font-weight:700}#conversejs #converse-register .info{font-style:italic;color:green;font-size:85%;margin:5px 0}#conversejs #converse-register .instructions,#conversejs .form-help{color:gray;font-size:85%}#conversejs #converse-register .instructions:hover,#conversejs .form-help:hover{color:#6C4C44}#conversejs .form-help{padding-top:5px}#conversejs #converse-login,#conversejs #converse-register{background:#fff;padding:1em}#conversejs #converse-login input,#conversejs #converse-register input{width:100%;height:30px;margin:5px 0 10px;padding-left:.5em}#conversejs #converse-register .input-group{display:table;margin:auto;width:178px}#conversejs #converse-register .input-group input[name=username],#conversejs #converse-register .input-group span{display:table-cell}#conversejs #converse-register .input-group input[name=username]{width:100%}#conversejs .cancel-submit,#conversejs .save-submit{width:45%;margin:5px 3px}#conversejs .cancel,#conversejs .cancel-submit{color:#681F2C}#conversejs .save-submit{color:#436F64}#conversejs #converse-login label,#conversejs #converse-register label,#conversejs .chatroom-form label,#conversejs .controlbox-pane label{font-size:14px;font-weight:700;height:auto;margin:4px}#conversejs #converse-login .login-submit,#conversejs #converse-login .submit,#conversejs #converse-register .login-submit,#conversejs #converse-register .submit{height:30px;padding:0;font-size:14px}#conversejs #converse-login .submit{margin:1em 0}#conversejs form.add-chatroom{background:0 0;padding:.5em}#conversejs form.add-chatroom input[type=button],#conversejs form.add-chatroom input[type=submit],#conversejs form.add-chatroom input[type=text]{margin:0;width:100%;padding:.25em}#conversejs form.add-chatroom input[type=button],#conversejs form.add-chatroom input[type=submit],#conversejs form.add-chatroom span.spinner{margin-top:.5em;display:table-cell;width:auto}#conversejs form.add-chatroom input[type=submit]{color:#436F64}#conversejs select#select-xmpp-status{float:right;margin-right:.5em}#conversejs .chat-head{border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;font-size:100%;margin:0;padding:6px}#conversejs .chat-head.controlbox-head{background-color:#436F64;border-top-left-radius:4px;border-top-right-radius:4px;color:#fff;height:44px;margin:0;padding:6px 6px 6px 0}#conversejs .chat-head .avatar{float:left}#conversejs .chat-head #controlbox-tabs{text-align:center;display:inline;overflow:hidden;font-size:12px;list-style-type:none}#conversejs .chat-head #controlbox-tabs a.current,#conversejs .chat-head #controlbox-tabs a.current:hover{box-shadow:none;border-bottom:0;height:44px;cursor:default;color:#6C4C44}#conversejs .chat-head #controlbox-tabs li{float:left;list-style:none;padding-left:0;text-shadow:#fff 0 1px 0;width:38%}#conversejs .chat-head #controlbox-tabs li a{background-color:#fff;border-bottom:1px solid #CCC;border-top-left-radius:4px;border-top-right-radius:4px;box-shadow:inset 2px -2px 20px rgba(0,0,0,.3);color:#888;display:block;font-size:12px;height:43px;line-height:43px;margin:0;text-align:center;text-decoration:none}#conversejs .chat-head #controlbox-tabs li a:hover{color:#6C4C44}#conversejs div#chatrooms{overflow-y:auto}#conversejs form.sendXMPPMessage{-moz-background-clip:padding;-moz-border-radius:4px;-webkit-background-clip:padding-box;-webkit-border-radius:4px;background:#fff;border-radius:4px;border-top-left-radius:0;border-top-right-radius:0;border:0;margin:0;padding:0;position:relative;height:82px;width:200px}@media screen and (max-width:480px){#conversejs form.sendXMPPMessage{width:100%}}#conversejs form.sendXMPPMessage .chat-textarea{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border:0;height:62px;padding:.5em;width:100%;resize:none}#conversejs .chat-toolbar{font-size:14px;margin:0;padding:0 4px;height:20px;display:block}#conversejs .chat-toolbar a{color:#436F64}#conversejs .chat-toolbar .unencrypted,#conversejs .chat-toolbar .unencrypted a{color:#8f2831}#conversejs .chat-toolbar .unverified,#conversejs .chat-toolbar .unverified a{color:#cf5300}#conversejs .chat-toolbar .private,#conversejs .chat-toolbar .private a{color:#4b7003}#conversejs .chat-toolbar .toggle-clear,#conversejs .chat-toolbar .toggle-otr,#conversejs .chat-toolbar .toggle-participants{float:right}#conversejs .chat-toolbar li{display:inline-block;list-style:none;padding:0 3px;cursor:pointer;margin-top:1px}#conversejs .chat-toolbar li:hover{cursor:pointer}#conversejs .chat-toolbar ul{background:#fff;bottom:100%;box-shadow:0 -1px 2px 0 rgba(0,0,0,.4);display:none;font-size:12px;margin:0 0 1px;position:absolute;right:0}#conversejs .chat-toolbar ul li{cursor:pointer;list-style:none;position:relative}#conversejs .chat-toolbar ul li a:hover{color:#8f2831}#conversejs .chat-toolbar .toggle-smiley{padding-left:5px}#conversejs .chat-toolbar .toggle-smiley ul li{font-size:14px;padding:5px;z-index:98}#conversejs .chat-toolbar .toggle-smiley ul li:hover{background-color:#E3C9C1}#conversejs .chat-toolbar .toggle-otr ul li{background-color:#fff;display:block;z-index:99}#conversejs .chat-toolbar .toggle-otr ul li a{-moz-transition:background-color .2s ease-in-out;-webkit-transition:background-color .2s ease-in-out;transition:background-color .2s ease-in-out;display:block;padding:1px;text-decoration:none}#conversejs .chat-toolbar-text{font-size:12px;padding-right:3px}#conversejs #set-custom-xmpp-status{float:left;padding:0}#conversejs #set-custom-xmpp-status input{height:26px;width:-webkit-calc(100% - 40px);width:calc(100% - 40px);padding:0 0 0 .5em}#conversejs #set-custom-xmpp-status button{height:26px;width:40px;padding:1px}#conversejs .chat-textarea-chatbox-selected{border:1px solid #578308;margin:0}#conversejs .chat-textarea-chatroom-selected{border:2px solid #436F64;margin:0}#conversejs #controlbox{display:none}#conversejs #controlbox div.xmpp-status{display:inline}#conversejs .chatbox .dropdown{background-color:#F1E2DD}#conversejs .chatbox .dropdown dd{position:relative}#conversejs .chatbox .dropdown dd,#conversejs .dropdown dt,#conversejs .dropdown ul{margin:0;padding:0}#conversejs .add-xmpp-contact{background:0 0;padding:5px}#conversejs .add-xmpp-contact input{margin:0 0 1rem;width:100%}#conversejs .add-xmpp-contact button{width:100%}#conversejs .xmpp-status-menu{text-align:left;box-shadow:1px 4px 10px 1px rgba(0,0,0,.4)}#conversejs .xmpp-status-menu li{padding:2px}#conversejs .xmpp-status-menu li a{width:100%;padding:0 8px}#conversejs .xmpp-status-menu li a.logout,#conversejs .xmpp-status-menu li a.logout span{color:#681F2C}#conversejs .set-xmpp-status{background:0 0;padding:.5em}#conversejs .set-xmpp-status .dropdown dd ul{z-index:22}#conversejs .box-flyout,#conversejs .minimized-chats-flyout{border-radius:4px;bottom:6px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;height:400px;position:absolute}@media screen and (max-width:480px){#conversejs .box-flyout,#conversejs .minimized-chats-flyout{height:400px}}#conversejs .minimized-chats-flyout{border-radius:4px;bottom:35px;box-shadow:1px 3px 5px 3px rgba(0,0,0,.4);display:block;position:absolute;height:auto;width:130px}#conversejs .minimized-chats-flyout .chat-head,#conversejs .minimized-chats-flyout .chat-head-chatroom{border-radius:4px;width:130px;height:35px;margin-bottom:1px}#conversejs .minimized-chats-flyout.minimized{height:auto}#conversejs .dragresize{position:absolute;width:200px;height:5px;background:0 0;border:0;top:0;margin-left:0;cursor:n-resize;z-index:20}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment