<commit_before>var Q = require('q');
var fs = require('fs-extra');
var fmpOperations = require('./fmp_operations');
var child_process = require('child_process');
var os = require('os');
var async = require('async');
var path = require('path');
var log = require('../log').logger('fmp');
var config = require('../config');
var engine = require('../engine');
var http = require('http');
var https = require('https');
var fs = require('fs-extra');
var util = require('../util');
var request = require('request');
var TEMP_DIRECTORY = '/tmp';
// Compare two semantic version strings, which can be of the form 1.2.3, v1.2.3, V 1.2.3, etc.
// Returns 1 for a > b, 0 for equal, and -1 for a < b
function compareVersions(a,b) {
	try {
		a = a.replace(/v|\s/ig, '').split('.').map(function(x) {return parseInt(x,10)});
		b = b.replace(/v|\s/ig, '').split('.').map(function(x) {return parseInt(x,10)});
		if (a.length !== 3 || b.length !== 3) {
			throw new Error()
		}
	} catch(err) {
		throw new Error('Invalid version number format')
	}
	if(a[0] === b[0]) {
		if(a[1] === b[1]) {
			if(a[2] === b[2]) {
				return 0
			} else {
				return a[2] > b[2] ? 1 : -1;
			}
		} else {
			return a[1] > b[1] ? 1 : -1;
		}
	} else {
		return a[0] > b[0] ? 1 : -1;
	}
}

function compareProducts(a,b) {
	if(a.product === 'FabMo-Updater') {
		return b.product === 'FabMo-Updater' ? 0 : -1;
	}
	if(b.product === 'FabMo-Updater') {
		return a.product === 'FabMo-Updater' ? 0 : 1;
	}
	return 0;
}

// Return a promise that fulfills with a registry object loaded from the provided URL
function fetchPackagesList(url) {
	log.info('Retrieving a list of packages from ' + url)
	deferred = Q.defer();
	try {
		request(url, {timeout: 5000}, function (error, response, body) {
		  	if(error) {
		  		return deferred.reject(error);
		  	}
		  	if (response.statusCode == 200) {

		    	try {
		    		var p = JSON.parse(body);
					return deferred.resolve(p);
		    	} catch(err) {
		    		return deferred.reject(err);
		    	}
		  	} else {
		  		return deferred.reject(new Error(response.statusMessage));
		  	}
		});
	} catch(err) {
		deferred.reject(err);
	}
	return deferred.promise;
}

// Given the filename for a package manifest, return a promise that fulfills with the manifest object
// Basic checks are performed on the manifest to determine whether or not it is legitimate
function loadManifest(filename) {
	log.info('Loading the package manifest ' + filename);
	var deferred = Q.defer()
	fs.readFile(filename, 'utf8', function (err, data) {
		if(err) {
			log.error('Could not read the package manifest file.');
			return deferred.reject(err);
		}
		try {
	    	// Parse the data
	    	var manifest = JSON.parse(data);

	    	// Check for mandatory fields
			var requiredFields = ['product', 'repository', 'os', 'platform', 'version', 'operations', 'updaterNeeded']
			requiredFields.forEach(function(field) {
				if(!manifest[field]) {
					throw new Error('Update manifest is missing the required "' + field + '" field.');
				}
			});

			// Clean up object manifest
			manifest.services = manifest.services || [];

			manifest.operations.forEach(function(operation) {
				if(!(operation.op in fmpOperations)) {
					throw new Error('Operation "' + operation + '" found in the manifest is unknown.');
				}
			});

			manifest.cwd = path.resolve(path.dirname(filename));

			// Resolve promise, deliver manifest
			deferred.resolve(manifest);

		} catch(e) {
			deferred.reject(e);
		}
	});
	return deferred.promise;
}

// Given a filename, unpack the update into a temporary directory.  Return a promise that fulfills with the path to the package manifest
function unpackPackage(filename) {
	log.info('Unpacking update from '  + filename);
	var deferred = Q.defer();
	try {
		var updateDir = path.resolve(TEMP_DIRECTORY, 'fmp-update');

		// Trash the update directory if it already exists
		fs.remove(updateDir, function(err) {
			// Create a new empty one
			fs.mkdir(updateDir, function(err) {
				if(err) { return deferred.reject(err); }
				// Unpack the actual file into the newly created directory
				child_process.exec('tar -xzf ' + path.resolve(filename), {cwd : updateDir}, function(err, stdout, stderr) {
					if(err) { return deferred.reject(err); }
					deferred.resolve(path.resolve(updateDir, 'manifest.json'));
				});
			});
		});
	} catch(e) {
		deferred.reject(e);
	}
	return deferred.promise;
}

// Execute an operation object found in the package manifest.  Return a promise that resolves with the result of the operation.
function executeOperation(operation) {
	var deferred = Q.defer();
	try {
		// Double check to make sure this operation is defined
		if(!(operation.op in fmpOperations)) {
			throw new Error('Operation "' + operation.op + '" found in the manifest is unknown.');
		}
		log.info('Executing operation: ' + operation.op)
		// Execute the operation (return the operations promise to complete)
		return fmpOperations[operation.op](operation);
	} catch(e) {
		deferred.reject(e);
	}
	return deferred.promise
}

// Execute the operations in the provided manifest in sequence. Return a promise that resolves with the package manifest object.
function executeOperations(manifest) {
	deferred = Q.defer();
	var cwd = manifest.cwd
	async.eachSeries(
		manifest.operations,
		function(operation, callback) {
			operation.cwd = cwd;
			executeOperation(operation)
				.then(function() {callback();})
				.catch(callback)
		},
		function(err) {
			if(err) {
				return deferred.reject(err);
			}
			return deferred.resolve(manifest);
		}
	);
	return deferred.promise
}

// Delete the token file specified by the provided package manifest.  Do nothing if there is no token file specified.
// Return a promise that resolves with the manifest object
function clearToken(manifest) {
	var deferred = Q.defer();

	if(manifest.token) {
		log.info('Clearing update token ' + manifest.token)
		fs.unlink(manifest.token, function(err) {
			// err is swallowed on purpose.  It's ok if this operation fails due to the file not existing
		    deferred.resolve(manifest);
		});
	} else {
		deferred.resolve(manifest);
	}
	return deferred.promise;
}

// Create the token file specified by the provided package manifest.  Do nothing if there is no token file specified.
// Return a promise that resolves with the manifest object
function setToken(manifest) {
	var deferred = Q.defer();

	if(manifest.token) {
		log.info('Setting update token ' + manifest.token)
		fs.writeFile(manifest.token, "", function(err) {
	    	if(err) {
	        	return deferred.reject(err);
		    }
		    deferred.resolve(manifest);
		});
	}
	return deferred.promise;
}

function stopService(service, callback) {
	log.info('Stopping service ' + service)

	var hooks = require('../hooks');
	return hooks.stopService(service).then(callback).done();
}

function startService(service, callback) {
	log.info('Starting service ' + service)
	var hooks = require('../hooks');
	hooks.startService(service).then(callback).done();
}

function stopServices(manifest) {
	var deferred = Q.defer();
	if (manifest && manifest.services.length > 0) {
		log.info('Stopping services');
		async.mapSeries(
			manifest.services,
			stopService,
			function(err) {
				if(err) { return deferred.reject(err); }
				return deferred.resolve(manifest);
			}
		);
	} else {
		deferred.resolve(manifest);
	}
	return deferred.promise
}

function startServices(manifest) {
	var deferred = Q.defer();
	try {
		if (manifest && manifest.services.length > 0) {
			log.info('Starting services');
			async.mapSeries(
				manifest.services,
				startService,
				function(err) {
					if(err) { return deferred.reject(err); }
					return deferred.resolve(manifest);
				}
			);
		} else {
			deferred.resolve(manifest);
		}
	} catch(err) {
		deferred.reject(err);
	}

	return deferred.promise
}

function unlock(manifest) {
	try {
		if(manifest) {
			log.info('Unlocking the installation');
			return require('../hooks').unlock().then(function() { return manifest; });
		}
		return Q(manifest);
	} catch(err) {
		return Q.reject(err);
	}
}

function lock(manifest) {
	try {
		if(manifest) {
			log.info('Locking the installation');
			return require('../hooks').lock().then(function() { return manifest; });
		}
		return Q(manifest);
	} catch(err) {
		return Q.reject(err);
	}
}

function installPackage(package) {
	if(!package || !package.local_filename) {
		return Q();
	}
	return installPackageFromFile(package.local_filename);
}

function installPackageFromFile(filename) {
	if(!filename) {
		return Q();
	}
	log.info('Installing package ' + filename);
	return unpackPackage(filename)
		.then(installUnpackedPackage)

}

function installUnpackedPackage(manifest_filename) {
	return loadManifest(manifest_filename)
		.then(stopServices)
		.then(unlock)
		.then(clearToken)
		.then(executeOperations)
		.then(setToken)
		.finally(lock)
		.then(startServices)
}

function filterPackages(registry, options) {
	if(!registry || !registry.packages) { return []; }
	var packages = registry.packages.filter(function(package) {
		for(var key in options) {
			if(options.hasOwnProperty(key)) {
				try {
					allowed = options[key].split('|');
					var accept = false;
					for(var i=0; i<allowed.length; i++) {
						var field = allowed[i];
						if(field === package[key] || package[key] === '*') {
							accept = true;
							break;
						}
					}
					if(!accept) {
						return false;
					}
				} catch(e) {
					return false;
				}
			}
		}
		return true;
	});
	return packages
		.sort(function(a,b) {
			if(a.product === b.product) {
				return compareVersions(a.version, b.version);
			}
			return compareProducts(a.product, b.product);
		})
		.reverse();
}

function downloadPackage(package) {

	// Deal with insane package
	if(!package) {return Q();}
	if(!package.url) {
		log.warn('No url specified in download package');
		return Q();
	}

	var deferred = Q.defer();
	var filename = "/opt/fabmo/update.fmp";
	log.info('Starting download of ' + package.url);
	var file = fs.createWriteStream(filename);
	request(package.url)
		.on('error', function(err) { // Handle errors
    		deferred.reject(err);
  		})
		.pipe(file).on('finish', function() {
			file.close(function(err) {
      			if(err) {
      				return deferred.reject(err);
      			}
	  			log.info('Download of ' + package.url + ' is complete.')
  				package.local_filename = filename;
  				deferred.resolve(package);
      			});  // close() is async, call cb after close completes.
    		});

	return deferred.promise;
}

// Check the package source for an available update that is appropriate for the provided constraints
function checkForAvailablePackage(product) {
	var updateSource = config.updater.get('packages_url');
	var OS = config.platform;
	var PLATFORM = config.updater.get('platform');
	var options = options || {};

	log.info("Checking online source for updates");
	return fetchPackagesList(updateSource)
		.then(function(registry) {
			var deferred = Q.defer();

			// Cut down the list of packages to only ones for the specified product
			updates = filterPackages(registry, {platform : PLATFORM, os : OS, 'product' : product});

			// If no updates are available for the product, end the process
			if(updates.length == 0) {
				return deferred.resolve();
			}

			var getVersion = function(err, callback) {
				callback(null, {number: 'v0.0.0'});
			};

			switch(product) {
				case 'FabMo-Engine':
					getVersion = engine.getVersion;
					break;
				case 'FabMo-Updater':
					getVersion = require('../updater').getVersion;
					break;
				default:
					break;
			}
			// Read the version manifest for the currently installed engine
			getVersion(function(err, version) {
				if(err) {
					deferred.reject(err);
				}

				// Determine if the newest package listed in the package registry is newer than the installed version
				var newerPackageAvailable = false;
				try {
					var newerPackageAvailable = compareVersions(updates[0].version, version.number) > 0;
				} catch(e) {
					return deferred.resolve(updates[0]);
					log.warn(e);
				}

				// If so, return it, or return nothing if not
				if(newerPackageAvailable) {
					log.info("A newer package update is available!");
					return deferred.resolve(updates[0]);
				}
				return deferred.resolve();
			});
			return deferred.promise;
		});
}

