<commit_before>var env = process.env.RACK_ENV;

var express = require('express')
  , compression = require('compression')
  , Twitter = require('twitter')
  , fs = require('fs')
  , _ = require('lodash')
  , Q = require('q')
  , app = express();

var apicache = require('apicache').options({ debug: true }).middleware;

var client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER_KEY,
  consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
  access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
  access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});

app.use(compression()); //gzip!

app.use(function(req, res, next){

  var whitelist = ['localhost:4000', 'localhost:8080', 'slowsbarbq.com']

  if(whitelist.indexOf(req.get('host')) > -1){
    res.setHeader('Access-Control-Allow-Origin', req.get('host'));
  }

  next();
});

app.get("/cards/:handle", apicache('20 minutes'), function(req, res, next){

  console.time('getEmbends'); // Track how long this takes!
  var startTime = Date.now();

  timeline(req.params.handle)
    .then(function(data){
      console.timeEnd('getEmbends'); // How long did it take?
      var endTime = Date.now()

      res.send({
        'created_at': endTime,
        'generation_time': (endTime - startTime) + 'ms',
        'cached_until': endTime + (20 * 60 * 1000),
        'cards': data
      })
    }, function(error){
      res.status(500).send({'error': data})
    })

})

app.use(function(req, res, next){ res.sendfile('./public/index.html'); })

var port = process.env.PORT || 8080;
app.listen(port);

console.log("listening on port " + port);

////////
/// helpers ============================

function settled(results) {
  var embeds = [];
  results.forEach(function (result) {
    if (result.state === "fulfilled") {
      console.log('got embed code for ', result.value.url);
      embeds.push({
        url: result.value.url,
        html: result.value.html
      });
    } else {
      console.log('error: ', result.reason);
    }
  });
  return embeds;
}

function withMedia(tweets) {
  return _.filter(tweets, function(t) {
    if(t.entities.media) {
      return t;
    }
  });
}

function embed(tweet){
  var defer = Q.defer();

  var params = {
    id: tweet.id_str,
    omit_script: true,
    hide_thread: true
  }
  //console.log(params)
  client.get('statuses/oembed', params, function(error, tweets, response){
    if (error) {
      console.log('cannot get embed code for ', tweet.id_str)
      defer.reject(error);
    } else {
      defer.resolve(tweets);
    }
  });
  return defer.promise;
}

function timeline(handle){
  var defer = Q.defer();
  var maxCards = 10;
  var params = {
    screen_name: handle,
    trim_user: true,
    count: 100,
    include_rts: true,
    include_entities: true
  };

  client.get('statuses/user_timeline', params, function(error, tweets, response){
    if (!error) {
      var _embeds = [];

      withMedia(tweets).forEach(function(tweet){
        if(_embeds.length < maxCards) {
          _embeds.push(embed(tweet));
        }
      })

      Q.allSettled(_embeds)
      .then(settled)
      .done(function(embeds){
        console.log('all done')
        defer.resolve(embeds)
      });

    } else {
      defer.reject(error);
    }
  });

  return defer.promise;
}
<commit_msg>cors works regardless of host<commit_after>var env = process.env.RACK_ENV;

var express = require('express')
  , compression = require('compression')
  , Twitter = require('twitter')
  , fs = require('fs')
  , _ = require('lodash')
  , Q = require('q')
  , app = express();

var apicache = require('apicache').options({ debug: true }).middleware;

var client = new Twitter({
  consumer_key: process.env.TWITTER_CONSUMER_KEY,
  consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
  access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
  access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});

app.use(compression()); //gzip!

app.use(function(req, res, next){
  var whitelist = ['localhost:4000', 'localhost:8080', 'slowsbarbq.com']
  var host = req.get('host');

  whitelist.forEach(function(val, key){
    if (host.indexOf(val) > -1){
      res.setHeader('Access-Control-Allow-Origin', host);
    }
  })

  next();
});

app.get("/cards/:handle", apicache('20 minutes'), function(req, res, next){

  console.time('getEmbends'); // Track how long this takes!
  var startTime = Date.now();

  timeline(req.params.handle)
    .then(function(data){
      console.timeEnd('getEmbends'); // How long did it take?
      var endTime = Date.now()

      res.send({
        'created_at': endTime,
        'generation_time': (endTime - startTime) + 'ms',
        'cached_until': endTime + (20 * 60 * 1000),
        'cards': data
      })
    }, function(error){
      res.status(500).send({'error': data})
    })

})

app.use(function(req, res, next){ res.sendfile('./public/index.html'); })

var port = process.env.PORT || 8080;
app.listen(port);

console.log("listening on port " + port);

////////
/// helpers ============================

function settled(results) {
  var embeds = [];
  results.forEach(function (result) {
    if (result.state === "fulfilled") {
      console.log('got embed code for ', result.value.url);
      embeds.push({
        url: result.value.url,
        html: result.value.html
      });
    } else {
      console.log('error: ', result.reason);
    }
  });
  return embeds;
}

function withMedia(tweets) {
  return _.filter(tweets, function(t) {
    if(t.entities.media) {
      return t;
    }
  });
}

function embed(tweet){
  var defer = Q.defer();

  var params = {
    id: tweet.id_str,
    omit_script: true,
    hide_thread: true
  }
  //console.log(params)
  client.get('statuses/oembed', params, function(error, tweets, response){
    if (error) {
      console.log('cannot get embed code for ', tweet.id_str)
      defer.reject(error);
    } else {
      defer.resolve(tweets);
    }
  });
  return defer.promise;
}

function timeline(handle){
  var defer = Q.defer();
  var maxCards = 10;
  var params = {
    screen_name: handle,
    trim_user: true,
    count: 100,
    include_rts: true,
    include_entities: true
  };

  client.get('statuses/user_timeline', params, function(error, tweets, response){
    if (!error) {
      var _embeds = [];

      withMedia(tweets).forEach(function(tweet){
        if(_embeds.length < maxCards) {
          _embeds.push(embed(tweet));
        }
      })

      Q.allSettled(_embeds)
      .then(settled)
      .done(function(embeds){
        console.log('all done')
        defer.resolve(embeds)
      });

    } else {
      defer.reject(error);
    }
  });

  return defer.promise;
}
<|endoftext|>


<commit_before>'use strict';

