<commit_before>var Profile;
define(['utils','server'],
function(Utils,Server){

	/**
     * Profile class.
     * The Profile class contains functions for user profile form initialisation and management
     * @class
     * @constructor
     * @return Profile object
     */
	Profile = {};

	/**
	* The function defines the behaviour after the request for deleting a user profile is send to the server.
	* It shows the appropriate message within a modal body and sign the current user after closing the info modal
	* by clearing the session storage and loading the login page.
	* @private
	* @memberOf Profile#
	*/
	afterDeleteFunction = function(){
		Utils.showSuccessModal(Messages.userDeleted,'userDeletedBtn');
		$('#userDeletedBtn').on('click',function(){
			Utils.hideModal('#deleteUserProfileModal');
			require('mainPage').signOut();
		});
		modalFooter.append(okBtn);
	};

	/**
	* The function performs all necessary steps after the user has been updated on the server.
	* It updates the current user profile to the information received from the server and shows the
	* appropriate message a success or an error one depending on the current state.
	* @param {String} message to be shown in the manage user profile form
	* message container identified by "#userProfileErrors" selector.
	* @private
	* @memberOf Profile#
	*/
	afterProfileUpdate = function(msg){
		setProfileFields(Utils.getCurrentUser());
		isSuccessMsg = msg.find('span').hasClass('alert-success');
		if(!isSuccessMsg){
			Utils.clearErrorMessagesFrom('#userProfileErrors');
			$('#userProfileErrors').append(msg);
		}
		Utils.updateUserInfoPanel();
		setTimeout(function(){
			$('#saveProfileLoadingSign').addClass('hidden');
		},50);
	};

	/**
	* Checks if the previous value defers from the currently entered for the given object
	* If the information is not equals the previous one then "changed" class is added.
	* @param {Object} input object to check for value changes.
	* @private
	* @memberOf Profile#
	*/
	checkIfChanged = function(object){
		var t = object;
		var currentValue = t.val();
		var defaultValue = t.attr('data-default');
		if(currentValue != defaultValue){
			if(!t.hasClass('changed'))t.addClass('changed');
		}else{
			t.removeClass('changed');
		}
	};

	/**
	* The function performs validation of the all input values from a managing user profile form.
	* @return {Boolean} true if all of the value are valid and false otherwise.
	* @private
	* @memberOf Profile#
	*/
	checkUserProfileEntries = function(){

		Utils.clearErrorMessagesFrom("#userProfileErrors");

		var fn  = Utils.checkInputField(
								"#inputFirstName",
								"#userProfileErrors",
								Validation._isName,
								Messages.emptyUsername,
								Messages.wrongUsername
								);
		var ln = Utils.checkInputField(
								"#inputLastName",
								"#userProfileErrors",
								Validation._isName,
								Messages.emptyLastName,
								Messages.wrongLastName);

		var aff =  Utils.checkInputField(
									"#inputAffiliation",
									"#userProfileErrors",
									Validation._isAffiliation,
									Messages.emptyAffiliation,
									Messages.wrongAffiliation
									);
		var email = Utils.checkInputField(
								"#inputEmail",
								"#userProfileErrors",
								Validation._isEmail,
								Messages.emptyEmailAddress,
								Messages.wrongEmailAddress);

		return (fn && ln && aff && email);
	};

	/**
	* Defines focus change on enter click for every input field from the user profile form.
	* After enter click on last input field it triggers click on the 'save' button.
	* @private
	* @memberOf Profile#
	*/
	defineOnEnterClicks = function(){
		Utils.changeFocusOnEnterClick("#inputFirstName","#inputLastName");
		Utils.changeFocusOnEnterClick("#inputLastName","#inputAffiliation");
		Utils.changeFocusOnEnterClick("#inputAffiliation","#inputEmail");
		Utils.addOnEnterClickEvent("#inputEmail","#saveProfileInfo");
	};

	/**
	* Defines the behaviour after changing of the user profile field value. The function checks if the given
	* information defers from the current user profile and if any changes are available is toggles "save" button
	* availability so the user profile can changed and uploaded to the server.
	* @private
	* @memberOf Profile#
	*/
	defineOnFieldValueChange = function(){
		var inputs = $('#manageProfileContainer').find('input');
		inputs.each(function(){
			$(this).on('keyup',function(){
				checkIfChanged($(this));
				toggleSaveBtn();
			});
		});
	};

	/**
	* Collect the changed information from the managing user profile form and stores it in the new object.
	* The object can be used in the request to the user for updating the user profile information.
	* @return {Object} collected user profile changes object
	* @private
	* @memberOf Profile#
	*/
	getUserProfileChanges = function(){
		profileChanges = new Object();
		($('#inputUsername').hasClass('changed'))    ?   profileChanges.username = $('#inputUsername').val()   : "";
		($('#inputFirstName').hasClass('changed'))   ?   profileChanges.firstName = $('#inputFirstName').val() : "";
		($('#inputLastName').hasClass('changed'))    ?   profileChanges.lastName = $('#inputLastName').val()   : "";
		($('#inputAffiliation').hasClass('changed')) ?   profileChanges.affiliation = $('#inputAffiliation').val() : "";
		($('#inputEmail').hasClass('changed'))       ?   profileChanges.email = $('#inputEmail').val() : "";
		return profileChanges;
	};

	/**
	* Initializes the 'delete' user profile button on click behaviour. The button is identified by "#deleteUserBtn" selector.
	* The function shows a confirmation modal, where user may approve his decision.
	* If the user submits the profile deletion by clicking on 'YES' button within a confirmation modal,
	* the delete user request is send to the server.
	* @private
	* @memberOf Profile#
	*/
	initDeleteUserProfileBtn = function(){
		$('#deleteUserBtn').on('click',function(){
		    var pBody = $('
'+Messages.confirmUserDeletionQuestion+'
');
			Utils.createConfirmModal('deleteUserProfileModal','deleteUserConfirmedBtn','YES','NO',pBody);
			Utils.showModal('#deleteUserProfileModal');
			$('#deleteUserConfirmedBtn').on('click',function(){
				Utils.hideModal('#deleteUserProfileModal');
				Server.deleteUser(Utils.getCurrentUser().username, afterDeleteFunction);
			});
		});
	};

	/**
	* Triggers the form initialization procedure for user profile managing purposes.
	* @public
	* @name Profile#initForm
	* @function
	*/
	Profile.initForm = function(){
		initProfileFields();
		initSaveProfileInfoBtn();
		initDeleteUserProfileBtn();
	};

	/**
	* Initializes the user profile fields. The function gets the information about the current user and
	* fills on all of the profile form fields with the appropriate data. It also defines on enter click events for
	* changing the focus to the next field and enables save button if any changes on a user profile are made.
	* @private
	* @memberOf Profile#
	*/
	initProfileFields = function(){
		Utils.clearErrorMessagesFrom("#manageProfile .errorMessages");
		setProfileFields(Utils.getCurrentUser());
		defineOnEnterClicks();
		defineOnFieldValueChange();
	};

	/**
	* Defines the behaviour after clicking on the "save" button within manage user profile form.
	* The function checks all of the changed values entered by a user for a validity and sends them to the
	* server in order to update user's profile.
	* @see Server#updateUser for sending an updating user request.
	* @private
	* @memberOf Profile#
	*/
	initSaveProfileInfoBtn = function(){
		var saveBtn = $("#saveProfileInfo");
		saveBtn.on('click',function(){
			if(checkUserProfileEntries() && !saveBtn.hasClass('disabled')){
				$('#saveProfileLoadingSign').removeClass('hidden');
				var msg = Server.updateUser(getUserProfileChanges());
				afterProfileUpdate(msg);
			}
		});
	};

	/**
	* Checks if there is any changes to be saved for the given user profile.
	* The function looks for "changed" class availability that represents new user profile information.
	* @private
	* @memberOf Profile#
	*/
	isAnyFieldChanges =function(){
		var result = false;
		var changes = $('#manageProfileContainer').find('input').filter('.changed');
		if(changes.length != 0) result = true;
		return result;
	};

	/**
	* Fills up all of the input fields within the manage user profile form
	* with the information retrieved from the current user profile.
	* @private
	* @memberOf Profile#
	*/
	setProfileFields = function(user){
		$("#inputUsername")
			.val(user.username)
			.attr('data-default',user.username);
		$("#inputFirstName")
			.val(user.firstName)
			.attr('data-default',user.firstName);
		$("#inputLastName")
			.val(user.lastName)
			.attr('data-default',user.lastName);
		$("#inputAffiliation")
			.val(user.affiliation)
			.attr('data-default',user.affiliation);
		$("#inputEmail")
			.val(user.email)
			.attr('data-default',user.email);
	};

	/**
	* Toggles availability for a "save" button identified by the "#saveProfileInfo" selector.
	* @private
	* @memberOf Profile#
	*/
	toggleSaveBtn = function(){
		var saveBtn = $('#saveProfileInfo');
		if(isAnyFieldChanges()){
			saveBtn.removeClass('disabled');
		}else{
			(!saveBtn.hasClass('disabled')) ? saveBtn.addClass('disabled') : "";
		}
	};

	return Profile;

});
<commit_msg>removed dead code<commit_after>var Profile;
define(['utils','server'],
function(Utils,Server){

	/**
     * Profile class.
     * The Profile class contains functions for user profile form initialisation and management
     * @class
     * @constructor
     * @return Profile object
     */
	Profile = {};

	/**
	* The function defines the behaviour after the request for deleting a user profile is send to the server.
	* It shows the appropriate message within a modal body and sign the current user after closing the info modal
	* by clearing the session storage and loading the login page.
	* @private
	* @memberOf Profile#
	*/
	afterDeleteFunction = function(){
		Utils.showSuccessModal(Messages.userDeleted,'userDeletedBtn');
		$('#userDeletedBtn').on('click',function(){
			Utils.hideModal('#deleteUserProfileModal');
			require('mainPage').signOut();
		});
	};

	/**
	* The function performs all necessary steps after the user has been updated on the server.
	* It updates the current user profile to the information received from the server and shows the
	* appropriate message a success or an error one depending on the current state.
	* @param {String} message to be shown in the manage user profile form
	* message container identified by "#userProfileErrors" selector.
	* @private
	* @memberOf Profile#
	*/
	afterProfileUpdate = function(msg){
		setProfileFields(Utils.getCurrentUser());
		isSuccessMsg = msg.find('span').hasClass('alert-success');
		if(!isSuccessMsg){
			Utils.clearErrorMessagesFrom('#userProfileErrors');
			$('#userProfileErrors').append(msg);
		}
		Utils.updateUserInfoPanel();
		setTimeout(function(){
			$('#saveProfileLoadingSign').addClass('hidden');
		},50);
	};

	/**
	* Checks if the previous value defers from the currently entered for the given object
	* If the information is not equals the previous one then "changed" class is added.
	* @param {Object} input object to check for value changes.
	* @private
	* @memberOf Profile#
	*/
	checkIfChanged = function(object){
		var t = object;
		var currentValue = t.val();
		var defaultValue = t.attr('data-default');
		if(currentValue != defaultValue){
			if(!t.hasClass('changed'))t.addClass('changed');
		}else{
			t.removeClass('changed');
		}
	};

	/**
	* The function performs validation of the all input values from a managing user profile form.
	* @return {Boolean} true if all of the value are valid and false otherwise.
	* @private
	* @memberOf Profile#
	*/
	checkUserProfileEntries = function(){

		Utils.clearErrorMessagesFrom("#userProfileErrors");

		var fn  = Utils.checkInputField(
								"#inputFirstName",
								"#userProfileErrors",
								Validation._isName,
								Messages.emptyUsername,
								Messages.wrongUsername
								);
		var ln = Utils.checkInputField(
								"#inputLastName",
								"#userProfileErrors",
								Validation._isName,
								Messages.emptyLastName,
								Messages.wrongLastName);

		var aff =  Utils.checkInputField(
									"#inputAffiliation",
									"#userProfileErrors",
									Validation._isAffiliation,
									Messages.emptyAffiliation,
									Messages.wrongAffiliation
									);
		var email = Utils.checkInputField(
								"#inputEmail",
								"#userProfileErrors",
								Validation._isEmail,
								Messages.emptyEmailAddress,
								Messages.wrongEmailAddress);

		return (fn && ln && aff && email);
	};

	/**
	* Defines focus change on enter click for every input field from the user profile form.
	* After enter click on last input field it triggers click on the 'save' button.
	* @private
	* @memberOf Profile#
	*/
	defineOnEnterClicks = function(){
		Utils.changeFocusOnEnterClick("#inputFirstName","#inputLastName");
		Utils.changeFocusOnEnterClick("#inputLastName","#inputAffiliation");
		Utils.changeFocusOnEnterClick("#inputAffiliation","#inputEmail");
		Utils.addOnEnterClickEvent("#inputEmail","#saveProfileInfo");
	};

	/**
	* Defines the behaviour after changing of the user profile field value. The function checks if the given
	* information defers from the current user profile and if any changes are available is toggles "save" button
	* availability so the user profile can changed and uploaded to the server.
	* @private
	* @memberOf Profile#
	*/
	defineOnFieldValueChange = function(){
		var inputs = $('#manageProfileContainer').find('input');
		inputs.each(function(){
			$(this).on('keyup',function(){
				checkIfChanged($(this));
				toggleSaveBtn();
			});
		});
	};

	/**
	* Collect the changed information from the managing user profile form and stores it in the new object.
	* The object can be used in the request to the user for updating the user profile information.
	* @return {Object} collected user profile changes object
	* @private
	* @memberOf Profile#
	*/
	getUserProfileChanges = function(){
		profileChanges = new Object();
		($('#inputUsername').hasClass('changed'))    ?   profileChanges.username = $('#inputUsername').val()   : "";
		($('#inputFirstName').hasClass('changed'))   ?   profileChanges.firstName = $('#inputFirstName').val() : "";
		($('#inputLastName').hasClass('changed'))    ?   profileChanges.lastName = $('#inputLastName').val()   : "";
		($('#inputAffiliation').hasClass('changed')) ?   profileChanges.affiliation = $('#inputAffiliation').val() : "";
		($('#inputEmail').hasClass('changed'))       ?   profileChanges.email = $('#inputEmail').val() : "";
		return profileChanges;
	};

	/**
	* Initializes the 'delete' user profile button on click behaviour. The button is identified by "#deleteUserBtn" selector.
	* The function shows a confirmation modal, where user may approve his decision.
	* If the user submits the profile deletion by clicking on 'YES' button within a confirmation modal,
	* the delete user request is send to the server.
	* @private
	* @memberOf Profile#
	*/
	initDeleteUserProfileBtn = function(){
		$('#deleteUserBtn').on('click',function(){
		    var pBody = $('
'+Messages.confirmUserDeletionQuestion+'
');
			Utils.createConfirmModal('deleteUserProfileModal','deleteUserConfirmedBtn','YES','NO',pBody);
			Utils.showModal('#deleteUserProfileModal');
			$('#deleteUserConfirmedBtn').on('click',function(){
				Utils.hideModal('#deleteUserProfileModal');
				Server.deleteUser(Utils.getCurrentUser().username, afterDeleteFunction);
			});
		});
	};

	/**
	* Triggers the form initialization procedure for user profile managing purposes.
	* @public
	* @name Profile#initForm
	* @function
	*/
	Profile.initForm = function(){
		initProfileFields();
		initSaveProfileInfoBtn();
		initDeleteUserProfileBtn();
	};

	/**
	* Initializes the user profile fields. The function gets the information about the current user and
	* fills on all of the profile form fields with the appropriate data. It also defines on enter click events for
	* changing the focus to the next field and enables save button if any changes on a user profile are made.
	* @private
	* @memberOf Profile#
	*/
	initProfileFields = function(){
		Utils.clearErrorMessagesFrom("#manageProfile .errorMessages");
		setProfileFields(Utils.getCurrentUser());
		defineOnEnterClicks();
		defineOnFieldValueChange();
	};

	/**
	* Defines the behaviour after clicking on the "save" button within manage user profile form.
	* The function checks all of the changed values entered by a user for a validity and sends them to the
	* server in order to update user's profile.
	* @see Server#updateUser for sending an updating user request.
	* @private
	* @memberOf Profile#
	*/
	initSaveProfileInfoBtn = function(){
		var saveBtn = $("#saveProfileInfo");
		saveBtn.on('click',function(){
			if(checkUserProfileEntries() && !saveBtn.hasClass('disabled')){
				$('#saveProfileLoadingSign').removeClass('hidden');
				var msg = Server.updateUser(getUserProfileChanges());
				afterProfileUpdate(msg);
			}
		});
	};

	/**
	* Checks if there is any changes to be saved for the given user profile.
	* The function looks for "changed" class availability that represents new user profile information.
	* @private
	* @memberOf Profile#
	*/
	isAnyFieldChanges =function(){
		var result = false;
		var changes = $('#manageProfileContainer').find('input').filter('.changed');
		if(changes.length != 0) result = true;
		return result;
	};

	/**
	* Fills up all of the input fields within the manage user profile form
	* with the information retrieved from the current user profile.
	* @private
	* @memberOf Profile#
	*/
	setProfileFields = function(user){
		$("#inputUsername")
			.val(user.username)
			.attr('data-default',user.username);
		$("#inputFirstName")
			.val(user.firstName)
			.attr('data-default',user.firstName);
		$("#inputLastName")
			.val(user.lastName)
			.attr('data-default',user.lastName);
		$("#inputAffiliation")
			.val(user.affiliation)
			.attr('data-default',user.affiliation);
		$("#inputEmail")
			.val(user.email)
			.attr('data-default',user.email);
	};

	/**
	* Toggles availability for a "save" button identified by the "#saveProfileInfo" selector.
	* @private
	* @memberOf Profile#
	*/
	toggleSaveBtn = function(){
		var saveBtn = $('#saveProfileInfo');
		if(isAnyFieldChanges()){
			saveBtn.removeClass('disabled');
		}else{
			(!saveBtn.hasClass('disabled')) ? saveBtn.addClass('disabled') : "";
		}
	};

	return Profile;

});
<|endoftext|>


<commit_before>/**
 * Collect all cloned nodes, including the original node.
 *
 * @method  collectInclClones
 * @author  Fritz Lekschas
 * @date    2015-12-30
 * @param   {Object}  node  Start node
 * @return  {Array}         Array of original and cloned nodes.
 */
export function collectInclClones (node) {
  let originalNode = node;

  if (node.clone) {
    originalNode = node.originalNode;
  }

  let clones = [originalNode];

  if (originalNode.clones.length) {
    clones = clones.concat(originalNode.clones);
  }

  return clones;
}
<commit_msg>Add an option to only include clones when the original node is hovered. This is useful when traversing down the graph because clones don't display children.<commit_after>/**
 * Collect all cloned nodes, including the original node.
 *
 * @method  collectInclClones
 * @author  Fritz Lekschas
 * @date    2016-03-20
 * @param   {Object}   node                 Start node
 * @param   {Boolean}  onlyForOriginalNode  If `true` only collect clones when
 *   `node` is not a clone itself.
 * @return  {Array}                         Array of original and cloned nodes.
 */
export function collectInclClones (node, onlyForOriginalNode) {
  let originalNode = node;

  if (node.clone) {
    originalNode = node.originalNode;
    if (onlyForOriginalNode) {
      return [];
    }
  }

  let clones = [originalNode];

  if (originalNode.clones.length) {
    clones = clones.concat(originalNode.clones);
  }

  return clones;
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var debug = require('debug')('wpcom:batch');

/**
 * Create a `Batch` instance
 *
 * @param {WPCOM} wpcom
 * @api public
 */

function Batch(wpcom) {
  if (!(this instanceof Batch)) {
    return new Batch(wpcom);
  }

  this.wpcom = wpcom;

  this.urls = [];
}

/**
 * Add url to batch requests
 *
 * @param {String} url
 * @api public
 */

Batch.prototype.add = function (url) {
  this.urls.push(url);
  return this;
};

/**
 * Run the batch request
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Batch.prototype.run = function (query, fn) {
  // add urls to query object
  if ('function' === typeof query) {
    fn = query;
    query = {};
  }

  var querystr = [];

  for (var x = 0; x < this.urls.length; x++) {
      querystr.push(encodeURIComponent( 'urls[]' ) + '=' + encodeURIComponent( this.urls[x] ));
  }

  query.querystr = querystr.join('&');

  return this.wpcom.req.get('/batch', query, fn);
};

/**
 * Expose `Batch` module
 */

module.exports = Batch;
<commit_msg>batch: refact -> store url strings<commit_after>
/**
 * Module dependencies.
 */

var qs = require('qs');
var debug = require('debug')('wpcom:batch');

/**
 * Create a `Batch` instance
 *
 * @param {WPCOM} wpcom
 * @api public
 */

function Batch(wpcom) {
  if (!(this instanceof Batch)) {
    return new Batch(wpcom);
  }

  this.wpcom = wpcom;

  this.urls = '';
}

/**
 * Add url to batch requests
 *
 * @param {String} url
 * @api public
 */

Batch.prototype.add = function (url) {
  this.urls += encodeURIComponent('urls[]') + '=' + encodeURIComponent(url) + '&';
  return this;
};

/**
 * Run the batch request
 *
 * @param {Object} [query]
 * @param {Function} fn
 * @api public
 */

Batch.prototype.run = function (query, fn) {
  // add urls to query object
  if ('function' === typeof query) {
    fn = query;
    query = {};
  }

  return this.wpcom.req.get('/batch', this.urls + qs.stringify(query), fn);
};

/**
 * Expose `Batch` module
 */

module.exports = Batch;
<|endoftext|>


<commit_before>"use strict";
/**
 * Graph ACL.
 */

var async = require('async');

/**
 * Creates an instance of ACL.
 *
 * @constructor
 * @this {ACL}
 * @param {Connector|Neo4jConnector} connector - A connector to a graph database of your choice
 */
var ACL = function(connector) {
  this.connector = connector;
};

/**
  addUserRoles( userId, roles, function(err) )

  Adds roles to a given user id.

  @param {String|Number} userId -  User id.
  @param {String|Array} roles - Role(s) to add to the user id.
  @param {Function} cb - Callback called when finished.
*/
ACL.prototype.addUserRoles = function(userId, roles, callback){
  var _this = this;

  if (typeof userId === 'undefined') {
    callback(new Error('User ID is empty'));
    return;
  }
  if (typeof roles === 'undefined') {
    callback(new Error('Roles list is empty'));
    return;
  }

  // When only one role in string format, transform it to array
  if (!(roles instanceof Array)) {
    roles = [roles];
  }

  this._createUser(userId, function (err, user) {
    async.map(
      roles, // Array
      function(item, cb){
        _this._createRole(item, function(err, role) {
          _this._createRelationship(user._id, role._id, 'BELONGS_TO', cb);
        });
      },
      function(err, results){
        if (results.length === 1) {
          callback(err, results[0]);
        } else {
          callback(err, results);
        }
      }
    );
  });
};

/**
  removeUserRoles( userId, roles, function(err) )

  Remove roles from a given user.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
*/
ACL.prototype.removeUserRoles = function(userId, roles, callback){
  var _this = this;
  var userNode;

  // When only one role in string format, transform it to array
  if (!(roles instanceof Array)) {
    roles = [roles];
  }

  this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, userNodes) {
    userNode = userNodes[0];

    _this.connector.getNodeRelationships(userNode._id, {types: ['BELONGS_TO']}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.getNode(relationship._end, function(err, roleNode) {
            if (roles.indexOf(roleNode.rid) !== -1) {
              _this.connector.removeRelationship(relationship._id, cb);
            } else {
              cb(null, true);
            }
          });
        },
        function(err, results){
          if (results.length === 1) {
            callback(err, results[0]);
          } else {
            callback(err, results);
          }
        }
      );
    });
  });
};

