<commit_before>DDH.game2048 = DDH.game2048 || {};

DDH.game2048.build = function(ops) {
    // Global Variables Declaration
    var WINNUM = 2048,
        SIZE = 4,
        TILE_COUNT = SIZE * SIZE,
        started = false,
        tiles = init_area(),
        score = 0;

    function rc_to_index(row, col) {
        return row * SIZE + col;
    }

    function index_to_rc(index) {
        return { 'row' : Math.floor(index / SIZE), 'col' : index % SIZE };
    }

    //This function moves and sums numbers
    function move(dir) {
        var points = 0;
        var transposed = false;
        var swapped =  false;

        if (dir === 'w' || dir === 's') {
            transpose_area();
            transposed = true;
        }
        if (dir === 'd' || dir === 's') {
            swap_cols_area();
            swapped = true;
        }

        var result = handle_move(transposed, swapped);

        if (dir === 'd' || dir === 's')
            swap_cols_area();
        if (dir === 'w' || dir === 's')
            transpose_area();

        increase_points(result.points);

        return result.moved;
    }

    function handle_move(transposed, swapped) {
        var result = {'moved': false, 'points': false};

        var moves = 0;

        for(var i = 0; i < TILE_COUNT; ++i) {
            var row = Math.floor(i / SIZE),
                col = i % SIZE;
            moves = col === 0 ? 0 : moves;

            if (tiles[i].val === 0) {
                ++moves;
                continue;
            }

            //Move across empty tiles
            if(moves > 0) {
                var temp_tile = tiles[rc_to_index(row, col - moves)];
                temp_tile.val = 0;

                tiles[rc_to_index(row, col - moves)] = tiles[i];
                tiles[i] = temp_tile;

                result.moved = true;
            }

            //Find and merge two matching tiles
            for(var j = col + 1; j < SIZE; ++j) {
                var tile_a = tiles[rc_to_index(row, col - moves)];
                var tile_b = tiles[rc_to_index(row, j)];

                if(tile_b.val === 0)
                    continue;

                if(tile_a.val === tile_b.val) {
                    merge(tile_a, tile_b, row, col - moves, transposed, swapped);

                    result.points = tile_a.val;
                    result.moved = true;
                }
                break;
            }
        }

        return result;
    }

    function gen_translate_string(row, col) {
        return "translate(" + (col * 85 + 5) + "px," + row * 85 + "px)";
    }

    //Row and col indicate the place where the animation should end
    function merge(tile_a, tile_b, row, col, transposed, swapped) {
        tile_a.val += tile_b.val;
        tile_b.val = 0;

        //Recalculate the real world pos
        if(swapped)
            col = SIZE - 1 - col;

        if(transposed) {
            var tmp = col;
            col = row;
            row = tmp;
        }

        var translate_string = gen_translate_string(row, col);

        tile_b.div.css({ "-ms-transform" : translate_string,
                        "-webkit-transform" : translate_string,
                        "transform" : translate_string,
                        "opacity" : 0.00 });

        tile_b.div.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () {
            this.remove();
        });
    }

    // Updates the 'points' div
    function increase_points(points) {
        score += points;
        if (points > 0){
            var addition = "
+" + points + "
";
            $('.game2048__points_addition').html(addition);
        }

        $('.game2048__points').text(score);
    }

    //Update the board
    function update_tiles() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            var pos = index_to_rc(i);
            var tile = tiles[i];

            if("undefined" !== typeof(tile.div)) {
                var translate_string = gen_translate_string(pos.row, pos.col);

                if(tile.val > 0)
                    tile.div
                        .html(tile.val)
                        .attr("class", "boxtile val-" + tile.val)
                        .css({ "-ms-transform" : translate_string,
                            "-webkit-transform" : translate_string,
                            "transform" : translate_string });
            }
        }
    }

    // 'area' initialization
    function init_area() {
        var tiles = [TILE_COUNT];

        for(var i = 0; i < TILE_COUNT; ++i) {
            tiles[i] = {
                val: 0
            };
        }

        return tiles;
    }

    function transpose_area() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            var pos = index_to_rc(i);

            if(pos.col >= pos.row)
                continue;

            var index_to_swap = pos.col * SIZE + pos.row;
            var tmp_tile = tiles[i];
            tiles[i] = tiles[index_to_swap];
            tiles[index_to_swap] = tmp_tile;
        }
    }

    function swap_cols_area() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            var pos = index_to_rc(i);

            if(i % SIZE >= (SIZE / 2))
                continue;

            var index_to_swap = rc_to_index(pos.row, SIZE - 1 - pos.col);
            var tmp_tile = tiles[i];

            tiles[i] = tiles[index_to_swap];
            tiles[index_to_swap] = tmp_tile;
        }
    }

    //4 has a 10% chance of being chosen
    function add_random_tile() {
        var unused_tiles = [];
        for(var i = 0; i < TILE_COUNT; ++i) {
            if(tiles[i].val === 0) {
                unused_tiles.push(i);
            }
        }

        var rand_tile = unused_tiles[Math.floor(Math.random() * unused_tiles.length)];
        var rand_val = Math.floor(Math.random() * 11) < 2 ? 4 : 2;

        tiles[rand_tile].div = create_tile_div();
        tiles[rand_tile].val = rand_val;
    }

    function create_tile_div() {
        var div = $("

");
        $("#game2048__area_container").append(div);
        return div;
    }

    //If there is the winning number inside the table, returns true and
    //prints a congratulation message
    function has_won() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            if (tiles[i].val == WINNUM) {
                game_over_message(true);
                return true;
            }
        }
        return false;
    }

    function has_lost() {
        var full_tiles_count = 0,
            move_possible = false;

        for(var i = 0; i < TILE_COUNT; ++i) {
            if (tiles[i].val > 0)
                ++full_tiles_count;

            var pos = index_to_rc(i);

            var row = pos.row;
            var col = pos.col;

            // check all available movements
            if ((row !== 0 && tiles[i].val === tiles[rc_to_index(row - 1, col)].val) ||
                (row !== SIZE - 1 && tiles[i].val === tiles[rc_to_index(row + 1, col)].val) ||
                (col !== 0 && tiles[i].val === tiles[rc_to_index(row, col - 1)].val) ||
                (col !== SIZE - 1 && tiles[i].val === tiles[rc_to_index(row, col + 1)].val)) {
                move_possible = true;
            }
        }

        if (full_tiles_count === TILE_COUNT && !move_possible) {
            game_over_message(false);
            return true;
        }

        return false;
    }

    // This function shows game over message
    function game_over_message(game_won) {
        var result_msg = $('#game2048__area .game2048__message p');
        var result_box = $('#game2048__area .game2048__message');
        if (game_won == true) {
            result_msg.text("You Won!");
            result_box.addClass("game2048__won");
        } else {
            result_msg.text("You Lost!");
            result_box.removeClass("game2048__won");
        }
        result_box.show();
    }

    // This function reset game_area, points, result
    function init_game() {
        var game_area = $('#game2048__area');
        var game_area_container = $('#game2048__area_container');
        var result_box = $('#game2048__area .game2048__message');

        increase_points(-score);
        game_over = false;
        result_box.hide();
        game_area.focus();
        game_area_container.children(".boxtile").remove();
        tiles = init_area();
        add_random_tile();
        update_tiles();
    }

    return {
        onShow: function() {

        //Hide this goodie on mobile devices for now
        if(is_mobile || is_mobile_device) {
            DDH.spice_tabs.game2048.hideLink();
            DDH.spice_tabs.game2048.hide();
            return;
        }

        //'started' is a boolean variable used in order to avoid the
        //duplication of the gaming tiles. Moving around the DDG tabs the
        //'onShow' function is executed over and over. This simple solution
        //prevents the problem
        if (!started) {
            started = true;

            var game_over = false;
            var game_area = $('#game2048__area');

            init_game();

            game_area.keydown(function(e) {
                e.preventDefault();

                var move_made = false;
                if (!game_over) {
                    if (e.keyCode === 87 || e.keyCode === 38) { // w or up arrow
                        move_made = move('w');
                    } else if (e.keyCode === 65 || e.keyCode === 37) { // a or left arrow
                        move_made = move('a');
                    } else if (e.keyCode === 83 || e.keyCode === 40) { // s or dowm arrow
                        move_made = move('s');
                    } else if (e.keyCode === 68 || e.keyCode === 39) { // d or right arrow
                        move_made = move('d');
                    }

                    if (move_made) {
                        add_random_tile();
                        game_over = has_won() || has_lost();
                        update_tiles();
                    }
                }
                return false;
            });

            var new_game_button = $(".zci--game2048 .game2048__new_game");
            new_game_button.on("click", function(e) {
                e.preventDefault();
                init_game();
            });
            }
        }
    };
};
<commit_msg>Added "use strict"<commit_after>DDH.game2048 = DDH.game2048 || {};

