Skip to content

Instantly share code, notes, and snippets.

@benmanns
Created February 12, 2013 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benmanns/4771476 to your computer and use it in GitHub Desktop.
Save benmanns/4771476 to your computer and use it in GitHub Desktop.
(function(){var global = this;function debug(){return debug};function require(p, parent){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '" from ' + parent); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path), global); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('debug' == p) return debug; if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/'), parent); };};require.register("neuralnetwork.js", function(module, exports, require, global){
var _ = require("underscore"),
lookup = require("./lookup");
var NeuralNetwork = function(options) {
options = options || {};
this.learningRate = options.learningRate || 0.3;
this.momentum = options.momentum || 0.1;
this.hiddenSizes = options.hiddenLayers;
}
NeuralNetwork.prototype = {
initialize: function(sizes) {
this.sizes = sizes;
this.outputLayer = this.sizes.length - 1;
this.biases = []; // weights for bias nodes
this.weights = [];
this.outputs = [];
// state for training
this.deltas = [];
this.changes = []; // for momentum
this.errors = [];
for (var layer = 0; layer <= this.outputLayer; layer++) {
var size = this.sizes[layer];
this.deltas[layer] = zeros(size);
this.errors[layer] = zeros(size);
this.outputs[layer] = zeros(size);
if (layer > 0) {
this.biases[layer] = randos(size);
this.weights[layer] = new Array(size);
this.changes[layer] = new Array(size);
for (var node = 0; node < size; node++) {
var prevSize = this.sizes[layer - 1];
this.weights[layer][node] = randos(prevSize);
this.changes[layer][node] = zeros(prevSize);
}
}
}
},
run: function(input) {
if (this.inputLookup) {
input = lookup.toArray(this.inputLookup, input);
}
var output = this.runInput(input);
if (this.outputLookup) {
output = lookup.toHash(this.outputLookup, output);
}
return output;
},
runInput: function(input) {
this.outputs[0] = input; // set output state of input layer
for (var layer = 1; layer <= this.outputLayer; layer++) {
for (var node = 0; node < this.sizes[layer]; node++) {
var weights = this.weights[layer][node];
var sum = this.biases[layer][node];
for (var k = 0; k < weights.length; k++) {
sum += weights[k] * input[k];
}
this.outputs[layer][node] = 1 / (1 + Math.exp(-sum));
}
var output = input = this.outputs[layer];
}
return output;
},
train: function(data, options) {
data = this.formatData(data);
options = options || {};
var iterations = options.iterations || 20000;
var errorThresh = options.errorThresh || 0.005;
var log = options.log || false;
var logPeriod = options.logPeriod || 10;
var callback = options.callback;
var callbackPeriod = options.callbackPeriod || 10;
var inputSize = data[0].input.length;
var outputSize = data[0].output.length;
var hiddenSizes = this.hiddenSizes;
if (!hiddenSizes) {
hiddenSizes = [Math.max(3, Math.floor(inputSize / 2))];
}
var sizes = _([inputSize, hiddenSizes, outputSize]).flatten();
this.initialize(sizes);
var error = 1;
for (var i = 0; i < iterations && error > errorThresh; i++) {
var sum = 0;
for (var j = 0; j < data.length; j++) {
var err = this.trainPattern(data[j].input, data[j].output);
sum += err;
}
error = sum / data.length;
if (log && (i % logPeriod == 0)) {
console.log("iterations:", i, "training error:", error);
}
if (callback && (i % callbackPeriod == 0)) {
callback({ error: error, iterations: i });
}
}
return {
error: error,
iterations: i
};
},
trainPattern : function(input, target) {
// forward propogate
this.runInput(input);
// back propogate
this.calculateDeltas(target);
this.adjustWeights();
var error = mse(this.errors[this.outputLayer]);
return error;
},
calculateDeltas: function(target) {
for (var layer = this.outputLayer; layer >= 0; layer--) {
for (var node = 0; node < this.sizes[layer]; node++) {
var output = this.outputs[layer][node];
var error = 0;
if (layer == this.outputLayer) {
error = target[node] - output;
}
else {
var deltas = this.deltas[layer + 1];
for (var k = 0; k < deltas.length; k++) {
error += deltas[k] * this.weights[layer + 1][k][node];
}
}
this.errors[layer][node] = error;
this.deltas[layer][node] = error * output * (1 - output);
}
}
},
adjustWeights: function() {
for (var layer = 1; layer <= this.outputLayer; layer++) {
var incoming = this.outputs[layer - 1];
for (var node = 0; node < this.sizes[layer]; node++) {
var delta = this.deltas[layer][node];
for (var k = 0; k < incoming.length; k++) {
var change = this.changes[layer][node][k];
change = (this.learningRate * delta * incoming[k])
+ (this.momentum * change);
this.changes[layer][node][k] = change;
this.weights[layer][node][k] += change;
}
this.biases[layer][node] += this.learningRate * delta;
}
}
},
formatData: function(data) {
// turn sparse hash input into arrays with 0s as filler
if (!_(data[0].input).isArray()) {
if (!this.inputLookup) {
this.inputLookup = lookup.buildLookup(_(data).pluck("input"));
}
data = data.map(function(datum) {
var array = lookup.toArray(this.inputLookup, datum.input)
return _(_(datum).clone()).extend({ input: array });
}, this);
}
if (!_(data[0].output).isArray()) {
if (!this.outputLookup) {
this.outputLookup = lookup.buildLookup(_(data).pluck("output"));
}
data = data.map(function(datum) {
var array = lookup.toArray(this.outputLookup, datum.output);
return _(_(datum).clone()).extend({ output: array });
}, this);
}
return data;
},
test : function(data, binaryThresh) {
data = this.formatData(data);
binaryThresh = binaryThresh || 0.5;
// for binary classification problems with one output node
var isBinary = data[0].output.length == 1;
var falsePos = 0,
falseNeg = 0,
truePos = 0,
trueNeg = 0;
// for classification problems
var misclasses = [];
// run each pattern through the trained network and collect
// error and misclassification statistics
var sum = 0;
for (var i = 0; i < data.length; i++) {
var output = this.runInput(data[i].input);
var target = data[i].output;
var actual, expected;
if (isBinary) {
actual = output[0] > binaryThresh ? 1 : 0;
expected = target[0];
}
else {
actual = output.indexOf(_(output).max());
expected = target.indexOf(_(target).max());
}
if (actual != expected) {
var misclass = data[i];
_(misclass).extend({
actual: actual,
expected: expected
})
misclasses.push(misclass);
}
if (isBinary) {
if (actual == 0 && expected == 0) {
trueNeg++;
}
else if (actual == 1 && expected == 1) {
truePos++;
}
else if (actual == 0 && expected == 1) {
falseNeg++;
}
else if (actual == 1 && expected == 0) {
falsePos++;
}
}
var errors = output.map(function(value, i) {
return target[i] - value;
});
sum += mse(errors);
}
var error = sum / data.length;
var stats = {
error: error,
misclasses: misclasses
};
if (isBinary) {
_(stats).extend({
trueNeg: trueNeg,
truePos: truePos,
falseNeg: falseNeg,
falsePos: falsePos,
total: data.length,
precision: truePos / (truePos + falsePos),
recall: truePos / (truePos + falseNeg),
accuracy: (trueNeg + truePos) / data.length
})
}
return stats;
},
toJSON: function() {
/* make json look like:
{
layers: [
{ x: {},
y: {}},
{'0': {bias: -0.98771313, weights: {x: 0.8374838, y: 1.245858},
'1': {bias: 3.48192004, weights: {x: 1.7825821, y: -2.67899}}},
{ f: {bias: 0.27205739, weights: {'0': 1.3161821, '1': 2.00436}}}
]
}
*/
var layers = [];
for (var layer = 0; layer <= this.outputLayer; layer++) {
layers[layer] = {};
var nodes;
// turn any internal arrays back into hashes for readable json
if (layer == 0 && this.inputLookup) {
nodes = _(this.inputLookup).keys();
}
else if (layer == this.outputLayer && this.outputLookup) {
nodes = _(this.outputLookup).keys();
}
else {
nodes = _.range(0, this.sizes[layer]);
}
for (var j = 0; j < nodes.length; j++) {
var node = nodes[j];
layers[layer][node] = {};
if (layer > 0) {
layers[layer][node].bias = this.biases[layer][j];
layers[layer][node].weights = {};
for (var k in layers[layer - 1]) {
var index = k;
if (layer == 1 && this.inputLookup) {
index = this.inputLookup[k];
}
layers[layer][node].weights[k] = this.weights[layer][j][index];
}
}
}
}
return { layers: layers };
},
fromJSON: function(json) {
var size = json.layers.length;
this.outputLayer = size - 1;
this.sizes = new Array(size);
this.weights = new Array(size);
this.biases = new Array(size);
this.outputs = new Array(size);
for (var i = 0; i <= this.outputLayer; i++) {
var layer = json.layers[i];
if (i == 0 && !layer[0]) {
this.inputLookup = lookup.lookupFromHash(layer);
}
else if (i == this.outputLayer && !layer[0]) {
this.outputLookup = lookup.lookupFromHash(layer);
}
var nodes = _(layer).keys();
this.sizes[i] = nodes.length;
this.weights[i] = [];
this.biases[i] = [];
this.outputs[i] = [];
for (var j in nodes) {
var node = nodes[j];
this.biases[i][j] = layer[node].bias;
this.weights[i][j] = _(layer[node].weights).toArray();
}
}
return this;
},
toFunction: function() {
var json = this.toJSON();
// return standalone function that mimics run()
return new Function("inputs",
' var net = ' + JSON.stringify(json) + ';\n\n\
for(var i = 1; i < net.layers.length; i++) {\n\
var layer = net.layers[i];\n\
var outputs = {};\n\
for(var id in layer) {\n\
var node = layer[id];\n\
var sum = node.bias;\n\
for(var iid in node.weights)\n\
sum += node.weights[iid] * inputs[iid];\n\
outputs[id] = (1/(1 + Math.exp(-sum)));\n\
}\n\
inputs = outputs;\n\
}\n\
return outputs;');
}
}
function randomWeight() {
return Math.random() * 0.4 - 0.2;
}
function zeros(size) {
var array = new Array(size);
for (var i = 0; i < size; i++) {
array[i] = 0;
}
return array;
}
function randos(size) {
var array = new Array(size);
for (var i = 0; i < size; i++) {
array[i] = randomWeight();
}
return array;
}
function mse(errors) {
// mean squared error
var sum = 0;
for (var i = 0; i < errors.length; i++) {
sum += Math.pow(errors[i], 2);
}
return sum / errors.length;
}
exports.NeuralNetwork = NeuralNetwork;
});require.register("lookup.js", function(module, exports, require, global){
var _ = require("underscore");
/* Functions for turning sparse hashes into arrays and vice versa */
function buildLookup(hashes) {
// [{a: 1}, {b: 6, c: 7}] -> {a: 0, b: 1, c: 2}
var hash = _(hashes).reduce(function(memo, hash) {
return _(memo).extend(hash);
}, {});
return lookupFromHash(hash);
}
function lookupFromHash(hash) {
// {a: 6, b: 7} -> {a: 0, b: 1}
var lookup = {};
var index = 0;
for (var i in hash) {
lookup[i] = index++;
}
return lookup;
}
function toArray(lookup, hash) {
// {a: 0, b: 1}, {a: 6} -> [6, 0]
var array = [];
for (var i in lookup) {
array[lookup[i]] = hash[i] || 0;
}
return array;
}
function toHash(lookup, array) {
// {a: 0, b: 1}, [6, 7] -> {a: 6, b: 7}
var hash = {};
for (var i in lookup) {
hash[i] = array[lookup[i]];
}
return hash;
}
module.exports = {
buildLookup: buildLookup,
lookupFromHash: lookupFromHash,
toArray: toArray,
toHash: toHash
};
});require.register("underscore", function(module, exports, require, global){
// Underscore.js 1.3.3
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// 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;
// Create quick reference variables for speed access to core prototypes.
var slice = ArrayProto.slice,
unshift = ArrayProto.unshift,
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;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) { return new wrapper(obj); };
// 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.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root['_'] = _;
}
// Current version.
_.VERSION = '1.3.3';
// 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;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
// 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[results.length] = iterator.call(context, value, index, list);
});
if (obj.length === +obj.length) results.length = obj.length;
return results;
};
// **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);
}
});
if (!initial) throw new TypeError('Reduce of empty array with no initial value');
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 reversed = _.toArray(obj).reverse();
if (context && !initial) iterator = _.bind(iterator, context);
return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
};
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
var result;
any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// 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, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
var results = [];
if (obj == null) return results;
each(obj, function(value, index, list) {
if (!iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// 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, iterator, context) {
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
// 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, iterator, context) {
iterator || (iterator = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
// Determine if a given value is included in the array or object using `===`.
// Aliased as `contains`.
_.include = _.contains = function(obj, target) {
var found = false;
if (obj == null) return found;
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
found = any(obj, function(value) {
return value === target;
});
return found;
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
return _.map(obj, function(value) {
return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
// Return the maximum element or (element-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.max.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Return the minimum element (or element-based computation).
_.min = function(obj, iterator, context) {
if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.min.apply(Math, obj);
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Shuffle an array.
_.shuffle = function(obj) {
var shuffled = [], rand;
each(obj, function(value, index, list) {
rand = Math.floor(Math.random() * (index + 1));
shuffled[index] = shuffled[rand];
shuffled[rand] = value;
});
return shuffled;
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, val, context) {
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
if (a === void 0) return 1;
if (b === void 0) return -1;
return a < b ? -1 : a > b ? 1 : 0;
}), 'value');
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, val) {
var result = {};
var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
each(obj, function(value, index) {
var key = iterator(value, index);
(result[key] || (result[key] = [])).push(value);
});
return result;
};
// Use a comparator function to figure out at what index an object should
// be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator) {
iterator || (iterator = _.identity);
var low = 0, high = array.length;
while (low < high) {
var mid = (low + high) >> 1;
iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
}
return low;
};
// Safely convert anything iterable into a real, live array.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (_.isArguments(obj)) return slice.call(obj);
if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray();
return _.values(obj);
};
// Return the number of elements in an object.
_.size = function(obj) {
return _.isArray(obj) ? obj.length : _.keys(obj).length;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head` and `take`. The **guard** check
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// Returns everything but the last entry of the array. Especcialy 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`.
_.initial = function(array, n, guard) {
return slice.call(array, 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`.
_.last = function(array, n, guard) {
if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0));
} else {
return array[array.length - 1];
}
};
// Returns everything but the first entry of the array. Aliased as `tail`.
// Especially useful on the arguments object. Passing an **index** will return
// the rest of the values in the array from that index onward. The **guard**
// check allows it to work with `_.map`.
_.rest = _.tail = function(array, index, guard) {
return slice.call(array, (index == null) || guard ? 1 : index);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, function(value){ return !!value; });
};
// Return a completely flattened version of an array.
_.flatten = function(array, shallow) {
return _.reduce(array, function(memo, value) {
if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
memo[memo.length] = value;
return memo;
}, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// 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) {
var initial = iterator ? _.map(array, iterator) : array;
var results = [];
// The `isSorted` flag is irrelevant if the array only contains two elements.
if (array.length < 3) isSorted = true;
_.reduce(initial, function (memo, value, index) {
if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {
memo.push(value);
results.push(array[index]);
}
return memo;
}, []);
return results;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(_.flatten(arguments, true));
};
// Produce an array that contains every item shared between all the
// passed-in arrays. (Aliased as "intersect" for back-compat.)
_.intersection = _.intersect = function(array) {
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0;
});
});
};
// 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 = _.flatten(slice.call(arguments, 1), true);
return _.filter(array, function(value){ return !_.include(rest, value); });
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
return results;
};
// 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.
// 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, l;
if (isSorted) {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
return -1;
};
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
_.lastIndexOf = function(array, item) {
if (array == null) return -1;
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
var i = array.length;
while (i--) if (i in array && array[i] === item) return i;
return -1;
};
// 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).
_.range = function(start, stop, step) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while(idx < len) {
range[idx++] = start;
start += step;
}
return range;
};
// Function (ahem) Functions
// ------------------
// Reusable constructor function for prototype setting.
var ctor = function(){};
// Create a function bound to a given object (assigning `this`, and arguments,
// optionally). Binding with arguments is also known as `curry`.
// Delegates to **ECMAScript 5**'s native `Function.bind` if available.
// We check for `func.bind` first, to fail fast when `func` is undefined.
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && 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;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
// Bind all of an object's methods to that object. 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) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], 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));
};
};
// 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);
};
// 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)));
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var context, args, timeout, throttling, more, result;
var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
return function() {
context = this; args = arguments;
var later = function() {
timeout = null;
if (more) func.apply(context, args);
whenDone();
};
if (!timeout) timeout = setTimeout(later, wait);
if (throttling) {
more = true;
} else {
result = func.apply(context, args);
}
whenDone();
throttling = true;
return result;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
if (immediate && !timeout) func.apply(context, args);
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
// 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;
return memo = func.apply(this, arguments);
};
};
// 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.
_.wrap = function(func, wrapper) {
return function() {
var args = [func].concat(slice.call(arguments, 0));
return wrapper.apply(this, args);
};
};
// 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];
};
};
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
if (times <= 0) return func();
return function() {
if (--times < 1) { return func.apply(this, arguments); }
};
};
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
return _.map(obj, _.identity);
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// Extend a given object with all the properties in passed-in object(s).
_.extend = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
obj[prop] = source[prop];
}
});
return obj;
};
// Return a copy of the object only containing the whitelisted properties.
_.pick = function(obj) {
var result = {};
each(_.flatten(slice.call(arguments, 1)), function(key) {
if (key in obj) result[key] = obj[key];
});
return result;
};
// Fill in a given object with default properties.
_.defaults = function(obj) {
each(slice.call(arguments, 1), function(source) {
for (var prop in source) {
if (obj[prop] == null) obj[prop] = source[prop];
}
});
return obj;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// Internal recursive comparison function.
function eq(a, b, stack) {
// 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;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
if (a._chain) a = a._wrapped;
if (b._chain) b = b._wrapped;
// Invoke a custom `isEqual` method if one is provided.
if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(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);
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;
}
if (typeof a != 'object' || typeof b != 'object') 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`.
var length = stack.length;
while (length--) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if (stack[length] == a) return true;
}
// Add the first object to the stack of traversed objects.
stack.push(a);
var size = 0, result = true;
// Recursively compare objects and arrays.
if (className == '[object Array]') {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
// Ensure commutative equality for sparse arrays.
if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
}
}
} else {
// Objects with different constructors are not equivalent.
if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
// 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], stack))) 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;
}
}
// Remove the first object from the stack of traversed objects.
stack.pop();
return result;
}
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(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;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType == 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
// Is a given variable an arguments object?
_.isArguments = function(obj) {
return toString.call(obj) == '[object Arguments]';
};
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
};
}
// Is a given value a function?
_.isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
};
// Is a given value a string?
_.isString = function(obj) {
return toString.call(obj) == '[object String]';
};
// Is a given value a number?
_.isNumber = function(obj) {
return toString.call(obj) == '[object Number]';
};
// Is a given object a finite number?
_.isFinite = function(obj) {
return _.isNumber(obj) && isFinite(obj);
};
// Is the given value `NaN`?
_.isNaN = function(obj) {
// `NaN` is the only value for which `===` is not reflexive.
return obj !== obj;
};
// Is a given value a boolean?
_.isBoolean = function(obj) {
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
};
// Is a given value a date?
_.isDate = function(obj) {
return toString.call(obj) == '[object Date]';
};
// Is the given value a regular expression?
_.isRegExp = function(obj) {
return toString.call(obj) == '[object RegExp]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// Has own property?
_.has = function(obj, key) {
return hasOwnProperty.call(obj, key);
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iterators.
_.identity = function(value) {
return value;
};
// Run a function **n** times.
_.times = function (n, iterator, context) {
for (var i = 0; i < n; i++) iterator.call(context, i);
};
// Escape a string for HTML interpolation.
_.escape = function(string) {
return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
};
// If the value of the named property is a function then invoke it;
// otherwise, return it.
_.result = function(object, property) {
if (object == null) return null;
var value = object[property];
return _.isFunction(value) ? value.call(object) : value;
};
// Add your own custom functions to the Underscore object, ensuring that
// they're correctly added to the OOP wrapper as well.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
addToWrapper(name, _[name] = obj[name]);
});
};
// Generate a unique integer id (unique within the entire client session).
// Useful for temporary DOM ids.
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = idCounter++;
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /.^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
'\\': '\\',
"'": "'",
'r': '\r',
'n': '\n',
't': '\t',
'u2028': '\u2028',
'u2029': '\u2029'
};
for (var p in escapes) escapes[escapes[p]] = p;
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
// Within an interpolation, evaluation, or escaping, remove HTML escaping
// that had been previously added.
var unescape = function(code) {
return code.replace(unescaper, function(match, escape) {
return escapes[escape];
});
};
// 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) {
settings = _.defaults(settings || {}, _.templateSettings);
// Compile the template source, taking care to escape characters that
// cannot be included in a string literal and then unescape them in code
// blocks.
var source = "__p+='" + text
.replace(escaper, function(match) {
return '\\' + escapes[match];
})
.replace(settings.escape || noMatch, function(match, code) {
return "'+\n_.escape(" + unescape(code) + ")+\n'";
})
.replace(settings.interpolate || noMatch, function(match, code) {
return "'+\n(" + unescape(code) + ")+\n'";
})
.replace(settings.evaluate || noMatch, function(match, code) {
return "';\n" + unescape(code) + "\n;__p+='";
}) + "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __p='';" +
"var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" +
source + "return __p;\n";
var render = new Function(settings.variable || 'obj', '_', source);
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for build time
// precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' +
source + '}';
return template;
};
// Add a "chain" function, which will delegate to the wrapper.
_.chain = function(obj) {
return _(obj).chain();
};
// The OOP Wrapper
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
// Expose `wrapper.prototype` as `_.prototype`
_.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};
// A method to easily add functions to the OOP wrapper.
var addToWrapper = function(name, func) {
wrapper.prototype[name] = function() {
var args = slice.call(arguments);
unshift.call(args, this._wrapped);
return result(func.apply(_, args), this._chain);
};
};
// 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) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
var wrapped = this._wrapped;
method.apply(wrapped, arguments);
var length = wrapped.length;
if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
return result(wrapped, this._chain);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});
// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};
// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
}).call(this);
});brain = require('neuralnetwork.js');
})();
var brain = (function() {var require = function (file, cwd) {
var resolved = require.resolve(file, cwd || '/');
var mod = require.modules[resolved];
if (!mod) throw new Error(
'Failed to resolve module ' + file + ', tried ' + resolved
);
var cached = require.cache[resolved];
var res = cached? cached.exports : mod();
return res;
};
require.paths = [];
require.modules = {};
require.cache = {};
require.extensions = [".js",".coffee",".json"];
require._core = {
'assert': true,
'events': true,
'fs': true,
'path': true,
'vm': true
};
require.resolve = (function () {
return function (x, cwd) {
if (!cwd) cwd = '/';
if (require._core[x]) return x;
var path = require.modules.path();
cwd = path.resolve('/', cwd);
var y = cwd || '/';
if (x.match(/^(?:\.\.?\/|\/)/)) {
var m = loadAsFileSync(path.resolve(y, x))
|| loadAsDirectorySync(path.resolve(y, x));
if (m) return m;
}
var n = loadNodeModulesSync(x, y);
if (n) return n;
throw new Error("Cannot find module '" + x + "'");
function loadAsFileSync (x) {
x = path.normalize(x);
if (require.modules[x]) {
return x;
}
for (var i = 0; i < require.extensions.length; i++) {
var ext = require.extensions[i];
if (require.modules[x + ext]) return x + ext;
}
}
function loadAsDirectorySync (x) {
x = x.replace(/\/+$/, '');
var pkgfile = path.normalize(x + '/package.json');
if (require.modules[pkgfile]) {
var pkg = require.modules[pkgfile]();
var b = pkg.browserify;
if (typeof b === 'object' && b.main) {
var m = loadAsFileSync(path.resolve(x, b.main));
if (m) return m;
}
else if (typeof b === 'string') {
var m = loadAsFileSync(path.resolve(x, b));
if (m) return m;
}
else if (pkg.main) {
var m = loadAsFileSync(path.resolve(x, pkg.main));
if (m) return m;
}
}
return loadAsFileSync(x + '/index');
}
function loadNodeModulesSync (x, start) {
var dirs = nodeModulesPathsSync(start);
for (var i = 0; i < dirs.length; i++) {
var dir = dirs[i];
var m = loadAsFileSync(dir + '/' + x);
if (m) return m;
var n = loadAsDirectorySync(dir + '/' + x);
if (n) return n;
}
var m = loadAsFileSync(x);
if (m) return m;
}
function nodeModulesPathsSync (start) {
var parts;
if (start === '/') parts = [ '' ];
else parts = path.normalize(start).split('/');
var dirs = [];
for (var i = parts.length - 1; i >= 0; i--) {
if (parts[i] === 'node_modules') continue;
var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
dirs.push(dir);
}
return dirs;
}
};
})();
require.alias = function (from, to) {
var path = require.modules.path();
var res = null;
try {
res = require.resolve(from + '/package.json', '/');
}
catch (err) {
res = require.resolve(from, '/');
}
var basedir = path.dirname(res);
var keys = (Object.keys || function (obj) {
var res = [];
for (var key in obj) res.push(key);
return res;
})(require.modules);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key.slice(0, basedir.length + 1) === basedir + '/') {
var f = key.slice(basedir.length);
require.modules[to + f] = require.modules[basedir + f];
}
else if (key === basedir) {
require.modules[to] = require.modules[basedir];
}
}
};
(function () {
var process = {};
var global = typeof window !== 'undefined' ? window : {};
var definedProcess = false;
require.define = function (filename, fn) {
if (!definedProcess && require.modules.__browserify_process) {
process = require.modules.__browserify_process();
definedProcess = true;
}
var dirname = require._core[filename]
? ''
: require.modules.path().dirname(filename)
;
var require_ = function (file) {
var requiredModule = require(file, dirname);
var cached = require.cache[require.resolve(file, dirname)];
if (cached && cached.parent === null) {
cached.parent = module_;
}
return requiredModule;
};
require_.resolve = function (name) {
return require.resolve(name, dirname);
};
require_.modules = require.modules;
require_.define = require.define;
require_.cache = require.cache;
var module_ = {
id : filename,
filename: filename,
exports : {},
loaded : false,
parent: null
};
require.modules[filename] = function () {
require.cache[filename] = module_;
fn.call(
module_.exports,
require_,
module_,
module_.exports,
dirname,
filename,
process,
global
);
module_.loaded = true;
return module_.exports;
};
};
})();
require.define("path",function(require,module,exports,__dirname,__filename,process,global){function filter (xs, fn) {
var res = [];
for (var i = 0; i < xs.length; i++) {
if (fn(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Regex to split a filename into [*, dir, basename, ext]
// posix version
var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0)
? arguments[i]
: process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
return p && typeof p === 'string';
}).join('/'));
};
exports.dirname = function(path) {
var dir = splitPathRe.exec(path)[1] || '';
var isWindows = false;
if (!dir) {
// No dirname
return '.';
} else if (dir.length === 1 ||
(isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
// It is just a slash or a drive letter with a slash
return dir;
} else {
// It is a full dirname, strip trailing slash
return dir.substring(0, dir.length - 1);
}
};
exports.basename = function(path, ext) {
var f = splitPathRe.exec(path)[2] || '';
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPathRe.exec(path)[3] || '';
};
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
});
require.define("__browserify_process",function(require,module,exports,__dirname,__filename,process,global){var process = module.exports = {};
process.nextTick = (function () {
var canSetImmediate = typeof window !== 'undefined'
&& window.setImmediate;
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canSetImmediate) {
return function (f) { return window.setImmediate(f) };
}
if (canPost) {
var queue = [];
window.addEventListener('message', function (ev) {
if (ev.source === window && ev.data === 'browserify-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
return function nextTick(fn) {
queue.push(fn);
window.postMessage('browserify-tick', '*');
};
}
return function nextTick(fn) {
setTimeout(fn, 0);
};
})();
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.binding = function (name) {
if (name === 'evals') return (require)('vm')
else throw new Error('No such module. (Possibly not yet loaded)')
};
(function () {
var cwd = '/';
var path;
process.cwd = function () { return cwd };
process.chdir = function (dir) {
if (!path) path = require('path');
cwd = path.resolve(dir, cwd);
};
})();
});
require.define("/package.json",function(require,module,exports,__dirname,__filename,process,global){module.exports = {"main":"underscore.js"}
});
require.define("/node_modules/underscore/index.js",function(require,module,exports,__dirname,__filename,process,global){// Underscore.js 1.4.4
// http://underscorejs.org
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore may be freely distributed under the MIT license.
(function() {
// Baseline setup
// --------------
// Establish the root object, `window` in the browser, or `global` on the server.
var root = this;
// 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;
// Create quick reference variables for speed access to core prototypes.
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;
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
this._wrapped = obj;
};
// 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.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}
// Current version.
_.VERSION = '1.4.4';
// 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;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
};
// 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[results.length] = iterator.call(context, value, index, list);
});
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);
}
});
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);
}
});
if (!initial) throw new TypeError(reduceError);
return memo;
};
// Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) {
var result;
any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) {
result = value;
return true;
}
});
return result;
};
// 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, iterator, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results[results.length] = value;
});
return results;
};
// Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) {
return _.filter(obj, function(value, index, list) {
return !iterator.call(context, value, index, list);
}, 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, iterator, context) {
iterator || (iterator = _.identity);
var result = true;
if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
// 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, iterator, context) {
iterator || (iterator = _.identity);
var result = false;
if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker;
});
return !!result;
};
// 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;
});
};
// Invoke a method (with arguments) on every item in a collection.
_.invoke = function(obj, method) {
var args = slice.call(arguments, 2);
var isFunc = _.isFunction(method);
return _.map(obj, function(value) {
return (isFunc ? method : value[method]).apply(value, args);
});
};
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; });
};
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
_.where = function(obj, attrs, first) {
if (_.isEmpty(attrs)) return first ? null : [];
return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) {
if (attrs[key] !== value[key]) return false;
}
return true;
});
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
return _.where(obj, attrs, true);
};
// Return the maximum element or (element-based computation).
// Can't optimize arrays of integers longer than 65,535 elements.
// See: 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);
}
if (!iterator && _.isEmpty(obj)) return -Infinity;
var result = {computed : -Infinity, value: -Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed >= result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// 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);
}
if (!iterator && _.isEmpty(obj)) return Infinity;
var result = {computed : Infinity, value: Infinity};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed});
});
return result.value;
};
// Shuffle an array.
_.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;
});
return shuffled;
};
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
return _.isFunction(value) ? value : function(obj){ return obj[value]; };
};
// Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, value, context) {
var iterator = lookupIterator(value);
return _.pluck(_.map(obj, function(value, index, list) {
return {
value : value,
index : index,
criteria : iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
var b = right.criteria;
if (a !== b) {
if (a > b || a === void 0) return 1;
if (a < b || b === void 0) return -1;
}
return left.index < right.index ? -1 : 1;
}), 'value');
};
// An internal function used for aggregate "group by" operations.
var group = function(obj, value, context, behavior) {
var result = {};
var iterator = lookupIterator(value || _.identity);
each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj);
behavior(result, key, value);
});
return result;
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
_.groupBy = function(obj, value, context) {
return group(obj, value, context, function(result, key, value) {
(_.has(result, key) ? result[key] : (result[key] = [])).push(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 = function(obj, value, context) {
return group(obj, value, context, function(result, key) {
if (!_.has(result, key)) result[key] = 0;
result[key]++;
});
};
// 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 = iterator == null ? _.identity : 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 convert anything iterable into a real, live array.
_.toArray = function(obj) {
if (!obj) return [];
if (_.isArray(obj)) return slice.call(obj);
if (obj.length === +obj.length) 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;
};
// Array Functions
// ---------------
// Get the first element of an array. Passing **n** will return the first N
// values in the array. Aliased as `head` and `take`. The **guard** check
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
};
// 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`.
_.initial = function(array, n, guard) {
return slice.call(array, 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`.
_.last = function(array, n, guard) {
if (array == null) return void 0;
if ((n != null) && !guard) {
return slice.call(array, Math.max(array.length - n, 0));
} else {
return array[array.length - 1];
}
};
// 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`.
_.rest = _.tail = _.drop = function(array, n, guard) {
return slice.call(array, (n == null) || guard ? 1 : n);
};
// Trim out all falsy values from an array.
_.compact = function(array) {
return _.filter(array, _.identity);
};
// Internal implementation of a recursive `flatten` function.
var flatten = function(input, shallow, output) {
each(input, function(value) {
if (_.isArray(value)) {
shallow ? push.apply(output, value) : flatten(value, shallow, output);
} else {
output.push(value);
}
});
return output;
};
// Return a completely flattened version of an array.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
};
// Return a version of the array that does not contain the specified value(s).
_.without = function(array) {
return _.difference(array, slice.call(arguments, 1));
};
// 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;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array;
var results = [];
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]);
}
});
return results;
};
// Produce an array that contains the union: each distinct element from all of
// the passed-in arrays.
_.union = function() {
return _.uniq(concat.apply(ArrayProto, arguments));
};
// 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 _.indexOf(other, item) >= 0;
});
});
};
// 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); });
};
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
var args = slice.call(arguments);
var length = _.max(_.pluck(args, 'length'));
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(args, "" + i);
}
return results;
};
// 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, l = list.length; i < l; i++) {
if (values) {
result[list[i]] = values[i];
} else {
result[list[i][0]] = list[i][1];
}
}
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.
// 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, l = array.length;
if (isSorted) {
if (typeof isSorted == 'number') {
i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
} else {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
for (; i < l; 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 i = (hasIndex ? from : array.length);
while (i--) if (array[i] === item) return i;
return -1;
};
// 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).
_.range = function(start, stop, step) {
if (arguments.length <= 1) {
stop = start || 0;
start = 0;
}
step = arguments[2] || 1;
var len = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
var range = new Array(len);
while(idx < len) {
range[idx++] = start;
start += step;
}
return range;
};
// Function (ahem) Functions
// ------------------
// 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) {
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
var args = slice.call(arguments, 2);
return function() {
return func.apply(context, args.concat(slice.call(arguments)));
};
};
// Partially apply a function by creating a version that has had some of its
// arguments pre-filled, without changing its dynamic `this` context.
_.partial = function(func) {
var args = slice.call(arguments, 1);
return function() {
return func.apply(this, args.concat(slice.call(arguments)));
};
};
// Bind all of an object's methods to that object. 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) funcs = _.functions(obj);
each(funcs, function(f) { obj[f] = _.bind(obj[f], 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));
};
};
// 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);
};
// 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)));
};
// Returns a function, that, when invoked, will only be triggered at most once
// during a given window of time.
_.throttle = function(func, wait) {
var context, args, timeout, result;
var previous = 0;
var later = function() {
previous = new Date;
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = new Date;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
return result;
};
};
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout, result;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) result = func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(context, args);
return result;
};
};
// 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.
_.wrap = function(func, wrapper) {
return function() {
var args = [func];
push.apply(args, arguments);
return wrapper.apply(this, args);
};
};
// 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];
};
};
// Returns a function that will only be executed after being called N times.
_.after = function(times, func) {
if (times <= 0) return func();
return function() {
if (--times < 1) {
return func.apply(this, arguments);
}
};
};
// Object Functions
// ----------------
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
return keys;
};
// Retrieve the values of an object's properties.
_.values = function(obj) {
var values = [];
for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
return values;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
var pairs = [];
for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
return pairs;
};
// Invert the keys and values of an object. The values must be serializable.
_.invert = function(obj) {
var result = {};
for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
return result;
};
// Return a sorted list of the function names available on the object.
// Aliased as `methods`
_.functions = _.methods = function(obj) {
var names = [];
for (var key in obj) {
if (_.isFunction(obj[key])) names.push(key);
}
return names.sort();
};
// 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];
}
}
});
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;
};
// 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];
}
return copy;
};
// 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] == null) obj[prop] = source[prop];
}
}
});
return obj;
};
// Create a (shallow-cloned) duplicate of an object.
_.clone = function(obj) {
if (!_.isObject(obj)) return obj;
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
};
// Invokes interceptor with the obj, and then returns obj.
// The primary purpose of this method is to "tap into" a method chain, in
// order to perform operations on intermediate results within the chain.
_.tap = function(obj, interceptor) {
interceptor(obj);
return obj;
};
// 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;
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
if (a instanceof _) a = a._wrapped;
if (b instanceof _) b = b._wrapped;
// Compare `[[Class]]` names.
var className = toString.call(a);
if (className != toString.call(b)) return false;
switch (className) {
// Strings, numbers, dates, and booleans are compared by value.
case '[object String]':
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String(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);
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;
}
if (typeof a != 'object' || typeof b != 'object') 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`.
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;
}
// 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]') {
// Compare array lengths to determine if a deep comparison is necessary.
size = a.length;
result = size == b.length;
if (result) {
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
}
}
} else {
// 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))) {
return false;
}
// 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;
}
}
// Remove the first object from the stack of traversed objects.
aStack.pop();
bStack.pop();
return result;
};
// Perform a deep comparison to check if two objects are equal.
_.isEqual = function(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;
};
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType === 1);
};
// Is a given value an array?
// Delegates to ECMA5's native Array.isArray
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
// Is a given variable an object?
_.isObject = function(obj) {
return obj === Object(obj);
};
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
_['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
};
});
// Define a fallback version of the method in browsers (ahem, IE), where
// there isn't any inspectable "Arguments" type.
if (!_.isArguments(arguments)) {
_.isArguments = function(obj) {
return !!(obj && _.has(obj, 'callee'));
};
}
// Optimize `isFunction` if appropriate.
if (typeof (/./) !== 'function') {
_.isFunction = function(obj) {
return typeof obj === 'function';
};
}
// Is a given object a finite number?
_.isFinite = function(obj) {
return isFinite(obj) && !isNaN(parseFloat(obj));
};
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
_.isNaN = function(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]';
};
// Is a given value equal to null?
_.isNull = function(obj) {
return obj === null;
};
// Is a given variable undefined?
_.isUndefined = function(obj) {
return obj === void 0;
};
// 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);
};
// Utility Functions
// -----------------
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
// previous owner. Returns a reference to the Underscore object.
_.noConflict = function() {
root._ = previousUnderscore;
return this;
};
// Keep the identity function around for default iterators.
_.identity = function(value) {
return value;
};
// Run a function **n** times.
_.times = function(n, iterator, context) {
var accum = Array(n);
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
return accum;
};
// Return a random integer between min and max (inclusive).
_.random = function(min, max) {
if (max == null) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min + 1));
};
// List of HTML entities for escaping.
var entityMap = {
escape: {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;',
'/': '&#x2F;'
}
};
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')
};
// 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];
});
};
});
// If the value of the named property is a function then invoke it;
// otherwise, return it.
_.result = function(object, property) {
if (object == null) return null;
var value = object[property];
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;
_.uniqueId = function(prefix) {
var id = ++idCounter + '';
return prefix ? prefix + id : id;
};
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
// 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;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
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]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
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 + '}';
return template;
};
// Add a "chain" function, which will delegate to the wrapper.
_.chain = function(obj) {
return _(obj).chain();
};
// OOP
// ---------------
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
// Helper function to continue chaining intermediate results.
var result = function(obj) {
return this._chain ? _(obj).chain() : obj;
};
// 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) {
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);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
_.prototype[name] = function() {
return result.call(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() {
return this._wrapped;
}
});
}).call(this);
});
return require('brain')})();
1,109c1,10
< var brain = (function() {var require = function (file, cwd) {
< var resolved = require.resolve(file, cwd || '/');
< var mod = require.modules[resolved];
< if (!mod) throw new Error(
< 'Failed to resolve module ' + file + ', tried ' + resolved
< );
< var cached = require.cache[resolved];
< var res = cached? cached.exports : mod();
< return res;
< };
<
< require.paths = [];
< require.modules = {};
< require.cache = {};
< require.extensions = [".js",".coffee",".json"];
<
< require._core = {
< 'assert': true,
< 'events': true,
< 'fs': true,
< 'path': true,
< 'vm': true
< };
<
< require.resolve = (function () {
< return function (x, cwd) {
< if (!cwd) cwd = '/';
<
< if (require._core[x]) return x;
< var path = require.modules.path();
< cwd = path.resolve('/', cwd);
< var y = cwd || '/';
<
< if (x.match(/^(?:\.\.?\/|\/)/)) {
< var m = loadAsFileSync(path.resolve(y, x))
< || loadAsDirectorySync(path.resolve(y, x));
< if (m) return m;
< }
<
< var n = loadNodeModulesSync(x, y);
< if (n) return n;
<
< throw new Error("Cannot find module '" + x + "'");
<
< function loadAsFileSync (x) {
< x = path.normalize(x);
< if (require.modules[x]) {
< return x;
< }
<
< for (var i = 0; i < require.extensions.length; i++) {
< var ext = require.extensions[i];
< if (require.modules[x + ext]) return x + ext;
< }
< }
<
< function loadAsDirectorySync (x) {
< x = x.replace(/\/+$/, '');
< var pkgfile = path.normalize(x + '/package.json');
< if (require.modules[pkgfile]) {
< var pkg = require.modules[pkgfile]();
< var b = pkg.browserify;
< if (typeof b === 'object' && b.main) {
< var m = loadAsFileSync(path.resolve(x, b.main));
< if (m) return m;
< }
< else if (typeof b === 'string') {
< var m = loadAsFileSync(path.resolve(x, b));
< if (m) return m;
< }
< else if (pkg.main) {
< var m = loadAsFileSync(path.resolve(x, pkg.main));
< if (m) return m;
< }
< }
<
< return loadAsFileSync(x + '/index');
< }
<
< function loadNodeModulesSync (x, start) {
< var dirs = nodeModulesPathsSync(start);
< for (var i = 0; i < dirs.length; i++) {
< var dir = dirs[i];
< var m = loadAsFileSync(dir + '/' + x);
< if (m) return m;
< var n = loadAsDirectorySync(dir + '/' + x);
< if (n) return n;
< }
<
< var m = loadAsFileSync(x);
< if (m) return m;
< }
<
< function nodeModulesPathsSync (start) {
< var parts;
< if (start === '/') parts = [ '' ];
< else parts = path.normalize(start).split('/');
<
< var dirs = [];
< for (var i = parts.length - 1; i >= 0; i--) {
< if (parts[i] === 'node_modules') continue;
< var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
< dirs.push(dir);
< }
<
< return dirs;
< }
< };
< })();
---
> (function(){var global = this;function debug(){return debug};function require(p, parent){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '" from ' + parent); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path), global); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('debug' == p) return debug; if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/'), parent); };};require.register("neuralnetwork.js", function(module, exports, require, global){
> var _ = require("underscore"),
> lookup = require("./lookup");
>
> var NeuralNetwork = function(options) {
> options = options || {};
> this.learningRate = options.learningRate || 0.3;
> this.momentum = options.momentum || 0.1;
> this.hiddenSizes = options.hiddenLayers;
> }
111,135c12,40
< require.alias = function (from, to) {
< var path = require.modules.path();
< var res = null;
< try {
< res = require.resolve(from + '/package.json', '/');
< }
< catch (err) {
< res = require.resolve(from, '/');
< }
< var basedir = path.dirname(res);
<
< var keys = (Object.keys || function (obj) {
< var res = [];
< for (var key in obj) res.push(key);
< return res;
< })(require.modules);
<
< for (var i = 0; i < keys.length; i++) {
< var key = keys[i];
< if (key.slice(0, basedir.length + 1) === basedir + '/') {
< var f = key.slice(basedir.length);
< require.modules[to + f] = require.modules[basedir + f];
< }
< else if (key === basedir) {
< require.modules[to] = require.modules[basedir];
---
> NeuralNetwork.prototype = {
> initialize: function(sizes) {
> this.sizes = sizes;
> this.outputLayer = this.sizes.length - 1;
>
> this.biases = []; // weights for bias nodes
> this.weights = [];
> this.outputs = [];
>
> // state for training
> this.deltas = [];
> this.changes = []; // for momentum
> this.errors = [];
>
> for (var layer = 0; layer <= this.outputLayer; layer++) {
> var size = this.sizes[layer];
> this.deltas[layer] = zeros(size);
> this.errors[layer] = zeros(size);
> this.outputs[layer] = zeros(size);
>
> if (layer > 0) {
> this.biases[layer] = randos(size);
> this.weights[layer] = new Array(size);
> this.changes[layer] = new Array(size);
>
> for (var node = 0; node < size; node++) {
> var prevSize = this.sizes[layer - 1];
> this.weights[layer][node] = randos(prevSize);
> this.changes[layer][node] = zeros(prevSize);
136a42
> }
138c44
< };
---
> },
140,158c46,49
< (function () {
< var process = {};
< var global = typeof window !== 'undefined' ? window : {};
< var definedProcess = false;
<
< require.define = function (filename, fn) {
< if (!definedProcess && require.modules.__browserify_process) {
< process = require.modules.__browserify_process();
< definedProcess = true;
< }
<
< var dirname = require._core[filename]
< ? ''
< : require.modules.path().dirname(filename)
< ;
<
< var require_ = function (file) {
< var requiredModule = require(file, dirname);
< var cached = require.cache[require.resolve(file, dirname)];
---
> run: function(input) {
> if (this.inputLookup) {
> input = lookup.toArray(this.inputLookup, input);
> }
160,162c51
< if (cached && cached.parent === null) {
< cached.parent = module_;
< }
---
> var output = this.runInput(input);
164,196c53,57
< return requiredModule;
< };
< require_.resolve = function (name) {
< return require.resolve(name, dirname);
< };
< require_.modules = require.modules;
< require_.define = require.define;
< require_.cache = require.cache;
< var module_ = {
< id : filename,
< filename: filename,
< exports : {},
< loaded : false,
< parent: null
< };
<
< require.modules[filename] = function () {
< require.cache[filename] = module_;
< fn.call(
< module_.exports,
< require_,
< module_,
< module_.exports,
< dirname,
< filename,
< process,
< global
< );
< module_.loaded = true;
< return module_.exports;
< };
< };
< })();
---
> if (this.outputLookup) {
> output = lookup.toHash(this.outputLookup, output);
> }
> return output;
> },
197a59,60
> runInput: function(input) {
> this.outputs[0] = input; // set output state of input layer
199,202c62,72
< require.define("path",function(require,module,exports,__dirname,__filename,process,global){function filter (xs, fn) {
< var res = [];
< for (var i = 0; i < xs.length; i++) {
< if (fn(xs[i], i, xs)) res.push(xs[i]);
---
> for (var layer = 1; layer <= this.outputLayer; layer++) {
> for (var node = 0; node < this.sizes[layer]; node++) {
> var weights = this.weights[layer][node];
>
> var sum = this.biases[layer][node];
> for (var k = 0; k < weights.length; k++) {
> sum += weights[k] * input[k];
> }
> this.outputs[layer][node] = 1 / (1 + Math.exp(-sum));
> }
> var output = input = this.outputs[layer];
204,205c74,75
< return res;
< }
---
> return output;
> },
207,225c77,78
< // resolves . and .. elements in a path array with directory names there
< // must be no slashes, empty elements, or device names (c:\) in the array
< // (so also no leading and trailing slashes - it does not distinguish
< // relative and absolute paths)
< function normalizeArray(parts, allowAboveRoot) {
< // if the path tries to go above the root, `up` ends up > 0
< var up = 0;
< for (var i = parts.length; i >= 0; i--) {
< var last = parts[i];
< if (last == '.') {
< parts.splice(i, 1);
< } else if (last === '..') {
< parts.splice(i, 1);
< up++;
< } else if (up) {
< parts.splice(i, 1);
< up--;
< }
< }
---
> train: function(data, options) {
> data = this.formatData(data);
227,232c80,86
< // if the path is allowed to go above the root, restore leading ..s
< if (allowAboveRoot) {
< for (; up--; up) {
< parts.unshift('..');
< }
< }
---
> options = options || {};
> var iterations = options.iterations || 20000;
> var errorThresh = options.errorThresh || 0.005;
> var log = options.log || false;
> var logPeriod = options.logPeriod || 10;
> var callback = options.callback;
> var callbackPeriod = options.callbackPeriod || 10;
234,235c88,89
< return parts;
< }
---
> var inputSize = data[0].input.length;
> var outputSize = data[0].output.length;
237,255c91,96
< // Regex to split a filename into [*, dir, basename, ext]
< // posix version
< var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
<
< // path.resolve([from ...], to)
< // posix version
< exports.resolve = function() {
< var resolvedPath = '',
< resolvedAbsolute = false;
<
< for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
< var path = (i >= 0)
< ? arguments[i]
< : process.cwd();
<
< // Skip empty and invalid entries
< if (typeof path !== 'string' || !path) {
< continue;
< }
---
> var hiddenSizes = this.hiddenSizes;
> if (!hiddenSizes) {
> hiddenSizes = [Math.max(3, Math.floor(inputSize / 2))];
> }
> var sizes = _([inputSize, hiddenSizes, outputSize]).flatten();
> this.initialize(sizes);
257,259c98,105
< resolvedPath = path + '/' + resolvedPath;
< resolvedAbsolute = path.charAt(0) === '/';
< }
---
> var error = 1;
> for (var i = 0; i < iterations && error > errorThresh; i++) {
> var sum = 0;
> for (var j = 0; j < data.length; j++) {
> var err = this.trainPattern(data[j].input, data[j].output);
> sum += err;
> }
> error = sum / data.length;
261,262c107,113
< // At this point the path should be resolved to a full absolute path, but
< // handle relative paths to be safe (might happen when process.cwd() fails)
---
> if (log && (i % logPeriod == 0)) {
> console.log("iterations:", i, "training error:", error);
> }
> if (callback && (i % callbackPeriod == 0)) {
> callback({ error: error, iterations: i });
> }
> }
264,267c115,119
< // Normalize the path
< resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
< return !!p;
< }), !resolvedAbsolute).join('/');
---
> return {
> error: error,
> iterations: i
> };
> },
269,270c121,123
< return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
< };
---
> trainPattern : function(input, target) {
> // forward propogate
> this.runInput(input);
272,281c125,127
< // path.normalize(path)
< // posix version
< exports.normalize = function(path) {
< var isAbsolute = path.charAt(0) === '/',
< trailingSlash = path.slice(-1) === '/';
<
< // Normalize the path
< path = normalizeArray(filter(path.split('/'), function(p) {
< return !!p;
< }), !isAbsolute).join('/');
---
> // back propogate
> this.calculateDeltas(target);
> this.adjustWeights();
283,291c129,131
< if (!path && !isAbsolute) {
< path = '.';
< }
< if (path && trailingSlash) {
< path += '/';
< }
<
< return (isAbsolute ? '/' : '') + path;
< };
---
> var error = mse(this.errors[this.outputLayer]);
> return error;
> },
292a133,136
> calculateDeltas: function(target) {
> for (var layer = this.outputLayer; layer >= 0; layer--) {
> for (var node = 0; node < this.sizes[layer]; node++) {
> var output = this.outputs[layer][node];
294,300c138,152
< // posix version
< exports.join = function() {
< var paths = Array.prototype.slice.call(arguments, 0);
< return exports.normalize(filter(paths, function(p, index) {
< return p && typeof p === 'string';
< }).join('/'));
< };
---
> var error = 0;
> if (layer == this.outputLayer) {
> error = target[node] - output;
> }
> else {
> var deltas = this.deltas[layer + 1];
> for (var k = 0; k < deltas.length; k++) {
> error += deltas[k] * this.weights[layer + 1][k][node];
> }
> }
> this.errors[layer][node] = error;
> this.deltas[layer][node] = error * output * (1 - output);
> }
> }
> },
301a154,156
> adjustWeights: function() {
> for (var layer = 1; layer <= this.outputLayer; layer++) {
> var incoming = this.outputs[layer - 1];
303,317c158,159
< exports.dirname = function(path) {
< var dir = splitPathRe.exec(path)[1] || '';
< var isWindows = false;
< if (!dir) {
< // No dirname
< return '.';
< } else if (dir.length === 1 ||
< (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
< // It is just a slash or a drive letter with a slash
< return dir;
< } else {
< // It is a full dirname, strip trailing slash
< return dir.substring(0, dir.length - 1);
< }
< };
---
> for (var node = 0; node < this.sizes[layer]; node++) {
> var delta = this.deltas[layer][node];
318a161,162
> for (var k = 0; k < incoming.length; k++) {
> var change = this.changes[layer][node][k];
320,327c164,165
< exports.basename = function(path, ext) {
< var f = splitPathRe.exec(path)[2] || '';
< // TODO: make this comparison case-insensitive on windows?
< if (ext && f.substr(-1 * ext.length) === ext) {
< f = f.substr(0, f.length - ext.length);
< }
< return f;
< };
---
> change = (this.learningRate * delta * incoming[k])
> + (this.momentum * change);
328a167,173
> this.changes[layer][node][k] = change;
> this.weights[layer][node][k] += change;
> }
> this.biases[layer][node] += this.learningRate * delta;
> }
> }
> },
330,332c175,252
< exports.extname = function(path) {
< return splitPathRe.exec(path)[3] || '';
< };
---
> formatData: function(data) {
> // turn sparse hash input into arrays with 0s as filler
> if (!_(data[0].input).isArray()) {
> if (!this.inputLookup) {
> this.inputLookup = lookup.buildLookup(_(data).pluck("input"));
> }
> data = data.map(function(datum) {
> var array = lookup.toArray(this.inputLookup, datum.input)
> return _(_(datum).clone()).extend({ input: array });
> }, this);
> }
>
> if (!_(data[0].output).isArray()) {
> if (!this.outputLookup) {
> this.outputLookup = lookup.buildLookup(_(data).pluck("output"));
> }
> data = data.map(function(datum) {
> var array = lookup.toArray(this.outputLookup, datum.output);
> return _(_(datum).clone()).extend({ output: array });
> }, this);
> }
> return data;
> },
>
> test : function(data, binaryThresh) {
> data = this.formatData(data);
> binaryThresh = binaryThresh || 0.5;
>
> // for binary classification problems with one output node
> var isBinary = data[0].output.length == 1;
> var falsePos = 0,
> falseNeg = 0,
> truePos = 0,
> trueNeg = 0;
>
> // for classification problems
> var misclasses = [];
>
> // run each pattern through the trained network and collect
> // error and misclassification statistics
> var sum = 0;
> for (var i = 0; i < data.length; i++) {
> var output = this.runInput(data[i].input);
> var target = data[i].output;
>
> var actual, expected;
> if (isBinary) {
> actual = output[0] > binaryThresh ? 1 : 0;
> expected = target[0];
> }
> else {
> actual = output.indexOf(_(output).max());
> expected = target.indexOf(_(target).max());
> }
>
> if (actual != expected) {
> var misclass = data[i];
> _(misclass).extend({
> actual: actual,
> expected: expected
> })
> misclasses.push(misclass);
> }
>
> if (isBinary) {
> if (actual == 0 && expected == 0) {
> trueNeg++;
> }
> else if (actual == 1 && expected == 1) {
> truePos++;
> }
> else if (actual == 0 && expected == 1) {
> falseNeg++;
> }
> else if (actual == 1 && expected == 0) {
> falsePos++;
> }
> }
334,336c254,259
< exports.relative = function(from, to) {
< from = exports.resolve(from).substr(1);
< to = exports.resolve(to).substr(1);
---
> var errors = output.map(function(value, i) {
> return target[i] - value;
> });
> sum += mse(errors);
> }
> var error = sum / data.length;
338,341c261,324
< function trim(arr) {
< var start = 0;
< for (; start < arr.length; start++) {
< if (arr[start] !== '') break;
---
> var stats = {
> error: error,
> misclasses: misclasses
> };
>
> if (isBinary) {
> _(stats).extend({
> trueNeg: trueNeg,
> truePos: truePos,
> falseNeg: falseNeg,
> falsePos: falsePos,
> total: data.length,
> precision: truePos / (truePos + falsePos),
> recall: truePos / (truePos + falseNeg),
> accuracy: (trueNeg + truePos) / data.length
> })
> }
> return stats;
> },
>
> toJSON: function() {
> /* make json look like:
> {
> layers: [
> { x: {},
> y: {}},
> {'0': {bias: -0.98771313, weights: {x: 0.8374838, y: 1.245858},
> '1': {bias: 3.48192004, weights: {x: 1.7825821, y: -2.67899}}},
> { f: {bias: 0.27205739, weights: {'0': 1.3161821, '1': 2.00436}}}
> ]
> }
> */
> var layers = [];
> for (var layer = 0; layer <= this.outputLayer; layer++) {
> layers[layer] = {};
>
> var nodes;
> // turn any internal arrays back into hashes for readable json
> if (layer == 0 && this.inputLookup) {
> nodes = _(this.inputLookup).keys();
> }
> else if (layer == this.outputLayer && this.outputLookup) {
> nodes = _(this.outputLookup).keys();
> }
> else {
> nodes = _.range(0, this.sizes[layer]);
> }
>
> for (var j = 0; j < nodes.length; j++) {
> var node = nodes[j];
> layers[layer][node] = {};
>
> if (layer > 0) {
> layers[layer][node].bias = this.biases[layer][j];
> layers[layer][node].weights = {};
> for (var k in layers[layer - 1]) {
> var index = k;
> if (layer == 1 && this.inputLookup) {
> index = this.inputLookup[k];
> }
> layers[layer][node].weights[k] = this.weights[layer][j][index];
> }
> }
> }
342a326,327
> return { layers: layers };
> },
344,346c329,357
< var end = arr.length - 1;
< for (; end >= 0; end--) {
< if (arr[end] !== '') break;
---
> fromJSON: function(json) {
> var size = json.layers.length;
> this.outputLayer = size - 1;
>
> this.sizes = new Array(size);
> this.weights = new Array(size);
> this.biases = new Array(size);
> this.outputs = new Array(size);
>
> for (var i = 0; i <= this.outputLayer; i++) {
> var layer = json.layers[i];
> if (i == 0 && !layer[0]) {
> this.inputLookup = lookup.lookupFromHash(layer);
> }
> else if (i == this.outputLayer && !layer[0]) {
> this.outputLookup = lookup.lookupFromHash(layer);
> }
>
> var nodes = _(layer).keys();
> this.sizes[i] = nodes.length;
> this.weights[i] = [];
> this.biases[i] = [];
> this.outputs[i] = [];
>
> for (var j in nodes) {
> var node = nodes[j];
> this.biases[i][j] = layer[node].bias;
> this.weights[i][j] = _(layer[node].weights).toArray();
> }
347a359,360
> return this;
> },
349,350c362,379
< if (start > end) return [];
< return arr.slice(start, end - start + 1);
---
> toFunction: function() {
> var json = this.toJSON();
> // return standalone function that mimics run()
> return new Function("inputs",
> ' var net = ' + JSON.stringify(json) + ';\n\n\
> for(var i = 1; i < net.layers.length; i++) {\n\
> var layer = net.layers[i];\n\
> var outputs = {};\n\
> for(var id in layer) {\n\
> var node = layer[id];\n\
> var sum = node.bias;\n\
> for(var iid in node.weights)\n\
> sum += node.weights[iid] * inputs[iid];\n\
> outputs[id] = (1/(1 + Math.exp(-sum)));\n\
> }\n\
> inputs = outputs;\n\
> }\n\
> return outputs;');
351a381
> }
353,354c383,385
< var fromParts = trim(from.split('/'));
< var toParts = trim(to.split('/'));
---
> function randomWeight() {
> return Math.random() * 0.4 - 0.2;
> }
356,362c387,390
< var length = Math.min(fromParts.length, toParts.length);
< var samePartsLength = length;
< for (var i = 0; i < length; i++) {
< if (fromParts[i] !== toParts[i]) {
< samePartsLength = i;
< break;
< }
---
> function zeros(size) {
> var array = new Array(size);
> for (var i = 0; i < size; i++) {
> array[i] = 0;
363a392,393
> return array;
> }
365,367c395,398
< var outputParts = [];
< for (var i = samePartsLength; i < fromParts.length; i++) {
< outputParts.push('..');
---
> function randos(size) {
> var array = new Array(size);
> for (var i = 0; i < size; i++) {
> array[i] = randomWeight();
368a400,401
> return array;
> }
370,375c403,410
< outputParts = outputParts.concat(toParts.slice(samePartsLength));
<
< return outputParts.join('/');
< };
<
< });
---
> function mse(errors) {
> // mean squared error
> var sum = 0;
> for (var i = 0; i < errors.length; i++) {
> sum += Math.pow(errors[i], 2);
> }
> return sum / errors.length;
> }
377c412
< require.define("__browserify_process",function(require,module,exports,__dirname,__filename,process,global){var process = module.exports = {};
---
> exports.NeuralNetwork = NeuralNetwork;
379,400c414,415
< process.nextTick = (function () {
< var canSetImmediate = typeof window !== 'undefined'
< && window.setImmediate;
< var canPost = typeof window !== 'undefined'
< && window.postMessage && window.addEventListener
< ;
<
< if (canSetImmediate) {
< return function (f) { return window.setImmediate(f) };
< }
<
< if (canPost) {
< var queue = [];
< window.addEventListener('message', function (ev) {
< if (ev.source === window && ev.data === 'browserify-tick') {
< ev.stopPropagation();
< if (queue.length > 0) {
< var fn = queue.shift();
< fn();
< }
< }
< }, true);
---
> });require.register("lookup.js", function(module, exports, require, global){
> var _ = require("underscore");
402,411c417
< return function nextTick(fn) {
< queue.push(fn);
< window.postMessage('browserify-tick', '*');
< };
< }
<
< return function nextTick(fn) {
< setTimeout(fn, 0);
< };
< })();
---
> /* Functions for turning sparse hashes into arrays and vice versa */
413,421c419,425
< process.title = 'browser';
< process.browser = true;
< process.env = {};
< process.argv = [];
<
< process.binding = function (name) {
< if (name === 'evals') return (require)('vm')
< else throw new Error('No such module. (Possibly not yet loaded)')
< };
---
> function buildLookup(hashes) {
> // [{a: 1}, {b: 6, c: 7}] -> {a: 0, b: 1, c: 2}
> var hash = _(hashes).reduce(function(memo, hash) {
> return _(memo).extend(hash);
> }, {});
> return lookupFromHash(hash);
> }
423,431c427,435
< (function () {
< var cwd = '/';
< var path;
< process.cwd = function () { return cwd };
< process.chdir = function (dir) {
< if (!path) path = require('path');
< cwd = path.resolve(dir, cwd);
< };
< })();
---
> function lookupFromHash(hash) {
> // {a: 6, b: 7} -> {a: 0, b: 1}
> var lookup = {};
> var index = 0;
> for (var i in hash) {
> lookup[i] = index++;
> }
> return lookup;
> }
433c437,444
< });
---
> function toArray(lookup, hash) {
> // {a: 0, b: 1}, {a: 6} -> [6, 0]
> var array = [];
> for (var i in lookup) {
> array[lookup[i]] = hash[i] || 0;
> }
> return array;
> }
435,436c446,453
< require.define("/package.json",function(require,module,exports,__dirname,__filename,process,global){module.exports = {"main":"underscore.js"}
< });
---
> function toHash(lookup, array) {
> // {a: 0, b: 1}, [6, 7] -> {a: 6, b: 7}
> var hash = {};
> for (var i in lookup) {
> hash[i] = array[lookup[i]];
> }
> return hash;
> }
438,441c455,468
< require.define("/node_modules/underscore/index.js",function(require,module,exports,__dirname,__filename,process,global){// Underscore.js 1.4.4
< // http://underscorejs.org
< // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
< // Underscore may be freely distributed under the MIT license.
---
> module.exports = {
> buildLookup: buildLookup,
> lookupFromHash: lookupFromHash,
> toArray: toArray,
> toHash: toHash
> };
> });require.register("underscore", function(module, exports, require, global){
> // Underscore.js 1.3.3
> // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
> // Underscore is freely distributable under the MIT license.
> // Portions of Underscore are inspired or borrowed from Prototype,
> // Oliver Steele's Functional, and John Resig's Micro-Templating.
> // For all details and documentation:
> // http://documentcloud.github.com/underscore
461,463c488,489
< var push = ArrayProto.push,
< slice = ArrayProto.slice,
< concat = ArrayProto.concat,
---
> var slice = ArrayProto.slice,
> unshift = ArrayProto.unshift,
484,488c510
< var _ = function(obj) {
< if (obj instanceof _) return obj;
< if (!(this instanceof _)) return new _(obj);
< this._wrapped = obj;
< };
---
> var _ = function(obj) { return new wrapper(obj); };
500c522
< root._ = _;
---
> root['_'] = _;
504c526
< _.VERSION = '1.4.4';
---
> _.VERSION = '1.3.3';
518c540
< if (iterator.call(context, obj[i], i, obj) === breaker) return;
---
> if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
537a560
> if (obj.length === +obj.length) results.length = obj.length;
541,542d563
< var reduceError = 'Reduce of empty array with no initial value';
<
560c581
< if (!initial) throw new TypeError(reduceError);
---
> if (!initial) throw new TypeError('Reduce of empty array with no initial value');
573,588c594,596
< 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);
< }
< });
< if (!initial) throw new TypeError(reduceError);
< return memo;
---
> var reversed = _.toArray(obj).reverse();
> if (context && !initial) iterator = _.bind(iterator, context);
> return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator);
618,620c626,631
< return _.filter(obj, function(value, index, list) {
< return !iterator.call(context, value, index, list);
< }, context);
---
> var results = [];
> if (obj == null) return results;
> each(obj, function(value, index, list) {
> if (!iterator.call(context, value, index, list)) results[results.length] = value;
> });
> return results;
627d637
< iterator || (iterator = _.identity);
651,654c661,665
< // Determine if the array or object contains a given value (using `===`).
< // Aliased as `include`.
< _.contains = _.include = function(obj, target) {
< if (obj == null) return false;
---
> // Determine if a given value is included in the array or object using `===`.
> // Aliased as `contains`.
> _.include = _.contains = function(obj, target) {
> var found = false;
> if (obj == null) return found;
656c667
< return any(obj, function(value) {
---
> found = any(obj, function(value) {
658a670
> return found;
664d675
< var isFunc = _.isFunction(method);
666c677
< return (isFunc ? method : value[method]).apply(value, args);
---
> return (_.isFunction(method) ? method || value : value[method]).apply(value, args);
675,692d685
< // Convenience version of a common use case of `filter`: selecting only objects
< // containing specific `key:value` pairs.
< _.where = function(obj, attrs, first) {
< if (_.isEmpty(attrs)) return first ? null : [];
< return _[first ? 'find' : 'filter'](obj, function(value) {
< for (var key in attrs) {
< if (attrs[key] !== value[key]) return false;
< }
< return true;
< });
< };
<
< // Convenience version of a common use case of `find`: getting the first object
< // containing specific `key:value` pairs.
< _.findWhere = function(obj, attrs) {
< return _.where(obj, attrs, true);
< };
<
694,695d686
< // Can't optimize arrays of integers longer than 65,535 elements.
< // See: https://bugs.webkit.org/show_bug.cgi?id=80797
697,699c688
< if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
< return Math.max.apply(Math, obj);
< }
---
> if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.max.apply(Math, obj);
701c690
< var result = {computed : -Infinity, value: -Infinity};
---
> var result = {computed : -Infinity};
711,713c700
< if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
< return Math.min.apply(Math, obj);
< }
---
> if (!iterator && _.isArray(obj) && obj[0] === +obj[0]) return Math.min.apply(Math, obj);
715c702
< var result = {computed : Infinity, value: Infinity};
---
> var result = {computed : Infinity};
725,730c712,715
< var rand;
< var index = 0;
< var shuffled = [];
< each(obj, function(value) {
< rand = _.random(index++);
< shuffled[index - 1] = shuffled[rand];
---
> var shuffled = [], rand;
> each(obj, function(value, index, list) {
> rand = Math.floor(Math.random() * (index + 1));
> shuffled[index] = shuffled[rand];
736,740d720
< // An internal function to generate lookup iterators.
< var lookupIterator = function(value) {
< return _.isFunction(value) ? value : function(obj){ return obj[value]; };
< };
<
742,743c722,723
< _.sortBy = function(obj, value, context) {
< var iterator = lookupIterator(value);
---
> _.sortBy = function(obj, val, context) {
> var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
747d726
< index : index,
751,757c730,733
< var a = left.criteria;
< var b = right.criteria;
< if (a !== b) {
< if (a > b || a === void 0) return 1;
< if (a < b || b === void 0) return -1;
< }
< return left.index < right.index ? -1 : 1;
---
> var a = left.criteria, b = right.criteria;
> if (a === void 0) return 1;
> if (b === void 0) return -1;
> return a < b ? -1 : a > b ? 1 : 0;
761,762c737,739
< // An internal function used for aggregate "group by" operations.
< var group = function(obj, value, context, behavior) {
---
> // Groups the object's values by a criterion. Pass either a string attribute
> // to group by, or a function that returns the criterion.
> _.groupBy = function(obj, val) {
764c741
< var iterator = lookupIterator(value || _.identity);
---
> var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; };
766,767c743,744
< var key = iterator.call(context, value, index, obj);
< behavior(result, key, value);
---
> var key = iterator(value, index);
> (result[key] || (result[key] = [])).push(value);
772,794c749,752
< // Groups the object's values by a criterion. Pass either a string attribute
< // to group by, or a function that returns the criterion.
< _.groupBy = function(obj, value, context) {
< return group(obj, value, context, function(result, key, value) {
< (_.has(result, key) ? result[key] : (result[key] = [])).push(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 = function(obj, value, context) {
< return group(obj, value, context, function(result, key) {
< if (!_.has(result, key)) result[key] = 0;
< result[key]++;
< });
< };
<
< // 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 = iterator == null ? _.identity : lookupIterator(iterator);
< var value = iterator.call(context, obj);
---
> // Use a comparator function to figure out at what index an object should
> // be inserted so as to maintain order. Uses binary search.
> _.sortedIndex = function(array, obj, iterator) {
> iterator || (iterator = _.identity);
797,798c755,756
< var mid = (low + high) >>> 1;
< iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
---
> var mid = (low + high) >> 1;
> iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
805,807c763,766
< if (!obj) return [];
< if (_.isArray(obj)) return slice.call(obj);
< if (obj.length === +obj.length) return _.map(obj, _.identity);
---
> if (!obj) return [];
> if (_.isArray(obj)) return slice.call(obj);
> if (_.isArguments(obj)) return slice.call(obj);
> if (obj.toArray && _.isFunction(obj.toArray)) return obj.toArray();
813,814c772
< if (obj == null) return 0;
< return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
---
> return _.isArray(obj) ? obj.length : _.keys(obj).length;
824d781
< if (array == null) return void 0;
828c785
< // Returns everything but the last entry of the array. Especially useful on
---
> // Returns everything but the last entry of the array. Especcialy useful on
839d795
< if (array == null) return void 0;
847,849c803,805
< // 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**
---
> // Returns everything but the first entry of the array. Aliased as `tail`.
> // Especially useful on the arguments object. Passing an **index** will return
> // the rest of the values in the array from that index onward. The **guard**
851,852c807,808
< _.rest = _.tail = _.drop = function(array, n, guard) {
< return slice.call(array, (n == null) || guard ? 1 : n);
---
> _.rest = _.tail = function(array, index, guard) {
> return slice.call(array, (index == null) || guard ? 1 : index);
857,869c813
< return _.filter(array, _.identity);
< };
<
< // Internal implementation of a recursive `flatten` function.
< var flatten = function(input, shallow, output) {
< each(input, function(value) {
< if (_.isArray(value)) {
< shallow ? push.apply(output, value) : flatten(value, shallow, output);
< } else {
< output.push(value);
< }
< });
< return output;
---
> return _.filter(array, function(value){ return !!value; });
874c818,822
< return flatten(array, shallow, []);
---
> return _.reduce(array, function(memo, value) {
> if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value));
> memo[memo.length] = value;
> return memo;
> }, []);
885,891c833,834
< _.uniq = _.unique = function(array, isSorted, iterator, context) {
< if (_.isFunction(isSorted)) {
< context = iterator;
< iterator = isSorted;
< isSorted = false;
< }
< var initial = iterator ? _.map(array, iterator, context) : array;
---
> _.uniq = _.unique = function(array, isSorted, iterator) {
> var initial = iterator ? _.map(array, iterator) : array;
893,896c836,840
< var seen = [];
< each(initial, function(value, index) {
< if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
< seen.push(value);
---
> // The `isSorted` flag is irrelevant if the array only contains two elements.
> if (array.length < 3) isSorted = true;
> _.reduce(initial, function (memo, value, index) {
> if (isSorted ? _.last(memo) !== value || !memo.length : !_.include(memo, value)) {
> memo.push(value);
899c843,844
< });
---
> return memo;
> }, []);
906c851
< return _.uniq(concat.apply(ArrayProto, arguments));
---
> return _.uniq(_.flatten(arguments, true));
910,911c855,856
< // passed-in arrays.
< _.intersection = function(array) {
---
> // passed-in arrays. (Aliased as "intersect" for back-compat.)
> _.intersection = _.intersect = function(array) {
923,924c868,869
< var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
< return _.filter(array, function(value){ return !_.contains(rest, value); });
---
> var rest = _.flatten(slice.call(arguments, 1), true);
> return _.filter(array, function(value){ return !_.include(rest, value); });
933,935c878
< for (var i = 0; i < length; i++) {
< results[i] = _.pluck(args, "" + i);
< }
---
> for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
939,954d881
< // 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, l = list.length; i < l; i++) {
< if (values) {
< result[list[i]] = values[i];
< } else {
< result[list[i][0]] = list[i][1];
< }
< }
< return result;
< };
<
963c890
< var i = 0, l = array.length;
---
> var i, l;
965,970c892,893
< if (typeof isSorted == 'number') {
< i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
< } else {
< i = _.sortedIndex(array, item);
< return array[i] === item ? i : -1;
< }
---
> i = _.sortedIndex(array, item);
> return array[i] === item ? i : -1;
972,973c895,896
< if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
< for (; i < l; i++) if (array[i] === item) return i;
---
> if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
> for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i;
978c901
< _.lastIndexOf = function(array, item, from) {
---
> _.lastIndexOf = function(array, item) {
980,985c903,905
< var hasIndex = from != null;
< if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
< return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
< }
< var i = (hasIndex ? from : array.length);
< while (i--) if (array[i] === item) return i;
---
> if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
> var i = array.length;
> while (i--) if (i in array && array[i] === item) return i;
1013a934,936
> // Reusable constructor function for prototype setting.
> var ctor = function(){};
>
1015,1017c938,942
< // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
< // available.
< _.bind = function(func, context) {
---
> // optionally). Binding with arguments is also known as `curry`.
> // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
> // We check for `func.bind` first, to fail fast when `func` is undefined.
> _.bind = function bind(func, context) {
> var bound, args;
1019,1030c944,952
< var args = slice.call(arguments, 2);
< return function() {
< return func.apply(context, args.concat(slice.call(arguments)));
< };
< };
<
< // Partially apply a function by creating a version that has had some of its
< // arguments pre-filled, without changing its dynamic `this` context.
< _.partial = function(func) {
< var args = slice.call(arguments, 1);
< return function() {
< return func.apply(this, args.concat(slice.call(arguments)));
---
> 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;
> var result = func.apply(self, args.concat(slice.call(arguments)));
> if (Object(result) === result) return result;
> return self;
1038c960
< if (funcs.length === 0) funcs = _.functions(obj);
---
> if (funcs.length == 0) funcs = _.functions(obj);
1069,1075c991,992
< var context, args, timeout, result;
< var previous = 0;
< var later = function() {
< previous = new Date;
< timeout = null;
< result = func.apply(context, args);
< };
---
> var context, args, timeout, throttling, more, result;
> var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
1077,1082c994,995
< var now = new Date;
< var remaining = wait - (now - previous);
< context = this;
< args = arguments;
< if (remaining <= 0) {
< clearTimeout(timeout);
---
> context = this; args = arguments;
> var later = function() {
1084c997,1003
< previous = now;
---
> if (more) func.apply(context, args);
> whenDone();
> };
> if (!timeout) timeout = setTimeout(later, wait);
> if (throttling) {
> more = true;
> } else {
1086,1087d1004
< } else if (!timeout) {
< timeout = setTimeout(later, remaining);
1088a1006,1007
> whenDone();
> throttling = true;
1098c1017
< var timeout, result;
---
> var timeout;
1103c1022
< if (!immediate) result = func.apply(context, args);
---
> if (!immediate) func.apply(context, args);
1105c1024
< var callNow = immediate && !timeout;
---
> if (immediate && !timeout) func.apply(context, args);
1108,1109d1026
< if (callNow) result = func.apply(context, args);
< return result;
1120,1122c1037
< memo = func.apply(this, arguments);
< func = null;
< return memo;
---
> return memo = func.apply(this, arguments);
1131,1132c1046
< var args = [func];
< push.apply(args, arguments);
---
> var args = [func].concat(slice.call(arguments, 0));
1154,1156c1068
< if (--times < 1) {
< return func.apply(this, arguments);
< }
---
> if (--times < 1) { return func.apply(this, arguments); }
1174,1190c1086
< var values = [];
< for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
< return values;
< };
<
< // Convert an object into a list of `[key, value]` pairs.
< _.pairs = function(obj) {
< var pairs = [];
< for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
< return pairs;
< };
<
< // Invert the keys and values of an object. The values must be serializable.
< _.invert = function(obj) {
< var result = {};
< for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
< return result;
---
> return _.map(obj, _.identity);
1206,1209c1102,1103
< if (source) {
< for (var prop in source) {
< obj[prop] = source[prop];
< }
---
> for (var prop in source) {
> obj[prop] = source[prop];
1217,1220c1111,1113
< var copy = {};
< var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
< each(keys, function(key) {
< if (key in obj) copy[key] = obj[key];
---
> var result = {};
> each(_.flatten(slice.call(arguments, 1)), function(key) {
> if (key in obj) result[key] = obj[key];
1222,1232c1115
< return copy;
< };
<
< // 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];
< }
< return copy;
---
> return result;
1238,1241c1121,1122
< if (source) {
< for (var prop in source) {
< if (obj[prop] == null) obj[prop] = source[prop];
< }
---
> for (var prop in source) {
> if (obj[prop] == null) obj[prop] = source[prop];
1261,1262c1142,1143
< // Internal recursive comparison function for `isEqual`.
< var eq = function(a, b, aStack, bStack) {
---
> // Internal recursive comparison function.
> function eq(a, b, stack) {
1269,1270c1150,1154
< if (a instanceof _) a = a._wrapped;
< if (b instanceof _) b = b._wrapped;
---
> if (a._chain) a = a._wrapped;
> if (b._chain) b = b._wrapped;
> // Invoke a custom `isEqual` method if one is provided.
> if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
> if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
1300c1184
< var length = aStack.length;
---
> var length = stack.length;
1304c1188
< if (aStack[length] == a) return bStack[length] == b;
---
> if (stack[length] == a) return true;
1307,1308c1191
< aStack.push(a);
< bStack.push(b);
---
> stack.push(a);
1318c1201,1202
< if (!(result = eq(a[size], b[size], aStack, bStack))) break;
---
> // Ensure commutative equality for sparse arrays.
> if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break;
1322,1328c1206,1207
< // 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))) {
< return false;
< }
---
> // Objects with different constructors are not equivalent.
> if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;
1335c1214
< if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
---
> if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break;
1347,1348c1226
< aStack.pop();
< bStack.pop();
---
> stack.pop();
1350c1228
< };
---
> }
1354c1232
< return eq(a, b, [], []);
---
> return eq(a, b, []);
1368c1246
< return !!(obj && obj.nodeType === 1);
---
> return !!(obj && obj.nodeType == 1);
1382,1390c1260,1263
< // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
< each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
< _['is' + name] = function(obj) {
< return toString.call(obj) == '[object ' + name + ']';
< };
< });
<
< // Define a fallback version of the method in browsers (ahem, IE), where
< // there isn't any inspectable "Arguments" type.
---
> // Is a given variable an arguments object?
> _.isArguments = function(obj) {
> return toString.call(obj) == '[object Arguments]';
> };
1397,1402c1270,1283
< // Optimize `isFunction` if appropriate.
< if (typeof (/./) !== 'function') {
< _.isFunction = function(obj) {
< return typeof obj === 'function';
< };
< }
---
> // Is a given value a function?
> _.isFunction = function(obj) {
> return toString.call(obj) == '[object Function]';
> };
>
> // Is a given value a string?
> _.isString = function(obj) {
> return toString.call(obj) == '[object String]';
> };
>
> // Is a given value a number?
> _.isNumber = function(obj) {
> return toString.call(obj) == '[object Number]';
> };
1406c1287
< return isFinite(obj) && !isNaN(parseFloat(obj));
---
> return _.isNumber(obj) && isFinite(obj);
1409c1290
< // Is the given value `NaN`? (NaN is the only number which does not equal itself).
---
> // Is the given value `NaN`?
1411c1292,1293
< return _.isNumber(obj) && obj != +obj;
---
> // `NaN` is the only value for which `===` is not reflexive.
> return obj !== obj;
1418a1301,1310
> // Is a given value a date?
> _.isDate = function(obj) {
> return toString.call(obj) == '[object Date]';
> };
>
> // Is the given value a regular expression?
> _.isRegExp = function(obj) {
> return toString.call(obj) == '[object RegExp]';
> };
>
1429,1430c1321
< // Shortcut function for checking if an object has a given property directly
< // on itself (in other words, not on a prototype).
---
> // Has own property?
1451,1493c1342,1349
< _.times = function(n, iterator, context) {
< var accum = Array(n);
< for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
< return accum;
< };
<
< // Return a random integer between min and max (inclusive).
< _.random = function(min, max) {
< if (max == null) {
< max = min;
< min = 0;
< }
< return min + Math.floor(Math.random() * (max - min + 1));
< };
<
< // List of HTML entities for escaping.
< var entityMap = {
< escape: {
< '&': '&amp;',
< '<': '&lt;',
< '>': '&gt;',
< '"': '&quot;',
< "'": '&#x27;',
< '/': '&#x2F;'
< }
< };
< 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')
< };
<
< // 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];
< });
< };
< });
---
> _.times = function (n, iterator, context) {
> for (var i = 0; i < n; i++) iterator.call(context, i);
> };
>
> // Escape a string for HTML interpolation.
> _.escape = function(string) {
> return (''+string).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
> };
1503c1359,1360
< // Add your own custom functions to the Underscore object.
---
> // Add your own custom functions to the Underscore object, ensuring that
> // they're correctly added to the OOP wrapper as well.
1506,1511c1363
< var func = _[name] = obj[name];
< _.prototype[name] = function() {
< var args = [this._wrapped];
< push.apply(args, arguments);
< return result.call(this, func.apply(_, args));
< };
---
> addToWrapper(name, _[name] = obj[name]);
1519c1371
< var id = ++idCounter + '';
---
> var id = idCounter++;
1534c1386
< var noMatch = /(.)^/;
---
> var noMatch = /.^/;
1539,1545c1391,1397
< "'": "'",
< '\\': '\\',
< '\r': 'r',
< '\n': 'n',
< '\t': 't',
< '\u2028': 'u2028',
< '\u2029': 'u2029'
---
> '\\': '\\',
> "'": "'",
> 'r': '\r',
> 'n': '\n',
> 't': '\t',
> 'u2028': '\u2028',
> 'u2029': '\u2029'
1547a1400
> for (var p in escapes) escapes[escapes[p]] = p;
1548a1402,1410
> var unescaper = /\\(\\|'|r|n|t|u2028|u2029)/g;
>
> // Within an interpolation, evaluation, or escaping, remove HTML escaping
> // that had been previously added.
> var unescape = function(code) {
> return code.replace(unescaper, function(match, escape) {
> return escapes[escape];
> });
> };
1554,1555c1416
< var render;
< settings = _.defaults({}, settings, _.templateSettings);
---
> settings = _.defaults(settings || {}, _.templateSettings);
1557,1583c1418,1433
< // Combine delimiters into one regular expression via alternation.
< var matcher = new RegExp([
< (settings.escape || noMatch).source,
< (settings.interpolate || noMatch).source,
< (settings.evaluate || noMatch).source
< ].join('|') + '|$', 'g');
<
< // Compile the template source, escaping string literals appropriately.
< 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]; });
<
< if (escape) {
< source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
< }
< if (interpolate) {
< source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
< }
< if (evaluate) {
< source += "';\n" + evaluate + "\n__p+='";
< }
< index = offset + match.length;
< return match;
< });
< source += "';\n";
---
> // Compile the template source, taking care to escape characters that
> // cannot be included in a string literal and then unescape them in code
> // blocks.
> var source = "__p+='" + text
> .replace(escaper, function(match) {
> return '\\' + escapes[match];
> })
> .replace(settings.escape || noMatch, function(match, code) {
> return "'+\n_.escape(" + unescape(code) + ")+\n'";
> })
> .replace(settings.interpolate || noMatch, function(match, code) {
> return "'+\n(" + unescape(code) + ")+\n'";
> })
> .replace(settings.evaluate || noMatch, function(match, code) {
> return "';\n" + unescape(code) + "\n;__p+='";
> }) + "';\n";
1588,1589c1438,1439
< source = "var __t,__p='',__j=Array.prototype.join," +
< "print=function(){__p+=__j.call(arguments,'');};\n" +
---
> source = "var __p='';" +
> "var print=function(){__p+=Array.prototype.join.call(arguments, '')};\n" +
1592,1598c1442
< try {
< render = new Function(settings.variable || 'obj', '_', source);
< } catch (e) {
< e.source = source;
< throw e;
< }
<
---
> var render = new Function(settings.variable || 'obj', '_', source);
1604,1605c1448,1451
< // Provide the compiled function source as a convenience for precompilation.
< template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
---
> // Provide the compiled function source as a convenience for build time
> // precompilation.
> template.source = 'function(' + (settings.variable || 'obj') + '){\n' +
> source + '}';
1615c1461
< // OOP
---
> // The OOP Wrapper
1616a1463
>
1619a1467,1470
> var wrapper = function(obj) { this._wrapped = obj; };
>
> // Expose `wrapper.prototype` as `_.prototype`
> _.prototype = wrapper.prototype;
1622,1623c1473,1483
< var result = function(obj) {
< return this._chain ? _(obj).chain() : obj;
---
> var result = function(obj, chain) {
> return chain ? _(obj).chain() : obj;
> };
>
> // A method to easily add functions to the OOP wrapper.
> var addToWrapper = function(name, func) {
> wrapper.prototype[name] = function() {
> var args = slice.call(arguments);
> unshift.call(args, this._wrapped);
> return result(func.apply(_, args), this._chain);
> };
1632,1636c1492,1497
< _.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);
---
> wrapper.prototype[name] = function() {
> var wrapped = this._wrapped;
> method.apply(wrapped, arguments);
> var length = wrapped.length;
> if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0];
> return result(wrapped, this._chain);
1643,1644c1504,1505
< _.prototype[name] = function() {
< return result.call(this, method.apply(this._wrapped, arguments));
---
> wrapper.prototype[name] = function() {
> return result(method.apply(this._wrapped, arguments), this._chain);
1648,1659c1509,1513
< _.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() {
< return this._wrapped;
< }
---
> // Start chaining a wrapped Underscore object.
> wrapper.prototype.chain = function() {
> this._chain = true;
> return this;
> };
1661c1515,1518
< });
---
> // Extracts the result from a wrapped and chained object.
> wrapper.prototype.value = function() {
> return this._wrapped;
> };
1665,1666c1522,1523
< });
< return require('brain')})();
\ No newline at end of file
---
> });brain = require('neuralnetwork.js');
> })();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment