<commit_before>/**
 * david
 * https://github.com/alanshaw/david
 *
 * Copyright (c) 2013 Alan Shaw
 * Licensed under the MIT license.
 */

var events = require('events');
var npm = require('npm');
var moment = require('moment');
var semver = require('semver');
var semverext = require('./semverext');

// Give this module ability to emit events (and for others to listen)
var exports = new events.EventEmitter();

function Package(name, stable, latest) {
	this.name = name;
	this.stable = stable;
	this.latest = latest;
	this.expires = moment().add(Package.TTL);
}

Package.TTL = moment.duration({days: 1});

/**
 * Cache of the npm packages that projects depend on. Keyed by package name.
 */
var dependencies = {};

/**
 * Get a package for a given dependency name, guaranteed to be less old than Package.TTL
 *
 * @param {String} pkgName
 * @param {Function<Error, Package>} callback
 */
function getDependency(pkgName, callback) {

	process.nextTick(function() {

		var dep = dependencies[pkgName];

		if(dep && dep.expires > new Date()) {
			callback(null, dep);
			return;
		}

		npm.load({}, function(err) {

			if(err) {
				callback(err);
				return;
			}

			npm.commands.view([pkgName, 'versions'], true, function(err, data) {

				if(err) {
					callback(err);
					return;
				}

				// Get the latest dep in this tick (as it might have been updated in a tick between when it was first assigned and now)
				dep = dependencies[pkgName];

				var latest = Object.keys(data)[0],
					versions = data[latest].versions,
					stable = getLatestStable(versions),
					oldStable = dep ? dep.stable : undefined,
					oldLatest = dep ? dep.latest : undefined;

				dep = dependencies[pkgName] = new Package(pkgName, stable, latest);

				if(oldStable != stable) {
					exports.emit('stableVersionChange', pkgName, oldStable, stable);
				}

				if(oldLatest != latest) {
					exports.emit('latestVersionChange', pkgName, oldLatest, latest);
				}

				callback(null, dep);
			});
		});
	});
}

/**
 * Determine if a version is a stable version or not.
 *
 * @param {String} version
 * @return {Boolean}
 */
function isStable(version) {
	return !(/[a-z+\-]/i.test(version || ''));
}

/**
 * Get the latest stable version from a list of versions in ascending order.
 *
 * @param {Array<String>} versions
 * @return {String}
 */
function getLatestStable(versions) {

	versions = versions.slice();

	while(versions.length) {

		var version = versions.pop();

		if(isStable(version)) {
			return version;
		}
	}

	return null;
}

/**
 * Get a list of dependencies for the passed manifest.
 *
 * @param {Object} manifest Parsed package.json file contents
 * @param {Object|Function<Error, Object>} [options] Options or callback
 * @param {Boolean} [options.dev] Consider devDependencies
 * @param {Function<Error, Object>} callback Function that receives the results
 */
exports.getDependencies = function(manifest, options, callback) {

	process.nextTick(function() {

		// Allow callback to be passed as second parameter
		if(!callback) {
			callback = options;
			options = {};
		} else {
			options = options || {};
		}

		var pkgs = {};
		var deps = manifest[options.dev ? 'devDependencies' : 'dependencies'] || {};
		var depNames = Object.keys(deps);

		if(!depNames.length) {
			callback(null, pkgs);
			return;
		}

		var processedDeps = 0;

		depNames.forEach(function(depName) {

			getDependency(depName, function(err, dep) {

				processedDeps++;

				if(err) {
					console.log('Failed to get dependency', depName, err);
				} else {
					pkgs[depName] = {required: deps[depName], stable: dep.stable, latest: dep.latest};
				}

				if(processedDeps == depNames.length) {
					callback(null, pkgs);
				}
			});
		});
	});
};

/**
 * Get a list of updated packages for the passed manifest.
 *
 * @param {Object} manifest Parsed package.json file contents
 * @param {Object|Function<Error, Object>} [options] Options or callback
 * @param {Boolean} [options.stable] Consider only stable packages
 * @param {Boolean} [options.dev] Consider devDependencies
 * @param {Function<Error, Object>} callback Function that receives the results
 */
exports.getUpdatedDependencies = function(manifest, options, callback) {

	process.nextTick(function() {

		// Allow callback to be passed as second parameter
		if(!callback) {
			callback = options;
			options = {};
		} else {
			options = options || {};
		}

		var updatedPkgs = {};
		var deps = manifest[options.dev ? 'devDependencies' : 'dependencies'] || {};
		var depNames = Object.keys(deps);

		if(!depNames.length) {
			callback(null, updatedPkgs);
			return;
		}

		var processedDeps = 0;

		depNames.forEach(function(depName) {

			getDependency(depName, function(err, dep) {

				processedDeps++;

				if(err) {

					console.log('Failed to get dependency', depName, err);

				} else {

					var pkgDepVersion = deps[depName] || '*';

					// TODO: Handle tags correctly
					if(pkgDepVersion != 'latest' && pkgDepVersion != '*') {

						var range = semver.validRange(pkgDepVersion) || '';
						var version = options.stable ? dep.stable : dep.latest;
						var addToUpdatedPkgs = false;

						if(version) {

							if(!range) {

								addToUpdatedPkgs = true;

							} else if(!semver.satisfies(version, range)) {

								if(options.stable && semverext.gtr(version, range)) {

									addToUpdatedPkgs = true;

								} else if(!options.stable) {

									addToUpdatedPkgs = true;
								}
							}
						}

						if(addToUpdatedPkgs) {
							updatedPkgs[depName] = {required: pkgDepVersion, stable: dep.stable, latest: dep.latest};
						}
					}
				}

				if(processedDeps == depNames.length) {
					callback(null, updatedPkgs);
				}
			});
		});
	});
};

/**
 * Set the TTL for cached packages.
 *
 * @param {moment.duration} duration Time period the packages will be cacched for, expressed as a moment.duration.
 */
exports.setCacheDuration = function(duration) {
	Package.TTL = duration;
};

module.exports = exports;
<commit_msg>Added helper function to cache dependencies and manage the cache.<commit_after>/**
 * david
 * https://github.com/alanshaw/david
 *
 * Copyright (c) 2013 Alan Shaw
 * Licensed under the MIT license.
 */

var events = require('events');
var npm = require('npm');
var moment = require('moment');
var semver = require('semver');
var semverext = require('./semverext');

// Give this module ability to emit events (and for others to listen)
var exports = new events.EventEmitter();

function Package(name, stable, latest) {
	this.name = name;
	this.stable = stable;
	this.latest = latest;
	this.expires = moment().add(Package.TTL);
}

Package.TTL = moment.duration({days: 1});

var dependencies = {}; // Cache of the npm packages that projects depend on. Keyed by package name.
var dependenciesCount = 0; // The current number of dependencies in the cache
var maxDependencies = Infinity; // The maximum number of dependencies allowed in the cache

/**
 * Cache a dependency if maxDependencies > 0.
 *
 * @param {Package} dep
 * @return {Package} The cached dependency
 */
function cacheDependency(dep) {

	// Do we cache?
	if(maxDependencies > 0) {

		// Is it a new entry?
		if(!dependencies[dep.name]) {

			// Have we cached too many?
			if(dependenciesCount + 1 > maxDependencies) {

				var foundExpired = false,
					depNames = Object.keys(dependencies),
					now = new Date(),
					oldestDepName = depNames[0];

				// Find an expired dependency to remove from the cache
				for(var i = 0, len = depNames.length; i < len; ++i) {

					if(dependencies[depNames[i]].expires < now) {
						foundExpired = true;
						delete dependencies[depNames[i]];
						break;
					} else if(dependencies[depNames[i]].expires < dependencies[oldestDepName].expires) {
						// Keep track of the oldest dependency incase we don't find an expired dependency
						oldestDepName = depNames;
					}
				}

				if(!foundExpired) {
					delete dependencies[oldestDepName];
				}

			} else {
				dependenciesCount++;
			}
		}
	}

	return dependencies[dep.name] = dep;
}

/**
 * Get a package for a given dependency name, guaranteed to be less old than Package.TTL
 *
 * @param {String} pkgName
 * @param {Function<Error, Package>} callback
 */
function getDependency(pkgName, callback) {

	process.nextTick(function() {

		var dep = dependencies[pkgName];

		if(dep && dep.expires > new Date()) {
			callback(null, dep);
			return;
		}

		npm.load({}, function(err) {

			if(err) {
				callback(err);
				return;
			}

			npm.commands.view([pkgName, 'versions'], true, function(err, data) {

				if(err) {
					callback(err);
					return;
				}

				// Get the latest dep in this tick (as it might have been updated in a tick between when it was first assigned and now)
				dep = dependencies[pkgName];

				var latest = Object.keys(data)[0],
					versions = data[latest].versions,
					stable = getLatestStable(versions),
					oldStable = dep ? dep.stable : undefined,
					oldLatest = dep ? dep.latest : undefined;

				dep = cacheDependency(new Package(pkgName, stable, latest));

				if(oldStable != stable) {
					exports.emit('stableVersionChange', pkgName, oldStable, stable);
				}

				if(oldLatest != latest) {
					exports.emit('latestVersionChange', pkgName, oldLatest, latest);
				}

				callback(null, dep);
			});
		});
	});
}

/**
 * Determine if a version is a stable version or not.
 *
 * @param {String} version
 * @return {Boolean}
 */
function isStable(version) {
	return !(/[a-z+\-]/i.test(version || ''));
}

/**
 * Get the latest stable version from a list of versions in ascending order.
 *
 * @param {Array<String>} versions
 * @return {String}
 */
function getLatestStable(versions) {

	versions = versions.slice();

	while(versions.length) {

		var version = versions.pop();

		if(isStable(version)) {
			return version;
		}
	}

	return null;
}

/**
 * Get a list of dependencies for the passed manifest.
 *
 * @param {Object} manifest Parsed package.json file contents
 * @param {Object|Function<Error, Object>} [options] Options or callback
 * @param {Boolean} [options.dev] Consider devDependencies
 * @param {Function<Error, Object>} callback Function that receives the results
 */
exports.getDependencies = function(manifest, options, callback) {

	process.nextTick(function() {

		// Allow callback to be passed as second parameter
		if(!callback) {
			callback = options;
			options = {};
		} else {
			options = options || {};
		}

		var pkgs = {};
		var deps = manifest[options.dev ? 'devDependencies' : 'dependencies'] || {};
		var depNames = Object.keys(deps);

		if(!depNames.length) {
			callback(null, pkgs);
			return;
		}

		var processedDeps = 0;

		depNames.forEach(function(depName) {

			getDependency(depName, function(err, dep) {

				processedDeps++;

				if(err) {
					console.log('Failed to get dependency', depName, err);
				} else {
					pkgs[depName] = {required: deps[depName], stable: dep.stable, latest: dep.latest};
				}

				if(processedDeps == depNames.length) {
					callback(null, pkgs);
				}
			});
		});
	});
};

/**
 * Get a list of updated packages for the passed manifest.
 *
 * @param {Object} manifest Parsed package.json file contents
 * @param {Object|Function<Error, Object>} [options] Options or callback
 * @param {Boolean} [options.stable] Consider only stable packages
 * @param {Boolean} [options.dev] Consider devDependencies
 * @param {Function<Error, Object>} callback Function that receives the results
 */