DDH.game2048.build = function(ops) {
    "use strict";

    // Global Variables Declaration
    var WINNUM = 2048,
        SIZE = 4,
        TILE_COUNT = SIZE * SIZE,
        started = false,
        tiles = init_area(),
        score = 0;

    function rc_to_index(row, col) {
        return row * SIZE + col;
    }

    function index_to_rc(index) {
        return { 'row' : Math.floor(index / SIZE), 'col' : index % SIZE };
    }

    //This function moves and sums numbers
    function move(dir) {
        var points = 0;
        var transposed = false;
        var swapped =  false;

        if (dir === 'w' || dir === 's') {
            transpose_area();
            transposed = true;
        }
        if (dir === 'd' || dir === 's') {
            swap_cols_area();
            swapped = true;
        }

        var result = handle_move(transposed, swapped);

        if (dir === 'd' || dir === 's')
            swap_cols_area();
        if (dir === 'w' || dir === 's')
            transpose_area();

        increase_points(result.points);

        return result.moved;
    }

    function handle_move(transposed, swapped) {
        var result = {'moved': false, 'points': false};

        var moves = 0;

        for(var i = 0; i < TILE_COUNT; ++i) {
            var row = Math.floor(i / SIZE),
                col = i % SIZE;
            moves = col === 0 ? 0 : moves;

            if (tiles[i].val === 0) {
                ++moves;
                continue;
            }

            //Move across empty tiles
            if(moves > 0) {
                var temp_tile = tiles[rc_to_index(row, col - moves)];
                temp_tile.val = 0;

                tiles[rc_to_index(row, col - moves)] = tiles[i];
                tiles[i] = temp_tile;

                result.moved = true;
            }

            //Find and merge two matching tiles
            for(var j = col + 1; j < SIZE; ++j) {
                var tile_a = tiles[rc_to_index(row, col - moves)];
                var tile_b = tiles[rc_to_index(row, j)];

                if(tile_b.val === 0)
                    continue;

                if(tile_a.val === tile_b.val) {
                    merge(tile_a, tile_b, row, col - moves, transposed, swapped);

                    result.points = tile_a.val;
                    result.moved = true;
                }
                break;
            }
        }

        return result;
    }

    function gen_translate_string(row, col) {
        return "translate(" + (col * 85 + 5) + "px," + row * 85 + "px)";
    }

    //Row and col indicate the place where the animation should end
    function merge(tile_a, tile_b, row, col, transposed, swapped) {
        tile_a.val += tile_b.val;
        tile_b.val = 0;

        //Recalculate the real world pos
        if(swapped)
            col = SIZE - 1 - col;

        if(transposed) {
            var tmp = col;
            col = row;
            row = tmp;
        }

        var translate_string = gen_translate_string(row, col);

        tile_b.div.css({ "-ms-transform" : translate_string,
                        "-webkit-transform" : translate_string,
                        "transform" : translate_string,
                        "opacity" : 0.00 });

        tile_b.div.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () {
            this.remove();
        });
    }

    // Updates the 'points' div
    function increase_points(points) {
        score += points;
        if (points > 0){
            var addition = "
+" + points + "
";
            $('.game2048__points_addition').html(addition);
        }

        $('.game2048__points').text(score);
    }

    //Update the board
    function update_tiles() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            var pos = index_to_rc(i);
            var tile = tiles[i];

            if("undefined" !== typeof(tile.div)) {
                var translate_string = gen_translate_string(pos.row, pos.col);

                if(tile.val > 0)
                    tile.div
                        .html(tile.val)
                        .attr("class", "boxtile val-" + tile.val)
                        .css({ "-ms-transform" : translate_string,
                            "-webkit-transform" : translate_string,
                            "transform" : translate_string });
            }
        }
    }

    // 'area' initialization
    function init_area() {
        var tiles = [TILE_COUNT];

        for(var i = 0; i < TILE_COUNT; ++i) {
            tiles[i] = {
                val: 0
            };
        }

        return tiles;
    }

    function transpose_area() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            var pos = index_to_rc(i);

            if(pos.col >= pos.row)
                continue;

            var index_to_swap = pos.col * SIZE + pos.row;
            var tmp_tile = tiles[i];
            tiles[i] = tiles[index_to_swap];
            tiles[index_to_swap] = tmp_tile;
        }
    }

    function swap_cols_area() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            var pos = index_to_rc(i);

            if(i % SIZE >= (SIZE / 2))
                continue;

            var index_to_swap = rc_to_index(pos.row, SIZE - 1 - pos.col);
            var tmp_tile = tiles[i];

            tiles[i] = tiles[index_to_swap];
            tiles[index_to_swap] = tmp_tile;
        }
    }

    //4 has a 10% chance of being chosen
    function add_random_tile() {
        var unused_tiles = [];
        for(var i = 0; i < TILE_COUNT; ++i) {
            if(tiles[i].val === 0) {
                unused_tiles.push(i);
            }
        }

        var rand_tile = unused_tiles[Math.floor(Math.random() * unused_tiles.length)];
        var rand_val = Math.floor(Math.random() * 11) < 2 ? 4 : 2;

        tiles[rand_tile].div = create_tile_div();
        tiles[rand_tile].val = rand_val;
    }

    function create_tile_div() {
        var div = $("

");
        $("#game2048__area_container").append(div);
        return div;
    }

    //If there is the winning number inside the table, returns true and
    //prints a congratulation message
    function has_won() {
        for(var i = 0; i < TILE_COUNT; ++i) {
            if (tiles[i].val == WINNUM) {
                game_over_message(true);
                return true;
            }
        }
        return false;
    }

    function has_lost() {
        var full_tiles_count = 0,
            move_possible = false;

        for(var i = 0; i < TILE_COUNT; ++i) {
            if (tiles[i].val > 0)
                ++full_tiles_count;

            var pos = index_to_rc(i);

            var row = pos.row;
            var col = pos.col;

            // check all available movements
            if ((row !== 0 && tiles[i].val === tiles[rc_to_index(row - 1, col)].val) ||
                (row !== SIZE - 1 && tiles[i].val === tiles[rc_to_index(row + 1, col)].val) ||
                (col !== 0 && tiles[i].val === tiles[rc_to_index(row, col - 1)].val) ||
                (col !== SIZE - 1 && tiles[i].val === tiles[rc_to_index(row, col + 1)].val)) {
                move_possible = true;
            }
        }

        if (full_tiles_count === TILE_COUNT && !move_possible) {
            game_over_message(false);
            return true;
        }

        return false;
    }

    function is_game_over() {
        return has_won() || has_lost();
    }

    // This function shows game over message
    function game_over_message(game_won) {
        var result_msg = $('#game2048__area .game2048__message p');
        var result_box = $('#game2048__area .game2048__message');
        if (game_won === true) {
            result_msg.text("You Won!");
            result_box.addClass("game2048__won");
        } else {
            result_msg.text("You Lost!");
            result_box.removeClass("game2048__won");
        }
        result_box.show();
    }

    // This function reset game_area, points, result
    function init_game() {
        var game_area = $('#game2048__area');
        var game_area_container = $('#game2048__area_container');
        var result_box = $('#game2048__area .game2048__message');

        increase_points(-score);
        result_box.hide();
        game_area.focus();
        game_area_container.children(".boxtile").remove();
        tiles = init_area();
        add_random_tile();
        update_tiles();
    }

    return {
        onShow: function() {

        //Hide this goodie on mobile devices for now
        if(is_mobile || is_mobile_device) {
            DDH.spice_tabs.game2048.hideLink();
            DDH.spice_tabs.game2048.hide();
            return;
        }

        //'started' is a boolean variable used in order to avoid the
        //duplication of the gaming tiles. Moving around the DDG tabs the
        //'onShow' function is executed over and over. This simple solution
        //prevents the problem
        if (!started) {
            started = true;
            var game_area = $('#game2048__area');

            init_game();

            game_area.keydown(function(e) {
                e.preventDefault();

                var move_made = false;
                if (!is_game_over()) {
                    if (e.keyCode === 87 || e.keyCode === 38) { // w or up arrow
                        move_made = move('w');
                    } else if (e.keyCode === 65 || e.keyCode === 37) { // a or left arrow
                        move_made = move('a');
                    } else if (e.keyCode === 83 || e.keyCode === 40) { // s or dowm arrow
                        move_made = move('s');
                    } else if (e.keyCode === 68 || e.keyCode === 39) { // d or right arrow
                        move_made = move('d');
                    }

                    if (move_made) {
                        add_random_tile();
                        update_tiles();
                    }
                }
                return false;
            });

            var new_game_button = $(".zci--game2048 .game2048__new_game");
            new_game_button.on("click", function(e) {
                e.preventDefault();
                init_game();
            });
            }
        }
    };
};
<|endoftext|>


<commit_before>var Logger = require('logger-facade-nodejs'),
    _ = require('lodash'),
    SMI = require('./smi'),
    Backend = require('./backend'),
    Frontend = require('./frontend'),
    packageJson = require('../package.json');

var Broker = function(configuration, smiService, frontend, backend){
  var defaults = {
    frontend: 'tcp://127.0.0.1:5560',
    backend: 'tcp://127.0.0.1:5559',
    smi: {
      // heartbeat interval in ms
      heartbeat: 1000,
      // max ttl for a service in ms
      maxTTL: 1500,
      // refresh service ttl update interval in ms
      updateInterval: 100
    }
  };

  var config = _.defaults(configuration, defaults);

  // alway override version
  config.version = packageJson.version;

  var log = Logger.getLogger('Broker');

  // public methods

  this.version = config.version;

  this.run = function(){
    log.info("Async Broker v%s", config.version);

    smiService = smiService || new SMI(config.smi);
    smiService.run(config.smi);

    backend =  backend || new Backend({ backend: config.backend }, smiService);
    frontend = frontend || new Frontend({ frontend: config.frontend }, smiService);

    backend.frontendSendCallback = frontend.send;
    frontend.backendSendCallback = backend.send;

    backend.run();
    frontend.run();

    log.info("Async Broker is waiting for messages...\n");
  };

  this.stop = function(){
    log.info("\nAsync Broker disconnecting...");

    smiService.stop();
    frontend.stop();
    backend.stop();
  };

};

module.exports = Broker;
<commit_msg>refactor broker module to avoid using the this keywords<commit_after>var Logger = require('logger-facade-nodejs'),
    _ = require('lodash'),
    SMI = require('./smi'),
    Backend = require('./backend'),
    Frontend = require('./frontend'),
    packageJson = require('../package.json');

var Broker = function(configuration, smiService, frontend, backend){
  var defaults = {
    frontend: 'tcp://127.0.0.1:5560',
    backend: 'tcp://127.0.0.1:5559',
    smi: {
      // heartbeat interval in ms
      heartbeat: 1000,
      // max ttl for a service in ms
      maxTTL: 1500,
      // refresh service ttl update interval in ms
      updateInterval: 100
    }
  };

  var config = _.defaults(configuration, defaults);

  // alway override version
  config.version = packageJson.version;

  var log = Logger.getLogger('Broker');

  var run = function(){
    log.info("Async Broker v%s", config.version);

    smiService = smiService || new SMI(config.smi);
    smiService.run(config.smi);

    backend =  backend || new Backend({ backend: config.backend }, smiService);
    frontend = frontend || new Frontend({ frontend: config.frontend }, smiService);

    backend.frontendSendCallback = frontend.send;
    frontend.backendSendCallback = backend.send;

    backend.run();
    frontend.run();

    log.info("Async Broker is waiting for messages...\n");
  };

  var stop = function(){
    log.info("\nAsync Broker disconnecting...");

    smiService.stop();
    frontend.stop();
    backend.stop();
  };

  return {
    version: config.version,
    run:     run,
    stop:    stop
  };
};

module.exports = Broker;
<|endoftext|>


<commit_before>'use strict'

var sorted = require('sorted-array-functions')
var match = require('./match')
var onlyRegex = require('./onlyRegex')

function Bucket (parent) {
  this.data = []
  this._algo = parent._algo
  this._isDeep = parent._isDeep
  this.magic = this._isDeep ? 0 : Number.MAX_SAFE_INTEGER
}

Bucket.prototype.add = function (set) {
  sorted.add(this.data, set, this._algo)
  if (this._isDeep) {
    if (this.magic < set.magic) {
      this.magic = set.magic
    }
  } else {
    if (this.magic > set.magic) {
      this.magic = set.magic
    }
  }
  return this
}

