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

'use strict'

const inquirer = require('inquirer')
const rc = require('rc')
const path = require('path')
const _ = require('lodash')
const fs = require('fs')
const ini = require('ini')
const updateNotifier = require('update-notifier')
const rimraf = require('rimraf')
const chalk = require('chalk')
const utils = require('./utils')
const showTime = require('./')

const pkg = require('./package.json')

const ui = new inquirer.ui.BottomBar()
const log = ui.log.write.bind(ui.log)

const win = process.platform === 'win32'
const home = win ? process.env.USERPROFILE : process.env.HOME
const args = rc('show-time', {
  cache: path.join(home, '.show-time', 'cache'),
  player: null,
  feed: null,
  lang: 'eng',
  port: '8888',
  'peer-port': '6881',
  log: log,
  offline: false
})
const options = _.pick(args, 'cache', 'player', 'feed', 'lang', 'port', 'peer-port', 'log', 'offline')

const players = [
  'chromecast',
  'vlc',
  'airplay',
  'mplayer',
  'smplayer',
  'mpchc',
  'potplayer',
  'mpv',
  'omx',
  'webplay',
  'jack'
]

const configFile = path.join(home, '.show-time', 'config')

if (args.download) {
  options.port = 0
  options['peer-port'] = 0
  options.player = false
}

if (args['clear-cache']) {
  if (!options.cache) {
    console.error('No cache directory configured')
    process.exit(0)
  } else {
    utils.dirStats(options.cache)
    .then(stats => {
      console.log('Removing %s file(s), freeing %s', stats.count, stats.hsize)
      rimraf.sync(options.cache)
    })
    .then(() => {
      console.log(chalk.bold.green('OK'))
      process.exit(0)
    })
    .catch(err => {
      console.error(chalk.bold.red('Error: ' + err))
      process.exit(1)
    })
  }
}

if (args.help || args.h) {
  console.log('show-time [options]')
  console.log('')
  console.log('Options:')
  console.log('  --version, -v    Show version and exit')
  console.log('  --help, -h       Show this help and exit')
  console.log('  --clear-cache    Clears cache and exit')
  console.log('  --configure      Configuration wizard')
  console.log('  --config <file>  Use alternative configuration file')
  console.log('  --cache <path>   Path to cache (--no-cache to disable)')
  console.log('  --player <name>  Automatically play to given player')
  console.log('  --feed <url>     ShowRSS feed URL')
  console.log('  --lang <lang>    Preferred language for subtitles')
  console.log('  --port <port>    Stream port (default 8888)')
  console.log('  --peer-port <port> Peer listening port (default 6881)')
  console.log('  --download       Download only mode')
  console.log('')
  console.log('Valid players: ' + players.join(', '))
  process.exit(0)
}

if (args.version || args.v) {
  console.log(pkg.version)
  process.exit(0)
}

updateNotifier({
  packageName: pkg.name,
  packageVersion: pkg.version
}).notify()

// Check for old 'cache/download' directory, and warn user he should remove it
if (utils.canRead(utils.cachePath(options.cache, 'download')) && !args.stopAskDeleteCacheDownload) {
  console.error('%s: %s', chalk.bold.red('WARNING'), chalk.red('downloads cache format has changed, you should delete the old one to avoid wasting space'))
  utils.dirStats(utils.cachePath(options.cache, 'download'))
  .then(stats => utils.ask.list(
    'Would you like to remove it now (' + stats.count + ' files, ' + stats.hsize + ')?', [
    { name: 'Yes, remove it now', value: 'yes' },
    { name: 'No, remove it later', value: 'no' },
    { name: 'No, and don\'t ask me again, I\'ll handle it myself', value: 'never' }
  ], 'yes'))
  .then(answer => {
    if (answer === 'never') {
      // Persist this choice in config file
      fs.writeFileSync(configFile, Buffer.concat([fs.readFileSync(configFile), new Buffer('\n; Do not ask again about deleting cache/download folder\nstopAskDeleteCacheDownload = 1\n')]))
    } else if (answer === 'yes') {
      // Do delete
      rimraf.sync(utils.cachePath(options.cache, 'download'))
    }
  })
  .then(main)
  .catch(err => { log('Error: ' + err); process.exit(1) })
} else {
  main()
}

function configure () {
  const startWizard = args.configure
    ? Promise.resolve(true)
    : utils.ask.confirm('Missing configuration, would you like to start configuration helper?')

  return startWizard
  .then(cont => cont || process.exit(0))
  .then(_.constant(_.omit(options, 'log')))
  .then(conf => utils.ask.input('Enter your ShowRSS feed URL (https://showrss.info/ free, no mail):', conf.feed).then(feed => feed ? _.defaults({ feed }, conf) : (console.error('Feed is required'), process.exit(1))))
  .then(conf => utils.ask.input('Preferred subtitles language (3 letters, i.e. "eng", "fre"…)?', conf.lang).then(lang => _.defaults({ lang }, conf)))
  .then(conf => utils.ask.list('Default player?', ['disabled'].concat(players), conf.player).then(player => (player === 'disabled') ? null : player).then(player => _.defaults({ player }, conf)))
  .then(conf => utils.ask.confirm('Advanced options?', false).then(advanced => advanced
    ? utils.ask.confirm('Enable cache?', !!conf.cache)
        .then(cache => cache ? utils.ask.input('Cache path', conf.cache) : null)
        .then(cache => _.defaults({ cache }, conf))
      .then(conf => utils.ask.input('Stream server port?', conf.port).then(port => _.defaults({ port }, conf)))
      .then(conf => utils.ask.input('Peer discovery port?', conf['peer-port']).then(peerPort => _.defaults({ 'peer-port': peerPort }, conf)))
    : conf
  ))
  .then(conf => utils.createDir(path.dirname(configFile)).then(_.constant(conf)))
  .then(conf => fs.writeFileSync(configFile, ini.encode(conf)))
  .then(() => console.log('Successfully saved configuration to "' + configFile + '"'))
  .catch(err => (console.error('Failed saving configuration: ' + err.message), process.exit(1)))
}

function start () {
  return showTime(options)
  .then(() => { log('Terminated.'); process.exit(0) })
  .catch(err => { log('Error: ' + err); process.exit(1) })
}

function main () {
  if (!options.feed || args.configure) {
    return configure()
  } else {
    return start()
  }
}
<commit_msg>fix(cli): do not do anything else when clearing cache (fixes cli crashing when trying to clear cache while offline)<commit_after>#!/usr/bin/env node

'use strict'

const inquirer = require('inquirer')
const rc = require('rc')
const path = require('path')
const _ = require('lodash')
const fs = require('fs')
const ini = require('ini')
const updateNotifier = require('update-notifier')
const rimraf = require('rimraf')
const chalk = require('chalk')
const utils = require('./utils')
const showTime = require('./')

const pkg = require('./package.json')

const ui = new inquirer.ui.BottomBar()
const log = ui.log.write.bind(ui.log)

const win = process.platform === 'win32'
const home = win ? process.env.USERPROFILE : process.env.HOME
const args = rc('show-time', {
  cache: path.join(home, '.show-time', 'cache'),
  player: null,
  feed: null,
  lang: 'eng',
  port: '8888',
  'peer-port': '6881',
  log: log,
  offline: false
})
const options = _.pick(args, 'cache', 'player', 'feed', 'lang', 'port', 'peer-port', 'log', 'offline')

const players = [
  'chromecast',
  'vlc',
  'airplay',
  'mplayer',
  'smplayer',
  'mpchc',
  'potplayer',
  'mpv',
  'omx',
  'webplay',
  'jack'
]

const configFile = path.join(home, '.show-time', 'config')

if (args.download) {
  options.port = 0
  options['peer-port'] = 0
  options.player = false
}

if (args['clear-cache']) {
  if (!options.cache) {
    console.error('No cache directory configured')
    process.exit(0)
  } else {
    return utils.dirStats(options.cache)
    .then(stats => {
      console.log('Removing %s file(s), freeing %s', stats.count, stats.hsize)
      rimraf.sync(options.cache)
    })
    .then(() => {
      console.log(chalk.bold.green('OK'))
      process.exit(0)
    })
    .catch(err => {
      console.error(chalk.bold.red('Error: ' + err))
      process.exit(1)
    })
  }
}

if (args.help || args.h) {
  console.log('show-time [options]')
  console.log('')
  console.log('Options:')
  console.log('  --version, -v    Show version and exit')
  console.log('  --help, -h       Show this help and exit')
  console.log('  --clear-cache    Clears cache and exit')
  console.log('  --configure      Configuration wizard')
  console.log('  --config <file>  Use alternative configuration file')
  console.log('  --cache <path>   Path to cache (--no-cache to disable)')
  console.log('  --player <name>  Automatically play to given player')
  console.log('  --feed <url>     ShowRSS feed URL')
  console.log('  --lang <lang>    Preferred language for subtitles')
  console.log('  --port <port>    Stream port (default 8888)')
  console.log('  --peer-port <port> Peer listening port (default 6881)')
  console.log('  --download       Download only mode')
  console.log('')
  console.log('Valid players: ' + players.join(', '))
  process.exit(0)
}

if (args.version || args.v) {
  console.log(pkg.version)
  process.exit(0)
}

updateNotifier({
  packageName: pkg.name,
  packageVersion: pkg.version
}).notify()

// Check for old 'cache/download' directory, and warn user he should remove it
if (utils.canRead(utils.cachePath(options.cache, 'download')) && !args.stopAskDeleteCacheDownload) {
  console.error('%s: %s', chalk.bold.red('WARNING'), chalk.red('downloads cache format has changed, you should delete the old one to avoid wasting space'))
  utils.dirStats(utils.cachePath(options.cache, 'download'))
  .then(stats => utils.ask.list(
    'Would you like to remove it now (' + stats.count + ' files, ' + stats.hsize + ')?', [
    { name: 'Yes, remove it now', value: 'yes' },
    { name: 'No, remove it later', value: 'no' },
    { name: 'No, and don\'t ask me again, I\'ll handle it myself', value: 'never' }
  ], 'yes'))
  .then(answer => {
    if (answer === 'never') {
      // Persist this choice in config file
      fs.writeFileSync(configFile, Buffer.concat([fs.readFileSync(configFile), new Buffer('\n; Do not ask again about deleting cache/download folder\nstopAskDeleteCacheDownload = 1\n')]))
    } else if (answer === 'yes') {
      // Do delete
      rimraf.sync(utils.cachePath(options.cache, 'download'))
    }
  })
  .then(main)
  .catch(err => { log('Error: ' + err); process.exit(1) })
} else {
  main()
}

function configure () {
  const startWizard = args.configure
    ? Promise.resolve(true)
    : utils.ask.confirm('Missing configuration, would you like to start configuration helper?')

  return startWizard
  .then(cont => cont || process.exit(0))
  .then(_.constant(_.omit(options, 'log')))
  .then(conf => utils.ask.input('Enter your ShowRSS feed URL (https://showrss.info/ free, no mail):', conf.feed).then(feed => feed ? _.defaults({ feed }, conf) : (console.error('Feed is required'), process.exit(1))))
  .then(conf => utils.ask.input('Preferred subtitles language (3 letters, i.e. "eng", "fre"…)?', conf.lang).then(lang => _.defaults({ lang }, conf)))
  .then(conf => utils.ask.list('Default player?', ['disabled'].concat(players), conf.player).then(player => (player === 'disabled') ? null : player).then(player => _.defaults({ player }, conf)))
  .then(conf => utils.ask.confirm('Advanced options?', false).then(advanced => advanced
    ? utils.ask.confirm('Enable cache?', !!conf.cache)
        .then(cache => cache ? utils.ask.input('Cache path', conf.cache) : null)
        .then(cache => _.defaults({ cache }, conf))
      .then(conf => utils.ask.input('Stream server port?', conf.port).then(port => _.defaults({ port }, conf)))
      .then(conf => utils.ask.input('Peer discovery port?', conf['peer-port']).then(peerPort => _.defaults({ 'peer-port': peerPort }, conf)))
    : conf
  ))
  .then(conf => utils.createDir(path.dirname(configFile)).then(_.constant(conf)))
  .then(conf => fs.writeFileSync(configFile, ini.encode(conf)))
  .then(() => console.log('Successfully saved configuration to "' + configFile + '"'))
  .catch(err => (console.error('Failed saving configuration: ' + err.message), process.exit(1)))
}

