<commit_before>(function(root) { "use_strict";

// Import
// ========

var _,
    util,
    errors,
    Chronicle,
    ot,
    Data;

if (typeof exports !== 'undefined') {
  _    = require('underscore');
  // Should be require('substance-util') in the future
  util   = require('./lib/util/util');
  errors   = require('./lib/util/errors');
  Chronicle = require('./lib/chronicle/chronicle');
  ot   = require('./lib/chronicle/lib/ot');
  Data = require('./data');

} else {
  _ = root._;
  util = root.Substance.util;
  errors   = root.Substance.errors;
  Chronicle = root.Substance.Chronicle;
  ot = Chronicle.ot;
  Data = root.Substance.Data;
}

var ArrayOperation = ot.ArrayOperation;
var TextOperation = ot.TextOperation;

var ChronicleAdapter = function(graph) {
  this.graph = graph;
  this.state = Chronicle.ROOT;
};

ChronicleAdapter.__prototype__ = function() {

  // Note: there are only "create", "delete", and "update" after conversion
  this.apply = function(change) {
    this.graph.__exec__(change);
  };

  this.invert = function(change) {
    var inverted = util.deepclone(change);

    if (change.op === "create") {
      inverted.op = "delete";
    }
    else if (change.op === "delete") {
      inverted.op = "create";
    }
    else if (change.op === "update") {
      var property = new Data.Graph.Property(this.graph, change.path);
      if (property.type === "string") {
        inverted.args = TextOperation.fromJSON(change.args).invert().toJSON();
      } else if (property.type === "array") {
        inverted.args = ArrayOperation.fromJSON(change.args).invert().toJSON();
      }
    }

    return inverted;
  };

  this.transform = function(a, b, options) {

    var path1 = (a.op === "create") ? a.path.concat([a.args.id]) : a.path;
    var path2 = (b.op === "create") ? b.path.concat([b.args.id]) : b.path;

    // operations on different elements do not need to be transformed
    if (!_.isEqual(path1, path2)) return [a, b];

    // 'create' commands can not be transformed, as an element can only be created once.
    // Note: transform is used to merge other changes into the branch.
    // Merging such a change leads to inconsistencies, e.g., delete before creation or alike.
    // So it is ok and desired to fail in this case.
    if (a.op === "create" || b.op === "create") {
      throw new errors.SubstanceError("'insert' commands can not be transformed");
    }

    // 'update' after 'delete' is turned into a NOP
    if (a.op === "delete" && b.op === "update") {
      return [a, {op: "NOP"}];
    }
    // ... and vice versa
    else if (a.op === "update" && b.op === "delete") {
      return [{op: "NOP"}, b];
    }

    // 'delete'/'delete' are turned into a NOP/NOP
    else if (a.op === "delete" && b.op === "delete") {
      return [{op: "NOP"}, {op: "NOP"}];
    }

    else if (a.op === "update" && b.op === "update") {
      var a_t = {op: "update", path: a.path};
      var b_t = {op: "update", path: b.path};

      var property = new Data.Graph.Property(this.graph, a.path);
      var op1, op2, transformed;

      // String updates

      if (property.type === "string") {
        op1 = TextOperation.fromJSON(a.args);
        op2 = TextOperation.fromJSON(b.args);
        transformed = TextOperation.transform(op1, op2, options);
      }

      // Array updates

      else if (property.type === "array") {
        op1 = ArrayOperation.fromJSON(a.args);
        op2 = ArrayOperation.fromJSON(b.args);
        transformed = ArrayOperation.transform(op1, op2, options);
      }

      a_t.args = transformed[0].toJSON();
      b_t.args = transformed[1].toJSON();

      return [a_t, b_t];

    } else {
      throw new errors.SubstanceError("Illegal state.");
    }

  };

  this.reset = function() {
    this.graph.reset();
  };

};

ChronicleAdapter.__prototype__.prototype = Chronicle.Versioned.prototype;
ChronicleAdapter.prototype = new ChronicleAdapter.__prototype__();

var Converter = function() {

  function create_update(command) {
    var converted = {
      op: "update",
      path: command.path.slice(0),
    };
    return converted;
  }

  // Note: delete commands need to be augmented with the
  // node's data to allow command inversion
  this.delete = function(command, node) {
    return {
      op: "delete",
      path: [],
      args: util.deepclone(node)
    };
  };

  this.pop = function(command, array) {
    if (array.length === 0)  return null;

    var converted = create_update(command);
    var last = _.last(array);
    converted.args = ["-", array.length-1, last];
    return converted;
  };

  this.push = function(command, array) {
    var converted = create_update(command);
    converted.args = ["+", array.length, command.args.value];
    return converted;
  };

  this.insert = function(command, array) {
    var converted = create_update(command);
    converted.args = ["+", array.length, command.args.value];
    return converted;
  };

};

var VersionedGraph = function(schema) {
  Data.Graph.call(this, schema);

  this.chronicle = Chronicle.create();
  this.chronicle.manage(new ChronicleAdapter(this));

};

VersionedGraph.__prototype__ = function() {

  var __super__ = util.prototype(this);
  var converter = new Converter();

  this.exec = function(command) {

    if (!command || command.op === "NOP") return;

    // parse the command to have a normalized representation
    command = new Data.Graph.Command(command);

    // convert the command into a Chroniclible version
    if (converter[command.op]) {
      var item = this.resolve(command.path);
      command = converter[command.op](command, item);
    } else {
      command = command.toJSON();
    }

    // it might happen that the converter returns null as if the command was a NOP
    if (command && command.op !== "NOP") {
      this.__exec__(command);
      this.chronicle.record(util.deepclone(command));
    }
  };

  this.__exec__ = function(command) {
    __super__.exec.call(this, command);
  };

  this.reset = function() {
    __super__.reset.call(this);
    this.chronicle.versioned.state = Chronicle.ROOT;
  };

};

VersionedGraph.__prototype__.prototype = Data.Graph.prototype;
VersionedGraph.prototype = new VersionedGraph.__prototype__();

if (typeof exports === 'undefined') {
  root.Substance.Data.VersionedGraph = VersionedGraph;
} else {
  module.exports = VersionedGraph;
}

})(this);
<commit_msg>Fix regressions.<commit_after>(function(root) { "use_strict";

// Import
// ========

var _,
    util,
    errors,
    Chronicle,
    ot,
    Data;

if (typeof exports !== 'undefined') {
  _    = require('underscore');
  // Should be require('substance-util') in the future
  util   = require('./lib/util/util');
  errors   = require('./lib/util/errors');
  Chronicle = require('./lib/chronicle/chronicle');
  ot   = require('./lib/chronicle/lib/ot');
  Data = require('./data');

} else {
  _ = root._;
  util = root.Substance.util;
  errors   = root.Substance.errors;
  Chronicle = root.Substance.Chronicle;
  ot = Chronicle.ot;
  Data = root.Substance.Data;
}

var ArrayOperation = ot.ArrayOperation;
var TextOperation = ot.TextOperation;

var ChronicleAdapter = function(graph) {
  this.graph = graph;
  this.state = Chronicle.ROOT;
};

ChronicleAdapter.__prototype__ = function() {

  // Note: there are only "create", "delete", and "update" after conversion
  this.apply = function(change) {
    this.graph.__exec__(change);
  };

  this.invert = function(change) {
    var inverted = util.deepclone(change);

    if (change.op === "create") {
      inverted.op = "delete";
    }
    else if (change.op === "delete") {
      inverted.op = "create";
    }
    else if (change.op === "update") {
      var property = this.graph.getProperty(change.path);
      if (property.baseType === "string") {
        inverted.args = TextOperation.fromJSON(change.args).invert().toJSON();
      } else if (property.baseType === "array") {
        inverted.args = ArrayOperation.fromJSON(change.args).invert().toJSON();
      }
    }
    return inverted;
  };

  this.transform = function(a, b, options) {

    var path1 = (a.op === "create") ? a.path.concat([a.args.id]) : a.path;
    var path2 = (b.op === "create") ? b.path.concat([b.args.id]) : b.path;

    // operations on different elements do not need to be transformed
    if (!_.isEqual(path1, path2)) return [a, b];

    // 'create' commands can not be transformed, as an element can only be created once.
    // Note: transform is used to merge other changes into the branch.
    // Merging such a change leads to inconsistencies, e.g., delete before creation or alike.
    // So it is ok and desired to fail in this case.
    if (a.op === "create" || b.op === "create") {
      throw new errors.SubstanceError("'insert' commands can not be transformed");
    }

    // 'update' after 'delete' is turned into a NOP
    if (a.op === "delete" && b.op === "update") {
      return [a, {op: "NOP"}];
    }
    // ... and vice versa
    else if (a.op === "update" && b.op === "delete") {
      return [{op: "NOP"}, b];
    }

    // 'delete'/'delete' are turned into a NOP/NOP
    else if (a.op === "delete" && b.op === "delete") {
      return [{op: "NOP"}, {op: "NOP"}];
    }

    else if (a.op === "update" && b.op === "update") {
      var a_t = {op: "update", path: a.path};
      var b_t = {op: "update", path: b.path};

      var property = new Data.Graph.Property(this.graph, a.path);
      var op1, op2, transformed;

      // String updates

      if (property.type === "string") {
        op1 = TextOperation.fromJSON(a.args);
        op2 = TextOperation.fromJSON(b.args);
        transformed = TextOperation.transform(op1, op2, options);
      }

      // Array updates

      else if (property.type === "array") {
        op1 = ArrayOperation.fromJSON(a.args);
        op2 = ArrayOperation.fromJSON(b.args);
        transformed = ArrayOperation.transform(op1, op2, options);
      }

      a_t.args = transformed[0].toJSON();
      b_t.args = transformed[1].toJSON();

      return [a_t, b_t];

    } else {
      throw new errors.SubstanceError("Illegal state.");
    }

  };

  this.reset = function() {
    this.graph.reset();
  };

};

ChronicleAdapter.__prototype__.prototype = Chronicle.Versioned.prototype;
ChronicleAdapter.prototype = new ChronicleAdapter.__prototype__();

var Converter = function() {

  function create_update(command) {
    var converted = {
      op: "update",
      path: command.path.slice(0),
    };
    return converted;
  }

  // Note: delete commands need to be augmented with the
  // node's data to allow command inversion
  this.delete = function(command, node) {
    return {
      op: "delete",
      path: [],
      args: util.deepclone(node)
    };
  };

  this.pop = function(command, array) {
    if (array.length === 0)  return null;

    var converted = create_update(command);
    var last = _.last(array);
    converted.args = ["-", array.length-1, last];
    return converted;
  };

  this.push = function(command, array) {
    var converted = create_update(command);
    converted.args = ["+", array.length, command.args.value];
    return converted;
  };

  this.insert = function(command, array) {
    var converted = create_update(command);
    converted.args = ["+", array.length, command.args.value];
    return converted;
  };

};

var VersionedGraph = function(schema) {
  Data.Graph.call(this, schema);

  this.chronicle = Chronicle.create();
  this.chronicle.manage(new ChronicleAdapter(this));

};

VersionedGraph.__prototype__ = function() {

  var __super__ = util.prototype(this);
  var converter = new Converter();

  this.exec = function(command) {

    if (!command || command.op === "NOP") return;

    // parse the command to have a normalized representation
    command = new Data.Command(command);

    // convert the command into a Chroniclible version
    if (converter[command.op]) {
      var item = this.resolve(command.path);
      command = converter[command.op](command, item);
    } else {
      command = command.toJSON();
    }

    // it might happen that the converter returns null as if the command was a NOP
    if (command && command.op !== "NOP") {
      this.__exec__(command);
      this.chronicle.record(util.deepclone(command));
    }
  };

  this.__exec__ = function(command) {
    __super__.exec.call(this, command);
  };

  this.reset = function() {
    __super__.reset.call(this);
    this.chronicle.versioned.state = Chronicle.ROOT;
  };

};

VersionedGraph.__prototype__.prototype = Data.Graph.prototype;
VersionedGraph.prototype = new VersionedGraph.__prototype__();

if (typeof exports === 'undefined') {
  root.Substance.Data.VersionedGraph = VersionedGraph;
} else {
  module.exports = VersionedGraph;
}

})(this);
<|endoftext|>