Bucket.prototype.remove = function (pattern, payload) {
  var foundPattern = false
  var data = this.data
  for (var i = 0; i < data.length; i++) {
    if (match(pattern, data[i].pattern)) {
      if (payload === null || payload === data[i].payload || onlyRegex(pattern)) {
        data.splice(i, 1)
        foundPattern = true

        // to remove all occurences
        this.remove(pattern, payload)
        break
      }
    }
  }

  return foundPattern
}

Bucket.prototype.forEach = function (func, that) {
  this.data.forEach(func, that)
  return this
}

module.exports = Bucket
<commit_msg>Call onlyRegex just once when removing<commit_after>'use strict'

var sorted = require('sorted-array-functions')
var match = require('./match')
var onlyRegex = require('./onlyRegex')

function Bucket (parent) {
  this.data = []
  this._algo = parent._algo
  this._isDeep = parent._isDeep
  this.magic = this._isDeep ? 0 : Number.MAX_SAFE_INTEGER
}

Bucket.prototype.add = function (set) {
  sorted.add(this.data, set, this._algo)
  if (this._isDeep) {
    if (this.magic < set.magic) {
      this.magic = set.magic
    }
  } else {
    if (this.magic > set.magic) {
      this.magic = set.magic
    }
  }
  return this
}

Bucket.prototype.remove = function (pattern, payload) {
  var foundPattern = false
  var data = this.data
  var justRegex = onlyRegex(pattern)
  for (var i = 0; i < data.length; i++) {
    if (match(pattern, data[i].pattern)) {
      if (payload === null || payload === data[i].payload || justRegex) {
        data.splice(i, 1)
        foundPattern = true

        // to remove all occurences
        this.remove(pattern, payload)
        break
      }
    }
  }

  return foundPattern
}

Bucket.prototype.forEach = function (func, that) {
  this.data.forEach(func, that)
  return this
}

module.exports = Bucket
<|endoftext|>


<commit_before>var glob = require('glob');
var fs = require('fs');
var config = require('./config');
var JSZip = require('jszip');
var which = require('which');
var createRunner = require('./runner');
var Minimatch = require('minimatch').Minimatch;
var async = require('async');

function createManifest(fn) {
  var debug = require('debug')('lone:bundle:manifest');
  var manifest = {
    files: [],
    directories: []
  };
  var ignore = [];

  // Already ran the manifest
  if (config.manifest) {
    return fn();
  }

  function addIgnore(pattern) {
    pattern = pattern.replace(config.src + '/', '');
    debug('ignore', pattern);
    ignore.push(new Minimatch(pattern, {
      flipNegate: true
    }));
  }
  config.ignore.push.apply(config.ignore, ['node_modules/lone/**']);

  config.ignore.map(addIgnore);
  glob('{*,**/*}', {
    cwd: config.src,
    root: config.src,
    mark: true,
    strict: true
  }, function(err, files) {
    if (err) {
      return fn(err);
    }

    manifest.files = files.filter(function(p) {
      var gIgnore = ignore.some(function(i) {
        return i.match(p);
      });

      if (gIgnore === true) {
        return false;
      }
      if (p.charAt(p.length - 1) === '/') {
        manifest.directories.push(p);
        return false;
      }
      return true;
    });

    config.manifest = manifest;
    debug('files collected', config.manifest.files.length);
    fn();
  });
}

function createZip(fn) {
  var zip = new JSZip(null, {
    type: 'nodebuffer'
  });
  var debug = require('debug')('lone:bundle:zip');

  debug('reading files');

  async.parallelLimit(config.manifest.files.map(function(p) {
    return function(cb) {
      fs.readFile(config.src + '/' + p, function(err, data) {
        if (err) {
          return cb(err);
        }

        zip.file(p, data);
        cb(null);
      });
    };
  }), 100, function(err) {
    if (err) {
      return fn(err);
    }
    debug('writing', config.bundle);
    fs.writeFile(config.bundle, zip.generate({
      type: 'nodebuffer'
    }), fn);
  });
}

function install(fn) {
  var debug = require('debug')('lone:bundle:install');
  var cmd = config.node.out + ' ' + which.sync('npm-cli.js') + ' install --production';
  var run = createRunner(debug, config.src);
  debug('Installing dependencies...', cmd);
  debug('which node-gyp?', which.sync('node-gyp'));
  run(cmd)(fn);
}

module.exports = function(fn) {
  async.series([install, createManifest, createZip], fn);
};
<commit_msg>debugging windows<commit_after>var glob = require('glob');
var fs = require('fs');
var config = require('./config');
var JSZip = require('jszip');
var which = require('which');
var createRunner = require('./runner');
var Minimatch = require('minimatch').Minimatch;
var async = require('async');
var path = require('path');

function createManifest(fn) {
  var debug = require('debug')('lone:bundle:manifest');
  var manifest = {
    files: [],
    directories: []
  };
  var ignore = [];

  // Already ran the manifest
  if (config.manifest) {
    return fn();
  }

  function addIgnore(pattern) {
    pattern = pattern.replace(config.src + '/', '');
    debug('ignore', pattern);
    ignore.push(new Minimatch(pattern, {
      flipNegate: true
    }));
  }
  config.ignore.push.apply(config.ignore, ['node_modules/lone/**']);

  config.ignore.map(addIgnore);
  glob('{*,**/*}', {
    cwd: config.src,
    root: config.src,
    mark: true,
    strict: true
  }, function(err, files) {
    if (err) {
      return fn(err);
    }

    manifest.files = files.filter(function(p) {
      var gIgnore = ignore.some(function(i) {
        return i.match(p);
      });

      if (gIgnore === true) {
        return false;
      }
      if (p.charAt(p.length - 1) === '/') {
        manifest.directories.push(p);
        return false;
      }
      return true;
    });

    config.manifest = manifest;
    debug('files collected', config.manifest.files.length);
    fn();
  });
}

function createZip(fn) {
  var zip = new JSZip(null, {
    type: 'nodebuffer'
  });
  var debug = require('debug')('lone:bundle:zip');

  debug('reading files');

  async.parallelLimit(config.manifest.files.map(function(p) {
    return function(cb) {
      fs.readFile(config.src + '/' + p, function(err, data) {
        if (err) {
          return cb(err);
        }

        zip.file(p, data);
        cb(null);
      });
    };
  }), 100, function(err) {
    if (err) {
      return fn(err);
    }
    debug('writing', config.bundle);
    fs.writeFile(config.bundle, zip.generate({
      type: 'nodebuffer'
    }), fn);
  });
}

function install(fn) {
  var debug = require('debug')('lone:bundle:install');
  var cmd = config.node.out + ' ' + path.join(config.node.working,
    'deps', 'npm', 'bin', 'npm-cli.js') + ' install --production';

  var run = createRunner(debug, config.src);
  debug('Installing dependencies...', cmd);
  debug('which node-gyp?', which.sync('node-gyp'));
  run(cmd)(fn);
}

module.exports = function(fn) {
  async.series([install, createManifest, createZip], fn);
};
<|endoftext|>


<commit_before>var mdeps = require("module-deps"),
through   = require("through"),
async     = require("async"),
path      = require("path"),
fs        = require("fs"),
uglify = require("uglify-js"),
builtins = require("builtins");

function bundle (input, complete) {

  async.waterfall([

    /**
     */

    function resolveDeps (next) {

      var deps = [];

      var md = mdeps({
        xtransform: function (tr, file) {

          var buffer = [];
          console.log(tr);

          return through(write, end);

          var self = this;

          function write (chunk) {
            buffer.push(chunk.toString());
            // console.log(chunk.toString(""))
            console.log(tr);
          }

          function end() {
            var content = buffer.join("");
            // console.log(content);

            /*var source = uglify.parse(content, {
              strict: false
            });
            source.figure_out_scope();
            source.compute_char_frequency();
            source.mangle_names();

            // TODO - production
            content = source.print_to_string({
              ascii_only: true,
              quote_keys: true
            });*/

            this.queue(content);
            this.queue(null);
          }

        },
        filter: function (id) {
          return !~builtins.indexOf(id);
        }
      });
      md.pipe(through(function (chunk) {
        deps.push(chunk);
      }, function () {
        next(null, deps);
      }));

      md.end({ file: input })

    },

    function bundleScript (deps, next) {
      var buffer = [loader.toString()];
      var dbuffer = [];

      for (var i = deps.length; i--;) {
        var dep = deps[i];

        var req = "function (require, module, exports, __dirname) { \n"
        if (dep.id.toLowerCase().indexOf(".json", dep.id.length - 5) !== -1) {
          //this is the result of require("someFile.json"), so we need to export it from the function
          req += "module.exports = "
        }
        req += dep.source + "}";

        dbuffer.push(JSON.stringify(dep.id) + ": ["+req+", "+!!dep.entry+", "+JSON.stringify(dep.deps)+"]")
      }

      buffer = ["(" + loader.toString() + ").call(null, {"+dbuffer.join(",")+"}," + JSON.stringify(deps[deps.length-1].id) + ")"].toString();

      next(null, buffer);
    }
  ], complete)
}

var loader = function (deps, key) {
  var pathModule = global.require("path");
  var darr = [];
  var dir = global.require("path").dirname(process.execPath);

  var argv3 = process.argv[3];
  if (argv3) {
    argv3 = pathModule.relative(process.execPath, argv3);
    argv3 = pathModule.resolve(pathModule.dirname(key), argv3);
  }
  if (process.argv[2] == "--child_process" && deps[argv3]) {
    //we've been forked and should run the module specified by argv3[3] instead of the start up module
    key = argv3;
    process.argv = process.argv.splice(2, 2);
  }
  else if (process.argv[2] == "--child_process") {
    //fork called, but for a module not bundled.
    argv3 = process.argv[3];
    process.argv = process.argv.splice(2, 2);
    global.require(argv3);
    return;
  }
  darr.push(deps[key]); //start up module.

  function initModule (dep) {
    if (dep.module) return dep.module.exports;
    dep.module = { exports: {} };

    dep[0](function (path) {
      var rdep = deps[dep[2][path]];
      var exports = rdep ? rdep.module ? rdep.module.exports : initModule(rdep) : global.require(path);
      return exports;
    }, dep.module, dep.module.exports, dir);

    return dep.module.exports;
  }

  //run the startup module
  darr.forEach(initModule);

  return darr.filter(function (dep) {
    return dep[1];
  }).map(function (dep) {
    return dep.module || {};
  }).pop();
}

module.exports = bundle;
<commit_msg>Make process.argv consistent in the child fork cas<commit_after>var mdeps = require("module-deps"),
through   = require("through"),
async     = require("async"),
path      = require("path"),
fs        = require("fs"),
uglify = require("uglify-js"),
builtins = require("builtins");