/**
  userRoles( userId, function(err, roles) )

  Return all the roles from a given user.

  @param {String|Number} User id.
  @param {Function} Callback called when finished.
*/
ACL.prototype.userRoles = function(userId, callback){
  var _this = this;
  var roles = [];

  _this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, nodes) {
    _this.connector.getNodeRelationships(nodes[0]._id, {types: ['BELONGS_TO']}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.getNode(relationship._end, function(err, roleNode) {
            if (typeof roleNode.rid !== 'undefined') {
              roles.push(roleNode);
            }
            cb(null, true);
          });
        },
        function(err, results){
          callback(err, roles);
        }
      );
    });
  });
};

/**
  addRoleParents( role, parents, function(err) )

  Adds a parent or parent list to role.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
*/
ACL.prototype.addRoleParents = function(role, parents, callback){
  var _this = this;
  // @todo: Create a relationship of type 'BELONGS_TO' between role and each parent
  // When only one parent role in string format, transform it to array
  if (!(parents instanceof Array)) {
    parents = [parents];
  }

  this._createRole(role, function (err, role) {
    async.map(
      parents, // Array
      function(item, cb){
        _this._createRole(item, function(err, parent) {
          _this._createRelationship(role._id, parent._id, 'BELONGS_TO', cb);
        });
      },
      function(err, results){
        if (results.length === 1) {
          callback(err, results[0]);
        } else {
          callback(err, results);
        }
      }
    );
  });
};