exports.getUpdatedDependencies = function(manifest, options, callback) {

	process.nextTick(function() {

		// Allow callback to be passed as second parameter
		if(!callback) {
			callback = options;
			options = {};
		} else {
			options = options || {};
		}

		var updatedPkgs = {};
		var deps = manifest[options.dev ? 'devDependencies' : 'dependencies'] || {};
		var depNames = Object.keys(deps);

		if(!depNames.length) {
			callback(null, updatedPkgs);
			return;
		}

		var processedDeps = 0;

		depNames.forEach(function(depName) {

			getDependency(depName, function(err, dep) {

				processedDeps++;

				if(err) {

					console.log('Failed to get dependency', depName, err);

				} else {

					var pkgDepVersion = deps[depName] || '*';

					// TODO: Handle tags correctly
					if(pkgDepVersion != 'latest' && pkgDepVersion != '*') {

						var range = semver.validRange(pkgDepVersion) || '';
						var version = options.stable ? dep.stable : dep.latest;
						var addToUpdatedPkgs = false;

						if(version) {

							if(!range) {

								addToUpdatedPkgs = true;

							} else if(!semver.satisfies(version, range)) {

								if(options.stable && semverext.gtr(version, range)) {

									addToUpdatedPkgs = true;

								} else if(!options.stable) {

									addToUpdatedPkgs = true;
								}
							}
						}

						if(addToUpdatedPkgs) {
							updatedPkgs[depName] = {required: pkgDepVersion, stable: dep.stable, latest: dep.latest};
						}
					}
				}

				if(processedDeps == depNames.length) {
					callback(null, updatedPkgs);
				}
			});
		});
	});
};

/**
 * Set the TTL for cached packages.
 *
 * @param {moment.duration} duration Time period the packages will be cacched for, expressed as a moment.duration.
 */
exports.setCacheDuration = function(duration) {
	Package.TTL = duration;
};

/**
 * Set the maximum number of dependencies that can be stored in the cache.
 *
 * @param {Integer} size
 */
exports.setCacheSize = function(size) {
	maxDependencies = size;
};

module.exports = exports;
<|endoftext|>


<commit_before>/* jshint indent: 2 */

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('pedidos', {
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true
        },
        usuariosId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            references: {
                model: 'usuarios',
                key: 'id'
            }
        },
        grupoDeMesaId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            references: {
                model: 'gruposDeMesas',
                key: 'id'
            }
        },
        pedidoEstadoId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            references: {
                model: 'pedidoEstado',
                key: 'id'
            }
        }
    }, {
        tableName: 'pedidos'
    });
};
<commit_msg>cambio de nombre de atributo grupodemesaid a grupoDeMesasId<commit_after>/* jshint indent: 2 */

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('pedidos', {
        id: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            primaryKey: true,
            autoIncrement: true
        },
        usuariosId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            references: {
                model: 'usuarios',
                key: 'id'
            }
        },
        grupoDeMesasId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            references: {
                model: 'gruposDeMesas',
                key: 'id'
            }
        },
        pedidoEstadoId: {
            type: DataTypes.INTEGER(11),
            allowNull: false,
            references: {
                model: 'pedidoEstado',
                key: 'id'
            }
        }
    }, {
        tableName: 'pedidos'
    });
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

/**
 * Deploy helper based on the deploy script
 */

const inquirer = require('inquirer');
const chalk = require('chalk');
const execa = require('execa');
const SEMVER_REGEX = /^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/;

function createLogger() {
  const ui = new inquirer.ui.BottomBar();

  return function (msg) {
    ui.log.write(chalk.green(msg));
  }
}

async function main() {
  try {
    log = createLogger();
    const { haveCheckedDocs, newVersion } = await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveCheckedDocs',
        message: 'Have you checked that docs are up to date? (settings options, pre request script API, supported languages)',
        default: false,
      },
      {
        type: 'input',
        name: 'newVersion',
        message: 'What is the new version?',
        validate: function (value) {
          if (value.match(SEMVER_REGEX)) {
            return true;
          }

          return 'Please enter a valid version (e.g. 3.2.1)';
        },
      },
    ]);

    if (!haveCheckedDocs) {
      log('Check docs and try again.');
      return;
    }

    log('Making sure local repo is up to date...');
    // TODO: checkout staging
    // await syncRepo();
    log('Running tests...');
    // await runTests();
    log('Updating version in files...');
    await updateVersion(newVersion);
    log('Building browser extensions...');
    await buildExtensions();
    log('Now you can verify that the extensions work as expected. (You can verify firefox using ./bin/run_ext_firefox.sh)');
    const { haveVerifiedExtensions } = await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Have you checked that the extension builds work as expected?',
        default: true,
      },
    ]);
    log('Creating upgrade commit...');
    await createVersionCommit(newVersion);
    log('Syncing with remote...');
    await syncRepo();
    log('Creating release tag...');
    await createReleaseTag(version);
    log('Pushing release tag...');
    await pushReleaseTag();
    log('Running release command for release notes...');
    await startReleaseNotes();
    log('Create a staging to master PR');
    log('Now wait till all the CI builds are completed, and the binaries have been published in Github release');
    await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Have all the CI builds completed?',
        default: true,
      },
    ]);
    await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Merge the staging branch with master',
        default: true,
      },
    ]);
    await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Upload updated browser extensions',
        default: true,
      },
    ]);
    log('C\'est fini! 🎉');

  } catch (error) {
    console.error(error);
  }
}
main();

const exec = async(...args) => {
  const subprocess = execa(...args);
  subprocess.stdout.pipe(process.stdout);

  await subprocess;
};

const syncRepo = async() => {
  return exec('sh', ['-c', `until git pull --rebase && git push; do echo '\''Retrying...'\''; done`]);
};

const runTests = async() => {
  return exec('yarn', ['test']);
};

const buildExtensions = async() => {
  return exec('yarn', ['build-ext2']);
};

const updateVersion = async(version) => {
  return exec('./bin/update_version.sh', [version]);
};

const createVersionCommit = async(version) => {
  await exec('git', [ 'add', '--all' ]);
  await exec('git', [ 'commit', '-am', `Upgraded to v${version}` ]);
  await syncRepo();
};

const createReleaseTag = async(version) => {
  return exec('./bin/create_tag.sh', [ `v${version}` ]);
};

const pushReleaseTag = async() => {
  return exec('git', [ 'push', '--tags' ]);
};

const startReleaseNotes = async() => {
  return exec('release');
};
<commit_msg>Fixed issues in deploy script<commit_after>#!/usr/bin/env node
// @ts-check
/**
 * Deploy helper based on the deploy script
 */

const inquirer = require('inquirer');
const chalk = require('chalk');
const execa = require('execa');
const SEMVER_REGEX = /^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/;

function createLogger() {
  const ui = new inquirer.ui.BottomBar();

  return function (msg) {
    ui.log.write(chalk.green(msg));
  }
}

async function main() {
  try {
    const log = createLogger();
    const { haveCheckedDocs, newVersion } = await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveCheckedDocs',
        message: 'Have you checked that docs are up to date? (settings options, pre request script API, supported languages)',
        default: false,
      },
      {
        type: 'input',
        name: 'newVersion',
        message: 'What is the new version?',
        validate: function (value) {
          if (value.match(SEMVER_REGEX)) {
            return true;
          }

          return 'Please enter a valid version (e.g. 3.2.1)';
        },
      },
    ]);

    if (!haveCheckedDocs) {
      log('Check docs and try again.');
      return;
    }

    log('Making sure local repo is up to date...');
    // TODO: checkout staging
    // await syncRepo();
    log('Running tests...');
    // await runTests();
    log('Updating version in files...');
    await updateVersion(newVersion);
    log('Building browser extensions...');
    await buildExtensions();
    log('Now you can verify that the extensions work as expected. (You can verify firefox using ./bin/run_ext_firefox.sh)');
    const { haveVerifiedExtensions } = await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Have you checked that the extension builds work as expected?',
        default: true,
      },
    ]);
    log('Creating upgrade commit...');
    await createVersionCommit(newVersion);
    log('Syncing with remote...');
    await syncRepo();
    log('Creating release tag...');
    await createReleaseTag(newVersion);
    log('Pushing release tag...');
    await pushReleaseTag();
    log('Running release command for release notes...');
    await startReleaseNotes();
    log('Create a staging to master PR');
    log('Now wait till all the CI builds are completed, and the binaries have been published in Github release');
    await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Have all the CI builds completed?',
        default: true,
      },
    ]);
    await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Merge the staging branch with master',
        default: true,
      },
    ]);
    await inquirer.prompt([
      {
        type: 'confirm',
        name: 'haveVerifiedExtensions',
        message: 'Upload updated browser extensions',
        default: true,
      },
    ]);
    log('C\'est fini! 🎉');

  } catch (error) {
    console.error(error);
  }
}
main();

const exec = async(...args) => {
  // @ts-ignore
  const subprocess = execa(...args);
  subprocess.stdout.pipe(process.stdout);

  await subprocess;
};

const syncRepo = async() => {
  return exec('sh', ['-c', `until git pull --rebase && git push; do echo '\''Retrying...'\''; done`]);
};

const runTests = async() => {
  return exec('yarn', ['test']);
};

const buildExtensions = async() => {
  return exec('yarn', ['build-ext2']);
};

const updateVersion = async(version) => {
  return exec('./bin/update_version.sh', [version]);
};

const createVersionCommit = async(version) => {
  await exec('git', [ 'add', '--all' ]);
  await exec('git', [ 'commit', '-am', `Upgraded to v${version}` ]);
  await syncRepo();
};

const createReleaseTag = async(version) => {
  return exec('./bin/create_tag.sh', [ `v${version}` ]);
};

const pushReleaseTag = async() => {
  return exec('git', [ 'push', '--tags' ]);
};

const startReleaseNotes = async() => {
  return exec('release');
};
<|endoftext|>


<commit_before>#!/usr/src/app/bin/node_gc

var CLIEngine = require("eslint").CLIEngine;
var fs = require("fs");
var glob = require("glob");
var options = { extensions: [".js"], ignore: true, reset: false, useEslintrc: true };
var cli = new CLIEngine(options);

// a wrapper for emitting perf timing
function runWithTiming(name, fn) {
  var start = new Date(),
      rv = fn(),
      duration = (new Date() - start) / 1000;
  console.error("eslint.timing." + name + ": " + duration + "s");
  return rv;
}

function buildIssueJson(message, path) {
  // ESLint doesn't emit a ruleId in the
  // case of a fatal error (such as an invalid
  // token)
  var checkName = message.ruleId;
  if(message.fatal) {
    checkName = "fatal";
  }

  var issue = {
    type: "issue",
    categories: ["Style"],
    check_name: checkName,
    description: message.message,
    location: {
      path: path,
      positions: {
        begin: {
          line: message.line,
          column: message.column
        },
        end: {
          line: message.line,
          column: message.column
        }
      }
    },
    remediation_points: 50000
  };
  return JSON.stringify(issue);
}