function bundle (input, complete) {

  async.waterfall([

    /**
     */

    function resolveDeps (next) {

      var deps = [];

      var md = mdeps({
        xtransform: function (tr, file) {

          var buffer = [];
          console.log(tr);

          return through(write, end);

          var self = this;

          function write (chunk) {
            buffer.push(chunk.toString());
            // console.log(chunk.toString(""))
            console.log(tr);
          }

          function end() {
            var content = buffer.join("");
            // console.log(content);

            /*var source = uglify.parse(content, {
              strict: false
            });
            source.figure_out_scope();
            source.compute_char_frequency();
            source.mangle_names();

            // TODO - production
            content = source.print_to_string({
              ascii_only: true,
              quote_keys: true
            });*/

            this.queue(content);
            this.queue(null);
          }

        },
        filter: function (id) {
          return !~builtins.indexOf(id);
        }
      });
      md.pipe(through(function (chunk) {
        deps.push(chunk);
      }, function () {
        next(null, deps);
      }));

      md.end({ file: input })

    },

    function bundleScript (deps, next) {
      var buffer = [loader.toString()];
      var dbuffer = [];

      for (var i = deps.length; i--;) {
        var dep = deps[i];

        var req = "function (require, module, exports, __dirname) { \n"
        if (dep.id.toLowerCase().indexOf(".json", dep.id.length - 5) !== -1) {
          //this is the result of require("someFile.json"), so we need to export it from the function
          req += "module.exports = "
        }
        req += dep.source + "}";

        dbuffer.push(JSON.stringify(dep.id) + ": ["+req+", "+!!dep.entry+", "+JSON.stringify(dep.deps)+"]")
      }

      buffer = ["(" + loader.toString() + ").call(null, {"+dbuffer.join(",")+"}," + JSON.stringify(deps[deps.length-1].id) + ")"].toString();

      next(null, buffer);
    }
  ], complete)
}

var loader = function (deps, key) {
  var pathModule = global.require("path");
  var darr = [];
  var dir = global.require("path").dirname(process.execPath);

  var argv3 = process.argv[3];
  if (argv3) {
    argv3 = pathModule.relative(process.execPath, argv3);
    argv3 = pathModule.resolve(pathModule.dirname(key), argv3);
  }
  if (process.argv[2] == "--child_process" && deps[argv3]) {
    //we've been forked and should run the module specified by argv3[3] instead of the start up module
    key = argv3;
    process.argv.splice(2, 2); //restore the argv to [0] = executable, [1] = nexejs
  }
  else if (process.argv[2] == "--child_process") {
    //fork called, but for a module not bundled.
    argv3 = process.argv[3];
    process.argv.splice(1, 2); //restore the argv to [0] = executable, [1] = script
    global.require(argv3);
    return;
  }
  darr.push(deps[key]); //start up module.

  function initModule (dep) {
    if (dep.module) return dep.module.exports;
    dep.module = { exports: {} };

    dep[0](function (path) {
      var rdep = deps[dep[2][path]];
      var exports = rdep ? rdep.module ? rdep.module.exports : initModule(rdep) : global.require(path);
      return exports;
    }, dep.module, dep.module.exports, dir);

    return dep.module.exports;
  }

  //run the startup module
  darr.forEach(initModule);

  return darr.filter(function (dep) {
    return dep[1];
  }).map(function (dep) {
    return dep.module || {};
  }).pop();
}

module.exports = bundle;
<|endoftext|>


<commit_before>/**
 * @ngdoc module
 * @name angular.filters
 * @description
 *  bunch of useful filters for angularJS
 */

angular.module('angular.filter', [

  'a8m.ucfirst',
  'a8m.uri-encode',
  'a8m.slugify',
  'a8m.strip-tags',
  'a8m.stringular',
  'a8m.truncate',
  'a8m.starts-with',
  'a8m.ends-with',

  'a8m.concat',
  'a8m.unique',
  'a8m.is-empty',
  'a8m.after',
  'a8m.after-where',
  'a8m.before',
  'a8m.before-where',
  'a8m.where',
  'a8m.reverse',
  'a8m.remove',
  'a8m.remove-with',
  'a8m.group-by',
  'a8m.search-field',
  'a8m.fuzzy-by',
  'a8m.fuzzy',
  'a8m.omit',

  'a8m.math',
  'a8m.math.max',
  'a8m.math.min',

  'a8m.angular',
  'a8m.is-null'

]);
<commit_msg>fix(filters): register wrap module<commit_after>/**
 * @ngdoc module
 * @name angular.filters
 * @description
 *  bunch of useful filters for angularJS
 */

angular.module('angular.filter', [

  'a8m.ucfirst',
  'a8m.uri-encode',
  'a8m.slugify',
  'a8m.strip-tags',
  'a8m.stringular',
  'a8m.truncate',
  'a8m.starts-with',
  'a8m.ends-with',
  'a8m.wrap',

  'a8m.concat',
  'a8m.unique',
  'a8m.is-empty',
  'a8m.after',
  'a8m.after-where',
  'a8m.before',
  'a8m.before-where',
  'a8m.where',
  'a8m.reverse',
  'a8m.remove',
  'a8m.remove-with',
  'a8m.group-by',
  'a8m.search-field',
  'a8m.fuzzy-by',
  'a8m.fuzzy',
  'a8m.omit',

  'a8m.math',
  'a8m.math.max',
  'a8m.math.min',

  'a8m.angular',
  'a8m.is-null'

]);
<|endoftext|>


<commit_before>var whitelistSites = ['amazonaws.com', 'google.com', 'facebook.com', 'etsy.com', 'thinkgeek.com', 'github.com', 'yahoo.com', 'twitter.com', 'reddit.com', 'ml.com', 'bankofamerica.com', 'bankofamerica.co.uk'];
function isCachedSite(parsedDomain) {
    var cachedSites = JSON.parse(localStorage.cachedSites || "[]");
    console.log("  Cached Sites: " + JSON.stringify(cachedSites));
    var foundSite = false;
    // Check for the domain to be in our whitelist
    whitelistSites.some(function(site) {
        if (parsedDomain == site) {
            console.log("Found in WhiteList: " + parsedDomain);
            foundSite = true;
            return true;
        }
    });
    if (!foundSite && (cachedSites !== [])) {
        // Check for the domain to be in our cached entries
        cachedSites.some(function(site) {
            if (parsedDomain == site) {
                console.log("Found in Cached Sites: " + parsedDomain);
                foundSite = true;
                return true;
            }
        });
    }
    //return whether we found the domain in our whitelist or cached entries
    return foundSite;
}

function cacheSite(parsedDomain) {
    var cachedSites = JSON.parse(localStorage.cachedSites || "[]");
    cachedSites.push(parsedDomain);
    while (cachedSites.length > 250) {
        cachedSites.shift();
    }
    localStorage.cachedSites = JSON.stringify(cachedSites);
    console.log("  After Caching: " + JSON.stringify(cachedSites));
}

function resetCachedSites() {
    var cachedSites = [];
    localStorage.cachedSites = JSON.stringify(cachedSites);
    return true;
}
/*
 * These are for the heartbleed vulnerability sites, we will cache these for less time
 */
function isCachedBleedSite(parsedDomain) {
    var cachedBleedSites = JSON.parse(localStorage.cachedBleedSites || "[]");
    console.log("  Cached Bleed Sites: " + JSON.stringify(cachedBleedSites));
    var foundSite = false;
    if (!foundSite && (cachedBleedSites !== [])) {
        // Check for the domain to be in our cached entries
        cachedBleedSites.some(function(site) {
            if (parsedDomain == site) {
                console.log("   Found in Cached Bleed Sites: " + parsedDomain);
                foundSite = true;
                return true;
            }
        });
    }
    //return whether we found the domain in our whitelist or cached entries
    return foundSite;
}

function cacheBleedSite(parsedDomain) {
    var cachedBleedSites = JSON.parse(localStorage.cachedBleedSites || "[]");
    cachedBleedSites.push(parsedDomain);
    while (cachedBleedSites.length > 20) {
        cachedBleedSites.shift();
    }
    localStorage.cachedBleedSites = JSON.stringify(cachedBleedSites);
    console.log("  After Caching Bleed: " + JSON.stringify(cachedBleedSites));
}

function resetCachedBleedSites() {
    var cachedBleedSites = [];
    localStorage.cachedBleedSites = JSON.stringify(cachedBleedSites);
    return true;
}

<commit_msg>Split cached and whitelist checking<commit_after>var whitelistSites = ['amazonaws.com', 'google.com', 'facebook.com', 'etsy.com', 'thinkgeek.com', 'github.com', 'yahoo.com', 'twitter.com', 'reddit.com', 'ml.com', 'bankofamerica.com', 'bankofamerica.co.uk'];
function isWhiteListSite(parsedDomain) {
    var foundSite = false;
    // Check for the domain to be in our whitelist
    whitelistSites.some(function(site) {
        if (parsedDomain == site) {
            console.log("Found in WhiteList: " + parsedDomain);
            foundSite = true;
            return true;
        }
    });
    return foundSite;
}
function isCachedSite(parsedDomain) {
    var cachedSites = JSON.parse(localStorage.cachedSites || "[]");
    console.log("  Cached Sites: " + JSON.stringify(cachedSites));
    var foundSite = false;
    if (!foundSite && (cachedSites !== [])) {
        // Check for the domain to be in our cached entries
        cachedSites.some(function(site) {
            if (parsedDomain == site) {
                console.log("Found in Cached Sites: " + parsedDomain);
                foundSite = true;
                return true;
            }
        });
    }
    //return whether we found the domain in our whitelist or cached entries
    return foundSite;
}

function cacheSite(parsedDomain) {
    var cachedSites = JSON.parse(localStorage.cachedSites || "[]");
    cachedSites.push(parsedDomain);
    while (cachedSites.length > 250) {
        cachedSites.shift();
    }
    localStorage.cachedSites = JSON.stringify(cachedSites);
    console.log("  After Caching: " + JSON.stringify(cachedSites));
}

function resetCachedSites() {
    var cachedSites = [];
    localStorage.cachedSites = JSON.stringify(cachedSites);
    return true;
}
/*
 * These are for the heartbleed vulnerability sites, we will cache these for less time
 */
function isCachedBleedSite(parsedDomain) {
    var cachedBleedSites = JSON.parse(localStorage.cachedBleedSites || "[]");
    console.log("  Cached Bleed Sites: " + JSON.stringify(cachedBleedSites));
    var foundSite = false;
    if (!foundSite && (cachedBleedSites !== [])) {
        // Check for the domain to be in our cached entries
        cachedBleedSites.some(function(site) {
            if (parsedDomain == site) {
                console.log("   Found in Cached Bleed Sites: " + parsedDomain);
                foundSite = true;
                return true;
            }
        });
    }
    //return whether we found the domain in our whitelist or cached entries
    return foundSite;
}