/**
  removeRole( role, function(err) )

  Removes a role from the system.

  @param {String|Number} roleId - Role to be removed
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype.removeRole = function(roleId, callback){
  var _this = this;
  var role;

  this.connector.getNodesWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, node) {
    role = node[0];

    _this.connector.getNodeRelationships(role._id, {}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.removeRelationship(relationship._id, cb);
        },
        function(err, results){
          _this.connector.deleteNode(role._id, function (err, success) {
            callback(err, success);
          });
        }
      );
    });
  });

  // @todo: node-neo4j: Maybe create a new function for erasing node and all its relationships?
};

/**
  allow( roles, resources, permissions, function(err) )

  Adds the given permissions to the given roles over the given resources.

  @param {String|Array} role(s) to add permissions to.
  @param {String|Array} resource(s) to add permisisons to.
  @param {String|Array} permission(s) to add to the roles over the resources.
  @param {Function} Callback called when finished.

  allow( permissionsArray, function(err) )

  @param {Array} Array with objects expressing what permissions to give.

  [{roles:{String|Array}, allows:[{resources:{String|Array}, permissions:{String|Array}]]

  @param {Function} Callback called when finished.
*/
ACL.prototype.allow = function(roles, resources, permissions, callback){
  if (!(roles instanceof Array)) {
    roles = [roles];
  }
  if (!(resources instanceof Array)) {
    resources = [resources];
  }
  if (!(permissions instanceof Array)) {
    permissions = [permissions];
  }

  /*async.map(
    roles, // Array
    function(role, cb){
      _this._createRole(role, cb);
    },
    function(err, results){
      if (results.length === 1) {
        callback(err, results[0]);
      } else {
        callback(err, results);
      }
    }
  );

  async.map(
    resources, // Array
    function(resource, cb){
      _this._createResource(resource, cb);
    },
    function(err, results){
      if (results.length === 1) {
        callback(err, results[0]);
      } else {
        callback(err, results);
      }
    }
  );*/

};