exports.installPackage = installPackage;
exports.installUnpackedPackage = installUnpackedPackage;
exports.installPackageFromFile = installPackageFromFile
exports.checkForAvailablePackage = checkForAvailablePackage;
exports.downloadPackage = downloadPackage;
<commit_msg>Fix order of operations in update package search<commit_after>var Q = require('q');
var fs = require('fs-extra');
var fmpOperations = require('./fmp_operations');
var child_process = require('child_process');
var os = require('os');
var async = require('async');
var path = require('path');
var log = require('../log').logger('fmp');
var config = require('../config');
var engine = require('../engine');
var http = require('http');
var https = require('https');
var fs = require('fs-extra');
var util = require('../util');
var request = require('request');
var TEMP_DIRECTORY = '/tmp';

// Compare two semantic version strings, which can be of the form 1.2.3, v1.2.3, V 1.2.3, etc.
// Returns 1 for a > b, 0 for equal, and -1 for a < b
function compareVersions(a,b) {
	try {
		a = a.replace(/v|\s/ig, '').split('.').map(function(x) {return parseInt(x,10)});
		b = b.replace(/v|\s/ig, '').split('.').map(function(x) {return parseInt(x,10)});
		if (a.length !== 3 || b.length !== 3) {
			throw new Error()
		}
	} catch(err) {
		throw new Error('Invalid version number format')
	}
	if(a[0] === b[0]) {
		if(a[1] === b[1]) {
			if(a[2] === b[2]) {
				return 0
			} else {
				return a[2] > b[2] ? 1 : -1;
			}
		} else {
			return a[1] > b[1] ? 1 : -1;
		}
	} else {
		return a[0] > b[0] ? 1 : -1;
	}
}

function compareProducts(a,b) {
	if(a.product === 'FabMo-Updater') {
		return b.product === 'FabMo-Updater' ? 0 : -1;
	}
	if(b.product === 'FabMo-Updater') {
		return a.product === 'FabMo-Updater' ? 0 : 1;
	}
	return 0;
}

// Return a promise that fulfills with a registry object loaded from the provided URL
function fetchPackagesList(url) {
	log.info('Retrieving a list of packages from ' + url)
	var deferred = Q.defer();
	try {
		request(url, {timeout: 5000}, function (error, response, body) {
		  	if(error) {
		  		return deferred.reject(error);
		  	}
		  	if (response.statusCode == 200) {

		    	try {
		    		var p = JSON.parse(body);
					return deferred.resolve(p);
		    	} catch(err) {
		    		return deferred.reject(err);
		    	}
		  	} else {
		  		return deferred.reject(new Error(response.statusMessage));
		  	}
		});
	} catch(err) {
		deferred.reject(err);
	}
	return deferred.promise;
}

// Given the filename for a package manifest, return a promise that fulfills with the manifest object
// Basic checks are performed on the manifest to determine whether or not it is legitimate
function loadManifest(filename) {
	log.info('Loading the package manifest ' + filename);
	var deferred = Q.defer()
	fs.readFile(filename, 'utf8', function (err, data) {
		if(err) {
			log.error('Could not read the package manifest file.');
			return deferred.reject(err);
		}
		try {
	    	// Parse the data
	    	var manifest = JSON.parse(data);

	    	// Check for mandatory fields
			var requiredFields = ['product', 'repository', 'os', 'platform', 'version', 'operations', 'updaterNeeded']
			requiredFields.forEach(function(field) {
				if(!manifest[field]) {
					throw new Error('Update manifest is missing the required "' + field + '" field.');
				}
			});

			// Clean up object manifest
			manifest.services = manifest.services || [];

			manifest.operations.forEach(function(operation) {
				if(!(operation.op in fmpOperations)) {
					throw new Error('Operation "' + operation + '" found in the manifest is unknown.');
				}
			});

			manifest.cwd = path.resolve(path.dirname(filename));

			// Resolve promise, deliver manifest
			deferred.resolve(manifest);

		} catch(e) {
			deferred.reject(e);
		}
	});
	return deferred.promise;
}

// Given a filename, unpack the update into a temporary directory.  Return a promise that fulfills with the path to the package manifest
function unpackPackage(filename) {
	log.info('Unpacking update from '  + filename);
	var deferred = Q.defer();
	try {
		var updateDir = path.resolve(TEMP_DIRECTORY, 'fmp-update');

		// Trash the update directory if it already exists
		fs.remove(updateDir, function(err) {
			// Create a new empty one
			fs.mkdir(updateDir, function(err) {
				if(err) { return deferred.reject(err); }
				// Unpack the actual file into the newly created directory
				child_process.exec('tar -xzf ' + path.resolve(filename), {cwd : updateDir}, function(err, stdout, stderr) {
					if(err) { return deferred.reject(err); }
					deferred.resolve(path.resolve(updateDir, 'manifest.json'));
				});
			});
		});
	} catch(e) {
		deferred.reject(e);
	}
	return deferred.promise;
}

// Execute an operation object found in the package manifest.  Return a promise that resolves with the result of the operation.
function executeOperation(operation) {
	var deferred = Q.defer();
	try {
		// Double check to make sure this operation is defined
		if(!(operation.op in fmpOperations)) {
			throw new Error('Operation "' + operation.op + '" found in the manifest is unknown.');
		}
		log.info('Executing operation: ' + operation.op)
		// Execute the operation (return the operations promise to complete)
		return fmpOperations[operation.op](operation);
	} catch(e) {
		deferred.reject(e);
	}
	return deferred.promise
}

// Execute the operations in the provided manifest in sequence. Return a promise that resolves with the package manifest object.
function executeOperations(manifest) {
	var deferred = Q.defer();
	var cwd = manifest.cwd
	async.eachSeries(
		manifest.operations,
		function(operation, callback) {
			operation.cwd = cwd;
			executeOperation(operation)
				.then(function() {callback();})
				.catch(callback)
		},
		function(err) {
			if(err) {
				return deferred.reject(err);
			}
			return deferred.resolve(manifest);
		}
	);
	return deferred.promise
}

// Delete the token file specified by the provided package manifest.  Do nothing if there is no token file specified.
// Return a promise that resolves with the manifest object
function clearToken(manifest) {
	var deferred = Q.defer();

	if(manifest.token) {
		log.info('Clearing update token ' + manifest.token)
		fs.unlink(manifest.token, function(err) {
			// err is swallowed on purpose.  It's ok if this operation fails due to the file not existing
		    deferred.resolve(manifest);
		});
	} else {
		deferred.resolve(manifest);
	}
	return deferred.promise;
}

// Create the token file specified by the provided package manifest.  Do nothing if there is no token file specified.
// Return a promise that resolves with the manifest object
function setToken(manifest) {
	var deferred = Q.defer();

	if(manifest.token) {
		log.info('Setting update token ' + manifest.token)
		fs.writeFile(manifest.token, "", function(err) {
	    	if(err) {
	        	return deferred.reject(err);
		    }
		    deferred.resolve(manifest);
		});
	}
	return deferred.promise;
}

function stopService(service, callback) {
	log.info('Stopping service ' + service)

	var hooks = require('../hooks');
	return hooks.stopService(service).then(callback).done();
}

function startService(service, callback) {
	log.info('Starting service ' + service)
	var hooks = require('../hooks');
	hooks.startService(service).then(callback).done();
}

function stopServices(manifest) {
	var deferred = Q.defer();
	if (manifest && manifest.services.length > 0) {
		log.info('Stopping services');
		async.mapSeries(
			manifest.services,
			stopService,
			function(err) {
				if(err) { return deferred.reject(err); }
				return deferred.resolve(manifest);
			}
		);
	} else {
		deferred.resolve(manifest);
	}
	return deferred.promise
}

function startServices(manifest) {
	var deferred = Q.defer();
	try {
		if (manifest && manifest.services.length > 0) {
			log.info('Starting services');
			async.mapSeries(
				manifest.services,
				startService,
				function(err) {
					if(err) { return deferred.reject(err); }
					return deferred.resolve(manifest);
				}
			);
		} else {
			deferred.resolve(manifest);
		}
	} catch(err) {
		deferred.reject(err);
	}

	return deferred.promise
}

function unlock(manifest) {
	try {
		if(manifest) {
			log.info('Unlocking the installation');
			return require('../hooks').unlock().then(function() { return manifest; });
		}
		return Q(manifest);
	} catch(err) {
		return Q.reject(err);
	}
}

function lock(manifest) {
	try {
		if(manifest) {
			log.info('Locking the installation');
			return require('../hooks').lock().then(function() { return manifest; });
		}
		return Q(manifest);
	} catch(err) {
		return Q.reject(err);
	}
}

function installPackage(package) {
	if(!package || !package.local_filename) {
		return Q();
	}
	return installPackageFromFile(package.local_filename);
}

function installPackageFromFile(filename) {
	if(!filename) {
		return Q();
	}
	log.info('Installing package ' + filename);
	return unpackPackage(filename)
		.then(installUnpackedPackage)

}

function installUnpackedPackage(manifest_filename) {
	return loadManifest(manifest_filename)
		.then(stopServices)
		.then(unlock)
		.then(clearToken)
		.then(executeOperations)
		.then(setToken)
		.finally(lock)
		.then(startServices)
}

function filterPackages(registry, options) {
	if(!registry || !registry.packages) { return []; }
	var packages = registry.packages.filter(function(package) {
		for(var key in options) {
			if(options.hasOwnProperty(key)) {
				try {
					allowed = options[key].split('|');
					var accept = false;
					for(var i=0; i<allowed.length; i++) {
						var field = allowed[i];
						if(field === package[key] || package[key] === '*') {
							accept = true;
							break;
						}
					}
					if(!accept) {
						return false;
					}
				} catch(e) {
					return false;
				}
			}
		}
		return true;
	});
	return packages
		.sort(function(a,b) {
			if(a.product === b.product) {
				return compareVersions(a.version, b.version);
			}
			return compareProducts(a.product, b.product);
		})
		.reverse();
}

function downloadPackage(package) {

	// Deal with insane package
	if(!package) {return Q();}
	if(!package.url) {
		log.warn('No url specified in download package');
		return Q();
	}

	var deferred = Q.defer();
	var filename = "/opt/fabmo/update.fmp";
	log.info('Starting download of ' + package.url);
	var file = fs.createWriteStream(filename);
	request(package.url)
		.on('error', function(err) { // Handle errors
    		deferred.reject(err);
  		})
		.pipe(file).on('finish', function() {
			file.close(function(err) {
      			if(err) {
      				return deferred.reject(err);
      			}
	  			log.info('Download of ' + package.url + ' is complete.')
  				package.local_filename = filename;
  				deferred.resolve(package);
      			});  // close() is async, call cb after close completes.
    		});

	return deferred.promise;
}