function cacheBleedSite(parsedDomain) {
    var cachedBleedSites = JSON.parse(localStorage.cachedBleedSites || "[]");
    cachedBleedSites.push(parsedDomain);
    while (cachedBleedSites.length > 20) {
        cachedBleedSites.shift();
    }
    localStorage.cachedBleedSites = JSON.stringify(cachedBleedSites);
    console.log("  After Caching Bleed: " + JSON.stringify(cachedBleedSites));
}

function resetCachedBleedSites() {
    var cachedBleedSites = [];
    localStorage.cachedBleedSites = JSON.stringify(cachedBleedSites);
    return true;
}

<|endoftext|>


<commit_before><commit_msg>adding projection magic<commit_after><|endoftext|>


<commit_before>'use strict';

var util = require('./util');

function generateRequestHash(data, token) {
  return util.hmacHash('sha1', token, [
    'hmac.client',
    data.ts,
    data.nonce,
    data.method,
    data.url,
    data.hostName,
    data.hostPort,
    data.contentType
  ].join('\u000A'));
}

function authFactory(config) {

  var MAX_REQUEST_VALIDITY_MS = 60000 // 60 sec.
    , HEADER_RX = /^hmac(\s[a-z]+=[\w\-]+)+$/

    , identify = config.identifyCallback
    , apiKey = config.apiKey || 'apiKey'

    , options = {
        validityTime: MAX_REQUEST_VALIDITY_MS
      };

  function decomposeAuthorizationHeader(header) {

    if (!header || !HEADER_RX.test(header)) {
      return false;
    }

    var data = {}
      , headerData = String(header).split(' ');

    data.type = headerData[0].toLowerCase();

    headerData.slice(1).forEach(function (headerPart) {
      var entry = headerPart.split('=')
        , entryKey = entry[0].toLowerCase();

      if (entryKey === 'ts') {
        data[entryKey] = parseInt(entry[1], 10);
      }

      else {
        data[entryKey] = entry[1];
      }
    });

    return data;
  }

  function decomposeContentTypeHeader(header) {

    if (!header) {
      return 'text/plain';
    }

    var content = {}
      , contentType = header.split(/;\s*/g);

    content.type = contentType[0].toLowerCase();
    content.encoding = contentType[1] ? contentType[1].toLowerCase() : 'utf-8';

    return content;
  }

  function decomposeHost(request) {
    var host = {}
      , hostName = request.headers.host || request.host
      , hostData = hostName.split(':')
      , defaultPort = request.connection && request.connection.encrypted ? 443 : 80;

    host.name = hostData[0];
    host.port = hostData[1] ? parseInt(hostData[1], 10) : defaultPort;

    return host;
  }

  function calculateRequestHash(request, token) {
    var credentials = decomposeAuthorizationHeader(request.headers.authorization)
      , host = decomposeHost(request)
      , content = decomposeContentTypeHeader(request.headers['content-type']);

    return generateRequestHash({
      ts: credentials.ts,
      nonce: credentials.nonce,
      method: request.method,
      url: request.url,
      hostName: host.name,
      hostPort: host.port,
      contentType: content.type
    }, token);
  }

  function unauthorized(reason) {
    var err = new Error();

    err.message = reason;
    err.status = 403;

    return err;
  }

  function hasValidTimestamp(ts) {
    return Math.abs(util.utcNow() - ts) <= options.validityTime;
  }

  var api = {
    set: function (option, value) {
      options[option] = value;
    },

    /**
     * Method for authorizing incoming requests
     * @param {Object} request Express request object
     * @param {Function} cb Node style callback function (first argument should be an Error or null)
     */
    authorizeRequest: function (request, cb) {
      var credentials = decomposeAuthorizationHeader(request.headers.authorization);

      if (!credentials) {
        cb(unauthorized('Invalid Authorization header', request));
      }

      else if (!hasValidTimestamp(credentials.ts)) {
        cb(unauthorized('Request does not match time bounds', request, options));
      }

      else {
        identify(credentials.id, function (err, identity) {

          if (!identity) {
            cb(unauthorized('Authorization required', request, identity));
          }

          else if (!identity.nonce(credentials.nonce)) {
            cb(unauthorized('Request nonce is invalid', request, options));
          }

          else if (credentials.hash !== calculateRequestHash(request, identity[apiKey])) {
            cb(unauthorized('Invalid request hash', request, identity));
          }

          else {
            request.credentials = credentials;
            request.identity = identity;
            cb(null, identity);
          }
        });
      }

    }
  };

  return api;
}

authFactory.generateRequestHash = generateRequestHash;

authFactory.utils = util;

module.exports = authFactory;
<commit_msg>User Express originalUrl before url property<commit_after>'use strict';

var util = require('./util');

function generateRequestHash(data, token) {
  return util.hmacHash('sha1', token, [
    'hmac.client',
    data.ts,
    data.nonce,
    data.method,
    data.url,
    data.hostName,
    data.hostPort,
    data.contentType
  ].join('\u000A'));
}

function authFactory(config) {

  var MAX_REQUEST_VALIDITY_MS = 60000 // 60 sec.
    , HEADER_RX = /^hmac(\s[a-z]+=[\w\-]+)+$/

    , identify = config.identifyCallback
    , apiKey = config.apiKey || 'apiKey'

    , options = {
        validityTime: MAX_REQUEST_VALIDITY_MS
      };

  function decomposeAuthorizationHeader(header) {

    if (!header || !HEADER_RX.test(header)) {
      return false;
    }

    var data = {}
      , headerData = String(header).split(' ');

    data.type = headerData[0].toLowerCase();

    headerData.slice(1).forEach(function (headerPart) {
      var entry = headerPart.split('=')
        , entryKey = entry[0].toLowerCase();

      if (entryKey === 'ts') {
        data[entryKey] = parseInt(entry[1], 10);
      }

      else {
        data[entryKey] = entry[1];
      }
    });

    return data;
  }

  function decomposeContentTypeHeader(header) {

    if (!header) {
      return 'text/plain';
    }

    var content = {}
      , contentType = header.split(/;\s*/g);

    content.type = contentType[0].toLowerCase();
    content.encoding = contentType[1] ? contentType[1].toLowerCase() : 'utf-8';

    return content;
  }

  function decomposeHost(request) {
    var host = {}
      , hostName = request.headers.host || request.host
      , hostData = hostName.split(':')
      , defaultPort = request.connection && request.connection.encrypted ? 443 : 80;

    host.name = hostData[0];
    host.port = hostData[1] ? parseInt(hostData[1], 10) : defaultPort;

    return host;
  }

  function calculateRequestHash(request, token) {
    var credentials = decomposeAuthorizationHeader(request.headers.authorization)
      , host = decomposeHost(request)
      , content = decomposeContentTypeHeader(request.headers['content-type']);

    return generateRequestHash({
      ts: credentials.ts,
      nonce: credentials.nonce,
      method: request.method,
      url: request.originalUrl || request.url,
      hostName: host.name,
      hostPort: host.port,
      contentType: content.type
    }, token);
  }

  function unauthorized(reason) {
    var err = new Error();

    err.message = reason;
    err.status = 403;

    return err;
  }

  function hasValidTimestamp(ts) {
    return Math.abs(util.utcNow() - ts) <= options.validityTime;
  }

  var api = {
    set: function (option, value) {
      options[option] = value;
    },

    /**
     * Method for authorizing incoming requests
     * @param {Object} request Express request object
     * @param {Function} cb Node style callback function (first argument should be an Error or null)
     */
    authorizeRequest: function (request, cb) {
      var credentials = decomposeAuthorizationHeader(request.headers.authorization);

      if (!credentials) {
        cb(unauthorized('Invalid Authorization header', request));
      }

      else if (!hasValidTimestamp(credentials.ts)) {
        cb(unauthorized('Request does not match time bounds', request, options));
      }

      else {
        identify(credentials.id, function (err, identity) {

          if (!identity) {
            cb(unauthorized('Authorization required', request, identity));
          }

          else if (!identity.nonce(credentials.nonce)) {
            cb(unauthorized('Request nonce is invalid', request, options));
          }

          else if (credentials.hash !== calculateRequestHash(request, identity[apiKey])) {
            cb(unauthorized('Invalid request hash', request, identity));
          }

          else {
            request.credentials = credentials;
            request.identity = identity;
            cb(null, identity);
          }
        });
      }

    }
  };

  return api;
}

authFactory.generateRequestHash = generateRequestHash;

authFactory.utils = util;

module.exports = authFactory;
<|endoftext|>


<commit_before>var protocol = require('./protocol.js');
var util = require('util');
var events = require('events');
var http = require('http');
var WebSocket = require('ws');

var Chrome = function (options, notifier) {
    var self = this;
    addCommandShorthands.call(self);
    self.notifier = notifier;
    self.callbacks = {};
    self.nextCommandId = 1;
    connectToChrome.call(self, options.host, options.port, options.chooseTab);
}

util.inherits(Chrome, events.EventEmitter);

Chrome.prototype.send = function (method, params, callback) {
    var self = this;
    var id = self.nextCommandId++;
    if (typeof params == 'function') {
        callback = params;
        params = undefined;
    }
    var message = {'id': id, 'method': method, 'params': params};
    self.ws.send(JSON.stringify(message));
    // register command response callback
    if (typeof callback == 'function') {
        self.callbacks[id] = callback;
    }
}

Chrome.prototype.close = function () {
    var self = this;
    self.ws.close();
}

function addCommandShorthands() {
    var self = this;
    for (var domain in protocol.commands) {
        Chrome.prototype[domain] = {};
        var commands = protocol.commands[domain];
        for (var i = 0; i < commands.length; i++) {
            var command = commands[i];
            (function (method) {
                Chrome.prototype[domain][command] = function (params, callback) {
                    self.send(method, params, callback);
                };
            })(domain + '.' + command);
        }
    }
}

function connectToChrome(host, port, chooseTab) {
    var self = this;
    var options = {'host': host, 'port': port, 'path': '/json'};
    var request = http.get(options, function (response) {
        var data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            var tabs = JSON.parse(data);
            var tab = tabs[chooseTab(tabs)];
            if (tab) {
                var tabDebuggerUrl = tab.webSocketDebuggerUrl;
                if (tabDebuggerUrl) {
                    connectToWebSocket.call(self, tabDebuggerUrl);
                } else {
                    // a WebSocket is already connected to this tab?
                    var error = new Error('Unable to connect to the WebSocket');
                    self.notifier.emit('error', error);
                }
            } else {
                var error = new Error('Invalid tab index');
                self.notifier.emit('error', error);
            }
        });
    });
    request.on('error', function (error) {
        self.notifier.emit('error', error);
    });
}