/**
  removeAllow(role, resources, permissions, callback)
*/
ACL.prototype.removeAllow = function(role, resources, permissions, callback){

  callback();
};

/**
  removePermissions( role, resources, permissions)

  Remove permissions from the given roles owned by the given role.

  Note: we loose atomicity when removing empty role_resources.

  @param {String}
  @param {String|Array}
  @param {String|Array}
*/
ACL.prototype.removePermissions = function(role, resources, permissions, callback){

  callback();
};

/**
  allowedPermissions( userId, resources, function(err, obj) )

  Returns all the allowable permissions a given user have to
  access the given resources.

  It returns an array of objects where every object maps a
  resource name to a list of permissions for that resource.

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {Function} Callback called when finished.
*/
ACL.prototype.allowedPermissions = function(userId, resources, callback){

  callback();
};

/**
  isAllowed( userId, resource, permissions, function(err, allowed) )

  Checks if the given user is allowed to access the resource for the given
  permissions (note: it must fulfill all the permissions).

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called wish the result.
*/
ACL.prototype.isAllowed = function(userId, resource, permissions, callback){

  callback();
};

/**
  areAnyRolesAllowed( roles, resource, permissions, function(err, allowed) )

  Returns true if any of the given roles have the right permissions.

  @param {String|Array} Role(s) to check the permissions for.
  @param {String} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called with the result.
*/
ACL.prototype.areAnyRolesAllowed = function(roles, resource, permissions, callback){

  callback();
};

/**
  whatResources(role, function(err, {resourceName: [permissions]})

  Returns what resources a given role or roles have permissions over.

  whatResources(role, permissions, function(err, resources) )

  Returns what resources a role has the given permissions over.

  @param {String|Array} Roles
  @param {String|Array} Permissions
  @param {Function} Callback called wish the result.
*/
ACL.prototype.whatResources = function(roles, permissions, callback){

  callback();
};

/**
  removeResource( resource, function(err) )

  Removes a resource from the system

  @param {String} resourceId - Resource to be removed
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype.removeResource = function(resourceId, callback){
  var _this = this;
  var resource;

  this.connector.getNodesWithLabelsAndProperties(['Resource'], {rsid: resourceId}, function(err, node) {
    resource = node[0];

    _this.connector.getNodeRelationships(resource._id, {}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.removeRelationship(relationship._id, cb);
        },
        function(err, results){
          _this.connector.deleteNode(resource._id, function (err, success) {
            callback(err, success);
          });
        }
      );
    });
  });
};

/*ACL.prototype.permittedResources = function(roles, permissions, callback){

  callback();
};*/

/////////////////////////
// "Private" functions //
/////////////////////////

/**
  Create User. If user already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createUser('user1', callback);

  @param {String|Number} userId - User id.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createUser = function (userId, callback) {
  var _this = this;

  this.connector.existsNodeWithLabelsAndProperties(['User'], {uid: userId}, function(err, exists) {
    if (exists) {
      _this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, userRetrieved) {
        callback(null, userRetrieved[0]);
      });
    } else {
      _this.connector.createNode(['User'], {uid: userId}, function (err, userCreated) {
        callback(null, userCreated);
      });
    }
  });
};

/**
  Create Role. If role already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createRole('role1', callback);

  @param {String|Number} roleId - Role id.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createRole = function (roleId, callback) {
  var _this = this;

  this.connector.existsNodeWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, exists) {
    if (exists) {
      _this.connector.getNodesWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, roleRetrieved) {
        callback(null, roleRetrieved[0]);
      });
    } else {
      _this.connector.createNode(['Role'], {rid: roleId}, function (err, roleCreated) {
        callback(null, roleCreated);
      });
    }
  });
};

/**
  Create Resource. If role already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createResource('resource1', callback);

  @param {String|Number} resourceId - Resource id.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createResource = function (resourceId, callback) {
  var _this = this;

  this.connector.existsNodeWithLabelsAndProperties(['Resource'], {rsid: resourceId}, function(err, exists) {
    if (exists) {
      _this.connector.getNodesWithLabelsAndProperties(['Resource'], {rsid: resourceId}, function(err, resourceRetrieved) {
        callback(null, resourceRetrieved[0]);
      });
    } else {
      _this.connector.createNode(['Resource'], {rsid: resourceId}, function (err, resourceCreated) {
        callback(null, resourceCreated);
      });
    }
  });
};

/**
  Create Relationship. If relationship already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createRelationship(1, 2, 'TYPE', callback);

  @param {String|Number} nodeId1 - First Node ID.
  @param {String|Number} nodeId2 - Second Node ID.
  @param {String} type - Relationship type.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createRelationship = function (nodeId1, nodeId2, type, callback) {
  var _this = this;

  this.connector.existsRelationshipsBetweenNodes(nodeId1, nodeId2, type, function(err, exists) {
    if (exists) {
      _this.connector.getRelationshipsBetweenNodes(nodeId1, nodeId2, type, function(err, relationshipRetrieved) {
        callback(null, relationshipRetrieved);
      });
    } else {
      _this.connector.addRelationship(nodeId1, nodeId2, type, function (err, relationshipCreated) {
        callback(null, relationshipCreated);
      });
    }
  });
};

module.exports = ACL;
<commit_msg>added function allow<commit_after>"use strict";
/**
 * Graph ACL.
 */

var async = require('async');

/**
 * Creates an instance of ACL.
 *
 * @constructor
 * @this {ACL}
 * @param {Connector|Neo4jConnector} connector - A connector to a graph database of your choice
 */
var ACL = function(connector) {
  this.connector = connector;
};

/**
  addUserRoles( userId, roles, function(err) )

  Adds roles to a given user id.

  @param {String|Number} userId -  User id.
  @param {String|Array} roles - Role(s) to add to the user id.
  @param {Function} cb - Callback called when finished.
*/
ACL.prototype.addUserRoles = function(userId, roles, callback){
  var _this = this;

  if (typeof userId === 'undefined') {
    callback(new Error('User ID is empty'));
    return;
  }
  if (typeof roles === 'undefined') {
    callback(new Error('Roles list is empty'));
    return;
  }

  // When only one role in string format, transform it to array
  if (!(roles instanceof Array)) {
    roles = [roles];
  }

  this._createUser(userId, function (err, user) {
    async.map(
      roles, // Array
      function(item, cb){
        _this._createRole(item, function(err, role) {
          _this._createRelationship(user._id, role._id, 'BELONGS_TO', cb);
        });
      },
      function(err, results){
        if (results.length === 1) {
          callback(err, results[0]);
        } else {
          callback(err, results);
        }
      }
    );
  });
};

/**
  removeUserRoles( userId, roles, function(err) )

  Remove roles from a given user.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
*/
ACL.prototype.removeUserRoles = function(userId, roles, callback){
  var _this = this;
  var userNode;

  // When only one role in string format, transform it to array
  if (!(roles instanceof Array)) {
    roles = [roles];
  }

  this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, userNodes) {
    userNode = userNodes[0];

    _this.connector.getNodeRelationships(userNode._id, {types: ['BELONGS_TO']}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.getNode(relationship._end, function(err, roleNode) {
            if (roles.indexOf(roleNode.rid) !== -1) {
              _this.connector.removeRelationship(relationship._id, cb);
            } else {
              cb(null, true);
            }
          });
        },
        function(err, results){
          if (results.length === 1) {
            callback(err, results[0]);
          } else {
            callback(err, results);
          }
        }
      );
    });
  });
};

/**
  userRoles( userId, function(err, roles) )

  Return all the roles from a given user.

  @param {String|Number} User id.
  @param {Function} Callback called when finished.
*/
ACL.prototype.userRoles = function(userId, callback){
  var _this = this;
  var roles = [];

  _this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, nodes) {
    _this.connector.getNodeRelationships(nodes[0]._id, {types: ['BELONGS_TO']}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.getNode(relationship._end, function(err, roleNode) {
            if (typeof roleNode.rid !== 'undefined') {
              roles.push(roleNode);
            }
            cb(null, true);
          });
        },
        function(err, results){
          callback(err, roles);
        }
      );
    });
  });
};