<commit_before>var alphabet = "ОЕАИНТСРВЛКМДПУЯЫЬГЗБЧЙХЖШЮЙЩЭФЪЁ";

function encode(text)
{
    var result = "";

    for (var  i = 0; i < text.length; i++) {
        var n = alphabet.indexOf(text[i].toUpperCase());
        result += "ф";
        for (var j = 0; j < n; j++) {
            result += "ы";
        }
        result += "р";
        if ((i+1) != text.length) result += '-';
    }

    return result.replace(/-фр-/g, " ");
}

function decode(text) {
    text = text.replace(/ф/g, "").replace(/р/g, "");
    var words = text.split(" ");

    var result = "";

    for (var i = 0; i < words.length; i++) {
        var letters = words[i].split("-");

        for (var j = 0; j < letters.length; j++) {
            var n = (letters[j].match(/ы/g) || []).length;
            result += alphabet[n];
        }

        result += " ";
    }

    return result;
}
<commit_msg>improvoe algo<commit_after>var alphabet = "ОЕАИНТСРВЛКМДПУЯЫЬГЗБЧЙХЖШЮЙЩЭФЪЁ";

function encode(text)
{
    var result = "";

    for (var  i = 0; i < text.length; i++) {
        var n = alphabet.indexOf(text[i].toUpperCase());
        result += "ф";
        for (var j = 0; j <= n; j++) {
            result += "ы";
            if (j > 1 && (n - j) % 4 == 0) {
                for (var z = 0; z < (n - j) / 4; z++) {
                    result += "p";
                }
                break;
            }
        }
        result += "р";
        if ((i+1) != text.length) result += '-';
    }

    return result.replace(/-фр-/g, function(space) {
        var random = Math.floor(Math.random() * 10);
        if (random > 6) {
            return " ";
        } else if (random > 4) {
            return " <3 ";
        } else if (random > 2) {
            return " ^^ ";
        } else {
            return " (ᵔᴥᵔ) ";
        }
    });
}

function decode(text) {
    text = text.replace(/ф/g, "")
        .replace(/р/g, "")
        .replace(/p/g, "ыыыы")
        .replace(/\<\3|\^\^|\(\ᵔ\ᴥ\ᵔ\)/g, "");

    var words = text.split(" ");

    var result = "";

    for (var i = 0; i < words.length; i++) {
        var letters = words[i].split("-");

        for (var j = 0; j < letters.length; j++) {
            var n = (letters[j].match(/ы/g) || []).length;
            if (typeof  alphabet[n - 1] != "undefined") result += alphabet[n - 1];
        }

        result += " ";
    }

    return result;
}
<|endoftext|>