function start () {
  return showTime(options)
  .then(() => { log('Terminated.'); process.exit(0) })
  .catch(err => { log('Error: ' + err); process.exit(1) })
}

function main () {
  if (!options.feed || args.configure) {
    return configure()
  } else {
    return start()
  }
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';
var brightness = require('brightness');
var meow = require('meow');
var progressControl = require('progress-control');
var chalk = require('chalk');
var cliCursor = require('cli-cursor');

var cli = meow({
	help: [
		'Example',
		'  $ brightness',
		'  $ brightness 0.8'
	]
});

try {
	if (!cli.input.length) {
		brightness.get(function (err, val) {
			if (err) {
				console.error(err.message);
				process.exit(1);
			}

			brightness.set(val, function (err) {
				if (err) {
					console.error(err.message);
					process.exit(1);
				}

				function updateBar(val) {
					brightness.set(val, function (err) {
						if (err) {
							console.error(err.message);
							process.exit(1);
						}
					});

					bar.update(val, {val: val * 100 + '%'});
				}

				cliCursor.hide();

				var text = '[:bar] :val   ' + chalk.dim('Use up/down arrows');
				var bar = progressControl(text, {total: 10}, {
					up: function () {
						val = Math.min(Math.round((val + 0.1) * 10) / 10, 1);
						updateBar(val);
					},
					down: function () {
						val = Math.max(Math.round((val - 0.1) * 10) / 10, 0);
						updateBar(val);
					}
				});

				updateBar(val);
			});
		});

		return;
	}

	brightness.set(parseFloat(cli.input[0], 10), function (err) {
		if (err) {
			console.error(err.message);
			process.exit(1);
		}
	});
} catch (err) {
	console.error(err.message);
	process.exit(1);
}
<commit_msg>round initial brightness value<commit_after>#!/usr/bin/env node
'use strict';
var brightness = require('brightness');
var meow = require('meow');
var progressControl = require('progress-control');
var chalk = require('chalk');
var cliCursor = require('cli-cursor');

var cli = meow({
	help: [
		'Example',
		'  $ brightness',
		'  $ brightness 0.8'
	]
});

try {
	if (!cli.input.length) {
		brightness.get(function (err, val) {
			if (err) {
				console.error(err.message);
				process.exit(1);
			}

			brightness.set(val, function (err) {
				if (err) {
					console.error(err.message);
					process.exit(1);
				}

				val = Math.round((val) * 10) / 10;

				function updateBar(val) {
					brightness.set(val, function (err) {
						if (err) {
							console.error(err.message);
							process.exit(1);
						}
					});

					bar.update(val, {val: val * 100 + '%'});
				}

				cliCursor.hide();

				var text = '[:bar] :val   ' + chalk.dim('Use up/down arrows');
				var bar = progressControl(text, {total: 10}, {
					up: function () {
						val = Math.min(Math.round((val + 0.1) * 10) / 10, 1);
						updateBar(val);
					},
					down: function () {
						val = Math.max(Math.round((val - 0.1) * 10) / 10, 0);
						updateBar(val);
					}
				});

				updateBar(val);
			});
		});

		return;
	}

	brightness.set(parseFloat(cli.input[0], 10), function (err) {
		if (err) {
			console.error(err.message);
			process.exit(1);
		}
	});
} catch (err) {
	console.error(err.message);
	process.exit(1);
}
<|endoftext|>


<commit_before>/*eslint no-console: ["error", {allow: ["log"]}] */

var validate  = require('./index.js');
var colors    = require('colors/safe');
var cliff     = require('cliff');
var pluralize = require('pluralize');
var bytes     = require('bytes');
var fs        = require('fs');

module.exports = function(dir, options) {
    if (fs.existsSync(dir)) {
        if (options.json) {
            validate.BIDS(dir, options, function (issues, summary) {
                console.log(JSON.stringify({ issues, summary }));
            });
        } else {
            validate.BIDS(dir, options, function (issues, summary) {
                var errors = issues.errors;
                var warnings = issues.warnings;
                if (issues.errors.length === 1 && issues.errors[0].code === "61") {
                    console.log(
                        colors.red(
                            "The directory " +
                            dir +
                            " failed an initial Quick Test. This means the basic names and structure of the files and directories do not comply with BIDS specification. For more info go to http://bids.neuroimaging.io/"
                        )
                    );
                } else if (issues.config && issues.config.length >= 1) {
                    console.log(colors.red("Invalid Config File"));
                    for (var i = 0; i < issues.config.length; i++) {
                        var issue = issues.config[i];
                        issue.file.file = { relativePath: issue.file.path };
                        issue.files = [issue.file];
                    }
                    logIssues(issues.config, "red", options);
                } else if (errors.length >= 1 || warnings.length >= 1) {
                    logIssues(errors, "red", options);
                    logIssues(warnings, "yellow", options);
                } else {
                    console.log(
                        colors.green("This dataset appears to be BIDS compatible.")
                    );
                }
                logSummary(summary);
                if (
                    issues === "Invalid" ||
                    (errors && errors.length >= 1) ||
                    (issues.config && issues.config.length >= 1)
                ) {
                    process.exit(1);
                }
            });
        }
    } else {
        console.log(colors.red(dir + " does not exist"));
        process.exit(2);
    }
};

function logIssues (issues, color, options) {
    for (var i = 0; i < issues.length; i++) {
        var issue = issues[i];
        console.log('\t' + colors[color]((i + 1) + ': ' + issue.reason + ' (code: ' + issue.code + ' - ' + issue.key + ')'));
        for (var j = 0; j < issue.files.length; j++) {
            var file = issues[i].files[j];
            if (!file || !file.file) {continue;}
            console.log('\t\t.' + file.file.relativePath);
            if (options.verbose) {console.log('\t\t\t' + file.reason);}
            if (file.line) {
                var msg = '\t\t\t@ line: ' + file.line;
                if (file.character) {
                    msg += ' character: ' + file.character;
                }
                console.log(msg);
            }
            if (file.evidence) {
                console.log('\t\t\tEvidence: ' + file.evidence);
            }

        }
        if (issue.additionalFileCount > 0) {
            console.log('\t\t'+colors[color]('... and '+issue.additionalFileCount+' more files having this issue (Use --verbose to see them all).'));
        }
        console.log();
    }
}

function logSummary (summary) {
    if (summary) {
        var numSessions = summary.sessions.length > 0 ? summary.sessions.length : 1;

        // data
        var column1 = [
                summary.totalFiles + ' ' + pluralize('File', summary.totalFiles) + ', ' + bytes(summary.size),
                summary.subjects.length + ' - ' + pluralize('Subject', summary.subjects.length),
                numSessions + ' - ' + pluralize('Session', numSessions)
            ],
            column2 = summary.tasks,
            column3 = summary.modalities;

        var longestColumn = Math.max(column1.length, column2.length, column3.length);
        var pad = '       ';

        // headers
        var headers = [pad, colors.blue.underline('Summary:') + pad, colors.blue.underline('Available Tasks:') + pad, colors.blue.underline('Available Modalities:')]

        // rows
        var rows = [headers];
        for (var i = 0; i < longestColumn; i++) {
            var val1, val2, val3;
            val1 = column1[i] ? column1[i] + pad : '';
            val2 = column2[i] ? column2[i] + pad : '';
            val3 = column3[i] ? column3[i] : '';
            rows.push(['       ', val1, val2, val3]);
        }
        console.log(cliff.stringifyRows(rows));

        console.log();
    }
}
<commit_msg>Added Neurostars message<commit_after>/*eslint no-console: ["error", {allow: ["log"]}] */

var validate  = require('./index.js');
var colors    = require('colors/safe');
var cliff     = require('cliff');
var pluralize = require('pluralize');
var bytes     = require('bytes');
var fs        = require('fs');

module.exports = function(dir, options) {
    if (fs.existsSync(dir)) {
        if (options.json) {
            validate.BIDS(dir, options, function (issues, summary) {
                console.log(JSON.stringify({ issues, summary }));
            });
        } else {
            validate.BIDS(dir, options, function (issues, summary) {
                var errors = issues.errors;
                var warnings = issues.warnings;
                if (issues.errors.length === 1 && issues.errors[0].code === "61") {
                    console.log(
                        colors.red(
                            "The directory " +
                            dir +
                            " failed an initial Quick Test. This means the basic names and structure of the files and directories do not comply with BIDS specification. For more info go to http://bids.neuroimaging.io/"
                        )
                    );
                } else if (issues.config && issues.config.length >= 1) {
                    console.log(colors.red("Invalid Config File"));
                    for (var i = 0; i < issues.config.length; i++) {
                        var issue = issues.config[i];
                        issue.file.file = { relativePath: issue.file.path };
                        issue.files = [issue.file];
                    }
                    logIssues(issues.config, "red", options);
                } else if (errors.length >= 1 || warnings.length >= 1) {
                    logIssues(errors, "red", options);
                    logIssues(warnings, "yellow", options);
                } else {
                    console.log(
                        colors.green("This dataset appears to be BIDS compatible.")
                    );
                }
                logSummary(summary);
                if (
                    issues === "Invalid" ||
                    (errors && errors.length >= 1) ||
                    (issues.config && issues.config.length >= 1)
                ) {
                    process.exit(1);
                }
            });
        }
    } else {
        console.log(colors.red(dir + " does not exist"));
        process.exit(2);
    }
};

function logIssues (issues, color, options) {
    for (var i = 0; i < issues.length; i++) {
        var issue = issues[i];
        console.log('\t' + colors[color]((i + 1) + ': ' + issue.reason + ' (code: ' + issue.code + ' - ' + issue.key + ')'));
        for (var j = 0; j < issue.files.length; j++) {
            var file = issues[i].files[j];
            if (!file || !file.file) {continue;}
            console.log('\t\t.' + file.file.relativePath);
            if (options.verbose) {console.log('\t\t\t' + file.reason);}
            if (file.line) {
                var msg = '\t\t\t@ line: ' + file.line;
                if (file.character) {
                    msg += ' character: ' + file.character;
                }
                console.log(msg);
            }
            if (file.evidence) {
                console.log('\t\t\tEvidence: ' + file.evidence);
            }

        }
        if (issue.additionalFileCount > 0) {
            console.log('\t\t'+colors[color]('... and '+issue.additionalFileCount+' more files having this issue (Use --verbose to see them all).'));
        }
        console.log();
    }
}

function logSummary (summary) {
    if (summary) {
        var numSessions = summary.sessions.length > 0 ? summary.sessions.length : 1;

        // data
        var column1 = [
                summary.totalFiles + ' ' + pluralize('File', summary.totalFiles) + ', ' + bytes(summary.size),
                summary.subjects.length + ' - ' + pluralize('Subject', summary.subjects.length),
                numSessions + ' - ' + pluralize('Session', numSessions)
            ],
            column2 = summary.tasks,
            column3 = summary.modalities;

        var longestColumn = Math.max(column1.length, column2.length, column3.length);
        var pad = '       ';

        // headers
        var headers = [pad, colors.blue.underline('Summary:') + pad, colors.blue.underline('Available Tasks:') + pad, colors.blue.underline('Available Modalities:')]

        // rows
        var rows = [headers];
        for (var i = 0; i < longestColumn; i++) {
            var val1, val2, val3;
            val1 = column1[i] ? column1[i] + pad : '';
            val2 = column2[i] ? column2[i] + pad : '';
            val3 = column3[i] ? column3[i] : '';
            rows.push(['       ', val1, val2, val3]);
        }
        console.log(cliff.stringifyRows(rows));

        console.log();

        //Neurostars message
console.log(colors.red("If you have any questions please post on https://neurostars.org/tags/bids"));

        console.log();
    }
}
<|endoftext|>


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

process.title = 'enable-travis';

var chalk = require('chalk');
var symbol = require('log-symbols');
var inquirer = require('inquirer');

var repo = require('git-repo-name');
var user = require('git-user-name');
var name = require('git-username');
var pkg = require('load-pkg');

var username = name() || user();
var repository = repo() || pkg && pkg.name;
var enable = require('./');

run(function (env) {
  enable(env.repo, env, function (err, res) {
    if (err) throw(err);
    if (res && res.result) {
      symbol.success + ' ' + console.log(chalk.green(env.repo, 'has been enabled!'));
    }
  });
});

function run(cb) {
  console.log(chalk.cyan('Please provide your github username and password:'));
  console.log(chalk.gray('(answers are never stored):'));
  console.log();

  var prompts = [];

  prompts.push({
    type: "input",
    name: 'username',
    message: chalk.bold('username'),
    default: username
  });

  prompts.push({
    type: "password",
    name: 'password',
    message: chalk.bold('password'),
    default: null
  });

  prompts.push({
    type: "input",
    name: 'repo',
    message: chalk.bold('owner/repo'),
    default: username + '/' + repository
  });

  inquirer.prompt(prompts, function (answer) {
    if(answer) {
      if (answer.repo && answer.repo.indexOf('/') === -1) {
        console.log(chalk.red('github repo must be in the form of `owner/repo'));
        process.exit(1);
      }
      cb(answer);
    } else {
      console.log(chalk.green('\n  Got it. All is good.'));
      process.exit(0);
    }
  });
}
<commit_msg>adds notif for projects that don't exist<commit_after>#!/usr/bin/env node

process.title = 'enable-travis';

var chalk = require('chalk');
var symbol = require('log-symbols');
var inquirer = require('inquirer');

var repo = require('git-repo-name');
var user = require('git-user-name');
var name = require('git-username');
var pkg = require('load-pkg');

var username = name() || user();
var repository = repo() || pkg && pkg.name;
var enable = require('./');

run(function (env) {
  enable(env.repo, env, function (err, res) {
    if (err) {
      console.log(chalk.yellow('Oops! Travis doesn\'t seem know about this project yet.'));
      console.log(chalk.yellow('Check to make sure your projects are up-to-date.'));
      process.exit(0);
    }
    if (res && res.result) {
      symbol.success + ' ' + console.log(chalk.green(env.repo, 'has been enabled!'));
    }
  });
});

function run(cb) {
  console.log(chalk.cyan('Please provide your github username and password:'));
  console.log(chalk.gray('(answers are never stored):'));
  console.log();

  var prompts = [];

  prompts.push({
    type: "input",
    name: 'username',
    message: chalk.bold('username'),
    default: username
  });

  prompts.push({
    type: "password",
    name: 'password',
    message: chalk.bold('password'),
    default: null
  });

  prompts.push({
    type: "input",
    name: 'repo',
    message: chalk.bold('owner/repo'),
    default: username + '/' + repository
  });

  inquirer.prompt(prompts, function (answer) {
    if(answer) {
      if (answer.repo && answer.repo.indexOf('/') === -1) {
        console.log(chalk.red('github repo must be in the form of `owner/repo'));
        process.exit(1);
      }
      cb(answer);
    } else {
      console.log(chalk.green('\n  Got it. All is good.'));
      process.exit(0);
    }
  });
}
<|endoftext|>


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

'use strict';

const dns = require('dns');
const https = require('https');
const logUpdate = require('log-update');
const colors = require('colors/safe');

const arg = process.argv[2];
const arrow = colors.cyan.bold('›');

if (!arg || arg === '-h' || arg === '--help') {
	console.log(`
 ${colors.cyan('Usage   :')} facebook-id-of ${colors.blue('<username>\n')}
 ${colors.cyan('Example :')} facebook-id-of ${colors.yellow('RishiDotJS\n')}
 ${colors.cyan('Help    :')} facebook-id-of ${colors.green('-h')} ${colors.dim('--help')}
 `);
	process.exit(1);
}

const updateNotifier = require('update-notifier');
const pkg = require('./package.json');

updateNotifier({pkg}).notify();

const userArgs = arg;
const pathReq = `/${userArgs}`;

const options = {
	hostname: 'www.facebook.com',
	port: 443,
	path: pathReq,
	method: 'GET',
	headers: {
		'accept': 'text/html,application/json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
		'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36',
		'Host': 'www.facebook.com',
		'Connection': 'Keep-Alive',
		'Accept-Language': 'en-GB,en-US;q=0.8,en;q=0.6'
	}
};

dns.lookup('facebook.com', err => {
	if (err && err.code === 'ENOTFOUND') {
		logUpdate(`\n${colors.red.bold(arrow)} Please check your internet connection`);
		process.exit(1);
	} else {
		logUpdate(`\n${arrow} ${colors.dim('Fetching UserID. Please wait!')}`);
	}
});

const req = https.request(options, res => {
	if (res.statusCode === 200) {
		logUpdate(`${colors.cyan.bold('\n›')} ${colors.dim(`Sorry "${arg}" is a facebook user!`)}\n`);
	}

	let store = '';
	res.setEncoding('utf8');

	res.on('data', d => {
		store += d;
	});

	res.on('end', () => {
		const rePattern = new RegExp(/entity_id":"\d*/);
		const arrMatches = store.match(rePattern);

		if (arrMatches && arrMatches[0]) {
			logUpdate();
			console.log(`${colors.cyan.bold(`${arrow}`)} ${colors.dim('Facebook ID of')} ${arg} ${colors.dim('is')} ${arrMatches[0].replace('entity_id":"', '')}\n`);
		} else {
			logUpdate(`${colors.cyan.bold('\n›')} ${colors.dim(`Sorry "${arg}" is not a facebook user!`)}\n`);
		}
	});
});
req.end();
<commit_msg>minor changes<commit_after>#!/usr/bin/env node

'use strict';

const dns = require('dns');
const https = require('https');
const logUpdate = require('log-update');
const colors = require('colors/safe');

const arg = process.argv[2];
const arrow = colors.cyan.bold('›');

if (!arg || arg === '-h' || arg === '--help') {
	console.log(`
 ${colors.cyan('Usage   :')} facebook-id-of ${colors.blue('<username>\n')}
 ${colors.cyan('Example :')} facebook-id-of ${colors.yellow('RishiDotJS\n')}
 ${colors.cyan('Help    :')} facebook-id-of ${colors.green('-h')} ${colors.dim('--help')}
 `);
	process.exit(1);
}

const updateNotifier = require('update-notifier');
const pkg = require('./package.json');

updateNotifier({pkg}).notify();

const userArgs = arg;
const pathReq = `/${userArgs}`;

const options = {
	hostname: 'www.facebook.com',
	port: 443,
	path: pathReq,
	method: 'GET',
	headers: {
		'accept': 'text/html,application/json,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
		'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36',
		'Host': 'www.facebook.com',
		'Connection': 'Keep-Alive',
		'Accept-Language': 'en-GB,en-US;q=0.8,en;q=0.6'
	}
};

dns.lookup('facebook.com', err => {
	if (err && err.code === 'ENOTFOUND') {
		logUpdate(`\n${colors.red.bold(arrow)} Please check your internet connection`);
		process.exit(1);
	} else {
		logUpdate(`\n${arrow} ${colors.dim('Fetching UserID. Please wait!')}`);
	}
});

const req = https.request(options, res => {
	if (res.statusCode === 200) {
		logUpdate(`${colors.cyan.bold('\n›')} ${colors.yellow(arg)} ${colors.dim(`is a facebook user!`)}\n`);
	}

	let store = '';
	res.setEncoding('utf8');

	res.on('data', d => {
		store += d;
	});

	res.on('end', () => {
		const rePattern = new RegExp(/entity_id":"\d*/);
		const arrMatches = store.match(rePattern);

		if (arrMatches && arrMatches[0]) {
			logUpdate();
			console.log(`${colors.cyan.bold(`${arrow}`)} ${colors.dim('Facebook ID of')} ${arg} ${colors.dim('is')} ${arrMatches[0].replace('entity_id":"', '')}\n`);
		} else {
			logUpdate(`${colors.cyan.bold('\n›')} ${colors.dim(`Sorry "${arg}" is not a facebook user!`)}\n`);
		}
	});
});
req.end();
<|endoftext|>


<commit_before>#!/usr/bin/env node
// `yargs/yargs` required to work with webpack, see here.
// https://github.com/yargs/yargs/issues/781
var yargs = require('yargs/yargs');
var Ganache = require("ganache-core");
var pkg = require("./package.json");
var corepkg = require("./node_modules/ganache-core/package.json");
var URL = require("url");
var Web3 = require("web3");
var web3 = new Web3(); // Used only for its BigNumber library.
var fs = require("fs");

var parser = yargs()
.option("unlock", {
  type: "string",
  alias: "u"
});

var argv = parser.parse(process.argv);

if (argv.help || argv['?']) {
  console.log("");
  console.log("testrpc: Fast Ethereum RPC client for testing and development");
  console.log("  Full docs: https://github.com/ethereumjs/testrpc");
  console.log("");
  console.log("Usage: testrpc [options]");
  console.log("  options:");
  console.log("  --port/-p <port to bind to, default 8545>");
  console.log("  --host/-h <host to bind to, default 0.0.0.0>");
  console.log("  --fork/-f <url>   (Fork from another currently running Ethereum client at a given block)");
  console.log("");
  console.log("  --db <db path>   (directory to save chain db)");
  console.log("  --seed <seed value for PRNG, default random>");
  console.log("  --deterministic/-d     (uses fixed seed)");
  console.log("  --mnemonic/-m <mnemonic>");
  console.log("  --accounts/-a <number of accounts to generate at startup>");
  console.log("  --acctKeys <path to file>  (saves generated accounts and private keys as JSON object in specified file)");
  console.log("  --secure/-s   (Lock accounts by default)");
  console.log("  --unlock <accounts>   (Comma-separated list of accounts or indices to unlock)");
  console.log("");
  console.log("  --blocktime/-b <block time in seconds>");
  console.log("  --networkId/-i <network id> (default current time)");
  console.log("  --gasPrice/-g <gas price>   (default 20000000000)");
  console.log("  --gasLimit/-l <gas limit>   (default 0x47E7C4)");
  console.log("");
  console.log("  --debug       (Output VM opcodes for debugging)");
  console.log("  --verbose/-v");
  console.log("  --mem         (Only show memory output, not tx history)");
  console.log("");
  console.log("  --help / -?    (this output)");
  console.log("");
  process.exit(0);
}

function parseAccounts(accounts) {
  function splitAccount(account) {
    account = account.split(',')
    return {
      secretKey: account[0],
      balance: account[1]
    };
  }

  if (typeof accounts === 'string')
    return [ splitAccount(accounts) ];
  else if (!Array.isArray(accounts))
    return;

  var ret = []
  for (var i = 0; i < accounts.length; i++) {
    ret.push(splitAccount(accounts[i]));
  }
  return ret;
}

if (argv.d || argv.deterministic) {
  argv.s = "TestRPC is awesome!"; // Seed phrase; don't change to Ganache, maintain original determinism
}

if (typeof argv.unlock == "string") {
  argv.unlock = [argv.unlock];
}

var logger = console;

// If the mem argument is passed, only show memory output,
// not transaction history.
if (argv.mem === true) {
  logger = {
    log: function() {}
  };

  setInterval(function() {
    console.log(process.memoryUsage());
  }, 1000);
}

var options = {
  port: argv.p || argv.port || "8545",
  hostname: argv.h || argv.hostname,
  debug: argv.debug,
  seed: argv.s || argv.seed,
  mnemonic: argv.m || argv.mnemonic,
  total_accounts: argv.a || argv.accounts,
  blocktime: argv.b || argv.blocktime,
  gasPrice: argv.g || argv.gasPrice,
  gasLimit: argv.l || argv.gasLimit,
  accounts: parseAccounts(argv.account),
  unlocked_accounts: argv.unlock,
  fork: argv.f || argv.fork || false,
  network_id: argv.i || argv.networkId,
  verbose: argv.v || argv.verbose,
  secure: argv.n || argv.secure || false,
  db_path: argv.db || null,
  account_keys_path: argv.acctKeys || null,
  logger: logger
}

var fork_address;

// If we're forking from another client, don't try to use the same port.
if (options.fork) {
  var split = options.fork.split("@");
  fork_address = split[0];
  var block;
  if (split.length > 1) {
    block = split[1];
  }

  if (URL.parse(fork_address).port == options.port) {
    options.port = (parseInt(options.port) + 1);
  }

  options.fork = fork_address + (block != null ? "@" + block : "");
}

var server = Ganache.server(options);

//console.log("Ganache CLI v" + pkg.version);
console.log("EthereumJS TestRPC v" + pkg.version + " (ganache-core: " + corepkg.version + ")");

server.listen(options.port, options.hostname, function(err, state) {
  if (err) {
    console.log(err);
    return;
  }
  console.log("");
  console.log("Available Accounts");
  console.log("==================");

  var accounts = state.accounts;
  var addresses = Object.keys(accounts);

  addresses.forEach(function(address, index) {
    var line = "(" + index + ") " + address;

    if (state.isUnlocked(address) == false) {
      line += " 🔒";
    }

    console.log(line);
  });

  console.log("");
  console.log("Private Keys");
  console.log("==================");

  addresses.forEach(function(address, index) {
    console.log("(" + index + ") " + accounts[address].secretKey.toString("hex"));
  });

  if (options.account_keys_path != null) {
    console.log("");
    console.log("Saving accounts and keys to " + options.account_keys_path);
    var obj = {}
    obj.addresses = accounts;
    obj.private_keys = {};
    addresses.forEach(function(address, index) {
       obj.private_keys[address] = accounts[address].secretKey.toString("hex");
    });
    var json = JSON.stringify(obj);
    fs.writeFile(options.account_keys_path, json, 'utf8',function(err){
      if(err) throw err;
    })
  }

  if (options.accounts == null) {
    console.log("");
    console.log("HD Wallet");
    console.log("==================");
    console.log("Mnemonic:      " + state.mnemonic);
    console.log("Base HD Path:  " + state.wallet_hdpath + "{account_index}")
  }

  if (options.gasPrice) {
    console.log("");
    console.log("Gas Price");
    console.log("==================");
    console.log(options.gasPrice);
  }

  if (options.gasLimit) {
    console.log("");
    console.log("Gas Limit");
    console.log("==================");
    console.log(options.gasLimit);
  }

  if (options.fork) {
    console.log("");
    console.log("Forked Chain");
    console.log("==================");
    console.log("Location:    " + fork_address);
    console.log("Block:       " + web3.toBigNumber(state.blockchain.fork_block_number).toString(10));
    console.log("Network ID:  " + state.net_version);
    console.log("Time:        " + (state.blockchain.startTime || new Date()).toString());
  }

  console.log("");
  console.log("Listening on " + (options.hostname || "localhost") + ":" + options.port);
});

process.on('uncaughtException', function(e) {
  console.log(e.stack);
  process.exit(1);
})

// See http://stackoverflow.com/questions/10021373/what-is-the-windows-equivalent-of-process-onsigint-in-node-js
if (process.platform === "win32") {
  require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  })
  .on("SIGINT", function () {
    process.emit("SIGINT");
  });
}