/**
  addRoleParents( role, parents, function(err) )

  Adds a parent or parent list to role.

  @param {String|Number} User id.
  @param {String|Array} Role(s) to remove to the user id.
  @param {Function} Callback called when finished.
*/
ACL.prototype.addRoleParents = function(role, parents, callback){
  var _this = this;
  // @todo: Create a relationship of type 'BELONGS_TO' between role and each parent
  // When only one parent role in string format, transform it to array
  if (!(parents instanceof Array)) {
    parents = [parents];
  }

  this._createRole(role, function (err, role) {
    async.map(
      parents, // Array
      function(item, cb){
        _this._createRole(item, function(err, parent) {
          _this._createRelationship(role._id, parent._id, 'BELONGS_TO', cb);
        });
      },
      function(err, results){
        if (results.length === 1) {
          callback(err, results[0]);
        } else {
          callback(err, results);
        }
      }
    );
  });
};

/**
  removeRole( role, function(err) )

  Removes a role from the system.

  @param {String|Number} roleId - Role to be removed
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype.removeRole = function(roleId, callback){
  var _this = this;
  var role;

  this.connector.getNodesWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, node) {
    role = node[0];

    _this.connector.getNodeRelationships(role._id, {}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.removeRelationship(relationship._id, cb);
        },
        function(err, results){
          _this.connector.deleteNode(role._id, function (err, success) {
            callback(err, success);
          });
        }
      );
    });
  });

  // @todo: node-neo4j: Maybe create a new function for erasing node and all its relationships?
};

/**
  allow( roles, resources, permissions, function(err) )

  Adds the given permissions to the given roles over the given resources.

  @param {String|Array} role(s) to add permissions to.
  @param {String|Array} resource(s) to add permisisons to.
  @param {String|Array} permission(s) to add to the roles over the resources.
  @param {Function} Callback called when finished.

  allow( permissionsArray, function(err) )

  @param {Array} Array with objects expressing what permissions to give.

  [{roles:{String|Array}, allows:[{resources:{String|Array}, permissions:{String|Array}]]

  @param {Function} Callback called when finished.
*/
ACL.prototype.allow = function(roles, resources, permissions, callback){
  var _this = this;
  var createdRoles = [];
  var createdResources = [];
  var permissionsFormatted = {};

  if (!(roles instanceof Array)) {
    roles = [roles];
  }
  if (!(resources instanceof Array)) {
    resources = [resources];
  }
  if (!(permissions instanceof Array)) {
    permissions = [permissions];
  }

  permissions.forEach(function (permission) {
    permissionsFormatted[permission] = true;
  })

  async.map(
    roles, // Array
    function(role, cb){
      _this._createRole(role, function (err, createdRole) {
        createdRoles.shift(createdRole);
        cb(null, true);
      });
    },
    function(err, results){
      async.map(
        resources, // Array
        function(resource, cb){
          _this._createResource(resource, function (err, createdResource) {
            createdResources.shift(createdResource);
            cb(null, true);
          });
        },
        function(err, results){
          createdRoles.forEach(function (role) {
            createdResources.forEach(function (resource) {
              //     create relationship with properties: 'create': true, etc
              _this._createRelationship(role._id, resource._id, 'HAS_ACCESS_TO', permissionsFormatted, cb);
            });
          });
        }
      );
    }
  );
};

/**
  removeAllow(role, resources, permissions, callback)
*/
ACL.prototype.removeAllow = function(role, resources, permissions, callback){

  callback();
};

/**
  removePermissions( role, resources, permissions)

  Remove permissions from the given roles owned by the given role.

  Note: we loose atomicity when removing empty role_resources.

  @param {String}
  @param {String|Array}
  @param {String|Array}
*/
ACL.prototype.removePermissions = function(role, resources, permissions, callback){

  callback();
};

/**
  allowedPermissions( userId, resources, function(err, obj) )

  Returns all the allowable permissions a given user have to
  access the given resources.

  It returns an array of objects where every object maps a
  resource name to a list of permissions for that resource.

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {Function} Callback called when finished.
*/
ACL.prototype.allowedPermissions = function(userId, resources, callback){

  callback();
};

/**
  isAllowed( userId, resource, permissions, function(err, allowed) )

  Checks if the given user is allowed to access the resource for the given
  permissions (note: it must fulfill all the permissions).

  @param {String|Number} User id.
  @param {String|Array} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called wish the result.
*/
ACL.prototype.isAllowed = function(userId, resource, permissions, callback){

  callback();
};

/**
  areAnyRolesAllowed( roles, resource, permissions, function(err, allowed) )

  Returns true if any of the given roles have the right permissions.

  @param {String|Array} Role(s) to check the permissions for.
  @param {String} resource(s) to ask permissions for.
  @param {String|Array} asked permissions.
  @param {Function} Callback called with the result.
*/
ACL.prototype.areAnyRolesAllowed = function(roles, resource, permissions, callback){

  callback();
};

/**
  whatResources(role, function(err, {resourceName: [permissions]})

  Returns what resources a given role or roles have permissions over.

  whatResources(role, permissions, function(err, resources) )

  Returns what resources a role has the given permissions over.

  @param {String|Array} Roles
  @param {String|Array} Permissions
  @param {Function} Callback called wish the result.
*/
ACL.prototype.whatResources = function(roles, permissions, callback){

  callback();
};

/**
  removeResource( resource, function(err) )

  Removes a resource from the system

  @param {String} resourceId - Resource to be removed
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype.removeResource = function(resourceId, callback){
  var _this = this;
  var resource;

  this.connector.getNodesWithLabelsAndProperties(['Resource'], {rsid: resourceId}, function(err, node) {
    resource = node[0];

    _this.connector.getNodeRelationships(resource._id, {}, function(err, relationships) {
      async.map(
        relationships, // Array
        function(relationship, cb){
          _this.connector.removeRelationship(relationship._id, cb);
        },
        function(err, results){
          _this.connector.deleteNode(resource._id, function (err, success) {
            callback(err, success);
          });
        }
      );
    });
  });
};

/*ACL.prototype.permittedResources = function(roles, permissions, callback){

  callback();
};*/

/////////////////////////
// "Private" functions //
/////////////////////////

/**
  Create User. If user already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createUser('user1', callback);

  @param {String|Number} userId - User id.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createUser = function (userId, callback) {
  var _this = this;

  this.connector.existsNodeWithLabelsAndProperties(['User'], {uid: userId}, function(err, exists) {
    if (exists) {
      _this.connector.getNodesWithLabelsAndProperties(['User'], {uid: userId}, function(err, userRetrieved) {
        callback(null, userRetrieved[0]);
      });
    } else {
      _this.connector.createNode(['User'], {uid: userId}, function (err, userCreated) {
        callback(null, userCreated);
      });
    }
  });
};

/**
  Create Role. If role already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createRole('role1', callback);

  @param {String|Number} roleId - Role id.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createRole = function (roleId, callback) {
  var _this = this;

  this.connector.existsNodeWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, exists) {
    if (exists) {
      _this.connector.getNodesWithLabelsAndProperties(['Role'], {rid: roleId}, function(err, roleRetrieved) {
        callback(null, roleRetrieved[0]);
      });
    } else {
      _this.connector.createNode(['Role'], {rid: roleId}, function (err, roleCreated) {
        callback(null, roleCreated);
      });
    }
  });
};

/**
  Create Resource. If role already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createResource('resource1', callback);

  @param {String|Number} resourceId - Resource id.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createResource = function (resourceId, callback) {
  var _this = this;

  this.connector.existsNodeWithLabelsAndProperties(['Resource'], {rsid: resourceId}, function(err, exists) {
    if (exists) {
      _this.connector.getNodesWithLabelsAndProperties(['Resource'], {rsid: resourceId}, function(err, resourceRetrieved) {
        callback(null, resourceRetrieved[0]);
      });
    } else {
      _this.connector.createNode(['Resource'], {rsid: resourceId}, function (err, resourceCreated) {
        callback(null, resourceCreated);
      });
    }
  });
};

/**
  Create Relationship. If relationship already exists, does nothing.

  Examples:
    connector = new Neo4jConnector('http://localhost:7474');
    connector._createRelationship(1, 2, 'TYPE', callback);

  @param {String|Number} nodeId1 - First Node ID.
  @param {String|Number} nodeId2 - Second Node ID.
  @param {String} type - Relationship type.
  @param {Function} callback - Callback called when finished.
*/
ACL.prototype._createRelationship = function (nodeId1, nodeId2, type, properties, callback) {
  var _this = this;

  if (typeof callback === 'undefined') {
    if (typeof properties === 'function') {
      callback = properties;
      properties = {};
    }
  }

  this.connector.existsRelationshipsBetweenNodes(nodeId1, nodeId2, type, function(err, exists) {
    if (exists) {
      _this.connector.getRelationshipsBetweenNodes(nodeId1, nodeId2, type, function(err, relationshipRetrieved) {
        callback(null, relationshipRetrieved);
      });
    } else {
      _this.connector.addRelationship(nodeId1, nodeId2, type, properties, function (err, relationshipCreated) {
        callback(null, relationshipCreated);
      });
    }
  });
};

