UNPKG

olorin

Version:
1,678 lines (1,464 loc) 171 kB
var global = Function("return this;")(); /*! * Ender: open module JavaScript framework (client-lib) * copyright Dustin Diaz & Jacob Thornton 2011 (@ded @fat) * http://ender.no.de * License MIT */ !function (context) { // a global object for node.js module compatiblity // ============================================ context['global'] = context // Implements simple module system // losely based on CommonJS Modules spec v1.1.1 // ============================================ var modules = {} , old = context.$ function require (identifier) { // modules can be required from ender's build system, or found on the window var module = modules[identifier] || window[identifier] if (!module) throw new Error("Requested module '" + identifier + "' has not been defined.") return module } function provide (name, what) { return (modules[name] = what) } context['provide'] = provide context['require'] = require function aug(o, o2) { for (var k in o2) k != 'noConflict' && k != '_VERSION' && (o[k] = o2[k]) return o } function boosh(s, r, els) { // string || node || nodelist || window if (typeof s == 'string' || s.nodeName || (s.length && 'item' in s) || s == window) { els = ender._select(s, r) els.selector = s } else els = isFinite(s.length) ? s : [s] return aug(els, boosh) } function ender(s, r) { return boosh(s, r) } aug(ender, { _VERSION: '0.3.6' , fn: boosh // for easy compat to jQuery plugins , ender: function (o, chain) { aug(chain ? boosh : ender, o) } , _select: function (s, r) { return (r || document).querySelectorAll(s) } }) aug(boosh, { forEach: function (fn, scope, i) { // opt out of native forEach so we can intentionally call our own scope // defaulting to the current item and be able to return self for (i = 0, l = this.length; i < l; ++i) i in this && fn.call(scope || this[i], this[i], i, this) // return self for chaining return this }, $: ender // handy reference to self }) ender.noConflict = function () { context.$ = old return this } if (typeof module !== 'undefined' && module.exports) module.exports = ender // use subscript notation as extern for Closure compilation context['ender'] = context['$'] = context['ender'] || ender }(this); // pakmanager:commander (function (context) { var module = { exports: {} }, exports = module.exports , $ = require("ender") ; /** * Module dependencies. */ var EventEmitter = require('events').EventEmitter; var spawn = require('child_process').spawn; var path = require('path'); var dirname = path.dirname; var basename = path.basename; /** * Expose the root command. */ exports = module.exports = new Command(); /** * Expose `Command`. */ exports.Command = Command; /** * Expose `Option`. */ exports.Option = Option; /** * Initialize a new `Option` with the given `flags` and `description`. * * @param {String} flags * @param {String} description * @api public */ function Option(flags, description) { this.flags = flags; this.required = ~flags.indexOf('<'); this.optional = ~flags.indexOf('['); this.bool = !~flags.indexOf('-no-'); flags = flags.split(/[ ,|]+/); if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); this.long = flags.shift(); this.description = description || ''; } /** * Return option name. * * @return {String} * @api private */ Option.prototype.name = function() { return this.long .replace('--', '') .replace('no-', ''); }; /** * Check if `arg` matches the short or long flag. * * @param {String} arg * @return {Boolean} * @api private */ Option.prototype.is = function(arg) { return arg == this.short || arg == this.long; }; /** * Initialize a new `Command`. * * @param {String} name * @api public */ function Command(name) { this.commands = []; this.options = []; this._execs = []; this._args = []; this._name = name; } /** * Inherit from `EventEmitter.prototype`. */ Command.prototype.__proto__ = EventEmitter.prototype; /** * Add command `name`. * * The `.action()` callback is invoked when the * command `name` is specified via __ARGV__, * and the remaining arguments are applied to the * function for access. * * When the `name` is "*" an un-matched command * will be passed as the first arg, followed by * the rest of __ARGV__ remaining. * * Examples: * * program * .version('0.0.1') * .option('-C, --chdir <path>', 'change the working directory') * .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf') * .option('-T, --no-tests', 'ignore test hook') * * program * .command('setup') * .description('run remote setup commands') * .action(function() { * console.log('setup'); * }); * * program * .command('exec <cmd>') * .description('run the given remote command') * .action(function(cmd) { * console.log('exec "%s"', cmd); * }); * * program * .command('teardown <dir> [otherDirs...]') * .description('run teardown commands') * .action(function(dir, otherDirs) { * console.log('dir "%s"', dir); * if (otherDirs) { * otherDirs.forEach(function (oDir) { * console.log('dir "%s"', oDir); * }); * } * }); * * program * .command('*') * .description('deploy the given env') * .action(function(env) { * console.log('deploying "%s"', env); * }); * * program.parse(process.argv); * * @param {String} name * @param {String} [desc] * @return {Command} the new command * @api public */ Command.prototype.command = function(name, desc) { var args = name.split(/ +/); var cmd = new Command(args.shift()); if (desc) cmd.description(desc); if (desc) this.executables = true; if (desc) this._execs[cmd._name] = true; this.commands.push(cmd); cmd.parseExpectedArgs(args); cmd.parent = this; if (desc) return this; return cmd; }; /** * Add an implicit `help [cmd]` subcommand * which invokes `--help` for the given command. * * @api private */ Command.prototype.addImplicitHelpCommand = function() { this.command('help [cmd]', 'display help for [cmd]'); }; /** * Parse expected `args`. * * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. * * @param {Array} args * @return {Command} for chaining * @api public */ Command.prototype.parseExpectedArgs = function(args) { if (!args.length) return; var self = this; args.forEach(function(arg) { var argDetails = { required: false, name: '', variadic: false }; switch (arg[0]) { case '<': argDetails.required = true; argDetails.name = arg.slice(1, -1); break; case '[': argDetails.name = arg.slice(1, -1); break; } if (argDetails.name.indexOf('...') === argDetails.name.length - 3) { argDetails.variadic = true; argDetails.name = argDetails.name.slice(0, -3); } if (argDetails.name) { self._args.push(argDetails); } }); return this; }; /** * Register callback `fn` for the command. * * Examples: * * program * .command('help') * .description('display verbose help') * .action(function() { * // output help here * }); * * @param {Function} fn * @return {Command} for chaining * @api public */ Command.prototype.action = function(fn) { var self = this; var listener = function(args, unknown) { // Parse any so-far unknown options args = args || []; unknown = unknown || []; var parsed = self.parseOptions(unknown); // Output help if necessary outputHelpIfNecessary(self, parsed.unknown); // If there are still any unknown options, then we simply // die, unless someone asked for help, in which case we give it // to them, and then we die. if (parsed.unknown.length > 0) { self.unknownOption(parsed.unknown[0]); } // Leftover arguments need to be pushed back. Fixes issue #56 if (parsed.args.length) args = parsed.args.concat(args); self._args.forEach(function(arg, i) { if (arg.required && null == args[i]) { self.missingArgument(arg.name); } else if (arg.variadic) { if (i !== self._args.length - 1) { self.variadicArgNotLast(arg.name); } args[i] = args.slice(i); } }); // Always append ourselves to the end of the arguments, // to make sure we match the number of arguments the user // expects if (self._args.length) { args[self._args.length] = self; } else { args.push(self); } fn.apply(self, args); }; this.parent.on(this._name, listener); if (this._alias) this.parent.on(this._alias, listener); return this; }; /** * Define option with `flags`, `description` and optional * coercion `fn`. * * The `flags` string should contain both the short and long flags, * separated by comma, a pipe or space. The following are all valid * all will output this way when `--help` is used. * * "-p, --pepper" * "-p|--pepper" * "-p --pepper" * * Examples: * * // simple boolean defaulting to false * program.option('-p, --pepper', 'add pepper'); * * --pepper * program.pepper * // => Boolean * * // simple boolean defaulting to true * program.option('-C, --no-cheese', 'remove cheese'); * * program.cheese * // => true * * --no-cheese * program.cheese * // => false * * // required argument * program.option('-C, --chdir <path>', 'change the working directory'); * * --chdir /tmp * program.chdir * // => "/tmp" * * // optional argument * program.option('-c, --cheese [type]', 'add cheese [marble]'); * * @param {String} flags * @param {String} description * @param {Function|Mixed} fn or default * @param {Mixed} defaultValue * @return {Command} for chaining * @api public */ Command.prototype.option = function(flags, description, fn, defaultValue) { var self = this , option = new Option(flags, description) , oname = option.name() , name = camelcase(oname); // default as 3rd arg if (typeof fn != 'function') { defaultValue = fn; fn = null; } // preassign default value only for --no-*, [optional], or <required> if (false == option.bool || option.optional || option.required) { // when --no-* we make sure default is true if (false == option.bool) defaultValue = true; // preassign only if we have a default if (undefined !== defaultValue) self[name] = defaultValue; } // register the option this.options.push(option); // when it's passed assign the value // and conditionally invoke the callback this.on(oname, function(val) { // coercion if (null !== val && fn) val = fn(val, undefined === self[name] ? defaultValue : self[name]); // unassigned or bool if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) { // if no value, bool true, and we have a default, then use it! if (null == val) { self[name] = option.bool ? defaultValue || true : false; } else { self[name] = val; } } else if (null !== val) { // reassign self[name] = val; } }); return this; }; /** * Parse `argv`, settings options and invoking commands when defined. * * @param {Array} argv * @return {Command} for chaining * @api public */ Command.prototype.parse = function(argv) { // implicit help if (this.executables) this.addImplicitHelpCommand(); // store raw args this.rawArgs = argv; // guess name this._name = this._name || basename(argv[1], '.js'); // process argv var parsed = this.parseOptions(this.normalize(argv.slice(2))); var args = this.args = parsed.args; var result = this.parseArgs(this.args, parsed.unknown); // executable sub-commands var name = result.args[0]; if (this._execs[name] && typeof this._execs[name] != "function") { return this.executeSubCommand(argv, args, parsed.unknown); } return result; }; /** * Execute a sub-command executable. * * @param {Array} argv * @param {Array} args * @param {Array} unknown * @api private */ Command.prototype.executeSubCommand = function(argv, args, unknown) { args = args.concat(unknown); if (!args.length) this.help(); if ('help' == args[0] && 1 == args.length) this.help(); // <cmd> --help if ('help' == args[0]) { args[0] = args[1]; args[1] = '--help'; } // executable var dir = dirname(argv[1]); var bin = basename(argv[1], '.js') + '-' + args[0]; // check for ./<bin> first var local = path.join(dir, bin); // run it args = args.slice(1); args.unshift(local); var proc = spawn('node', args, { stdio: 'inherit', customFds: [0, 1, 2] }); proc.on('error', function(err) { if (err.code == "ENOENT") { console.error('\n %s(1) does not exist, try --help\n', bin); } else if (err.code == "EACCES") { console.error('\n %s(1) not executable. try chmod or run with root\n', bin); } }); this.runningCommand = proc; }; /** * Normalize `args`, splitting joined short flags. For example * the arg "-abc" is equivalent to "-a -b -c". * This also normalizes equal sign and splits "--abc=def" into "--abc def". * * @param {Array} args * @return {Array} * @api private */ Command.prototype.normalize = function(args) { var ret = [] , arg , lastOpt , index; for (var i = 0, len = args.length; i < len; ++i) { arg = args[i]; if (i > 0) { lastOpt = this.optionFor(args[i-1]); } if (arg === '--') { // Honor option terminator ret = ret.concat(args.slice(i)); break; } else if (lastOpt && lastOpt.required) { ret.push(arg); } else if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) { arg.slice(1).split('').forEach(function(c) { ret.push('-' + c); }); } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) { ret.push(arg.slice(0, index), arg.slice(index + 1)); } else { ret.push(arg); } } return ret; }; /** * Parse command `args`. * * When listener(s) are available those * callbacks are invoked, otherwise the "*" * event is emitted and those actions are invoked. * * @param {Array} args * @return {Command} for chaining * @api private */ Command.prototype.parseArgs = function(args, unknown) { var name; if (args.length) { name = args[0]; if (this.listeners(name).length) { this.emit(args.shift(), args, unknown); } else { this.emit('*', args); } } else { outputHelpIfNecessary(this, unknown); // If there were no args and we have unknown options, // then they are extraneous and we need to error. if (unknown.length > 0) { this.unknownOption(unknown[0]); } } return this; }; /** * Return an option matching `arg` if any. * * @param {String} arg * @return {Option} * @api private */ Command.prototype.optionFor = function(arg) { for (var i = 0, len = this.options.length; i < len; ++i) { if (this.options[i].is(arg)) { return this.options[i]; } } }; /** * Parse options from `argv` returning `argv` * void of these options. * * @param {Array} argv * @return {Array} * @api public */ Command.prototype.parseOptions = function(argv) { var args = [] , len = argv.length , literal , option , arg; var unknownOptions = []; // parse options for (var i = 0; i < len; ++i) { arg = argv[i]; // literal args after -- if ('--' == arg) { literal = true; continue; } if (literal) { args.push(arg); continue; } // find matching Option option = this.optionFor(arg); // option is defined if (option) { // requires arg if (option.required) { arg = argv[++i]; if (null == arg) return this.optionMissingArgument(option); this.emit(option.name(), arg); // optional arg } else if (option.optional) { arg = argv[i+1]; if (null == arg || ('-' == arg[0] && '-' != arg)) { arg = null; } else { ++i; } this.emit(option.name(), arg); // bool } else { this.emit(option.name()); } continue; } // looks like an option if (arg.length > 1 && '-' == arg[0]) { unknownOptions.push(arg); // If the next argument looks like it might be // an argument for this option, we pass it on. // If it isn't, then it'll simply be ignored if (argv[i+1] && '-' != argv[i+1][0]) { unknownOptions.push(argv[++i]); } continue; } // arg args.push(arg); } return { args: args, unknown: unknownOptions }; }; /** * Return an object containing options as key-value pairs * * @return {Object} * @api public */ Command.prototype.opts = function() { var result = {} , len = this.options.length; for (var i = 0 ; i < len; i++) { var key = this.options[i].name(); result[key] = key === 'version' ? this._version : this[key]; } return result; }; /** * Argument `name` is missing. * * @param {String} name * @api private */ Command.prototype.missingArgument = function(name) { console.error(); console.error(" error: missing required argument `%s'", name); console.error(); process.exit(1); }; /** * `Option` is missing an argument, but received `flag` or nothing. * * @param {String} option * @param {String} flag * @api private */ Command.prototype.optionMissingArgument = function(option, flag) { console.error(); if (flag) { console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); } else { console.error(" error: option `%s' argument missing", option.flags); } console.error(); process.exit(1); }; /** * Unknown option `flag`. * * @param {String} flag * @api private */ Command.prototype.unknownOption = function(flag) { console.error(); console.error(" error: unknown option `%s'", flag); console.error(); process.exit(1); }; /** * Variadic argument with `name` is not the last argument as required. * * @param {String} name * @api private */ Command.prototype.variadicArgNotLast = function(name) { console.error(); console.error(" error: variadic arguments must be last `%s'", name); console.error(); process.exit(1); }; /** * Set the program version to `str`. * * This method auto-registers the "-V, --version" flag * which will print the version number when passed. * * @param {String} str * @param {String} flags * @return {Command} for chaining * @api public */ Command.prototype.version = function(str, flags) { if (0 == arguments.length) return this._version; this._version = str; flags = flags || '-V, --version'; this.option(flags, 'output the version number'); this.on('version', function() { process.stdout.write(str + '\n'); process.exit(0); }); return this; }; /** * Set the description to `str`. * * @param {String} str * @return {String|Command} * @api public */ Command.prototype.description = function(str) { if (0 == arguments.length) return this._description; this._description = str; return this; }; /** * Set an alias for the command * * @param {String} alias * @return {String|Command} * @api public */ Command.prototype.alias = function(alias) { if (0 == arguments.length) return this._alias; this._alias = alias; return this; }; /** * Set / get the command usage `str`. * * @param {String} str * @return {String|Command} * @api public */ Command.prototype.usage = function(str) { var args = this._args.map(function(arg) { return humanReadableArgName(arg); }); var usage = '[options]' + (this.commands.length ? ' [command]' : '') + (this._args.length ? ' ' + args.join(' ') : ''); if (0 == arguments.length) return this._usage || usage; this._usage = str; return this; }; /** * Get the name of the command * * @param {String} name * @return {String|Command} * @api public */ Command.prototype.name = function(name) { return this._name; }; /** * Return the largest option length. * * @return {Number} * @api private */ Command.prototype.largestOptionLength = function() { return this.options.reduce(function(max, option) { return Math.max(max, option.flags.length); }, 0); }; /** * Return help for options. * * @return {String} * @api private */ Command.prototype.optionHelp = function() { var width = this.largestOptionLength(); // Prepend the help information return [pad('-h, --help', width) + ' ' + 'output usage information'] .concat(this.options.map(function(option) { return pad(option.flags, width) + ' ' + option.description; })) .join('\n'); }; /** * Return command help documentation. * * @return {String} * @api private */ Command.prototype.commandHelp = function() { if (!this.commands.length) return ''; var commands = this.commands.map(function(cmd) { var args = cmd._args.map(function(arg) { return humanReadableArgName(arg); }).join(' '); return [ cmd._name + (cmd._alias ? '|' + cmd._alias : '') + (cmd.options.length ? ' [options]' : '') + ' ' + args , cmd.description() ]; }); var width = commands.reduce(function(max, command) { return Math.max(max, command[0].length); }, 0); return [ '' , ' Commands:' , '' , commands.map(function(cmd) { return pad(cmd[0], width) + ' ' + cmd[1]; }).join('\n').replace(/^/gm, ' ') , '' ].join('\n'); }; /** * Return program help documentation. * * @return {String} * @api private */ Command.prototype.helpInformation = function() { return [ '' , ' Usage: ' + this._name + (this._alias ? '|' + this._alias : '') + ' ' + this.usage() , '' + this.commandHelp() , ' Options:' , '' , '' + this.optionHelp().replace(/^/gm, ' ') , '' , '' ].join('\n'); }; /** * Output help information for this command * * @api public */ Command.prototype.outputHelp = function() { process.stdout.write(this.helpInformation()); this.emit('--help'); }; /** * Output help information and exit. * * @api public */ Command.prototype.help = function() { this.outputHelp(); process.exit(); }; /** * Camel-case the given `flag` * * @param {String} flag * @return {String} * @api private */ function camelcase(flag) { return flag.split('-').reduce(function(str, word) { return str + word[0].toUpperCase() + word.slice(1); }); } /** * Pad `str` to `width`. * * @param {String} str * @param {Number} width * @return {String} * @api private */ function pad(str, width) { var len = Math.max(0, width - str.length); return str + Array(len + 1).join(' '); } /** * Output help information if necessary * * @param {Command} command to output help for * @param {Array} array of options to search for -h or --help * @api private */ function outputHelpIfNecessary(cmd, options) { options = options || []; for (var i = 0; i < options.length; i++) { if (options[i] == '--help' || options[i] == '-h') { cmd.outputHelp(); process.exit(0); } } } /** * Takes an argument an returns its human readable equivalent for help usage. * * @param {Object} arg * @return {String} * @api private */ function humanReadableArgName(arg) { var nameOutput = arg.name + (arg.variadic === true ? '...' : ''); return arg.required ? '<' + nameOutput + '>' : '[' + nameOutput + ']' } provide("commander", module.exports); }(global)); // pakmanager:nan (function (context) { var module = { exports: {} }, exports = module.exports , $ = require("ender") ; console.log(require('path').relative('.', __dirname)); provide("nan", module.exports); }(global)); // pakmanager:tinycolor (function (context) { var module = { exports: {} }, exports = module.exports , $ = require("ender") ; var styles = { 'bold': ['\033[1m', '\033[22m'], 'italic': ['\033[3m', '\033[23m'], 'underline': ['\033[4m', '\033[24m'], 'inverse': ['\033[7m', '\033[27m'], 'black': ['\033[30m', '\033[39m'], 'red': ['\033[31m', '\033[39m'], 'green': ['\033[32m', '\033[39m'], 'yellow': ['\033[33m', '\033[39m'], 'blue': ['\033[34m', '\033[39m'], 'magenta': ['\033[35m', '\033[39m'], 'cyan': ['\033[36m', '\033[39m'], 'white': ['\033[37m', '\033[39m'], 'default': ['\033[39m', '\033[39m'], 'grey': ['\033[90m', '\033[39m'], 'bgBlack': ['\033[40m', '\033[49m'], 'bgRed': ['\033[41m', '\033[49m'], 'bgGreen': ['\033[42m', '\033[49m'], 'bgYellow': ['\033[43m', '\033[49m'], 'bgBlue': ['\033[44m', '\033[49m'], 'bgMagenta': ['\033[45m', '\033[49m'], 'bgCyan': ['\033[46m', '\033[49m'], 'bgWhite': ['\033[47m', '\033[49m'], 'bgDefault': ['\033[49m', '\033[49m'] } Object.keys(styles).forEach(function(style) { Object.defineProperty(String.prototype, style, { get: function() { return styles[style][0] + this + styles[style][1]; }, enumerable: false }); }); provide("tinycolor", module.exports); }(global)); // pakmanager:options (function (context) { var module = { exports: {} }, exports = module.exports , $ = require("ender") ; /*! * Copyright(c) 2011 Einar Otto Stangvik <einaros@gmail.com> * MIT Licensed */ var fs = require('fs'); function Options(defaults) { var internalValues = {}; var values = this.value = {}; Object.keys(defaults).forEach(function(key) { internalValues[key] = defaults[key]; Object.defineProperty(values, key, { get: function() { return internalValues[key]; }, configurable: false, enumerable: true }); }); this.reset = function() { Object.keys(defaults).forEach(function(key) { internalValues[key] = defaults[key]; }); return this; }; this.merge = function(options, required) { options = options || {}; if (Object.prototype.toString.call(required) === '[object Array]') { var missing = []; for (var i = 0, l = required.length; i < l; ++i) { var key = required[i]; if (!(key in options)) { missing.push(key); } } if (missing.length > 0) { if (missing.length > 1) { throw new Error('options ' + missing.slice(0, missing.length - 1).join(', ') + ' and ' + missing[missing.length - 1] + ' must be defined'); } else throw new Error('option ' + missing[0] + ' must be defined'); } } Object.keys(options).forEach(function(key) { if (key in internalValues) { internalValues[key] = options[key]; } }); return this; }; this.copy = function(keys) { var obj = {}; Object.keys(defaults).forEach(function(key) { if (keys.indexOf(key) !== -1) { obj[key] = values[key]; } }); return obj; }; this.read = function(filename, cb) { if (typeof cb == 'function') { var self = this; fs.readFile(filename, function(error, data) { if (error) return cb(error); var conf = JSON.parse(data); self.merge(conf); cb(); }); } else { var conf = JSON.parse(fs.readFileSync(filename)); this.merge(conf); } return this; }; this.isDefined = function(key) { return typeof values[key] != 'undefined'; }; this.isDefinedAndNonNull = function(key) { return typeof values[key] != 'undefined' && values[key] !== null; }; Object.freeze(values); Object.freeze(this); } module.exports = Options; provide("options", module.exports); }(global)); // pakmanager:underscore (function (context) { var module = { exports: {} }, exports = module.exports , $ = require("ender") ; // Underscore.js 1.7.0 // http://underscorejs.org // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. (function() { // Baseline setup // -------------- // Establish the root object, `window` in the browser, or `exports` on the server. var root = this; // Save the previous value of the `_` variable. var previousUnderscore = root._; // 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 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. if (typeof exports !== 'undefined') { if (typeof module !== 'undefined' && module.exports) { exports = module.exports = _; } exports._ = _; } else { root._ = _; } // Current version. _.VERSION = '1.7.0'; // Internal function that returns an efficient (for current engines) version // of the passed-in callback, to be repeatedly applied in other Underscore // functions. var createCallback = function(func, context, argCount) { if (context === void 0) return func; switch (argCount == null ? 3 : argCount) { case 1: return function(value) { return func.call(context, value); }; case 2: return function(value, other) { return func.call(context, value, other); }; case 3: return function(value, index, collection) { return func.call(context, value, index, collection); }; case 4: return function(accumulator, value, index, collection) { return func.call(context, accumulator, value, index, collection); }; } return function() { return func.apply(context, arguments); }; }; // A mostly-internal function to generate callbacks that can be applied // to each element in a collection, returning the desired result — either // identity, an arbitrary callback, a property matcher, or a property accessor. _.iteratee = function(value, context, argCount) { if (value == null) return _.identity; if (_.isFunction(value)) return createCallback(value, context, argCount); if (_.isObject(value)) return _.matches(value); return _.property(value); }; // Collection Functions // -------------------- // The cornerstone, an `each` implementation, aka `forEach`. // Handles raw objects in addition to array-likes. Treats all // sparse array-likes as if they were dense. _.each = _.forEach = function(obj, iteratee, context) { if (obj == null) return obj; iteratee = createCallback(iteratee, context); var i, length = obj.length; if (length === +length) { for (i = 0; i < length; i++) { iteratee(obj[i], i, obj); } } else { var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); } } return obj; }; // Return the results of applying the iteratee to each element. _.map = _.collect = function(obj, iteratee, context) { if (obj == null) return []; iteratee = _.iteratee(iteratee, context); var keys = obj.length !== +obj.length && _.keys(obj), length = (keys || obj).length, results = Array(length), currentKey; for (var index = 0; index < length; index++) { currentKey = keys ? keys[index] : index; results[index] = iteratee(obj[currentKey], currentKey, obj); } return results; }; var reduceError = 'Reduce of empty array with no initial value'; // **Reduce** builds up a single result from a list of values, aka `inject`, // or `foldl`. _.reduce = _.foldl = _.inject = function(obj, iteratee, memo, context) { if (obj == null) obj = []; iteratee = createCallback(iteratee, context, 4); var keys = obj.length !== +obj.length && _.keys(obj), length = (keys || obj).length, index = 0, currentKey; if (arguments.length < 3) { if (!length) throw new TypeError(reduceError); memo = obj[keys ? keys[index++] : index++]; } for (; index < length; index++) { currentKey = keys ? keys[index] : index; memo = iteratee(memo, obj[currentKey], currentKey, obj); } return memo; }; // The right-associative version of reduce, also known as `foldr`. _.reduceRight = _.foldr = function(obj, iteratee, memo, context) { if (obj == null) obj = []; iteratee = createCallback(iteratee, context, 4); var keys = obj.length !== + obj.length && _.keys(obj), index = (keys || obj).length, currentKey; if (arguments.length < 3) { if (!index) throw new TypeError(reduceError); memo = obj[keys ? keys[--index] : --index]; } while (index--) { currentKey = keys ? keys[index] : index; memo = iteratee(memo, obj[currentKey], currentKey, obj); } return memo; }; // Return the first value which passes a truth test. Aliased as `detect`. _.find = _.detect = function(obj, predicate, context) { var result; predicate = _.iteratee(predicate, context); _.some(obj, function(value, index, list) { if (predicate(value, index, list)) { result = value; return true; } }); return result; }; // Return all the elements that pass a truth test. // Aliased as `select`. _.filter = _.select = function(obj, predicate, context) { var results = []; if (obj == null) return results; predicate = _.iteratee(predicate, context); _.each(obj, function(value, index, list) { if (predicate(value, index, list)) results.push(value); }); return results; }; // Return all the elements for which a truth test fails. _.reject = function(obj, predicate, context) { return _.filter(obj, _.negate(_.iteratee(predicate)), context); }; // Determine whether all of the elements match a truth test. // Aliased as `all`. _.every = _.all = function(obj, predicate, context) { if (obj == null) return true; predicate = _.iteratee(predicate, context); var keys = obj.length !== +obj.length && _.keys(obj), length = (keys || obj).length, index, currentKey; for (index = 0; index < length; index++) { currentKey = keys ? keys[index] : index; if (!predicate(obj[currentKey], currentKey, obj)) return false; } return true; }; // Determine if at least one element in the object matches a truth test. // Aliased as `any`. _.some = _.any = function(obj, predicate, context) { if (obj == null) return false; predicate = _.iteratee(predicate, context); var keys = obj.length !== +obj.length && _.keys(obj), length = (keys || obj).length, index, currentKey; for (index = 0; index < length; index++) { currentKey = keys ? keys[index] : index; if (predicate(obj[currentKey], currentKey, obj)) return true; } return false; }; // Determine if the array or object contains a given value (using `===`). // Aliased as `include`. _.contains = _.include = function(obj, target) { if (obj == null) return false; if (obj.length !== +obj.length) obj = _.values(obj); return _.indexOf(obj, target) >= 0; }; // 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, _.property(key)); }; // Convenience version of a common use case of `filter`: selecting only objects // containing specific `key:value` pairs. _.where = function(obj, attrs) { return _.filter(obj, _.matches(attrs)); }; // Convenience version of a common use case of `find`: getting the first object // containing specific `key:value` pairs. _.findWhere = function(obj, attrs) { return _.find(obj, _.matches(attrs)); }; // Return the maximum element (or element-based computation). _.max = function(obj, iteratee, context) { var result = -Infinity, lastComputed = -Infinity, value, computed; if (iteratee == null && obj != null) { obj = obj.length === +obj.length ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value > result) { result = value; } } } else { iteratee = _.iteratee(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed > lastComputed || computed === -Infinity && result === -Infinity) { result = value; lastComputed = computed; } }); } return result; }; // Return the minimum element (or element-based computation). _.min = function(obj, iteratee, context) { var result = Infinity, lastComputed = Infinity, value, computed; if (iteratee == null && obj != null) { obj = obj.length === +obj.length ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value < result) { result = value; } } } else { iteratee = _.iteratee(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed < lastComputed || computed === Infinity && result === Infinity) { result = value; lastComputed = computed; } }); } return result; }; // Shuffle a collection, using the modern version of the // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). _.shuffle = function(obj) { var set = obj && obj.length === +obj.length ? obj : _.values(obj); var length = set.length; var shuffled = Array(length); for (var index = 0, rand; index < length; index++) { rand = _.random(0, index); if (rand !== index) shuffled[index] = shuffled[rand]; shuffled[rand] = set[index]; } return shuffled; }; // Sample **n** random values from a collection. // If **n** is not specified, returns a single random element. // The internal `guard` argument allows it to work with `map`. _.sample = function(obj, n, guard) { if (n == null || guard) { if (obj.length !== +obj.length) obj = _.values(obj); return obj[_.random(obj.length - 1)]; } return _.shuffle(obj).slice(0, Math.max(0, n)); }; // Sort the object's values by a criterion produced by an iteratee. _.sortBy = function(obj, iteratee, context) { iteratee = _.iteratee(iteratee, context); return _.pluck(_.map(obj, function(value, index, list) { return { value: value, index: index, criteria: iteratee(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; }), 'value'); }; // An internal function used for aggregate "group by" operations. var group = function(behavior) { return function(obj, iteratee, context) { var result = {}; iteratee = _.iteratee(iteratee, context); _.each(obj, function(value, index) { var key = iteratee(value, index, obj); behavior(result, value, key); }); 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 = group(function(result, value, key) { if (_.has(result, key)) result[key].push(value); else result[key] = [value]; }); // Indexes the object's values by a criterion, similar to `groupBy`, but for // when you know that your index values will be unique. _.indexBy = group(function(result, value, key) { result[key] = value; }); // Counts instances of an object that group by a certain criterion. Pass // either a string attribute to count by, or a function that returns the // criterion. _.countBy = group(function(result, value, key) { if (_.has(result, key)) result[key]++; else result[key] = 1; }); // Use a comparator function to figure out the smallest index at which // an object should be inserted so as to maintain order. Uses binary search. _.sortedIndex = function(array, obj, iteratee, context) { iteratee = _.iteratee(iteratee, context, 1); var value = iteratee(obj); var low = 0, high = array.length; while (low < high) { var mid = low + high >>> 1; if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; } return low; }; // Safely create a real, live array from anything iterable. _.toArray = function(obj) { if (!obj) return []; if (_.isArray(obj)) return slice.call(obj); if (obj.length === +obj.length) return _.map(obj, _.identity); 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; }; // Split a collection into two arrays: one whose elements all satisfy the given // predicate, and one whose elements all do not satisfy the predicate. _.partition = function(obj, predicate, context) { predicate = _.iteratee(predicate, context); var pass = [], fail = []; _.each(obj, function(value, key, obj) { (predicate(value, key, obj) ? pass : fail).push(value); }); return [pass, fail]; }; // 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; if (n == null || guard) return array[0]; if (n < 0) return []; return slice.call(array, 0, n); }; // Returns everything but the last entry of the array. Especially useful on // the arguments object. Passing **n** will return all the values in // the array, excluding the last N. The **guard** check allows it to work with // `