process.on("SIGINT", function () {
  // graceful shutdown
  server.close(function(err) {
    if (err) {
      console.log(err.stack || err);
    }
    process.exit();
  });
});
<commit_msg>Corrected gas limit in CLI usage<commit_after>#!/usr/bin/env node
// `yargs/yargs` required to work with webpack, see here.
// https://github.com/yargs/yargs/issues/781
var yargs = require('yargs/yargs');
var Ganache = require("ganache-core");
var pkg = require("./package.json");
var corepkg = require("./node_modules/ganache-core/package.json");
var URL = require("url");
var Web3 = require("web3");
var web3 = new Web3(); // Used only for its BigNumber library.
var fs = require("fs");

var parser = yargs()
.option("unlock", {
  type: "string",
  alias: "u"
});

var argv = parser.parse(process.argv);

if (argv.help || argv['?']) {
  console.log("");
  console.log("testrpc: Fast Ethereum RPC client for testing and development");
  console.log("  Full docs: https://github.com/ethereumjs/testrpc");
  console.log("");
  console.log("Usage: testrpc [options]");
  console.log("  options:");
  console.log("  --port/-p <port to bind to, default 8545>");
  console.log("  --host/-h <host to bind to, default 0.0.0.0>");
  console.log("  --fork/-f <url>   (Fork from another currently running Ethereum client at a given block)");
  console.log("");
  console.log("  --db <db path>   (directory to save chain db)");
  console.log("  --seed <seed value for PRNG, default random>");
  console.log("  --deterministic/-d     (uses fixed seed)");
  console.log("  --mnemonic/-m <mnemonic>");
  console.log("  --accounts/-a <number of accounts to generate at startup>");
  console.log("  --acctKeys <path to file>  (saves generated accounts and private keys as JSON object in specified file)");
  console.log("  --secure/-s   (Lock accounts by default)");
  console.log("  --unlock <accounts>   (Comma-separated list of accounts or indices to unlock)");
  console.log("");
  console.log("  --blocktime/-b <block time in seconds>");
  console.log("  --networkId/-i <network id> (default current time)");
  console.log("  --gasPrice/-g <gas price>   (default 20000000000)");
  console.log("  --gasLimit/-l <gas limit>   (default 90000)");
  console.log("");
  console.log("  --debug       (Output VM opcodes for debugging)");
  console.log("  --verbose/-v");
  console.log("  --mem         (Only show memory output, not tx history)");
  console.log("");
  console.log("  --help / -?    (this output)");
  console.log("");
  process.exit(0);
}