// Check the package source for an available update that is appropriate for the provided constraints
function checkForAvailablePackage(product) {
	var updateSource = config.updater.get('packages_url');
	var OS = config.platform;
	var PLATFORM = config.updater.get('platform');
	var options = options || {};

	log.info("Checking online source for updates");
	return fetchPackagesList(updateSource)
		.then(function(registry) {
			var deferred = Q.defer();

			// Cut down the list of packages to only ones for the specified product
			updates = filterPackages(registry, {platform : PLATFORM, os : OS, 'product' : product});

			// If no updates are available for the product, end the process
			if(updates.length == 0) {
				return deferred.resolve();
			}

			var getVersion = function(err, callback) {
				callback(null, {number: 'v0.0.0'});
			};

			switch(product) {
				case 'FabMo-Engine':
					getVersion = engine.getVersion;
					break;
				case 'FabMo-Updater':
					getVersion = require('../updater').getVersion;
					break;
				default:
					break;
			}
			// Read the version manifest for the currently installed engine
			getVersion(function(err, version) {
				if(err) {
					deferred.reject(err);
				}

				// Determine if the newest package listed in the package registry is newer than the installed version
				var newerPackageAvailable = false;
				try {
					var newerPackageAvailable = compareVersions(updates[0].version, version.number) > 0;
				} catch(e) {
					return deferred.resolve(updates[0]);
					log.warn(e);
				}

				// If so, return it, or return nothing if not
				if(newerPackageAvailable) {
					log.info("A newer package update is available!");
					return deferred.resolve(updates[0]);
				}
				return deferred.resolve();
			});
			return deferred.promise;
		});
}

exports.installPackage = installPackage;
exports.installUnpackedPackage = installUnpackedPackage;
exports.installPackageFromFile = installPackageFromFile
exports.checkForAvailablePackage = checkForAvailablePackage;
exports.downloadPackage = downloadPackage;
<|endoftext|>


<commit_before>var Discord = require('discord.io');
var request = require('request');

// Define the bot instance
var bot = new Discord.Client({
    autorun: true,
    token: ""
});

// Reconnect the bot if they somehow get disconnected
bot.on('disconnect', function(errMsg, code) {
  bot.connect()
});

// Make sure the emojis are fresh from the repo
function getEmojiFonts(){
  request('https://github.com/haykam821/Discord-Font-Service/raw/master/index.json', function (error, response, body) {
    if (!error && response.statusCode == 200) {
       importedJSON = JSON.parse(body);
       fonts = importedJSON;
    }
  })
};

setInterval(getEmojiFonts,3000);

// Define fonts in case it hasn't loaded yet
var fonts = {};

// Define a function to convert from text to letter emoji
function parseToEmoji(cmd, message) {
  try {
    array = message.toLowerCase().replace(cmd + ' ', '').split(' ');
    font = fonts[message.replace('font:', '').split(' ')[message.split(' ').length - 1]] == undefined ? fonts['default'] : fonts[message.replace('font:', '').split(' ')[message.split(' ').length - 1]]
    // Font setup
    if (array[array.length - 1].startsWith('font:')) {
        array.pop();
    } else {
        font = fonts['default'];
    };
    // Fix array again
    array = array.join(' ').split('');
    // Convert to emoji!
    for (var i = 0; i < array.length; i++) {
        console.log(font[1][array[i]])
        array[i] = font[1][array[i]] == undefined ? array[i] : font[1][array[i]]
    }
    return {
      font: font == fonts['default'] ? `Default (${fonts.default[0]})` : font[0],
      text: array.join(''),
      color: parseInt(font[2])
    }
  } catch (err) {
    return {
      font: 'None',
      text: `Fail. ${err}`,
      color: 0xFF1100
    }
  }
}

// Define a function that allows checking commands easily
function cmd(message, cmdname) {
  return message.toLowerCase().startsWith(cmdname);
}

// Message handling
bot.on('message', function(user, userID, channelID, message, event) {
  try {
    if (userID == bot.id) {
        // Respond to commands using parse to emoji function
        if (message.toLowerCase().startsWith('>e ')) {
            bot.editMessage({
                channelID: channelID,
                messageID: event.d.id,
                message: message,
                embed: {description:parseToEmoji('>e', message)},
            });
        }
        // Respond to commands using parse to emoji function, but output as raw
        if (message.toLowerCase().startsWith('>er ')) {
            bot.editMessage({
                channelID: channelID,
                messageID: event.d.id,
                message: message,
                embed: {description:`\`\`\`\n${parseToEmoji('>er',message)}\`\`\``},
            });
        }
    }
  } catch (err) {
    console.log('Error: ' + err);
  }
});
<commit_msg>Allow the commands in the message received function to use the new data provided by the function<commit_after>var Discord = require('discord.io');
var request = require('request');

// Define the bot instance
var bot = new Discord.Client({
    autorun: true,
    token: ""
});

// Reconnect the bot if they somehow get disconnected
bot.on('disconnect', function(errMsg, code) {
  bot.connect()
});

// Make sure the emojis are fresh from the repo
function getEmojiFonts(){
  request('https://github.com/haykam821/Discord-Font-Service/raw/master/index.json', function (error, response, body) {
    if (!error && response.statusCode == 200) {
       importedJSON = JSON.parse(body);
       fonts = importedJSON;
    }
  })
};

setInterval(getEmojiFonts,3000);

// Define fonts in case it hasn't loaded yet
var fonts = {};

// Define a function to convert from text to letter emoji
function parseToEmoji(cmd, message) {
  try {
    array = message.toLowerCase().replace(cmd + ' ', '').split(' ');
    font = fonts[message.replace('font:', '').split(' ')[message.split(' ').length - 1]] == undefined ? fonts['default'] : fonts[message.replace('font:', '').split(' ')[message.split(' ').length - 1]]
    // Font setup
    if (array[array.length - 1].startsWith('font:')) {
        array.pop();
    } else {
        font = fonts['default'];
    };
    // Fix array again
    array = array.join(' ').split('');
    // Convert to emoji!
    for (var i = 0; i < array.length; i++) {
        console.log(font[1][array[i]])
        array[i] = font[1][array[i]] == undefined ? array[i] : font[1][array[i]]
    }
    return {
      font: font == fonts['default'] ? `Default (${fonts.default[0]})` : font[0],
      text: array.join(''),
      color: parseInt(font[2])
    }
  } catch (err) {
    return {
      font: 'None',
      text: `Fail. ${err}`,
      color: 0xFF1100
    }
  }
}

// Define a function that allows checking commands easily
function cmd(message, cmdname) {
  return message.toLowerCase().startsWith(cmdname);
}