module.exports = ACL;
<|endoftext|>


<commit_before>const router = require('express').Router();
const knex = require('../db/knex');

router.get('/', function (req, res, next) {
  knex('restaurants')
  .then(restaurants => {
    const renderObject = {};
    renderObject.title = 'Restaurants';
    renderObject.restaurants = restaurants;
    res.render('archive', renderObject);
  });
});

router.get('/:id', function (req, res, next) {
  let restaurantId = req.params.id;
  knex('restaurants')
    .where('id', restaurantId)
    .then(restaurant => {
      console.log(restaurant);
    });
});

module.exports = router;
<commit_msg>added /:id route<commit_after>const router = require('express').Router();
const knex = require('../db/knex');

router.get('/', function (req, res, next) {
  knex('restaurants')
  .then(restaurants => {
    const renderObject = {};
    renderObject.title = 'Restaurants';
    renderObject.restaurants = restaurants;
    res.render('archive', renderObject);
  });
});

router.get('/:id', function (req, res, next) {
  let restaurantId = req.params.id;
  knex('restaurants')
    .where('id', restaurantId)
    .then(restaurant => {
      if (restaurant.length) {
        restaurant = restaurant[0];
        res.render('single', restaurant);
      } else throw new Error();
    }).catch(err => {
      let returnObject = {};
      returnObject.message = err.message || 'Sorry, we couldn\'t find that page!';
      res.status(404).render('error', returnObject);
    });
});

module.exports = router;
<|endoftext|>


<commit_before>// load the things we need
var mongoose = require('mongoose');

// define the schema for our position model
var telemetrySchema = mongoose.Schema({
    mission : String,
    timestamp : Date,
    telemetry : Object
}, { collection: 'telemetry' });

// create the model for users and expose it to our app
module.exports = mongoose.model('Telemetry', telemetrySchema);<commit_msg>added compound index to telemetry collection<commit_after>// load the things we need
var mongoose = require('mongoose');

// define the schema for our telemetry model
var telemetrySchema = mongoose.Schema({
    mission : String,
    timestamp : Date,
    telemetry : Object
}, { collection: 'telemetry' });

// define index on telemetry collection for fast retrieval of data
telemetrySchema.index({ mission: 1 , timestamp: -1 });

// create the model for users and expose it to our app
module.exports = mongoose.model('Telemetry', telemetrySchema);
<|endoftext|>


<commit_before>/**
 * PaySwarm purchase tool.
 *
 * Copyright (c) 2011-2013, Digital Bazaar, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the Digital Bazaar, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var async = require('async');
var common = require('./common');
var jsonld = require('./jsonld');
var payswarm = require('..');
var prompt = require('prompt');

function init(options) {
  var cmd = options.program
    .command('purchase [listing]')
    .description('purchase a listing [WARNING]');
  common
    .command
    .init(cmd)
    .option('    --source <account_url>',
      'URL for the financial account to use when purchasing.')
    .action(purchase)
    .on('--help', function() {
      console.log();
      console.log('  WARNING: Be careful with this tool!');
      console.log();
      console.log('  This tool will perform purchase on your behalf on a');
      console.log('  PaySwarm Authority using a real account. Under most');
      console.log('  circumstances, these purchases are made with legally');
      console.log('  binding contracts.');
      console.log();
    });
}

function purchase(listing, cmd) {
  /*
   * To purchase an asset, the following steps must be performed.
   *
   * 1. Retrieve the listing and generate a hash for the listing.
   * 2. Send a purchase request for the listing and retrieve the receipt.
   */
  async.auto({
    config: function(callback) {
      common.config.read(cmd, callback);
    },
    init: ['config', function(callback, results) {
      // check for source override
      if(cmd.source) {
        results.config.source = cmd.source;
      }

      callback(null);
    }],
    listingUrl: ['init', function(callback, results) {
      if(listing) {
        return callback(null, listing);
      }

      // get the listing purchase URL from stdin if not already specified
      prompt.start();
      prompt.get({
        properties: {
          listing: {
            description: 'Enter the URL of the listing you want to purchase'
          }
        }
      }, function(err, results) {
        if(err) {
          return callback(err);
        }
        callback(null, results.listing);
      });
    }],
    source: ['listing', function(callback, results) {
      if(results.config.source) {
        return callback(null, results.config.source);
      }

      // get the source financial account for the purchase if not specified
      prompt.start();
      prompt.get({
        properties: {
          source: {
            description: 'Financial account URL (source of funds)'
          }
        }
      }, function(err, results) {
        if(err) {
          return callback(err);
        }
        callback(null, results.source);
      });
    }],
    listing: ['listingUrl', function(callback, results) {
      // Step #1: Retrieve the listing from the Web
      var options = common.requestOptions(cmd);
      options.cache = true;
      payswarm.getJsonLd(results.listingUrl, options, callback);
    }],
    confirm: ['config', 'source', 'listing', function(callback, results) {
      // quick details
      console.log('Listing ID:', results.listingUrl);
      console.log('Source Account ID:', results.source);
      // FIXME: Get quote and output amount and/or other details
      //console.log('Amount: %s %s',
      //  results.quote.currency, results.quote.amount);
      if(cmd.yes) {
        return callback(null, true);
      }
      prompt.start();
      prompt.get({
        properties: {
          confirm: {
            description: 'Perform purchase?',
            pattern: '^(yes|y|true|t|1|no|n|false|f|0)$',
            default: 'no',
            required: true
          }
        }
      }, function(err, results) {
        if(err) {
          return callback(err);
        }
        try {
          callback(null, common.boolify(results.confirm));
        }
        catch(ex) {
          callback(ex);
        }
      });
    }],
    purchase: ['confirm', function(callback, results) {
      if(!results.confirm) {
        // skip purchase
        return callback();
      }
      // Step #2: Send a purchase request for the listing
      payswarm.purchase(results.listing, {
        // FIXME: URL should be retrieved via a .well-known/payswarm method
        transactionService: results.config.authority + 'transactions',
        customer: results.config.owner,
        source: results.source,
        publicKey: results.config.publicKey.id,
        privateKeyPem: results.config.publicKey.privateKeyPem,
        verbose: cmd.verbose,
        request: common.requestOptions(cmd)
      }, callback);
    }],
    receipt: ['purchase', function(callback, results) {
      var receipt = results.purchase;
      var err = null;
      if(!results.confirm) {
        // skip output
      }
      else if(!receipt) {
        err = new Error('No receipt.');
      }
      else if(jsonld.hasValue(receipt, 'type', 'Receipt')) {
        // print the receipt of sale to the console
        var contract = receipt.contract;
        console.log('Successfully purchased:', contract.listing);
        console.log('Transaction ID:', contract.id);
        if(cmd.verbose) {
          console.log('Receipt:');
          common.output(receipt);
        }
      }
      else {
        // bad receipt
        err = callback(new Error('Receipt:' +
          JSON.stringify(receipt, null, 2)));
      }
      callback(err);
    }]
  }, function(err) {
    common.error(err);
  });
}

module.exports = {
  init: init
};