function parseAccounts(accounts) {
  function splitAccount(account) {
    account = account.split(',')
    return {
      secretKey: account[0],
      balance: account[1]
    };
  }

  if (typeof accounts === 'string')
    return [ splitAccount(accounts) ];
  else if (!Array.isArray(accounts))
    return;

  var ret = []
  for (var i = 0; i < accounts.length; i++) {
    ret.push(splitAccount(accounts[i]));
  }
  return ret;
}

if (argv.d || argv.deterministic) {
  argv.s = "TestRPC is awesome!"; // Seed phrase; don't change to Ganache, maintain original determinism
}

if (typeof argv.unlock == "string") {
  argv.unlock = [argv.unlock];
}

var logger = console;

// If the mem argument is passed, only show memory output,
// not transaction history.
if (argv.mem === true) {
  logger = {
    log: function() {}
  };

  setInterval(function() {
    console.log(process.memoryUsage());
  }, 1000);
}

var options = {
  port: argv.p || argv.port || "8545",
  hostname: argv.h || argv.hostname,
  debug: argv.debug,
  seed: argv.s || argv.seed,
  mnemonic: argv.m || argv.mnemonic,
  total_accounts: argv.a || argv.accounts,
  blocktime: argv.b || argv.blocktime,
  gasPrice: argv.g || argv.gasPrice,
  gasLimit: argv.l || argv.gasLimit,
  accounts: parseAccounts(argv.account),
  unlocked_accounts: argv.unlock,
  fork: argv.f || argv.fork || false,
  network_id: argv.i || argv.networkId,
  verbose: argv.v || argv.verbose,
  secure: argv.n || argv.secure || false,
  db_path: argv.db || null,
  account_keys_path: argv.acctKeys || null,
  logger: logger
}

var fork_address;

// If we're forking from another client, don't try to use the same port.
if (options.fork) {
  var split = options.fork.split("@");
  fork_address = split[0];
  var block;
  if (split.length > 1) {
    block = split[1];
  }

  if (URL.parse(fork_address).port == options.port) {
    options.port = (parseInt(options.port) + 1);
  }

  options.fork = fork_address + (block != null ? "@" + block : "");
}

var server = Ganache.server(options);

//console.log("Ganache CLI v" + pkg.version);
console.log("EthereumJS TestRPC v" + pkg.version + " (ganache-core: " + corepkg.version + ")");

server.listen(options.port, options.hostname, function(err, state) {
  if (err) {
    console.log(err);
    return;
  }
  console.log("");
  console.log("Available Accounts");
  console.log("==================");

  var accounts = state.accounts;
  var addresses = Object.keys(accounts);

  addresses.forEach(function(address, index) {
    var line = "(" + index + ") " + address;

    if (state.isUnlocked(address) == false) {
      line += " 🔒";
    }

    console.log(line);
  });

  console.log("");
  console.log("Private Keys");
  console.log("==================");

  addresses.forEach(function(address, index) {
    console.log("(" + index + ") " + accounts[address].secretKey.toString("hex"));
  });

  if (options.account_keys_path != null) {
    console.log("");
    console.log("Saving accounts and keys to " + options.account_keys_path);
    var obj = {}
    obj.addresses = accounts;
    obj.private_keys = {};
    addresses.forEach(function(address, index) {
       obj.private_keys[address] = accounts[address].secretKey.toString("hex");
    });
    var json = JSON.stringify(obj);
    fs.writeFile(options.account_keys_path, json, 'utf8',function(err){
      if(err) throw err;
    })
  }

  if (options.accounts == null) {
    console.log("");
    console.log("HD Wallet");
    console.log("==================");
    console.log("Mnemonic:      " + state.mnemonic);
    console.log("Base HD Path:  " + state.wallet_hdpath + "{account_index}")
  }

  if (options.gasPrice) {
    console.log("");
    console.log("Gas Price");
    console.log("==================");
    console.log(options.gasPrice);
  }

  if (options.gasLimit) {
    console.log("");
    console.log("Gas Limit");
    console.log("==================");
    console.log(options.gasLimit);
  }

  if (options.fork) {
    console.log("");
    console.log("Forked Chain");
    console.log("==================");
    console.log("Location:    " + fork_address);
    console.log("Block:       " + web3.toBigNumber(state.blockchain.fork_block_number).toString(10));
    console.log("Network ID:  " + state.net_version);
    console.log("Time:        " + (state.blockchain.startTime || new Date()).toString());
  }

  console.log("");
  console.log("Listening on " + (options.hostname || "localhost") + ":" + options.port);
});

process.on('uncaughtException', function(e) {
  console.log(e.stack);
  process.exit(1);
})

// See http://stackoverflow.com/questions/10021373/what-is-the-windows-equivalent-of-process-onsigint-in-node-js
if (process.platform === "win32") {
  require("readline").createInterface({
    input: process.stdin,
    output: process.stdout
  })
  .on("SIGINT", function () {
    process.emit("SIGINT");
  });
}

process.on("SIGINT", function () {
  // graceful shutdown
  server.close(function(err) {
    if (err) {
      console.log(err.stack || err);
    }
    process.exit();
  });
});
<|endoftext|>


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

var lifecycleEvent = process.env.npm_lifecycle_event

if (!lifecycleEvent) {
  console.error(
    'Error: scripty - it seems you may be running scripty from the ' +
    'command-line directly.\n' +
    'At this time, scripty can only be run within an ' +
    'npm script specified in your package.json.\n\n' +
    'Example package.json entry:\n\n' +
    '  "scripts": {\n' +
    '    "foo:bar": "scripty"\n' +
    '  }\n\n' +
    'And then run via `npm run foo:bar`.\n\n' +
    'For more documentation, see:\n' +
    '  https://github.com/testdouble/scripty\n\n' +
    'Exiting.'
  )
  process.exit(1)
} else {
  var scripty = require('./lib/scripty')

  scripty(lifecycleEvent, {
    userArgs: process.argv.slice(2),
    spawn: {
      stdio: 'inherit'
    }
  }, function (er, code) {
    if (er) { throw er }
    process.exit(code)
  })
}
<commit_msg>add SCRIPTY_PARALLEL to the CLI<commit_after>#!/usr/bin/env node

var lifecycleEvent = process.env.npm_lifecycle_event