// Message handling
bot.on('message', function(user, userID, channelID, message, event) {
  try {
    if (userID == bot.id) {
        // Respond to commands using parse to emoji function
        if (message.toLowerCase().startsWith('>fontify ')) {
            var result = parseToEmoji('>fontify',message);
            bot1.editMessage({
                channelID: channelID,
                messageID: event.d.id,
                message: message,
                embed: {color:result.color,description:result.text,footer:{text:`Font: ${result.font}`}},
            });
        }
        // Respond to commands using parse to emoji function, but output as raw
        if (message.toLowerCase().startsWith('>codeify')) {
            var result = parseToEmoji('>codeify',message);
            bot1.editMessage({
                channelID: channelID,
                messageID: event.d.id,
                message: message,
                embed: {color:result.color,description:`\`\`\`\n${result.text}\`\`\``,footer:{text:`Font: ${result.font}`}},
            });
        }
    }
  } catch (err) {
    console.log('Error: ' + err);
  }
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';

import { ArticleFooterContainer } from '@economist/component-articletemplate/footer';
import { defaultGenerateClassNameList } from '@economist/component-variantify';

const extendedFooterBylineClasses = [
  'margin-l-1',
  'gutter-l',
  'col-10',
];
const extendedFooterBylineDetailsClasses = [
  'gutter-l',
  'col-10',
];
function BylineFooterContainer({ generateClassNameList = defaultGenerateClassNameList, children }) {
  return (
    <div className={[
      ...generateClassNameList(`ArticleTemplate--byline-footer`),
      ...extendedFooterBylineClasses,
    ].join(' ')}
    >
      {children}

  );
}
BylineFooterContainer.propTypes = {
  generateClassNameList: PropTypes.func,
  children: PropTypes.node,
};

export class WinFooter extends Component {

  static get propTypes() {
    return {
      generateClassNameList: PropTypes.func,
      byline: PropTypes.string,
      bylineLocation: PropTypes.string,
      bio: PropTypes.string,
    };
  }

  static get defaultProps() {
    return {
      generateClassNameList: defaultGenerateClassNameList,
    };
  }
  /* eslint-disable react/no-danger */
  render() {
    const { generateClassNameList, byline, bylineLocation, bio } = this.props;
    return (
      <ArticleFooterContainer generateClassNameList={generateClassNameList}>
        <BylineFooterContainer generateClassNameList={generateClassNameList}>
          <h3
            itemProp="byline"
            className={[
              ...generateClassNameList(`ArticleTemplate--byline`),
              ...extendedFooterBylineClasses,
            ].join(' ')}
          >
            {byline}

          <span
            itemProp="bylineLocation"
            className={[
              ...generateClassNameList(`ArticleTemplate--byline-location`),
              ...extendedFooterBylineDetailsClasses,
            ].join(' ')}
          >
            {bylineLocation}

          <span
            itemProp="bio"
            className={[
              ...generateClassNameList(`ArticleTemplate--byline-bio`),
              ...extendedFooterBylineDetailsClasses,
            ].join(' ')}
            dangerouslySetInnerHTML={{
              '__html': bio,
            }}
          />
        </BylineFooterContainer>
      </ArticleFooterContainer>
    );
  }
  /* eslint-enable react/no-danger */
}
<commit_msg>removed itemProps from footer as these are not valid NewsArticle schema<commit_after>import React, { Component, PropTypes } from 'react';

import { ArticleFooterContainer } from '@economist/component-articletemplate/footer';
import { defaultGenerateClassNameList } from '@economist/component-variantify';

const extendedFooterBylineClasses = [
  'margin-l-1',
  'gutter-l',
  'col-10',
];
const extendedFooterBylineDetailsClasses = [
  'gutter-l',
  'col-10',
];
function BylineFooterContainer({ generateClassNameList = defaultGenerateClassNameList, children }) {
  return (
    <div className={[
      ...generateClassNameList(`ArticleTemplate--byline-footer`),
      ...extendedFooterBylineClasses,
    ].join(' ')}
    >
      {children}

  );
}
BylineFooterContainer.propTypes = {
  generateClassNameList: PropTypes.func,
  children: PropTypes.node,
};

export class WinFooter extends Component {

  static get propTypes() {
    return {
      generateClassNameList: PropTypes.func,
      byline: PropTypes.string,
      bylineLocation: PropTypes.string,
      bio: PropTypes.string,
    };
  }

  static get defaultProps() {
    return {
      generateClassNameList: defaultGenerateClassNameList,
    };
  }
  /* eslint-disable react/no-danger */
  render() {
    const { generateClassNameList, byline, bylineLocation, bio } = this.props;
    return (
      <ArticleFooterContainer generateClassNameList={generateClassNameList}>
        <BylineFooterContainer generateClassNameList={generateClassNameList}>
          <h3
            className={[
              ...generateClassNameList(`ArticleTemplate--byline`),
              ...extendedFooterBylineClasses,
            ].join(' ')}
          >
            {byline}

          <span
            className={[
              ...generateClassNameList(`ArticleTemplate--byline-location`),
              ...extendedFooterBylineDetailsClasses,
            ].join(' ')}
          >
            {bylineLocation}

          <span
            className={[
              ...generateClassNameList(`ArticleTemplate--byline-bio`),
              ...extendedFooterBylineDetailsClasses,
            ].join(' ')}
            dangerouslySetInnerHTML={{
              '__html': bio,
            }}
          />
        </BylineFooterContainer>
      </ArticleFooterContainer>
    );
  }
  /* eslint-enable react/no-danger */
}
<|endoftext|>


<commit_before>var Color = (function () {

	var _additive = function (colors, operation) {
		var sum = colors.shift();
		for (var i in colors) {
			var color = colors[i];
			if(color) {
				for(var j in color) {
					switch (operation) {
						case "subtract":
							sum[j] -= color[j];
							break;
						case "add":
						default:
							sum[j] += color[j];
							break;
					}
				}
			}
		}
		return sum;
	}

	var _diff = function (color1, color2) {
		var mag1 = _magnitude(color1);
		var mag2 = _magnitude(color2);
		return mag1 - mag2;
	}

	var _adjust = function (color, direction, amount) {
		// Can't do this math on the origin, use the darkest grey.
		color = (_magnitude(color) === 0)? _parseColor('#010101') : color;

		// convert to polar coordinates
		var magnitude = _magnitude(color);
		var theta = Math.acos(color.b/magnitude);
		var phi = Math.atan(color.g/color.r);

		// Calculate new color vector magnitude
		var dM = _delta_magnitude(amount);
		var new_magnitude = 0;
		if (direction === 'lighten') {
			new_magnitude = magnitude + dM;
		} else if (direction === 'darken') {
			new_magnitude = magnitude - dM;
		} else {
			return color;
		}

		// convert back to color coordinates
		var r = Math.round(new_magnitude * Math.sin(theta) * Math.cos(phi));
		var g = Math.round(new_magnitude * Math.sin(theta) * Math.sin(phi));
		var b = Math.round(new_magnitude * Math.cos(theta));

		return  {
			r: (isNaN(r))? 0 : r,
			g: (isNaN(g))? 0 : g,
			b: (isNaN(b))? 0 : b,
		};
	}

	var _magnitude = function (color) {
		var sum = 0;
		for (var i in color) {
			sum += Math.pow(color[i],2);
		}
		return Math.sqrt(sum);
	}

	var _delta_magnitude = function (percent) {
		return _magnitude(_parseColor('#ffffff')) * percent;
	}

	var _parseColor = function (color) {
		if(typeof color !== 'string') {
			color = color.toString();
		}
		color = color.replace(/(#|0x)/g,"");
		var color_array = {r:0,g:0,b:0};
		if (color.length === 6) {
			color_array = {
				r: parseInt('0x' + color.substr(0,2)),
				g: parseInt('0x' + color.substr(2,2)),
				b: parseInt('0x' + color.substr(4,2)),
			};
		} else if (color.length === 3) {
			color_array = {
				r: parseInt('0x' + color.substr(0,1) + color.substr(0,1)),
				g: parseInt('0x' + color.substr(1,1) + color.substr(1,1)),
				b: parseInt('0x' + color.substr(2,1) + color.substr(2,1)),
			}
		} else {
			color_array = false;
		}
		return color_array;
	}

	var _formatColor = function (color) {
		var formatted = '#';
		for(var i in color) {
			// ceiling/floor checks
			if (color[i] < 0) {
				color[i] = 0;
			} else if( color[i] > 255) {
				color[i] = 255;
			}
			var component = "0" + Math.round(color[i]).toString(16);
			formatted += component.substr(component.length - 2);
		}
		return formatted;
	}

	var _argsToArray = function (args) {
		var a = [];
		for (var i in args) {
			a.push(_parseColor(args[i]));
		}
		return a;
	}

	var _parsePercent = function (num) {
		if (typeof num !== 'string') {
			return num;
		}
		if (num.indexOf('%') === -1) {
			return parseFloat(num);
		}
		percent = parseFloat(num)/100;
		return percent;
	}

	return {

		add: function() {
			return _formatColor(_additive(_argsToArray(arguments), "add"));
		},
		subtract: function () {
			return _formatColor(_additive(_argsToArray(arguments), "subtract"));
		},
		lighten: function (color, percent) {
			return _formatColor(_adjust(_parseColor(color), "lighten", _parsePercent(percent)));
		},
		darken: function (color, percent) {
			return _formatColor(_adjust(_parseColor(color), "darken", _parsePercent(percent)));
		},
		isLighter: function (color1, color2) {
			// Answering "is color1 lighter than color2?"
			return ((_magnitude(_parseColor(color1)) - _magnitude(_parseColor(color2))) > 0 );
		},
		isDarker: function (color1, color2) {
			// Answering "is color1 darker than color2?"
			return ((_magnitude(_parseColor(color1)) - _magnitude(_parseColor(color2))) < 0 );
		},
		parse: function(color) {
			return _formatColor(_parseColor(color));
		},
		diff: function(color1, color2) {
			return _diff(_parseColor(color1), _parseColor(color2));
		}
	};
})();
<commit_msg>added method to allow colors to lighten past their brightest to fade to white<commit_after>var Color = (function () {

	var _additive = function (colors, operation) {
		var sum = colors.shift();
		for (var i in colors) {
			var color = colors[i];
			if(color) {
				for(var j in color) {
					switch (operation) {
						case "subtract":
							sum[j] -= color[j];
							break;
						case "add":
						default:
							sum[j] += color[j];
							break;
					}
				}
			}
		}
		return sum;
	}

	var _diff = function (color1, color2) {
		var mag1 = _magnitude(color1);
		var mag2 = _magnitude(color2);
		return mag1 - mag2;
	}

	var _adjust = function (color, direction, amount) {
		// Can't do this math on the origin, use the darkest grey.
		color = (_magnitude(color) === 0)? _parseColor('#010101') : color;

		// convert to polar coordinates
		var magnitude = _magnitude(color);
		var theta = Math.acos(color.b/magnitude);
		var phi = Math.atan(color.g/color.r);

		// Calculate new color vector magnitude
		var dM = _delta_magnitude(amount);
		var new_magnitude = 0;
		if (direction === 'lighten') {
			new_magnitude = magnitude + dM;
		} else if (direction === 'darken') {
			new_magnitude = magnitude - dM;
		} else {
			return color;
		}

		// convert back to color coordinates
		var new_color = {
			r: Math.round(new_magnitude * Math.sin(theta) * Math.cos(phi)),
			g: Math.round(new_magnitude * Math.sin(theta) * Math.sin(phi)),
			b: Math.round(new_magnitude * Math.cos(theta)),
		}

		return  _validateColor(new_color, new_magnitude);
	}

	var _magnitude = function (color) {
		var sum = 0;
		for (var i in color) {
			sum += Math.pow(color[i],2);
		}
		return Math.sqrt(sum);
	}

	var _delta_magnitude = function (percent) {
		return brightest * percent;
	}

	var _parseColor = function (color) {
		if(typeof color !== 'string') {
			color = color.toString();
		}
		color = color.replace(/(#|0x)/g,"");
		var color_array = {r:0,g:0,b:0};
		if (color.length === 6) {
			color_array = {
				r: parseInt('0x' + color.substr(0,2)),
				g: parseInt('0x' + color.substr(2,2)),
				b: parseInt('0x' + color.substr(4,2)),
			};
		} else if (color.length === 3) {
			color_array = {
				r: parseInt('0x' + color.substr(0,1) + color.substr(0,1)),
				g: parseInt('0x' + color.substr(1,1) + color.substr(1,1)),
				b: parseInt('0x' + color.substr(2,1) + color.substr(2,1)),
			}
		} else {
			color_array = false;
		}
		return color_array;
	}

	var _validateColor = function (color, target_magnitude) {
		// check for bad or too dark
		for(var i in color) {
			if(isNaN(color[i]) || color[i] < 0) {
				color[i] = 0;
			}
		}

		// check for too bright
		if(_magnitude(color) >= brightest) {
			return _parseColor('fff');
		}

		// check for human visible colors
		var valid_components = [];
		for(var i in color) {
			if(color[i] <= 255) {
				valid_components.push(i);
			} else {
				color[i] = 255;
			}
		}

		// Not bright enough for the target_magnitude, add white
		if(valid_components.length < 3) {
			var delta_vector = {r:0,g:0,b:0};
			target_magnitude = Math.round(target_magnitude);
			for(var i in valid_components) {
				delta_vector[valid_components[i]] = 1;
			}
			while(Math.round(_magnitude(color)) < target_magnitude) {
				color = _additive([color, delta_vector], "add");
				for(var i in color) {
					if(color[i] > 255) {
						color[i] = 255;
					}
				}
			}
		}
		return color;
	}

	var _formatColor = function (color) {
		var formatted = '#';
		for(var i in color) {
			var component = "0" + Math.round(color[i]).toString(16);
			formatted += component.substr(component.length - 2);
		}
		return formatted;
	}

	var _argsToArray = function (args) {
		var a = [];
		for (var i in args) {
			a.push(_parseColor(args[i]));
		}
		return a;
	}

	var _parsePercent = function (num) {
		if (typeof num !== 'string') {
			return num;
		}
		if (num.indexOf('%') === -1) {
			return parseFloat(num);
		}
		percent = parseFloat(num)/100;
		return percent;
	}

	var brightest = _magnitude(_parseColor('fff'));

	return {

		add: function() {
			return _formatColor(_additive(_argsToArray(arguments), "add"));
		},
		subtract: function () {
			return _formatColor(_additive(_argsToArray(arguments), "subtract"));
		},
		lighten: function (color, percent) {
			return _formatColor(_adjust(_parseColor(color), "lighten", _parsePercent(percent)));
		},
		darken: function (color, percent) {
			return _formatColor(_adjust(_parseColor(color), "darken", _parsePercent(percent)));
		},
		isLighter: function (color1, color2) {
			// Answering "is color1 lighter than color2?"
			return ((_magnitude(_parseColor(color1)) - _magnitude(_parseColor(color2))) > 0 );
		},
		isDarker: function (color1, color2) {
			// Answering "is color1 darker than color2?"
			return ((_magnitude(_parseColor(color1)) - _magnitude(_parseColor(color2))) < 0 );
		},
		parse: function(color) {
			return _formatColor(_parseColor(color));
		},
		diff: function(color1, color2) {
			return _diff(_parseColor(color1), _parseColor(color2));
		}
	};
})();
<|endoftext|>


<commit_before>/**
 * Author: Zeta Ret, Ivo Yankulovski
 * Zeta Ret ProtoSS
 * ProtoSS Class/Interface/Header Manager
 * Requires: protoss.all.js v1.04a
 * Version: 1.04c
 * Date: 2017 - Today
**/
window.internal(
function ProtoSS(){
	var o=this,a=arguments;
	o.autoImplement=true;
	o.autoSuper=true;
	o.autoSuperList=true;
	o.autoSuperList2=true;
	o.errorData=null;
	o.debug=null;
	o.super(a);
	var m={};
	m.toInterface=function(i, pack){
		var imap={},key;
		for(key in i){
			if (key=="__name")continue;
			imap[key]=i[key].interface(key);
			if (pack)pack.internal(imap[key]);
		}
		return imap;
	};
	m.stringPattern=function(pat, str, pos){
	    if(!pos)pos=0;
	    var num=0;
		while(str.indexOf(pat, pos)==pos){
			num++;
			str=str.substr(0,pos)+str.substr(pos+pat.length,str.length);
		}
		return [num,str];
	};
	m.getSuperCls=function(sname, toppack, path){
		var many=sname.split("|"),
			cls=null,i,sn,tp,sp,pathsplit,s;
		for(i=0;i<many.length;i++){
			sn=many[i];
			tp=toppack;
			sp=o.stringPattern("/",sn);
			if (path && sp[0]>0){
				pathsplit=path.split(".");
				tp=tp.package(pathsplit.slice(0, pathsplit.length-sp[0]+1).join("."));
			}
			s=sp[1].split("::");
			if (s.length==1){
				cls=tp[s[0]];
				if(cls)return cls;
			}
			cls=tp.package(s[0])[s[1]];
			if(cls)return cls;
		}
		return cls;
	};
	m.resolveCls=function(s, toppack, path){
		var k,sk,kk,skk,i;
		for(k in s){
			if (k=="__name")continue;
			sk=s[k];
			for(kk in sk){
				skk=sk[kk];
				for(i=0;i<skk.length;i++){
					if (skk[i].constructor==String){
						skk[i]=o.getSuperCls(skk[i], toppack, path);
					}
				}
			}
		}
		return o;
	};
	m.resolveHeaders=function(toppack, path, protoss){
		var i,j,v,vl,c1,c2,sla,ia,sl,sa,ta;
		try{
		if(o.autoImplement){
			ia=[];
			ta=ProtoSS.headerImplement;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.implement(protoss?c2.__protoss||c2:c2);
				else ia.push(v);
			}
			ProtoSS.headerImplement=ia;
		}
		if(o.autoSuper){
			sa=[];
			ta=ProtoSS.headerSuper;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.setSuper(protoss?c2.__protoss||c2:c2);
				else sa.push(v);
			}
			ProtoSS.headerSuper=sa;
		}
		if(o.autoSuperList){
			sla=[];
			ta=ProtoSS.headerSuperList;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(protoss?c2.__protoss||c2:c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList(sl);
				}
			}
			ProtoSS.headerSuperList=sla;
		}
		if(o.autoSuperList2){
			sla=[];
			ta=ProtoSS.headerSuperList2;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(protoss?c2.__protoss||c2:c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList2(sl);
				}
			}
			ProtoSS.headerSuperList2=sla;
		}
		} catch(e){
			o.errorData=[ta,ta[i-1],i,j,v,vl,c1,c2,sla,ia,sl,sa];
			if(o.debug)o.debug("error", "resolveHeaders", o, o.errorData);
			throw(e);
		}

		return o;
	};
	o.superize(a,m,true,true);
	return o;
}
);
ProtoSS.headerImplement=[];
ProtoSS.headerSuper=[];
ProtoSS.headerSuperList=[];
ProtoSS.headerSuperList2=[];
ProtoSS.stringmap={};
ProtoSS.eventProps=function(event, props){
	var l=props.length,i,p,pu;
	event.eventprops=props;
	for(i=0;i<l;i++){
		p=props[i];
		pu=p.toUpperCase();
		event[pu]=p;
		event[pu+"_CHANGE"]=p+"Change";
	}
	return event;
};
ProtoSS.staticProps=function(stat, props){
	var k;
	for(k in props)stat[k]=props[k];
	return stat;
};
ProtoSS.getDefinitionByName=function(sname, toppack){
	if(!toppack)toppack=window;
	var many=sname.split("|"),
		cls=null,i,sn,tp,s;
	for(i=0;i<many.length;i++){
		sn=many[i];
		tp=toppack;
		s=sn.split("::");
		if (s.length==1){
			cls=tp[s[0]];
			if(cls)return cls;
		}
		cls=tp.package(s[0])[s[1]];
		if(cls)return cls;
	}
	return cls;
};
<commit_msg>Update ProtoSS.js<commit_after>/**
 * Author: Zeta Ret, Ivo Yankulovski
 * Zeta Ret ProtoSS
 * ProtoSS Class/Interface/Header Manager
 * Requires: protoss.all.js v1.04a
 * Version: 1.04c
 * Date: 2017 - Today
**/
window.internal(
function ProtoSS(){
	var o=this,a=arguments;
	o.autoImplement=true;
	o.autoSuper=true;
	o.autoSuperList=true;
	o.autoSuperList2=true;
	o.errorData=null;
	o.debug=null;
	o.super(a);
	var m={};
	m.toInterface=function(i, pack){
		var imap={},key;
		for(key in i){
			if (key=="__name")continue;
			imap[key]=i[key].interface(key);
			if (pack)pack.internal(imap[key]);
		}
		return imap;
	};
	m.stringPattern=function(pat, str, pos){
		if(!pos)pos=0;
		var num=0;
		while(str.indexOf(pat, pos)==pos){
			num++;
			str=str.substr(0,pos)+str.substr(pos+pat.length,str.length);
		}
		return [num,str];
	};
	m.getSuperCls=function(sname, toppack, path){
		var many=sname.split("|"),
			cls=null,i,sn,tp,sp,pathsplit,s;
		for(i=0;i<many.length;i++){
			sn=many[i];
			tp=toppack;
			sp=o.stringPattern("/",sn);
			if (path && sp[0]>0){
				pathsplit=path.split(".");
				tp=tp.package(pathsplit.slice(0, pathsplit.length-sp[0]+1).join("."));
			}
			s=sp[1].split("::");
			if (s.length==1){
				cls=tp[s[0]];
				if(cls)return cls;
			}
			cls=tp.package(s[0])[s[1]];
			if(cls)return cls;
		}
		return cls;
	};
	m.resolveCls=function(s, toppack, path){
		var k,sk,kk,skk,i;
		for(k in s){
			if (k=="__name")continue;
			sk=s[k];
			for(kk in sk){
				skk=sk[kk];
				for(i=0;i<skk.length;i++){
					if (skk[i].constructor==String){
						skk[i]=o.getSuperCls(skk[i], toppack, path);
					}
				}
			}
		}
		return o;
	};
	m.resolveHeaders=function(toppack, path, protoss){
		var i,j,v,vl,c1,c2,sla,ia,sl,sa,ta;
		try{
		if(o.autoImplement){
			ia=[];
			ta=ProtoSS.headerImplement;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.implement(protoss?c2.__protoss||c2:c2);
				else ia.push(v);
			}
			ProtoSS.headerImplement=ia;
		}
		if(o.autoSuper){
			sa=[];
			ta=ProtoSS.headerSuper;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.setSuper(protoss?c2.__protoss||c2:c2);
				else sa.push(v);
			}
			ProtoSS.headerSuper=sa;
		}
		if(o.autoSuperList){
			sla=[];
			ta=ProtoSS.headerSuperList;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(protoss?c2.__protoss||c2:c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList(sl);
				}
			}
			ProtoSS.headerSuperList=sla;
		}
		if(o.autoSuperList2){
			sla=[];
			ta=ProtoSS.headerSuperList2;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(protoss?c2.__protoss||c2:c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList2(sl);
				}
			}
			ProtoSS.headerSuperList2=sla;
		}
		} catch(e){
			o.errorData=[ta,ta[i-1],i,j,v,vl,c1,c2,sla,ia,sl,sa];
			if(o.debug)o.debug("error", "resolveHeaders", o, o.errorData);
			throw(e);
		}

		return o;
	};
	o.superize(a,m,true,true);
	return o;
}
);
ProtoSS.headerImplement=[];
ProtoSS.headerSuper=[];
ProtoSS.headerSuperList=[];
ProtoSS.headerSuperList2=[];
ProtoSS.stringmap={};
ProtoSS.eventProps=function(event, props){
	var l=props.length,i,p,pu;
	event.eventprops=props;
	for(i=0;i<l;i++){
		p=props[i];
		pu=p.toUpperCase();
		event[pu]=p;
		event[pu+"_CHANGE"]=p+"Change";
	}
	return event;
};
ProtoSS.staticProps=function(stat, props){
	var k;
	for(k in props)stat[k]=props[k];
	return stat;
};
ProtoSS.getDefinitionByName=function(sname, toppack){
	if(!toppack)toppack=window;
	var many=sname.split("|"),
		cls=null,i,sn,tp,s;
	for(i=0;i<many.length;i++){
		sn=many[i];
		tp=toppack;
		s=sn.split("::");
		if (s.length==1){
			cls=tp[s[0]];
			if(cls)return cls;
		}
		cls=tp.package(s[0])[s[1]];
		if(cls)return cls;
	}
	return cls;
};
<|endoftext|>