function connectToWebSocket(url) {
    var self = this;
    self.ws = new WebSocket(url);
    self.ws.on('open', function() {
        self.notifier.emit('connect', self);
    });
    self.ws.on('message', function (data) {
        var message = JSON.parse(data);
        // command response
        if (message.id) {
            var callback = self.callbacks[message.id];
            if (callback) {
                if (message.result) {
                    callback(false, message.result);
                } else if (message.error) {
                    callback(true, message.error);
                }
                // unregister command response callback
                delete self.callbacks[message.id];
            }
        }
        // event
        else if (message.method) {
            self.emit('event', message);
            self.emit(message.method, message.params);
        }
    });
    self.ws.on('error', function (error) {
        self.notifier.emit('error', error);
    });
}

module.exports = Chrome;
<commit_msg>Ensure that no more messages are received after 'close()'<commit_after>var protocol = require('./protocol.js');
var util = require('util');
var events = require('events');
var http = require('http');
var WebSocket = require('ws');

var Chrome = function (options, notifier) {
    var self = this;
    addCommandShorthands.call(self);
    self.notifier = notifier;
    self.callbacks = {};
    self.nextCommandId = 1;
    connectToChrome.call(self, options.host, options.port, options.chooseTab);
}

util.inherits(Chrome, events.EventEmitter);

Chrome.prototype.send = function (method, params, callback) {
    var self = this;
    var id = self.nextCommandId++;
    if (typeof params == 'function') {
        callback = params;
        params = undefined;
    }
    var message = {'id': id, 'method': method, 'params': params};
    self.ws.send(JSON.stringify(message));
    // register command response callback
    if (typeof callback == 'function') {
        self.callbacks[id] = callback;
    }
}

Chrome.prototype.close = function () {
    var self = this;
    self.ws.removeAllListeners();
    self.ws.close();
}

function addCommandShorthands() {
    var self = this;
    for (var domain in protocol.commands) {
        Chrome.prototype[domain] = {};
        var commands = protocol.commands[domain];
        for (var i = 0; i < commands.length; i++) {
            var command = commands[i];
            (function (method) {
                Chrome.prototype[domain][command] = function (params, callback) {
                    self.send(method, params, callback);
                };
            })(domain + '.' + command);
        }
    }
}

function connectToChrome(host, port, chooseTab) {
    var self = this;
    var options = {'host': host, 'port': port, 'path': '/json'};
    var request = http.get(options, function (response) {
        var data = '';
        response.on('data', function (chunk) {
            data += chunk;
        });
        response.on('end', function () {
            var tabs = JSON.parse(data);
            var tab = tabs[chooseTab(tabs)];
            if (tab) {
                var tabDebuggerUrl = tab.webSocketDebuggerUrl;
                if (tabDebuggerUrl) {
                    connectToWebSocket.call(self, tabDebuggerUrl);
                } else {
                    // a WebSocket is already connected to this tab?
                    var error = new Error('Unable to connect to the WebSocket');
                    self.notifier.emit('error', error);
                }
            } else {
                var error = new Error('Invalid tab index');
                self.notifier.emit('error', error);
            }
        });
    });
    request.on('error', function (error) {
        self.notifier.emit('error', error);
    });
}

function connectToWebSocket(url) {
    var self = this;
    self.ws = new WebSocket(url);
    self.ws.on('open', function() {
        self.notifier.emit('connect', self);
    });
    self.ws.on('message', function (data) {
        var message = JSON.parse(data);
        // command response
        if (message.id) {
            var callback = self.callbacks[message.id];
            if (callback) {
                if (message.result) {
                    callback(false, message.result);
                } else if (message.error) {
                    callback(true, message.error);
                }
                // unregister command response callback
                delete self.callbacks[message.id];
            }
        }
        // event
        else if (message.method) {
            self.emit('event', message);
            self.emit(message.method, message.params);
        }
    });
    self.ws.on('error', function (error) {
        self.notifier.emit('error', error);
    });
}

module.exports = Chrome;
<|endoftext|>