if(require.main === module) {
  common.error('Run this tool with the payswarm application.');
}
<commit_msg>[tools] Authenticate purchase request.<commit_after>/**
 * PaySwarm purchase tool.
 *
 * Copyright (c) 2011-2013, Digital Bazaar, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of the Digital Bazaar, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var async = require('async');
var common = require('./common');
var jsonld = require('./jsonld');
var payswarm = require('..');
var prompt = require('prompt');

function init(options) {
  var cmd = options.program
    .command('purchase [listing]')
    .description('purchase a listing [WARNING]');
  common
    .command
    .init(cmd)
    .option('    --source <account_url>',
      'URL for the financial account to use when purchasing.')
    .action(purchase)
    .on('--help', function() {
      console.log();
      console.log('  WARNING: Be careful with this tool!');
      console.log();
      console.log('  This tool will perform purchase on your behalf on a');
      console.log('  PaySwarm Authority using a real account. Under most');
      console.log('  circumstances, these purchases are made with legally');
      console.log('  binding contracts.');
      console.log();
    });
}

function purchase(listing, cmd) {
  /*
   * To purchase an asset, the following steps must be performed.
   *
   * 1. Retrieve the listing and generate a hash for the listing.
   * 2. Send a purchase request for the listing and retrieve the receipt.
   */
  async.auto({
    config: function(callback) {
      common.config.read(cmd, callback);
    },
    init: ['config', function(callback, results) {
      // check for source override
      if(cmd.source) {
        results.config.source = cmd.source;
      }

      callback(null);
    }],
    listingUrl: ['init', function(callback, results) {
      if(listing) {
        return callback(null, listing);
      }

      // get the listing purchase URL from stdin if not already specified
      prompt.start();
      prompt.get({
        properties: {
          listing: {
            description: 'Enter the URL of the listing you want to purchase'
          }
        }
      }, function(err, results) {
        if(err) {
          return callback(err);
        }
        callback(null, results.listing);
      });
    }],
    source: ['listing', function(callback, results) {
      if(results.config.source) {
        return callback(null, results.config.source);
      }

      // get the source financial account for the purchase if not specified
      prompt.start();
      prompt.get({
        properties: {
          source: {
            description: 'Financial account URL (source of funds)'
          }
        }
      }, function(err, results) {
        if(err) {
          return callback(err);
        }
        callback(null, results.source);
      });
    }],
    listing: ['listingUrl', function(callback, results) {
      // Step #1: Retrieve the listing from the Web
      var options = common.requestOptions(cmd);
      options.cache = true;
      payswarm.getJsonLd(results.listingUrl, options, callback);
    }],
    confirm: ['config', 'source', 'listing', function(callback, results) {
      // quick details
      console.log('Listing ID:', results.listingUrl);
      console.log('Source Account ID:', results.source);
      // FIXME: Get quote and output amount and/or other details
      //console.log('Amount: %s %s',
      //  results.quote.currency, results.quote.amount);
      if(cmd.yes) {
        return callback(null, true);
      }
      prompt.start();
      prompt.get({
        properties: {
          confirm: {
            description: 'Perform purchase?',
            pattern: '^(yes|y|true|t|1|no|n|false|f|0)$',
            default: 'no',
            required: true
          }
        }
      }, function(err, results) {
        if(err) {
          return callback(err);
        }
        try {
          callback(null, common.boolify(results.confirm));
        }
        catch(ex) {
          callback(ex);
        }
      });
    }],
    purchase: ['confirm', function(callback, results) {
      if(!results.confirm) {
        // skip purchase
        return callback();
      }
      // authenticate so we get a full receipt
      // FIXME: add option to not authenticate
      // FIXME: move this into purchase call?
      var requestOptions = common.requestOptions(cmd, {
        httpSignature: {
          keyId: results.config.publicKey.id,
          key: results.config.publicKey.privateKeyPem
        }
      });
      // Step #2: Send a purchase request for the listing
      payswarm.purchase(results.listing, {
        // FIXME: URL should be retrieved via a .well-known/payswarm method
        transactionService: results.config.authority + 'transactions',
        customer: results.config.owner,
        source: results.source,
        publicKey: results.config.publicKey.id,
        privateKeyPem: results.config.publicKey.privateKeyPem,
        verbose: cmd.verbose,
        request: requestOptions
      }, callback);
    }],
    receipt: ['purchase', function(callback, results) {
      var receipt = results.purchase;
      var err = null;
      if(!results.confirm) {
        // skip output
      }
      else if(!receipt) {
        err = new Error('No receipt.');
      }
      else if(jsonld.hasValue(receipt, 'type', 'Receipt')) {
        // print the receipt of sale to the console
        var contract = receipt.contract;
        console.log('Successfully purchased:', contract.listing);
        console.log('Transaction ID:', contract.id);
        if(cmd.verbose) {
          console.log('Receipt:');
          common.output(receipt);
        }
      }
      else {
        // bad receipt
        err = callback(new Error('Receipt:' +
          JSON.stringify(receipt, null, 2)));
      }
      callback(err);
    }]
  }, function(err) {
    common.error(err);
  });
}

module.exports = {
  init: init
};

if(require.main === module) {
  common.error('Run this tool with the payswarm application.');
}
<|endoftext|>


<commit_before>const Data = require('./data');

class Block {
	constructor(board, $block, config) {
		this.board = board;
		this.$block = $block;
		this.x = config.x;
		this.y = config.y;
		this.rotate = config.rotate;
		this.config = config;
		this.queues = {
			top: [],
			left: [],
			right: [],
			bottom: [],
		};
	}

	get center() {
		return {
			x: (this.x + .5) * 50,
			y: (this.y + .5) * 50,
		};
	}

	get top() {
		return {
			x: (this.x + .5) * 50,
			y: this.y * 50,
		};
	}

	get left() {
		return {
			x: this.x * 50,
			y: (this.y + .5) * 50,
		};
	}

	get right() {
		return {
			x: (this.x + 1) * 50,
			y: (this.y + .5) * 50,
		};
	}

	get bottom() {
		return {
			x: (this.x + .5) * 50,
			y: (this.y + 1) * 50,
		};
	}

	rotatedDirection(direction) {
		if (!this.config.rotate_levels) {
			return direction;
		}

		const directions = ['top', 'right', 'bottom', 'left'];
		return directions[(directions.indexOf(direction) + this.rotate) % 4];
	}

	passTo(direction, data) {
		if (direction === 'bottom' && this.y + 1 === this.board.height && this.x === this.board.outputBlockX) {
			this.board.output(data.value);
			data.fadeOut();
			return;
		}

		switch (direction){
			case 'top':
				if (0 <= this.y-1) {
					this.board.getBlock(this.x,this.y-1).input('bottom', data);
				} else {
					data.fadeOut();
				}
				break;
			case 'bottom':
				if (this.board.height > this.y+1) {
					this.board.getBlock(this.x,this.y+1).input('top', data);
				} else {
					data.fadeOut();
				}
				break;
			case 'left':
				if (0 <= this.x-1) {
					this.board.getBlock(this.x-1,this.y).input('right', data);
				} else {
					data.fadeOut();
				}
				break;
			case 'right':
				if (this.board.width > this.x+1) {
					this.board.getBlock(this.x+1,this.y).input('left', data);
				} else {
					data.fadeOut();
				}
				break;
			default:
				break;
		}

	}

	input(position, data) {
		this.queues[position].push(data);
		this.checkEmission();
	}