if (!lifecycleEvent) {
  console.error(
    'Error: scripty - it seems you may be running scripty from the ' +
    'command-line directly.\n' +
    'At this time, scripty can only be run within an ' +
    'npm script specified in your package.json.\n\n' +
    'Example package.json entry:\n\n' +
    '  "scripts": {\n' +
    '    "foo:bar": "scripty"\n' +
    '  }\n\n' +
    'And then run via `npm run foo:bar`.\n\n' +
    'For more documentation, see:\n' +
    '  https://github.com/testdouble/scripty\n\n' +
    'Exiting.'
  )
  process.exit(1)
} else {
  var scripty = require('./lib/scripty')

  scripty(lifecycleEvent, {
    userArgs: process.argv.slice(2),
    parallel: process.env['SCRIPTY_PARALLEL'] === 'true',
    spawn: {
      stdio: 'inherit'
    }
  }, function (er, code) {
    if (er) { throw er }
    process.exit(code)
  })
}
<|endoftext|>


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

var clivas = require('clivas')
var cp = require('child_process')
var fs = require('fs')
var minimist = require('minimist')
var moment = require('moment')
var networkAddress = require('network-address')
var path = require('path')
var prettysize = require('prettysize')
var WebTorrent = require('../')

process.title = 'WebTorrent'

process.on('exit', function (code) {
  if (code !== 0) {
    clivas.line('{red:ERROR:} If you think this is a bug in webtorrent, report it!')
    console.log('=====>                                               <=====')
    console.log('=====>  https://github.com/feross/webtorrent/issues  <=====')
    console.log('=====>                                               <=====')
  }
})

var argv = minimist(process.argv.slice(2), {
  alias: {
    p: 'port',
    b: 'blocklist',
    t: 'subtitles',
    l: 'list',
    i: 'index',
    o: 'out',
    q: 'quiet',
    h: 'help',
    v: 'version'
  },
  boolean: [ // options that are always boolean
    'airplay',
    'chromecast',
    'mplayer',
    'mpv',
    'vlc',
    'xbmc',
    'stdout',
    'list',
    'quiet',
    'help',
    'version'
  ],
  default: {
    port: 8000
  }
})

if (argv.version) {
  console.log(require('../package.json').version)
  return done()
}

var torrentId = argv._[0]

if (argv.help || !torrentId) {
  fs.readFileSync(path.join(__dirname, 'ascii-logo.txt'), 'utf8')
    .split('\n')
    .forEach(function (line) {
      clivas.line('{bold:' + line.substring(0, 20) + '}{red:' + line.substring(20) + '}')
    })

  console.log(function () {/*
  Usage:
      webtorrent <options> <torrent-uri>

      Download the torrent from:
          * magnet uri
          * http url to .torrent file
          * filesystem path to .torrent file
          * info hash (hex string)

  Streaming options:
      --airplay               Apple TV
      --chromecast            Chromecast
      --mplayer               MPlayer
      --mpv                   MPV
      --omx [jack]            omx [default: hdmi]
      --vlc                   VLC
      --xbmc                  XBMC
      --stdout                standard out (implies --quiet)

  Options:
      -o, --out [path]        set download destination [default: /tmp/webtorrent]
      -l, --list              list files in torrent (with indexes)
      -i, --index [index]     stream a particular file from torrent (by index)
      -p, --port [number]     change the http port [default: 8000]
      -b, --blocklist [path]  load blocklist file/http url
      -t, --subtitles [file]  load subtitles file
      -q, --quiet             don't show UI on stdout
      -v, --version           print the current version

  Please report bugs!  https://github.com/feross/webtorrent/issues

    */}.toString().split(/\n/).slice(1, -1).join('\n'))
  return done()
}

if (process.env.DEBUG || argv.stdout) {
  argv.quiet = argv.q = true
}

var VLC_ARGS = process.env.DEBUG
  ? '-q --play-and-exit'
  : '--play-and-exit --extraintf=http:logger --verbose=2 --file-logging --logfile=vlc-log.txt'
var MPLAYER_EXEC = 'mplayer -ontop -really-quiet -noidx -loop 0'
var MPV_EXEC = 'mpv --ontop --really-quiet --loop=no'
var OMX_EXEC = 'omxplayer -r -o ' + (typeof argv.omx === 'string')
  ? argv.omx
  : 'hdmi'

if (argv.subtitles) {
  VLC_ARGS += ' --sub-file=' + argv.subtitles
  MPLAYER_EXEC += ' -sub ' + argv.subtitles
  MPV_EXEC += ' --sub-file=' + argv.subtitles
  OMX_EXEC += ' --subtitles ' + argv.subtitles
}

function error (err) {
  clivas.line('{red:ERROR:} ' + (err.message || err))
}

function errorAndExit (err) {
  error(err)
  process.exit(1)
}

var started = Date.now()
function getRuntime () {
  return Math.floor((Date.now() - started) / 1000)
}

var client = new WebTorrent({
  blocklist: argv.blocklist
})
.on('error', errorAndExit)

if (!argv.out) { // If no output file has been specified
  process.on('SIGINT', remove)
  process.on('SIGTERM', remove)
}

function remove (cb) {
  process.removeListener('SIGINT', remove)
  process.removeListener('SIGTERM', remove)
  client.destroy(cb)
}

var torrent = client.add(torrentId, (argv.out ? { tmp: argv.out } : {}))

torrent.on('infoHash', function () {
  function updateMetadata () {
    var numPeers = torrent.swarm.numPeers
    clivas.clear()
    clivas.line('{green:fetching torrent metadata from} {bold:'+numPeers+'} {green:peers}')
  }

  if (!argv.quiet && !argv.list) {
    torrent.swarm.on('wire', updateMetadata)
    torrent.on('metadata', function () {
      torrent.swarm.removeListener('wire', updateMetadata)
    })
    updateMetadata()
  }
})

var filename, swarm, wires, server, serving

if (argv.list) torrent.once('ready', onReady)
else {
  server = torrent.createServer()
  server.listen(argv.port, function () {
    if (torrent.ready) onReady()
    else torrent.once('ready', onReady)
  }).once('connection', function () {
    serving = true
  })
}

function done () {
  if (!serving) {
    process.exit(0)
  }
}

function onReady () {
  filename = torrent.name
  swarm = torrent.swarm
  wires = torrent.swarm.wires

  if (argv.list) {
    torrent.files.forEach(function (file, i) {
      clivas.line('{3+bold:'+i+'} : {magenta:'+file.name+'} {blue:('+bytes(file.length)+')}')
    })
    return done()
  }

  torrent.on('verifying', function (data) {
    if (argv.quiet) return
    clivas.clear()
    clivas.line(
      '{green:verifying existing torrent} {bold:'+Math.floor(data.percentDone)+'%} ' +
      '({bold:'+Math.floor(data.percentVerified)+'%} {green:passed verification})'
    )
  })

  torrent.on('done', function () {
    if (!argv.quiet) {
      // TODO: expose this data from bittorrent-swarm
      var numActiveWires = torrent.swarm.wires.reduce(function (num, wire) {
        return num + (wire.downloaded > 0)
      }, 0)
      clivas.line(
        'torrent downloaded {green:successfully} from ' +
        '{bold:'+numActiveWires+'/'+torrent.swarm.wires.length+'} {green:peers} ' +
        'in {bold:'+getRuntime()+'s}!'
      )
    }
    done()
  })

  var cmd, player
  var playerName = argv.airplay ? 'Airplay'
    : argv.chromecast ? 'Chromecast'
    : argv.xbmc ? 'XBMC'
    : argv.vlc ? 'VLC'
    : argv.mplayer ? 'MPlayer'
    : argv.mpv ? 'mpv'
    : argv.omx ? 'OMXPlayer'
    : null

  // if no index specified, use largest file
  var index = (typeof argv.index === 'number')
    ? argv.index
    : torrent.files.indexOf(torrent.files.reduce(function (a, b) {
      return a.length > b.length ? a : b
    }))
  var href = 'http://' + networkAddress() + ':' + argv.port + '/' + index

  if (playerName) torrent.files[index].select()
  if (argv.stdout) torrent.files[index].createReadStream().pipe(process.stdout)

  if (argv.vlc && process.platform === 'win32') {
    var registry = require('windows-no-runnable').registry
    var key
    if (process.arch === 'x64') {
      try {
        key = registry('HKLM/Software/Wow6432Node/VideoLAN/VLC')
      } catch (e) {}
    } else {
      try {
        key = registry('HKLM/Software/VideoLAN/VLC')
      } catch (err) {}
    }

    if (key) {
      var vlcPath = key.InstallDir.value + path.sep + 'vlc'
      VLC_ARGS = VLC_ARGS.split(' ')
      VLC_ARGS.unshift(href)
      cp.execFile(vlcPath, VLC_ARGS, function (err) {
        if (err) return errorAndExit(err)
        done()
      })
    }
  } else if (argv.vlc) {
    var root = '/Applications/VLC.app/Contents/MacOS/VLC'
    var home = (process.env.HOME || '') + root
    cmd = 'vlc ' + href + ' ' + VLC_ARGS + ' || ' +
      root + ' ' + href + ' ' + VLC_ARGS + ' || ' +
      home + ' ' + href + ' ' + VLC_ARGS
  } else if (argv.mplayer) {
    cmd = MPLAYER_EXEC + ' ' + href
  } else if (argv.mpv) {
    cmd = MPV_EXEC + ' ' + href
  } else if (argv.omx) {
    cmd = OMX_EXEC + ' ' + href
  }

  if (cmd) {
    player = cp.exec(cmd, function (err) {
      if (err) return errorAndExit(err)
      done()
    })
  }

  if (argv.airplay) {
    var airplay = require('airplay-js')
    airplay.createBrowser()
      .on('deviceOn', function (device) {
        device.play(href, 0, function () {})
      })
      .start()
    // TODO: handle case where user closes airplay. do same thing as when VLC is closed
  }

  if (argv.chromecast) {
    var chromecast = require('chromecast-js')
    new chromecast.Browser()
      .on('deviceOn', function (device) {
        device.connect()
        device.on('connected', function () {
          device.play(href)
        })
      })
  }

  if (argv.xbmc) {
    var xbmc = require('nodebmc')
    new xbmc.Browser()
      .on('deviceOn', function (device) {
          device.play(href, function () {})
      })
  }

  var hotswaps = 0
  torrent.on('hotswap', function () {
    hotswaps += 1
  })

  if (!argv.quiet) {
    process.stdout.write(new Buffer('G1tIG1sySg==', 'base64')) // clear for drawing

    setInterval(draw, 500)
  }

  function active (wire) {
    return !wire.peerChoking
  }

  function draw () {
    var unchoked = wires.filter(active)
    var linesremaining = clivas.height
    var peerslisted = 0
    var speed = swarm.downloadSpeed()
    var estimatedSecondsRemaining = Math.max(0, torrent.length - swarm.downloaded) / (speed > 0 ? speed : -1)
    var estimate = moment.duration(estimatedSecondsRemaining, 'seconds').humanize()

    clivas.clear()

    if (playerName)
      clivas.line('{green:Streaming to} {bold:' + playerName + '}')
    if (server)
      clivas.line('{green:server running at} {bold:' + href + '}')

    clivas.line('')
    clivas.line('{green:downloading:} {bold:' + filename + '}')
    clivas.line(
      '{green:speed: }{bold:' + bytes(speed) + '/s}  ' +
      '{green:downloaded:} {bold:' + bytes(swarm.downloaded) + '}' +
      '/{bold:' + bytes(torrent.length) + '}  ' +
      '{green:uploaded:} {bold:' + bytes(swarm.uploaded) + '}  ' +
      '{green:peers:} {bold:' + unchoked.length + '/' + wires.length + '}  ' +
      '{green:hotswaps:} {bold:' + hotswaps + '}'
    )
    clivas.line(
      '{green:time remaining:} {bold:' + estimate + ' remaining}  ' +
      '{green:total time:} {bold:' + getRuntime() + 's}  ' +
      '{green:queued peers:} {bold:' + swarm.numQueued + '}  ' +
      '{green:blocked:} {bold:' + torrent.numBlockedPeers + '}'
    )
    clivas.line('{80:}')
    linesremaining -= 8

    var pieces = torrent.storage.pieces
    var piecesBar = []
    for(var i = 0; i < pieces.length; i++) {
      var piece = pieces[i]
      if (piece.verified || piece.blocksWritten === 0) {
        continue;
      }
      var bar = ''
      for(var j = 0; j < piece.blocks.length; j++) {
        bar += piece.blocks[j] ? '{green:█}' : '{red:█}';
      }
      clivas.line('{4+cyan:' + i + '} ' + bar);
      linesremaining -= 1
    }
    clivas.line('{80:}')
    linesremaining -= 1

    wires.every(function (wire) {
      var progress = '?'
      if (torrent.parsedTorrent) {
        var bits = 0
        var piececount = Math.ceil(torrent.parsedTorrent.length / torrent.parsedTorrent.pieceLength)
        for(var i = 0; i < piececount; i++) {
          if (wire.peerPieces.get(i)) {
            bits++
          }
        }
        progress = bits === piececount ? 'S' : Math.floor(100 * bits / piececount) + '%'
      }
      var tags = []
      if (wire.peerChoking) tags.push('choked')
      var reqStats = wire.requests.map(function(req) {
          return req.piece;
      })
      clivas.line(
        '{3:' + progress + '} ' +
        '{25+magenta:' + wire.remoteAddress + '} {10:'+bytes(wire.downloaded)+'} ' +
        '{10+cyan:' + bytes(wire.downloadSpeed()) + '/s} ' +
        '{10+red:' + bytes(wire.uploadSpeed()) + '/s} ' +
        '{15+grey:' + tags.join(', ') + '}' +
        '{15+cyan:' + reqStats.join(' ') + '}'
      )
      peerslisted++
      return linesremaining - peerslisted > 4
    })
    linesremaining -= peerslisted

    if (wires.length > peerslisted) {
      clivas.line('{80:}')
      clivas.line('... and '+(wires.length - peerslisted)+' more')
    }

    clivas.line('{80:}')
    clivas.flush(true)
  }
}