<commit_before>function modalEvents(button, modal, page ) {
    switch (button.data('action')) {
        case "new_user":
            modal.find('.modal-title').text('Registrar usuario');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/new', { user_id: button.data('user_id')  }, function(){

            });
            break;
        case "user_profile":
            modal.find('.modal-title').text('Editar información del usuario');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/profile', { user_id: button.data('user_id')  }, function(){
                $('#form_updateprofile').submit(function(event){
                    $.post('/user/update', $(this).serialize()).done(function (data) {
                        alert(data.message);
                        if (data.status=='Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "change_password":
            modal.find('.modal-title').text('Cambiar contraseña');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/change-password', { user_id: button.data('user_id')  }, function(){
                $('#form_updatepassword').submit(function (event) {
                    $.post('/user/update-password', $(this).serialize()).done(function (data) {
                        alert(data.message);
                        if(data.status=='Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "new_item":
            modal.find('.modal-title').text('Registrar artículo');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/item/new', {}, function(){
                $('#itemForm').submit(function(event){
                    $.post('/item/register', $(this).serialize()).done(function (data){
                        alert(data.message);
                        if(data.status == 'Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                })
            });
            break;
        case "edit_item":
            modal.find('.modal-title').text('Editar artículos');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/item/list/',{ page: page }, function(){
                $(this).find('.list-group-item').click(function(){
                    // alert("Funciona, item: "+ $(this).data('item_id'));
                    $("#modal_content").load('/item/edit-item/',{ id: $(this).data('item_id') }, function () {
                        $('#itemForm').submit(function (event) {
                            $.post('/item/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });
                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
        // Editar articulos
        case "edit_user":
            modal.find('.modal-title').text('Editar usuario');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/list/',{ page: page }, function(){
                $(this).find('.list-group-item').click(function(){
                    // alert("Funciona, item: "+ $(this).data('item_id'));
                    $("#modal_content").load('/user/edit-user/',{ id: $(this).data('user_id') }, function () {
                        $('#updateUser').submit(function (event) {
                            $.post('/user/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });
                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
        //stores
        case "new_store":
            modal.find('.modal-title').text('Registrar sucursal');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/store/new', { /* post body data */ }, function(){
                $('#storeForm').submit(function(event){
                    $.post('/store/register', $(this).serialize()).done(function (data){
                        alert(data.message);
                        if(data.status == 'Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "edit_store":
            modal.find('.modal-title').text('Editar sucursal');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/store/list/',{ page: page }, function(){
                $(this).find('.list-group-item').click(function(){
                    $("#modal_content").load('/store/edit-store/', {id: $(this).data('store_id')}, function () {
                        $('#storeForm').submit(function (event) {
                            $.post('/store/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });
                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
        case "new_supplier":
            modal.find('.modal-title').text('Registrar proveedor');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/supplier/new', { /* post body data */ }, function(){
                $('#supplierForm').submit(function(event){
                    $.post('/supplier/register', $(this).serialize()).done(function (data){
                        alert(data.message);
                        if(data.status == 'Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "edit_supplier":
            modal.find('.modal-title').text('Editar proveedor');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/supplier/list/', { page : page } , function(){
                $(this).find('.list-group-item').click(function(){
                    $("#modal_content").load("/supplier/edit-supplier/", {id: $(this).data('supplier_id')}, function(){
                        $('#supplierForm').submit(function (event) {
                            $.post('/supplier/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });

                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
    }
}

$('#genericModal').on('show.bs.modal', function (event) {
    var button = $(event.relatedTarget);
    var modal = $(this);
    var page = 0;
    modalEvents(button, modal, page);
});

<commit_msg>bulck register<commit_after>function modalEvents(button, modal, page ) {
    switch (button.data('action')) {
        case "new_user":
            modal.find('.modal-title').text('Registrar usuario');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/new', { user_id: button.data('user_id')  }, function(){

            });
            break;
        case "user_profile":
            modal.find('.modal-title').text('Editar información del usuario');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/profile', { user_id: button.data('user_id')  }, function(){
                $('#form_updateprofile').submit(function(event){
                    $.post('/user/update', $(this).serialize()).done(function (data) {
                        alert(data.message);
                        if (data.status=='Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "change_password":
            modal.find('.modal-title').text('Cambiar contraseña');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/change-password', { user_id: button.data('user_id')  }, function(){
                $('#form_updatepassword').submit(function (event) {
                    $.post('/user/update-password', $(this).serialize()).done(function (data) {
                        alert(data.message);
                        if(data.status=='Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "new_item":
            modal.find('.modal-title').text('Registrar artículo');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/item/new', {}, function(){
                $('#itemForm').submit(function(event) {
                    var n_articles = $('input[id=nArts]').val();
                    if (confirm("¿Está seguro que quiere registrar " + n_articles + " artículos?")){
                        for(var i = 0; i < n_articles; i++)
                        {
                            $.post('/item/register', $(this).serialize()).done(function (data) {
                                if(i == 0)alert(data.message);
                                if (data.status == 'Ok') {
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        }
                }
                })
            });
            break;
        case "edit_item":
            modal.find('.modal-title').text('Editar artículos');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/item/list/',{ page: page }, function(){
                $(this).find('.list-group-item').click(function(){
                    // alert("Funciona, item: "+ $(this).data('item_id'));
                    $("#modal_content").load('/item/edit-item/',{ id: $(this).data('item_id') }, function () {
                        $('#itemForm').submit(function (event) {
                            $.post('/item/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });
                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
        // Editar articulos
        case "edit_user":
            modal.find('.modal-title').text('Editar usuario');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/user/list/',{ page: page }, function(){
                $(this).find('.list-group-item').click(function(){
                    // alert("Funciona, item: "+ $(this).data('item_id'));
                    $("#modal_content").load('/user/edit-user/',{ id: $(this).data('user_id') }, function () {
                        $('#updateUser').submit(function (event) {
                            $.post('/user/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });
                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
        //stores
        case "new_store":
            modal.find('.modal-title').text('Registrar sucursal');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/store/new', { /* post body data */ }, function(){
                $('#storeForm').submit(function(event){
                    $.post('/store/register', $(this).serialize()).done(function (data){
                        alert(data.message);
                        if(data.status == 'Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "edit_store":
            modal.find('.modal-title').text('Editar sucursal');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/store/list/',{ page: page }, function(){
                $(this).find('.list-group-item').click(function(){
                    $("#modal_content").load('/store/edit-store/', {id: $(this).data('store_id')}, function () {
                        $('#storeForm').submit(function (event) {
                            $.post('/store/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });
                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
        case "new_supplier":
            modal.find('.modal-title').text('Registrar proveedor');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/supplier/new', { /* post body data */ }, function(){
                $('#supplierForm').submit(function(event){
                    $.post('/supplier/register', $(this).serialize()).done(function (data){
                        alert(data.message);
                        if(data.status == 'Ok'){
                            modal.modal('hide');
                        }
                    });
                    event.preventDefault();
                });
            });
            break;
        case "edit_supplier":
            modal.find('.modal-title').text('Editar proveedor');
            modal.find('#modal_content').html("");
            modal.find('#modal_content').load('/supplier/list/', { page : page } , function(){
                $(this).find('.list-group-item').click(function(){
                    $("#modal_content").load("/supplier/edit-supplier/", {id: $(this).data('supplier_id')}, function(){
                        $('#supplierForm').submit(function (event) {
                            $.post('/supplier/update', $(this).serialize()).done(function (data) {
                                alert(data.message);
                                if(data.status=='Ok'){
                                    modal.modal('hide');
                                }
                            });
                            event.preventDefault();
                        });
                    });
                });

                $('.pagination').find('li').click(function () {
                    modalEvents(button, modal, $(this).data('pagenumber'));
                });
            });
            break;
    }
}

$('#genericModal').on('show.bs.modal', function (event) {
    var button = $(event.relatedTarget);
    var modal = $(this);
    var page = 0;
    modalEvents(button, modal, page);
});

<|endoftext|>


<commit_before>/*
	A JavaScript file to fetch and display the new articles, upon loading the page or clicking of the 'play again' button.
*/

var getArticle = function() {
	var xhttp;
	xhttp = new XMLHttpRequest();

	xhttp.open("POST", "http://onionornot.net/assets/php/fetch.php", true);
	xhttp.send();
	mainResponse.text(xhttp.resposeText);
}
<commit_msg>Update fetch.js<commit_after>/*
	A JavaScript file to fetch and display the new articles, upon loading the page or clicking of the 'play again' button.
*/

var getArticle = function() {
	var xhttp;
	xhttp = new XMLHttpRequest();

	xhttp.open("POST", "http://onionornot.net/assets/php/fetch.php", true);
	xhttp.send();
	$('.mainResponse').text(xhttp.resposeText);
}
<|endoftext|>


<commit_before>'use strict';

var Promise = require('bluebird');
var _ = require('underscore');
var util = require('util');

var core = require('kartotherian-core');
var Err = core.Err;

var promistreamus = require('promistreamus');
var iterators = require('./iterators');
var Job = require('./Job');

module.exports = JobProcessor;

/**
 *
 * @param {object} sources
 * @param {Function} sources.loadSourcesAsync
 * @param {Function} sources.getHandlerById
 * @param {object} kueJob Kue job
 * @param {object} kueJob.data job data
 * @param {object} kueJob.progress_data
 * @param {Function} kueJob.log
 * @param {Function} kueJob.progress
 * @param {object} metrics
 * @param {Function} metrics.endTiming
 * @param {Queue} queue
 * @constructor
 */
function JobProcessor(sources, kueJob, metrics, queue) {
    this.sources = sources;
    this.kueJob = kueJob;
    this.metrics = metrics;
    this.queue = queue;
    this.isShuttingDown = false;
    this.minEstimateHrsToBreak = 2;

    var stats = kueJob.progress_data && kueJob.progress_data.index ? kueJob.progress_data : {
        itemsPerSec: 0,
        sizeAvg: 0,
        estimateHrs: -1,
        nosave: 0,
        save: 0,
        tilegen: 0,
        tilegenempty: 0,
        tilegenerr: 0,
        tilegenok: 0,
        tilenodata: 0,
        totalsize: 0,
        smallestSize: undefined,
        smallestTile: undefined,
        largestSize: undefined,
        largestTile: undefined
    };

    this.job = new Job(kueJob.data, stats);
    this.metricsPrefix = util.format('gen.%s.%s.z%s.', this.job.generatorId, this.job.storageId,
        this.job.zoom < 10 ? '0' + this.job.zoom : this.job.zoom);
}

/**
 * Do the job, resolves promise when the job is complete
 * @returns {Promise}
 */
JobProcessor.prototype.runAsync = function() {
    var self = this,
        job = this.job;
    return this.sources.loadSourcesAsync(job.sources).then(function () {
        self.tileGenerator = self.sources.getHandlerById(job.generatorId);
        self.tileStore = self.sources.getHandlerById(job.storageId);
        self.iterator = self.createMainIterator();
        return self.jobProcessorAsync().then(function () {
            return self.reportAndRebalance(true).then(function() {
                // Until progress info is exposed in the UI, do it here too
                self.kueJob.log(JSON.stringify(job.stats, null, '  '));
            });
        });
    });
};

/**
 * Once in a while, report job progress, and attempt to re-balance the job
 * by splitting off its some of it into a new job
 * @param {boolean} isDone
 * @return {Promise}
 */
JobProcessor.prototype.reportAndRebalance = function reportAndRebalance (isDone) {
    let self = this,
        now = new Date();

    // Report if we haven't reported or 15 seconds since last report, or shutting down
    if (!self.isShuttingDown && self.lastProgressReportTime && (now - self.lastProgressReportTime) < 15000) {
        return Promise.resolve();
    }

    let job = self.job,
        stats = job.stats,
        progress, promise;

    if (!isDone) {
        // how long until we are done, in minutes
        progress = job.calculateProgress();
        stats.estimateHrs = stats.itemsPerSec > 0
            ? Math.round((job.size - progress) / stats.itemsPerSec / 60 / 60 * 10) / 10
            : 0;

        // If more than 1 minutes, +/- 3 minutes (random)
        if ((now - (self.lastRebalanceTime || stats.jobStart)) > (1 + Math.random() * 6) * 60 * 1000) {
            self.lastRebalanceTime = now;

            promise = self.queue.getPendingCountAsync().then(function (pendingCount) {

                if (pendingCount < 10 && stats.estimateHrs > self.minEstimateHrsToBreak) {
                    // next time break if the job is half as long, but not less than 5 minutes
                    self.minEstimateHrsToBreak = Math.max(self.minEstimateHrsToBreak / 2, 1 / 12);
                    // Split current job into 2
                    let newJobs = job.splitJob(2);
                    return self.queue.addJobAsync(newJobs);
                } else {
                    // next time break if the job is twice as long, but not more than 2 hours
                    self.minEstimateHrsToBreak = Math.min(self.minEstimateHrsToBreak * 2, 2);
                }
            });
        }
    } else {
        progress = job.size;
        delete stats.estimateHrs;
    }

    return (promise || Promise.resolve()).then(function () {
        self.kueJob.progress(progress, job.size, stats);
        self.lastProgressReportTime = now;
    });
};

/**
 * This iterator will go through all indexes for the current job
 * @returns {Function}
 */
JobProcessor.prototype.createMainIterator = function() {
    var self = this,
        job = this.job;

    return promistreamus.flatten(function() {
        let range = job.moveNextRange();
        if (range){
            return self.getRangeIterator(range[0], range[1], 0);
        }
        return false;
    });
};

JobProcessor.prototype.getRangeIterator = function(idxFrom, idxBefore, filterIndex) {
    var job = this.job;
    if (_.isFunction(this.tileGenerator.query) && (!job.filters || filterIndex >= job.filters.length)) {
        // tile generator source is capable of iterations - we shouldn't generate one by one
        if (!job.filters) {
            job.filters = [];
        }
        job.filters.push({
            sourceId: job.generatorId,
            zoom: job.zoom
        });
    }
    if (job.filters && filterIndex < job.filters.length) {
        return this.getExistingTilesIterator(idxFrom, idxBefore, filterIndex);
    } else {
        return iterators.getSimpleIterator(idxFrom, idxBefore);
    }
};

/**
 * Iterate over existing tiles in a storage
 * @param idxFrom from which index (in the zoom of the main job)
 * @param idxBefore before which index (in the zoom of the main job)
 * @param filterIndex which filter to apply
 * @returns {*}
 */
JobProcessor.prototype.getExistingTilesIterator = function(idxFrom, idxBefore, filterIndex) {

    var self = this,
        job = self.job,
        filter = job.filters[filterIndex],
        scale = filter.zoom !== undefined && filter.zoom !== job.zoom ? Math.pow(4, job.zoom - filter.zoom) : false,
        source = filter.sourceId ? self.sources.getHandlerById(filter.sourceId) : self.tileStore;

    if (!_.isFunction(source.query)) {
        throw new Err('Tile source %s does not support querying', filter.sourceId || job.storageId);
    }
    var getTiles = (filterIndex === job.filters.length - 1 && source === self.tileGenerator && !filter.missing && scale === false);
    var opts = {
        zoom: scale ? filter.zoom : job.zoom,
        idxFrom: scale ? Math.floor(idxFrom / scale) : idxFrom,
        idxBefore: scale ? Math.ceil(idxBefore / scale) : idxBefore,
        getTiles: getTiles
    };

    // If missing is set, invert the meaning of all other filters, and than invert the result

    if (filter.dateBefore !== undefined) {
        if (!filter.missing)
            opts.dateBefore = filter.dateBefore;
        else
            opts.dateFrom = filter.dateBefore;
    }
    if (filter.dateFrom !== undefined) {
        if (!filter.missing)
            opts.dateFrom = filter.dateFrom;
        else
            opts.dateBefore = filter.dateFrom;
    }
    if (filter.biggerThan !== undefined) {
        if (!filter.missing)
            opts.biggerThan = filter.biggerThan;
        else
            opts.smallerThan = filter.biggerThan;
    }
    if (filter.smallerThan !== undefined) {
        if (!filter.missing)
            opts.smallerThan = filter.smallerThan;
        else
            opts.biggerThan = filter.smallerThan;
    }

    var iterator = promistreamus.select(source.query(opts), function (v) {
        var res = {idx: v.idx};
        if (getTiles) {
            res.tile = v.tile;
            res.headers = v.headers;
        }
        return res;
    });

    if (filter.missing) {
        iterator = iterators.invertIterator(iterator, opts.idxFrom, opts.idxBefore);
    }

    if (filterIndex === job.filters.length - 1 && !scale) {
        // last filter and no need for scaling - return as is
        return iterator;
    }

    return promistreamus.flatten(promistreamus.select(
        iterators.sequenceToRangesIterator(iterator),
        function (range) {
            return self.getRangeIterator(
                Math.max(idxFrom, range[0] * (scale || 1)),
                Math.min(idxBefore, range[1] * (scale || 1)),
                filterIndex + 1);
        }));
};

JobProcessor.prototype.jobProcessorAsync = function() {
    var self = this,
        job = self.job,
        stats = job.stats;
    return self.iterator().then(function (iterValue) {
        if (iterValue === undefined || !job.isValidIndex(iterValue.idx)) {
            return;
        }
        // generate tile and repeat
        return self.processOneTileAsync(iterValue).then(function () {
            if (self.isShuttingDown) {
                throw new Err('Shutting down');
            }
            return self.jobProcessorAsync();
        });
    });
};

JobProcessor.prototype.processOneTileAsync = function(iterValue) {
    var start = Date.now(),
        self = this,
        idx = iterValue.idx,
        tile = iterValue.tile,
        job = this.job,
        stats = job.stats,
        xy = core.indexToXY(idx),
        x = xy[0],
        y = xy[1],
        promise;

    // Generate tile or get it from the iterator
    if (!tile) {
        promise = Promise.try(function () {
            stats.tilegen++;
            return self.tileGenerator.getTileAsync(job.zoom, x, y);
        }).then(function (dataAndHeader) {
            self.metrics.endTiming(self.metricsPrefix + 'created', start);
            stats.tilegenok++;
            return dataAndHeader[0];
        }, function (err) {
            if (core.isNoTileError(err)) {
                stats.tilegenempty++;
                return null;
            } else {
                self.metrics.endTiming(self.metricsPrefix + 'generror', start);
                stats.tilegenerr++;
                throw err;
            }
        }).then(function (data) {
            if (!data || !data.length) {
                self.metrics.endTiming(self.metricsPrefix + 'nodata', start);
                stats.tilenodata++;
                return null; // empty tile generated, no need to save
            }
            return data;
        });
    } else {
        promise = Promise.resolve(tile);
    }

    return promise.then(function (data) {
        if (data) {
            self.metrics.endTiming(self.metricsPrefix + 'saving', start);
            stats.save++;
            stats.totalsize += data.length;
            // double negative to treat "undefined" as true
            if (!(stats.smallestSize <= data.length)) {
                stats.smallestSize = data.length;
                stats.smallestTile = idx;
            }
            if (!(stats.largestSize >= data.length)) {
                stats.largestSize = data.length;
                stats.largestTile = idx;
            }
        } else {
            stats.nosave++;
            if (!job.deleteEmpty) {
                return;
            }
        }
        return self.tileStore.putTileAsync(job.zoom, x, y, data);
    }).then(function() {
        self.metrics.endTiming(self.metricsPrefix + 'done', start);
        job.completeIndex(idx);
        return self.reportAndRebalance();
    });
};

JobProcessor.prototype.shutdown = function() {
    this.isShuttingDown = true;
};
<commit_msg>Minor metrics cleanup<commit_after>'use strict';

var Promise = require('bluebird');
var _ = require('underscore');
var util = require('util');

var core = require('kartotherian-core');
var Err = core.Err;

var promistreamus = require('promistreamus');
var iterators = require('./iterators');
var Job = require('./Job');

module.exports = JobProcessor;

/**
 *
 * @param {object} sources
 * @param {Function} sources.loadSourcesAsync
 * @param {Function} sources.getHandlerById
 * @param {object} kueJob Kue job
 * @param {object} kueJob.data job data
 * @param {object} kueJob.progress_data
 * @param {Function} kueJob.log
 * @param {Function} kueJob.progress
 * @param {object} metrics
 * @param {Function} metrics.endTiming
 * @param {Queue} queue
 * @constructor
 */
function JobProcessor(sources, kueJob, metrics, queue) {
    this.sources = sources;
    this.kueJob = kueJob;
    this.metrics = metrics;
    this.queue = queue;
    this.isShuttingDown = false;
    this.minEstimateHrsToBreak = 2;

    var stats = kueJob.progress_data && kueJob.progress_data.index ? kueJob.progress_data : {
        itemsPerSec: 0,
        sizeAvg: 0,
        estimateHrs: -1,
        nosave: 0,
        save: 0,
        tilegen: 0,
        tilegenempty: 0,
        tilegenerr: 0,
        tilegenok: 0,
        tilenodata: 0,
        totalsize: 0,
        smallestSize: undefined,
        smallestTile: undefined,
        largestSize: undefined,
        largestTile: undefined
    };

    this.job = new Job(kueJob.data, stats);

    let metricsPrefix = util.format('gen.%s.%s.z%s.', this.job.generatorId, this.job.storageId,
        this.job.zoom < 10 ? '0' + this.job.zoom : this.job.zoom);

    this.metricsPrefixCreated = metricsPrefix + 'created';
    this.metricsPrefixGenerror = metricsPrefix + 'generror';
    this.metricsPrefixNodata = metricsPrefix + 'nodata';
    this.metricsPrefixSaving = metricsPrefix + 'saving';
    this.metricsPrefixDone = metricsPrefix + 'done';
}

/**
 * Do the job, resolves promise when the job is complete
 * @returns {Promise}
 */
JobProcessor.prototype.runAsync = function() {
    var self = this,
        job = this.job;
    return this.sources.loadSourcesAsync(job.sources).then(function () {
        self.tileGenerator = self.sources.getHandlerById(job.generatorId);
        self.tileStore = self.sources.getHandlerById(job.storageId);
        self.iterator = self.createMainIterator();
        return self.jobProcessorAsync().then(function () {
            return self.reportAndRebalance(true).then(function() {
                // Until progress info is exposed in the UI, do it here too
                self.kueJob.log(JSON.stringify(job.stats, null, '  '));
            });
        });
    });
};

/**
 * Once in a while, report job progress, and attempt to re-balance the job
 * by splitting off its some of it into a new job
 * @param {boolean} isDone
 * @return {Promise}
 */
JobProcessor.prototype.reportAndRebalance = function reportAndRebalance (isDone) {
    let self = this,
        now = new Date();

    // Report if we haven't reported or 15 seconds since last report, or shutting down
    if (!self.isShuttingDown && self.lastProgressReportTime && (now - self.lastProgressReportTime) < 15000) {
        return Promise.resolve();
    }

    let job = self.job,
        stats = job.stats,
        progress, promise;

    if (!isDone) {
        // how long until we are done, in minutes
        progress = job.calculateProgress();
        stats.estimateHrs = stats.itemsPerSec > 0
            ? Math.round((job.size - progress) / stats.itemsPerSec / 60 / 60 * 10) / 10
            : 0;

        // If more than 1 minutes, +/- 3 minutes (random)
        if ((now - (self.lastRebalanceTime || stats.jobStart)) > (1 + Math.random() * 6) * 60 * 1000) {
            self.lastRebalanceTime = now;

            promise = self.queue.getPendingCountAsync().then(function (pendingCount) {

                if (pendingCount < 10 && stats.estimateHrs > self.minEstimateHrsToBreak) {
                    // next time break if the job is half as long, but not less than 5 minutes
                    self.minEstimateHrsToBreak = Math.max(self.minEstimateHrsToBreak / 2, 1 / 12);
                    // Split current job into 2
                    let newJobs = job.splitJob(2);
                    return self.queue.addJobAsync(newJobs);
                } else {
                    // next time break if the job is twice as long, but not more than 2 hours
                    self.minEstimateHrsToBreak = Math.min(self.minEstimateHrsToBreak * 2, 2);
                }
            });
        }
    } else {
        progress = job.size;
        delete stats.estimateHrs;
    }

    return (promise || Promise.resolve()).then(function () {
        self.kueJob.progress(progress, job.size, stats);
        self.lastProgressReportTime = now;
    });
};

/**
 * This iterator will go through all indexes for the current job
 * @returns {Function}
 */
JobProcessor.prototype.createMainIterator = function() {
    var self = this,
        job = this.job;

    return promistreamus.flatten(function() {
        let range = job.moveNextRange();
        if (range){
            return self.getRangeIterator(range[0], range[1], 0);
        }
        return false;
    });
};

JobProcessor.prototype.getRangeIterator = function(idxFrom, idxBefore, filterIndex) {
    var job = this.job;
    if (_.isFunction(this.tileGenerator.query) && (!job.filters || filterIndex >= job.filters.length)) {
        // tile generator source is capable of iterations - we shouldn't generate one by one
        if (!job.filters) {
            job.filters = [];
        }
        job.filters.push({
            sourceId: job.generatorId,
            zoom: job.zoom
        });
    }
    if (job.filters && filterIndex < job.filters.length) {
        return this.getExistingTilesIterator(idxFrom, idxBefore, filterIndex);
    } else {
        return iterators.getSimpleIterator(idxFrom, idxBefore);
    }
};

/**
 * Iterate over existing tiles in a storage
 * @param idxFrom from which index (in the zoom of the main job)
 * @param idxBefore before which index (in the zoom of the main job)
 * @param filterIndex which filter to apply
 * @returns {*}
 */
JobProcessor.prototype.getExistingTilesIterator = function(idxFrom, idxBefore, filterIndex) {

    var self = this,
        job = self.job,
        filter = job.filters[filterIndex],
        scale = filter.zoom !== undefined && filter.zoom !== job.zoom ? Math.pow(4, job.zoom - filter.zoom) : false,
        source = filter.sourceId ? self.sources.getHandlerById(filter.sourceId) : self.tileStore;

    if (!_.isFunction(source.query)) {
        throw new Err('Tile source %s does not support querying', filter.sourceId || job.storageId);
    }
    var getTiles = (filterIndex === job.filters.length - 1 && source === self.tileGenerator && !filter.missing && scale === false);
    var opts = {
        zoom: scale ? filter.zoom : job.zoom,
        idxFrom: scale ? Math.floor(idxFrom / scale) : idxFrom,
        idxBefore: scale ? Math.ceil(idxBefore / scale) : idxBefore,
        getTiles: getTiles
    };

    // If missing is set, invert the meaning of all other filters, and than invert the result

    if (filter.dateBefore !== undefined) {
        if (!filter.missing)
            opts.dateBefore = filter.dateBefore;
        else
            opts.dateFrom = filter.dateBefore;
    }
    if (filter.dateFrom !== undefined) {
        if (!filter.missing)
            opts.dateFrom = filter.dateFrom;
        else
            opts.dateBefore = filter.dateFrom;
    }
    if (filter.biggerThan !== undefined) {
        if (!filter.missing)
            opts.biggerThan = filter.biggerThan;
        else
            opts.smallerThan = filter.biggerThan;
    }
    if (filter.smallerThan !== undefined) {
        if (!filter.missing)
            opts.smallerThan = filter.smallerThan;
        else
            opts.biggerThan = filter.smallerThan;
    }

    var iterator = promistreamus.select(source.query(opts), function (v) {
        var res = {idx: v.idx};
        if (getTiles) {
            res.tile = v.tile;
            res.headers = v.headers;
        }
        return res;
    });

    if (filter.missing) {
        iterator = iterators.invertIterator(iterator, opts.idxFrom, opts.idxBefore);
    }

    if (filterIndex === job.filters.length - 1 && !scale) {
        // last filter and no need for scaling - return as is
        return iterator;
    }

    return promistreamus.flatten(promistreamus.select(
        iterators.sequenceToRangesIterator(iterator),
        function (range) {
            return self.getRangeIterator(
                Math.max(idxFrom, range[0] * (scale || 1)),
                Math.min(idxBefore, range[1] * (scale || 1)),
                filterIndex + 1);
        }));
};

JobProcessor.prototype.jobProcessorAsync = function() {
    var self = this,
        job = self.job;
    return self.iterator().then(function (iterValue) {
        if (iterValue === undefined || !job.isValidIndex(iterValue.idx)) {
            return;
        }
        // generate tile and repeat
        return self.processOneTileAsync(iterValue).then(function () {
            if (self.isShuttingDown) {
                throw new Err('Shutting down');
            }
            return self.jobProcessorAsync();
        });
    });
};

JobProcessor.prototype.processOneTileAsync = function(iterValue) {
    var start = Date.now(),
        self = this,
        idx = iterValue.idx,
        tile = iterValue.tile,
        job = this.job,
        stats = job.stats,
        xy = core.indexToXY(idx),
        x = xy[0],
        y = xy[1],
        promise;

    // Generate tile or get it from the iterator
    if (!tile) {
        promise = Promise.try(function () {
            stats.tilegen++;
            return self.tileGenerator.getTileAsync(job.zoom, x, y);
        }).then(function (dataAndHeader) {
            self.metrics.endTiming(self.metricsPrefixCreated, start);
            stats.tilegenok++;
            return dataAndHeader[0];
        }, function (err) {
            if (core.isNoTileError(err)) {
                stats.tilegenempty++;
                return null;
            } else {
                self.metrics.endTiming(self.metricsPrefixGenerror, start);
                stats.tilegenerr++;
                throw err;
            }
        }).then(function (data) {
            if (!data || !data.length) {
                self.metrics.endTiming(self.metricsPrefixNodata, start);
                stats.tilenodata++;
                return null; // empty tile generated, no need to save
            }
            return data;
        });
    } else {
        promise = Promise.resolve(tile);
    }

    return promise.then(function (data) {
        if (data) {
            self.metrics.endTiming(self.metricsPrefixSaving, start);
            stats.save++;
            stats.totalsize += data.length;
            // double negative to treat "undefined" as true
            if (!(stats.smallestSize <= data.length)) {
                stats.smallestSize = data.length;
                stats.smallestTile = idx;
            }
            if (!(stats.largestSize >= data.length)) {
                stats.largestSize = data.length;
                stats.largestTile = idx;
            }
        } else {
            stats.nosave++;
            if (!job.deleteEmpty) {
                return;
            }
        }
        return self.tileStore.putTileAsync(job.zoom, x, y, data);
    }).then(function() {
        self.metrics.endTiming(self.metricsPrefixDone, start);
        job.completeIndex(idx);
        return self.reportAndRebalance();
    });
};

JobProcessor.prototype.shutdown = function() {
    this.isShuttingDown = true;
};
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var Module = require("./Module");
var NormalModuleMixin = require("webpack-core/lib/NormalModuleMixin");
var SourceMapSource = require("webpack-core/lib/SourceMapSource");
var OriginalSource = require("webpack-core/lib/OriginalSource");
var RawSource = require("webpack-core/lib/RawSource");
var ReplaceSource = require("webpack-core/lib/ReplaceSource");
var ModuleParseError = require("./ModuleParseError");
var TemplateArgumentDependency = require("./dependencies/TemplateArgumentDependency");
var path = require("path");

function NormalModule(request, userRequest, rawRequest, loaders, resource, parser) {
	Module.call(this);
	this.request = request;
	this.userRequest = userRequest;
	this.rawRequest = rawRequest;
	this.parser = parser;
	NormalModuleMixin.call(this, loaders, resource);
	this.meta = {};
	this.assets = {};
	this.built = false;
}
module.exports = NormalModule;

NormalModule.prototype = Object.create(Module.prototype);
NormalModuleMixin.mixin(NormalModule.prototype);

NormalModule.prototype.identifier = function() {
	return this.request;
};

NormalModule.prototype.readableIdentifier = function(requestShortener) {
	return requestShortener.shorten(this.userRequest);
};

NormalModule.prototype.fillLoaderContext = function fillLoaderContext(loaderContext, options, compilation) {
	loaderContext.webpack = true;
	loaderContext.emitFile = function(name, content, sourceMap) {
		if(typeof sourceMap === "string") {
			this.assets[name] = new OriginalSource(content, sourceMap);
		} else if(sourceMap) {
			this.assets[name] = new SourceMapSource(content, name, sourceMap);
		} else {
			this.assets[name] = new RawSource(content);
		}
	}.bind(this);
	loaderContext._module = this;
	loaderContext._compilation = compilation;
	loaderContext._compiler = compilation.compiler;
	compilation.applyPlugins("normal-module-loader", loaderContext, this);
};

NormalModule.prototype.disconnect = function disconnect() {
	this.built = false;
	Module.prototype.disconnect.call(this);
};

NormalModule.prototype.build = function build(options, compilation, resolver, fs, callback) {
	this.buildTimestamp = new Date().getTime();
	this.built = true;
	return this.doBuild(options, compilation, resolver, fs, function(err) {
		if(err) return callback(err);
		this.dependencies.length = 0;
		this.variables.length = 0;
		this.blocks.length = 0;
		if(options.module && options.module.noParse) {
			if(Array.isArray(options.module.noParse)) {
				if(options.module.noParse.some(function(regExp) {
					return typeof regExp === "string" ?
						this.request.indexOf(regExp) === 0 :
						regExp.test(this.request);
				}, this)) return callback();
			} else if(typeof regExp === "string" ?
					this.request.indexOf(options.module.noParse) === 0 :
					options.module.noParse.test(this.request)) {
				return callback();
			}
		}
		try {
			this.parser.parse(this._source.source(), {
				current: this,
				module: this,
				compilation: compilation,
				options: options
			});
		} catch(e) {
			var source = this._source.source();
			this._source = null;
			return callback(new ModuleParseError(this, source, e));
		}
		return callback();
	}.bind(this));
};

NormalModule.prototype.source = function(dependencyTemplates, outputOptions, requestShortener) {
	var _source = this._source;
	if(!_source) return new RawSource("throw new Error('No source availible');");
	var source = new ReplaceSource(_source);
	var topLevelBlock = this;
	function doDep(dep) {
		var template = dependencyTemplates.get(dep.Class);
		if(!template) throw new Error("No template for dependency: " + dep.Class.name);
		template.apply(dep, source, outputOptions, requestShortener, dependencyTemplates);
	}
	function doVariable(vars, variable) {
		var name = variable.name;
		var expr = variable.expressionSource(dependencyTemplates, outputOptions, requestShortener);
		vars.push({name: name, expression: expr});
	}
	function doBlock(block) {
		block.dependencies.forEach(doDep);
		block.blocks.forEach(doBlock);
		if(block.variables.length > 0) {
			var vars = [];
			block.variables.forEach(doVariable.bind(null, vars));
			var varNames = [];
			var varExpressions = [];
			var varStartCode = "";
			var varEndCode = "";
			function emitFunction() {
				if(varNames.length == 0) return;

				varStartCode += "/* WEBPACK VAR INJECTION */(function(require, " + varNames.join(", ") + ") {";
				// exports === this in the topLevelBlock, but exports do compress better...
				varEndCode = (topLevelBlock === block ? "}.call(exports, require, " : "}.call(this, require, ") +
					varExpressions.map(function(e) {return e.source()}).join(", ") + "))" + varEndCode;

				varNames.length = 0;
				varExpressions.length = 0;
			}
			vars.forEach(function(v) {
				if(varNames.indexOf(v.name) >= 0) emitFunction();
				varNames.push(v.name);
				varExpressions.push(v.expression);
			});
			emitFunction();
			var start = block.range ? block.range[0] : 0;
			var end = block.range ? block.range[1] : _source.size();
			if(varStartCode) source.insert(start + 0.5, varStartCode);
			if(varEndCode) source.insert(end + 0.5, "\n/* WEBPACK VAR INJECTION */" + varEndCode);
		}
	}
	doBlock(this);
	return source;
};

NormalModule.prototype.needRebuild = function needRebuild(fileTimestamps, contextTimestamps) {
	var timestamp = 0;
	this.fileDependencies.forEach(function(file) {
		var ts = fileTimestamps[file];
		if(!ts) timestamp = Infinity;
		if(ts > timestamp) timestamp = ts;
	});
	this.contextDependencies.forEach(function(context) {
		var ts = contextTimestamps[context];
		if(!ts) timestamp = Infinity;
		if(ts > timestamp) timestamp = ts;
	});
	return timestamp >= this.buildTimestamp;
};

NormalModule.prototype.size = function() {
	return this._source ? this._source.size() : -1;
};

NormalModule.prototype.updateHash = function(hash) {
	if(this._source) {
		hash.update("source");
		this._source.updateHash(hash);
	} else
		hash.update("null");
	Module.prototype.updateHash.call(this, hash);
};

NormalModule.prototype.getSourceHash = function() {
	if(!this._source) return "";
	var hash = require("crypto").createHash("md5");
	hash.update(this._source.source());
	return hash.digest("hex");
};

NormalModule.prototype.getAllModuleDependencies = function() {
	var list = [];
	function doDep(dep) {
		if(dep.module && list.indexOf(dep.module) < 0)
			list.push(dep.module);
	}
	function doVariable(variable) {
		variable.dependencies.forEach(doDep);
	}
	function doBlock(block) {
		block.variables.forEach(doVariable);
		block.dependencies.forEach(doDep);
		block.blocks.forEach(doBlock);
	}
	doBlock(this);
	return list;
};

NormalModule.prototype.createTemplate = function(keepModules) {
	var template = new NormalModule("", "", "", [], "", null);
	template._source = this._source;
	template.built = this.built;
	template.templateModules = keepModules;
	template._templateOrigin = this;
	template.readableIdentifier = function() {
		return "template of " + this._templateOrigin.id + " referencing " + keepModules.map(function(m) {
			return m.id;
		}).join(", ");
	};
	var args = template.arguments = [];
	function doDeps(deps) {
		return deps.map(function(dep) {
			if(dep.module && keepModules.indexOf(dep.module) < 0) {
				var argName = "__webpack_module_template_argument_" + args.length + "__";
				args.push(argName);
				return new TemplateArgumentDependency(argName, dep);
			} else {
				return dep;
			}
		});
	}
	function doVariable(variable, newVariable) {
		variable.dependencies.forEach(doDep);
	}
	function doBlock(block, newBlock) {
		block.variables.forEach(function(variable) {
			var newDependencies = doDeps(variable.dependencies);
			newBlock.addVariable(variable.name, variable.expression, newDependencies);
		});
		newBlock.dependencies = doDeps(block.dependencies);
		block.blocks.forEach(function(childBlock) {
			var newChildBlock = new AsyncDependenciesBlock(childBlock.name, childBlock.module, childBlock.loc);
			newBlock.addBlock(newChildBlock);
			doBlock(childBlock, newChildBlock);
		});
	}
	doBlock(this, template);
	return template;
};

NormalModule.prototype.getTemplateArguments = function(keepModules) {
	var list = [];
	function doDep(dep) {
		if(dep.module && keepModules.indexOf(dep.module) < 0)
			list.push(dep.module);
	}
	function doVariable(variable) {
		variable.dependencies.forEach(doDep);
	}
	function doBlock(block) {
		block.variables.forEach(doVariable);
		block.dependencies.forEach(doDep);
		block.blocks.forEach(doBlock);
	}
	doBlock(this);
	return list;
};
<commit_msg>cache the replaced source for performance<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var Module = require("./Module");
var NormalModuleMixin = require("webpack-core/lib/NormalModuleMixin");
var SourceMapSource = require("webpack-core/lib/SourceMapSource");
var OriginalSource = require("webpack-core/lib/OriginalSource");
var RawSource = require("webpack-core/lib/RawSource");
var ReplaceSource = require("webpack-core/lib/ReplaceSource");
var ModuleParseError = require("./ModuleParseError");
var TemplateArgumentDependency = require("./dependencies/TemplateArgumentDependency");
var path = require("path");

function NormalModule(request, userRequest, rawRequest, loaders, resource, parser) {
	Module.call(this);
	this.request = request;
	this.userRequest = userRequest;
	this.rawRequest = rawRequest;
	this.parser = parser;
	NormalModuleMixin.call(this, loaders, resource);
	this.meta = {};
	this.assets = {};
	this.built = false;
}
module.exports = NormalModule;

NormalModule.prototype = Object.create(Module.prototype);
NormalModuleMixin.mixin(NormalModule.prototype);

NormalModule.prototype.identifier = function() {
	return this.request;
};

NormalModule.prototype.readableIdentifier = function(requestShortener) {
	return requestShortener.shorten(this.userRequest);
};

NormalModule.prototype.fillLoaderContext = function fillLoaderContext(loaderContext, options, compilation) {
	loaderContext.webpack = true;
	loaderContext.emitFile = function(name, content, sourceMap) {
		if(typeof sourceMap === "string") {
			this.assets[name] = new OriginalSource(content, sourceMap);
		} else if(sourceMap) {
			this.assets[name] = new SourceMapSource(content, name, sourceMap);
		} else {
			this.assets[name] = new RawSource(content);
		}
	}.bind(this);
	loaderContext._module = this;
	loaderContext._compilation = compilation;
	loaderContext._compiler = compilation.compiler;
	compilation.applyPlugins("normal-module-loader", loaderContext, this);
};

NormalModule.prototype.disconnect = function disconnect() {
	this.built = false;
	Module.prototype.disconnect.call(this);
};

NormalModule.prototype.build = function build(options, compilation, resolver, fs, callback) {
	this.buildTimestamp = new Date().getTime();
	this.built = true;
	return this.doBuild(options, compilation, resolver, fs, function(err) {
		if(err) return callback(err);
		this.dependencies.length = 0;
		this.variables.length = 0;
		this.blocks.length = 0;
		this._cachedSource = null;
		if(options.module && options.module.noParse) {
			if(Array.isArray(options.module.noParse)) {
				if(options.module.noParse.some(function(regExp) {
					return typeof regExp === "string" ?
						this.request.indexOf(regExp) === 0 :
						regExp.test(this.request);
				}, this)) return callback();
			} else if(typeof regExp === "string" ?
					this.request.indexOf(options.module.noParse) === 0 :
					options.module.noParse.test(this.request)) {
				return callback();
			}
		}
		try {
			this.parser.parse(this._source.source(), {
				current: this,
				module: this,
				compilation: compilation,
				options: options
			});
		} catch(e) {
			var source = this._source.source();
			this._source = null;
			return callback(new ModuleParseError(this, source, e));
		}
		return callback();
	}.bind(this));
};

NormalModule.prototype.source = function(dependencyTemplates, outputOptions, requestShortener) {
	if(this._cachedSource) return this._cachedSource;
	var _source = this._source;
	if(!_source) return new RawSource("throw new Error('No source availible');");
	var source = this._cachedSource = new ReplaceSource(_source);
	var topLevelBlock = this;
	function doDep(dep) {
		var template = dependencyTemplates.get(dep.Class);
		if(!template) throw new Error("No template for dependency: " + dep.Class.name);
		template.apply(dep, source, outputOptions, requestShortener, dependencyTemplates);
	}
	function doVariable(vars, variable) {
		var name = variable.name;
		var expr = variable.expressionSource(dependencyTemplates, outputOptions, requestShortener);
		vars.push({name: name, expression: expr});
	}
	function doBlock(block) {
		block.dependencies.forEach(doDep);
		block.blocks.forEach(doBlock);
		if(block.variables.length > 0) {
			var vars = [];
			block.variables.forEach(doVariable.bind(null, vars));
			var varNames = [];
			var varExpressions = [];
			var varStartCode = "";
			var varEndCode = "";
			function emitFunction() {
				if(varNames.length == 0) return;

				varStartCode += "/* WEBPACK VAR INJECTION */(function(require, " + varNames.join(", ") + ") {";
				// exports === this in the topLevelBlock, but exports do compress better...
				varEndCode = (topLevelBlock === block ? "}.call(exports, require, " : "}.call(this, require, ") +
					varExpressions.map(function(e) {return e.source()}).join(", ") + "))" + varEndCode;

				varNames.length = 0;
				varExpressions.length = 0;
			}
			vars.forEach(function(v) {
				if(varNames.indexOf(v.name) >= 0) emitFunction();
				varNames.push(v.name);
				varExpressions.push(v.expression);
			});
			emitFunction();
			var start = block.range ? block.range[0] : 0;
			var end = block.range ? block.range[1] : _source.size();
			if(varStartCode) source.insert(start + 0.5, varStartCode);
			if(varEndCode) source.insert(end + 0.5, "\n/* WEBPACK VAR INJECTION */" + varEndCode);
		}
	}
	doBlock(this);
	return source;
};

NormalModule.prototype.needRebuild = function needRebuild(fileTimestamps, contextTimestamps) {
	var timestamp = 0;
	this.fileDependencies.forEach(function(file) {
		var ts = fileTimestamps[file];
		if(!ts) timestamp = Infinity;
		if(ts > timestamp) timestamp = ts;
	});
	this.contextDependencies.forEach(function(context) {
		var ts = contextTimestamps[context];
		if(!ts) timestamp = Infinity;
		if(ts > timestamp) timestamp = ts;
	});
	return timestamp >= this.buildTimestamp;
};

NormalModule.prototype.size = function() {
	return this._source ? this._source.size() : -1;
};

NormalModule.prototype.updateHash = function(hash) {
	if(this._source) {
		hash.update("source");
		this._source.updateHash(hash);
	} else
		hash.update("null");
	Module.prototype.updateHash.call(this, hash);
};

NormalModule.prototype.getSourceHash = function() {
	if(!this._source) return "";
	var hash = require("crypto").createHash("md5");
	hash.update(this._source.source());
	return hash.digest("hex");
};

NormalModule.prototype.getAllModuleDependencies = function() {
	var list = [];
	function doDep(dep) {
		if(dep.module && list.indexOf(dep.module) < 0)
			list.push(dep.module);
	}
	function doVariable(variable) {
		variable.dependencies.forEach(doDep);
	}
	function doBlock(block) {
		block.variables.forEach(doVariable);
		block.dependencies.forEach(doDep);
		block.blocks.forEach(doBlock);
	}
	doBlock(this);
	return list;
};

NormalModule.prototype.createTemplate = function(keepModules) {
	var template = new NormalModule("", "", "", [], "", null);
	template._source = this._source;
	template.built = this.built;
	template.templateModules = keepModules;
	template._templateOrigin = this;
	template.readableIdentifier = function() {
		return "template of " + this._templateOrigin.id + " referencing " + keepModules.map(function(m) {
			return m.id;
		}).join(", ");
	};
	var args = template.arguments = [];
	function doDeps(deps) {
		return deps.map(function(dep) {
			if(dep.module && keepModules.indexOf(dep.module) < 0) {
				var argName = "__webpack_module_template_argument_" + args.length + "__";
				args.push(argName);
				return new TemplateArgumentDependency(argName, dep);
			} else {
				return dep;
			}
		});
	}
	function doVariable(variable, newVariable) {
		variable.dependencies.forEach(doDep);
	}
	function doBlock(block, newBlock) {
		block.variables.forEach(function(variable) {
			var newDependencies = doDeps(variable.dependencies);
			newBlock.addVariable(variable.name, variable.expression, newDependencies);
		});
		newBlock.dependencies = doDeps(block.dependencies);
		block.blocks.forEach(function(childBlock) {
			var newChildBlock = new AsyncDependenciesBlock(childBlock.name, childBlock.module, childBlock.loc);
			newBlock.addBlock(newChildBlock);
			doBlock(childBlock, newChildBlock);
		});
	}
	doBlock(this, template);
	return template;
};

NormalModule.prototype.getTemplateArguments = function(keepModules) {
	var list = [];
	function doDep(dep) {
		if(dep.module && keepModules.indexOf(dep.module) < 0)
			list.push(dep.module);
	}
	function doVariable(variable) {
		variable.dependencies.forEach(doDep);
	}
	function doBlock(block) {
		block.variables.forEach(doVariable);
		block.dependencies.forEach(doDep);
		block.blocks.forEach(doBlock);
	}
	doBlock(this);
	return list;
};
<|endoftext|>


<commit_before>
define (['jquery', 'facebook', 'analyze'], function ($, facebook, Analyze) {

    FB.init({
        appId      : '1468034890110746',
        xfbml      : true,
        status     : true,
        cookie     : true,
        version    : 'v2.2'
    });

    function checkLoginState() {
        FB.getLoginStatus(function (response) { statusChangeCallback(response); });
    }

    function statusChangeCallback(response) {
          if (response.status === 'connected') {
              $.get('/analyze', function (res) {
                    Analyze.startAnalyzing();
              });
          } else if (response.status === 'not_authorized') {
             FB.login(function(response) { statusChangeCallback(response); }, {scope: 'user_likes'});
          } else {
             alert("Please login.");
          }
    }

    function onStartClick () {
        checkLoginState();

        // Hide logo
        $('#logo').animate({
            opacity:0,
            height:0,
            width:0
        },{
            duration: 1000,
            complete: function () {
                $('#logo').hide();
            }
        });

        // Hide button
        $('#start').animate({
            opacity:0
        },{
            duration: 1000,
            complete: function () {
                $('#start').hide();
                $('#loading').removeClass('hidden');
            }
        });

    }
    function inviteFriends () {
        // Use FB.ui to send the Request(s)
        FB.ui({method: 'apprequests',
            title: 'Deberías probar esta app',
            message: '\Check out this Awesome App!'
        }, function (){});
   }

   function loadLikesChart () {
            google.load('visualization', '1', {packages: ['corechart', 'bar']});
            google.setOnLoadCallback(function () {
                  var data = google.visualization.arrayToDataTable([
                    ['City', '2010 Population'],
                    ['New York City, NY', 8175000],
                    ['Los Angeles, CA', 3792000],
                    ['Chicago, IL', 2695000],
                  ]);

                  var options = {
                    title: 'Population of Largest U.S. Cities',
                    chartArea: {width: '50%'},
                    hAxis: {
                      title: 'Total Population',
                      minValue: 0
                    },
                    vAxis: {
                      title: 'City'
                    },
                      animation: {
                          easing: 'out',
                          delay: 1000,
                          startup: true
                     }
                  };

                  var chart = new google.visualization.BarChart(document.getElementById('likesChart'));
                  chart.draw(data, options);
                }
            );
     }

    // Attach callbacks
    $(document).ready(function () {
        $('#start').click(onStartClick);
        $('#invite').click(inviteFriends);
        loadLikesChart();
    });

});<commit_msg>Likes chart 4<commit_after>
define (['jquery', 'facebook', 'analyze'], function ($, facebook, Analyze) {

    FB.init({
        appId      : '1468034890110746',
        xfbml      : true,
        status     : true,
        cookie     : true,
        version    : 'v2.2'
    });

    function checkLoginState() {
        FB.getLoginStatus(function (response) { statusChangeCallback(response); });
    }

    function statusChangeCallback(response) {
          if (response.status === 'connected') {
              $.get('/analyze', function (res) {
                    Analyze.startAnalyzing();
              });
          } else if (response.status === 'not_authorized') {
             FB.login(function(response) { statusChangeCallback(response); }, {scope: 'user_likes'});
          } else {
             alert("Please login.");
          }
    }

    function onStartClick () {
        checkLoginState();

        // Hide logo
        $('#logo').animate({
            opacity:0,
            height:0,
            width:0
        },{
            duration: 1000,
            complete: function () {
                $('#logo').hide();
            }
        });

        // Hide button
        $('#start').animate({
            opacity:0
        },{
            duration: 1000,
            complete: function () {
                $('#start').hide();
                $('#loading').removeClass('hidden');
            }
        });

    }
    function inviteFriends () {
        // Use FB.ui to send the Request(s)
        FB.ui({method: 'apprequests',
            title: 'Deberías probar esta app',
            message: '\Check out this Awesome App!'
        }, function (){});
   }

   function loadLikesChart () {
            google.load('visualization', '1', {packages: ['corechart', 'bar']});
            google.setOnLoadCallback(function () {
                  var data = google.visualization.arrayToDataTable([
                    ['City', '2010 Population'],
                    ['New York City, NY', 8175000],
                    ['Los Angeles, CA', 3792000],
                    ['Chicago, IL', 2695000]
                  ]);

                  var options = {
                    title: 'Population of Largest U.S. Cities',
                    chartArea: {width: '50%'},
                    hAxis: {
                      title: 'Total Population',
                      minValue: 0
                    },
                    vAxis: {
                      title: 'City'
                    },
                      animation: {
                          easing: 'out',
                          delay: 1000,
                          startup: true
                     }
                  };

                  var chart = new google.visualization.BarChart(document.getElementById('likesChart'));
                  chart.draw(data, options);
                }
            );
     }

    // Attach callbacks
    $(document).ready(function () {
        $('#start').click(onStartClick);
        $('#invite').click(inviteFriends);
        loadLikesChart();
    });

});<|endoftext|>


<commit_before>var Q = require('q');
var _ = require('underscore');

var self;

function ObjectMapper() {
    self = this;

    // Predefine empty mappings object
    self.mappings = {};
}

function processTypes(typesObject) {
    if (typeof(typesObject) !== 'object') throw new Error('Mappings configuration has to be an object');

    var newMappings = {};
    for (var typeName in typesObject) {
        if (typeof(typesObject[typeName]) === 'string') {
            // Apply defaults to types which just point on their target
            newMappings[typeName] = {
                path: typesObject[typeName],
                strictTypes: false
            };
        } else {
            newMappings[typeName] = typesObject[typeName];
        }
    }

    return newMappings;
}

function checkType(value, type) {
    switch(type) {
        case 'number': return !isNaN(value);
        case 'string': return _.isString(value);
        case 'boolean': return _.isBoolean(value);
        case 'function': return _.isFunction(value);
        case 'object': return _.isObject(value) || _.isArray(value);
        default: return false;
    }
}

ObjectMapper.prototype.config = function(options) {
    if (!options) throw new Error('No options provided');

    // Path given, try to require
    if (typeof(options.mappings) === 'string') {
        self.mappings = processTypes(require(options.mappings));
    // Configuration object given
    } else if (typeof(options.mappings) === 'object') {
        self.mappings = processTypes(options.mappings);
    }
};

ObjectMapper.prototype.map = function(options) {
    var deferred = Q.defer();

    if (!self.mappings[options.objectType]) {
        deferred.reject(new Error('Unknown object type given: ' + options.objectType));
    }

    // Instantitiate object for type
    var classObject = require(process.cwd() + '/' + self.mappings[options.objectType].path);
    var object      = new classObject();

    var fields = options.requestData.query;
    for (var fieldName in fields) {
        // Only assign
        if (_.isUndefined(object[fieldName]) === false) {
            // Check strict mode
            if (checkType(fields[fieldName], typeof(object[fieldName])) !== true) {
                var errMsg = 'Type missmatch for parameter "' + fieldName + '"! Expected: [' + typeof(object[fieldName]) + '] Given: [' + typeof(fields[fieldName]) + ']';
                deferred.reject(new Error(errMsg));
            }

            object[fieldName] = fields[fieldName];
        }
    }

    // We're done!
    deferred.resolve(object);

    return deferred.promise;
};

ObjectMapper.prototype.middleware = function(req, res, next) {
    if (req.query.objectType) {
        var objectType = req.query.objectType;

        // Build and map new data object based on given data
        self.map({
            objectType: objectType,
            requestData: req
        }).then(function(mappedObject){
            // Create dataObjects array if not existing
            if (!req.dataObjects) {
                req.dataObjects = {};
            }

            // Store mapped object in request data
            req.dataObjects[objectType] = mappedObject;
        }, function(error){
            console.error(error);
        });
    }

    // In any case move to next middleware
    next();
};

module.exports = ObjectMapper;
<commit_msg>We can move to next() after mapping is done<commit_after>var Q = require('q');
var _ = require('underscore');

var self;

function ObjectMapper() {
    self = this;

    // Predefine empty mappings object
    self.mappings = {};
}

function processTypes(typesObject) {
    if (typeof(typesObject) !== 'object') throw new Error('Mappings configuration has to be an object');

    var newMappings = {};
    for (var typeName in typesObject) {
        if (typeof(typesObject[typeName]) === 'string') {
            // Apply defaults to types which just point on their target
            newMappings[typeName] = {
                path: typesObject[typeName],
                strictTypes: false
            };
        } else {
            newMappings[typeName] = typesObject[typeName];
        }
    }

    return newMappings;
}

function checkType(value, type) {
    switch(type) {
        case 'number': return !isNaN(value);
        case 'string': return _.isString(value);
        case 'boolean': return _.isBoolean(value);
        case 'function': return _.isFunction(value);
        case 'object': return _.isObject(value) || _.isArray(value);
        default: return false;
    }
}

ObjectMapper.prototype.config = function(options) {
    if (!options) throw new Error('No options provided');

    // Path given, try to require
    if (typeof(options.mappings) === 'string') {
        self.mappings = processTypes(require(options.mappings));
    // Configuration object given
    } else if (typeof(options.mappings) === 'object') {
        self.mappings = processTypes(options.mappings);
    }
};

ObjectMapper.prototype.map = function(options) {
    var deferred = Q.defer();

    if (!self.mappings[options.objectType]) {
        deferred.reject(new Error('Unknown object type given: ' + options.objectType));
    }

    // Instantitiate object for type
    var classObject = require(process.cwd() + '/' + self.mappings[options.objectType].path);
    var object      = new classObject();

    var fields = options.requestData.query;
    for (var fieldName in fields) {
        // Only assign
        if (_.isUndefined(object[fieldName]) === false) {
            // Check strict mode
            if (checkType(fields[fieldName], typeof(object[fieldName])) !== true) {
                var errMsg = 'Type missmatch for parameter "' + fieldName + '"! Expected: [' + typeof(object[fieldName]) + '] Given: [' + typeof(fields[fieldName]) + ']';
                deferred.reject(new Error(errMsg));
            }

            object[fieldName] = fields[fieldName];
        }
    }

    // We're done!
    deferred.resolve(object);

    return deferred.promise;
};

ObjectMapper.prototype.middleware = function(req, res, next) {
    if (req.query.objectType) {
        var objectType = req.query.objectType;

        // Build and map new data object based on given data
        self.map({
            objectType: objectType,
            requestData: req
        }).then(function(mappedObject){
            // Create dataObjects array if not existing
            if (!req.dataObjects) {
                req.dataObjects = {};
            }

            // Store mapped object in request data
            req.dataObjects[objectType] = mappedObject;

            next();
        }, function(error){
            console.error(error);

            next();
        });
    }
};

module.exports = ObjectMapper;
<|endoftext|>