function isFileWithMatchingExtension(file, extensions) {
  var stats = fs.lstatSync(file);
  var extension = "." + file.split(".").pop();
  return (
    stats.isFile() &&
    !stats.isSymbolicLink()
    && extensions.indexOf(extension) >= 0
  );
}

function isFileIgnoredByLibrary(file) {
  var path = file.replace(/^\/code\//, "");
  var ignored = cli.isPathIgnored(path);
  if (ignored) {
    output = "File `" + path + "` ignored because of your .eslintignore file." + "\n";
    process.stderr.write(output);
  }
  return ignored;
}

function exclusionBasedFileListBuilder(excludePaths) {
  // Uses glob to traverse code directory and find files to analyze,
  // excluding files passed in with by CLI config, and including only
  // files in the list of desired extensions.
  //
  // Deprecated style of file expansion, supported for users of the old CLI.
  return function(extensions) {
    var analysisFiles = [];
    var allFiles = glob.sync("/code/**/**", {});

    allFiles.forEach(function(file, i, a){
      if(excludePaths.indexOf(file.split("/code/")[1]) < 0) {
        if(fs.lstatSync(file).isFile()) {
          if (!isFileIgnoredByLibrary(file) && isFileWithMatchingExtension(file)) {
            analysisFiles.push(file);
          }
        }
      }
    });

    return analysisFiles;
  };
}

function inclusionBasedFileListBuilder(includePaths) {
  // Uses glob to expand the files and directories in includePaths, filtering
  // down to match the list of desired extensions.
  return function(extensions) {
    var analysisFiles = [];

    includePaths.forEach(function(fileOrDirectory, i) {
      if ((/\/$/).test(fileOrDirectory)) {
        // if it ends in a slash, expand and push
        var filesInThisDirectory = glob.sync(
          "/code/" + fileOrDirectory + "/**/**"
        );
        filesInThisDirectory.forEach(function(file, j){
          if (!isFileIgnoredByLibrary(file) && isFileWithMatchingExtension(file, extensions)) {
            analysisFiles.push(file);
          }
        });
      } else {
        // if not, check for ending in *.js
        var fullPath = "/code/" + fileOrDirectory;
        if (!isFileIgnoredByLibrary(fullPath) && isFileWithMatchingExtension(fullPath, extensions)) {
          analysisFiles.push(fullPath);
        }
      }
    });

    return analysisFiles;
  };
}

var buildFileList;
runWithTiming("engineConfig", function () {
  if (fs.existsSync("/config.json")) {
    var engineConfig = JSON.parse(fs.readFileSync("/config.json"));

    if (engineConfig.config) {
      options.configFile = "/code/" + engineConfig.config;
    }

    if (engineConfig.include_paths) {
      buildFileList = inclusionBasedFileListBuilder(
        engineConfig.include_paths
      );
    } else if (engineConfig.exclude_paths) {
      var ignores = engineConfig.exclude_paths;
      buildFileList = exclusionBasedFileListBuilder(ignores);
    } else {
      // No includes or excludes, let's try with everything
      buildFileList = exclusionBasedFileListBuilder([]);
    }

    var userConfig = engineConfig.config || {};
    if (userConfig.extensions) {
      options.extensions = userConfig.extensions;
    }
  }
});

var analysisFiles = runWithTiming("buildFileList", function() {
  return buildFileList(options.extensions);
});

function analyzeFiles() {
  var batchNum = 0,
      batchSize = 100,
      batchFiles,
      batchReport;

  while(analysisFiles.length > 0) {
    batchFiles = analysisFiles.splice(0, batchSize);

    runWithTiming("analyze-batch-" + batchNum, function() {
       batchReport = cli.executeOnFiles(batchFiles);
    });
    runWithTiming("report-batch" + batchNum, function() {
      batchReport.results.forEach(function(result) {
        var path = result.filePath.replace(/^\/code\//, "");

        result.messages.forEach(function(message) {
          var issueJson = buildIssueJson(message, path);
          console.log(issueJson + "\u0000");
        });
      });
    });
    runWithTiming("gc-batch-" + batchNum, function() {
      batchFiles = null;
      batchReport = null;
      global.gc();
    });

    batchNum++;
  }
}

analyzeFiles();
<commit_msg>Update location of optional config file<commit_after>#!/usr/src/app/bin/node_gc

var CLIEngine = require("eslint").CLIEngine;
var fs = require("fs");
var glob = require("glob");
var options = { extensions: [".js"], ignore: true, reset: false, useEslintrc: true };
var cli = new CLIEngine(options);

// a wrapper for emitting perf timing
function runWithTiming(name, fn) {
  var start = new Date(),
      rv = fn(),
      duration = (new Date() - start) / 1000;
  console.error("eslint.timing." + name + ": " + duration + "s");
  return rv;
}

function buildIssueJson(message, path) {
  // ESLint doesn't emit a ruleId in the
  // case of a fatal error (such as an invalid
  // token)
  var checkName = message.ruleId;
  if(message.fatal) {
    checkName = "fatal";
  }

  var issue = {
    type: "issue",
    categories: ["Style"],
    check_name: checkName,
    description: message.message,
    location: {
      path: path,
      positions: {
        begin: {
          line: message.line,
          column: message.column
        },
        end: {
          line: message.line,
          column: message.column
        }
      }
    },
    remediation_points: 50000
  };
  return JSON.stringify(issue);
}

function isFileWithMatchingExtension(file, extensions) {
  var stats = fs.lstatSync(file);
  var extension = "." + file.split(".").pop();
  return (
    stats.isFile() &&
    !stats.isSymbolicLink()
    && extensions.indexOf(extension) >= 0
  );
}

function isFileIgnoredByLibrary(file) {
  var path = file.replace(/^\/code\//, "");
  var ignored = cli.isPathIgnored(path);
  if (ignored) {
    output = "File `" + path + "` ignored because of your .eslintignore file." + "\n";
    process.stderr.write(output);
  }
  return ignored;
}

function exclusionBasedFileListBuilder(excludePaths) {
  // Uses glob to traverse code directory and find files to analyze,
  // excluding files passed in with by CLI config, and including only
  // files in the list of desired extensions.
  //
  // Deprecated style of file expansion, supported for users of the old CLI.
  return function(extensions) {
    var analysisFiles = [];
    var allFiles = glob.sync("/code/**/**", {});

    allFiles.forEach(function(file, i, a){
      if(excludePaths.indexOf(file.split("/code/")[1]) < 0) {
        if(fs.lstatSync(file).isFile()) {
          if (!isFileIgnoredByLibrary(file) && isFileWithMatchingExtension(file)) {
            analysisFiles.push(file);
          }
        }
      }
    });

    return analysisFiles;
  };
}

function inclusionBasedFileListBuilder(includePaths) {
  // Uses glob to expand the files and directories in includePaths, filtering
  // down to match the list of desired extensions.
  return function(extensions) {
    var analysisFiles = [];

    includePaths.forEach(function(fileOrDirectory, i) {
      if ((/\/$/).test(fileOrDirectory)) {
        // if it ends in a slash, expand and push
        var filesInThisDirectory = glob.sync(
          "/code/" + fileOrDirectory + "/**/**"
        );
        filesInThisDirectory.forEach(function(file, j){
          if (!isFileIgnoredByLibrary(file) && isFileWithMatchingExtension(file, extensions)) {
            analysisFiles.push(file);
          }
        });
      } else {
        // if not, check for ending in *.js
        var fullPath = "/code/" + fileOrDirectory;
        if (!isFileIgnoredByLibrary(fullPath) && isFileWithMatchingExtension(fullPath, extensions)) {
          analysisFiles.push(fullPath);
        }
      }
    });

    return analysisFiles;
  };
}

var buildFileList;
runWithTiming("engineConfig", function () {
  if (fs.existsSync("/config.json")) {
    var engineConfig = JSON.parse(fs.readFileSync("/config.json"));

    if (engineConfig.include_paths) {
      buildFileList = inclusionBasedFileListBuilder(
        engineConfig.include_paths
      );
    } else if (engineConfig.exclude_paths) {
      var ignores = engineConfig.exclude_paths;
      buildFileList = exclusionBasedFileListBuilder(ignores);
    } else {
      // No includes or excludes, let's try with everything
      buildFileList = exclusionBasedFileListBuilder([]);
    }

    var userConfig = engineConfig.config || {};
    if (userConfig.config) {
      options.configFile = "/code/" + userConfig.config;
    }

    if (userConfig.extensions) {
      options.extensions = userConfig.extensions;
    }
  }
});

var analysisFiles = runWithTiming("buildFileList", function() {
  return buildFileList(options.extensions);
});

function analyzeFiles() {
  var batchNum = 0,
      batchSize = 100,
      batchFiles,
      batchReport;

  while(analysisFiles.length > 0) {
    batchFiles = analysisFiles.splice(0, batchSize);

    runWithTiming("analyze-batch-" + batchNum, function() {
       batchReport = cli.executeOnFiles(batchFiles);
    });
    runWithTiming("report-batch" + batchNum, function() {
      batchReport.results.forEach(function(result) {
        var path = result.filePath.replace(/^\/code\//, "");

        result.messages.forEach(function(message) {
          var issueJson = buildIssueJson(message, path);
          console.log(issueJson + "\u0000");
        });
      });
    });
    runWithTiming("gc-batch-" + batchNum, function() {
      batchFiles = null;
      batchReport = null;
      global.gc();
    });

    batchNum++;
  }
}

analyzeFiles();
<|endoftext|>


<commit_before>define(["Tone/core/Tone", "Tone/effect/MidSideEffect", "Tone/signal/Signal",
	"Tone/signal/Multiply", "Tone/signal/Expr"],
	function(Tone){

	"use strict";

	/**
	 *  @class Applies a width factor to the mid/side seperation.
	 *         0 is all mid and 1 is all side.
	 *         Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).
	 *

	 *
	 *         Mid *= 2*(1-width)

	 *         Side *= 2*width
	 *
	 *
	 *  @extends {Tone.MidSideEffect}
	 *  @constructor
	 *  @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change.
	 */
	Tone.StereoWidener = function(){

		var options = this.optionsObject(arguments, ["width"], Tone.StereoWidener.defaults);
		Tone.MidSideEffect.call(this, options);

		/**
		 *  The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change.
		 *  @type {NormalRange}
		 *  @signal
		 */
		this.width = new Tone.Signal(0.5, Tone.Type.NormalRange);

		/**
		 *  Mid multiplier
		 *  @type {Tone.Expr}
		 *  @private
		 */
		this._midMult = new Tone.Expr("$0 * ($1 * (1 - $2))");

		/**
		 *  Side multiplier
		 *  @type {Tone.Expr}
		 *  @private
		 */
		this._sideMult = new Tone.Expr("$0 * ($1 * $2)");

		/**
		 *  constant output of 2
		 *  @type {Tone}
		 *  @private
		 */
		this._two = new Tone.Signal(2);

		//the mid chain
		this._two.connect(this._midMult, 0, 1);
		this.width.connect(this._midMult, 0, 2);
		//the side chain
		this._two.connect(this._sideMult, 0, 1);
		this.width.connect(this._sideMult, 0, 2);
		//connect it to the effect send/return
		this.midSend.chain(this._midMult, this.midReturn);
		this.sideSend.chain(this._sideMult, this.sideReturn);
		this._readOnly(["width"]);
	};

	Tone.extend(Tone.StereoWidener, Tone.MidSideEffect);

	/**
	 *  the default values
	 *  @static
	 *  @type {Object}
	 */
	Tone.StereoWidener.defaults = {
		"width" : 0.5
	};

	/**
	 *  Clean up.
	 *  @returns {Tone.StereoWidener} this
	 */
	Tone.StereoWidener.prototype.dispose = function(){
		Tone.MidSideEffect.prototype.dispose.call(this);
		this._writable(["width"]);
		this.width.dispose();
		this.width = null;
		this._midMult.dispose();
		this._midMult = null;
		this._sideMult.dispose();
		this._sideMult = null;
		this._two.dispose();
		this._two = null;
		return this;
	};

	return Tone.StereoWidener;
});<commit_msg>uses defaults<commit_after>define(["Tone/core/Tone", "Tone/effect/MidSideEffect", "Tone/signal/Signal",
	"Tone/signal/Multiply", "Tone/signal/Expr"],
	function(Tone){

	"use strict";

	/**
	 *  @class Applies a width factor to the mid/side seperation.
	 *         0 is all mid and 1 is all side.
	 *         Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).
	 *

	 *
	 *         Mid *= 2*(1-width)

	 *         Side *= 2*width
	 *
	 *
	 *  @extends {Tone.MidSideEffect}
	 *  @constructor
	 *  @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change.
	 */
	Tone.StereoWidener = function(){

		var options = this.optionsObject(arguments, ["width"], Tone.StereoWidener.defaults);
		Tone.MidSideEffect.call(this, options);

		/**
		 *  The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change.
		 *  @type {NormalRange}
		 *  @signal
		 */
		this.width = new Tone.Signal(options.width, Tone.Type.NormalRange);

		/**
		 *  Mid multiplier
		 *  @type {Tone.Expr}
		 *  @private
		 */
		this._midMult = new Tone.Expr("$0 * ($1 * (1 - $2))");

		/**
		 *  Side multiplier
		 *  @type {Tone.Expr}
		 *  @private
		 */
		this._sideMult = new Tone.Expr("$0 * ($1 * $2)");

		/**
		 *  constant output of 2
		 *  @type {Tone}
		 *  @private
		 */
		this._two = new Tone.Signal(2);

		//the mid chain
		this._two.connect(this._midMult, 0, 1);
		this.width.connect(this._midMult, 0, 2);
		//the side chain
		this._two.connect(this._sideMult, 0, 1);
		this.width.connect(this._sideMult, 0, 2);
		//connect it to the effect send/return
		this.midSend.chain(this._midMult, this.midReturn);
		this.sideSend.chain(this._sideMult, this.sideReturn);
		this._readOnly(["width"]);
	};

	Tone.extend(Tone.StereoWidener, Tone.MidSideEffect);

	/**
	 *  the default values
	 *  @static
	 *  @type {Object}
	 */
	Tone.StereoWidener.defaults = {
		"width" : 0.5
	};

	/**
	 *  Clean up.
	 *  @returns {Tone.StereoWidener} this
	 */
	Tone.StereoWidener.prototype.dispose = function(){
		Tone.MidSideEffect.prototype.dispose.call(this);
		this._writable(["width"]);
		this.width.dispose();
		this.width = null;
		this._midMult.dispose();
		this._midMult = null;
		this._sideMult.dispose();
		this._sideMult = null;
		this._two.dispose();
		this._two = null;
		return this;
	};

	return Tone.StereoWidener;
});<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

var crypto = require('crypto');
var base58 = require('bs58');
var fs = require('fs');
var path = require('path');
var async = require('async');
var program = require('commander');
var storj = require('storj');
var SpeedTest = require('myspeed').Client;
var platform = require('os').platform();
var prompt = require('prompt');
var url = require('url');
var colors = require('colors/safe');
var Logger = require('kad-logger-json');
var TelemetryReporter = require('storj-telemetry-reporter');

var HOME = platform !== 'win32' ? process.env.HOME : process.env.USERPROFILE;
var CONFNAME = 'config.json';
var SPEEDTEST_URL = 'ws://speedofme.storj.io';
var SPEEDTEST_RESULT_PATH = path.join(require('os').tmpdir(), 'speedtest.json');

prompt.message = colors.white.bold(' STORJSHARE');
prompt.delimiter = colors.blue(' >> ');

program
  .version(
    'Farmer: v' + require('../package').version + '\n' +
    'Core:   v' + storj.version
  )
  .option(
    '-d, --datadir [path]',
    'Set configuration and storage path',
    path.join(HOME, '.storjshare')
  )
  .option(
    '-p, --password [password]',
    'Password to unlock your private key',
    ''
  )
  .parse(process.argv);

var schema = {
  properties: {
    address: {
      description: 'Enter your public hostname or IP address',
      required: true,
      default: storj.Network.DEFAULTS.address,
    },
    port: {
      description: 'Enter the TCP port number the service should use (0 for random)',
      required: false,
      type: 'number',
      default: storj.Network.DEFAULTS.port,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    forward: {
      description: 'Use NAT traversal strategies to become available on the network',
      required: true,
      type: 'boolean',
      default: storj.Network.DEFAULTS.forward
    },
    seed: {
      description: 'Enter the URI of a known seed',
      required: false,
      default: storj.Network.DEFAULTS.seeds[0],
      message: 'Invalid seed URI supplied, make sure the nodeID is correct',
      conform: function(value) {
        var parsed = url.parse(value);
        var proto = parsed.protocol === 'storj:';
        var nodeid = parsed.path.substr(1).length === 40;
        var address = parsed.hostname && parsed.port;

        return proto && nodeid && address;
      }
    },
    datadir: {
      description: 'Enter the path to store configuration and data',
      required: true,
      default: program.datadir,
      message: 'Directory already exists, refusing to overwrite',
      conform: function(value) {
        if (fs.existsSync(value)) {
          return false;
        }
        fs.mkdirSync(value);
        return true;
      }
    },
    space: {
      description: 'Enter the amount of storage space you can share',
      required: true,
      default: '2GB',
      message: 'Invalid format supplied, try 50MB, 2GB, or 1TB',
      conform: function(value) {
        var size = parseFloat(value);
        var unit = value.split(size)[1];

        return size && (['MB','GB','TB'].indexOf(unit) !== -1);
      }
    },
    payto: {
      description: 'Enter a payment address to receive rewards (telemetry must be enabled)',
      required: false
    },
    telemetry: {
      description: 'Will you share telemetry data with Storj to help improve the network?',
      required: true,
      default: false,
      type: 'boolean'
    },
    tunnels: {
      description: 'Enter the number of tunnel connection other farmer can open through you',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.tunnels,
      conform: function(value) {
        return (value > -1);
      }
    },
    tunnelport: {
      description: 'Enter the TCP port number the tunnel server should use (0 for random)',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.tunport,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    gatewaysmin: {
      description: 'Enter the start TCP port for tunnel connections (0 for random)',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.gateways.min,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    gatewaysmax: {
      description: 'Enter the end TCP port for tunnel connections (0 for random)',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.gateways.max,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    keypath: {
      description: 'Enter the path to store your encrypted private key',
      required: true,
      default: path.join(program.datadir || path.join(HOME, '.storjshare'), 'id_ecdsa'),
      message: 'Refusing to overwrite the supplied path',
      conform: function(value) {
        return fs.existsSync(path.dirname(value)) &&
               !fs.existsSync(value);
      }
    },
    password: {
      description: 'Enter a password to protect your private key',
      hidden: true,
      replace: '*',
      required: true
    }
  }
};

var keypass = {
  properties: {
    password: {
      description: 'Unlock your private key to start storj',
      hidden: true,
      replace: '*',
      required: true
    }
  }
};

function getDirectorySize(dir, callback) {
  fs.stat(dir, function(err, stats) {
    if (err || !stats.isDirectory()) {
      return callback(err, 0);
    }

    var total = stats.size;

    function done(err) {
      callback(err, total);
    }

    fs.readdir(dir, function(err, list) {
      if (err) {
        return callback(err);
      }

      async.each(list, function(diritem, next) {
        var child = path.join(dir, diritem);

        getDirectorySize(child, function(err, size) {
          total = total + size;
          next(err);
        });
      }, done);
    });
  });
}

function encrypt(password, str) {
  var aes256 = crypto.createCipher('aes-256-cbc', password);
  var a = aes256.update(str, 'utf8');
  var b = aes256.final();
  var buf = new Buffer(a.length + b.length);

  a.copy(buf, 0);
  b.copy(buf, a.length);

  return base58.encode(buf);
}

function decrypt(password, str) {
  var aes256 = crypto.createDecipher('aes-256-cbc', password);
  var a = aes256.update(new Buffer(base58.decode(str)));
  var b = aes256.final();
  var buf = new Buffer(a.length + b.length);

  a.copy(buf, 0);
  b.copy(buf, a.length);

  return buf.toString('utf8');
}

function report(reporter, config, farmer) {
  var bandwidth = fs.existsSync(SPEEDTEST_RESULT_PATH) ?
                  fs.readFileSync(SPEEDTEST_RESULT_PATH).toString() :
                  null;
  var needstest = false;
  var hours25 = 60 * 60 * 25 * 1000;

  function send() {
    getDirectorySize(config.storage.path, function(err, size) {
      if (err) {
        return;
      }

      var totalSpace = Number(config.storage.size);

      switch (config.storage.unit) {
        case 'MB':
          totalSpace = totalSpace * Math.pow(1024, 2);
          break;
        case 'GB':
          totalSpace = totalSpace * Math.pow(1024, 3);
          break;
        case 'TB':
          totalSpace = totalSpace * Math.pow(1024, 4);
          break;
        default:
          // NOOP
      }

      var report = {
        storage: {
          free: Number((totalSpace - size).toFixed()),
          used: Number(size.toFixed())
        },
        bandwidth: {
          upload: bandwidth ? Number(bandwidth.upload) : 0,
          download: bandwidth ? Number(bandwidth.download) : 0
        },
        contact: farmer._contact,
        payment: config.address
      };

      process.stdout.write(JSON.stringify({type: 'info',
          message: 'telemetry report ' + JSON.stringify(report),
          timestamp: new Date()
        }) + '\n');

      reporter.send(report, function(err, report) {
        process.stdout.write(JSON.stringify({
          type: err ? 'error' : 'info',
          message: err ? err.message :
                         'sent telemetry report ' + JSON.stringify(report),
          timestamp: new Date()
        }) + '\n');
      });
    });

    setTimeout(function() {
      report(reporter, config, farmer);
    }, 5 * (60 * 1000));
  }

  if (!bandwidth) {
    needstest = true;
  } else {
    bandwidth = JSON.parse(bandwidth);

    if ((new Date() - new Date(bandwidth.timestamp)) > hours25) {
      needstest = true;
    }
  }

  if (needstest && SPEEDTEST_URL) {
    SpeedTest({ url: SPEEDTEST_URL }).test(function(err, result) {
      if (err) {
        return process.stdout.write(JSON.stringify({
          type: 'error',
          message: err.message,
          timestamp: new Date()
        }) + '\n');
      }

      bandwidth = {
        upload: result.upload,
        download: result.download,
        timestamp: Date.now()
      };

      fs.writeFileSync(SPEEDTEST_RESULT_PATH, JSON.stringify(bandwidth));
      send();
    });
  } else {
    send();
  }
}

function opcodeUpdate(opcode) {
  if (Buffer(opcode, 'hex')[0] !== 0xf) {
    return '0f' + opcode;
  } else {
    return opcode;
  }
}

function start(datadir) {
  if (!fs.existsSync(datadir)) {
    console.log('The supplied datadir does not exist');
    process.exit();
  }

  if (!fs.existsSync(path.join(datadir, CONFNAME))) {
    console.log('No storj configuration found in datadir');
    process.exit();
  }

  var config = JSON.parse(
    fs.readFileSync(path.join(datadir, CONFNAME)).toString()
  );
  var privkey = fs.readFileSync(config.keypath).toString();

  function open(passwd, privkey) {
    try {
      privkey = decrypt(passwd, privkey);
    } catch (err) {
      console.log('Failed to unlock private key - incorrect password');
      process.exit();
    }

    var keypair = storj.KeyPair(privkey);
    var farmerconf = {
      keypair: keypair,
      payment: config.address,
      storage: {
        path: datadir,
        size: config.storage.size,
        unit: config.storage.unit
      },
      address: config.network.address,
      port: config.network.port,
      seeds: config.network.seeds,
      noforward: !config.network.forward,
      logger: new Logger(),
      tunport: config.network.tunnelport,
      tunnels: config.network.tunnels,
      gateways: config.network.gateways,
      opcodes: !Array.isArray(config.network.opcodes) ?
               storj.FarmerInterface.DEFAULTS.opcodes :
               config.network.opcodes.map(opcodeUpdate)
    };

    farmerconf.logger.pipe(process.stdout);

    var farmer = new storj.FarmerInterface(farmerconf);

    farmer.join(function(err) {
      if (err) {
        console.log(err);
        process.exit();
      }
    });

    if (config.telemetry.enabled) {
      try {
        report(TelemetryReporter(
          'https://status.storj.io',
          keypair
        ), config, farmer);
      } catch (err) {
        farmerconf.logger.error(
          'telemetry reporter failed, reason: %s', err.message
        );
      }
    }
  }

  if (program.password) {
    open(program.password, privkey);
  } else {
    prompt.start();
    prompt.get(keypass, function(err, result) {
      if (err) {
        return console.log(err);
      }

      open(result.password, privkey);
    });
  }
}

if (!fs.existsSync(program.datadir)) {
  console.log('\n Let\'s setup your Storj configuration!\n');

  prompt.start();

  prompt.get(schema, function(err, result) {
    if (err) {
      return console.log(err);
    }

    var size = parseFloat(result.space);
    var unit = result.space.split(size.toString())[1];

    var config = {
      keypath: result.keypath,
      address: result.payto,
      storage: {
        path: result.datadir,
        size: size,
        unit: unit
      },
      network: {
        address: result.address,
        port: result.port,
        seeds: [result.seed],
        opcodes: ['0f01020202', '0f02020202', '0f03020202'],
        forward: result.forward,
        tunnels: result.tunnels,
        tunnelport: result.tunnelport,
        gateways: { min: result.gatewaysmin, max: result.gatewaysmax }
      },
      telemetry: {
        service: 'https://status.storj.io',
        enabled: result.telemetry
      }
    };

    fs.writeFileSync(
      path.join(result.datadir, CONFNAME),
      JSON.stringify(config, null, 2)
    );

    fs.writeFileSync(
      config.keypath,
      encrypt(result.password, storj.KeyPair().getPrivateKey())
    );

    start(result.datadir);
  });
} else {
  start(program.datadir);
}
<commit_msg>add note to first run wizard about missing datadir<commit_after>#!/usr/bin/env node

'use strict';

var crypto = require('crypto');
var base58 = require('bs58');
var fs = require('fs');
var path = require('path');
var async = require('async');
var program = require('commander');
var storj = require('storj');
var SpeedTest = require('myspeed').Client;
var platform = require('os').platform();
var prompt = require('prompt');
var url = require('url');
var colors = require('colors/safe');
var Logger = require('kad-logger-json');
var TelemetryReporter = require('storj-telemetry-reporter');

var HOME = platform !== 'win32' ? process.env.HOME : process.env.USERPROFILE;
var CONFNAME = 'config.json';
var SPEEDTEST_URL = 'ws://speedofme.storj.io';
var SPEEDTEST_RESULT_PATH = path.join(require('os').tmpdir(), 'speedtest.json');

prompt.message = colors.white.bold(' STORJSHARE');
prompt.delimiter = colors.blue(' >> ');

program
  .version(
    'Farmer: v' + require('../package').version + '\n' +
    'Core:   v' + storj.version
  )
  .option(
    '-d, --datadir [path]',
    'Set configuration and storage path',
    path.join(HOME, '.storjshare')
  )
  .option(
    '-p, --password [password]',
    'Password to unlock your private key',
    ''
  )
  .parse(process.argv);

var schema = {
  properties: {
    address: {
      description: 'Enter your public hostname or IP address',
      required: true,
      default: storj.Network.DEFAULTS.address,
    },
    port: {
      description: 'Enter the TCP port number the service should use (0 for random)',
      required: false,
      type: 'number',
      default: storj.Network.DEFAULTS.port,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    forward: {
      description: 'Use NAT traversal strategies to become available on the network',
      required: true,
      type: 'boolean',
      default: storj.Network.DEFAULTS.forward
    },
    seed: {
      description: 'Enter the URI of a known seed',
      required: false,
      default: storj.Network.DEFAULTS.seeds[0],
      message: 'Invalid seed URI supplied, make sure the nodeID is correct',
      conform: function(value) {
        var parsed = url.parse(value);
        var proto = parsed.protocol === 'storj:';
        var nodeid = parsed.path.substr(1).length === 40;
        var address = parsed.hostname && parsed.port;

        return proto && nodeid && address;
      }
    },
    datadir: {
      description: 'Enter the path to store configuration and data',
      required: true,
      default: program.datadir,
      message: 'Directory already exists, refusing to overwrite',
      conform: function(value) {
        if (fs.existsSync(value)) {
          return false;
        }
        fs.mkdirSync(value);
        return true;
      }
    },
    space: {
      description: 'Enter the amount of storage space you can share',
      required: true,
      default: '2GB',
      message: 'Invalid format supplied, try 50MB, 2GB, or 1TB',
      conform: function(value) {
        var size = parseFloat(value);
        var unit = value.split(size)[1];

        return size && (['MB','GB','TB'].indexOf(unit) !== -1);
      }
    },
    payto: {
      description: 'Enter a payment address to receive rewards (telemetry must be enabled)',
      required: false
    },
    telemetry: {
      description: 'Will you share telemetry data with Storj to help improve the network?',
      required: true,
      default: false,
      type: 'boolean'
    },
    tunnels: {
      description: 'Enter the number of tunnel connection other farmer can open through you',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.tunnels,
      conform: function(value) {
        return (value > -1);
      }
    },
    tunnelport: {
      description: 'Enter the TCP port number the tunnel server should use (0 for random)',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.tunport,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    gatewaysmin: {
      description: 'Enter the start TCP port for tunnel connections (0 for random)',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.gateways.min,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    gatewaysmax: {
      description: 'Enter the end TCP port for tunnel connections (0 for random)',
      required: true,
      type: 'number',
      default: storj.Network.DEFAULTS.gateways.max,
      conform: function(value) {
        return (value > -1) && (value <= 65535);
      }
    },
    keypath: {
      description: 'Enter the path to store your encrypted private key',
      required: true,
      default: path.join(program.datadir || path.join(HOME, '.storjshare'), 'id_ecdsa'),
      message: 'Refusing to overwrite the supplied path',
      conform: function(value) {
        return fs.existsSync(path.dirname(value)) &&
               !fs.existsSync(value);
      }
    },
    password: {
      description: 'Enter a password to protect your private key',
      hidden: true,
      replace: '*',
      required: true
    }
  }
};

var keypass = {
  properties: {
    password: {
      description: 'Unlock your private key to start storj',
      hidden: true,
      replace: '*',
      required: true
    }
  }
};

function getDirectorySize(dir, callback) {
  fs.stat(dir, function(err, stats) {
    if (err || !stats.isDirectory()) {
      return callback(err, 0);
    }

    var total = stats.size;

    function done(err) {
      callback(err, total);
    }

    fs.readdir(dir, function(err, list) {
      if (err) {
        return callback(err);
      }

      async.each(list, function(diritem, next) {
        var child = path.join(dir, diritem);

        getDirectorySize(child, function(err, size) {
          total = total + size;
          next(err);
        });
      }, done);
    });
  });
}

function encrypt(password, str) {
  var aes256 = crypto.createCipher('aes-256-cbc', password);
  var a = aes256.update(str, 'utf8');
  var b = aes256.final();
  var buf = new Buffer(a.length + b.length);

  a.copy(buf, 0);
  b.copy(buf, a.length);

  return base58.encode(buf);
}

function decrypt(password, str) {
  var aes256 = crypto.createDecipher('aes-256-cbc', password);
  var a = aes256.update(new Buffer(base58.decode(str)));
  var b = aes256.final();
  var buf = new Buffer(a.length + b.length);

  a.copy(buf, 0);
  b.copy(buf, a.length);

  return buf.toString('utf8');
}

function report(reporter, config, farmer) {
  var bandwidth = fs.existsSync(SPEEDTEST_RESULT_PATH) ?
                  fs.readFileSync(SPEEDTEST_RESULT_PATH).toString() :
                  null;
  var needstest = false;
  var hours25 = 60 * 60 * 25 * 1000;

  function send() {
    getDirectorySize(config.storage.path, function(err, size) {
      if (err) {
        return;
      }

      var totalSpace = Number(config.storage.size);

      switch (config.storage.unit) {
        case 'MB':
          totalSpace = totalSpace * Math.pow(1024, 2);
          break;
        case 'GB':
          totalSpace = totalSpace * Math.pow(1024, 3);
          break;
        case 'TB':
          totalSpace = totalSpace * Math.pow(1024, 4);
          break;
        default:
          // NOOP
      }

      var report = {
        storage: {
          free: Number((totalSpace - size).toFixed()),
          used: Number(size.toFixed())
        },
        bandwidth: {
          upload: bandwidth ? Number(bandwidth.upload) : 0,
          download: bandwidth ? Number(bandwidth.download) : 0
        },
        contact: farmer._contact,
        payment: config.address
      };

      process.stdout.write(JSON.stringify({type: 'info',
          message: 'telemetry report ' + JSON.stringify(report),
          timestamp: new Date()
        }) + '\n');

      reporter.send(report, function(err, report) {
        process.stdout.write(JSON.stringify({
          type: err ? 'error' : 'info',
          message: err ? err.message :
                         'sent telemetry report ' + JSON.stringify(report),
          timestamp: new Date()
        }) + '\n');
      });
    });

    setTimeout(function() {
      report(reporter, config, farmer);
    }, 5 * (60 * 1000));
  }

  if (!bandwidth) {
    needstest = true;
  } else {
    bandwidth = JSON.parse(bandwidth);

    if ((new Date() - new Date(bandwidth.timestamp)) > hours25) {
      needstest = true;
    }
  }

  if (needstest && SPEEDTEST_URL) {
    SpeedTest({ url: SPEEDTEST_URL }).test(function(err, result) {
      if (err) {
        return process.stdout.write(JSON.stringify({
          type: 'error',
          message: err.message,
          timestamp: new Date()
        }) + '\n');
      }

      bandwidth = {
        upload: result.upload,
        download: result.download,
        timestamp: Date.now()
      };

      fs.writeFileSync(SPEEDTEST_RESULT_PATH, JSON.stringify(bandwidth));
      send();
    });
  } else {
    send();
  }
}

function opcodeUpdate(opcode) {
  if (Buffer(opcode, 'hex')[0] !== 0xf) {
    return '0f' + opcode;
  } else {
    return opcode;
  }
}

function start(datadir) {
  if (!fs.existsSync(datadir)) {
    console.log('The supplied datadir does not exist');
    process.exit();
  }

  if (!fs.existsSync(path.join(datadir, CONFNAME))) {
    console.log('No storj configuration found in datadir');
    process.exit();
  }

  var config = JSON.parse(
    fs.readFileSync(path.join(datadir, CONFNAME)).toString()
  );
  var privkey = fs.readFileSync(config.keypath).toString();

  function open(passwd, privkey) {
    try {
      privkey = decrypt(passwd, privkey);
    } catch (err) {
      console.log('Failed to unlock private key - incorrect password');
      process.exit();
    }

    var keypair = storj.KeyPair(privkey);
    var farmerconf = {
      keypair: keypair,
      payment: config.address,
      storage: {
        path: datadir,
        size: config.storage.size,
        unit: config.storage.unit
      },
      address: config.network.address,
      port: config.network.port,
      seeds: config.network.seeds,
      noforward: !config.network.forward,
      logger: new Logger(),
      tunport: config.network.tunnelport,
      tunnels: config.network.tunnels,
      gateways: config.network.gateways,
      opcodes: !Array.isArray(config.network.opcodes) ?
               storj.FarmerInterface.DEFAULTS.opcodes :
               config.network.opcodes.map(opcodeUpdate)
    };

    farmerconf.logger.pipe(process.stdout);

    var farmer = new storj.FarmerInterface(farmerconf);

    farmer.join(function(err) {
      if (err) {
        console.log(err);
        process.exit();
      }
    });

    if (config.telemetry.enabled) {
      try {
        report(TelemetryReporter(
          'https://status.storj.io',
          keypair
        ), config, farmer);
      } catch (err) {
        farmerconf.logger.error(
          'telemetry reporter failed, reason: %s', err.message
        );
      }
    }
  }

  if (program.password) {
    open(program.password, privkey);
  } else {
    prompt.start();
    prompt.get(keypass, function(err, result) {
      if (err) {
        return console.log(err);
      }

      open(result.password, privkey);
    });
  }
}

if (!fs.existsSync(program.datadir)) {
  console.log('\n ' + colors.bold.underline(
    'Let\'s setup your StorjShare configuration!')
  );
  console.log(colors.italic(
    ' The data directory does not exist yet; it will be created.\n')
  );

  prompt.start();

  prompt.get(schema, function(err, result) {
    if (err) {
      return console.log(err);
    }

    var size = parseFloat(result.space);
    var unit = result.space.split(size.toString())[1];

    var config = {
      keypath: result.keypath,
      address: result.payto,
      storage: {
        path: result.datadir,
        size: size,
        unit: unit
      },
      network: {
        address: result.address,
        port: result.port,
        seeds: [result.seed],
        opcodes: ['0f01020202', '0f02020202', '0f03020202'],
        forward: result.forward,
        tunnels: result.tunnels,
        tunnelport: result.tunnelport,
        gateways: { min: result.gatewaysmin, max: result.gatewaysmax }
      },
      telemetry: {
        service: 'https://status.storj.io',
        enabled: result.telemetry
      }
    };

    fs.writeFileSync(
      path.join(result.datadir, CONFNAME),
      JSON.stringify(config, null, 2)
    );

    fs.writeFileSync(
      config.keypath,
      encrypt(result.password, storj.KeyPair().getPrivateKey())
    );

    start(result.datadir);
  });
} else {
  start(program.datadir);
}
<|endoftext|>


<commit_before>/*
 Copyright 2017 Aleksandar Jankovic

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const View = require('../base/View');
const DialogBox = require('../DialogBox');
const LoginBox = require('./LoginBox');
const storageManager = require('../../StorageManager');
const keyHandler = require('../../KeyHandler');
const socketManager = require('../../SocketManager');
const eventCentral = require('../../EventCentral');

class MainMenu extends View {
  constructor({ parentElement }) {
    super({ isFullscreen: false });
    this.element.setAttribute('id', 'mainMenu');
    this.element.classList.add('hide');

    const menu = document.createElement('UL');
    this.rows = [];

    const loginRow = document.createElement('LI');
    this.rows.push({ rowName: 'login', row: loginRow });
    loginRow.appendChild(document.createElement('BUTTON'));
    loginRow.lastChild.appendChild(document.createTextNode('Registera/Logga in'));
    loginRow.addEventListener('click', () => {
      new LoginBox({
        description: ['Endast för Krismyndigheten och Försvarsmakten'],
        extraDescription: ['Skriv in ert användarnamn och lösenord'],
        parentElement,
        socketManager,
        keyHandler,
      }).appendTo(parentElement);
    });
    this.accessElements.push({
      element: loginRow,
      accessLevel: 0,
      maxAccessLevel: 0,
    });

    const aliasRow = document.createElement('LI');
    this.rows.push({ rowName: 'alias', row: aliasRow });
    aliasRow.appendChild(document.createElement('BUTTON'));
    aliasRow.lastChild.appendChild(document.createTextNode('Skapa alias'));
    aliasRow.classList.add('hide');
    aliasRow.addEventListener('click', () => {
      const dialog = new DialogBox({
        buttons: {
          left: {
            text: 'Avbryt',
            eventFunc: () => {
              dialog.removeView();
            },
          },
          right: {
            text: 'Skapa',
            eventFunc: () => {
              if (!dialog.markEmptyFields()) {
                const alias = dialog.inputs.find(({ inputName }) => inputName === 'alias').inputElement.value;

                socketManager.emitEvent('addAlias', { alias }, ({ error }) => {
                  if (error) {
                    dialog.changeExtraDescription({ text: error.text });

                    return;
                  }

                  storageManager.addAlias(alias);
                  eventCentral.triggerEvent({ event: eventCentral.Events.ALIAS, params: { aliases: storageManager.getAliases() } });
                  dialog.removeView();
                });
              }
            },
          },
        },
        description: [
          'Skriv in ett nytt alias. Ni kommer kunna välja att skicka meddelande med detta alias istället för ert användarnamn',
          'Skriv in ett av dina existerande alias om ni vill ändra det',
        ],
        parentElement,
        inputs: [{
          placeholder: 'Alias',
          inputName: 'alias',
          required: true,
        }],
        keyHandler,
      });
      dialog.appendTo(parentElement);
    });
    this.accessElements.push({
      element: aliasRow,
      accessLevel: 2,
    });

    const logoutRow = document.createElement('LI');
    this.rows.push({ rowName: 'logout', row: logoutRow });
    logoutRow.appendChild(document.createElement('BUTTON'));
    logoutRow.lastChild.appendChild(document.createTextNode('Logga ut'));
    logoutRow.classList.add('hide');
    logoutRow.addEventListener('click', () => {
      storageManager.removeUser();

      new LoginBox({
        description: ['Endast för Krismyndigheten och Försvarsmakten'],
        extraDescription: ['Skriv in ert användarnamn och lösenord'],
        parentElement,
        socketManager,
        keyHandler,
      }).appendTo(parentElement);
    });
    this.accessElements.push({
      element: logoutRow,
      accessLevel: 1,
    });

    menu.appendChild(loginRow);
    menu.appendChild(aliasRow);
    menu.appendChild(logoutRow);
    this.element.appendChild(menu);
  }
}

module.exports = MainMenu;
<commit_msg>No longer used<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (C) 2007-2012 Guillaume Pellerin, Parisson
 * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
 * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
 *
 * This file is part of TimeSide.
 *
 * TimeSide is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * TimeSide is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
 *          Olivier Guilyardi <olivier@samalyse.com>
 */

/**
 * Class for telemeta global functions.
 * Note that the dollar sign is a reserved keyword in some browsers
 * (see http://davidwalsh.name/dollar-functions)
 * which might be in conflict with jQuery dollar sign.
 */

//returns the full path of the current url location removing the last slash '/' followed by one or more '#', if any
function urlNormalized(){
    var sPath = window.location.href;
    sPath = sPath.replace(/\/#*$/,"");
    return sPath;
}
/**
 *sets up few stuff when the page is ready (see functions below it)
 */
jQuery(document).ready(function() {
    foldInfoBlocks();
    setSelectedMenu();
});

/**
 *function inherited from old code, never touched. Guess fixes the click on the left data table, if any
 */
function foldInfoBlocks() {
    var $J = jQuery;
    var extra = $J('.extraInfos');
    extra.find('.folded dl, .folded table').css('display', 'none');
    extra.find('h4').click(function() {
        $J(this).parents('.extraInfos').children().toggleClass('folded').find('dl, table').toggle(100);
        //toggle toggles the visibility of elements
        return false;
    });
}

/**
 * Global telemeta function which sets the current selected menu according to the current url
 */
function setSelectedMenu(){
    var $J = jQuery;
    var menus = $J('#menu a');
    //build collections/items from http:/site/collections/items,
    //being http:/site/ = window.location.origin

    //function for normalizing paths (removes last n occurrences of the slash)
    var normalize = function(str){
        return str.replace(/\/+#*$/,"");
    }

    var host = window.location.host;
    var protocol = window.location.protocol
    var href = normalize(window.location.href);

    if(!(host) || !(protocol) || !(href)){
        return;
    }

    //var pageOrigin = normalize(window.location.origin); //does not exist in FF, so:
    var pageOrigin = normalize(protocol+"//"+host);
    var pageHref = normalize(href);

    menus.each(function(){
        ///if we are at home, the window location href corresponds to window location origin,
        //so we select only links whose link points EXACTLY to the origin (home link)
        var linkHref = normalize(this.href);
        var elm = $J(this);

        if(linkHref.indexOf("#") != -1){
            var reg = new RegExp("[#]+", "g");
            var baseHref = linkHref.split(reg);
            linkHref = pageOrigin + "/" + baseHref[1]
        }

        if(pageOrigin===pageHref){
            if(pageHref == linkHref){
                elm.addClass('active');
            }else{
                elm.removeClass('active');
            }
        }else{
            //here, on the other hand, we select if a link points to a page or super page
            //of the current page
            if(linkHref!=pageOrigin && pageHref.match("^"+linkHref+".*")){
                elm.addClass('active');
            }else{
                elm.removeClass('active');
            }
        }

    })
}

/*****************************************************************************
 * json(param, method, onSuccesFcn(data, textStatus, jqXHR), onErrorFcn(jqXHR, textStatus, errorThrown))
 * global function to senbd/retrieve data with the server
 *
 * param: the data to be sent or retrieved.
 *   param will be converted to string, escaping quotes newlines and backslashes if necessary.
 *   param can be a javascript string, boolean, number, dictionary and array.
 *       If dictionary or array, it must contain only the above mentioned recognized types.
 *       So, eg, {[" a string"]} is fine, {[/asd/]} not
 *
 * method: the json method, eg "telemeta.update_marker". See base.py
 *
 * onSuccesFcn(data, textStatus, jqXHR) OPTIONAL --IF MISSING, NOTHING HAPPENS --
 *    A function to be called if the request succeeds with the same syntax of jQuery's ajax onSuccess function.
 *    The function gets passed three arguments
 *       The data returned from the server, formatted according to the dataType parameter;
 *       a string describing the status;
 *       and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object
 *
 * onErrorFcn(jqXHR, textStatus, errorThrown) OPTIONAL. --IF MISSING, THE DEFAULT ERROR DIALOG IS SHOWN--
 *     A function to be called if the request fails with the same syntax of jQuery ajax onError function..
 *     The function receives three arguments:
 *       The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object,
 *       a string describing the type of error that occurred and
 *       an optional exception object, if one occurred.
 *       Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror".
 * ****************************************************************************/

var json = function(param,method,onSuccessFcn,onErrorFcn){
    //this function converts a javascript object to a string
    var toString_ = function(string){
        if(typeof string == "string"){
            //escapes newlines quotes and backslashes
            string = string.replace(/\\/g,"\\\\")
            .replace(/\n/g,"\\n")
            .replace(/"/g,"\\\"");
        }
        var array; //used for arrays and objects (see below)
        if(typeof string == "boolean" || typeof string== "number" || typeof string == "string"){
            string = '"'+string+'"';
        }else if(string instanceof Array){
            array = [];
            for(var i = 0;i <string.length ; i++){
                array.push(toString_(string[i])); //recursive invocation
            }
            string='[';
            string+=array.join(",");
            string+=']';
        }else{
            array = [];
            for(var k in string){
                array.push(toString_(k)+":"+toString_(string[k])); //recursive invocation
            }
            string='{';
            string+=array.join(",");
            string+='}';
        }
        return string;
    };

    //creating the string to send.
    var param2string = toString_(param);
    var data2send = '{"id":"jsonrpc", "params":';
    data2send+=param2string;
    data2send+=', "method":"'
    data2send+=method;
    data2send+='","jsonrpc":"1.0"}';

    var $J = jQuery;
    $J.ajax({
        type: "POST",
        url: 'json/',
        contentType: "application/json",
        data: data2send,
        dataType: "json",
        success: function(data, textStatus, jqXHR){
            if(onSuccessFcn){
                onSuccessFcn(data, textStatus, jqXHR);
            }
        },
        error: function(jqXHR, textStatus, errorThrown){
            if(onErrorFcn){
                onErrorFcn(jqXHR, textStatus, errorThrown);
                return;
            }
            //default:
            var details = "\n(no further info available)";
            if(jqXHR) {
                details="\nThe server responded witha status of "+jqXHR.status+" ("+
                jqXHR.statusText+")\n\nDetails (request responseText):\n"+jqXHR.responseText;
            }
            alert("ERROR: Failed to save"+details);

        }
    });

};

/**
 * function for writing to the console. Catches errors, if any (eg, console == undefined) and does nothing in case
 */
function consolelog(text){
    if(typeof console != 'undefined'){
        var c = console;
        if (c.log) {
            c.log(text);
        }
    }
}

// Drop down menus

$(document).ready(function () {

    $('#nav li').hover(
        function () {
            //show its submenu
            $('ul', this).slideDown(200);

        },
        function () {
            //hide its submenu
            $('ul', this).slideUp(100);
        }
    );

});<commit_msg>make ajax sync<commit_after>/*
 * Copyright (C) 2007-2012 Guillaume Pellerin, Parisson
 * Copyright (c) 2011 Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
 * Copyright (c) 2010 Olivier Guilyardi <olivier@samalyse.com>
 *
 * This file is part of TimeSide.
 *
 * TimeSide is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * TimeSide is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with TimeSide.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Riccardo Zaccarelli <riccardo.zaccarelli@gmail.com>
 *          Olivier Guilyardi <olivier@samalyse.com>
 */

/**
 * Class for telemeta global functions.
 * Note that the dollar sign is a reserved keyword in some browsers
 * (see http://davidwalsh.name/dollar-functions)
 * which might be in conflict with jQuery dollar sign.
 */

//returns the full path of the current url location removing the last slash '/' followed by one or more '#', if any
function urlNormalized(){
    var sPath = window.location.href;
    sPath = sPath.replace(/\/#*$/,"");
    return sPath;
}
/**
 *sets up few stuff when the page is ready (see functions below it)
 */
jQuery(document).ready(function() {
    foldInfoBlocks();
    setSelectedMenu();
});

/**
 *function inherited from old code, never touched. Guess fixes the click on the left data table, if any
 */
function foldInfoBlocks() {
    var $J = jQuery;
    var extra = $J('.extraInfos');
    extra.find('.folded dl, .folded table').css('display', 'none');
    extra.find('h4').click(function() {
        $J(this).parents('.extraInfos').children().toggleClass('folded').find('dl, table').toggle(100);
        //toggle toggles the visibility of elements
        return false;
    });
}

/**
 * Global telemeta function which sets the current selected menu according to the current url
 */
function setSelectedMenu(){
    var $J = jQuery;
    var menus = $J('#menu a');
    //build collections/items from http:/site/collections/items,
    //being http:/site/ = window.location.origin

    //function for normalizing paths (removes last n occurrences of the slash)
    var normalize = function(str){
        return str.replace(/\/+#*$/,"");
    }

    var host = window.location.host;
    var protocol = window.location.protocol
    var href = normalize(window.location.href);

    if(!(host) || !(protocol) || !(href)){
        return;
    }

    //var pageOrigin = normalize(window.location.origin); //does not exist in FF, so:
    var pageOrigin = normalize(protocol+"//"+host);
    var pageHref = normalize(href);

    menus.each(function(){
        ///if we are at home, the window location href corresponds to window location origin,
        //so we select only links whose link points EXACTLY to the origin (home link)
        var linkHref = normalize(this.href);
        var elm = $J(this);

        if(linkHref.indexOf("#") != -1){
            var reg = new RegExp("[#]+", "g");
            var baseHref = linkHref.split(reg);
            linkHref = pageOrigin + "/" + baseHref[1]
        }

        if(pageOrigin===pageHref){
            if(pageHref == linkHref){
                elm.addClass('active');
            }else{
                elm.removeClass('active');
            }
        }else{
            //here, on the other hand, we select if a link points to a page or super page
            //of the current page
            if(linkHref!=pageOrigin && pageHref.match("^"+linkHref+".*")){
                elm.addClass('active');
            }else{
                elm.removeClass('active');
            }
        }

    })
}

/*****************************************************************************
 * json(param, method, onSuccesFcn(data, textStatus, jqXHR), onErrorFcn(jqXHR, textStatus, errorThrown))
 * global function to senbd/retrieve data with the server
 *
 * param: the data to be sent or retrieved.
 *   param will be converted to string, escaping quotes newlines and backslashes if necessary.
 *   param can be a javascript string, boolean, number, dictionary and array.
 *       If dictionary or array, it must contain only the above mentioned recognized types.
 *       So, eg, {[" a string"]} is fine, {[/asd/]} not
 *
 * method: the json method, eg "telemeta.update_marker". See base.py
 *
 * onSuccesFcn(data, textStatus, jqXHR) OPTIONAL --IF MISSING, NOTHING HAPPENS --
 *    A function to be called if the request succeeds with the same syntax of jQuery's ajax onSuccess function.
 *    The function gets passed three arguments
 *       The data returned from the server, formatted according to the dataType parameter;
 *       a string describing the status;
 *       and the jqXHR (in jQuery 1.4.x, XMLHttpRequest) object
 *
 * onErrorFcn(jqXHR, textStatus, errorThrown) OPTIONAL. --IF MISSING, THE DEFAULT ERROR DIALOG IS SHOWN--
 *     A function to be called if the request fails with the same syntax of jQuery ajax onError function..
 *     The function receives three arguments:
 *       The jqXHR (in jQuery 1.4.x, XMLHttpRequest) object,
 *       a string describing the type of error that occurred and
 *       an optional exception object, if one occurred.
 *       Possible values for the second argument (besides null) are "timeout", "error", "abort", and "parsererror".
 * ****************************************************************************/

var json = function(param,method,onSuccessFcn,onErrorFcn){
    //this function converts a javascript object to a string
    var toString_ = function(string){
        if(typeof string == "string"){
            //escapes newlines quotes and backslashes
            string = string.replace(/\\/g,"\\\\")
            .replace(/\n/g,"\\n")
            .replace(/"/g,"\\\"");
        }
        var array; //used for arrays and objects (see below)
        if(typeof string == "boolean" || typeof string== "number" || typeof string == "string"){
            string = '"'+string+'"';
        }else if(string instanceof Array){
            array = [];
            for(var i = 0;i <string.length ; i++){
                array.push(toString_(string[i])); //recursive invocation
            }
            string='[';
            string+=array.join(",");
            string+=']';
        }else{
            array = [];
            for(var k in string){
                array.push(toString_(k)+":"+toString_(string[k])); //recursive invocation
            }
            string='{';
            string+=array.join(",");
            string+='}';
        }
        return string;
    };

    //creating the string to send.
    var param2string = toString_(param);
    var data2send = '{"id":"jsonrpc", "params":';
    data2send+=param2string;
    data2send+=', "method":"'
    data2send+=method;
    data2send+='","jsonrpc":"1.0"}';

    var $J = jQuery;
    $J.ajax({
        type: "POST",
        url: 'json/',
        contentType: "application/json",
        async : false;
        data: data2send,
        dataType: "json",
        success: function(data, textStatus, jqXHR){
            if(onSuccessFcn){
                onSuccessFcn(data, textStatus, jqXHR);
            }
        },
        error: function(jqXHR, textStatus, errorThrown){
            if(onErrorFcn){
                onErrorFcn(jqXHR, textStatus, errorThrown);
                return;
            }
            //default:
            var details = "\n(no further info available)";
            if(jqXHR) {
                details="\nThe server responded witha status of "+jqXHR.status+" ("+
                jqXHR.statusText+")\n\nDetails (request responseText):\n"+jqXHR.responseText;
            }
            alert("ERROR: Failed to save"+details);

        }
    });

};

/**
 * function for writing to the console. Catches errors, if any (eg, console == undefined) and does nothing in case
 */
function consolelog(text){
    if(typeof console != 'undefined'){
        var c = console;
        if (c.log) {
            c.log(text);
        }
    }
}

// Drop down menus

$(document).ready(function () {

    $('#nav li').hover(
        function () {
            //show its submenu
            $('ul', this).slideDown(200);

        },
        function () {
            //hide its submenu
            $('ul', this).slideUp(100);
        }
    );

});<|endoftext|>


<commit_before>module.exports = HingeConstraint;

var Constraint = require('./Constraint')
,   RotationalEquation = require('../equations/RotationalEquation')
,   RotationalMotorEquation = require('../equations/RotationalMotorEquation')
,   ContactEquation = require('../equations/ContactEquation')
,   Vec3 = require('../math/Vec3')

/**
 * Hinge constraint. Tries to keep the local body axes equal.
 * @class HingeConstraint
 * @author schteppe
 * @param {RigidBody} bodyA
 * @param {Vec3} pivotA A point defined locally in bodyA. This defines the offset of axisA.
 * @param {Vec3} axisA an axis that bodyA can rotate around.
 * @param {RigidBody} bodyB
 * @param {Vec3} pivotB
 * @param {Vec3} axisB
 * @param {Number} maxForce
 */
function HingeConstraint(bodyA, pivotA, axisA, bodyB, pivotB, axisB, maxForce){
    Constraint.call(this,bodyA,bodyB);

    maxForce = maxForce || 1e6;
    var that = this;
    // Equations to be fed to the solver
    var eqs = this.equations = [
        new RotationalEquation(bodyA,bodyB), // rotational1
        new RotationalEquation(bodyA,bodyB), // rotational2
        new ContactEquation(bodyA,bodyB),    // p2pNormal
        new ContactEquation(bodyA,bodyB),    // p2pTangent1
        new ContactEquation(bodyA,bodyB),    // p2pTangent2
    ];

    this.getRotationalEquation1 =   function(){ return eqs[0]; };
    this.getRotationalEquation2 =   function(){ return eqs[1]; };
    this.getPointToPointEquation1 = function(){ return eqs[2]; };
    this.getPointToPointEquation2 = function(){ return eqs[3]; };
    this.getPointToPointEquation3 = function(){ return eqs[4]; };

    var r1 =        this.getRotationalEquation1();
    var r2 =        this.getRotationalEquation2();
    var normal =    this.getPointToPointEquation1();
    var t1 =        this.getPointToPointEquation2();
    var t2 =        this.getPointToPointEquation3();
    var motor; // not activated by default

    t1.minForce = t2.minForce = normal.minForce = -maxForce;
    t1.maxForce = t2.maxForce = normal.maxForce =  maxForce;

    var unitPivotA = pivotA.unit();
    var unitPivotB = pivotB.unit();

    var axisA_x_pivotA = new Vec3();
    var axisA_x_axisA_x_pivotA = new Vec3();
    var axisB_x_pivotB = new Vec3();
    axisA.cross(unitPivotA,axisA_x_pivotA);
    if(axisA_x_pivotA.norm2() < 0.001){ // pivotA is along the same line as axisA
        unitPivotA.tangents(axisA_x_pivotA,axisA_x_pivotA);
    }
    axisA.cross(axisA_x_pivotA,axisA_x_axisA_x_pivotA);
    axisB.cross(unitPivotB,axisB_x_pivotB);
    if(axisB_x_pivotB.norm2() < 0.001){ // pivotB is along the same line as axisB
        axisB.tangents(axisB_x_pivotB,axisB_x_pivotB);
    }

    axisA_x_pivotA.normalize();
    axisB_x_pivotB.normalize();

    // Motor stuff
    var motorEnabled = false;
    this.motorTargetVelocity = 0;
    this.motorMinForce = -maxForce;
    this.motorMaxForce = maxForce;
    this.enableMotor = function(){
        if(!motorEnabled){
            motor = new RotationalMotorEquation(bodyA,bodyB,maxForce);
            eqs.push(motor);
            motorEnabled = true;
        }
    };
    this.disableMotor = function(){
        if(motorEnabled){
            motorEnabled = false;
            motor = null;
            eqs.pop();
        }
    };

    // Update
    this.update = function(){
        // Update world positions of pivots
        /*
        bodyB.position.vsub(bodyA.position,normal.ni);
        normal.ni.normalize();
        */
        normal.ni.set(1,0,0);
        t1.ni.set(0,1,0);
        t2.ni.set(0,0,1);
        bodyA.quaternion.vmult(pivotA,normal.ri);
        bodyB.quaternion.vmult(pivotB,normal.rj);

        //normal.ni.tangents(t1.ni,t2.ni);
        normal.ri.copy(t1.ri);
        normal.rj.copy(t1.rj);
        normal.ri.copy(t2.ri);
        normal.rj.copy(t2.rj);

        // update rotational constraints
        bodyA.quaternion.vmult(axisA_x_pivotA, r1.ni);
        bodyB.quaternion.vmult(axisB,          r1.nj);
        bodyA.quaternion.vmult(axisA_x_axisA_x_pivotA,  r2.ni);
        bodyB.quaternion.vmult(axisB,           r2.nj);

        if(motorEnabled){
            bodyA.quaternion.vmult(axisA,motor.axisA);
            bodyB.quaternion.vmult(axisB,motor.axisB);
            motor.targetVelocity = that.motorTargetVelocity;
            motor.maxForce = that.motorMaxForce;
            motor.minForce = that.motorMinForce;
        }
    };
};
HingeConstraint.prototype = new Constraint();
<commit_msg>cleaned up hinge constraint<commit_after>module.exports = HingeConstraint;

var Constraint = require('./Constraint')
,   RotationalEquation = require('../equations/RotationalEquation')
,   RotationalMotorEquation = require('../equations/RotationalMotorEquation')
,   ContactEquation = require('../equations/ContactEquation')
,   Vec3 = require('../math/Vec3')

/**
 * Hinge constraint. Tries to keep the local body axes equal.
 * @class HingeConstraint
 * @author schteppe
 * @param {RigidBody} bodyA
 * @param {Vec3} pivotA A point defined locally in bodyA. This defines the offset of axisA.
 * @param {Vec3} axisA an axis that bodyA can rotate around.
 * @param {RigidBody} bodyB
 * @param {Vec3} pivotB
 * @param {Vec3} axisB
 * @param {Number} maxForce
 */
function HingeConstraint(bodyA, pivotA, axisA, bodyB, pivotB, axisB, maxForce){
    Constraint.call(this,bodyA,bodyB);

    maxForce = maxForce || 1e6;
    var that = this;

    // Equations to be fed to the solver
    var eqs = this.equations = [
        new RotationalEquation(bodyA,bodyB), // rotational1
        new RotationalEquation(bodyA,bodyB), // rotational2
        new ContactEquation(bodyA,bodyB),    // p2pNormal
        new ContactEquation(bodyA,bodyB),    // p2pTangent1
        new ContactEquation(bodyA,bodyB),    // p2pTangent2
    ];

    this.pivotA = pivotA;
    this.pivotB = pivotB;
    this.axisA = axisA;
    this.axisB = axisB;

    var r1 =        this.getRotationalEquation1();
    var r2 =        this.getRotationalEquation2();
    var normal =    this.getPointToPointEquation1();
    var t1 =        this.getPointToPointEquation2();
    var t2 =        this.getPointToPointEquation3();
    var motor; // not activated by default

    t1.minForce = t2.minForce = normal.minForce = -maxForce;
    t1.maxForce = t2.maxForce = normal.maxForce =  maxForce;

    var unitPivotA = pivotA.unit();
    var unitPivotB = pivotB.unit();

    var axisA_x_pivotA = this.axisA_x_pivotA = new Vec3();
    var axisA_x_axisA_x_pivotA = this.axisA_x_axisA_x_pivotA = new Vec3();
    var axisB_x_pivotB = this.axisB_x_pivotB = new Vec3();
    axisA.cross(unitPivotA,axisA_x_pivotA);
    if(axisA_x_pivotA.norm2() < 0.001){ // pivotA is along the same line as axisA
        unitPivotA.tangents(axisA_x_pivotA,axisA_x_pivotA);
    }
    axisA.cross(axisA_x_pivotA,axisA_x_axisA_x_pivotA);
    axisB.cross(unitPivotB,axisB_x_pivotB);
    if(axisB_x_pivotB.norm2() < 0.001){ // pivotB is along the same line as axisB
        axisB.tangents(axisB_x_pivotB,axisB_x_pivotB);
    }

    axisA_x_pivotA.normalize();
    axisB_x_pivotB.normalize();

    // Motor stuff
    this.motorEnabled = false;
    this.motorTargetVelocity = 0;
    this.motorMinForce = -maxForce;
    this.motorMaxForce = maxForce;
    this.motorEquation = new RotationalMotorEquation(bodyA,bodyB,maxForce);
};
HingeConstraint.prototype = new Constraint();

HingeConstraint.prototype.enableMotor = function(){
    if(!this.motorEnabled){
        this.equations.push(this.motorEquation);
        this.motorEnabled = true;
    }
};

HingeConstraint.prototype.disableMotor = function(){
    if(this.motorEnabled){
        this.motorEnabled = false;
        this.equations.pop();
    }
};

HingeConstraint.prototype.update = function(){
    var bodyA = this.bodyA,
        bodyB = this.bodyB,
        eqs = this.equations,
        motor = this.motorEquation,
        r1 = eqs[0],
        r2 = eqs[1],
        normal = eqs[2],
        t1 = eqs[3],
        t2 = eqs[4];

    // Update world positions of pivots
    /*
    bodyB.position.vsub(bodyA.position,normal.ni);
    normal.ni.normalize();
    */
    normal.ni.set(1,0,0);
    t1.ni.set(0,1,0);
    t2.ni.set(0,0,1);
    bodyA.quaternion.vmult(this.pivotA,normal.ri);
    bodyB.quaternion.vmult(this.pivotB,normal.rj);

    //normal.ni.tangents(t1.ni,t2.ni);
    normal.ri.copy(t1.ri);
    normal.rj.copy(t1.rj);
    normal.ri.copy(t2.ri);
    normal.rj.copy(t2.rj);

    // update rotational constraints
    bodyA.quaternion.vmult(this.axisA_x_pivotA,         r1.ni);
    bodyB.quaternion.vmult(this.axisB,                  r1.nj);
    bodyA.quaternion.vmult(this.axisA_x_axisA_x_pivotA, r2.ni);
    bodyB.quaternion.vmult(this.axisB,                  r2.nj);

    if(this.motorEnabled){
        bodyA.quaternion.vmult(this.axisA,motor.axisA);
        bodyB.quaternion.vmult(this.axisB,motor.axisB);
        motor.targetVelocity = this.motorTargetVelocity;
        motor.maxForce = this.motorMaxForce;
        motor.minForce = this.motorMinForce;
    }
};

HingeConstraint.prototype.getRotationalEquation1 =   function(){ return this.equations[0]; };
HingeConstraint.prototype.getRotationalEquation2 =   function(){ return this.equations[1]; };
HingeConstraint.prototype.getPointToPointEquation1 = function(){ return this.equations[2]; };
HingeConstraint.prototype.getPointToPointEquation2 = function(){ return this.equations[3]; };
HingeConstraint.prototype.getPointToPointEquation3 = function(){ return this.equations[4]; };
<|endoftext|>