function bytes (num) {
  return prettysize(num)
}
<commit_msg>Control+C shuts down webtorrent on the first try<commit_after>#!/usr/bin/env node

var clivas = require('clivas')
var cp = require('child_process')
var fs = require('fs')
var minimist = require('minimist')
var moment = require('moment')
var networkAddress = require('network-address')
var path = require('path')
var prettysize = require('prettysize')
var WebTorrent = require('../')

process.title = 'WebTorrent'

process.on('exit', function (code) {
  if (code !== 0) {
    clivas.line('{red:ERROR:} If you think this is a bug in webtorrent, report it!')
    console.log('=====>                                               <=====')
    console.log('=====>  https://github.com/feross/webtorrent/issues  <=====')
    console.log('=====>                                               <=====')
  }
})

var argv = minimist(process.argv.slice(2), {
  alias: {
    p: 'port',
    b: 'blocklist',
    t: 'subtitles',
    l: 'list',
    i: 'index',
    o: 'out',
    q: 'quiet',
    h: 'help',
    v: 'version'
  },
  boolean: [ // options that are always boolean
    'airplay',
    'chromecast',
    'mplayer',
    'mpv',
    'vlc',
    'xbmc',
    'stdout',
    'list',
    'quiet',
    'help',
    'version'
  ],
  default: {
    port: 8000
  }
})

if (argv.version) {
  console.log(require('../package.json').version)
  return done()
}

var torrentId = argv._[0]

if (argv.help || !torrentId) {
  fs.readFileSync(path.join(__dirname, 'ascii-logo.txt'), 'utf8')
    .split('\n')
    .forEach(function (line) {
      clivas.line('{bold:' + line.substring(0, 20) + '}{red:' + line.substring(20) + '}')
    })

  console.log(function () {/*
  Usage:
      webtorrent <options> <torrent-uri>

      Download the torrent from:
          * magnet uri
          * http url to .torrent file
          * filesystem path to .torrent file
          * info hash (hex string)

  Streaming options:
      --airplay               Apple TV
      --chromecast            Chromecast
      --mplayer               MPlayer
      --mpv                   MPV
      --omx [jack]            omx [default: hdmi]
      --vlc                   VLC
      --xbmc                  XBMC
      --stdout                standard out (implies --quiet)

  Options:
      -o, --out [path]        set download destination [default: /tmp/webtorrent]
      -l, --list              list files in torrent (with indexes)
      -i, --index [index]     stream a particular file from torrent (by index)
      -p, --port [number]     change the http port [default: 8000]
      -b, --blocklist [path]  load blocklist file/http url
      -t, --subtitles [file]  load subtitles file
      -q, --quiet             don't show UI on stdout
      -v, --version           print the current version

  Please report bugs!  https://github.com/feross/webtorrent/issues

    */}.toString().split(/\n/).slice(1, -1).join('\n'))
  return done()
}

if (process.env.DEBUG || argv.stdout) {
  argv.quiet = argv.q = true
}

var VLC_ARGS = process.env.DEBUG
  ? '-q --play-and-exit'
  : '--play-and-exit --extraintf=http:logger --verbose=2 --file-logging --logfile=vlc-log.txt'
var MPLAYER_EXEC = 'mplayer -ontop -really-quiet -noidx -loop 0'
var MPV_EXEC = 'mpv --ontop --really-quiet --loop=no'
var OMX_EXEC = 'omxplayer -r -o ' + (typeof argv.omx === 'string')
  ? argv.omx
  : 'hdmi'

if (argv.subtitles) {
  VLC_ARGS += ' --sub-file=' + argv.subtitles
  MPLAYER_EXEC += ' -sub ' + argv.subtitles
  MPV_EXEC += ' --sub-file=' + argv.subtitles
  OMX_EXEC += ' --subtitles ' + argv.subtitles
}

function error (err) {
  clivas.line('{red:ERROR:} ' + (err.message || err))
}

function errorAndExit (err) {
  error(err)
  process.exit(1)
}

var started = Date.now()
function getRuntime () {
  return Math.floor((Date.now() - started) / 1000)
}

var client = new WebTorrent({
  blocklist: argv.blocklist
})
.on('error', errorAndExit)

if (!argv.out) { // If no output file has been specified
  process.on('SIGINT', remove)
  process.on('SIGTERM', remove)
}

function remove () {
  process.removeListener('SIGINT', remove)
  process.removeListener('SIGTERM', remove)

  // destroying can take a while, so print a message to the user
  clivas.line('')
  clivas.line('{green:webtorrent is exiting...}')

  client.destroy(process.exit)
}

var torrent = client.add(torrentId, (argv.out ? { tmp: argv.out } : {}))

torrent.on('infoHash', function () {
  function updateMetadata () {
    var numPeers = torrent.swarm.numPeers
    clivas.clear()
    clivas.line('{green:fetching torrent metadata from} {bold:'+numPeers+'} {green:peers}')
  }

  if (!argv.quiet && !argv.list) {
    torrent.swarm.on('wire', updateMetadata)
    torrent.on('metadata', function () {
      torrent.swarm.removeListener('wire', updateMetadata)
    })
    updateMetadata()
  }
})

var filename, swarm, wires, server, serving

if (argv.list) torrent.once('ready', onReady)
else {
  server = torrent.createServer()
  server.listen(argv.port, function () {
    if (torrent.ready) onReady()
    else torrent.once('ready', onReady)
  }).once('connection', function () {
    serving = true
  })
}

function done () {
  if (!serving) {
    process.exit(0)
  }
}

function onReady () {
  filename = torrent.name
  swarm = torrent.swarm
  wires = torrent.swarm.wires

  if (argv.list) {
    torrent.files.forEach(function (file, i) {
      clivas.line('{3+bold:'+i+'} : {magenta:'+file.name+'} {blue:('+bytes(file.length)+')}')
    })
    return done()
  }

  torrent.on('verifying', function (data) {
    if (argv.quiet) return
    clivas.clear()
    clivas.line(
      '{green:verifying existing torrent} {bold:'+Math.floor(data.percentDone)+'%} ' +
      '({bold:'+Math.floor(data.percentVerified)+'%} {green:passed verification})'
    )
  })

  torrent.on('done', function () {
    if (!argv.quiet) {
      // TODO: expose this data from bittorrent-swarm
      var numActiveWires = torrent.swarm.wires.reduce(function (num, wire) {
        return num + (wire.downloaded > 0)
      }, 0)
      clivas.line(
        'torrent downloaded {green:successfully} from ' +
        '{bold:'+numActiveWires+'/'+torrent.swarm.wires.length+'} {green:peers} ' +
        'in {bold:'+getRuntime()+'s}!'
      )
    }
    done()
  })

  var cmd, player
  var playerName = argv.airplay ? 'Airplay'
    : argv.chromecast ? 'Chromecast'
    : argv.xbmc ? 'XBMC'
    : argv.vlc ? 'VLC'
    : argv.mplayer ? 'MPlayer'
    : argv.mpv ? 'mpv'
    : argv.omx ? 'OMXPlayer'
    : null

  // if no index specified, use largest file
  var index = (typeof argv.index === 'number')
    ? argv.index
    : torrent.files.indexOf(torrent.files.reduce(function (a, b) {
      return a.length > b.length ? a : b
    }))
  var href = 'http://' + networkAddress() + ':' + argv.port + '/' + index

  if (playerName) torrent.files[index].select()
  if (argv.stdout) torrent.files[index].createReadStream().pipe(process.stdout)

  if (argv.vlc && process.platform === 'win32') {
    var registry = require('windows-no-runnable').registry
    var key
    if (process.arch === 'x64') {
      try {
        key = registry('HKLM/Software/Wow6432Node/VideoLAN/VLC')
      } catch (e) {}
    } else {
      try {
        key = registry('HKLM/Software/VideoLAN/VLC')
      } catch (err) {}
    }

    if (key) {
      var vlcPath = key.InstallDir.value + path.sep + 'vlc'
      VLC_ARGS = VLC_ARGS.split(' ')
      VLC_ARGS.unshift(href)
      cp.execFile(vlcPath, VLC_ARGS, function (err) {
        if (err) return errorAndExit(err)
        done()
      })
    }
  } else if (argv.vlc) {
    var root = '/Applications/VLC.app/Contents/MacOS/VLC'
    var home = (process.env.HOME || '') + root
    cmd = 'vlc ' + href + ' ' + VLC_ARGS + ' || ' +
      root + ' ' + href + ' ' + VLC_ARGS + ' || ' +
      home + ' ' + href + ' ' + VLC_ARGS
  } else if (argv.mplayer) {
    cmd = MPLAYER_EXEC + ' ' + href
  } else if (argv.mpv) {
    cmd = MPV_EXEC + ' ' + href
  } else if (argv.omx) {
    cmd = OMX_EXEC + ' ' + href
  }

  if (cmd) {
    player = cp.exec(cmd, function (err) {
      if (err) return errorAndExit(err)
      done()
    })
  }

  if (argv.airplay) {
    var airplay = require('airplay-js')
    airplay.createBrowser()
      .on('deviceOn', function (device) {
        device.play(href, 0, function () {})
      })
      .start()
    // TODO: handle case where user closes airplay. do same thing as when VLC is closed
  }

  if (argv.chromecast) {
    var chromecast = require('chromecast-js')
    new chromecast.Browser()
      .on('deviceOn', function (device) {
        device.connect()
        device.on('connected', function () {
          device.play(href)
        })
      })
  }

  if (argv.xbmc) {
    var xbmc = require('nodebmc')
    new xbmc.Browser()
      .on('deviceOn', function (device) {
          device.play(href, function () {})
      })
  }

  var hotswaps = 0
  torrent.on('hotswap', function () {
    hotswaps += 1
  })

  if (!argv.quiet) {
    process.stdout.write(new Buffer('G1tIG1sySg==', 'base64')) // clear for drawing

    setInterval(draw, 500)
  }

  function active (wire) {
    return !wire.peerChoking
  }

  function draw () {
    var unchoked = wires.filter(active)
    var linesremaining = clivas.height
    var peerslisted = 0
    var speed = swarm.downloadSpeed()
    var estimatedSecondsRemaining = Math.max(0, torrent.length - swarm.downloaded) / (speed > 0 ? speed : -1)
    var estimate = moment.duration(estimatedSecondsRemaining, 'seconds').humanize()

    clivas.clear()

    if (playerName)
      clivas.line('{green:Streaming to} {bold:' + playerName + '}')
    if (server)
      clivas.line('{green:server running at} {bold:' + href + '}')

    clivas.line('')
    clivas.line('{green:downloading:} {bold:' + filename + '}')
    clivas.line(
      '{green:speed: }{bold:' + bytes(speed) + '/s}  ' +
      '{green:downloaded:} {bold:' + bytes(swarm.downloaded) + '}' +
      '/{bold:' + bytes(torrent.length) + '}  ' +
      '{green:uploaded:} {bold:' + bytes(swarm.uploaded) + '}  ' +
      '{green:peers:} {bold:' + unchoked.length + '/' + wires.length + '}  ' +
      '{green:hotswaps:} {bold:' + hotswaps + '}'
    )
    clivas.line(
      '{green:time remaining:} {bold:' + estimate + ' remaining}  ' +
      '{green:total time:} {bold:' + getRuntime() + 's}  ' +
      '{green:queued peers:} {bold:' + swarm.numQueued + '}  ' +
      '{green:blocked:} {bold:' + torrent.numBlockedPeers + '}'
    )
    clivas.line('{80:}')
    linesremaining -= 8

    var pieces = torrent.storage.pieces
    var piecesBar = []
    for(var i = 0; i < pieces.length; i++) {
      var piece = pieces[i]
      if (piece.verified || piece.blocksWritten === 0) {
        continue;
      }
      var bar = ''
      for(var j = 0; j < piece.blocks.length; j++) {
        bar += piece.blocks[j] ? '{green:█}' : '{red:█}';
      }
      clivas.line('{4+cyan:' + i + '} ' + bar);
      linesremaining -= 1
    }
    clivas.line('{80:}')
    linesremaining -= 1

    wires.every(function (wire) {
      var progress = '?'
      if (torrent.parsedTorrent) {
        var bits = 0
        var piececount = Math.ceil(torrent.parsedTorrent.length / torrent.parsedTorrent.pieceLength)
        for(var i = 0; i < piececount; i++) {
          if (wire.peerPieces.get(i)) {
            bits++
          }
        }
        progress = bits === piececount ? 'S' : Math.floor(100 * bits / piececount) + '%'
      }
      var tags = []
      if (wire.peerChoking) tags.push('choked')
      var reqStats = wire.requests.map(function(req) {
          return req.piece;
      })
      clivas.line(
        '{3:' + progress + '} ' +
        '{25+magenta:' + wire.remoteAddress + '} {10:'+bytes(wire.downloaded)+'} ' +
        '{10+cyan:' + bytes(wire.downloadSpeed()) + '/s} ' +
        '{10+red:' + bytes(wire.uploadSpeed()) + '/s} ' +
        '{15+grey:' + tags.join(', ') + '}' +
        '{15+cyan:' + reqStats.join(' ') + '}'
      )
      peerslisted++
      return linesremaining - peerslisted > 4
    })
    linesremaining -= peerslisted

    if (wires.length > peerslisted) {
      clivas.line('{80:}')
      clivas.line('... and '+(wires.length - peerslisted)+' more')
    }

    clivas.line('{80:}')
    clivas.flush(true)
  }
}