<commit_before>'use strict'

var proxy = {
  proxyType: 'unspecified'
};

if (process.env.http_proxy != undefined && process.env.http_proxy != null){
  proxy = {
    proxyType: 'manual',
    httpProxy: process.env.http_proxy
  }
}

console.log(process.env);

exports.config = {
  directConnect: true,

  allScriptsTimeout: 80000,

  specs: [
    'test/e2e/*.js'
  ],

  capabilities: {
    browserName: 'chrome',
    proxy: proxy
  },

  baseUrl: 'http://localhost:3000',

  framework: 'jasmine2',

  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 90000
  },

  onPrepare: function () {
    var jasmineReporters = require('jasmine-reporters')
    jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
      consolidateAll: true,
      savePath: 'build/reports/e2e_results'
    }))

    // Get cookie consent popup out of the way
    browser.get('/#')
    browser.manage().addCookie({ name: 'cookieconsent_status', value: 'dismiss' })
  }
}

if (process.env.TRAVIS_BUILD_NUMBER) {
  exports.config.capabilities.chromeOptions = {
    args: ['--headless', '--disable-gpu', '--window-size=800,600']
  }
}
<commit_msg>now fix it<commit_after>'use strict'

var proxy = {
  proxyType: 'autodetect'
};

if (process.env.http_proxy != undefined && process.env.http_proxy != null) {
  proxy = {
    proxyType: 'manual',
    httpProxy: process.env.http_proxy
  }
}

exports.config = {
  directConnect: true,

  allScriptsTimeout: 80000,

  specs: [
    'test/e2e/*.js'
  ],

  capabilities: {
    browserName: 'chrome',
    proxy: proxy
  },

  baseUrl: 'http://localhost:3000',

  framework: 'jasmine2',

  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 90000
  },

  onPrepare: function () {
    var jasmineReporters = require('jasmine-reporters')
    jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
      consolidateAll: true,
      savePath: 'build/reports/e2e_results'
    }))

    // Get cookie consent popup out of the way
    browser.get('/#')
    browser.manage().addCookie({ name: 'cookieconsent_status', value: 'dismiss' })
  }
}

if (process.env.TRAVIS_BUILD_NUMBER) {
  exports.config.capabilities.chromeOptions = {
    args: ['--headless', '--disable-gpu', '--window-size=800,600']
  }
}
<|endoftext|>


<commit_before>// TODO(joeltine): Remove promise module when stable node version supports it
// natively.
var Promise = require('promise');
var allTests = require('./alltests');

// Timeout for individual test package to complete.
var TEST_TIMEOUT = 45 * 1000;
var TEST_SERVER = 'http://localhost:8080';
var IGNORED_TESTS = [
  // Test hangs in IE8.
  'closure/goog/ui/plaintextspellchecker_test.html',
  // TODO(joeltine): Re-enable once fixed for external testing.
  'closure/goog/testing/multitestrunner_test.html',
  // These Promise-based tests all timeout for unknown reasons.
  // Disable for now.
  'closure/goog/testing/fs/integration_test.html',
  'closure/goog/debug/fpsdisplay_test.html',
  'closure/goog/net/jsloader_test.html',
  'closure/goog/net/filedownloader_test.html',
  'closure/goog/promise/promise_test.html',
  'closure/goog/editor/plugins/abstractdialogplugin_test.html',
  'closure/goog/net/crossdomainrpc_test.html'
];