	checkEmission() {
		if (this.config.type === 'empty') {
			for (let source in this.queues) {
				const queue = this.queues[source];
				while (queue.length) {
					const data = queue.shift();
					data.fadeOut();
				}
			}
		} else if (this.config.type === 'wire') {
			const rotatedPlugs = this.config.io.plugs.map((direction) => this.rotatedDirection(direction));

			for (let source in this.queues) {
				const queue = this.queues[source];

				// When data exists in pluged direction
				if (queue.length !== 0 && rotatedPlugs.includes(source)) {
					const destinations = rotatedPlugs.filter((direction) => direction !== source);
					const data = queue.shift();
					// pass through
					data.animate(this.center).then(() => {
						destinations.forEach((destination) => {
							this.emit(destination, data.value);
						});
						data.kill();
					});
				}

				// Erase data when data exists in non-pluged direction
				if (!rotatedPlugs.includes(source)) {
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'calc') {
			const rotatedPlugs = this.config.io.plugs.map((direction) => this.rotatedDirection(direction));

			for (let source in this.queues) {
				const queue = this.queues[source];

				// When data exists in pluged direction
				if (queue.length !== 0 && rotatedPlugs.includes(source)) {
					const destinations = rotatedPlugs.filter((direction) => direction !== source);
					const data = queue.shift();
					data.animate(this.center).then(() => {
						destinations.forEach((destination) => {
							this.emit(destination, this.config.func(data.value));
						});
						data.kill();
					});
				}

				// Erase data when data exists in non-pluged direction
				if (!rotatedPlugs.includes(source)) {
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'calc2') {
			const rotatedIns = this.config.io.in.map((direction) => this.rotatedDirection(direction));
			const rotatedOut = this.rotatedDirection(this.config.io.out);

			// Execute calculation when all inputs are satisfied
			if (rotatedIns.every((source) => this.queues[source].length > 0)) {
				const datas = rotatedIns.map((source) => this.queues[source].shift());

				datas[0].animate(this.center).promise().then(() => {
					this.emit(rotatedOut, this.config.func(...datas.map((data) => data.value)));
					datas[0].kill();
				});

				for (let data of datas.slice(1)) {
					data.animate(this.center).promise().then(() => {
						data.kill();
					});
				}
			}

			// Erase data when data exists in non-pluged direction
			for (let source in this.queues) {
				if (!rotatedIns.includes(source)) {
					let queue = this.queues[source];
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'calc-switch') {
			const rotatedIns = this.config.io.in.map((direction) => this.rotatedDirection(direction));
			const rotatedOuts = this.config.io.out.map((direction) => this.rotatedDirection(direction));

			// Execute calculation when all inputs are satisfied
			if (rotatedIns.every((source) => this.queues[source].length > 0)) {
				const datas = rotatedIns.map((source) => this.queues[source].shift());

				datas[0].animate(this.center).promise().then(() => {
					const [directionIndex, value] = this.config.func(...datas.map((data) => data.value));
					this.emit(rotatedOuts[directionIndex], value);
					datas[0].kill();
				});

				for (let data of datas.slice(1)) {
					data.animate(this.center).promise().then(() => {
						data.kill();
					});
				}
			}

			// Erase data when data exists in non-pluged direction
			for (let source in this.queues) {
				if (!rotatedIns.includes(source)) {
					const queue = this.queues[source];
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'if'){
			if (this.config.io.in.every((source) => this.queues[source].length > 0)) {
				const dataA = this.queues[this.config.io.in[0]].shift();
				const dataB = this.queues[this.config.io.in[1]].shift();

				if (dataB.value){
					dataA.animate(this.center).promise().then(() => {
						this.emit(this.config.io.out[1], dataA.value);
						dataA.kill();
					});
					dataB.animate(this.center).promise().then(() => {
						dataB.kill();
					});
				} else {
					dataA.animate(this.center).promise().then(() => {
						this.emit(this.config.io.out[0], dataA.value);
						dataA.kill();
					});
					dataB.animate(this.center).promise().then(() => {
						dataB.kill();
					});
				}
			}
		}
	}

	emit(direction, value) {
		const data = new Data(this.board, this.center, value);

		if (this.board.executing) {
			data.animate(this[direction]).then(() => {
				this.passTo(direction, data);
			});
		} else {
			data.fadeOut();
		}
	}
}

module.exports = Block;
<commit_msg>Make Block to extend EventEmitter<commit_after>const Data = require('./data');
const EventEmitter = require('events');

class Block extends EventEmitter {
	constructor(board, $block, config) {
		super();
		this.board = board;
		this.$block = $block;
		this.x = config.x;
		this.y = config.y;
		this.rotate = config.rotate;
		this.config = config;
		this.queues = {
			top: [],
			left: [],
			right: [],
			bottom: [],
		};
	}

	get center() {
		return {
			x: (this.x + .5) * 50,
			y: (this.y + .5) * 50,
		};
	}

	get top() {
		return {
			x: (this.x + .5) * 50,
			y: this.y * 50,
		};
	}

	get left() {
		return {
			x: this.x * 50,
			y: (this.y + .5) * 50,
		};
	}

	get right() {
		return {
			x: (this.x + 1) * 50,
			y: (this.y + .5) * 50,
		};
	}

	get bottom() {
		return {
			x: (this.x + .5) * 50,
			y: (this.y + 1) * 50,
		};
	}

	rotatedDirection(direction) {
		if (!this.config.rotate_levels) {
			return direction;
		}

		const directions = ['top', 'right', 'bottom', 'left'];
		return directions[(directions.indexOf(direction) + this.rotate) % 4];
	}

	passTo(direction, data) {
		if (direction === 'bottom' && this.y + 1 === this.board.height && this.x === this.board.outputBlockX) {
			this.board.output(data.value);
			data.fadeOut();
			return;
		}

		switch (direction){
			case 'top':
				if (0 <= this.y-1) {
					this.board.getBlock(this.x,this.y-1).input('bottom', data);
				} else {
					data.fadeOut();
				}
				break;
			case 'bottom':
				if (this.board.height > this.y+1) {
					this.board.getBlock(this.x,this.y+1).input('top', data);
				} else {
					data.fadeOut();
				}
				break;
			case 'left':
				if (0 <= this.x-1) {
					this.board.getBlock(this.x-1,this.y).input('right', data);
				} else {
					data.fadeOut();
				}
				break;
			case 'right':
				if (this.board.width > this.x+1) {
					this.board.getBlock(this.x+1,this.y).input('left', data);
				} else {
					data.fadeOut();
				}
				break;
			default:
				break;
		}

	}

	input(position, data) {
		this.queues[position].push(data);
		this.checkEmission();
	}

	checkEmission() {
		if (this.config.type === 'empty') {
			for (let source in this.queues) {
				const queue = this.queues[source];
				while (queue.length) {
					const data = queue.shift();
					data.fadeOut();
				}
			}
		} else if (this.config.type === 'wire') {
			const rotatedPlugs = this.config.io.plugs.map((direction) => this.rotatedDirection(direction));

			for (let source in this.queues) {
				const queue = this.queues[source];

				// When data exists in pluged direction
				if (queue.length !== 0 && rotatedPlugs.includes(source)) {
					const destinations = rotatedPlugs.filter((direction) => direction !== source);
					const data = queue.shift();
					// pass through
					data.animate(this.center).then(() => {
						destinations.forEach((destination) => {
							this.emit(destination, data.value);
						});
						data.kill();
					});
				}

				// Erase data when data exists in non-pluged direction
				if (!rotatedPlugs.includes(source)) {
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'calc') {
			const rotatedPlugs = this.config.io.plugs.map((direction) => this.rotatedDirection(direction));

			for (let source in this.queues) {
				const queue = this.queues[source];

				// When data exists in pluged direction
				if (queue.length !== 0 && rotatedPlugs.includes(source)) {
					const destinations = rotatedPlugs.filter((direction) => direction !== source);
					const data = queue.shift();
					data.animate(this.center).then(() => {
						destinations.forEach((destination) => {
							this.emit(destination, this.config.func(data.value));
						});
						data.kill();
					});
				}

				// Erase data when data exists in non-pluged direction
				if (!rotatedPlugs.includes(source)) {
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'calc2') {
			const rotatedIns = this.config.io.in.map((direction) => this.rotatedDirection(direction));
			const rotatedOut = this.rotatedDirection(this.config.io.out);

			// Execute calculation when all inputs are satisfied
			if (rotatedIns.every((source) => this.queues[source].length > 0)) {
				const datas = rotatedIns.map((source) => this.queues[source].shift());

				datas[0].animate(this.center).promise().then(() => {
					this.emit(rotatedOut, this.config.func(...datas.map((data) => data.value)));
					datas[0].kill();
				});

				for (let data of datas.slice(1)) {
					data.animate(this.center).promise().then(() => {
						data.kill();
					});
				}
			}

			// Erase data when data exists in non-pluged direction
			for (let source in this.queues) {
				if (!rotatedIns.includes(source)) {
					let queue = this.queues[source];
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'calc-switch') {
			const rotatedIns = this.config.io.in.map((direction) => this.rotatedDirection(direction));
			const rotatedOuts = this.config.io.out.map((direction) => this.rotatedDirection(direction));

			// Execute calculation when all inputs are satisfied
			if (rotatedIns.every((source) => this.queues[source].length > 0)) {
				const datas = rotatedIns.map((source) => this.queues[source].shift());

				datas[0].animate(this.center).promise().then(() => {
					const [directionIndex, value] = this.config.func(...datas.map((data) => data.value));
					this.emit(rotatedOuts[directionIndex], value);
					datas[0].kill();
				});

				for (let data of datas.slice(1)) {
					data.animate(this.center).promise().then(() => {
						data.kill();
					});
				}
			}

			// Erase data when data exists in non-pluged direction
			for (let source in this.queues) {
				if (!rotatedIns.includes(source)) {
					const queue = this.queues[source];
					while (queue.length) {
						const data = queue.shift();
						data.fadeOut();
					}
				}
			}
		} else if (this.config.type === 'if'){
			if (this.config.io.in.every((source) => this.queues[source].length > 0)) {
				const dataA = this.queues[this.config.io.in[0]].shift();
				const dataB = this.queues[this.config.io.in[1]].shift();

				if (dataB.value){
					dataA.animate(this.center).promise().then(() => {
						this.emit(this.config.io.out[1], dataA.value);
						dataA.kill();
					});
					dataB.animate(this.center).promise().then(() => {
						dataB.kill();
					});
				} else {
					dataA.animate(this.center).promise().then(() => {
						this.emit(this.config.io.out[0], dataA.value);
						dataA.kill();
					});
					dataB.animate(this.center).promise().then(() => {
						dataB.kill();
					});
				}
			}
		}
	}

	emit(direction, value) {
		const data = new Data(this.board, this.center, value);

		if (this.board.executing) {
			data.animate(this[direction]).then(() => {
				this.passTo(direction, data);
			});
		} else {
			data.fadeOut();
		}
	}
}

module.exports = Block;
<|endoftext|>


<commit_before>'use strict';

var auth = require('./auth.json');
var expect = require('chai').expect;
var should = require('chai').should();

var sap = require('../index')(auth);

describe('Access Token', function() {
  this.timeout(30000);

  it('Should create authentication token', function(done) {
    setTimeout(function() {
      should.exist(sap.access_token);
      done();
    }, 1000);
  });
});

describe('Customers', function() {
  it('Should get all Customers', function(done) {
    sap.getCustomers(function(err, res, body) {
        expect(body.length).to.not.equal(0);
        done();
    });
  });
});
<commit_msg>Add response status check to test<commit_after>'use strict';

var auth = require('./auth.json');
var expect = require('chai').expect;
var should = require('chai').should();

var sap = require('../index')(auth);

describe('Access Token', function() {
  this.timeout(30000);

  it('Should create authentication token', function(done) {
    setTimeout(function() {
      should.exist(sap.access_token);
      done();
    }, 1000);
  });
});

describe('Customers', function() {
  it('Should get all Customers', function(done) {
    sap.getCustomers(function(err, res, body) {
      expect(res.statusCode).to.equal(200);
      expect(body.length).to.not.equal(0);
      done();
    });
  });
});
<|endoftext|>