function bytes (num) {
  return prettysize(num)
}
<|endoftext|>


<commit_before>/**
 * @copyright 2015, Robin Dietrich
 * @license AGPLv3 <http://www.gnu.org/licenses/agpl.html>
 */
define(function(require, exports, module) {
    main.consumes = [
        "Plugin", "language", "ext", "tabManager", "c9", "save",
        "settings", "preferences", "fs"
    ];
    main.provides = ["cpp"];

    return main;

    function main(options, imports, register) {
        var _ = require("lodash");
        var language = imports.language;
        var ext = imports.ext;
        var Plugin = imports.Plugin;
        var plugin = new Plugin("Robin Dietrich", main.consumes);
        var tabManager = imports.tabManager;
        var save = imports.save;
        var settings = imports.settings;
        var prefs = imports.preferences;
        var fs = imports.fs;

        // Use this to get the full file path for clang-autocomplete
        var basedir = imports.c9.workspaceDir;

        // Worker / Server components
        var server = null;
        var worker_cc = null;
        var worker_diag = null;

        // Registeres our language handlers
        /*language.registerLanguageHandler('plugins/c9.ide.language.cpp/worker/codecompletion_worker', function(err, worker_) {
            if (err) console.log(err);

            // Set worker object and register callback's
            worker_cc = worker_;
            worker_cc.on("invokeCompletion", ccomplete);
        });

        language.registerLanguageHandler('plugins/c9.ide.language.cpp/worker/diagnose_worker', function(err, worker_) {
            if (err)
                console.log(err);

            // Set worker object and register callback's
            worker_diag = worker_;
            worker_diag.on("invokeDiagnose", diagnose);
        });*/

        // Initialized the server side handler
        plugin.on("load", function() {
            // Load our server side plugin
            ext.loadRemotePlugin("clang_tool", {
                code: require("text!./server/cpp_server.js"),
                redefine: !server
            }, function(err, server_) {
                if (err)
                    console.log(err);

                server = server_;
                server.load();
                server.setArgs(settings.get("project/c_cpp/@compilerArguments").split("\n"));
            });

            // Read settings
            settings.on("read", function(e) {
                // project specific settings
                settings.setDefaults("project/c_cpp", [
                    ["compilerArguments", "-I/usr/include\n-I/usr/local/include"]
                ]);
            }, plugin);

            // Listen to updates
            settings.on("project/c_cpp/@compilerArguments", function(value){
                server.set_args(value.split("\n"));
            }, plugin);

            // Project specific preferences
            prefs.add({
                "Project" : {
                    "C / C++" : {
                        position: 1000,
                        "Compiler Arguments" : {
                           type: "textarea",
                           width: 200,
                           height: 130,
                           rowheight: 155,
                           path: "project/c_cpp/@compilerArguments",
                           position: 5000
                        }
                    }
                }
            }, plugin);
        });

        // Make sure the plugin is unloaded so that cached translation units get purged
        plugin.on("unload", function(){
            if (server) {
                server.unload();
                server = null;
                worker_cc = null;
                worker_diag = null;
            }
        });

        // Public api for the cpp plugin
        plugin.freezePublicAPI({
            // Returns code completion results
            complete: function(path, row, col, callback) {
                if (server) {
                    server.complete(path, row, col, callback);
                } else {
                    callback("Server not initialized yet.");
                }
            },

            // Returns clang's diagnostic information
            diagnose: function(path, callback) {
                if (server) {
                    server.diagnose(path, callback);
                } else {
                    callback("Server not initialized yet.");
                }
            }
        });

        // Calls the code completion function
        function ccomplete(ev) {
            // get value and original path
            var value = tabManager.focussedTab.document.value;
            var path = basedir+tabManager.focussedTab.path;

            // do completion on the new file
            server.complete(path, value, ev.data.pos.row+1, ev.data.pos.column+1, function(err, results) {
                worker_cc.emit("invokeCompletionReturn", {
                    data: { id: ev.data.id, results: results }
                });
            });
        }

        // Calls the diagnose function
        function diagnose(ev) {
            // get value and original path
            var value = tabManager.focussedTab.document.value;
            var path = basedir+tabManager.focussedTab.path;

            server.diagnose(path, value, function(err, results) {
                worker_diag.emit("diagnoseReturn", {
                    data: { id: ev.data.id, results: results, path: path }
                });
            });
        }

        // Registers our plugin with C9
        register(null, { cpp: plugin });
    }
});
<commit_msg>Some reordering of declerations<commit_after>/**
 * @copyright 2015, Robin Dietrich
 * @license AGPLv3 <http://www.gnu.org/licenses/agpl.html>
 */
define(function(require, exports, module) {
    main.consumes = [
        "Plugin", "language", "ext", "tabManager", "c9", "save",
        "settings", "preferences", "fs"
    ];
    main.provides = ["cpp"];

    return main;

    function main(options, imports, register) {
        var _ = require("lodash");
        var language = imports.language;
        var ext = imports.ext;
        var Plugin = imports.Plugin;
        var plugin = new Plugin("Robin Dietrich", main.consumes);
        var tabManager = imports.tabManager;
        var c9 = imports.c9;
        var save = imports.save;
        var settings = imports.settings;
        var prefs = imports.preferences;
        var fs = imports.fs;

        // Use this to get the full file path for clang-autocomplete
        var basedir = c9.workspaceDir;

        // External clang_tool component
        var clang_tool = null;

        function loadClangTool() {
            ext.loadRemotePlugin("clang_tool", {
                code: require("text!./server/cpp_server.js"),
                redefine: !clang_tool
            }, function(err, plugin) {
                if (err) {
                    alert("[c9.ide.language.cpp] Error initializing server: ", err);
                    return;
                }

                clang_tool = plugin;
                clang_tool.load();
                clang_tool.setArgs(settings.get("project/c_cpp/@compilerArguments").split("\n"));
            });
        }

        c9.on("connect", loadClangTool);
        c9.on("disconnect", function() {
            clang_tool = null;
        });

        // Register our language handlers
        /*language.registerLanguageHandler('plugins/c9.ide.language.cpp/worker/codecompletion_worker', function(err, worker_) {
            if (err) console.log(err);

            // Set worker object and register callback's
            worker_cc = worker_;
            worker_cc.on("invokeCompletion", ccomplete);
        });

        language.registerLanguageHandler('plugins/c9.ide.language.cpp/worker/diagnose_worker', function(err, worker_) {
            if (err)
                console.log(err);

            // Set worker object and register callback's
            worker_diag = worker_;
            worker_diag.on("invokeDiagnose", diagnose);
        });*/

        // Initialize the plugin
        plugin.on("load", function() {
            // Add project specific preferences
            prefs.add({
                "Project" : {
                    "C / C++" : {
                        position: 1000,
                        "Compiler Arguments" : {
                           type: "textarea",
                           width: 200,
                           height: 130,
                           rowheight: 155,
                           path: "project/c_cpp/@compilerArguments",
                           position: 5000
                        }
                    }
                }
            }, plugin);

            // Set default values
            settings.on("read", function(e) {
                settings.setDefaults("project/c_cpp", [
                    ["compilerArguments", "-I/usr/include\n-I/usr/local/include"]
                ]);
            }, plugin);

            // Listen to updates
            settings.on("project/c_cpp/@compilerArguments", function(value) {
                if (clang_tool)
                    clang_tool.setArgs(value.split("\n"));
            }, plugin);
        });

        // Make sure the plugin is unloaded correctly so that cached translation units get purged
        plugin.on("unload", function(){
            if (clang_tool) {
                clang_tool.unload();
                clang_tool = null;
            }
        });

        // Public api for the cpp plugin
        plugin.freezePublicAPI({});

        // Calls the code completion function
        /*function ccomplete(ev) {
            // get value and original path
            var value = tabManager.focussedTab.document.value;
            var path = basedir+tabManager.focussedTab.path;

            // do completion on the new file
            server.complete(path, value, ev.data.pos.row+1, ev.data.pos.column+1, function(err, results) {
                worker_cc.emit("invokeCompletionReturn", {
                    data: { id: ev.data.id, results: results }
                });
            });
        }

        // Calls the diagnose function
        function diagnose(ev) {
            // get value and original path
            var value = tabManager.focussedTab.document.value;
            var path = basedir+tabManager.focussedTab.path;

            server.diagnose(path, value, function(err, results) {
                worker_diag.emit("diagnoseReturn", {
                    data: { id: ev.data.id, results: results, path: path }
                });
            });
        }*/

        // Registers our plugin with C9
        register(null, { cpp: plugin });
    }
});
<|endoftext|>


