Example #1
0
var stream = require('stream');
var Transform = stream.Transform;
var Duplex = stream.Duplex;
var dgram = require('dgram');
var crypto = require('crypto');
var crc32 = require('buffer-crc32');
var util = require('util');
var _ = require('underscore');

_.mixin({
  options: function(self, options, defaults) {
    if (options)
      _.extend(self, _.defaults(_.pick(options, _.keys(defaults)), defaults));
    else
      _.extend(self, defaults);
  }
});

var thumbs = {
  twiddle: function() {}
};

var defaults = {
  address: '0.0.0.0',
  type: 'udp4',
  port: 12345,
  broadcast: null,
  multicast: null,
  multicastTTL: 1,
  // for testing
  scope: null
Example #2
0
//		var $div = $('<div class="asdf">asdf</div>');
//
//		log(_.isElement($body));
//		log(_.isElement($body[0]));
//		log(_.isElement($div));
//		log(_.isElement($div[0]));
//	}
//});


/*times*/
_(15).times(log);

/*mixin*/
_.mixin({sqr: function (number) {
	return number * number;
}});

_.mixin({sqrArray: function (array) {
	return _.map(array, _.sqr);
}});

_.chain([1, 2, 3])
	.map(_.sqr)
	.tap(log);

_.chain([3, 1, 2])
	.sqrArray()
	.tap(log);

Example #3
0
(function (global) {

    var core = require('../core'),
        _ = require('underscore'),
        _str = require('underscore.string');

        require('../query/expressions');
        require('../query/expressionvisitor');
        require('../query/queryparser');
        require('./sqlbooleanizer');
        require('./typeconverter');
        require('./sqlhelpers');

    _.mixin(_str.exports());

    var ctor = function (schemaName, tableMetadata) {
        this.schemaName = schemaName;
        this.tableMetadata = tableMetadata;
    };

    var instanceMembers = {

        format: function (query) {
            this.sql = '';
            this.paramNumber = 0;
            this.parameters = [];

            // if a skip is requested but no top is defined, we need
            // to still generate the paging query, so default top to
            // max. Really when doing paging, the user should also be
            // specifying a top explicitly however.
            if (query.skip > 0 && query.take === undefined) {
                query.take = Number.MAX_SAFE_INTEGER;
            }

            if (query.skip >= 0 && query.take >= 0) {
                this.sql = this._formatPagedQuery(query);
            }
            else {
                this.sql = this._formatQuery(query);
            }

            this.sql = this.sql.trim();
        },

        _formatQuery: function (query) {
            var formattedSql;

            var selection = query.selections ? this._formatSelection(query.selections, query.systemProperties) : '*';

            // set the top clause to be the minimumn of the top
            // and result limit values if either has been set.
            var take = '';
            var limit = -1;
            var resultLimit = query.resultLimit || Number.MAX_VALUE;
            if (query.take >= 0) {
                limit = Math.min(resultLimit, query.take);
            }
            else if (resultLimit != Number.MAX_VALUE) {
                limit = query.resultLimit;
            }
            if (limit != -1) {
                take = 'TOP ' + limit.toString() + ' ';
            }

            var filter = this._formatFilter(query);
            var ordering = this._formatOrderBy(query);

            var tableName = SqlHelpers.formatTableName(this.schemaName, query.table);
            formattedSql = _.sprintf("SELECT %s%s FROM %s", take, selection, tableName);
            if (filter.length > 0) {
                formattedSql += ' WHERE ' + filter;
            }
            if (ordering.length > 0) {
                formattedSql += ' ORDER BY ' + ordering;
            }

            if (query.inlineCount === 'allpages') {
                formattedSql += '; ' + this._formatCountQuery(tableName, query);
            }

            return formattedSql;
        },

        _formatPagedQuery: function (query) {
            var formattedSql, selection = '',
                aliasedSelection = '';

            if (query.selections) {
                selection = this._formatSelection(query.selections, query.systemProperties);
                aliasedSelection = '[t1].[ROW_NUMBER], ' + this._formatSelection(query.selections, query.systemProperties, '[t1].');
            }
            else {
                selection = aliasedSelection = "*";
            }

            var filter = this._formatFilter(query, '(1 = 1)');
            var ordering = this._formatOrderBy(query, '[id]');

            // Plug all the pieces into the template to get the paging sql
            var tableName = SqlHelpers.formatTableName(this.schemaName, query.table);
            formattedSql = _.sprintf(
                "SELECT %s FROM (SELECT ROW_NUMBER() OVER (ORDER BY %s) AS [ROW_NUMBER], %s " +
                "FROM %s WHERE %s) AS [t1] " +
                "WHERE [t1].[ROW_NUMBER] BETWEEN %d + 1 AND %d + %d " +
                "ORDER BY [t1].[ROW_NUMBER]",
                aliasedSelection, ordering, selection, tableName, filter, query.skip, query.skip, query.take);

            if (query.inlineCount === 'allpages') {
                formattedSql += '; ' + this._formatCountQuery(tableName, query);
            }

            return formattedSql;
        },

        _formatCountQuery: function (table, query) {
            var filter;

            if (query.filters || query.id !== undefined || this.tableMetadata.supportsSoftDelete) {
                this.sql = '';
                filter = this._formatFilter(query);
            }

            var sql = 'SELECT COUNT(*) AS [count] FROM ' + table;
            if (filter) {
                sql += ' WHERE ' + filter;
            }
            return sql;
        },

        _formatOrderBy: function (query, defaultOrder) {
            var ordering = query.ordering;

            if (!ordering) {
                return defaultOrder || '';
            }

            // if we already have a parsed orderby, us it,
            // otherwise parse the orderby
            var orderings;
            if (query._parsed && query._parsed.ordering) {
                orderings = query._parsed.ordering;
            }
            else {
                orderings = QueryParser.orderBy(ordering);
            }

            var order = '';
            var self = this;
            orderings.forEach(function (ordering) {
                if (order.length > 0) {
                    order += ', ';
                }
                self.sql = '';
                self.visit(ordering.selector);
                if (!ordering.ascending) {
                    self.sql += ' DESC';
                }
                order += self.sql;
            });

            return order;
        },

        _formatSelection: function (selection, systemProperties, prefix) {
            systemProperties = (systemProperties || []).map(core.systemPropertyToColumnName);

            var formattedSelection = '',
                columns = selection.split(',').concat(systemProperties);

            columns.forEach(function (column) {
                var member = column.trim();
                if (formattedSelection.length > 0) {
                    formattedSelection += ', ';
                }
                formattedSelection += (prefix || '') + SqlHelpers.formatMember(member);
            });

            return formattedSelection;
        },

        _formatFilter: function (query, defaultFilter) {
            // if we already have a parsed filter use it,
            // otherwise parse the filter
            var filterExpr;
            if (query._parsed && query._parsed.filters) {
                filterExpr = query._parsed.filters;
            }
            else if (query.filters && query.filters.length > 0) {
                filterExpr = QueryParser.filter(query.filters);
            }

            if (query.id !== undefined) {
                var id = this.tableMetadata.hasStringId ? "'" + query.id.replace(/'/g, "''") + "'" : query.id;
                var idFilterExpr = QueryParser.filter(_.sprintf('(id eq %s)', id));

                // append the id filter to any existing filter
                if (filterExpr) {
                    filterExpr = new BinaryExpression(filterExpr, idFilterExpr, ExpressionType.And);
                }
                else {
                    filterExpr = idFilterExpr;
                }
            }

            // if soft delete is enabled filter out deleted records
            if (this.tableMetadata.supportsSoftDelete && !query.includeDeleted) {
                var deletedFilter = QueryParser.filter(_.sprintf('(__deleted eq false)'));
                if (filterExpr) {
                    filterExpr = new BinaryExpression(filterExpr, deletedFilter, ExpressionType.And);
                }
                else {
                    filterExpr = deletedFilter;
                }
            }

            if (!filterExpr) {
                return defaultFilter || '';
            }

            this.sql = '';
            filterExpr = this._finalizeExpression(filterExpr);
            this.visit(filterExpr);

            return this.sql;
        },

        // run the final query translation pipeline on the specified
        // expression, modifying the expression tree as needed
        _finalizeExpression: function (expr) {
            expr = SqlBooleanizer.booleanize(expr);
            expr = TypeConverter.convertTypes(expr, this.tableMetadata);
            return expr;
        },

        visitBinary: function (expr) {
            this.sql += '(';

            var left = null;
            var right = null;

            // modulo requires the dividend to be an integer, monetary or numeric
            // rewrite the expression to convert to numeric, allowing the DB to apply
            // rounding if needed. our default data type for number is float which
            // is incompatible with modulo.
            if (expr.expressionType == ExpressionType.Modulo) {
                expr.left = new ConvertExpression('numeric', expr.left);
            }

            if (expr.left) {
                left = this.visit(expr.left);
            }

            if (expr.right && (expr.right.value === null)) {
                // inequality expressions against a null literal have a special
                // translation in SQL
                if (expr.expressionType == ExpressionType.Equal) {
                    this.sql += ' IS NULL';
                }
                else if (expr.expressionType == ExpressionType.NotEqual) {
                    this.sql += ' IS NOT NULL';
                }
            }
            else {
                switch (expr.expressionType) {
                    case ExpressionType.Equal:
                        this.sql += ' = ';
                        break;
                    case ExpressionType.NotEqual:
                        this.sql += ' != ';
                        break;
                    case ExpressionType.LessThan:
                        this.sql += ' < ';
                        break;
                    case ExpressionType.LessThanOrEqual:
                        this.sql += ' <= ';
                        break;
                    case ExpressionType.GreaterThan:
                        this.sql += ' > ';
                        break;
                    case ExpressionType.GreaterThanOrEqual:
                        this.sql += ' >= ';
                        break;
                    case ExpressionType.And:
                        this.sql += ' AND ';
                        break;
                    case ExpressionType.Or:
                        this.sql += ' OR ';
                        break;
                    case ExpressionType.Add:
                        this.sql += ' + ';
                        break;
                    case ExpressionType.Subtract:
                        this.sql += ' - ';
                        break;
                    case ExpressionType.Multiply:
                        this.sql += ' * ';
                        break;
                    case ExpressionType.Divide:
                        this.sql += ' / ';
                        break;
                    case ExpressionType.Modulo:
                        this.sql += ' % ';
                        break;
                }

                if (expr.right) {
                    right = this.visit(expr.right);
                }
            }

            this.sql += ')';

            if ((left !== expr.left) || (right !== expr.right)) {
                return new BinaryExpression(left, right);
            }

            return expr;
        },

        visitConstant: function (expr) {
            if (expr.value === null) {
                this.sql += 'NULL';
                return expr;
            }

            this.sql += this._createParameter(expr.value);

            return expr;
        },

        _createParameter: function (value) {
            var parameter = {
                name: '@p' + (this.paramNumber++).toString(),
                pos: this.paramNumber,
                value: value
            };

            this.parameters.push(parameter);

            // TODO: maintaining the above named parameter code for now
            // for when the sql driver supports them.
            return '?';
        },

        visitMember: function (expr) {
            if (typeof expr.member === 'string') {
                this.sql += SqlHelpers.formatMember(expr.member);
            }
            else {
                this._formatMappedMember(expr);
            }

            return expr;
        },

        visitUnary: function (expr) {
            if (expr.expressionType == ExpressionType.Not) {
                this.sql += 'NOT ';
                this.visit(expr.operand);
            }
            else if (expr.expressionType == ExpressionType.Convert) {
                this.sql += _.sprintf("CONVERT(%s, ", expr.desiredType);
                this.visit(expr.operand);
                this.sql += ')';
            }

            return expr;
        },

        visitFunction: function (expr) {
            if (expr.memberInfo) {
                this._formatMappedFunction(expr);
            }
            return expr;
        },

        _formatMappedFunction: function (expr) {
            if (expr.memberInfo.type == 'string') {
                this._formatMappedStringMember(expr.instance, expr.memberInfo, expr.args);
            }
            else if (expr.memberInfo.type == 'date') {
                this._formatMappedDateMember(expr.instance, expr.memberInfo, expr.args);
            }
            else if (expr.memberInfo.type == 'math') {
                this._formatMappedMathMember(expr.instance, expr.memberInfo, expr.args);
            }
        },

        _formatMappedMember: function (expr) {
            if (expr.member.type == 'string') {
                this._formatMappedStringMember(expr.instance, expr.member, null);
            }
        },

        _formatMappedDateMember: function (instance, mappedMemberInfo, args) {
            var functionName = mappedMemberInfo.memberName;

            if (functionName == 'day') {
                this.sql += 'DAY(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (mappedMemberInfo.memberName == 'month') {
                this.sql += 'MONTH(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (mappedMemberInfo.memberName == 'year') {
                this.sql += 'YEAR(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (mappedMemberInfo.memberName == 'hour') {
                this.sql += 'DATEPART(HOUR, ';
                this.visit(instance);
                this.sql += ')';
            }
            else if (mappedMemberInfo.memberName == 'minute') {
                this.sql += 'DATEPART(MINUTE, ';
                this.visit(instance);
                this.sql += ')';
            }
            else if (mappedMemberInfo.memberName == 'second') {
                this.sql += 'DATEPART(SECOND, ';
                this.visit(instance);
                this.sql += ')';
            }
        },

        _formatMappedMathMember: function (instance, mappedMemberInfo, args) {
            var functionName = mappedMemberInfo.memberName;

            if (functionName == 'floor') {
                this.sql += 'FLOOR(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (functionName == 'ceiling') {
                this.sql += 'CEILING(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (functionName == 'round') {
                // Use the 'away from zero' midpoint rounding strategy - when
                // a number is halfway between two others, it is rounded toward
                // the nearest number that is away from zero.
                this.sql += 'ROUND(';
                this.visit(instance);
                this.sql += ', 0)';
            }
        },

        _formatMappedStringMember: function (instance, mappedMemberInfo, args) {
            var functionName = mappedMemberInfo.memberName;

            if (functionName == 'substringof') {
                this.sql += '(';
                this.visit(instance);

                this.sql += ' LIKE ';

                // form '%' + <arg> + '%'
                this.sql += "('%' + ";
                this.visit(args[0]);
                this.sql += " + '%')";

                this.sql += ')';
            }
            else if (functionName == 'startswith') {
                this.sql += '(';
                this.visit(instance);

                this.sql += ' LIKE ';

                // form '<arg> + '%'
                this.sql += '(';
                this.visit(args[0]);
                this.sql += " + '%')";

                this.sql += ')';
            }
            else if (functionName == 'endswith') {
                this.sql += '(';
                this.visit(instance);

                this.sql += ' LIKE ';

                // form '%' + '<arg>
                this.sql += "('%' + ";
                this.visit(args[0]);
                this.sql += ')';

                this.sql += ')';
            }
            else if (functionName == 'concat') {
                // Rewrite as an string addition with appropriate conversions.
                // Note: due to sql operator precidence, we only need to inject a
                // single conversion - the other will be upcast to string.
                if (!isConstantOfType(args[0], 'string')) {
                    args[0] = new ConvertExpression(SqlHelpers.getSqlType(''), args[0]);
                } else if (!isConstantOfType(args[1], 'string')) {
                    args[1] = new ConvertExpression(SqlHelpers.getSqlType(''), args[1]);
                }
                var concat = new BinaryExpression(args[0], args[1], ExpressionType.Add);
                this.visit(concat);
            }
            else if (functionName == 'tolower') {
                this.sql += 'LOWER(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (functionName == 'toupper') {
                this.sql += 'UPPER(';
                this.visit(instance);
                this.sql += ')';
            }
            else if (functionName == 'length') {
                // special translation since SQL LEN function doesn't
                // preserve trailing spaces
                this.sql += '(LEN(';
                this.visit(instance);
                this.sql += " + 'X') - 1)";
            }
            else if (functionName == 'trim') {
                this.sql += 'LTRIM(RTRIM(';
                this.visit(instance);
                this.sql += '))';
            }
            else if (functionName == 'indexof') {
                this.sql += "(PATINDEX('%' + ";
                this.visit(args[0]);
                this.sql += " + '%', ";
                this.visit(instance);
                this.sql += ') - 1)';
            }
            else if (functionName == 'replace') {
                this.sql += "REPLACE(";
                this.visit(instance);
                this.sql += ", ";
                this.visit(args[0]);
                this.sql += ", ";
                this.visit(args[1]);
                this.sql += ')';
            }
            else if (functionName == 'substring') {
                this.sql += 'SUBSTRING(';
                this.visit(instance);

                this.sql += ", ";
                this.visit(args[0]);
                this.sql += " + 1, ";  // need to add 1 since SQL is 1 based, but OData is zero based

                if (args.length == 1) {
                    // Overload not taking an explicit length. The
                    // LEN of the entire expression is used in this case
                    // which means everything after the start index will
                    // be taken.
                    this.sql += 'LEN(';
                    this.visit(instance);
                    this.sql += ')';
                }
                else if (args.length == 2) {
                    // overload taking a length
                    this.visit(args[1]);
                }

                this.sql += ')';
            }
        }
    };

    function isConstantOfType(expr, type) {
        return (expr.expressionType == ExpressionType.Constant) && (typeof expr.value === type);
    }

    SqlFormatter = core.deriveClass(ExpressionVisitor, ctor, instanceMembers);

})(typeof exports === "undefined" ? this : exports);
Example #4
0
var path = require('path');
var Module = require('module');
var _ = require('underscore');
var gettextParser = require('gettext-parser');
var fs = require('fs');
var vm = require('vm');

global._ = _;
_.mixin(require('underscore.deepclone'));

if (process.env['NODE_PATH']) {
  process.env['NODE_PATH'] += ':' + path.resolve('./bower_components');
} else {
  process.env['NODE_PATH'] = path.resolve('./bower_components');
}
Module._initPaths();
module.paths.unshift(path.resolve('./bower_components'));
global.window = global;
var jsdom = require('jsdom');
var window = jsdom.jsdom().defaultView;
global.jQuery = global.$ = require('./bower_components/jquery/dist/jquery.js')(window);
global.document = window.document;
global.rivets = require('./bower_components/rivets/dist/rivets.js');
global.Backbone = require('./bower_components/backbone/backbone.js');
global.Backbone.DeepModel = require('backbone-deep-model');

// Disable the interpolation to catch up all of the patterns
_.templateSettings = {
  interpolate: null
};
global.Formbuilder = require('./formbuilder.js');
Example #5
0
(function(){
  'use strict';
  
  function ChainOfFoo( text, depth, callback, progress ){
    depth = depth || 1;
    
    var self = this;
    this.times = [];    
    var time = this.time = function( name ){
      var current = _( self.times ).find( function( time ){ return time.name === name; } );
      if( _( current ).isUndefined() ){
        current = {
          name: name,
          time: 0          
        };
        self.times.push( current );
      }
      current.start = Date.now();
    };
    var end = this.end = function( name ){
      var current = _( self.times ).find( function( time ){ return time.name === name; } );
      var now = Date.now();
      current.end = now;
      current.time += now - current.start;
    };   
    this.logTimes = function(){
      _( _( self.times ).sortBy( function( time ){ return time.time; } ) ).each( function( time ){
        console.log( time.time + ' / ' + time.name );
      });
    };
    
    this.time( 'total' );
    
    this.depth = depth;    
    this.progress = progress;
    this.callback = callback;
    this.map = {};
    this.text = text;
    time( 'split' );
    this.words = split( text );
    end( 'split' );
    this.mapCorpus();
  }

  var seperator = '\u241E';
  var regexs = {
    uppercase: /[A-Z]/,
    word: /[\w\']+/,
    toBeFollowedBySpace: /[\.\?\),:!;%]/,
    seperatorOrWhitespace: new RegExp( seperator + '|\s' ),
    terminator: /[\.\?!]/
  };
  
  _.mixin({
    flatMap: function( obj, iterator, context ){
      return _( obj ).chain().map( iterator, context ).flatten().value();
    },
    isWord: function( value ){
      return regexs.word.test( value );
    },
    setFlags: function( regex, flags ){
      return new RegExp( regex.source, flags );
    },
    capture: function( regex, flags ){
      return new RegExp( '(' + regex.source + ')', flags );
    },
    spaceAfterPunctuation: function( value ){
      return value.replace( _( regexs.toBeFollowedBySpace ).setFlags( 'g' ), function( c ){ 
        return c + ' '; 
      });
    },
    spaceBeforePunctuation: function( value ){
      return value.replace( /\(/g, ' (' );
    }
  });
  
  ChainOfFoo.prototype.generate = function( length, startUpper, endOnPunc ){    
    length = length || 50;
    length = length < 1 ? 1 : length;
    var self = this;
    var result = '';
    var nextWord;
    var lastWord;
    
    if( self.words.length < 2 ){      
      if( self.words.length === 0 ){
        return '';
      }
      return self.words[ 0 ];
    }    
    
    var startIds = _( self.map ).keys();
    
    if( startUpper ){
      var upperIds = _( startIds ).filter( function( word ){
        var c = word[ 0 ];
        return regexs.uppercase.test( c );
      });
      if( upperIds.length > 0 ){
        startIds = upperIds;
      }
    }
    
    var currentId = _( startIds ).sample();
    var words = currentId.split( seperator );
    var text = words.join( ' ' );
    
    result += text;
    length--;
    
    var hasEnded = false;
    var atEnd = false;
    while( !hasEnded ){            
      var nexts = self.map[ currentId ];
      if( _( nexts ).isUndefined() ){
        hasEnded = true;
      }
      if( _( nexts ).isArray() && nexts.length > 0 ){              
        nextWord = _( nexts ).sample();
        //if we should be ending, if possible bias the selection 
        //towards words that are near the end of a sentence.
        if( atEnd && endOnPunc ){          
          //try to only get the nexts that are terminators
          var possible = _( nexts ).filter( function( next ){
            return regexs.terminator.test( next );
          });
          
          //maybe none of the nexts were terminators?
          if( possible.length === 0 ){
            //see if any of the nexts themselves have terminator children
            possible = _( nexts ).filter( function( next ){
              return _( self.map[ next ] ).filter( function( next ){
                return regexs.terminator.test( next );
              });
            });
          }
          
          //only if we have a terminator or a child with a terminator
          if( possible.length > 0 ){
            nextWord = _( possible ).sample();
          }
        } 
        
        result += ( _( nextWord ).isWord() && _( lastWord ).isWord() ? ' ' : '' ) + nextWord;
        lastWord = nextWord;
        currentId = currentId.split( seperator ).slice( 1 ).concat( nextWord ).join( seperator );
        if( _( nextWord ).isWord() ){
          length--;
        }        
        atEnd = length < 1;
      }      
      
      if( !hasEnded ){
        if( endOnPunc ){
          hasEnded = atEnd && regexs.terminator.test( nextWord );
        } else {
          hasEnded = atEnd;
        }
      }
    }
    return _( result ).chain().spaceAfterPunctuation().spaceBeforePunctuation().value();
  };
  
  function split( text ){
    var seperated = text.replace( _( regexs.word ).setFlags( 'g' ), function( word ){
      return word + seperator;
    });
    
    var split = seperated.split( /\u241E|\s/ );    
    return ( 
      _( split )
      .chain()
      .flatMap( function( word ){
        return word.split( _( regexs.word ).capture( 'g' ) );
      })
      .flatMap( function( word ){
        if( _( word ).isWord() ){
          return word;
        }
        return word.split( '' );
      })
      .filter( function( word ){
        return word !== '';
      })
      .value()
    );
  }
  
  function mapWord( context, mapping, word, i ){
    var prefix = [];    
    context.time( 'mapWord' );
    for( var j = 0; j < context.depth; j++ ){          
      var index = i + j;
      if( index < context.words.length - 1 ){
        prefix.push( context.words[ index ] );
      }
    }
    var identifier = prefix.join( seperator );
    if( i < context.words.length - 1 ){
      var next = context.words[ i + context.depth ];        
      if( !_( mapping ).has( identifier ) ){
        mapping[ identifier ] = [ next ];
      } else {
        mapping[ identifier ].push( next );
      }        
    }
    context.end( 'mapWord' );
  }

  ChainOfFoo.prototype.mapCorpus = function(){
    var context = this;
    var mapping = {};
    
    var timerId;
    var i = 0;
    context.time( 'mapCorpus' );
    function delayWord(){
      mapWord( context, mapping, context.words[ i ], i );
      if( _( context.progress ).isFunction() ){
        context.progress( i, context.words.length );
      }        
      i++;
      if( i < context.words.length ){
        timerId = setImmediate( delayWord );
      } else {     
        clearImmediate( timerId );
        context.map = mapping;
        context.end( 'mapCorpus' );
        context.end( 'total' );
        if( _( context.callback ).isFunction() ){
          context.callback( context );
        }
      }
    };
    delayWord();
  };
  
  module.exports = ChainOfFoo;
})();  
Example #6
0
var _  = require('underscore'),
    utils = require('../utils/utils'),
    db = {};

_.mixin(require('../utils/db-mixins'));

exports.setDatabase = function(object) {
  db = object;
}

exports.database = function(req, res) {
  res.jsonp(db)
}

// GET /:resource?attr=&attr=
exports.list = function(req, res) {
  var collection = db[req.params.resource],
      properties = {},
      result;

  Object.keys(req.query).forEach(function (key) {
    var value = req.query[key];
    properties[key] = utils.toNative(value);
  });
    
  if (_(properties).isEmpty()) {
    result = collection;
  } else {
    result = _(collection).where(properties);
  }
Example #7
0
var _ = require('underscore');

// from => object delegate from
// to => object or function delegate to
//      function will be lazy evaluated in the context of from
// function_name => function to be delegated
//
_.mixin({delegate: function(from, to, function_name) {
    from[function_name] = function() {
        if (_.isFunction(to)) {
            to = _.bind(to, from)();
        }

        if (_.isEmpty(arguments)) {
            return to[function_name].call(to);
        } else {
            return to[function_name].apply(to, arguments);
        }
    };
}});
Example #8
0
        type = 'date';
    }else if(_.isRegExp(value)){
        type = 'regexp';
    }else if(_.isFunction(value)){
        type = 'function';
    }else if(_.isArray(value)){
        type = 'array';
    }else if(_.isObject(value)){
        type = 'object';
    }
    return type;
}

/**
 *
 * Checks a value is undefined or null
 *
 * @param value
 * @returns {boolean}
 */
function isDefined(value){
    return getType(value) !== 'null' && getType(value) !== 'undefined';
}

_.mixin({
    getType: getType,
    isDefined: isDefined
});

module.exports = _;
Example #9
0
var needle = require("needle");
var fs = require("fs");
var _ = require("underscore");
var log4js = require("log4js");

// Used to deep merge configs
var deepExt = require("underscore-deep-extend");
// Wire deepExtend function
_.mixin({deepExtend: deepExt(_)});
var sun = require("suncalc");
var when = require("when");

// local deps
var hue = require("./hue-api");
var configs = require("./state");
var server = require("./rest");
var pluginManager = require("./pluginManager");
var utils = require("./utils");

// console.log(configs.general.logging.fileAppender);
// log4js.configure({
//   appenders: [
//     { type: "console" },
//     configs.general.logging.fileAppender
//   ],
//   replaceConsole: true,
//   levels : {
// 	"Rest" : "DEBUG"
//   }
// });
  add(value) {
    this.iterations++
    let prevValue = this.values_[this.index_]
    if (prevValue === undefined) {
      this.count++
      prevValue = 0
    }
    this.sum += value - prevValue
    this.values_[this.index_] = value
    this.index_ = (this.index_ + 1) % this.values_.length
  }

  get variance() {
    const avg = this.value
    let sum = 0
    let count = 0
    const increment = this.count > 12 ? 4 : 1
    for (let i = 0; i < this.count; i += increment) {
      const value = this.values_[i]
      if (value === undefined) continue
      sum += Math.pow(value - avg, 2)
      count++
    }
    return sum / count
  }
}

_.mixin({
  simpleMovingAverage: (period) => new SMA(period),
})
Example #11
0
var helpers = {};
var namespace = null;
var moment = require('moment-timezone');
var _ = require('underscore');
_.mixin(require('underscore.nested'));
var url = require('url');
var handlebars = require('handlebars');

helpers.compare = function(lvalue, rvalue, options) {
  if (arguments.length < 3) {
    var err = "Handlerbars Helper 'compare' needs 2 parameters";
    console.log(err);
    throw new Error(err);
  }
  operator = options.hash.operator || "==";

  var operators = {
    '==':       function(l,r) { return l == r; },
    '===':      function(l,r) { return l === r; },
    '!=':       function(l,r) { return l != r; },
    '<':        function(l,r) { return l < r; },
    '>':        function(l,r) { return l > r; },
    '<=':       function(l,r) { return l <= r; },
    '>=':       function(l,r) { return l >= r; },
    'typeof':   function(l,r) { return typeof l == r; }
  }

  if (!operators[operator]) {
    throw new Error("Handlerbars Helper 'compare' doesn't know the operator "+operator);
  }
Example #12
0
File: ext.js Project: villadora/jsr
var _ = require('underscore');


_.mixin({
    deepClone: function(obj) {
        function __deepClone(source, target) {
            var key, val;
            for (key in source) {
                if (key.lastIndexOf('__', 0) === 0) {
                    // escape internal property
                    continue;
                }

                if (source.hasOwnProperty(key)) {
                    val = source[key];
                    if (typeof val === 'object' && val !== null) {
                        if (val instanceof RegExp) {
                            val = new RegExp(val);
                        } else {
                            val = __deepClone(val, _.isArray(val) ? [] : {});
                        }
                    }
                    target[key] = val;
                }
            }
            return target;
        }

        return __deepClone(obj, _.isArray(obj) ? [] : {});
    }
});
Example #13
0
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import reducers from './reducers/'
import Router from './components/router'
import { instance as user } from './lib/user'
import _ from 'underscore'
import s from 'underscore.string'
import assign from 'es6-object-assign'
import cookie from 'js-cookie'

require('whatwg-fetch')

_.mixin(s.exports())
assign.polyfill()

user.set(JSON.parse(cookie.get('user') || '{}'))
user.onChange((data) => cookie.set('user', data, { expires: 7 }))

const store = createStore(reducers, applyMiddleware(thunk))

render(
	<Provider store={store}>{Router}</Provider>,
	document.getElementById('app')
)
/*
 Performs Cookie-signed requests to the backend. 
 Think of this as a HTTP client for the rest of the library.
 httpOpts get passed from the object model for lists, list items etc, and feed into request. 
 */

var _ = require('underscore'),
request = require('request'),
underscoreDeepExtend = require('underscore-deep-extend'),
constants = require('../../constants.js');

_.mixin({
  deepExtend: underscoreDeepExtend(_)
});

module.exports = function(client, httpOpts, waterfallCb){
  //Remove the body from SP_ONLINE_SECURITY_OPTIONS before we deepExtend so we can update items.
  //Strings and JSON don't mix when doing deepExtends
  if(constants.SP_ONLINE_SECURITY_OPTIONS.hasOwnProperty('body')) {
    delete constants.SP_ONLINE_SECURITY_OPTIONS.body;
  }
  var requestOpts = _.deepExtend({}, httpOpts, client.baseHTTPOptions, constants.SP_ONLINE_SECURITY_OPTIONS, {
    headers: {
      'Cookie': 'FedAuth=' + client.FedAuth + '; rtFa=' + client.rtFa,
      'Accept' : 'application/json; odata=verbose',
      'Content-Type' : 'application/json; odata=verbose'
    },
    json : httpOpts.json || true,
    timeout: constants.SP_ONLINE_TIMEOUT
  }, httpOpts);
  return request(requestOpts, waterfallCb);
turtle-to-jsonld
Copyright 2013,2014 Kuno Woudt <*****@*****.**>

turtle-to-jsonld is licensed under Apache v2, see
LICENSE.txt for more information.

*/

var N3 = require ('n3');
var jsonld = require ('jsonld').promises;
var processContext = require ('jsonld').processContext;
var when = require ('when');
var _ = require ('underscore');

_.mixin(require('underscore.string').exports());

var term = function (str) {
    if (N3.Util.isBlank(str)) {
        return {
            type: 'blank node',
            value: str
        };
    } else if (N3.Util.isLiteral(str)) {
        var ret = {
            type: 'literal',
            value: N3.Util.getLiteralValue(str),
            datatype: N3.Util.getLiteralType(str),
        };

        var language = N3.Util.getLiteralLanguage(str);
Example #16
0
var _ = require('underscore');
_.mixin( require('underscore.deferred') );
var inflection = require('inflection');
var Twit = require('twit');
var T = new Twit(require('./config.js'));
var wordfilter = require('wordfilter');
var ent = require('ent');
var pos = require('pos');
var wordnikKey = require('./permissions.js').key;
var request = require('request');

Array.prototype.pick = function() {
  return this[Math.floor(Math.random()*this.length)];
};

Array.prototype.pickRemove = function() {
  var index = Math.floor(Math.random()*this.length);
  return this.splice(index,1)[0];
};

function getNouns(words) {
  var nouns = [];
  // accepts an array of words
  words = new pos.Lexer().lex(words.join(' '));
  var taggedWords = new pos.Tagger().tag(words);
  for (var i=0;i<taggedWords.length;i++) {
    var taggedWord = taggedWords[i];
    var word = taggedWord[0];
    var tag = taggedWord[1];
    console.log(word, tag, tag.length, tag==='NN');
    if (tag === 'NN' || tag === 'NNS') {
Example #17
0
"use strict";var _=require("underscore"),Mustache=require("mustache"),xml2js=require("xml2js"),builder=new xml2js.Builder;_.mixin({stringValue:function(r){return _.isArray(r)?(r=r[0],r._?r._:r):r},variables:function(r){return _.isString(r)?_.map(_.filter(Mustache.parse(r),function(r){return"&"===r[0]}),function(r){return r[1]}):null},hasVariable:function(r){return _.isString(r)&&0!==_.variables(r).length},deepCopy:function(r){if(!_.isObject(r))throw new Error("_.deepCopy() : argument should be object.");return JSON.parse(JSON.stringify(r))},deleteProps:function(r,e){var n=function(r,e){return _.reduce(r,function(r,n){return r.push(_.deleteProps(n,e)),r},[])};return _.isArray(r)?n(r,e):_.reduce(e,function(r,e){return delete r[e],r},r)},sum:function(r,e){return _.reduce(r,function(r,n){return r+e(n)},0)},count:function(r,e){return _.sum(r,function(r){return e(r)?1:0})},reverseEach:function(r,e){_.each(_.chain(r).reverse().value(),e)},arrayFrom:function(r){return Array.apply(null,{length:r}).map(Number.call,Number)},reduceInReverse:function(r,e,n){var u=_.arrayFrom(r.length);return u=_.chain(u).reverse().value(),_.reduce(u,function(n,u){return e(n,r[u],u)},n)},nestedEach:function(r,e,n){_.each(r,function(r){_.each(e,function(e){n(r,e)})})},splice:function(r,e){return _.reduceInReverse(r,function(r,n,u){return e(n)&&r.splice(u,1),r},r)},containsAsPartial:function(r,e){return _.reduce(r,function(r,n){return r||_.includeString(n,e)},!1)},consistOf:function(r,e){return _.isArray(r)?_.reduce(r,function(r,n){return r&&_.consistOf(n,e)},!0):_.isString(e)?_.has(r,e):_.isArray(e)?_.reduce(e,function(e,n){return e&&_.consistOf(r,n)},!0):_.reduce(e,function(e,n,u){return e&&r[u]&&_.consistOf(r[u],n)},!0)},includeString:function(r,e){return!!e&&-1!==r.indexOf(e)}});
	else if (a === undefined || b === undefined) { return false; }
	else { return a.toString() === b.toString(); } 
};


/**********************************************************
* Extended Underscore with mixins
**********************************************************/

_u.mixin(
	{
			'exists' : exists
		, 'splitTrim' : splitTrim
		, 'isSimpleData' : isSimpleData
		, 'isNotEmptyString' : isNotEmptyString
		, 'isStringOfLength' : isStringOfLength
		, 'isNumberBetween' : isNumberBetween
		, 'hasAllKeys' : hasAllKeys
		, 'isInArray' : isInArray
		, 'isMatch' : isMatch
	}
);



/**********************************************************
* Export Module
**********************************************************/
module.exports = _u;

Example #19
0
// This file is part of Canvas.
//
// Canvas is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License as published by the Free
// Software Foundation, version 3 of the License.
//
// Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
// details.
//
// You should have received a copy of the GNU Affero General Public License along
// with this program. If not, see <http://www.gnu.org/licenses/>.

// Adds _.sum method.
//
// Use like:
//
// _.sum([2,3,4]) #=> 9
//
// or with a custom accessor:
//
// _.sum([[2,3], [3,4]], (a) -> a[0]) #=> 5
import _ from 'underscore'

export default _.mixin({
  sum(array, accessor = null, start = 0) {
    return _.reduce(array, (memo, el) => (accessor != null ? accessor(el) : el) + memo, start)
  }
})
var _ = require('underscore'),
	coffee = require('coffee-script'),
	node_fs = require('fs'),
	node_path = require('path'),
	node_proc = require('child_process'),
	node_util = require('util'),
	uglify = require('uglify-js'),
	smio = (global.smoothio = {}),
	stylus = require('stylus'),
	exitCode = 0,
	lastFilePath = null,
	noLogging = false,
	restartInterval = null,
	watchedFiles = [];

_.mixin(require('underscore.string'));

smio.instName = node_path.basename(process.cwd());
smio.logBuffer = [];
smio.resLangs = [''];

smio.compileCoffeeScripts = function(dirOrFilePath, srvOutDirPath, cltOutDirPath, noWatch, lazyClient, nameIfSource) {
	var files = (nameIfSource || node_fs.statSync(dirOrFilePath).isFile()) ? [null] : node_fs.readdirSync(dirOrFilePath), fileContent, fileContentClient, fileContentServer, javaScript, filePath, lines, consts, ignore, tmp, pos, doClient = !lazyClient;
	for (var i = 0; i < files.length; i++) {
		fileContentServer = '';
		fileContentClient = '';
		consts = null;
		if (!files[i])
			if (nameIfSource)
				files[i] = nameIfSource;
			else {
Example #21
0
var _ = require('underscore');

_.mixin({
    noop: function() {},

    contains: function(arr, thing) {
        return arr.indexOf(thing) !== -1;
    },

    attempt: function(fn) {
        try {
            fn();
        } catch(e) {
            return e;
        }

        return true;
    },

    now: window.performance && window.performance.now ?
        function() { return window.performance.now(); } :
        Date.now ?
        function() { return Date.now(); } :
        function() { return +(new Date()); }
});
Example #22
0
'use strict';
var util = require('util');
var generators = require('yeoman-generator');
var path = require('path');
var chalk = require('chalk');
var yosay = require('yosay');
var slugify = require("underscore.string/slugify");
var _ = require('underscore');
_.mixin(require('underscore.inflections'));
var mkdirp = require('mkdirp');

var AngmGenerator = generators.Base.extend({

	init: function () {

		this.pkg = require('../package.json');

		// Greetings to the user.
		this.log(yosay(
			'Welcome to ' + chalk.red('official Generator Angm Material') + ' generator!'
		));
	},

	askForApplicationDetails: function () {
		var done = this.async();

		var prompts = [{
			name: 'appName',
			message: 'What would you like to call your application?',
			default: 'Ang-modular'
		}, {
Example #23
0
(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._;

  // 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.5.2';

  // 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, length = obj.length; i < length; i++) {
        if (iterator.call(context, obj[i], i, obj) === breaker) return;
      }
    } else {
      var keys = _.keys(obj);
      for (var i = 0, length = keys.length; i < length; i++) {
        if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
      }
    }
  };

  // Return the results of applying the iterator to each element.
  // Delegates to **ECMAScript 5**'s native `map` if available.
  _.map = _.collect = function(obj, iterator, context) {
    var results = [];
    if (obj == null) return results;
    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
    each(obj, function(value, index, list) {
      results.push(iterator.call(context, value, index, list));
    });
    return 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.push(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 ? void 0 : [];
    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 [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
  _.max = function(obj, iterator, context) {
    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
      return Math.max.apply(Math, obj);
    }
    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, using the modern version of the 
  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
  _.shuffle = function(obj) {
    var rand;
    var index = 0;
    var shuffled = [];
    each(obj, function(value) {
      rand = _.random(index++);
      shuffled[index - 1] = shuffled[rand];
      shuffled[rand] = value;
    });
    return shuffled;
  };

  // Sample **n** random values from an array.
  // If **n** is not specified, returns a single random element from the array.
  // The internal `guard` argument allows it to work with `map`.
  _.sample = function(obj, n, guard) {
    if (arguments.length < 2 || guard) {
      return obj[_.random(obj.length - 1)];
    }
    return _.shuffle(obj).slice(0, Math.max(0, n));
  };

  // An internal function to generate lookup iterators.
  var lookupIterator = function(value) {
    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;
    }), 'value');
  };

  // An internal function used for aggregate "group by" operations.
  var group = function(behavior) {
    return function(obj, value, context) {
      var result = {};
      var iterator = value == null ? _.identity : lookupIterator(value);
      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 = group(function(result, key, value) {
    (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
  });

  // Indexes the object's values by a criterion, similar to `groupBy`, but for
  // when you know that your index values will be unique.
  _.indexBy = group(function(result, key, value) {
    result[key] = value;
  });

  // Counts instances of an object that group by a certain criterion. Pass
  // either a string attribute to count by, or a function that returns the
  // criterion.
  _.countBy = group(function(result, key) {
    _.has(result, key) ? result[key]++ : result[key] = 1;
  });

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

  // 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 ? array[0] : 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
  // `_.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 array[array.length - 1];
    } else {
      return slice.call(array, Math.max(array.length - n, 0));
    }
  };

  // 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) {
    if (shallow && _.every(input, _.isArray)) {
      return concat.apply(output, input);
    }
    each(input, function(value) {
      if (_.isArray(value) || _.isArguments(value)) {
        shallow ? push.apply(output, value) : flatten(value, shallow, output);
      } else {
        output.push(value);
      }
    });
    return output;
  };

  // Flatten out an array, either recursively (by default), or just one level.
  _.flatten = function(array, shallow) {
    return flatten(array, shallow, []);
  };

  // Return 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(_.flatten(arguments, true));
  };

  // Produce an array that contains every item shared between all the
  // passed-in arrays.
  _.intersection = function(array) {
    var rest = slice.call(arguments, 1);
    return _.filter(_.uniq(array), function(item) {
      return _.every(rest, function(other) {
        return _.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 length = _.max(_.pluck(arguments, "length").concat(0));
    var results = new Array(length);
    for (var i = 0; i < length; i++) {
      results[i] = _.pluck(arguments, '' + i);
    }
    return 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, length = list.length; i < length; 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, length = array.length;
    if (isSorted) {
      if (typeof isSorted == 'number') {
        i = (isSorted < 0 ? Math.max(0, length + 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 < length; i++) if (array[i] === item) return i;
    return -1;
  };

  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
  _.lastIndexOf = function(array, item, from) {
    if (array == null) return -1;
    var hasIndex = from != null;
    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
    }
    var 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 length = Math.max(Math.ceil((stop - start) / step), 0);
    var idx = 0;
    var range = new Array(length);

    while(idx < length) {
      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). Delegates to **ECMAScript 5**'s native `Function.bind` if
  // available.
  _.bind = function(func, context) {
    var args, bound;
    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
    if (!_.isFunction(func)) throw new TypeError;
    args = slice.call(arguments, 2);
    return bound = function() {
      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
      ctor.prototype = func.prototype;
      var self = new ctor;
      ctor.prototype = null;
      var result = func.apply(self, args.concat(slice.call(arguments)));
      if (Object(result) === result) return result;
      return self;
    };
  };

  // 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) throw new Error("bindAll must be passed function names");
    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. Normally, the throttled function will run
  // as much as it can, without ever going more than once per `wait` duration;
  // but if you'd like to disable the execution on the leading edge, pass
  // `{leading: false}`. To disable execution on the trailing edge, ditto.
  _.throttle = function(func, wait, options) {
    var context, args, result;
    var timeout = null;
    var previous = 0;
    options || (options = {});
    var later = function() {
      previous = options.leading === false ? 0 : new Date;
      timeout = null;
      result = func.apply(context, args);
    };
    return function() {
      var now = new Date;
      if (!previous && options.leading === false) previous = now;
      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 && options.trailing !== false) {
        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, args, context, timestamp, result;
    return function() {
      context = this;
      args = arguments;
      timestamp = new Date();
      var later = function() {
        var last = (new Date()) - timestamp;
        if (last < wait) {
          timeout = setTimeout(later, wait - last);
        } else {
          timeout = null;
          if (!immediate) result = func.apply(context, args);
        }
      };
      var callNow = immediate && !timeout;
      if (!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) {
    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.push(key);
    return keys;
  };

  // Retrieve the values of an object's properties.
  _.values = function(obj) {
    var keys = _.keys(obj);
    var length = keys.length;
    var values = new Array(length);
    for (var i = 0; i < length; i++) {
      values[i] = obj[keys[i]];
    }
    return values;
  };

  // Convert an object into a list of `[key, value]` pairs.
  _.pairs = function(obj) {
    var keys = _.keys(obj);
    var length = keys.length;
    var pairs = new Array(length);
    for (var i = 0; i < length; i++) {
      pairs[i] = [keys[i], obj[keys[i]]];
    }
    return pairs;
  };

  // Invert the keys and values of an object. The values must be serializable.
  _.invert = function(obj) {
    var result = {};
    var keys = _.keys(obj);
    for (var i = 0, length = keys.length; i < length; i++) {
      result[obj[keys[i]]] = keys[i];
    }
    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] === void 0) 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;
    }
    // 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;
    }
    // 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 {
      // 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(Math.max(0, 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;'
    }
  };
  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 with the
  // `object` as context; otherwise, return it.
  _.result = function(object, property) {
    if (object == null) return void 0;
    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);
Example #24
0
(function (module) {

	var winston = require('winston');
	var async = require('async');
	var nconf = require('nconf');
	var session = require('express-session');
	var _ = require('underscore');
	var semver = require('semver');
	var db;

	_.mixin(require('underscore.deep'));

	module.questions = [
		{
			name: 'mongo:host',
			description: 'Host IP or address of your MongoDB instance',
			'default': nconf.get('mongo:host') || '127.0.0.1'
		},
		{
			name: 'mongo:port',
			description: 'Host port of your MongoDB instance',
			'default': nconf.get('mongo:port') || 27017
		},
		{
			name: 'mongo:username',
			description: 'MongoDB username',
			'default': nconf.get('mongo:username') || ''
		},
		{
			name: 'mongo:password',
			description: 'Password of your MongoDB database',
			hidden: true,
			default: nconf.get('mongo:password') || '',
			before: function (value) { value = value || nconf.get('mongo:password') || ''; return value; }
		},
		{
			name: "mongo:database",
			description: "MongoDB database name",
			'default': nconf.get('mongo:database') || 'nodebb'
		}
	];

	module.helpers = module.helpers || {};
	module.helpers.mongo = require('./mongo/helpers');

	module.init = function (callback) {
		callback = callback || function () {};
		var mongoClient;
		try {
			mongoClient = require('mongodb').MongoClient;
		} catch (err) {
			winston.error('Unable to initialize MongoDB! Is MongoDB installed? Error :' + err.message);
			return callback(err);
		}

		var usernamePassword = '';
		if (nconf.get('mongo:username') && nconf.get('mongo:password')) {
			usernamePassword = nconf.get('mongo:username') + ':' + encodeURIComponent(nconf.get('mongo:password')) + '@';
		}

		// Sensible defaults for Mongo, if not set
		if (!nconf.get('mongo:host')) {
			nconf.set('mongo:host', '127.0.0.1');
		}
		if (!nconf.get('mongo:port')) {
			nconf.set('mongo:port', 27017);
		}
		if (!nconf.get('mongo:database')) {
			nconf.set('mongo:database', 'nodebb');
		}

		var hosts = nconf.get('mongo:host').split(',');
		var ports = nconf.get('mongo:port').toString().split(',');
		var servers = [];

		for (var i = 0; i < hosts.length; i++) {
			servers.push(hosts[i] + ':' + ports[i]);
		}

		var connString = 'mongodb://' + usernamePassword + servers.join() + '/' + nconf.get('mongo:database');

		var connOptions = {
			server: {
				poolSize: parseInt(nconf.get('mongo:poolSize'), 10) || 10
			}
		};

		connOptions = _.deepExtend((nconf.get('mongo:options') || {}), connOptions);

		mongoClient.connect(connString, connOptions, function (err, _db) {
			if (err) {
				winston.error("NodeBB could not connect to your Mongo database. Mongo returned the following error: " + err.message);
				return callback(err);
			}

			db = _db;

			module.client = db;

			require('./mongo/main')(db, module);
			require('./mongo/hash')(db, module);
			require('./mongo/sets')(db, module);
			require('./mongo/sorted')(db, module);
			require('./mongo/list')(db, module);

			if (nconf.get('mongo:password') && nconf.get('mongo:username')) {
				db.authenticate(nconf.get('mongo:username'), nconf.get('mongo:password'), function (err) {
					if (err) {
						return callback(err);
					}
					createSessionStore();
					createIndices();
				});
			} else {
				winston.warn('You have no mongo password setup!');
				createSessionStore();
				createIndices();
			}

			function createSessionStore() {
				var sessionStore;
				if (nconf.get('redis')) {
					sessionStore = require('connect-redis')(session);
					var rdb = require('./redis');
					rdb.client = rdb.connect();

					module.sessionStore = new sessionStore({
						client: rdb.client,
						ttl: 60 * 60 * 24 * 14
					});
				} else if (nconf.get('mongo')) {
					sessionStore = require('connect-mongo')(session);
					module.sessionStore = new sessionStore({
						db: db
					});
				}
			}

			function createIndices() {
				winston.info('[database] Checking database indices.');
				async.series([
					async.apply(createIndex, 'objects', {_key: 1, score: -1}, {background: true}),
					async.apply(createIndex, 'objects', {_key: 1, value: -1}, {background: true, unique: true, sparse: true}),
					async.apply(createIndex, 'objects', {expireAt: 1}, {expireAfterSeconds: 0, background: true})
				], function (err) {
					if (err) {
						winston.error('Error creating index ' + err.message);
					}
					winston.info('[database] Checking database indices done!');
					callback(err);
				});
			}

			function createIndex(collection, index, options, callback) {
				db.collection(collection).createIndex(index, options, callback);
			}
		});
	};

	module.checkCompatibility = function (callback) {
		var mongoPkg = require.main.require('./node_modules/mongodb/package.json'),
			err = semver.lt(mongoPkg.version, '2.0.0') ? new Error('The `mongodb` package is out-of-date, please run `./nodebb setup` again.') : null;

		if (err) {
			err.stacktrace = false;
		}
		callback(err);
	};

	module.info = function (db, callback) {
		if (!db) {
			return callback();
		}
		async.parallel({
			serverStatus: function (next) {
				db.command({'serverStatus': 1}, next);
			},
			stats: function (next) {
				db.command({'dbStats': 1}, next);
			},
			listCollections: function (next) {
				db.listCollections().toArray(function (err, items) {
					if (err) {
						return next(err);
					}
					async.map(items, function (collection, next) {
						db.collection(collection.name).stats(next);
					}, next);
				});
			}
		}, function (err, results) {
			if (err) {
				return callback(err);
			}
			var stats = results.stats;
			var scale = 1024 * 1024;

			results.listCollections = results.listCollections.map(function (collectionInfo) {
				return {
					name: collectionInfo.ns,
					count: collectionInfo.count,
					size: collectionInfo.size,
					avgObjSize: collectionInfo.avgObjSize,
					storageSize: collectionInfo.storageSize,
					totalIndexSize: collectionInfo.totalIndexSize,
					indexSizes: collectionInfo.indexSizes
				};
			});

			stats.mem = results.serverStatus.mem;
			stats.collectionData = results.listCollections;
			stats.network = results.serverStatus.network;
			stats.raw = JSON.stringify(stats, null, 4);

			stats.avgObjSize = stats.avgObjSize.toFixed(2);
			stats.dataSize = (stats.dataSize / scale).toFixed(2);
			stats.storageSize = (stats.storageSize / scale).toFixed(2);
			stats.fileSize = stats.fileSize ? (stats.fileSize / scale).toFixed(2) : 0;
			stats.indexSize = (stats.indexSize / scale).toFixed(2);
			stats.storageEngine = results.serverStatus.storageEngine ? results.serverStatus.storageEngine.name : 'mmapv1';
			stats.host = results.serverStatus.host;
			stats.version = results.serverStatus.version;
			stats.uptime = results.serverStatus.uptime;
			stats.mongo = true;

			callback(null, stats);
		});
	};

	module.close = function () {
		db.close();
	};

}(exports));
Example #25
0
/* global require, console, module */
var _ = require('underscore'), 
	_s = require('underscore.string'),
	extend = require('node.extend');

_.mixin(_s.exports());

_.extend = extend;

_.mask = function mask(obj, keys) {
	var ret;

	ret = {};
	if (!Array.isArray(keys)) {
		keys = Object.keys(keys);
	}

	for (var i = 0, l = keys.length; i < l; ++i) {
		if (obj.hasOwnProperty(keys[i])) {
			ret[keys[i]] = obj[keys[i]];
		}
	}
	return ret;
};

_.bindr = function(fn, that) {
	var args;

	if (typeof fn !== "function") {
		// closest thing possible to the ECMAScript 5 internal IsCallable function
		throw new TypeError("_.bindr - what is trying to be bound is not callable");
Example #26
0
		else {
			// Read
			dependencyDetection.registerDependency(observable);
			return _latestValue;
		}
	}
	
	subscribable.call(observable); //user observable as 'this' for subscribable
	
	observable.peek = function() { return _latestValue };
	observable.valueHasMutated = function() { observable.notifySubscribers(_latestValue) };
	observable.valueWillMutate = function() { observable.notifySubscribers(_latestValue, 'beforeChange') };
	
	//TODO this primitive only compare isn't good for BigMoney etc
	observable.equalityComparer = function(a,b) {
		var oldValueIsPrimitive = (a === null) || (typeof(a) in primitiveTypes);
		return oldValueIsPrimitive ? (a === b) : false;
	}
	
	observable.__is_observable__ = true;
	
	return observable;
};

_.mixin({
	'isObservable': function(value) {
		return _.isSubscribable(value) && value.__is_observable__ === true;
	}
})

module.exports = observable;
Example #27
0
var querystring = require("querystring");
var https = require('https');
var _ = require('underscore');
var crypto = require('crypto');

_.mixin({
  // compact for objects
  compactObject: function(to_clean) {
    _.map(to_clean, function(value, key, to_clean) {
      if (value === undefined)
        delete to_clean[key];
    });
    return to_clean;
  }
});  

var Bitstamp = function(key, secret, client_id) {
  this.key = key;
  this.secret = secret;
  this.client_id = client_id;

  _.bindAll(this);
}

Bitstamp.prototype._request = function(method, path, data, callback, args) {
  
  var options = {
    host: 'www.bitstamp.net',
    path: path,
    method: method,
    headers: {
Example #28
0
try {
  config = JSON.parse(fs.readFileSync(__dirname + '/config/config.json'));
} catch (err) {
  console.warn('There has been an error parsing the config-file.')
  console.warn(err.stack);
}

// Use defaults for undefined values
config = defaultsDeep(config, defaults);

/*
 * Extend UNDERSCORE
 */
_.mixin({
  exclone: function(object, extra) {
    return _(object).chain().clone().extend(extra).value();
  }
});

// Checks for program arguments and runs the responsible operations
// e.g. "node app.js <arg1> <arg2>"
//   "-port <portnumber>" changes server port on <portnumber>
function checkArguments() {
  for (var i = 0; i < process.argv.length; i++) {
    switch (process.argv[i]) {
      case "-port": // next argument need to be a port number
        // isNaN() checks if content is not a number
        if (!isNaN(process.argv[++i])) {
          config.port = process.argv[i];
        } else { // next argument isn't a port number, so check it in next loop
          i--;
Example #29
0
'use strict';
var util = require('util');
var path = require('path');
var yeoman = require('yeoman-generator');
var _ = require('underscore');
_.str = require('underscore.string');
_.mixin(_.str.exports());
_.str.include('Underscore.string', 'string');


var FrontendGenerator = module.exports = function FrontendGenerator(args, options, config) {
  yeoman.generators.Base.apply(this, arguments);
  this.argument('appname', { type: String, required: false });
  this.appname = this.appname || path.basename(process.cwd());
  this.on('end', function () {
    this.installDependencies({ skipInstall: options['skip-install'] });
  });
  this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json')));
};

util.inherits(FrontendGenerator, yeoman.generators.Base);

FrontendGenerator.prototype.app = function app() {
  this.mkdir('example');
  this.template('example/_example.js','example/example.js');
  this.template('example/_index.html','example/index.html');

  this.mkdir('grunt-config');
  this.copy('grunt-config/coffee.js','grunt-config/coffee.js');
  this.copy('grunt-config/connect.js','grunt-config/connect.js');
  this.copy('grunt-config/copy.js','grunt-config/copy.js');
Example #30
0
    if(!path.existsSync(currentPath)) {
      fs.mkdirSync(currentPath, mode);
    }
  });
};

http.getJSON = function(options, callback, processor) {
  processor = processor || JSON.parse;
  return http.get(options, function(res){
    var body = "";
    res.on('data', function(chunk) { body += chunk; });
    res.on('end', function() {
      try {
        var val = processor(body);
      } catch(e) {
        console.log("Failed to eval: ", e, body);
      }
      callback(val);
    });
  });
}

_.mixin({
  curry: function(func) {
    bindArgs = _.toArray(arguments);
    bindArgs.shift();
    bindArgs.unshift(func, {});
    return _.bind.apply(this, bindArgs);
  }
});