describe('Run all Closure unit tests', function() {
  var removeIgnoredTests = function(tests) {
    for (var i = 0; i < IGNORED_TESTS.length; i++) {
      var index = tests.indexOf(IGNORED_TESTS[i]);
      if (index != -1) {
        tests.splice(index, 1);
      }
    }
    return tests;
  };

  beforeAll(function() { allTests = removeIgnoredTests(allTests); });

  beforeEach(function() {
    // Ignores synchronization with angular loading. Since we don't use angular,
    // enable it.
    browser.ignoreSynchronization = true;
  });

  // Polls currently loaded test page for test completion. Returns Promise that
  // will resolve when test is finished.
  var waitForTestSuiteCompletion = function(testPath) {
    var testStartTime = +new Date();

    var waitForTest = function(resolve, reject) {
      // executeScript runs the passed method in the "window" context of
      // the current test. JSUnit exposes hooks into the test's status through
      // the "G_testRunner" global object.
      browser.executeScript(function() {
               if (window['G_testRunner'] &&
                   window['G_testRunner']['isFinished']()) {
                 var status = {};
                 status['isFinished'] = true;
                 status['isSuccess'] = window['G_testRunner']['isSuccess']();
                 status['report'] = window['G_testRunner']['getReport']();
                 return status;
               } else {
                 return {'isFinished': false};
               }
             })
          .then(
              function(status) {
                if (status && status.isFinished) {
                  resolve(status);
                } else {
                  var currTime = +new Date();
                  if (currTime - testStartTime > TEST_TIMEOUT) {
                    status.isSuccess = false;
                    status.report = testPath + ' timed out after ' +
                        (TEST_TIMEOUT / 1000) + 's!';
                    // resolve so tests continue running.
                    resolve(status);
                  } else {
                    // Check every 300ms for completion.
                    setTimeout(
                        waitForTest.bind(undefined, resolve, reject), 300);
                  }
                }
              },
              function(err) { reject(err); });
    };

    return new Promise(function(resolve, reject) {
      waitForTest(resolve, reject);
    });
  };

  it('should run all tests with 0 failures', function(done) {
    var failureReports = [];

    // Navigates to testPath to invoke tests. Upon completion inspects returned
    // test status and keeps track of the total number failed tests.
    var runNextTest = function(testPath) {
      return browser.navigate()
          .to(TEST_SERVER + '/' + testPath)
          .then(function() { return waitForTestSuiteCompletion(testPath); })
          .then(function(status) {
            if (!status.isSuccess) {
              failureReports.push(status.report);
            }

            return status;
          });
    };

    // Chains the next test to the completion of the previous through its
    // promise.
    var chainNextTest = function(promise, test) {
      return promise.then(function() { runNextTest(test); });
    };

    var testPromise = null;
    for (var i = 0; i < allTests.length; i++) {
      if (testPromise != null) {
        testPromise = chainNextTest(testPromise, allTests[i]);
      } else {
        testPromise = runNextTest(allTests[i]);
      }
    }

    testPromise.then(function() {
      var totalFailures = failureReports.length;
      if (totalFailures > 0) {
        console.error('There was ' + totalFailures + ' test failure(s)!');
        for (var i = 0; i < failureReports.length; i++) {
          console.error(failureReports[i]);
        }
      }
      expect(failureReports.length).toBe(0);
      done();
    });
  });
});
<commit_msg>Disable flash_test.html <commit_after>// TODO(joeltine): Remove promise module when stable node version supports it
// natively.
var Promise = require('promise');
var allTests = require('./alltests');

// Timeout for individual test package to complete.
var TEST_TIMEOUT = 45 * 1000;
var TEST_SERVER = 'http://localhost:8080';
var IGNORED_TESTS = [
  // Test hangs in IE8.
  'closure/goog/ui/plaintextspellchecker_test.html',
  // TODO(joeltine): Re-enable once fixed for external testing.
  'closure/goog/testing/multitestrunner_test.html',
  // These Promise-based tests all timeout for unknown reasons.
  // Disable for now.
  'closure/goog/testing/fs/integration_test.html',
  'closure/goog/debug/fpsdisplay_test.html',
  'closure/goog/net/jsloader_test.html',
  'closure/goog/net/filedownloader_test.html',
  'closure/goog/promise/promise_test.html',
  'closure/goog/editor/plugins/abstractdialogplugin_test.html',
  'closure/goog/net/crossdomainrpc_test.html',
  // Causes flaky Adobe Acrobat update popups.
  'closure/goog/useragent/flash_test.html'
];