<commit_before>/**
 * @license RequireCSS 0.3.0 Copyright (c) 2011, VIISON All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/VIISON/RequireCSS for details
 */

/*jslint forin: true */
/*global document: true, setTimeout: true, define: true */

(function () {
	"use strict";

	var doc = document,
		head = doc.head || doc.getElementsByTagName('head')[0],
		// Eliminate browsers that admit to not support the link load event (e.g. Firefox < 9)
		nativeLoad = doc.createElement('link').onload === null ? undefined : false,
		a = doc.createElement('a');

	function createLink(url) {
		var link = doc.createElement('link');

		link.rel = "stylesheet";
		link.type = "text/css";
		link.href = url;

		return link;
	}

	function styleSheetLoaded(url) {
		var i;

		// Get absolute url by assigning to a link and reading it back below
		a.href = url;

		for (i in doc.styleSheets) {
			if (doc.styleSheets[i].href === a.href) {
				return true;
			}
		}

		return false;
	}

	define(function () {
		var css;

		css = {
			version: '0.3.0',

			testLoad: function (url, load) {
				// Test if the browser supports the link load event,
				// in case we don't know yet (mostly WebKit)
				if (nativeLoad === undefined) {
					// Create a link element with a data url,
					// it would fire a load event immediately
					var link = createLink('data:text/css,');

					link.onload = function () {
						// Native link load event works
						nativeLoad = true;
					};

					head.appendChild(link);

					// Schedule function in event loop, this will
					// execute after a potential execution of the link onload
					setTimeout(function () {
						head.removeChild(link);

						if (nativeLoad !== true) {
							// Native link load event is broken
							nativeLoad = false;
						}

						css.loadSwitch(url, load);
					}, 0);
				} else {
					css.loadSwitch(url, load);
				}
			},

			loadSwitch: function (url, load) {
				if (nativeLoad) {
					css.loadLink(url, load);
				} else {
					css.loadScript(url, load);
				}
			},

			/**
			 * Load using the browsers built-in load event on link tags
			 */
			loadLink: function (url, load) {
				var link = createLink(url);

				link.onload = function () {
					load();
				};

				head.appendChild(link);
			},

			/**
			 * Insert a script tag and use it's onload & onerror to know when
			 * the CSS is loaded, this will unfortunately also fire on other
			 * errors (file not found, network problems)
			 */
			loadScript: function (url, load) {
				var link = createLink(url),
					script = doc.createElement('script');

				head.appendChild(link);

				script.onload = script.onerror = function () {
					head.removeChild(script);

					// In Safari the stylesheet might not yet be applied, when
					// the script is loaded so we poll document.styleSheets for it
					var checkLoaded = function () {
						if (styleSheetLoaded(url)) {
							load();

							return;
						}

						setTimeout(checkLoaded, 25);
					};
					checkLoaded();
				};
				script.src = url;

				head.appendChild(script);
			},

			load: function (name, req, load) { //, config (not used)
				// Append default extension
				var url = name.search(/\.(css|less|scss)$/i) === -1 ? name + '.css' : name;

				css.testLoad(req.toUrl(url), load);
			}
		};

		return css;
	});
}());<commit_msg>Do not export internal functions (also yields better minification results)<commit_after>/**
 * @license RequireCSS 0.3.0 Copyright (c) 2011, VIISON All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/VIISON/RequireCSS for details
 */

/*jslint forin: true */
/*global document: true, setTimeout: true, define: true */

(function () {
	"use strict";

	var doc = document,
		head = doc.head || doc.getElementsByTagName('head')[0],
		// Eliminate browsers that admit to not support the link load event (e.g. Firefox < 9)
		nativeLoad = doc.createElement('link').onload === null ? undefined : false,
		a = doc.createElement('a');

	function createLink(url) {
		var link = doc.createElement('link');

		link.rel = "stylesheet";
		link.type = "text/css";
		link.href = url;

		return link;
	}

	function styleSheetLoaded(url) {
		var i;

		// Get absolute url by assigning to a link and reading it back below
		a.href = url;

		for (i in doc.styleSheets) {
			if (doc.styleSheets[i].href === a.href) {
				return true;
			}
		}

		return false;
	}

	function loadSwitch(url, load) {
		if (nativeLoad) {
			loadLink(url, load);
		} else {
			loadScript(url, load);
		}
	};

	/**
	 * Load using the browsers built-in load event on link tags
	 */
	function loadLink(url, load) {
		var link = createLink(url);

		link.onload = function () {
			load();
		};

		head.appendChild(link);
	};

	/**
	 * Insert a script tag and use it's onload & onerror to know when
	 * the CSS is loaded, this will unfortunately also fire on other
	 * errors (file not found, network problems)
	 */
	function loadScript(url, load) {
		var link = createLink(url),
			script = doc.createElement('script');

		head.appendChild(link);

		script.onload = script.onerror = function () {
			head.removeChild(script);

			// In Safari the stylesheet might not yet be applied, when
			// the script is loaded so we poll document.styleSheets for it
			var checkLoaded = function () {
				if (styleSheetLoaded(url)) {
					load();

					return;
				}

				setTimeout(checkLoaded, 25);
			};
			checkLoaded();
		};
		script.src = url;

		head.appendChild(script);
	};

	define(function () {
		var css;

		css = {
			version: '0.3.0',

			load: function (name, req, load) { //, config (not used)
				// convert name to actual url
				var url = req.toUrl(
					// Append default extension
					name.search(/\.(css|less|scss)$/i) === -1 ? name + '.css' : name
				);

				// Test if the browser supports the link load event,
				// in case we don't know yet (mostly WebKit)
				if (nativeLoad === undefined) {
					// Create a link element with a data url,
					// it would fire a load event immediately
					var link = createLink('data:text/css,');

					link.onload = function () {
						// Native link load event works
						nativeLoad = true;
					};

					head.appendChild(link);

					// Schedule function in event loop, this will
					// execute after a potential execution of the link onload
					setTimeout(function () {
						head.removeChild(link);

						if (nativeLoad !== true) {
							// Native link load event is broken
							nativeLoad = false;
						}

						loadSwitch(url, load);
					}, 0);
				} else {
					loadSwitch(url, load);
				}
			}
		};

		return css;
	});
}());<|endoftext|>


<commit_before>/**
 * @license RequireCSS 0.3.0 Copyright (c) 2011, VIISON All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/viison/requirejs-css for details
 */
(function () {

	var head = document.head || document.getElementsByTagName('head')[0],
		// Eliminate browsers that admit to not support the link load event (e.g. Firefox)
		nativeLoad = document.createElement('link').onload === null ? undefined : false;

	function createLink(url) {
		var link = document.createElement('link');

		link.rel = "stylesheet";
		link.type = "text/css";
		link.href = url;

		return link;
	}

	function styleSheetLoaded(url) {
		// Get absolute url
		var a = document.createElement('a');
		a.href = url;

		for (var i in document.styleSheets) {
			if (document.styleSheets[i].href === a.href) {
				return true;
			}
		}

		return false;
	}

	define(function () {
		var css;

		css = {
			version: '0.3.0',

			testLoad: function (url, load) {
				// Test if the browser supports the link load event,
				// in case we don't know yet (mostly WebKit)
				if (nativeLoad === undefined) {
					// Create a link element with a data url,
					// it would fire a load event immediately
					var link = createLink('data:text/css,');

					link.onload = function () {
						// Native link load event works
						nativeLoad = true;
					};

					head.appendChild(link);

					// Schedule function in event loop, this will
					// execute after a potential execution of the link onload
					setTimeout(function () {
						head.removeChild(link);

						if (nativeLoad !== true) {
							// Native link load event is broken
							nativeLoad = false;
						}

						css.loadSwitch(url, load);
					}, 0);
				} else {
					css.loadSwitch(url, load);
				}
			},

			loadSwitch: function (url, load) {
				if (nativeLoad) {
					css.loadLink(url, load);
				} else {
					css.loadScript(url, load);
				}
			},

			/**
			 * Load using the browsers built-in load event on link tags
			 */
			loadLink: function (url, load) {
				var link = createLink(url);

				link.onload = function () {
					load();
				};

				head.appendChild(link);
			},

			/**
			 * Insert a script tag and use it's onload & onerror to know when
			 * the CSS is loaded, this will unfortunately also fire on other
			 * errors (file not found, network problems)
			 */
			loadScript: function (url, load) {
				var link = createLink(url),
					script = document.createElement('script');

				head.appendChild(link);

				script.onload = script.onerror = function () {
					head.removeChild(script);

					// In Safari the stylesheet might not yet be applied, when
					// the script is loaded so we poll document.styleSheets for it
					var checkLoaded = function() {
						if (styleSheetLoaded(url)) {
							load();

							return;
						}

						setTimeout(checkLoaded, 25);
					}
					checkLoaded();
				};
				script.src = url;

				head.appendChild(script);
			},

			load: function (name, req, load, config) {
				// Append default extension
				var url = name.search(/\.(css|less|scss)$/i) === -1 ? name + '.css' : name;

				css.testLoad(req.toUrl(url), load);
			}
		};

		return css;
	});
}());<commit_msg>Correct repository url<commit_after>/**
 * @license RequireCSS 0.3.0 Copyright (c) 2011, VIISON All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/VIISON/RequireCSS for details
 */
(function () {

	var head = document.head || document.getElementsByTagName('head')[0],
		// Eliminate browsers that admit to not support the link load event (e.g. Firefox)
		nativeLoad = document.createElement('link').onload === null ? undefined : false;

	function createLink(url) {
		var link = document.createElement('link');

		link.rel = "stylesheet";
		link.type = "text/css";
		link.href = url;

		return link;
	}

	function styleSheetLoaded(url) {
		// Get absolute url
		var a = document.createElement('a');
		a.href = url;

		for (var i in document.styleSheets) {
			if (document.styleSheets[i].href === a.href) {
				return true;
			}
		}

		return false;
	}

	define(function () {
		var css;

		css = {
			version: '0.3.0',

			testLoad: function (url, load) {
				// Test if the browser supports the link load event,
				// in case we don't know yet (mostly WebKit)
				if (nativeLoad === undefined) {
					// Create a link element with a data url,
					// it would fire a load event immediately
					var link = createLink('data:text/css,');

					link.onload = function () {
						// Native link load event works
						nativeLoad = true;
					};

					head.appendChild(link);

					// Schedule function in event loop, this will
					// execute after a potential execution of the link onload
					setTimeout(function () {
						head.removeChild(link);

						if (nativeLoad !== true) {
							// Native link load event is broken
							nativeLoad = false;
						}

						css.loadSwitch(url, load);
					}, 0);
				} else {
					css.loadSwitch(url, load);
				}
			},

			loadSwitch: function (url, load) {
				if (nativeLoad) {
					css.loadLink(url, load);
				} else {
					css.loadScript(url, load);
				}
			},

			/**
			 * Load using the browsers built-in load event on link tags
			 */
			loadLink: function (url, load) {
				var link = createLink(url);

				link.onload = function () {
					load();
				};

				head.appendChild(link);
			},

			/**
			 * Insert a script tag and use it's onload & onerror to know when
			 * the CSS is loaded, this will unfortunately also fire on other
			 * errors (file not found, network problems)
			 */
			loadScript: function (url, load) {
				var link = createLink(url),
					script = document.createElement('script');

				head.appendChild(link);

				script.onload = script.onerror = function () {
					head.removeChild(script);

					// In Safari the stylesheet might not yet be applied, when
					// the script is loaded so we poll document.styleSheets for it
					var checkLoaded = function() {
						if (styleSheetLoaded(url)) {
							load();

							return;
						}

						setTimeout(checkLoaded, 25);
					}
					checkLoaded();
				};
				script.src = url;

				head.appendChild(script);
			},

			load: function (name, req, load, config) {
				// Append default extension
				var url = name.search(/\.(css|less|scss)$/i) === -1 ? name + '.css' : name;

				css.testLoad(req.toUrl(url), load);
			}
		};

		return css;
	});
}());<|endoftext|>