var CONFIG_FILE = '/.cartridgerc';
var MATCH_REGEX = /(\[\/\/\]: <> \(Modules start\)\s)([^[]*)(\[\/\/\]: <> \(Modules end\)\s)/g;

var del      = require('del');
var path     = require('path');
var chalk    = require('chalk');
var template = require('lodash/template');
var Promise  = require('bluebird');
var fs       = Promise.promisifyAll(require('fs-extra'));
var inArray = require('in-array');

var paths = {
	project:   path.resolve('../../'),
	config:    path.resolve('../../', '_config'),
	readme:    path.resolve('../../', 'readme.md'),
	cartridge: path.resolve('../../_cartridge')
};

// Checks if the project has been set up with Cartridge
function hasCartridgeInstalled() {
	try {
		fs.accessSync(paths.project + CONFIG_FILE, fs.R_OK | fs.W_OK);
	} catch(err) {
		return false;
	}

	return true;
}

function insertModulesInToReadme(readmeContents) {
	return readmeContents.replace(MATCH_REGEX, this.renderedModules);
}

function updateReadme(renderedModuleTemplate) {

	return fs.readFileAsync(paths.readme, 'utf8')
		.bind({
			renderedModules: renderedModuleTemplate
		})
		.then(insertModulesInToReadme)
		.then(function(fileContent){
			return fs.writeFileAsync(paths.readme, fileContent)
		})
		.catch(function(err) {
			console.log('updateReadme error');
			console.error(err);
			process.exit(1);
		});
}

function compileTemplate(rawTemplate) {
	var compiledTemplate = template(rawTemplate);

	return compiledTemplate(this)
}

function updateReadmeModules(rcData) {
	var filePath = path.join(paths.cartridge, 'modules.tpl');

	return fs.readFileAsync(filePath, 'utf8')
		.bind(rcData)
		.then(compileTemplate)
		.then(updateReadme)
		.catch(function(err){
			console.log('updateReadmeModules error');
			console.error(err);
			console.trace();
			process.exit(1);
		});
}

function ensureProjectConfigPaths(projectConfig) {
	if(!projectConfig.hasOwnProperty('paths')) {
		projectConfig.paths = {
			src:   {},
			dest: {}
		};
	}

	if(!projectConfig.paths.hasOwnProperty('src')) {
		projectConfig.paths.src = {};
	}

	if(!projectConfig.paths.hasOwnProperty('dest')) {
		projectConfig.paths.dest = {};
	}

	return projectConfig;
}

function getModuleId(modules, moduleName) {
	var i, moduleIndex;

	// Yes so check that this one doesn't already exist
	for(i = 0; i < modules.length; i++) {

		if(modules[i].name == moduleName) {
			moduleIndex = i;
			break;
		}
	}

	if(moduleIndex === undefined) {
		moduleIndex = modules.length;
	}

	return moduleIndex;
}

function removeModuleDataFromRcObject(data, moduleName) {
	for (var i = 0; i < data.modules.length; i++) {
		if(data.modules[i].name === moduleName) {
			data.modules.splice(i, 1);
		}
	}

	return data;
}

function addModule(rcContent) {
	// This is bound to the module data
	var i, moduleIndex;

	// Check if any modules have been added to the rc yet
	if(!rcContent.hasOwnProperty('modules')) {
		// No so create the array
		rcContent.modules = [];
		moduleIndex = 0;
	} else {
		moduleIndex = getModuleId(rcContent.modules, this.name);
	}

	// Set the data
	rcContent.modules[moduleIndex] = this;

	return rcContent;
}

function writeJsonFile(fileContent) {
	return fs.writeJsonAsync(this, fileContent)
		.then(function(){
			return fileContent;
		});
}

module.exports = function(packageConfig) {
	var cartridgeApi = {};

	function _copyToProjectDir(packageName, copyPath, destinationPath) {
		var fullFileName = path.basename(copyPath);
		var projectDestinationDirectory = (destinationPath) ? path.join(paths.project, destinationPath) : paths.project;
		var destinationFileList = fs.readdirSync(projectDestinationDirectory);
		var projectDestinationPath = path.join(projectDestinationDirectory, fullFileName);
		var fileAlreadyExists = inArray(destinationFileList, fullFileName);

		if(fileAlreadyExists) {
			cartridgeApi.logMessage('Skipping: Copying ' + fullFileName + ' file as it already exists');
			return Promise.resolve();
		}

		return fs.copyAsync(copyPath, projectDestinationPath)
			.then(function(){
				cartridgeApi.logMessage('Finished: Copying ' + fullFileName + ' for ' + packageName + '');
				return Promise.resolve();
			});
	}

	function _removeFromProjectDir(removePath, packageName) {
		var fullFileName = path.basename(removePath);
		var projectRemovePath = path.join(paths.project, removePath);

		return fs.removeAsync(projectRemovePath)
			.then(function(){
				cartridgeApi.logMessage('Finished: Removing ' + fullFileName + ' for ' + packageName + '');
				return Promise.resolve();
			});
	}

	cartridgeApi.exitIfDevEnvironment = function() {
		if(process.env.NODE_ENV === 'development') {

			cartridgeApi.logMessage('NODE_ENV is set to ' + chalk.underline('development'));
			cartridgeApi.logMessage('Skipping postinstall.js for ' + chalk.underline(packageConfig.name));
			cartridgeApi.logMessage('');

			process.exit(0);
		}
	}

	cartridgeApi.ensureCartridgeExists = function ensureCartridgeExists() {
		if(!hasCartridgeInstalled()) {
			console.error(chalk.red('Cartridge is not set up in this directory. Please set it up first before installing this module'));
			process.exit(1);
		}
	};

	// Adds the specified module to the .cartridgerc file
	cartridgeApi.addToRc = function addToRc() {
		var filePath = path.join(paths.project,  CONFIG_FILE);

		var moduleConfig = {
			name:    packageConfig.name,
			version: packageConfig.version,
			site:    packageConfig.homepage,
			task:    packageConfig.name + '/' + packageConfig.main
		};

		cartridgeApi.logMessage('Adding ' + packageConfig.name + ' to .cartridgerc');

		return fs.readJsonAsync(filePath)
			.bind(moduleConfig)
			.then(addModule)
			.bind(filePath)
			.then(writeJsonFile)
			.then(updateReadmeModules)
			.then(function() {
				cartridgeApi.logMessage('Finished: adding ' + packageConfig.name + ' to .cartridgerc');
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('addToRc error');
				console.error(err);
				process.exit(1);
			});
	};

	// Removes the specified module from the .cartridgerc file
	cartridgeApi.removeFromRc = function removeFromRc() {
		var filePath = path.join(paths.project,  CONFIG_FILE);

		cartridgeApi.logMessage('Removing ' + packageConfig.name + ' from .cartridgerc');

		return fs.readJsonAsync(filePath)
			.then(function(data) {
				return removeModuleDataFromRcObject(data, packageConfig.name);
			})
			.bind(filePath)
			.then(writeJsonFile)
			.then(updateReadmeModules)
			.then(function() {
				cartridgeApi.logMessage('Finished: Removing ' + packageConfig.name + ' from .cartridgerc');
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('removeFromRc error');
				console.error(err);
				process.exit(1);
			});
	};

	// Modify the project configuration (project.json) with a transform function
	cartridgeApi.modifyProjectConfig = function modifyProjectConfig(transform) {
		var filePath = path.join(paths.config,  '/project.json');

		cartridgeApi.logMessage('Updating project config for ' + packageConfig.name);

		return fs.readJsonAsync(paths.config + '/project.json')
			.then(ensureProjectConfigPaths)
			.then(transform)
			.bind(filePath)
			.then(writeJsonFile)
			.then(function(){
				cartridgeApi.logMessage('Finished: modifying project config for ' + packageConfig.name);
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('modifyProjectConfig error');
				console.error(err);
				process.exit(1);
			});
	};

	// Add configuration files to the project _config directory for this module
	cartridgeApi.addModuleConfig = function addModuleConfig(configPath) {
		var configFileName = path.basename(configPath)
		var toPath = path.join(paths.config, configFileName);
		var destinationFileList = fs.readdirSync(paths.config);
		var configFileExists = inArray(destinationFileList, configFileName);

		if(configFileExists) {
			cartridgeApi.logMessage('Skipping: Copying config file as it already exists');
			return Promise.resolve();
		}

		return fs.copyAsync(configPath, toPath)
			.then(function(){
				cartridgeApi.logMessage('Finished: adding ' + packageConfig.name + ' config files');
				return Promise.resolve();
			});
	};

	cartridgeApi.copyToProjectDir = function copyToProjectDir(fileList) {
		var copyTasks = [];

		for (var i = 0; i < fileList.length; i++) {
			copyTasks.push(_copyToProjectDir(packageConfig.name, fileList[i].copyPath, fileList[i].destinationPath));
		}

		return Promise.all(copyTasks);
	}

	// Remove configuration files from the project _config directory for this module
	cartridgeApi.removeModuleConfig = function removeModuleConfig(configPath) {
		var configFileName = path.basename(configPath)
		var projectModuleConfigPath = path.join(paths.config, configFileName);

		return fs.removeAsync(projectModuleConfigPath)
			.then(function(){
				cartridgeApi.logMessage('Finished: Removed ' + packageConfig.name + ' config files');
				return Promise.resolve();
			});
	};

	cartridgeApi.removeFromProjectDir = function removeFromProjectDir(fileList) {
		var removeTasks = [];

		for (var i = 0; i < fileList.length; i++) {
			removeTasks.push(_removeFromProjectDir(fileList[i], packageConfig.name));
		}

		return Promise.all(removeTasks);
	}

	cartridgeApi.finishInstall = function finishInstall(packageDetails) {
		cartridgeApi.logMessage('Finished: post install of ' + packageConfig.name);
		process.exit(0);
	};

	cartridgeApi.finishUninstall = function finishUninstall(packageDetails) {
		cartridgeApi.logMessage('Finished: post uninstall of ' + packageConfig.name);
		process.exit(0);
	};

	cartridgeApi.logMessage = function logMessage(message) {
		console.log(message);
	};

	return cartridgeApi;
};
<commit_msg>adding steps to update package json for the node server dependencies<commit_after>'use strict';

var CONFIG_FILE = '/.cartridgerc';
var MATCH_REGEX = /(\[\/\/\]: <> \(Modules start\)\s)([^[]*)(\[\/\/\]: <> \(Modules end\)\s)/g;

var del      = require('del');
var path     = require('path');
var chalk    = require('chalk');
var template = require('lodash/template');
var Promise  = require('bluebird');
var fs       = Promise.promisifyAll(require('fs-extra'));
var inArray = require('in-array');

var paths = {
	project:   path.resolve('../../'),
	config:    path.resolve('../../', '_config'),
	readme:    path.resolve('../../', 'readme.md'),
	cartridge: path.resolve('../../_cartridge'),
	pkg: 			 path.resolve('../../', 'package.json')
};

// Checks if the project has been set up with Cartridge
function hasCartridgeInstalled() {
	try {
		fs.accessSync(paths.project + CONFIG_FILE, fs.R_OK | fs.W_OK);
	} catch(err) {
		return false;
	}

	return true;
}

function insertModulesInToReadme(readmeContents) {
	return readmeContents.replace(MATCH_REGEX, this.renderedModules);
}

function updateReadme(renderedModuleTemplate) {

	return fs.readFileAsync(paths.readme, 'utf8')
		.bind({
			renderedModules: renderedModuleTemplate
		})
		.then(insertModulesInToReadme)
		.then(function(fileContent){
			return fs.writeFileAsync(paths.readme, fileContent)
		})
		.catch(function(err) {
			console.log('updateReadme error');
			console.error(err);
			process.exit(1);
		});
}

function updateJsonObj(obj, newObj){
	for (var key in newObj) {
    obj[key] = newObj[key];
	}
	return obj;
}

function compileTemplate(rawTemplate) {
	var compiledTemplate = template(rawTemplate);

	return compiledTemplate(this)
}

function updateReadmeModules(rcData) {
	var filePath = path.join(paths.cartridge, 'modules.tpl');

	return fs.readFileAsync(filePath, 'utf8')
		.bind(rcData)
		.then(compileTemplate)
		.then(updateReadme)
		.catch(function(err){
			console.log('updateReadmeModules error');
			console.error(err);
			console.trace();
			process.exit(1);
		});
}

function ensureProjectConfigPaths(projectConfig) {
	if(!projectConfig.hasOwnProperty('paths')) {
		projectConfig.paths = {
			src:   {},
			dest: {}
		};
	}

	if(!projectConfig.paths.hasOwnProperty('src')) {
		projectConfig.paths.src = {};
	}

	if(!projectConfig.paths.hasOwnProperty('dest')) {
		projectConfig.paths.dest = {};
	}

	return projectConfig;
}

function getModuleId(modules, moduleName) {
	var i, moduleIndex;

	// Yes so check that this one doesn't already exist
	for(i = 0; i < modules.length; i++) {

		if(modules[i].name == moduleName) {
			moduleIndex = i;
			break;
		}
	}

	if(moduleIndex === undefined) {
		moduleIndex = modules.length;
	}

	return moduleIndex;
}

function removeModuleDataFromRcObject(data, moduleName) {
	for (var i = 0; i < data.modules.length; i++) {
		if(data.modules[i].name === moduleName) {
			data.modules.splice(i, 1);
		}
	}

	return data;
}

function addModule(rcContent) {
	// This is bound to the module data
	var i, moduleIndex;

	// Check if any modules have been added to the rc yet
	if(!rcContent.hasOwnProperty('modules')) {
		// No so create the array
		rcContent.modules = [];
		moduleIndex = 0;
	} else {
		moduleIndex = getModuleId(rcContent.modules, this.name);
	}

	// Set the data
	rcContent.modules[moduleIndex] = this;

	return rcContent;
}

function writeJsonFile(fileContent) {
	return fs.writeJsonAsync(this, fileContent)
		.then(function(){
			return fileContent;
		});
}

module.exports = function(packageConfig) {
	var cartridgeApi = {};

	function _copyToProjectDir(packageName, copyPath, destinationPath) {
		var fullFileName = path.basename(copyPath);
		var projectDestinationDirectory = (destinationPath) ? path.join(paths.project, destinationPath) : paths.project;
		var destinationFileList = fs.readdirSync(projectDestinationDirectory);
		var projectDestinationPath = path.join(projectDestinationDirectory, fullFileName);
		var fileAlreadyExists = inArray(destinationFileList, fullFileName);

		if(fileAlreadyExists) {
			cartridgeApi.logMessage('Skipping: Copying ' + fullFileName + ' file as it already exists');
			return Promise.resolve();
		}

		return fs.copyAsync(copyPath, projectDestinationPath)
			.then(function(){
				cartridgeApi.logMessage('Finished: Copying ' + fullFileName + ' for ' + packageName + '');
				return Promise.resolve();
			});
	}

	function _removeFromProjectDir(removePath, packageName) {
		var fullFileName = path.basename(removePath);
		var projectRemovePath = path.join(paths.project, removePath);

		return fs.removeAsync(projectRemovePath)
			.then(function(){
				cartridgeApi.logMessage('Finished: Removing ' + fullFileName + ' for ' + packageName + '');
				return Promise.resolve();
			});
	}

	cartridgeApi.exitIfDevEnvironment = function() {
		if(process.env.NODE_ENV === 'development') {

			cartridgeApi.logMessage('NODE_ENV is set to ' + chalk.underline('development'));
			cartridgeApi.logMessage('Skipping postinstall.js for ' + chalk.underline(packageConfig.name));
			cartridgeApi.logMessage('');

			process.exit(0);
		}
	}

	cartridgeApi.ensureCartridgeExists = function ensureCartridgeExists() {
		if(!hasCartridgeInstalled()) {
			console.error(chalk.red('Cartridge is not set up in this directory. Please set it up first before installing this module'));
			process.exit(1);
		}
	};

	// Adds the specified module to the .cartridgerc file
	cartridgeApi.addToRc = function addToRc() {
		var filePath = path.join(paths.project,  CONFIG_FILE);

		var moduleConfig = {
			name:    packageConfig.name,
			version: packageConfig.version,
			site:    packageConfig.homepage,
			task:    packageConfig.name + '/' + packageConfig.main
		};

		cartridgeApi.logMessage('Adding ' + packageConfig.name + ' to .cartridgerc');

		return fs.readJsonAsync(filePath)
			.bind(moduleConfig)
			.then(addModule)
			.bind(filePath)
			.then(writeJsonFile)
			.then(updateReadmeModules)
			.then(function() {
				cartridgeApi.logMessage('Finished: adding ' + packageConfig.name + ' to .cartridgerc');
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('addToRc error');
				console.error(err);
				process.exit(1);
			});
	};

	// Removes the specified module from the .cartridgerc file
	cartridgeApi.removeFromRc = function removeFromRc() {
		var filePath = path.join(paths.project,  CONFIG_FILE);

		cartridgeApi.logMessage('Removing ' + packageConfig.name + ' from .cartridgerc');

		return fs.readJsonAsync(filePath)
			.then(function(data) {
				return removeModuleDataFromRcObject(data, packageConfig.name);
			})
			.bind(filePath)
			.then(writeJsonFile)
			.then(updateReadmeModules)
			.then(function() {
				cartridgeApi.logMessage('Finished: Removing ' + packageConfig.name + ' from .cartridgerc');
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('removeFromRc error');
				console.error(err);
				process.exit(1);
			});
	};

	// Modify the project configuration (project.json) with a transform function
	cartridgeApi.modifyProjectConfig = function modifyProjectConfig(transform) {
		var filePath = path.join(paths.config,  '/project.json');

		cartridgeApi.logMessage('Updating project config for ' + packageConfig.name);

		return fs.readJsonAsync(paths.config + '/project.json')
			.then(ensureProjectConfigPaths)
			.then(transform)
			.bind(filePath)
			.then(writeJsonFile)
			.then(function(){
				cartridgeApi.logMessage('Finished: modifying project config for ' + packageConfig.name);
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('modifyProjectConfig error');
				console.error(err);
				process.exit(1);
			});
	};

	// Add configuration files to the project _config directory for this module
	cartridgeApi.addModuleConfig = function addModuleConfig(configPath) {
		var configFileName = path.basename(configPath)
		var toPath = path.join(paths.config, configFileName);
		var destinationFileList = fs.readdirSync(paths.config);
		var configFileExists = inArray(destinationFileList, configFileName);

		if(configFileExists) {
			cartridgeApi.logMessage('Skipping: Copying config file as it already exists');
			return Promise.resolve();
		}

		return fs.copyAsync(configPath, toPath)
			.then(function(){
				cartridgeApi.logMessage('Finished: adding ' + packageConfig.name + ' config files');
				return Promise.resolve();
			});
	};

	cartridgeApi.copyToProjectDir = function copyToProjectDir(fileList) {
		var copyTasks = [];

		for (var i = 0; i < fileList.length; i++) {
			copyTasks.push(_copyToProjectDir(packageConfig.name, fileList[i].copyPath, fileList[i].destinationPath));
		}

		return Promise.all(copyTasks);
	}

	// Remove configuration files from the project _config directory for this module
	cartridgeApi.removeModuleConfig = function removeModuleConfig(configPath) {
		var configFileName = path.basename(configPath)
		var projectModuleConfigPath = path.join(paths.config, configFileName);

		return fs.removeAsync(projectModuleConfigPath)
			.then(function(){
				cartridgeApi.logMessage('Finished: Removed ' + packageConfig.name + ' config files');
				return Promise.resolve();
			});
	};

	cartridgeApi.removeFromProjectDir = function removeFromProjectDir(fileList) {
		var removeTasks = [];

		for (var i = 0; i < fileList.length; i++) {
			removeTasks.push(_removeFromProjectDir(fileList[i], packageConfig.name));
		}

		return Promise.all(removeTasks);
	}

	cartridgeApi.addToPackage = function addToPackage(objToAdd){
		//get package.json
		var pkg = {};
		return fs.readJsonAsync(paths.pkg)
			.then(function(data){
				pkg = data;
				return updateJsonObj(data.dependencies, objToAdd);
			})
			.then(function(newPkg){
				//update file with new values
				pkg.dependencies = newPkg;
				writeJsonFile(pkg);
			})
			.then(function(){
				cartridgeApi.logMessage('Finished: modifying package.json for ' + packageConfig.name);
				return Promise.resolve();
			})
			.catch(function(err){
				console.log('modifyPackageJson error');
				console.error(err);
				process.exit(1);
			});
	}

	cartridgeApi.finishInstall = function finishInstall(packageDetails) {
		cartridgeApi.logMessage('Finished: post install of ' + packageConfig.name);
		process.exit(0);
	};

	cartridgeApi.finishUninstall = function finishUninstall(packageDetails) {
		cartridgeApi.logMessage('Finished: post uninstall of ' + packageConfig.name);
		process.exit(0);
	};

	cartridgeApi.logMessage = function logMessage(message) {
		console.log(message);
	};

	return cartridgeApi;
};
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var Buffer = require('buffer').Buffer;
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var map = require('event-stream').map;

var FILE_DECL = /(?:href|src)="(.*)[\?]rev=(.*)[\"]/gi;

var revPlugin = function revPlugin() {

  return map(function(file, cb) {

    var contents = file.contents.toString();
    var lines = contents.split('\n');
    var i, length = lines.length;
    var line;
    var groups;
    var dependencyPath;
    var data, hash;

    if(!file) {
      throw new PluginError('gulp-rev', 'Missing fileName option for gulp-rev.');
    }

    for(i = 0; i < length; i++) {
      line = lines[i];
      groups = FILE_DECL.exec(line);
      if(groups && groups.length > 1) {
        dependencyPath = path.resolve(path.dirname(file.path), groups[1]);
        try {
          data = fs.readFileSync(dependencyPath);
          hash = crypto.createHash('md5');
          hash.update(data.toString(), 'utf8');
          line = line.replace(groups[2], hash.digest('hex'));
        }
        catch(e) {
          // fail silently.
        }
      }
      lines[i] = line;
      FILE_DECL.lastIndex = 0;
    }

    file.contents = new Buffer(lines.join('\n'));
    cb(null, file);

  });

};

module.exports = revPlugin;<commit_msg>throw error on file.contents null.<commit_after>var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var Buffer = require('buffer').Buffer;
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var map = require('event-stream').map;

var FILE_DECL = /(?:href|src)="(.*)[\?]rev=(.*)[\"]/gi;

var revPlugin = function revPlugin() {

  return map(function(file, cb) {

    var contents;
    var lines;
    var i, length;
    var line;
    var groups;
    var dependencyPath;
    var data, hash;

    if(!file) {
      throw new PluginError('gulp-rev-append', 'Missing file option for gulp-rev-append.');
    }

    if(!file.contents) {
      throw new PluginError('gulp-rev-append', 'Missing file.contents required for modifying files using gulp-rev-append.');
    }

    contents = file.contents.toString();
    lines = contents.split('\n');
    length = lines.length;

    for(i = 0; i < length; i++) {
      line = lines[i];
      groups = FILE_DECL.exec(line);
      if(groups && groups.length > 1) {
        dependencyPath = path.resolve(path.dirname(file.path), groups[1]);
        try {
          data = fs.readFileSync(dependencyPath);
          hash = crypto.createHash('md5');
          hash.update(data.toString(), 'utf8');
          line = line.replace(groups[2], hash.digest('hex'));
        }
        catch(e) {
          // fail silently.
        }
      }
      lines[i] = line;
      FILE_DECL.lastIndex = 0;
    }

    file.contents = new Buffer(lines.join('\n'));
    cb(null, file);

  });

};

module.exports = revPlugin;<|endoftext|>


<commit_before>var msaDb = module.exports = Msa.module("db")

// params
require('./params.js')

// init sequelize ORM
const Sequelize = require('sequelize')
const dbType = Msa.params.db.type
var sequelize
if(dbType === "sqlite") {
	sequelize = new Sequelize('database', null, null, {
//		host: 'localhost',
		dialect: 'sqlite',
		pool: Msa.params.db.pool,
		storage: Msa.params.db.path
		// http://docs.sequelizejs.com/manual/tutorial/querying.html#operators
//		operatorsAliases: false
	})
} else {
	throw `Unsupported DB type: ${dbType}`
}

// directories
// var sqliteDir = Msa.params.db.sqlite.dir

// API

msaDb.Orm = Sequelize
msaDb.orm = sequelize

// HTTP SERVICES ///////////////////////////////////////////
/*
// external dependencies (at the bottom of script to avoid cyclic dependency issue)
var msaUser = Msa.require("user")
var checkUserMdw = msaUser.checkUserMdw

msaNedb.app.getAsPartial('/', { wel: '/db/msa-db-browser.html' })

msaNedb.app.post('/',
//	checkUserMdw({ group:"admin" }),
	function(req, res, next) {
		var request = req.body.req
		var method = request.match(/\.[a-zA-Z]+/g)
		method = method[method.length-1].substring(1)
		var requestJs = "msaNedb."+request.replace(/\)$/,",dbCallback(req, res, next))").replace("(,","(")
		eval(requestJs)
})

var dbCallback = function(req, res, next) {
	return function(err, docs) {
		if(err) return next(err)
		res.json(docs)
	}
}
*/
// FILES /////////////////////////
//require("./files.js")

<commit_msg>Fix bug on sqlite db path<commit_after>var msaDb = module.exports = Msa.module("db")

const path = require('path')

// params
require('./params.js')

// init sequelize ORM
const Sequelize = require('sequelize')
const dbType = Msa.params.db.type
var sequelize
if(dbType === "sqlite") {
	sequelize = new Sequelize('database', null, null, {
//		host: 'localhost',
		dialect: 'sqlite',
		pool: Msa.params.db.pool,
		storage: path.resolve(Msa.dirname, Msa.params.db.path)
		// http://docs.sequelizejs.com/manual/tutorial/querying.html#operators
//		operatorsAliases: false
	})
} else {
	throw `Unsupported DB type: ${dbType}`
}

// directories
// var sqliteDir = Msa.params.db.sqlite.dir

// API

msaDb.Orm = Sequelize
msaDb.orm = sequelize

// HTTP SERVICES ///////////////////////////////////////////
/*
// external dependencies (at the bottom of script to avoid cyclic dependency issue)
var msaUser = Msa.require("user")
var checkUserMdw = msaUser.checkUserMdw

msaNedb.app.getAsPartial('/', { wel: '/db/msa-db-browser.html' })

msaNedb.app.post('/',
//	checkUserMdw({ group:"admin" }),
	function(req, res, next) {
		var request = req.body.req
		var method = request.match(/\.[a-zA-Z]+/g)
		method = method[method.length-1].substring(1)
		var requestJs = "msaNedb."+request.replace(/\)$/,",dbCallback(req, res, next))").replace("(,","(")
		eval(requestJs)
})

var dbCallback = function(req, res, next) {
	return function(err, docs) {
		if(err) return next(err)
		res.json(docs)
	}
}
*/
// FILES /////////////////////////
//require("./files.js")

<|endoftext|>


<commit_before>var dispatcher = require( 'dispatchy' );
var extend = require( 'extend' );
var os = require( 'os' );
var compileLess = require( './lib/compile-less' );
var write = require( 'write' ).sync;
var Promise = require( 'es6-promise' ).Promise;
var path = require( 'path' );
var url = require( 'url' );
var format = require( 'stringformat' );
var fs = require( 'fs-extra' );
var autoPrefix = require( './lib/autoprefix' );

var isNull = function ( val ) {
  return typeof val === 'undefined' || val === null;
};

var trim = function ( str ) {
  return (str || '').trim();
};

var makeMinName = function ( fileName ) {
  var rgex = /(.+)\.(\w+)$/gi;
  return fileName.replace( rgex, '$1.min.$2' );
};

var addVersion = function ( fileName, version ) {
  if ( !version ) {
    return fileName;
  }
  var rgex = /(.+)\.(\w+)$/gi;
  return fileName.replace( rgex, '$1.' + version + '.$2' );
};

/**
 * check if this is a relative (to the document) url
 *
 * We need to rewrite if the url is relative. This function will return false if:
 * - starts with "/", cause it means it is relative to the main domain
 * - starts with "data:", cause it means is a data uri
 * - starts with a protocol
 *
 * in all other cases it will return true
 *
 * @param urlToCheck the url to test
 * @returns {boolean}
 */
var checkIfRelativePath = function ( urlToCheck ) {
  var DATA_URI_MATCHER = /^data:/gi, //regex to test for an url with a data uri
    PROTOCOL_MATCHER = /^http|^https:\/\//gi, //regex to test for an url with an absolute path
    RELATIVE_TO_HOST_MATCHER = /^\//g; //regex to test for an url relative to the host

  return urlToCheck.match( DATA_URI_MATCHER ) ? false : urlToCheck.match( RELATIVE_TO_HOST_MATCHER ) ? false : !urlToCheck.match( PROTOCOL_MATCHER );
};

var md5 = function ( str, encoding ) {
  var crypto = require( 'crypto' );
  return crypto
    .createHash( 'md5' )
    .update( str + '' )
    .digest( encoding || 'hex' );
};

module.exports = {
  create: function ( descriptor, options ) {
    var fileCache = { };

    var opts = extend( true, {
      banner: '',
      copyAssetsToDestFolder: true,
      revision: '',
      minimize: false,
      assetsPathFormat: 'assets/{REVISION}_{GUID}_{FNAME}',
      autoprefixer: {
        browsers: [
          'last 2 versions'
        ]
      },
      lessOptions: {
        paths: [],
        relativeUrls: true,
        compress: false,
        dumpLineNumbers: 'comments'
      },
      userFns: {},
      cssoOptions: {
        structureModifications: false
      }
    }, options );

    return extend( dispatcher.create(), {
      getId: function ( pathToFile ) {
        var id = fileCache[ pathToFile ] = fileCache[ pathToFile ] || md5( pathToFile );
        return id;
      },
      rewriteURLS: function ( ctn, src, destDir ) {
        var me = this;
        var URL_MATCHER = /url\(\s*[\'"]?\/?(.+?)[\'"]?\s*\)/gi; //regex used to match the urls inside the less or css files

        var version = opts.revision;
        var rewritePathTemplate = opts.assetsPathFormat;
        var referencedFiles = [ ];

        if ( !isNull( ctn ) ) {
          ctn = ctn.replace( URL_MATCHER, function ( match, foundURL ) {
            foundURL = trim( foundURL );
            var needRewrite = checkIfRelativePath( foundURL );

            if ( needRewrite ) {
              var rewriteDescriptor = me.copyFileToNewLocation( src, destDir, foundURL, version, rewritePathTemplate );
              if ( rewriteDescriptor.copied ) {
                var pathToFile = rewriteDescriptor.to;
                referencedFiles.push( rewriteDescriptor.from );

                var outputPath = format( 'url({0})', pathToFile );
                //verbose.writeln( format( '===> This url will be transformed : {0} ==> {1}', url, outputPath ) );
                me.fire( 'url:transformed', {
                  from: foundURL,
                  to: outputPath
                } );

                return outputPath;
              }
            }

            return match;
          } );
        }

        return { ctn: ctn, referencedFiles: referencedFiles };
      },
      copyFileToNewLocation: function ( src, destDir, relativePathToFile, version, rewritePathTemplate ) {
        rewritePathTemplate = rewritePathTemplate || '';

        var me = this;
        var dirOfFile = path.dirname( src );

        var urlObj = url.parse( relativePathToFile );
        var relativePath = trim( urlObj.pathname );
        var lastPart = trim( urlObj.search ) + trim( urlObj.hash );

        if ( relativePath === '' ) {
          throw new Error( 'Not a valid url' );
        }

        var absolutePathToResource = path.normalize( path.resolve( dirOfFile, relativePath ) );

        var fileId = me.getId( absolutePathToResource ); //md5( absolutePathToResource );

        var fName = format( '{0}', path.basename( relativePath ) );

        var relativeOutputFn = rewritePathTemplate.replace( /\{REVISION\}/g, version ) // fileId, fName );
          .replace( /\{GUID\}/g, fileId )
          .replace( /\{FNAME\}/g, fName );

        var newPath = path.normalize( path.join( destDir, relativeOutputFn ) );

        if ( opts.copyAssetsToDestFolder ) {
          fs.copySync( absolutePathToResource, newPath );
        }

        me.fire( 'resource:copied', {
          from: absolutePathToResource,
          to: newPath
        } );

        var outName = relativeOutputFn + lastPart;

        me.fire( 'url:replaced', {
          from: relativePathToFile,
          to: outName
        } );

        return {
          to: outName,
          copied: opts.copyAssetsToDestFolder,
          from: absolutePathToResource
        };
      },
      process: function () {
        var me = this;

        var src = Array.isArray( descriptor.src ) ? descriptor.src : [
          descriptor.src
        ];
        var dest = descriptor.dest;

        dest = addVersion( dest, opts.revision );

        me.fire( 'compile:start', {
          descriptor: descriptor,
          modifiedDest: dest,
          options: opts
        } );

        // we should be able to use Promise.all
        // but for some reason, if the compileLess process
        // is run in parallel will have some troubles and will
        // stop.
        //
        // So in this case we're just making sure that everything
        // is done in sequence and the results of the operations
        // are stored in this promise variable
        var promises = [ ];

        return src.reduce( function ( seq, file ) {
          return seq.then( function () {
            me.fire( 'compile:file', { file: file } );
            return compileLess( file, opts.lessOptions, opts.userFns ).then( function ( params ) {
              var result = params.css;

              var rewriteDescriptor = me.rewriteURLS( result, file, path.dirname( dest ) );

              result = rewriteDescriptor.ctn;

              return autoPrefix( result, {
                file: file,
                dest: dest,
                autoprefixer: opts.autoprefixer
              } ).then( function ( prefixedCSS ) {
                promises.push( {
                  prefixed: prefixedCSS,
                  meta: {
                    dest: dest,
                    referencedFiles: rewriteDescriptor.referencedFiles,
                    imports: params.imports || [ ],
                    src: file
                  }
                } );
              } );
            } );
          } );
        }, Promise.resolve() ).then( function () {
          return Promise.all( promises ).then( function ( params ) {
            var results = [ ];
            //var meta = [ ];
            var files = [ ];

            params.forEach( function ( entry ) {
              results.push( entry.prefixed );
              var meta = entry.meta;
              //console.log( entry.prefixed );

              files = files.concat( meta.src )
                .concat( meta.imports )
                .concat( meta.referencedFiles );
            } );

            //results = results || [];
            var args = { referencedFiles: files };

            me.fire( 'compile:end', args );

            me.fire( 'before:write', extend( args, { dest: dest } ) );

            if ( args.cancel ) {
              return;
            }

            var result = results.join( os.EOL );

            var banner = opts.banner ? opts.banner + os.EOL : '';

            write( dest, (banner + result) );

            me.fire( 'write:file', args );

            if ( opts.minimize ) {
              var csso = require( 'csso' );
              var cssoOptions = opts.cssoOptions || { };
              var minimized = csso.justDoIt( result, !!cssoOptions.structureModifications );
              var minimizedDest = makeMinName( dest );

              write( minimizedDest, (banner + minimized) );

              me.fire( 'write:minimized', extend( { }, args, {
                dest: minimizedDest
              } ) );
            }

          } ).catch( function ( err ) {
            //console.log(err);
            me.fire( 'error', err );
          //throw err;
          } );
        } );
      }
    } );
  }
};
<commit_msg>ENH: Properly handle errors thrown during parsing less file<commit_after>var dispatcher = require( 'dispatchy' );
var extend = require( 'extend' );
var os = require( 'os' );
var compileLess = require( './lib/compile-less' );
var write = require( 'write' ).sync;
var Promise = require( 'es6-promise' ).Promise;
var path = require( 'path' );
var url = require( 'url' );
var format = require( 'stringformat' );
var fs = require( 'fs-extra' );
var autoPrefix = require( './lib/autoprefix' );

var isNull = function ( val ) {
  return typeof val === 'undefined' || val === null;
};

var trim = function ( str ) {
  return (str || '').trim();
};

var makeMinName = function ( fileName ) {
  var rgex = /(.+)\.(\w+)$/gi;
  return fileName.replace( rgex, '$1.min.$2' );
};

var addVersion = function ( fileName, version ) {
  if ( !version ) {
    return fileName;
  }
  var rgex = /(.+)\.(\w+)$/gi;
  return fileName.replace( rgex, '$1.' + version + '.$2' );
};

/**
 * check if this is a relative (to the document) url
 *
 * We need to rewrite if the url is relative. This function will return false if:
 * - starts with "/", cause it means it is relative to the main domain
 * - starts with "data:", cause it means is a data uri
 * - starts with a protocol
 *
 * in all other cases it will return true
 *
 * @param urlToCheck the url to test
 * @returns {boolean}
 */
var checkIfRelativePath = function ( urlToCheck ) {
  var DATA_URI_MATCHER = /^data:/gi, //regex to test for an url with a data uri
    PROTOCOL_MATCHER = /^http|^https:\/\//gi, //regex to test for an url with an absolute path
    RELATIVE_TO_HOST_MATCHER = /^\//g; //regex to test for an url relative to the host

  return urlToCheck.match( DATA_URI_MATCHER ) ? false : urlToCheck.match( RELATIVE_TO_HOST_MATCHER ) ? false : !urlToCheck.match( PROTOCOL_MATCHER );
};

var md5 = function ( str, encoding ) {
  var crypto = require( 'crypto' );
  return crypto
    .createHash( 'md5' )
    .update( str + '' )
    .digest( encoding || 'hex' );
};

module.exports = {
  create: function ( descriptor, options ) {
    var fileCache = { };

    var opts = extend( true, {
      banner: '',
      copyAssetsToDestFolder: true,
      revision: '',
      minimize: false,
      assetsPathFormat: 'assets/{REVISION}_{GUID}_{FNAME}',
      autoprefixer: {
        browsers: [
          'last 2 versions'
        ]
      },
      lessOptions: {
        paths: [],
        relativeUrls: true,
        compress: false,
        dumpLineNumbers: 'comments'
      },
      userFns: {},
      cssoOptions: {
        structureModifications: false
      }
    }, options );

    return extend( dispatcher.create(), {
      getId: function ( pathToFile ) {
        var id = fileCache[ pathToFile ] = fileCache[ pathToFile ] || md5( pathToFile );
        return id;
      },
      rewriteURLS: function ( ctn, src, destDir ) {
        var me = this;
        var URL_MATCHER = /url\(\s*[\'"]?\/?(.+?)[\'"]?\s*\)/gi; //regex used to match the urls inside the less or css files

        var version = opts.revision;
        var rewritePathTemplate = opts.assetsPathFormat;
        var referencedFiles = [ ];

        if ( !isNull( ctn ) ) {
          ctn = ctn.replace( URL_MATCHER, function ( match, foundURL ) {
            foundURL = trim( foundURL );
            var needRewrite = checkIfRelativePath( foundURL );

            if ( needRewrite ) {
              var rewriteDescriptor = me.copyFileToNewLocation( src, destDir, foundURL, version, rewritePathTemplate );
              if ( rewriteDescriptor.copied ) {
                var pathToFile = rewriteDescriptor.to;
                referencedFiles.push( rewriteDescriptor.from );

                var outputPath = format( 'url({0})', pathToFile );
                //verbose.writeln( format( '===> This url will be transformed : {0} ==> {1}', url, outputPath ) );
                me.fire( 'url:transformed', {
                  from: foundURL,
                  to: outputPath
                } );

                return outputPath;
              }
            }

            return match;
          } );
        }

        return { ctn: ctn, referencedFiles: referencedFiles };
      },
      copyFileToNewLocation: function ( src, destDir, relativePathToFile, version, rewritePathTemplate ) {
        rewritePathTemplate = rewritePathTemplate || '';

        var me = this;
        var dirOfFile = path.dirname( src );

        var urlObj = url.parse( relativePathToFile );
        var relativePath = trim( urlObj.pathname );
        var lastPart = trim( urlObj.search ) + trim( urlObj.hash );

        if ( relativePath === '' ) {
          throw new Error( 'Not a valid url' );
        }

        var absolutePathToResource = path.normalize( path.resolve( dirOfFile, relativePath ) );

        var fileId = me.getId( absolutePathToResource ); //md5( absolutePathToResource );

        var fName = format( '{0}', path.basename( relativePath ) );

        var relativeOutputFn = rewritePathTemplate.replace( /\{REVISION\}/g, version ) // fileId, fName );
          .replace( /\{GUID\}/g, fileId )
          .replace( /\{FNAME\}/g, fName );

        var newPath = path.normalize( path.join( destDir, relativeOutputFn ) );

        if ( opts.copyAssetsToDestFolder ) {
          fs.copySync( absolutePathToResource, newPath );
        }

        me.fire( 'resource:copied', {
          from: absolutePathToResource,
          to: newPath
        } );

        var outName = relativeOutputFn + lastPart;

        me.fire( 'url:replaced', {
          from: relativePathToFile,
          to: outName
        } );

        return {
          to: outName,
          copied: opts.copyAssetsToDestFolder,
          from: absolutePathToResource
        };
      },
      process: function () {
        var me = this;

        var src = Array.isArray( descriptor.src ) ? descriptor.src : [
          descriptor.src
        ];
        var dest = descriptor.dest;

        dest = addVersion( dest, opts.revision );

        me.fire( 'compile:start', {
          descriptor: descriptor,
          modifiedDest: dest,
          options: opts
        } );

        // we should be able to use Promise.all
        // but for some reason, if the compileLess process
        // is run in parallel will have some troubles and will
        // stop.
        //
        // So in this case we're just making sure that everything
        // is done in sequence and the results of the operations
        // are stored in this promise variable
        var promises = [ ];

        return src.reduce( function ( seq, file ) {
          return seq.then( function () {
            me.fire( 'compile:file', { file: file } );
            return compileLess( file, opts.lessOptions, opts.userFns ).then( function ( params ) {
              var result = params.css;

              var rewriteDescriptor = me.rewriteURLS( result, file, path.dirname( dest ) );

              result = rewriteDescriptor.ctn;

              return autoPrefix( result, {
                file: file,
                dest: dest,
                autoprefixer: opts.autoprefixer
              } ).then( function ( prefixedCSS ) {
                promises.push( {
                  prefixed: prefixedCSS,
                  meta: {
                    dest: dest,
                    referencedFiles: rewriteDescriptor.referencedFiles,
                    imports: params.imports || [ ],
                    src: file
                  }
                } );
              } );
            }, function ( err ) {
              setTimeout( function () {
                throw err;
              }, 0 );
            } );
          } );
        }, Promise.resolve() ).then( function () {
          return Promise.all( promises ).then( function ( params ) {
            var results = [ ];
            //var meta = [ ];
            var files = [ ];

            params.forEach( function ( entry ) {
              results.push( entry.prefixed );
              var meta = entry.meta;
              //console.log( entry.prefixed );

              files = files.concat( meta.src )
                .concat( meta.imports )
                .concat( meta.referencedFiles );
            } );

            //results = results || [];
            var args = { referencedFiles: files };

            me.fire( 'compile:end', args );

            me.fire( 'before:write', extend( args, { dest: dest } ) );

            if ( args.cancel ) {
              return;
            }

            var result = results.join( os.EOL );

            var banner = opts.banner ? opts.banner + os.EOL : '';

            write( dest, (banner + result) );

            me.fire( 'write:file', args );

            if ( opts.minimize ) {
              var csso = require( 'csso' );
              var cssoOptions = opts.cssoOptions || { };
              var minimized = csso.justDoIt( result, !!cssoOptions.structureModifications );
              var minimizedDest = makeMinName( dest );

              write( minimizedDest, (banner + minimized) );

              me.fire( 'write:minimized', extend( { }, args, {
                dest: minimizedDest
              } ) );
            }

          } ).catch( function ( err ) {
            //console.log(err);
            me.fire( 'error', err );
          //throw err;
          } );
        } );
      }
    } );
  }
};
<|endoftext|>


<commit_before>module.exports = {
    extends: [
        'eslint:recommended',
    ],
    rules: {
        'accessor-pairs': [
            'error',
        ],
        'array-bracket-newline': [
            'error',
            {
                minItems: 2,
                multiline: true,
            },
        ],
        'array-callback-return': [
            'error',
        ],
        'arrow-body-style': [
            'error',
            'always',
        ],
        'arrow-parens': [
            'error',
        ],
        'arrow-spacing': [
            'error',
        ],
        'block-scoped-var': [
            'error',
        ],
        'block-spacing': [
            'error',
        ],
        'brace-style': [
            'error',
        ],
        'callback-return': [
            'error',
        ],
        camelcase: [
            'error',
            {
                ignoreDestructuring: true,
            },
        ],
        'comma-dangle': [
            'error',
            'always-multiline',
        ],
        'comma-spacing': [
            'error',
        ],
        'comma-style': [
            'error',
        ],
        complexity: [
            'error',
        ],
        'computed-property-spacing': [
            'error',
            'always',
        ],
        'consistent-return': [
            'error',
        ],
        'consistent-this': [
            'error',
            '_this',
        ],
        curly: [
            'error',
        ],
        'dot-location': [
            'error',
            'property',
        ],
        'dot-notation': [
            'error',
        ],
        'eol-last': [
            'error',
        ],
        eqeqeq: [
            'error',
        ],
        'for-direction': [
            'error',
        ],
        'func-call-spacing': [
            'error',
        ],
        'func-name-matching': [
            'error',
        ],
        'func-names': [
            'error',
        ],
        'func-style': [
            'error',
        ],
        'function-paren-newline': [
            'error',
            'multiline',
        ],
        'generator-star-spacing': [
            'error',
        ],
        'getter-return': [
            'error',
        ],
        'global-require': [
            'error',
        ],
        'handle-callback-err': [
            'error',
        ],
        'id-blacklist': [
            'error',
            'data',
            'err',
            'e',
            'cb',
            'callback',
        ],
        'implicit-arrow-linebreak': [
            'error',
            'beside',
        ],
        indent: [
            'error',
            4,
            {
                SwitchCase: 1,
            },
        ],
        'jsx-quotes': [
            'error',
            'prefer-single',
        ],
        'key-spacing': [
            'error',
        ],
        'keyword-spacing': [
            'error',
        ],
        'lines-around-comment': [
            'error',
            {
                allowBlockStart: true,
            },
        ],
        'lines-between-class-members': [
            'error',
            'always',
        ],
        'max-classes-per-file': [
            'error',
        ],
        'max-depth': [
            'error',
        ],
        'max-len': [
            'warn',
            120,
        ],
        'max-lines-per-function': [
            'error',
        ],
        'max-nested-callbacks': [
            'error',
        ],
        'max-params': [
            'error',
        ],
        'max-statements-per-line': [
            'error',
        ],
        'multiline-comment-style': [
            'error',
            'separate-lines',
        ],
        'multiline-ternary': [
            'error',
        ],
        'new-cap': [
            'error',
        ],
        'new-parens': [
            'error',
        ],
        'newline-per-chained-call': [
            'error',
        ],
        'no-alert': [
            'error',
        ],
        'no-array-constructor': [
            'error',
        ],
        'no-async-promise-executor': [
            'error',
        ],
        'no-bitwise': [
            'error',
        ],
        'no-buffer-constructor': [
            'error',
        ],
        'no-caller': [
            'error',
        ],
        'no-confusing-arrow': [
            'error',
        ],
        'no-div-regex': [
            'error',
        ],
        'no-duplicate-imports': [
            'error',
        ],
        'no-else-return': [
            'error',
        ],
        'no-empty-function': [
            'error',
        ],
        'no-eq-null': [
            'error',
        ],
        'no-eval': [
            'error',
        ],
        'no-extend-native': [
            'error',
        ],
        'no-extra-bind': [
            'error',
        ],
        'no-extra-label': [
            'error',
        ],
        'no-extra-parens': [
            'error',
            'all',
        ],
        'no-floating-decimal': [
            'error',
        ],
        'no-global-assign': [
            'error',
        ],
        'no-implicit-coercion': [
            'error',
        ],
        'no-implicit-globals': [
            'error',
        ],
        'no-implied-eval': [
            'error',
        ],
        'no-invalid-this': [
            'error',
        ],
        'no-iterator': [
            'error',
        ],
        'no-label-var': [
            'error',
        ],
        'no-labels': [
            'error',
        ],
        'no-lone-blocks': [
            'error',
        ],
        'no-lonely-if': [
            'error',
        ],
        'no-loop-func': [
            'error',
        ],
        'no-magic-numbers': [
            'error',
            {
                ignore: [
                    -1,
                    0,
                    1,
                ],
                ignoreArrayIndexes: true,
            },
        ],
        'no-misleading-character-class': [
            'error',
        ],
        'no-mixed-operators': [
            'error',
        ],
        'no-multi-assign': [
            'error',
        ],
        'no-multi-str': [
            'error',
        ],
        'no-multiple-empty-lines': [
            'error',
        ],
        'no-negated-condition': [
            'error',
        ],
        'no-nested-ternary': [
            'error',
        ],
        'no-new': [
            'error',
        ],
        'no-new-func': [
            'error',
        ],
        'no-new-object': [
            'error',
        ],
        'no-new-require': [
            'error',
        ],
        'no-new-wrappers': [
            'error',
        ],
        'no-octal-escape': [
            'error',
        ],
        'no-param-reassign': [
            'error',
        ],
        'no-path-concat': [
            'error',
        ],
        'no-plusplus': [
            'error',
        ],
        'no-process-env': [
            'error',
        ],
        'no-process-exit': [
            'error',
        ],
        'no-proto': [
            'error',
        ],
        'no-prototype-builtins': [
            'error',
        ],
        'no-return-assign': [
            'error',
        ],
        'no-script-url': [
            'error',
        ],
        'no-self-compare': [
            'error',
        ],
        'no-sequences': [
            'error',
        ],
        'no-shadow': [
            'error',
        ],
        'no-shadow-restricted-names': [
            'error',
        ],
        'no-sync': [
            'error',
        ],
        'no-tabs': [
            'error',
        ],
        'no-template-curly-in-string': [
            'error',
        ],
        'no-throw-literal': [
            'error',
        ],
        'no-trailing-spaces': [
            'warn',
        ],
        'no-undef-init': [
            'error',
        ],
        'no-undefined': [
            'error',
        ],
        'no-unmodified-loop-condition': [
            'error',
        ],
        'no-unneeded-ternary': [
            'error',
        ],
        'no-unsafe-negation': [
            'error',
        ],
        'no-unused-expressions': [
            'error',
        ],
        'no-use-before-define': [
            'error',
            {
                variables: false,
            },
        ],
        'no-useless-call': [
            'error',
        ],
        'no-useless-catch': [
            'error',
        ],
        'no-useless-computed-key': [
            'error',
        ],
        'no-useless-concat': [
            'error',
        ],
        'no-useless-constructor': [
            'error',
        ],
        'no-useless-escape': [
            'error',
        ],
        'no-useless-rename': [
            'error',
        ],
        'no-useless-return': [
            'error',
        ],
        'no-var': [
            'error',
        ],
        'no-void': [
            'error',
        ],
        'no-warning-comments': [
            'warn',
        ],
        'no-whitespace-before-property': [
            'error',
        ],
        'no-with': [
            'error',
        ],
        'object-curly-newline': [
            'error',
            {
                minProperties: 1,
            },
        ],
        'object-curly-spacing': [
            'error',
            'always',
        ],
        'object-property-newline': [
            'error',
        ],
        'one-var': [
            'error',
            'never',
        ],
        'operator-assignment': [
            'error',
            'never',
        ],
        'padded-blocks': [
            'error',
            'never',
        ],
        'padding-line-between-statements': [
            'error',
            {
                blankLine: 'always',
                next: 'return',
                prev: '*',
            },
            {
                blankLine: 'always',
                next: '*',
                prev: [
                    'const',
                    'let',
                    'var',
                ],
            },
            {
                blankLine: 'any',
                next: [
                    'const',
                    'let',
                    'var',
                ],
                prev: [
                    'const',
                    'let',
                    'var',
                ],
            },
        ],
        'prefer-arrow-callback': [
            'error',
        ],
        'prefer-const': [
            'warn',
        ],
        'prefer-named-capture-group': [
            'error',
        ],
        'prefer-object-spread': [
            'error',
        ],
        'prefer-promise-reject-errors': [
            'error',
        ],
        'prefer-rest-params': [
            'error',
        ],
        'prefer-spread': [
            'error',
        ],
        'prefer-template': [
            'error',
        ],
        'quote-props': [
            'error',
            'as-needed',
        ],
        quotes: [
            'error',
            'single',
            {
                avoidEscape: true,
            },
        ],
        radix: [
            'error',
        ],
        'require-atomic-updates': [
            'error',
        ],
        'require-unicode-regexp': [
            'error',
        ],
        'rest-spread-spacing': [
            'error',
        ],
        semi: [
            'error',
            'always',
        ],
        'semi-spacing': [
            'error',
        ],
        'semi-style': [
            'error',
        ],
        'sort-keys': [
            'error',
            'asc',
            {
                caseSensitive: false,
                natural: true,
            },
        ],
        'space-before-blocks': [
            'error',
        ],
        'space-before-function-paren': [
            'error',
        ],
        'space-in-parens': [
            'error',
            'never',
        ],
        'space-infix-ops': [
            'error',
        ],
        'space-unary-ops': [
            'error',
        ],
        'spaced-comment': [
            'error',
        ],
        'switch-colon-spacing': [
            'error',
        ],
        'symbol-description': [
            'error',
        ],
        'template-tag-spacing': [
            'error',
            'always',
        ],
        'unicode-bom': [
            'error',
        ],
        'vars-on-top': [
            'error',
        ],
        'wrap-iife': [
            'error',
        ],
        'yield-star-spacing': [
            'error',
        ],
        yoda: [
            'error',
        ],
    },
};
<commit_msg>allow magic 2<commit_after>module.exports = {
    extends: [
        'eslint:recommended',
    ],
    rules: {
        'accessor-pairs': [
            'error',
        ],
        'array-bracket-newline': [
            'error',
            {
                minItems: 2,
                multiline: true,
            },
        ],
        'array-callback-return': [
            'error',
        ],
        'arrow-body-style': [
            'error',
            'always',
        ],
        'arrow-parens': [
            'error',
        ],
        'arrow-spacing': [
            'error',
        ],
        'block-scoped-var': [
            'error',
        ],
        'block-spacing': [
            'error',
        ],
        'brace-style': [
            'error',
        ],
        'callback-return': [
            'error',
        ],
        camelcase: [
            'error',
            {
                ignoreDestructuring: true,
            },
        ],
        'comma-dangle': [
            'error',
            'always-multiline',
        ],
        'comma-spacing': [
            'error',
        ],
        'comma-style': [
            'error',
        ],
        complexity: [
            'error',
        ],
        'computed-property-spacing': [
            'error',
            'always',
        ],
        'consistent-return': [
            'error',
        ],
        'consistent-this': [
            'error',
            '_this',
        ],
        curly: [
            'error',
        ],
        'dot-location': [
            'error',
            'property',
        ],
        'dot-notation': [
            'error',
        ],
        'eol-last': [
            'error',
        ],
        eqeqeq: [
            'error',
        ],
        'for-direction': [
            'error',
        ],
        'func-call-spacing': [
            'error',
        ],
        'func-name-matching': [
            'error',
        ],
        'func-names': [
            'error',
        ],
        'func-style': [
            'error',
        ],
        'function-paren-newline': [
            'error',
            'multiline',
        ],
        'generator-star-spacing': [
            'error',
        ],
        'getter-return': [
            'error',
        ],
        'global-require': [
            'error',
        ],
        'handle-callback-err': [
            'error',
        ],
        'id-blacklist': [
            'error',
            'data',
            'err',
            'e',
            'cb',
            'callback',
        ],
        'implicit-arrow-linebreak': [
            'error',
            'beside',
        ],
        indent: [
            'error',
            4,
            {
                SwitchCase: 1,
            },
        ],
        'jsx-quotes': [
            'error',
            'prefer-single',
        ],
        'key-spacing': [
            'error',
        ],
        'keyword-spacing': [
            'error',
        ],
        'lines-around-comment': [
            'error',
            {
                allowBlockStart: true,
            },
        ],
        'lines-between-class-members': [
            'error',
            'always',
        ],
        'max-classes-per-file': [
            'error',
        ],
        'max-depth': [
            'error',
        ],
        'max-len': [
            'warn',
            120,
        ],
        'max-lines-per-function': [
            'error',
        ],
        'max-nested-callbacks': [
            'error',
        ],
        'max-params': [
            'error',
        ],
        'max-statements-per-line': [
            'error',
        ],
        'multiline-comment-style': [
            'error',
            'separate-lines',
        ],
        'multiline-ternary': [
            'error',
        ],
        'new-cap': [
            'error',
        ],
        'new-parens': [
            'error',
        ],
        'newline-per-chained-call': [
            'error',
        ],
        'no-alert': [
            'error',
        ],
        'no-array-constructor': [
            'error',
        ],
        'no-async-promise-executor': [
            'error',
        ],
        'no-bitwise': [
            'error',
        ],
        'no-buffer-constructor': [
            'error',
        ],
        'no-caller': [
            'error',
        ],
        'no-confusing-arrow': [
            'error',
        ],
        'no-div-regex': [
            'error',
        ],
        'no-duplicate-imports': [
            'error',
        ],
        'no-else-return': [
            'error',
        ],
        'no-empty-function': [
            'error',
        ],
        'no-eq-null': [
            'error',
        ],
        'no-eval': [
            'error',
        ],
        'no-extend-native': [
            'error',
        ],
        'no-extra-bind': [
            'error',
        ],
        'no-extra-label': [
            'error',
        ],
        'no-extra-parens': [
            'error',
            'all',
        ],
        'no-floating-decimal': [
            'error',
        ],
        'no-global-assign': [
            'error',
        ],
        'no-implicit-coercion': [
            'error',
        ],
        'no-implicit-globals': [
            'error',
        ],
        'no-implied-eval': [
            'error',
        ],
        'no-invalid-this': [
            'error',
        ],
        'no-iterator': [
            'error',
        ],
        'no-label-var': [
            'error',
        ],
        'no-labels': [
            'error',
        ],
        'no-lone-blocks': [
            'error',
        ],
        'no-lonely-if': [
            'error',
        ],
        'no-loop-func': [
            'error',
        ],
        'no-magic-numbers': [
            'error',
            {
                ignore: [
                    -1,
                    0,
                    1,
                    2,
                ],
                ignoreArrayIndexes: true,
            },
        ],
        'no-misleading-character-class': [
            'error',
        ],
        'no-mixed-operators': [
            'error',
        ],
        'no-multi-assign': [
            'error',
        ],
        'no-multi-str': [
            'error',
        ],
        'no-multiple-empty-lines': [
            'error',
        ],
        'no-negated-condition': [
            'error',
        ],
        'no-nested-ternary': [
            'error',
        ],
        'no-new': [
            'error',
        ],
        'no-new-func': [
            'error',
        ],
        'no-new-object': [
            'error',
        ],
        'no-new-require': [
            'error',
        ],
        'no-new-wrappers': [
            'error',
        ],
        'no-octal-escape': [
            'error',
        ],
        'no-param-reassign': [
            'error',
        ],
        'no-path-concat': [
            'error',
        ],
        'no-plusplus': [
            'error',
        ],
        'no-process-env': [
            'error',
        ],
        'no-process-exit': [
            'error',
        ],
        'no-proto': [
            'error',
        ],
        'no-prototype-builtins': [
            'error',
        ],
        'no-return-assign': [
            'error',
        ],
        'no-script-url': [
            'error',
        ],
        'no-self-compare': [
            'error',
        ],
        'no-sequences': [
            'error',
        ],
        'no-shadow': [
            'error',
        ],
        'no-shadow-restricted-names': [
            'error',
        ],
        'no-sync': [
            'error',
        ],
        'no-tabs': [
            'error',
        ],
        'no-template-curly-in-string': [
            'error',
        ],
        'no-throw-literal': [
            'error',
        ],
        'no-trailing-spaces': [
            'warn',
        ],
        'no-undef-init': [
            'error',
        ],
        'no-undefined': [
            'error',
        ],
        'no-unmodified-loop-condition': [
            'error',
        ],
        'no-unneeded-ternary': [
            'error',
        ],
        'no-unsafe-negation': [
            'error',
        ],
        'no-unused-expressions': [
            'error',
        ],
        'no-use-before-define': [
            'error',
            {
                variables: false,
            },
        ],
        'no-useless-call': [
            'error',
        ],
        'no-useless-catch': [
            'error',
        ],
        'no-useless-computed-key': [
            'error',
        ],
        'no-useless-concat': [
            'error',
        ],
        'no-useless-constructor': [
            'error',
        ],
        'no-useless-escape': [
            'error',
        ],
        'no-useless-rename': [
            'error',
        ],
        'no-useless-return': [
            'error',
        ],
        'no-var': [
            'error',
        ],
        'no-void': [
            'error',
        ],
        'no-warning-comments': [
            'warn',
        ],
        'no-whitespace-before-property': [
            'error',
        ],
        'no-with': [
            'error',
        ],
        'object-curly-newline': [
            'error',
            {
                minProperties: 1,
            },
        ],
        'object-curly-spacing': [
            'error',
            'always',
        ],
        'object-property-newline': [
            'error',
        ],
        'one-var': [
            'error',
            'never',
        ],
        'operator-assignment': [
            'error',
            'never',
        ],
        'padded-blocks': [
            'error',
            'never',
        ],
        'padding-line-between-statements': [
            'error',
            {
                blankLine: 'always',
                next: 'return',
                prev: '*',
            },
            {
                blankLine: 'always',
                next: '*',
                prev: [
                    'const',
                    'let',
                    'var',
                ],
            },
            {
                blankLine: 'any',
                next: [
                    'const',
                    'let',
                    'var',
                ],
                prev: [
                    'const',
                    'let',
                    'var',
                ],
            },
        ],
        'prefer-arrow-callback': [
            'error',
        ],
        'prefer-const': [
            'warn',
        ],
        'prefer-named-capture-group': [
            'error',
        ],
        'prefer-object-spread': [
            'error',
        ],
        'prefer-promise-reject-errors': [
            'error',
        ],
        'prefer-rest-params': [
            'error',
        ],
        'prefer-spread': [
            'error',
        ],
        'prefer-template': [
            'error',
        ],
        'quote-props': [
            'error',
            'as-needed',
        ],
        quotes: [
            'error',
            'single',
            {
                avoidEscape: true,
            },
        ],
        radix: [
            'error',
        ],
        'require-atomic-updates': [
            'error',
        ],
        'require-unicode-regexp': [
            'error',
        ],
        'rest-spread-spacing': [
            'error',
        ],
        semi: [
            'error',
            'always',
        ],
        'semi-spacing': [
            'error',
        ],
        'semi-style': [
            'error',
        ],
        'sort-keys': [
            'error',
            'asc',
            {
                caseSensitive: false,
                natural: true,
            },
        ],
        'space-before-blocks': [
            'error',
        ],
        'space-before-function-paren': [
            'error',
        ],
        'space-in-parens': [
            'error',
            'never',
        ],
        'space-infix-ops': [
            'error',
        ],
        'space-unary-ops': [
            'error',
        ],
        'spaced-comment': [
            'error',
        ],
        'switch-colon-spacing': [
            'error',
        ],
        'symbol-description': [
            'error',
        ],
        'template-tag-spacing': [
            'error',
            'always',
        ],
        'unicode-bom': [
            'error',
        ],
        'vars-on-top': [
            'error',
        ],
        'wrap-iife': [
            'error',
        ],
        'yield-star-spacing': [
            'error',
        ],
        yoda: [
            'error',
        ],
    },
};
<|endoftext|>


<commit_before>var ansi      = require('ansi.js');
var cursorPos = require('get-cursor-position');

var placeholder = '\uFFFC';
var instances   = [];

function ProgressBar(options) {

  options = options || {};

  this.cursor  = ansi(process.stdout);
  this.total   = options.total || 100;
  this.current = options.current || 0;
  this.width   = options.width || this.total;

  if (typeof this.width === 'string') {
    if (endWith(this.width, '%')) {
      this.width = parseFloat(this.width) / 100 % 1;
    } else {
      this.width = parseFloat(this.width);
    }
  }

  this.clean = !!options.clean;
  this.chars = {
    completed: options.completed || '▇',
    blank    : options.blank || '—'
  };

  this.completed = false;

  // callback on completed
  this.callback = options.callback;
  this.setSchema(options.schema);

  instances.push(this);
}

// exports
// -------

module.exports = ProgressBar;

// proto
// -----

ProgressBar.prototype.setSchema = function (schema) {
  this.schema = schema || ' [:bar] :current/:total :percent :elapseds :etas';
};

ProgressBar.prototype.tick = function (delta, tokens) {

  if (this.completed) {
    return;
  }

  if (delta !== 0) {
    delta = delta || 1;
  }

  // swap tokens
  if (typeof delta === 'object') {
    tokens = delta;
    delta  = 1;
  }

  if (!this.start) {
    this.start = new Date;
  }

  this.current += delta;
  this.tokenize(tokens);

  if (this.current >= this.total) {
    this.completed = true;
    this.terminate();
    this.callback && this.callback(this);
  }
};

ProgressBar.prototype.update = function (ratio, tokens) {

  var completed = Math.floor(ratio * this.total);
  var delta     = completed - this.current;

  this.tick(delta, tokens);
};

ProgressBar.prototype.tokenize = function (tokens) {

  var ratio = this.current / this.total;

  ratio = Math.min(Math.max(ratio, 0), 1);

  var schema  = this.schema;
  var chars   = this.chars;
  var percent = ratio * 100;
  var elapsed = new Date - this.start;
  var eta     = percent === 100 ? 0 : elapsed * (this.total / this.current - 1);
  var output  = schema
    .replace(/:current/g, this.current)
    .replace(/:total/g, this.total)
    .replace(/:elapsed/g, formatTime(elapsed))
    .replace(/:eta/g, formatTime(eta))
    .replace(/:percent/g, toFixed(percent, 0) + '%');

  if (tokens) {
    for (var key in tokens) {
      if (tokens.hasOwnProperty(key)) {
        output = output.replace(new RegExp(':' + key, 'g'), ('' + tokens[key]) || placeholder);
      }
    }
  }

  var raw = output
    .replace(/\.(bgR|r)ed/g, '')
    .replace(/\.(bgB|b)lue/g, '')
    .replace(/\.(bgC|c)yan/g, '')
    .replace(/\.(bgG|g)rey/g, '')
    .replace(/\.(bgW|w)hite/g, '')
    .replace(/\.(bgB|b)lack/g, '')
    .replace(/\.(bgG|g)reen/g, '')
    .replace(/\.(bgY|y)ellow/g, '')
    .replace(/\.(bgM|m)agenta/g, '')
    // bright
    .replace(/\.(bgB|b)right(Black|Red|Green|Yellow|Blue|Magenta|Cyan|White)/g, '')
    // font style
    .replace(/\.bold|italic|underline|inverse/g, '')
    // gradient
    .replace(/\.gradient\((.+),(.+)\)/g, '');

  var width   = this.width;
  var columns = process.stdout.columns;

  width = width < 1 ? columns * width : width;
  width = Math.min(width, Math.max(0, columns - raw.length));

  var length    = Math.round(width * ratio);
  var blank     = repeatChar(width - length + 1, chars.blank);
  var completed = repeatChar(length + 1, chars.completed);

  output = output
    .replace(/:completed/g, completed || placeholder)
    .replace(/:blank/g, blank || placeholder)
    .replace(/:bar/g, (completed + blank) || placeholder);

  this.raw = raw
    .replace(/:completed/g, completed)
    .replace(/:blank/g, blank)
    .replace(/:bar/g, completed + blank);

  this.render(output);
};

ProgressBar.prototype.render = function (output) {

  if (this.output !== output) {

    var repaint = !!this.origin;
    var current = cursorPos.sync();

    if (!repaint) {
      this.origin = current;
    }

    this.clear();

    var originRow = this.origin.row;
    var originCol = this.origin.col;
    var totalRows = process.stdout.rows;
    var rowCount  = this.raw.split('\n').length;

    if (originRow === totalRows) {
      this.cursor.write(repeatChar(rowCount, '\n'));
      instances.forEach(function (instance) {
        if (instance.origin) {
          instance.origin.row -= rowCount;
        }
      });
      originRow -= rowCount - 1;
    }

    this.cursor.moveTo(originRow, originCol);
    //this.cursor.write(output);
    this.colorize(output);

    // move the cursor to the current position.
    if (repaint) {
      this.cursor.moveTo(current.row, current.col);
    }

    this.output = output;
  }
};

ProgressBar.prototype.colorize = function (output) {

  var cursor  = this.cursor;
  var parts   = output.split(/(\.[A-Za-z]+)/g);
  var content = '';
  var matches = [];

  function write() {

    //console.log(content)
    //console.log(matches)

    var hasFg    = false;
    var hasBg    = false;
    var gradient = null;

    matches.forEach(function (match) {

      if (match.method === 'gradient') {
        gradient = match;
        return;
      }

      var host = match.isBg
        ? cursor.bg : match.isFont
        ? cursor.font
        : cursor.fg;

      if (match.isBg) {
        hasBg = true;
      } else {
        hasFg = true;
      }

      host[match.method]();
    });

    content = content.replace(new RegExp(placeholder, 'g'), '');

    if (content) {

      if (gradient) {

        var color1 = gradient.color1;
        var color2 = gradient.color2;

        for (var i = 0, l = content.length; i < l; i++) {

          var color = i === 0
            ? color1 : i === l - 1
            ? color2
            : interpolate(color1, color2, (i + 1) / l);

          cursor.fg.rgb(color.r, color.g, color.b);
          cursor.write(content[i]);
          cursor.fg.reset();
        }
      } else {
        cursor.write(content);
      }
    }

    // reset font style
    matches.forEach(function (match) {
      if (match.isFont) {
        cursor.font['reset' + ucFirst(match.method)]();
      }
    });

    // reset foreground
    if (hasFg) {
      cursor.fg.reset();
    }

    // reset background
    if (hasBg) {
      cursor.bg.reset();
    }

    matches = [];
    content = '';
  }

  for (var i = 0, l = parts.length; i < l; i++) {

    var part  = parts[i];
    var match = null;

    if (!part) {
      continue;
    }

    if (startWith(part, '.')) {

      if (part === '.gradient') {
        if (parts[i + 1]) {
          match = parseGradient(parts[i + 1]);

          parts[i + 1] = parts[i + 1].replace(/^\((.+),(.+)\)/, '');
        }
      } else {
        match = parseMethod(cursor, part);
      }
    }

    if (match) {
      if (match.suffix) {
        if (i < l - 1) {
          parts[i + 1] += match.suffix;
        } else {
          // the last one
          cursor.write(match.suffix);
        }
      }

      matches.push(match);
    } else {

      if (matches.length) {
        write();
      }

      content += part;
    }
  }

  write();

  cursor.write('\n');
};

ProgressBar.prototype.clear = function () {

  if (this.output) {

    var lines = this.raw.split('\n');

    this.cursor.moveTo(this.origin.row, this.origin.col);

    for (var i = 0, l = lines.length; i < l; i++) {
      this.cursor.write(repeatChar(lines[i].length, ' ') + ' \n');
    }
  }
};

ProgressBar.prototype.terminate = function () {

  if (this.clean) {
    var pos = cursorPos.sync();
    this.clear();
    this.cursor.moveTo(pos.row, pos.col);
  }
};

// helpers
// -------

function toFixed(value, precision) {

  var power = Math.pow(10, precision);

  return (Math.round(value * power) / power).toFixed(precision);
}

function formatTime(ms) {
  return isNaN(ms) || !isFinite(ms)
    ? '0.0'
    : toFixed(ms / 1000, 1);
}

function startWith(str, prefix) {
  return ('' + str).indexOf(prefix) === 0;
}

function endWith(str, suffix) {

  str = '' + str;

  return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

function lcFirst(str) {
  return str.charAt(0).toLowerCase() + str.substring(1);
}

function ucFirst(str) {
  return str.charAt(0).toUpperCase() + str.substring(1);
}

function repeatChar(len, char) {
  return new Array(len).join(char);
}

function parseMethod(cursor, str) {

  str = str.substr(1);

  return parseColor(cursor, str)
    || parseFont(cursor, str)
    || parseGradient(str);
}

function parseColor(cursor, str) {

  var match = str.match(/^(bgR|r)ed/)
    || str.match(/^(bgB|b)lue/)
    || str.match(/^(bgC|c)yan/)
    || str.match(/^(bgG|g)rey/)
    || str.match(/^(bgW|w)hite/)
    || str.match(/^(bgB|b)lack/)
    || str.match(/^(bgG|g)reen/)
    || str.match(/^(bgY|y)ellow/)
    || str.match(/^(bgM|m)agenta/)
    || str.match(/^(bgB|b)right(Black|Red|Green|Yellow|Blue|Magenta|Cyan|White)/);

  if (match) {

    var method = match[0];
    var suffix = str.substr(method.length);
    var isBg   = startWith(method, 'bg');

    if (isBg) {
      method = lcFirst(method.substr(2));
    }

    if (typeof cursor[method] === 'function') {
      return {
        isBg  : isBg,
        method: method,
        suffix: suffix
      };
    }
  }
}

function parseFont(cursor, str) {

  var match = str.match(/^bold|italic|underline|inverse/);
  if (match) {

    var method = match[0];
    var suffix = str.substr(method.length);

    if (typeof cursor[method] === 'function') {
      return {
        isFont: true,
        method: method,
        suffix: suffix
      };
    }
  }
}

function parseGradient(str) {

  var match = str.match(/^\((.+),(.+)\)/);
  if (match) {

    var color1 = match[1];
    var color2 = match[2];

    color1 = startWith(color1, '#') ? hex2rgb(color1) : name2rgb(color1);
    color2 = startWith(color2, '#') ? hex2rgb(color2) : name2rgb(color2);

    if (color1 && color2) {
      return {
        method: 'gradient',
        color1: color1,
        color2: color2
      };
    }
  }
}

function interpolate(color1, color2, percent) {

  function makeChannel(a, b) {
    return a + Math.round((b - a) * percent);
  }

  return {
    r: makeChannel(color1.r, color2.r),
    g: makeChannel(color1.g, color2.g),
    b: makeChannel(color1.b, color2.b)
  };
}

function hex2rgb(color) {

  var c = color.substring(1);
  var r = c.substring(0, 2);
  var g = c.substring(2, 4);
  var b = c.substring(4, 6);

  return {
    r: parseInt(r, 16),
    g: parseInt(g, 16),
    b: parseInt(b, 16)
  };
}

function name2rgb(name) {
  var hex = {
    red    : '#ff0000',
    blue   : '#0000ff',
    cyan   : '#00ffff',
    grey   : '#808080',
    white  : '#ffffff',
    black  : '#000000',
    green  : '#008000',
    yellow : '#ffff00',
    magenta: '#ff00ff'
  }[name];

  return hex ? hex2rgb(hex) : null;
}
<commit_msg>eraseLine<commit_after>var ansi      = require('ansi.js');
var cursorPos = require('get-cursor-position');

var placeholder = '\uFFFC';
var instances   = [];

function ProgressBar(options) {

  options = options || {};

  this.cursor  = ansi(process.stdout);
  this.total   = options.total || 100;
  this.current = options.current || 0;
  this.width   = options.width || this.total;

  if (typeof this.width === 'string') {
    if (endWith(this.width, '%')) {
      this.width = parseFloat(this.width) / 100 % 1;
    } else {
      this.width = parseFloat(this.width);
    }
  }

  this.clean = !!options.clean;
  this.chars = {
    completed: options.completed || '▇',
    blank    : options.blank || '—'
  };

  this.completed = false;

  // callback on completed
  this.callback = options.callback;
  this.setSchema(options.schema);

  instances.push(this);
}

// exports
// -------

module.exports = ProgressBar;

// proto
// -----

ProgressBar.prototype.setSchema = function (schema) {
  this.schema = schema || ' [:bar] :current/:total :percent :elapseds :etas';
};

ProgressBar.prototype.tick = function (delta, tokens) {

  if (this.completed) {
    return;
  }

  if (delta !== 0) {
    delta = delta || 1;
  }

  // swap tokens
  if (typeof delta === 'object') {
    tokens = delta;
    delta  = 1;
  }

  if (!this.start) {
    this.start = new Date;
  }

  this.current += delta;
  this.tokenize(tokens);

  if (this.current >= this.total) {
    this.completed = true;
    this.terminate();
    this.callback && this.callback(this);
  }
};

ProgressBar.prototype.update = function (ratio, tokens) {

  var completed = Math.floor(ratio * this.total);
  var delta     = completed - this.current;

  this.tick(delta, tokens);
};

ProgressBar.prototype.tokenize = function (tokens) {

  var ratio = this.current / this.total;

  ratio = Math.min(Math.max(ratio, 0), 1);

  var schema  = this.schema;
  var chars   = this.chars;
  var percent = ratio * 100;
  var elapsed = new Date - this.start;
  var eta     = percent === 100 ? 0 : elapsed * (this.total / this.current - 1);
  var output  = schema
    .replace(/:current/g, this.current)
    .replace(/:total/g, this.total)
    .replace(/:elapsed/g, formatTime(elapsed))
    .replace(/:eta/g, formatTime(eta))
    .replace(/:percent/g, toFixed(percent, 0) + '%');

  if (tokens) {
    for (var key in tokens) {
      if (tokens.hasOwnProperty(key)) {
        output = output.replace(new RegExp(':' + key, 'g'), ('' + tokens[key]) || placeholder);
      }
    }
  }

  var raw = output
    .replace(/\.(bgR|r)ed/g, '')
    .replace(/\.(bgB|b)lue/g, '')
    .replace(/\.(bgC|c)yan/g, '')
    .replace(/\.(bgG|g)rey/g, '')
    .replace(/\.(bgW|w)hite/g, '')
    .replace(/\.(bgB|b)lack/g, '')
    .replace(/\.(bgG|g)reen/g, '')
    .replace(/\.(bgY|y)ellow/g, '')
    .replace(/\.(bgM|m)agenta/g, '')
    // bright
    .replace(/\.(bgB|b)right(Black|Red|Green|Yellow|Blue|Magenta|Cyan|White)/g, '')
    // font style
    .replace(/\.bold|italic|underline|inverse/g, '')
    // gradient
    .replace(/\.gradient\((.+),(.+)\)/g, '');

  var width   = this.width;
  var columns = process.stdout.columns;

  width = width < 1 ? columns * width : width;
  width = Math.min(width, Math.max(0, columns - raw.length));

  var length    = Math.round(width * ratio);
  var blank     = repeatChar(width - length + 1, chars.blank);
  var completed = repeatChar(length + 1, chars.completed);

  output = output
    .replace(/:completed/g, completed || placeholder)
    .replace(/:blank/g, blank || placeholder)
    .replace(/:bar/g, (completed + blank) || placeholder);

  this.raw = raw
    .replace(/:completed/g, completed)
    .replace(/:blank/g, blank)
    .replace(/:bar/g, completed + blank);

  this.render(output);
};

ProgressBar.prototype.render = function (output) {

  if (this.output !== output) {

    var repaint = !!this.origin;
    var current = cursorPos.sync();

    if (!repaint) {
      this.origin = current;
    }

    this.clear();

    var originRow = this.origin.row;
    var originCol = this.origin.col;
    var totalRows = process.stdout.rows;
    var rowCount  = this.raw.split('\n').length;

    if (originRow === totalRows) {
      this.cursor.write(repeatChar(rowCount, '\n'));
      instances.forEach(function (instance) {
        if (instance.origin) {
          instance.origin.row -= rowCount;
        }
      });
      originRow -= rowCount - 1;
    }

    this.cursor.moveTo(originRow, originCol);
    //this.cursor.write(output);
    this.colorize(output);

    // move the cursor to the current position.
    if (repaint) {
      this.cursor.moveTo(current.row, current.col);
    }

    this.output = output;
  }
};

ProgressBar.prototype.colorize = function (output) {

  var cursor  = this.cursor;
  var parts   = output.split(/(\.[A-Za-z]+)/g);
  var content = '';
  var matches = [];

  function write() {

    //console.log(content)
    //console.log(matches)

    var hasFg    = false;
    var hasBg    = false;
    var gradient = null;

    matches.forEach(function (match) {

      if (match.method === 'gradient') {
        gradient = match;
        return;
      }

      var host = match.isBg
        ? cursor.bg : match.isFont
        ? cursor.font
        : cursor.fg;

      if (match.isBg) {
        hasBg = true;
      } else {
        hasFg = true;
      }

      host[match.method]();
    });

    content = content.replace(new RegExp(placeholder, 'g'), '');

    if (content) {

      if (gradient) {

        var color1 = gradient.color1;
        var color2 = gradient.color2;

        for (var i = 0, l = content.length; i < l; i++) {

          var color = i === 0
            ? color1 : i === l - 1
            ? color2
            : interpolate(color1, color2, (i + 1) / l);

          cursor.fg.rgb(color.r, color.g, color.b);
          cursor.write(content[i]);
          cursor.fg.reset();
        }
      } else {
        cursor.write(content);
      }
    }

    // reset font style
    matches.forEach(function (match) {
      if (match.isFont) {
        cursor.font['reset' + ucFirst(match.method)]();
      }
    });

    // reset foreground
    if (hasFg) {
      cursor.fg.reset();
    }

    // reset background
    if (hasBg) {
      cursor.bg.reset();
    }

    matches = [];
    content = '';
  }

  for (var i = 0, l = parts.length; i < l; i++) {

    var part  = parts[i];
    var match = null;

    if (!part) {
      continue;
    }

    if (startWith(part, '.')) {

      if (part === '.gradient') {
        if (parts[i + 1]) {
          match = parseGradient(parts[i + 1]);

          parts[i + 1] = parts[i + 1].replace(/^\((.+),(.+)\)/, '');
        }
      } else {
        match = parseMethod(cursor, part);
      }
    }

    if (match) {
      if (match.suffix) {
        if (i < l - 1) {
          parts[i + 1] += match.suffix;
        } else {
          // the last one
          cursor.write(match.suffix);
        }
      }

      matches.push(match);
    } else {

      if (matches.length) {
        write();
      }

      content += part;
    }
  }

  write();

  cursor.write('\n');
};

ProgressBar.prototype.clear = function () {

  if (this.output) {

    var lines = this.raw.split('\n');

    this.cursor.moveTo(this.origin.row, this.origin.col);

    for (var i = 0, l = lines.length; i < l; i++) {
      this.cursor.eraseLine();
      this.cursor.write(repeatChar(lines[i].length, ' ') + ' \n');
    }
  }
};

ProgressBar.prototype.terminate = function () {

  if (this.clean) {
    var pos = cursorPos.sync();
    this.clear();
    this.cursor.moveTo(pos.row, pos.col);
  }
};

// helpers
// -------

function toFixed(value, precision) {

  var power = Math.pow(10, precision);

  return (Math.round(value * power) / power).toFixed(precision);
}

function formatTime(ms) {
  return isNaN(ms) || !isFinite(ms)
    ? '0.0'
    : toFixed(ms / 1000, 1);
}

function startWith(str, prefix) {
  return ('' + str).indexOf(prefix) === 0;
}

function endWith(str, suffix) {

  str = '' + str;

  return str.indexOf(suffix, str.length - suffix.length) !== -1;
}

function lcFirst(str) {
  return str.charAt(0).toLowerCase() + str.substring(1);
}

function ucFirst(str) {
  return str.charAt(0).toUpperCase() + str.substring(1);
}

function repeatChar(len, char) {
  return new Array(len).join(char);
}

function parseMethod(cursor, str) {

  str = str.substr(1);

  return parseColor(cursor, str)
    || parseFont(cursor, str)
    || parseGradient(str);
}

function parseColor(cursor, str) {

  var match = str.match(/^(bgR|r)ed/)
    || str.match(/^(bgB|b)lue/)
    || str.match(/^(bgC|c)yan/)
    || str.match(/^(bgG|g)rey/)
    || str.match(/^(bgW|w)hite/)
    || str.match(/^(bgB|b)lack/)
    || str.match(/^(bgG|g)reen/)
    || str.match(/^(bgY|y)ellow/)
    || str.match(/^(bgM|m)agenta/)
    || str.match(/^(bgB|b)right(Black|Red|Green|Yellow|Blue|Magenta|Cyan|White)/);

  if (match) {

    var method = match[0];
    var suffix = str.substr(method.length);
    var isBg   = startWith(method, 'bg');

    if (isBg) {
      method = lcFirst(method.substr(2));
    }

    if (typeof cursor[method] === 'function') {
      return {
        isBg  : isBg,
        method: method,
        suffix: suffix
      };
    }
  }
}

function parseFont(cursor, str) {

  var match = str.match(/^bold|italic|underline|inverse/);
  if (match) {

    var method = match[0];
    var suffix = str.substr(method.length);

    if (typeof cursor[method] === 'function') {
      return {
        isFont: true,
        method: method,
        suffix: suffix
      };
    }
  }
}

function parseGradient(str) {

  var match = str.match(/^\((.+),(.+)\)/);
  if (match) {

    var color1 = match[1].trim();
    var color2 = match[2].trim();

    color1 = startWith(color1, '#') ? hex2rgb(color1) : name2rgb(color1);
    color2 = startWith(color2, '#') ? hex2rgb(color2) : name2rgb(color2);

    if (color1 && color2) {
      return {
        method: 'gradient',
        color1: color1,
        color2: color2
      };
    }
  }
}

function interpolate(color1, color2, percent) {

  function makeChannel(a, b) {
    return a + Math.round((b - a) * percent);
  }

  return {
    r: makeChannel(color1.r, color2.r),
    g: makeChannel(color1.g, color2.g),
    b: makeChannel(color1.b, color2.b)
  };
}

function hex2rgb(color) {

  var c = color.substring(1);
  var r = c.substring(0, 2);
  var g = c.substring(2, 4);
  var b = c.substring(4, 6);

  return {
    r: parseInt(r, 16),
    g: parseInt(g, 16),
    b: parseInt(b, 16)
  };
}

function name2rgb(name) {
  var hex = {
    red    : '#ff0000',
    blue   : '#0000ff',
    cyan   : '#00ffff',
    grey   : '#808080',
    white  : '#ffffff',
    black  : '#000000',
    green  : '#008000',
    yellow : '#ffff00',
    magenta: '#ff00ff'
  }[name];

  return hex ? hex2rgb(hex) : null;
}
<|endoftext|>