describe('Run all Closure unit tests', function() {
  var removeIgnoredTests = function(tests) {
    for (var i = 0; i < IGNORED_TESTS.length; i++) {
      var index = tests.indexOf(IGNORED_TESTS[i]);
      if (index != -1) {
        tests.splice(index, 1);
      }
    }
    return tests;
  };

  beforeAll(function() { allTests = removeIgnoredTests(allTests); });

  beforeEach(function() {
    // Ignores synchronization with angular loading. Since we don't use angular,
    // enable it.
    browser.ignoreSynchronization = true;
  });

  // Polls currently loaded test page for test completion. Returns Promise that
  // will resolve when test is finished.
  var waitForTestSuiteCompletion = function(testPath) {
    var testStartTime = +new Date();

    var waitForTest = function(resolve, reject) {
      // executeScript runs the passed method in the "window" context of
      // the current test. JSUnit exposes hooks into the test's status through
      // the "G_testRunner" global object.
      browser.executeScript(function() {
               if (window['G_testRunner'] &&
                   window['G_testRunner']['isFinished']()) {
                 var status = {};
                 status['isFinished'] = true;
                 status['isSuccess'] = window['G_testRunner']['isSuccess']();
                 status['report'] = window['G_testRunner']['getReport']();
                 return status;
               } else {
                 return {'isFinished': false};
               }
             })
          .then(
              function(status) {
                if (status && status.isFinished) {
                  resolve(status);
                } else {
                  var currTime = +new Date();
                  if (currTime - testStartTime > TEST_TIMEOUT) {
                    status.isSuccess = false;
                    status.report = testPath + ' timed out after ' +
                        (TEST_TIMEOUT / 1000) + 's!';
                    // resolve so tests continue running.
                    resolve(status);
                  } else {
                    // Check every 300ms for completion.
                    setTimeout(
                        waitForTest.bind(undefined, resolve, reject), 300);
                  }
                }
              },
              function(err) { reject(err); });
    };

    return new Promise(function(resolve, reject) {
      waitForTest(resolve, reject);
    });
  };

  it('should run all tests with 0 failures', function(done) {
    var failureReports = [];

    // Navigates to testPath to invoke tests. Upon completion inspects returned
    // test status and keeps track of the total number failed tests.
    var runNextTest = function(testPath) {
      return browser.navigate()
          .to(TEST_SERVER + '/' + testPath)
          .then(function() { return waitForTestSuiteCompletion(testPath); })
          .then(function(status) {
            if (!status.isSuccess) {
              failureReports.push(status.report);
            }

            return status;
          });
    };

    // Chains the next test to the completion of the previous through its
    // promise.
    var chainNextTest = function(promise, test) {
      return promise.then(function() { runNextTest(test); });
    };

    var testPromise = null;
    for (var i = 0; i < allTests.length; i++) {
      if (testPromise != null) {
        testPromise = chainNextTest(testPromise, allTests[i]);
      } else {
        testPromise = runNextTest(allTests[i]);
      }
    }

    testPromise.then(function() {
      var totalFailures = failureReports.length;
      if (totalFailures > 0) {
        console.error('There was ' + totalFailures + ' test failure(s)!');
        for (var i = 0; i < failureReports.length; i++) {
          console.error(failureReports[i]);
        }
      }
      expect(failureReports.length).toBe(0);
      done();
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

angular.module('esn.domain', ['restangular', 'ngTagsInput'])
  .factory('domainAPI', ['Restangular', function(Restangular) {

    /**
     * Get the list of members of a domain.
     *
     * @param {String} id
     * @param {Hash} options - Hash with limit (int), offset (int) and search (string)
     */
    function getMembers(id, options) {
      return Restangular.one('domains', id).getList('members', options);
    }

    /**
     * Invite users to join a domain
     *
     * @param {String} id
     * @param {Array} emails - Array of emails (string)
     */
    function inviteUsers(id, emails) {
      return Restangular.one('domains', id).customPOST(emails, 'invitations');
    }

    /**
    * Check if the current user is the manager of the domain.
    * returns HTTP 200 if OK, HTTP 403 if not manager.
    *
    * @param {String} id - The domain id
    */
    function isManager(id) {
      return Restangular.one('domains', id).one('manager').get();
    }

    return {
      getMembers: getMembers,
      inviteUsers: inviteUsers,
      isManager: isManager
    };
  }])
  .controller('inviteMembers', function($scope, domainAPI, domain) {

    $scope.placeholder = 'Add an email';
    $scope.displayProperty = 'email';
    // regexp as string, single \ are \\ escaped, doubles \ are \\\ escaped
    // original regexp is
    // var regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    $scope.pattern = '^(([^<>()[\\\]\\\\\.,;:\\\s@\\\"]+(\\\.[^<>()[\\\]\\\\\.,;:\s@\\\"]+)*)|(\\\".+\\\"))@((\\\[[0-9]{1,3}\\\.[0-9]{1,3}\\\.[0-9]{1,3}\\\.[0-9]{1,3}\\\])|(([a-zA-Z\-0-9]+\\\.)+[a-zA-Z]{2,}))$'; // jshint ignore:line
    $scope.step = 0;
    $scope.domain = domain.name;
    $scope.emails = [];

    $scope.invite = function() {
      var emails = $scope.emails.map(function(element) {
        return element.email;
      });

      domainAPI.inviteUsers(domain._id, emails).then(
        function(data) {
          $scope.error = undefined;
          $scope.step = 1;
        },
        function(err) {
          $scope.error = err;
        }
      );
    };
  });
<commit_msg>OR-201 Explain regex<commit_after>'use strict';

angular.module('esn.domain', ['restangular', 'ngTagsInput'])
  .factory('domainAPI', ['Restangular', function(Restangular) {

    /**
     * Get the list of members of a domain.
     *
     * @param {String} id
     * @param {Hash} options - Hash with limit (int), offset (int) and search (string)
     */
    function getMembers(id, options) {
      return Restangular.one('domains', id).getList('members', options);
    }

    /**
     * Invite users to join a domain
     *
     * @param {String} id
     * @param {Array} emails - Array of emails (string)
     */
    function inviteUsers(id, emails) {
      return Restangular.one('domains', id).customPOST(emails, 'invitations');
    }

    /**
    * Check if the current user is the manager of the domain.
    * returns HTTP 200 if OK, HTTP 403 if not manager.
    *
    * @param {String} id - The domain id
    */
    function isManager(id) {
      return Restangular.one('domains', id).one('manager').get();
    }

    return {
      getMembers: getMembers,
      inviteUsers: inviteUsers,
      isManager: isManager
    };
  }])
  .controller('inviteMembers', function($scope, domainAPI, domain) {

    $scope.placeholder = 'Add an email';
    $scope.displayProperty = 'email';
    // Regular expression to check that the input text is a valid email
    // regexp as string, single \ are \\ escaped, doubles \ are \\\ escaped
    // original regexp is
    // var regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    $scope.pattern = '^(([^<>()[\\\]\\\\\.,;:\\\s@\\\"]+(\\\.[^<>()[\\\]\\\\\.,;:\s@\\\"]+)*)|(\\\".+\\\"))@((\\\[[0-9]{1,3}\\\.[0-9]{1,3}\\\.[0-9]{1,3}\\\.[0-9]{1,3}\\\])|(([a-zA-Z\-0-9]+\\\.)+[a-zA-Z]{2,}))$'; // jshint ignore:line
    $scope.step = 0;
    $scope.domain = domain.name;
    $scope.emails = [];

    $scope.invite = function() {
      var emails = $scope.emails.map(function(element) {
        return element.email;
      });

      domainAPI.inviteUsers(domain._id, emails).then(
        function(data) {
          $scope.error = undefined;
          $scope.step = 1;
        },
        function(err) {
          $scope.error = err;
        }
      );
    };
  });
<|endoftext|>


<commit_before>/*jslint unparam: true, node: true */
"use strict";

var express = require('express'),
    hogan = require('fs-hogan'),
    http = require('http'),
    config = require('./lib/config');
var app = express();

app.set('view engine', 'hjs');
app.engine('hjs', hogan.renderFile);

function getData(body) {
    var data = {};
    try {
        data = {ok: true, data: JSON.parse(body)};
    } catch (error) {
        data = {ok: false, data: error};
    }
    return data;
}

app.get('/work/:id', function (request, response) {

    var parameters = config.get();
    parameters.path = "/work/" + request.params.id;

    http.get(parameters, function (res) {
        var body = '';
        res.on('data', function (chunk) {
            body += chunk;
        });
        res.on('end', function () {
            var data = getData(body);
            if (data.ok) {
                console.log("Received from services for '" + parameters.path + "': " + body);
                response.render('index', data.data);
            } else {
                response.status("404");
                response.render('error', data);
            }
        });
    }).on('error', function (e) {
        console.log("Got error: ", e);
    });
});

var Server = app.listen(8000, function () {
    var host = Server.address().address,
        port = Server.address().port;
    console.log('Server listening at http://%s:%s', host, port);
});<commit_msg>Fix error-handling in patron-client<commit_after>/*jslint unparam: true, node: true */
"use strict";

var express = require('express'),
    hogan = require('fs-hogan'),
    http = require('http'),
    config = require('./lib/config');
var app = express();

app.set('view engine', 'hjs');
app.engine('hjs', hogan.renderFile);

function getData(body) {
    var data = {};
    try {
        data = {ok: true, data: JSON.parse(body)};
    } catch (error) {
        data = {ok: false, data: error};
    }
    return data;
}

app.get('/work/:id', function (request, response) {

    var parameters = config.get();
    parameters.path = "/work/" + request.params.id;

    http.get(parameters, function (res) {
        console.log(res);
        var body = '';
        res.on('data', function (chunk) {
            body += chunk;
        });
        res.on('end', function () {
            var data = getData(body);
            if (data.ok) {
                console.log("Received from services for '" + parameters.path + "': " + body);
                response.render('index', data.data);
            } else {
                response.status(res.statusCode);
                response.render('error', {data: res.statusMessage});
            }
        });
    }).on('error', function (e) {
        console.log("Got error: ", e);
    });
});

var Server = app.listen(8000, function () {
    var host = Server.address().address,
        port = Server.address().port;
    console.log('Server listening at http://%s:%s', host, port);
});<|endoftext|>


<commit_before>/*
    Nodes – Arko's Experiment with HTML5 canvas element
    Author: Loïc Cattani (Arko) <loic.cattani@gmail.com>
    Date: December 2010
*/

var canvas;
var context;
var mouse = { x: 0, y: 0, down: false };
var framerate = 60;
var intervalId; // Will hold the loop reference

function initialize() {
  // Get canvas element
  canvas = document.getElementById('world');

  if (canvas && canvas.getContext) {

    // Get 2D context
    context = canvas.getContext('2d');

    // Register Event Listeners
    canvas.addEventListener('mousedown', mouseDown, false);
    document.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);

    // Initiate Nodes World
    NodesWorld.initialize();

    // Initiate the loop
    start();
  }
}

// Event handler for mouseDown
function mouseDown() {
  mouse.down = true;
  mouseMove();
  event.preventDefault();
}

// Event handler for mouseUp
function mouseUp() {
  mouse.down = false;
  mouseMove();
  pause();
}

// Event handler for mouseMove
function mouseMove() {
  mouse.x = event.clientX - (window.innerWidth - canvas.width) / 2;
  mouse.y = event.clientY - (window.innerHeight - canvas.height) / 2;
}

// Initiate the loop
function start() {
  intervalId = setInterval(loop, 1000/framerate);
}

// Clear the loop
function pause() {
  clearInterval(intervalId);
}

// The loop
function loop() {
  NodesWorld.update();
  NodesWorld.draw();
}

var NodesWorld = new function () {
  // Physics
  this.boundaries = { x: 0, y: 0, width: 940, height: 660 };
  this.drag = 0.002; // Good val: 0.002
  this.gravity = { force: 0.2, direction: Math.PI/2 }; // Good force: 0.2

  // Content
  this.node_count = 10;
  this.nodes = new Array();

  this.initialize = function() {
    // Transform gravity to a force vector
    this.gravity = new Vector(this.gravity.force, this.gravity.direction);

    // Fill world with randomly positionned nodes
    for (var i = this.node_count - 1; i >= 0; i--){
      node = new Point(Math.random() * this.boundaries.width, Math.random() * this.boundaries.height);
      this.nodes.push(node);
    }
  }

  // Update world's objects
  this.update = function () {
    // Update nodes
    for( var i = 0, len = this.nodes.length; i < len; i++ ) {
      node = this.nodes[i];
      node.update(this.drag, this.gravity);
    }
  }

  // Draw world
  this.draw = function () {

    // Clear world
    context.fillStyle = "rgba(0,0,0,1)";
    context.fillRect(this.boundaries.x, this.boundaries.y, this.boundaries.width, this.boundaries.height);

    // Draw nodes
    for( var i = 0, len = this.nodes.length; i < len; i++ ) {
      node = this.nodes[i];
      context.beginPath();
      context.arc( node.x, node.y, node.radius, 0, Math.PI*2, true );
      context.fillStyle = node.fillcolor;
      context.strokeStyle = node.strokecolor;
      context.lineWidth = 2;
      context.fill();
      context.stroke();
    }
  }
}

/* Defines a point in a 2D space */
function Point (x, y) {
  this.x = x || 0;
  this.y = y || 0;
  this.velocity = new Vector();
  this.mass = 1; // Can't be 0!
  this.bounce_damp = 0.8;
  this.radius = 8;
  this.fillcolor = 'rgba(0,160,255,0.3)';
  this.strokecolor = 'rgba(0,160,255,1)';
}

// Update a point's position, optionally applying a drag and a force
Point.prototype.update = function (d, f) {
  this.drag(d);
  this.applyForce(f);
  this.x += this.velocity.x;
  this.y += this.velocity.y;
  this.checkCollisions();
}

Point.prototype.drag = function (d) {
  d = d || 0;
  this.velocity.setMagnitude(this.velocity.magnitude * ( 1 - d ));
}

Point.prototype.applyForce = function (f) {
  f = f || new Vector();
  this.velocity.setX( this.velocity.x + f.x / this.mass );
  this.velocity.setY( this.velocity.y + f.y / this.mass );
}

Point.prototype.speed = function () {
  return this.velocity.magnitude;
}

Point.prototype.checkCollisions = function () {
  // Check World's Boundaries Collisions
  bx = NodesWorld.boundaries.x + this.radius;
  bw = NodesWorld.boundaries.width - this.radius;
  by = NodesWorld.boundaries.y + this.radius;
  bh = NodesWorld.boundaries.height - this.radius;

  if (this.x < bx || this.x > bw) {
    this.velocity.setX(this.velocity.x * -this.bounce_damp);
    if (this.x < bx)
      this.x += 2 * (bx - this.x)
    if (this.x > bw)
      this.x += 2 * (bw - this.x)
  }

  if (this.y < by || this.y > bh) {
    this.velocity.setY(this.velocity.y * -this.bounce_damp);
    if (this.y < by)
      this.y += 2 * (by - this.y)
    if (this.y > bh)
      this.y += 2 * (bh - this.y)
  }
}

/* Defines a vector in a 2D space */
function Vector (m, a) {
  this.magnitude = m || 0;
  this.angle = a || 0;
  this.x = 0;
  this.y = 0;
  this.updateXY();
}

Vector.prototype.setX = function (x) {
  this.x = x || 0;
  this.updateMA();
}

Vector.prototype.setY = function (y) {
  this.y = y || 0;
  this.updateMA();
}

Vector.prototype.setMagnitude = function (m) {
  this.magnitude = m || 0;
  this.updateXY();
}

Vector.prototype.setAngle = function (a) {
  this.angle = a || 0;
  this.updateXY();
}

Vector.prototype.updateMA = function () {
  x = this.x;
  y = this.y;
  this.magnitude = Math.sqrt(x*x + y*y);
  this.angle = Math.atan2(y,x);
}

Vector.prototype.updateXY = function () {
  this.x = this.magnitude * Math.cos(this.angle);
  this.y = this.magnitude * Math.sin(this.angle);
}

initialize();
<commit_msg>Added some comments<commit_after>/*
    Nodes – Arko's Experiment with HTML5 canvas element
    Author: Loïc Cattani (Arko) <loic.cattani@gmail.com>
    Date: December 2010
*/

var canvas;
var context;
var mouse = { x: 0, y: 0, down: false };
var framerate = 60;
var intervalId; // Will hold the loop reference

function initialize() {

  // Get the canvas element
  canvas = document.getElementById('world');

  if (canvas && canvas.getContext) {

    // Get 2D context
    context = canvas.getContext('2d');

    // Register Event Listeners
    canvas.addEventListener('mousedown', mouseDown, false);
    document.addEventListener('mouseup', mouseUp, false);
    canvas.addEventListener('mousemove', mouseMove, false);

    // Initiate Nodes World
    NodesWorld.initialize();

    // Initiate the loop
    start();
  }
}

// Event handler for mouseDown
function mouseDown() {
  mouse.down = true;
  mouseMove();
  event.preventDefault();
}

// Event handler for mouseUp
function mouseUp() {
  mouse.down = false;
  mouseMove();
  pause();
}

// Event handler for mouseMove
function mouseMove() {
  mouse.x = event.clientX - (window.innerWidth - canvas.width) / 2;
  mouse.y = event.clientY - (window.innerHeight - canvas.height) / 2;
}

// Initiate the loop
function start() {
  intervalId = setInterval(loop, 1000/framerate);
}

// Clear the loop
function pause() {
  clearInterval(intervalId);
}

// The loop
function loop() {
  NodesWorld.update();
  NodesWorld.draw();
}

var NodesWorld = new function () {
  // Physics
  this.boundaries = { x: 0, y: 0, width: 940, height: 660 };
  this.drag = 0.002; // Good val: 0.002
  this.gravity = { force: 0.2, direction: Math.PI/2 }; // Good force: 0.2 Direction: Math.PI/2 rad => 90° from +x axis CW

  // Content
  this.node_count = 10;
  this.nodes = new Array();

  this.initialize = function() {
    // Transform gravity to a force vector
    this.gravity = new Vector(this.gravity.force, this.gravity.direction);

    // Fill world with randomly positionned nodes
    for (var i = this.node_count - 1; i >= 0; i--){
      node = new Point(Math.random() * this.boundaries.width, Math.random() * this.boundaries.height);
      this.nodes.push(node);
    }
  }

  // Update world's objects
  this.update = function () {
    // Update nodes
    for( var i = 0, len = this.nodes.length; i < len; i++ ) {
      node = this.nodes[i];
      node.update(this.drag, this.gravity);
    }
  }

  // Draw world
  this.draw = function () {

    // Clear world
    context.fillStyle = "rgba(0,0,0,1)";
    context.fillRect(this.boundaries.x, this.boundaries.y, this.boundaries.width, this.boundaries.height);

    // Draw nodes
    for( var i = 0, len = this.nodes.length; i < len; i++ ) {
      node = this.nodes[i];
      context.beginPath();
      context.arc( node.x, node.y, node.radius, 0, Math.PI*2, true );
      context.fillStyle = node.fillcolor;
      context.strokeStyle = node.strokecolor;
      context.lineWidth = 2;
      context.fill();
      context.stroke();
    }
  }
}

/* Defines a point in a 2D space */
function Point (x, y) {
  this.x = x || 0;
  this.y = y || 0;
  this.velocity = new Vector();
  this.mass = 1; // Can't be 0!
  this.bounce_damp = 0.8;
  this.radius = 8;
  this.fillcolor = 'rgba(0,160,255,0.3)';
  this.strokecolor = 'rgba(0,160,255,1)';
}

/* Update a point's position, optionally applying a drag and a force */
Point.prototype.update = function (d, f) {
  this.drag(d);
  this.applyForce(f);
  this.x += this.velocity.x;
  this.y += this.velocity.y;
  this.checkCollisions();
}

/* Apply the given drag as a coefficient */
Point.prototype.drag = function (d) {
  d = d || 0;
  this.velocity.setMagnitude(this.velocity.magnitude * ( 1 - d ));
}

/* Apply the given force as a vector */
Point.prototype.applyForce = function (f) {
  f = f || new Vector();
  this.velocity.setX( this.velocity.x + f.x / this.mass );
  this.velocity.setY( this.velocity.y + f.y / this.mass );
}

/* Returns the speed in pixels per time interval */
Point.prototype.speed = function () {
  return this.velocity.magnitude;
}

/* Check World's Boundaries Collisions */
Point.prototype.checkCollisions = function () {
  bx = NodesWorld.boundaries.x + this.radius;
  bw = NodesWorld.boundaries.width - this.radius;
  by = NodesWorld.boundaries.y + this.radius;
  bh = NodesWorld.boundaries.height - this.radius;

  // Check if the point's position is outside the x-axis boundaries
  if (this.x < bx || this.x > bw) {
     // Reverse and damp x velocity
    this.velocity.setX(this.velocity.x * -this.bounce_damp);
    if (this.x < bx)
      this.x += 2 * (bx - this.x)
    if (this.x > bw)
      this.x += 2 * (bw - this.x)
  }

  if (this.y < by || this.y > bh) {
     // Reverse and damp y velocity
    this.velocity.setY(this.velocity.y * -this.bounce_damp);
    if (this.y < by)
      this.y += 2 * (by - this.y)
    if (this.y > bh)
      this.y += 2 * (bh - this.y)
  }
}

/* Defines a vector in a 2D space */
function Vector (m, a) {
  this.magnitude = m || 0;
  this.angle = a || 0;
  this.x = 0;
  this.y = 0;
  this.updateXY();
}

Vector.prototype.setX = function (x) {
  this.x = x || 0;
  this.updateMA();
}

Vector.prototype.setY = function (y) {
  this.y = y || 0;
  this.updateMA();
}

Vector.prototype.setMagnitude = function (m) {
  this.magnitude = m || 0;
  this.updateXY();
}

Vector.prototype.setAngle = function (a) {
  this.angle = a || 0;
  this.updateXY();
}

Vector.prototype.updateMA = function () {
  x = this.x;
  y = this.y;
  this.magnitude = Math.sqrt(x*x + y*y);
  this.angle = Math.atan2(y,x);
}

Vector.prototype.updateXY = function () {
  this.x = this.magnitude * Math.cos(this.angle);
  this.y = this.magnitude * Math.sin(this.angle);
}

initialize();
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

// Services
import WidgetsService from 'services/WidgetsService';
import DatasetsService from 'services/DatasetsService';

import { toastr } from 'react-redux-toastr';

// Constants
import { STATE_DEFAULT, FORM_ELEMENTS } from 'components/admin/widgets/form/constants';

// Components
import Navigation from 'components/form/Navigation';
import Step1 from 'components/admin/widgets/form/steps/Step1';
import Spinner from 'components/ui/Spinner';

class WidgetsForm extends React.Component {
  constructor(props) {
    super(props);

    const formObj = props.dataset ?
      Object.assign({}, STATE_DEFAULT.form, { dataset: props.dataset }) :
      STATE_DEFAULT.form;

    this.state = Object.assign({}, STATE_DEFAULT, {
      id: props.id,
      loading: !!props.id,
      form: formObj
    });

    // BINDINGS
    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
    this.onStepChange = this.onStepChange.bind(this);

    this.service = new WidgetsService({
      authorization: props.authorization
    });

    this.datasetsService = new DatasetsService({
      authorization: props.authorization
    });
  }

  componentDidMount() {
    const { id } = this.state;

    const promises = [
      this.datasetsService.fetchAllData({})
    ];

    // Add the dashboard promise if the id exists
    if (id) {
      promises.push(this.service.fetchData({ id }));
    }

    Promise.all(promises)
      .then((response) => {
        const datasets = response[0];
        const current = response[1];

        this.setState({
          // CURRENT DASHBOARD
          form: (id) ? this.setFormFromParams(current) : this.state.form,
          loading: false,
          // OPTIONS
          datasets: datasets.map(p => ({ label: p.name, value: p.id }))
        });
      })
      .catch((err) => {
        console.error(err);
      });
  }

  /**
   * UI EVENTS
   * - onSubmit
   * - onChange
  */
  onSubmit(event) {
    event.preventDefault();

    // Validate the form
    FORM_ELEMENTS.validate(this.state.step);

    // Set a timeout due to the setState function of react
    setTimeout(() => {
      // Validate all the inputs on the current step
      const valid = FORM_ELEMENTS.isValid(this.state.step);

      if (valid) {
        // if we are in the last step we will submit the form
        if (this.state.step === this.state.stepLength && !this.state.submitting) {
          const { id } = this.state;

          // Start the submitting
          this.setState({ submitting: true });

          // Save data
          this.service.saveData({
            dataset: this.state.form.dataset,
            id: id || '',
            type: (id) ? 'PATCH' : 'POST',
            body: this.state.form
          })
            .then((data) => {
              toastr.success('Success', `The widget "${data.id}" - "${data.name}" has been uploaded correctly`);

              if (this.props.onSubmit) this.props.onSubmit();
            })
            .catch((err) => {
              this.setState({ submitting: false });
              toastr.error('Error', `Oops! There was an error, try again`);
              console.error(err);
            });
        } else {
          this.setState({
            step: this.state.step + 1
          }, () => console.info(this.state));
        }
      } else {
        toastr.error('Error', 'Fill all the required fields');
      }
    }, 0);
  }

  onChange(obj) {
    const form = Object.assign({}, this.state.form, obj);
    this.setState({ form }, () => console.info(this.state.form));
  }

  onStepChange(step) {
    this.setState({ step });
  }

  // HELPERS
  setFormFromParams(params) {
    const newForm = {};

    Object.keys(params).forEach((f) => {
      switch (f) {
        default: {
          if ((typeof params[f] !== 'undefined' || params[f] !== null) ||
              (typeof this.state.form[f] !== 'undefined' || this.state.form[f] !== null)) {
            newForm[f] = params[f] || this.state.form[f];
          }
        }
      }
    });

    return newForm;
  }

  render() {
    return (
      <form className="c-form" onSubmit={this.onSubmit} noValidate>
        <Spinner isLoading={this.state.loading} className="-light" />

        {(this.state.step === 1 && !this.state.loading) &&
          <Step1
            id={this.state.id}
            form={this.state.form}
            partners={this.state.partners}
            datasets={this.state.datasets}
            onChange={value => this.onChange(value)}
          />
        }

        {!this.state.loading &&
          <Navigation
            step={this.state.step}
            stepLength={this.state.stepLength}
            submitting={this.state.submitting}
            onStepChange={this.onStepChange}
          />
        }
      </form>
    );
  }
}

WidgetsForm.propTypes = {
  authorization: PropTypes.string,
  id: PropTypes.string,
  onSubmit: PropTypes.func,
  dataset: PropTypes.string // ID of the dataset that should be pre-selected
};

export default WidgetsForm;
<commit_msg>remove log calls in WidgetForm, replace them by toastr calls when necessary<commit_after>import React from 'react';
import PropTypes from 'prop-types';

// Services
import WidgetsService from 'services/WidgetsService';
import DatasetsService from 'services/DatasetsService';

import { toastr } from 'react-redux-toastr';

// Constants
import { STATE_DEFAULT, FORM_ELEMENTS } from 'components/admin/widgets/form/constants';

// Components
import Navigation from 'components/form/Navigation';
import Step1 from 'components/admin/widgets/form/steps/Step1';
import Spinner from 'components/ui/Spinner';

class WidgetsForm extends React.Component {
  constructor(props) {
    super(props);

    const formObj = props.dataset ?
      Object.assign({}, STATE_DEFAULT.form, { dataset: props.dataset }) :
      STATE_DEFAULT.form;

    this.state = Object.assign({}, STATE_DEFAULT, {
      id: props.id,
      loading: !!props.id,
      form: formObj
    });

    // BINDINGS
    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
    this.onStepChange = this.onStepChange.bind(this);

    this.service = new WidgetsService({
      authorization: props.authorization
    });

    this.datasetsService = new DatasetsService({
      authorization: props.authorization
    });
  }

  componentDidMount() {
    const { id } = this.state;

    const promises = [
      this.datasetsService.fetchAllData({})
    ];

    // Add the dashboard promise if the id exists
    if (id) {
      promises.push(this.service.fetchData({ id }));
    }

    Promise.all(promises)
      .then((response) => {
        const datasets = response[0];
        const current = response[1];

        this.setState({
          // CURRENT DASHBOARD
          form: (id) ? this.setFormFromParams(current) : this.state.form,
          loading: false,
          // OPTIONS
          datasets: datasets.map(p => ({ label: p.name, value: p.id }))
        });
      })
      .catch((err) => {
        toastr.error(err);
      });
  }

  /**
   * UI EVENTS
   * - onSubmit
   * - onChange
  */
  onSubmit(event) {
    event.preventDefault();

    // Validate the form
    FORM_ELEMENTS.validate(this.state.step);

    // Set a timeout due to the setState function of react
    setTimeout(() => {
      // Validate all the inputs on the current step
      const valid = FORM_ELEMENTS.isValid(this.state.step);

      if (valid) {
        // if we are in the last step we will submit the form
        if (this.state.step === this.state.stepLength && !this.state.submitting) {
          const { id } = this.state;

          // Start the submitting
          this.setState({ submitting: true });

          // Save data
          this.service.saveData({
            dataset: this.state.form.dataset,
            id: id || '',
            type: (id) ? 'PATCH' : 'POST',
            body: this.state.form
          })
            .then((data) => {
              toastr.success('Success', `The widget "${data.id}" - "${data.name}" has been uploaded correctly`);

              if (this.props.onSubmit) this.props.onSubmit();
            })
            .catch((err) => {
              this.setState({ submitting: false });
              toastr.error('Error', `Oops! There was an error, try again. ${err}`);
            });
        } else {
          this.setState({
            step: this.state.step + 1
          });
        }
      } else {
        toastr.error('Error', 'Fill all the required fields');
      }
    }, 0);
  }

  onChange(obj) {
    const form = Object.assign({}, this.state.form, obj);
    this.setState({ form });
  }

  onStepChange(step) {
    this.setState({ step });
  }

  // HELPERS
  setFormFromParams(params) {
    const newForm = {};

    Object.keys(params).forEach((f) => {
      switch (f) {
        default: {
          if ((typeof params[f] !== 'undefined' || params[f] !== null) ||
              (typeof this.state.form[f] !== 'undefined' || this.state.form[f] !== null)) {
            newForm[f] = params[f] || this.state.form[f];
          }
        }
      }
    });

    return newForm;
  }

  render() {
    return (
      <form className="c-form" onSubmit={this.onSubmit} noValidate>
        <Spinner isLoading={this.state.loading} className="-light" />

        {(this.state.step === 1 && !this.state.loading) &&
          <Step1
            id={this.state.id}
            form={this.state.form}
            partners={this.state.partners}
            datasets={this.state.datasets}
            onChange={value => this.onChange(value)}
          />
        }

        {!this.state.loading &&
          <Navigation
            step={this.state.step}
            stepLength={this.state.stepLength}
            submitting={this.state.submitting}
            onStepChange={this.onStepChange}
          />
        }
      </form>
    );
  }
}

WidgetsForm.propTypes = {
  authorization: PropTypes.string,
  id: PropTypes.string,
  onSubmit: PropTypes.func,
  dataset: PropTypes.string // ID of the dataset that should be pre-selected
};

export default WidgetsForm;
<|endoftext|>