<commit_before>steal.apps('steal/openajax').then(function(){

/**
 * jQuery hashchange 1.0.0
 *
 * (based on jquery.history)
 *
 * Copyright (c) 2008 Chris Leishman (chrisleishman.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Modified from original at http://plugins.jquery.com/project/hashchange
 *
 * treyk 06/10/2009 - Added in support for change to address bar in IE
 *                    Also removed live binding to a[href] because it's not needed with
 *                    monitoring for address bar changes in IE.
 *
 * History / hashchange plugin that provides history, hashchange event, and bookmarking for
 * DHTML and Ajax applications
 *
 * This plugin provides onhashchange event notification for browsers that don't yet support
 * this HTML 5 standard.  To get notifications for this event, simply use the provide
 * hashchange function:
 * @codestart
 * $(document).ready(function($) {
 *    $(document.body).hashchange(function() {
 *       alert("Got hashchange event: " + location.hash);
 *    });
 * });
 * @codeend
 *
 * This module needs to be initialized. You have the option of firing an initial hash change
 * event after initialization.  To do this, set the $.History.fireInitialChange variable to
 * true BEFORE calling init.  This variable defaults to true.
 * Note: If you want to get an initally change event, you must first bind to the
 * event before calling the init function.
 * @codestart
 * $(document).ready(function($) {
 *    $.History.fireInitialChange = false;  // Set before calling init function.
 *    $.History.init();
 * });
 * @codeend
 *
 *
 *
 *
 *
 *
 *
 */
(function($) {

function formatHash(hash) {
   if (!hash)
      hash = '#';
   else if (hash.charAt(0) != '#')
      hash = '#' + hash;

   return hash;
}

$.fn.extend({
   hashchange: function(callback) { return this.bind('hashchange', callback) },
   openOnClick: function(href) {
      if (href === undefined || href.length == 0)
         href = '#';
      return this.click(function(ev) {
         if (href && href.charAt(0) == '#') {
            // execute load in separate call stack
            window.setTimeout(function() { $.History.add(href) }, 0);
         }
         else {
            window.location(href);
         }
         ev.stopPropagation();
         return false;
      });
   }
});

function isHashchangeEventSupported(eventName) {
    var el = document.documentElement;
    eventName = 'on' + eventName;
    var isSupported = (eventName in el);
    if (!isSupported) {
      el.setAttribute(eventName, 'return;');
      isSupported = typeof el[eventName] == 'function';
    }
    el = null;
    return isSupported;
}

if(isHashchangeEventSupported("hashchange")){
   $.extend({
          History : {
             fireInitialChange: true,
             init: function() {
                if($.History.fireInitialChange)
                   $.event.trigger('hashchange');
         },

         add: function(hash) {
            location.hash = formatHash(hash);
         },

         replace: function(hash) {
            var path = location.href.split('#')[0] + formatHash(hash);
            location.replace(path);
         }
      }
   });
   return;
}

// IE 8 introduces the hashchange event natively - so nothing more to do
if ($.browser.msie && document.documentMode && document.documentMode >= 8) {
   $.extend({
      History : {
         fireInitialChange: true,
         init: function() {
            if($.History.fireInitialChange)
               $.event.trigger('hashchange');
         },

         add: function(hash) {
            location.hash = formatHash(hash);
         },

         replace: function(hash) {
            var path = location.href.split('#')[0] + formatHash(hash);
            location.replace(path);
         }
      }
   });
   return;
}

var curHash;
// hidden iframe for IE (earlier than 8)
var iframe;

$.extend({
   History : {
      fireInitialChange: true,
      init: function() {
         curHash = location.hash;

         if ($.browser.msie) {
            // stop the callback firing twice during init if no hash present
            if (curHash == '')
               curHash = '#';
            // add hidden iframe for IE
            iframe = $('').hide().get(0);
            $('body').prepend(iframe);
            updateIEFrame(location.hash);
            setInterval(checkHashIE, 100);
         }
         else if(!$.browser.rhino)
            setInterval(checkHash, 100); //id like this to wait for load

         if($.History.fireInitialChange)
            $.event.trigger('hashchange');
      },

      add: function(hash) {
         if (curHash === undefined)
            return;

         location.hash = formatHash(hash);

         //if (curHash == hash)  let it detect this itself because location.hash might not equal hash
         //   return;
         //curHash = hash;

         //if ($.browser.msie)
         //   updateIEFrame(hash);

         //$.event.trigger('hashchange');  Removed,
      },

      replace: function(hash) {
         var path = location.href.split('#')[0] + formatHash(hash);
         location.replace(path);
      }
   }
});
/*
$(document).ready(function() {
   $.History.init();
});
*/
$(window).unload(function() { iframe = null });

function checkHash() {
   var hash = location.hash;
   if (hash != curHash) {
      curHash = hash;
      $.event.trigger('hashchange');
   }
}
/*
function hasNamedAnchor(hash) {
   return ($(hash).length > 0 || $('a[name='+hash.slice(1)+']').length > 0);
}

if ($.browser.msie) {
    // Attach a live handler for any anchor links
//orig    $('a[href^=#]').live('click', function() {
    $("a[href*='#']").live('click', function() {
        var hash = $(this).attr('href');
        var poundIndex = hash.indexOf('#');
        if(poundIndex > 0)
           hash = hash.substring(poundIndex);
        // Don't intercept the click if there is an existing anchor on the page
        // that matches this hash
        if ( !hasNamedAnchor(hash) ) {
            $.History.add(hash);
            return false;
        }
    });
}
*/
function checkHashIE() {
   /* First, check for address bar change */
   var hash = location.hash;
   if (hash != curHash) {
      updateIEFrame(hash);
      curHash = hash;
      $.event.trigger('hashchange');
      return
   }

   // Now check for back/forward button
   // On IE, check for location.hash of iframe
   var idoc = iframe.contentDocument || iframe.contentWindow.document;
   var hash = idoc.location.hash;
   if (hash == '')
      hash = '#';

   if (hash != curHash) {
      if (location.hash != hash)
         location.hash = hash;
      curHash = hash;
      $.event.trigger('hashchange');
   }
}

function updateIEFrame(hash) {
   if (hash == '#')
      hash = '';
   var idoc = iframe.contentDocument || iframe.contentWindow.document;
   idoc.open();
   idoc.close();
   if (idoc.location.hash != hash)
      idoc.location.hash = hash;
}

})(jQuery);

 (function($) {
     /**
  * !class jQuery.Path
  * Provides functional access to the given path (usually initialized from location.href)
  */
 $.Path = function(path) {
     this.path = path;
 };
 $.Path.prototype = {
     domain : function() {
         var lhs = this.path.split('#')[0];
         return '/'+lhs.split('/').slice(3).join('/');
     },
     folder : function() {
         var first_pound = this.path.indexOf('#');
         if( first_pound == -1) return null;
         var after_pound =  this.path.substring( first_pound+1 );

         var first_amp = after_pound.indexOf("&");
         if(first_amp == -1 ) return after_pound.indexOf("=") != -1 ? null : after_pound;

         return after_pound.substring(0, first_amp);
     },
     //types of urls
     //  /someproject#action/controller&doo_doo=butter
     //  /someproject#doo_doo=butter
     params : function() {
         var first_pound = this.path.indexOf('#');
         if( first_pound == -1) return null;
         var after_pound =  this.path.substring( first_pound+1 );

         //now either return everything after the first & or everything
         var first_amp = after_pound.indexOf("&");
         if(first_amp == -1 ) return after_pound.indexOf("=") != -1 ? after_pound : null;

         return ( after_pound.substring(0,first_amp).indexOf("=") == -1 ? after_pound.substring(first_amp+1) : after_pound );

     }
 };

 $.Path.get_data = function(path) {
     var search = path.params();
     if(! search || ! search.match(/([^?#]*)(#.*)?$/) ) return {};

     // Support the legacy format that used MVC.Object.to_query_string that used %20 for
     // spaces and not the '+' sign;
     search = search.replace(/\+/g,"%20")

     var data = {};
     var parts = search.split('&');
     for(var i=0; i < parts.length; i++){
         var pair = parts[i].split('=');
         if(pair.length != 2) continue;
         var key = decodeURIComponent(pair[0]), value = decodeURIComponent(pair[1]);
         var key_components = jQuery.String.rsplit(key,/\[[^\]]*\]/);

         if( key_components.length > 1 ) {
             var last = key_components.length - 1;
             var nested_key = key_components[0].toString();
             if(! data[nested_key] ) data[nested_key] = {};
             var nested_hash = data[nested_key];

             for(var k = 1; k < last; k++){
                 nested_key = key_components[k].substring(1, key_components[k].length - 1);
                 if( ! nested_hash[nested_key] ) nested_hash[nested_key] ={};
                 nested_hash = nested_hash[nested_key];
             }
             nested_hash[ key_components[last].substring(1, key_components[last].length - 1) ] = value;
         } else {
             if (key in data) {
                 if (typeof data[key] == 'string' ) data[key] = [data[key]];
                  data[key].push(value);
             }
             else data[key] = value;
         }

     }
     return data;
 }
 })(jQuery);

 // On document ready, register the hashchange event on the document.body in order to publish
 // OpenAjax messages on the hashchange event.
 jQuery(function($) {
    $(window).hashchange(function() {
        var path = new $.Path(location.href);
        var data = $.Path.get_data(path);
        var folders = path.folder() || 'index';

       var hasSlash = (folders.indexOf('/') != -1);

       if(!hasSlash) {
          // If there is no name in the folder list, then assume it's a controller and
          // we need to add the index action to it (unless the name is index).
          if(folders != 'index')
             folders += '/index';
       }
       OpenAjax.hub.publish("history."+folders.replace("/","."), data);
    });

    $.History.init();
 });

});<commit_msg>Fixed bug in history plugin reported by Trey Kennedy.<commit_after>steal.apps('steal/openajax').then(function(){

/**
 * jQuery hashchange 1.0.0
 *
 * (based on jquery.history)
 *
 * Copyright (c) 2008 Chris Leishman (chrisleishman.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Modified from original at http://plugins.jquery.com/project/hashchange
 *
 * treyk 06/10/2009 - Added in support for change to address bar in IE
 *                    Also removed live binding to a[href] because it's not needed with
 *                    monitoring for address bar changes in IE.
 *
 * History / hashchange plugin that provides history, hashchange event, and bookmarking for
 * DHTML and Ajax applications
 *
 * This plugin provides onhashchange event notification for browsers that don't yet support
 * this HTML 5 standard.  To get notifications for this event, simply use the provide
 * hashchange function:
 * @codestart
 * $(document).ready(function($) {
 *    $(document.body).hashchange(function() {
 *       alert("Got hashchange event: " + location.hash);
 *    });
 * });
 * @codeend
 *
 * This module needs to be initialized. You have the option of firing an initial hash change
 * event after initialization.  To do this, set the $.History.fireInitialChange variable to
 * true BEFORE calling init.  This variable defaults to true.
 * Note: If you want to get an initally change event, you must first bind to the
 * event before calling the init function.
 * @codestart
 * $(document).ready(function($) {
 *    $.History.fireInitialChange = false;  // Set before calling init function.
 *    $.History.init();
 * });
 * @codeend
 *
 *
 *
 *
 *
 *
 *
 */
(function($) {

function formatHash(hash) {
   if (!hash)
      hash = '#';
   else if (hash.charAt(0) != '#')
      hash = '#' + hash;

   return hash;
}

$.fn.extend({
   hashchange: function(callback) { return this.bind('hashchange', callback) },
   openOnClick: function(href) {
      if (href === undefined || href.length == 0)
         href = '#';
      return this.click(function(ev) {
         if (href && href.charAt(0) == '#') {
            // execute load in separate call stack
            window.setTimeout(function() { $.History.add(href) }, 0);
         }
         else {
            window.location(href);
         }
         ev.stopPropagation();
         return false;
      });
   }
});

function isHashchangeEventSupported() {
   var el = window;
   var eventName = 'onhashchange';
   var isSupported = (eventName in el);
   if (!isSupported) {
      try {
         el.setAttribute(eventName, 'return;');
         isSupported = typeof el[eventName] == 'function';
      } catch(e) {}
   }
   el = null;
   return isSupported;
}

$.support.hashchange = isHashchangeEventSupported();

//For browsers that support hashchange natively, we don't have to poll for hash changes
if ($.support.hashchange) {
   $.support.hashchange = true
   $.extend({
      History : {
         fireInitialChange: true,
         init: function() {
            if($.History.fireInitialChange)
               $.event.trigger('hashchange');
         },

         add: function(hash) {
            location.hash = formatHash(hash);
         },

         replace: function(hash) {
            var path = location.href.split('#')[0] + formatHash(hash);
            location.replace(path);
         }
      }
   });
   return;
}

var curHash;
// hidden iframe for IE (earlier than 8)
var iframe;

$.extend({
   History : {
      fireInitialChange: true,
      init: function() {
         curHash = location.hash;

         if ($.browser.msie) {
            // stop the callback firing twice during init if no hash present
            if (curHash == '')
               curHash = '#';
            // add hidden iframe for IE
            iframe = $('').hide().get(0);
            $('body').prepend(iframe);
            updateIEFrame(location.hash);
            setInterval(checkHashIE, 100);
         }
         else if(!$.browser.rhino)
            setInterval(checkHash, 100); //id like this to wait for load

         if($.History.fireInitialChange)
            $.event.trigger('hashchange');
      },

      add: function(hash) {
         if (curHash === undefined)
            return;

         location.hash = formatHash(hash);

         //if (curHash == hash)  let it detect this itself because location.hash might not equal hash
         //   return;
         //curHash = hash;

         //if ($.browser.msie)
         //   updateIEFrame(hash);

         //$.event.trigger('hashchange');  Removed,
      },

      replace: function(hash) {
         var path = location.href.split('#')[0] + formatHash(hash);
         location.replace(path);
      }
   }
});
/*
$(document).ready(function() {
   $.History.init();
});
*/
$(window).unload(function() { iframe = null });

function checkHash() {
   var hash = location.hash;
   if (hash != curHash) {
      curHash = hash;
      $.event.trigger('hashchange');
   }
}
/*
function hasNamedAnchor(hash) {
   return ($(hash).length > 0 || $('a[name='+hash.slice(1)+']').length > 0);
}

if ($.browser.msie) {
    // Attach a live handler for any anchor links
//orig    $('a[href^=#]').live('click', function() {
    $("a[href*='#']").live('click', function() {
        var hash = $(this).attr('href');
        var poundIndex = hash.indexOf('#');
        if(poundIndex > 0)
           hash = hash.substring(poundIndex);
        // Don't intercept the click if there is an existing anchor on the page
        // that matches this hash
        if ( !hasNamedAnchor(hash) ) {
            $.History.add(hash);
            return false;
        }
    });
}
*/
function checkHashIE() {
   /* First, check for address bar change */
   var hash = location.hash;
   if (hash != curHash) {
      updateIEFrame(hash);
      curHash = hash;
      $.event.trigger('hashchange');
      return
   }

   // Now check for back/forward button
   // On IE, check for location.hash of iframe
   var idoc = iframe.contentDocument || iframe.contentWindow.document;
   var hash = idoc.location.hash;
   if (hash == '')
      hash = '#';

   if (hash != curHash) {
      if (location.hash != hash)
         location.hash = hash;
      curHash = hash;
      $.event.trigger('hashchange');
   }
}

function updateIEFrame(hash) {
   if (hash == '#')
      hash = '';
   var idoc = iframe.contentDocument || iframe.contentWindow.document;
   idoc.open();
   idoc.close();
   if (idoc.location.hash != hash)
      idoc.location.hash = hash;
}

})(jQuery);

 (function($) {

 var rsplit = function(string, regex) {
	var result = regex.exec(string),retArr = new Array(), first_idx, last_idx, first_bit;
	while (result != null)
	{
		first_idx = result.index; last_idx = regex.lastIndex;
		if ((first_idx) != 0)
		{
			first_bit = string.substring(0,first_idx);
			retArr.push(string.substring(0,first_idx));
			string = string.slice(first_idx);
		}
		retArr.push(result[0]);
		string = string.slice(result[0].length);
		result = regex.exec(string);
	}
	if (! string == '')
	{
		retArr.push(string);
	}
	return retArr;
 }

	 /**
  * !class jQuery.Path
  * Provides functional access to the given path (usually initialized from location.href)
  */
 $.Path = function(path) {
     this.path = path;
 };
 $.Path.prototype = {
     domain : function() {
         var lhs = this.path.split('#')[0];
         return '/'+lhs.split('/').slice(3).join('/');
     },
     folder : function() {
         var first_pound = this.path.indexOf('#');
         if( first_pound == -1) return null;
         var after_pound =  this.path.substring( first_pound+1 );

         var first_amp = after_pound.indexOf("&");
         if(first_amp == -1 ) return after_pound.indexOf("=") != -1 ? null : after_pound;

         return after_pound.substring(0, first_amp);
     },
     //types of urls
     //  /someproject#action/controller&doo_doo=butter
     //  /someproject#doo_doo=butter
     params : function() {
         var first_pound = this.path.indexOf('#');
         if( first_pound == -1) return null;
         var after_pound =  this.path.substring( first_pound+1 );

         //now either return everything after the first & or everything
         var first_amp = after_pound.indexOf("&");
         if(first_amp == -1 ) return after_pound.indexOf("=") != -1 ? after_pound : null;

         return ( after_pound.substring(0,first_amp).indexOf("=") == -1 ? after_pound.substring(first_amp+1) : after_pound );

     }
 };

 $.Path.get_data = function(path) {
     var search = path.params();
     if(! search || ! search.match(/([^?#]*)(#.*)?$/) ) return {};

     // Support the legacy format that used MVC.Object.to_query_string that used %20 for
     // spaces and not the '+' sign;
     search = search.replace(/\+/g,"%20")

     var data = {};
     var parts = search.split('&');
     for(var i=0; i < parts.length; i++){
         var pair = parts[i].split('=');
         if(pair.length != 2) continue;
         var key = decodeURIComponent(pair[0]), value = decodeURIComponent(pair[1]);
         var key_components = rsplit(key,/\[[^\]]*\]/);

         if( key_components.length > 1 ) {
             var last = key_components.length - 1;
             var nested_key = key_components[0].toString();
             if(! data[nested_key] ) data[nested_key] = {};
             var nested_hash = data[nested_key];

             for(var k = 1; k < last; k++){
                 nested_key = key_components[k].substring(1, key_components[k].length - 1);
                 if( ! nested_hash[nested_key] ) nested_hash[nested_key] ={};
                 nested_hash = nested_hash[nested_key];
             }
             nested_hash[ key_components[last].substring(1, key_components[last].length - 1) ] = value;
         } else {
             if (key in data) {
                 if (typeof data[key] == 'string' ) data[key] = [data[key]];
                  data[key].push(value);
             }
             else data[key] = value;
         }

     }
     return data;
 }
 })(jQuery);

 // On document ready, register the hashchange event on the document.body in order to publish
 // OpenAjax messages on the hashchange event.
 jQuery(function($) {
    $(window).hashchange(function() {
        var path = new $.Path(location.href);
        var data = $.Path.get_data(path);
        var folders = path.folder() || 'index';

       var hasSlash = (folders.indexOf('/') != -1);

       if(!hasSlash) {
          // If there is no name in the folder list, then assume it's a controller and
          // we need to add the index action to it (unless the name is index).
          if(folders != 'index')
             folders += '/index';
       }
       OpenAjax.hub.publish("history."+folders.replace("/","."), data);
    });

    $.History.init();
 });

});<|endoftext|>


<commit_before>var io, exec, Emitify, loadRemote;

(function(global) {
    'use strict';

    if (typeof module !== 'undefined' && module.exports)
        module.exports  = new SperoProto();
    else
        global.spero    = new SperoProto();

    function SperoProto() {
        var Progress;

        function Spero(prefix, callback) {
            if (!callback) {
                callback    = prefix;
                prefix      = '/spero';
            }

            loadAll(prefix, function() {
                Progress = new ProgressProto(prefix);
                Object.setPrototypeOf(Spero, Emitify());

                if (typeof callback === 'function')
                    callback();
            });
        }

        Spero.copy  = function(from, to, files) {
            Progress.copy(from, to, files);
        };

        Spero.abort = function() {
            Progress.abort();
        };

        Spero.pause = function() {
            Progress.pause();
        };

        Spero.continue = function() {
            Progress.continue();
        };

        function loadAll(prefix, callback) {
            var scripts = [];

            if (!exec)
                scripts.push('/modules/execon/lib/exec.js');

            if (!scripts.length)
                loadFiles(prefix, callback);
            else
                loadScript(scripts.map(function(name) {
                    return prefix + name;
                }), function() {
                    loadFiles(prefix, callback);
                });
        }

        function getModulePath(name, lib) {
            var path    = '',
                libdir  = '/',
                dir     = '/modules/';

            if (lib)
                libdir  = '/' + lib + '/';

            path    = dir + name + libdir + name + '.js';

            return path;
        }

        function loadFiles(prefix, callback) {
            exec.series([
                function(callback) {
                    var obj     = {
                            loadRemote  : getModulePath('loadremote', 'lib'),
                            load        : getModulePath('load'),
                            Emitify     : getModulePath('emitify', 'lib'),
                            join        : '/join/join.js'
                        },

                        scripts = Object.keys(obj)
                            .filter(function(name) {
                                return !window[name];
                            })
                            .map(function(name) {
                                return prefix + obj[name];
                            });

                    exec.if(!scripts.length, callback, function() {
                        loadScript(scripts, callback);
                    });
                },

                function(callback) {
                    loadRemote('socket', {
                        name : 'io',
                        prefix: prefix,
                        noPrefix: true
                    }, callback);
                },

                function() {
                    callback();
                }
            ]);
        }

        function loadScript(srcs, callback) {
            var i       = srcs.length,
                func    = function() {
                    --i;

                    if (!i)
                        callback();
                };

            srcs.forEach(function(src) {
                var element = document.createElement('script');

                element.src = src;
                element.addEventListener('load', function load() {
                    func();
                    element.removeEventListener('load', load);
                });

                document.body.appendChild(element);
            });
        }

        function ProgressProto(room) {
            var socket;

            init(room);

            function init(room) {
                var href            = getHost(),
                    FIVE_SECONDS    = 5000;

                socket = io.connect(href + room, {
                    'max reconnection attempts' : Math.pow(2, 32),
                    'reconnection limit'        : FIVE_SECONDS
                });

                socket.on('err', function(error) {
                    Spero.emit('error', error);
                });

                socket.on('file', function(name) {
                    Spero.emit('file', name);
                });

                socket.on('progress', function(percent) {
                    Spero.emit('progress', percent);
                });

                socket.on('end', function() {
                    Spero.emit('end');
                });

                socket.on('connect', function() {
                    Spero.emit('connect');
                });

                socket.on('disconnect', function() {
                    Spero.emit('disconnect');
                });
            }

            this.pause       = function() {
                socket.emit('pause');
            };

            this.continue   = function() {
                socket.emit('continue');
            };

            this.abort       = function() {
                socket.emit('abort');
            };

            this.copy       = function(from, to, files) {
                socket.emit('copy', from, to, files);
            };

            function getHost() {
                var l       = location,
                    href    = l.origin || l.protocol + '//' + l.host;

                return href;
            }
        }

        return Spero;
    }

})(this);
<commit_msg>feature(spero) setPrototypeOf -> Object.create<commit_after>var io, exec, Emitify, loadRemote;

(function(global) {
    'use strict';

    if (typeof module !== 'undefined' && module.exports)
        module.exports  = new SperoProto();
    else
        global.spero    = new SperoProto();

    function SperoProto() {
        function load(prefix, callback) {
            if (!callback) {
                callback    = prefix;
                prefix      = '/spero';
            }

            loadAll(prefix, function() {
                init();

                global.spero    = Spero(prefix);

                if (typeof callback === 'function')
                    callback();
            });
        }

        function Spero(prefix) {
            if (!(this instanceof Spero))
                return new Spero(prefix);

            Emitify.call(this);
            this._progress = ProgressProto(prefix, this);
        }

        function init() {
            Spero.prototype = Object.create(Emitify.prototype);

            Spero.prototype.copy  = function(from, to, files) {
                this._progress.copy(from, to, files);
            };

            Spero.prototype.abort = function() {
                this._progress.abort();
            };

            Spero.prototype.pause = function() {
                this._progress.pause();
            };

            Spero.prototype.continue = function() {
                this._progress.continue();
            };
        }

        function loadAll(prefix, callback) {
            var scripts = [];

            if (!exec)
                scripts.push('/modules/execon/lib/exec.js');

            if (!scripts.length)
                loadFiles(prefix, callback);
            else
                loadScript(scripts.map(function(name) {
                    return prefix + name;
                }), function() {
                    loadFiles(prefix, callback);
                });
        }

        function getModulePath(name, lib) {
            var path    = '',
                libdir  = '/',
                dir     = '/modules/';

            if (lib)
                libdir  = '/' + lib + '/';

            path    = dir + name + libdir + name + '.js';

            return path;
        }

        function loadFiles(prefix, callback) {
            exec.series([
                function(callback) {
                    var obj     = {
                            loadRemote  : getModulePath('loadremote', 'lib'),
                            load        : getModulePath('load'),
                            Emitify     : getModulePath('emitify', 'lib'),
                            join        : '/join/join.js'
                        },

                        scripts = Object.keys(obj)
                            .filter(function(name) {
                                return !window[name];
                            })
                            .map(function(name) {
                                return prefix + obj[name];
                            });

                    exec.if(!scripts.length, callback, function() {
                        loadScript(scripts, callback);
                    });
                },

                function(callback) {
                    loadRemote('socket', {
                        name : 'io',
                        prefix: prefix,
                        noPrefix: true
                    }, callback);
                },

                function() {
                    callback();
                }
            ]);
        }

        function loadScript(srcs, callback) {
            var i       = srcs.length,
                func    = function() {
                    --i;

                    if (!i)
                        callback();
                };

            srcs.forEach(function(src) {
                var element = document.createElement('script');

                element.src = src;
                element.addEventListener('load', function load() {
                    func();
                    element.removeEventListener('load', load);
                });

                document.body.appendChild(element);
            });
        }

        function ProgressProto(room, spero) {
            var socket;

            if (!(this instanceof ProgressProto))
                return new ProgressProto(room, spero);

            init(room);

            function init(room) {
                var href            = getHost(),
                    FIVE_SECONDS    = 5000;

                socket = io.connect(href + room, {
                    'max reconnection attempts' : Math.pow(2, 32),
                    'reconnection limit'        : FIVE_SECONDS
                });

                socket.on('err', function(error) {
                    spero.emit('error', error);
                });

                socket.on('file', function(name) {
                    spero.emit('file', name);
                });

                socket.on('progress', function(percent) {
                    spero.emit('progress', percent);
                });

                socket.on('end', function() {
                    spero.emit('end');
                });

                socket.on('connect', function() {
                    spero.emit('connect');
                });

                socket.on('disconnect', function() {
                    spero.emit('disconnect');
                });
            }

            this.pause       = function() {
                socket.emit('pause');
            };

            this.continue   = function() {
                socket.emit('continue');
            };

            this.abort       = function() {
                socket.emit('abort');
            };

            this.copy       = function(from, to, files) {
                socket.emit('copy', from, to, files);
            };

            function getHost() {
                var l       = location,
                    href    = l.origin || l.protocol + '//' + l.host;

                return href;
            }
        }

        return load;
    }

})(this);
<|endoftext|>