<commit_before>'use strict';

var fs = require('fs-plus');
var path = require('path');
var program = require('commander');
var pjson = require('./package.json');
var cucumber = require('cucumber');

function collectPaths(value, paths) {
    paths.push(value);
    return paths;
}

var config = {
    step_def_dir: './step-definitions',
    page_obj_dir: './page-objects',
    shared_obj_dir: './shared-objects',
    reports_dir: './reports',
    default_browser: 'chrome',
    timeout: 10000
};

var configFileName = path.resolve(process.cwd(), 'selenium-cucumber-js.json');

if (fs.isFileSync(configFileName)) {
    config = Object.assign(config, require(configFileName));
}

program
    .version(pjson.version)
    .description(pjson.description)
    .option('-s, --steps <path>', 'path to step definitions. defaults to ' + config.step_def_dir, config.step_def_dir)
    .option('-p, --pageObjects <path>', 'path to page objects. defaults to ' + config.page_obj_dir, config.page_obj_dir)
    .option('-o, --sharedObjects [paths]', 'path to shared objects (repeatable). defaults to ' + config.shared_obj_dir, collectPaths, [config.shared_obj_dir])
    .option('-b, --browser <path>', 'name of browser to use. defaults to ' + config.default_browser, config.default_browser)
    .option('-r, --reports <path>', 'output path to save reports. defaults to ' + config.reports_dir, config.reports_dir)
    .option('-d, --disableLaunchReport [optional]', 'Disables the auto opening the browser with test report')
    .option('-j, --junit <path>', 'output path to save junit-report.xml defaults to ' + config.reports_dir)
    .option('-t, --tags <tagName>', 'name of tag to run')
    .option('-f, --featureFile <path>', 'a specific feature file to run')
    .option('-x, --timeOut <n>', 'steps definition timeout in milliseconds. defaults to ' + config.timeout, parseInt, config.timeout)
    .option('-n, --noScreenshot [optional]', 'disable auto capturing of screenshots when an error is encountered')
    .parse(process.argv);

program.on('--help', function() {
    console.log('  For more details please visit https://github.com/john-doherty/selenium-cucumber-js#readme\n');
});

// store browserName globally (used within world.js to build driver)
global.browserName = program.browser;

// used within world.js to import page objects
global.pageObjectPath = path.resolve(program.pageObjects);

// used within world.js to output reports
global.reportsPath = path.resolve(program.reports);
if (!fs.existsSync(program.reports)){
    fs.makeTreeSync(program.reports);
}

// used within world.js to decide if reports should be generated
global.disableLaunchReport = (program.disableLaunchReport);

// used with world.js to determine if a screenshot should be captured on error
global.noScreenshot = (program.noScreenshot);

// used within world.js to output junit reports
global.junitPath = path.resolve(program.junit || program.reports);

// set the default timeout to 10 seconds if not already globally defined or passed via the command line
global.DEFAULT_TIMEOUT = global.DEFAULT_TIMEOUT || program.timeOut || 10 * 1000;

// used within world.js to import shared objects into the shared namespace
global.sharedObjectPaths = program.sharedObjects.map(function(item) {
    return path.resolve(item);
});

// rewrite command line switches for cucumber
process.argv.splice(2, 100);

// allow a specific feature file to be executed
if (program.featureFile) {
    process.argv.push(program.featureFile);
}

// add switch to tell cucumber to produce json report files
process.argv.push('-f');
process.argv.push('pretty');
process.argv.push('-f');
process.argv.push('json:' + path.resolve(__dirname, global.reportsPath, 'cucumber-report.json'));

// add cucumber world as first required script (this sets up the globals)
process.argv.push('-r');
process.argv.push(path.resolve(__dirname, 'runtime/world.js'));

// add path to import step definitions
process.argv.push('-r');
process.argv.push(path.resolve(program.steps));

// add tag
if (program.tags) {
    process.argv.push('-t');
    process.argv.push(program.tags);
}

// add strict option (fail if there are any undefined or pending steps)
process.argv.push('-S');

//
// execute cucumber
//
var cucumberCli = cucumber.Cli(process.argv);

global.cucumber = cucumber;

cucumberCli.run(function (succeeded) {

    var code = succeeded ? 0 : 1;

    function exitNow() {
        process.exit(code);
    }

    if (process.stdout.write('')) {
        exitNow();
    }
    else {
        // write() returned false, kernel buffer is not empty yet...
        process.stdout.on('drain', exitNow);
    }
});
<commit_msg>add custom coerce function for parsing integer options (Closes #28)<commit_after>'use strict';

var fs = require('fs-plus');
var path = require('path');
var program = require('commander');
var pjson = require('./package.json');
var cucumber = require('cucumber');

function collectPaths(value, paths) {
    paths.push(value);
    return paths;
}

function coerceInt(value, defaultValue) {
    var int = parseInt(value);

    if (typeof int == 'number') {
        return int;
    }
    else {
        return defaultValue;
    }
}

var config = {
    step_def_dir: './step-definitions',
    page_obj_dir: './page-objects',
    shared_obj_dir: './shared-objects',
    reports_dir: './reports',
    default_browser: 'chrome',
    timeout: 10000
};

var configFileName = path.resolve(process.cwd(), 'selenium-cucumber-js.json');

if (fs.isFileSync(configFileName)) {
    config = Object.assign(config, require(configFileName));
}

program
    .version(pjson.version)
    .description(pjson.description)
    .option('-s, --steps <path>', 'path to step definitions. defaults to ' + config.step_def_dir, config.step_def_dir)
    .option('-p, --pageObjects <path>', 'path to page objects. defaults to ' + config.page_obj_dir, config.page_obj_dir)
    .option('-o, --sharedObjects [paths]', 'path to shared objects (repeatable). defaults to ' + config.shared_obj_dir, collectPaths, [config.shared_obj_dir])
    .option('-b, --browser <path>', 'name of browser to use. defaults to ' + config.default_browser, config.default_browser)
    .option('-r, --reports <path>', 'output path to save reports. defaults to ' + config.reports_dir, config.reports_dir)
    .option('-d, --disableLaunchReport [optional]', 'Disables the auto opening the browser with test report')
    .option('-j, --junit <path>', 'output path to save junit-report.xml defaults to ' + config.reports_dir)
    .option('-t, --tags <tagName>', 'name of tag to run')
    .option('-f, --featureFile <path>', 'a specific feature file to run')
    .option('-x, --timeOut <n>', 'steps definition timeout in milliseconds. defaults to ' + config.timeout, coerceInt, config.timeout)
    .option('-n, --noScreenshot [optional]', 'disable auto capturing of screenshots when an error is encountered')
    .parse(process.argv);

program.on('--help', function() {
    console.log('  For more details please visit https://github.com/john-doherty/selenium-cucumber-js#readme\n');
});

// store browserName globally (used within world.js to build driver)
global.browserName = program.browser;

// used within world.js to import page objects
global.pageObjectPath = path.resolve(program.pageObjects);

// used within world.js to output reports
global.reportsPath = path.resolve(program.reports);
if (!fs.existsSync(program.reports)){
    fs.makeTreeSync(program.reports);
}

// used within world.js to decide if reports should be generated
global.disableLaunchReport = (program.disableLaunchReport);

// used with world.js to determine if a screenshot should be captured on error
global.noScreenshot = (program.noScreenshot);

// used within world.js to output junit reports
global.junitPath = path.resolve(program.junit || program.reports);

// set the default timeout to 10 seconds if not already globally defined or passed via the command line
global.DEFAULT_TIMEOUT = global.DEFAULT_TIMEOUT || program.timeOut || 10 * 1000;

// used within world.js to import shared objects into the shared namespace
global.sharedObjectPaths = program.sharedObjects.map(function(item) {
    return path.resolve(item);
});

// rewrite command line switches for cucumber
process.argv.splice(2, 100);

// allow a specific feature file to be executed
if (program.featureFile) {
    process.argv.push(program.featureFile);
}

// add switch to tell cucumber to produce json report files
process.argv.push('-f');
process.argv.push('pretty');
process.argv.push('-f');
process.argv.push('json:' + path.resolve(__dirname, global.reportsPath, 'cucumber-report.json'));

// add cucumber world as first required script (this sets up the globals)
process.argv.push('-r');
process.argv.push(path.resolve(__dirname, 'runtime/world.js'));

// add path to import step definitions
process.argv.push('-r');
process.argv.push(path.resolve(program.steps));

// add tag
if (program.tags) {
    process.argv.push('-t');
    process.argv.push(program.tags);
}

// add strict option (fail if there are any undefined or pending steps)
process.argv.push('-S');

//
// execute cucumber
//
var cucumberCli = cucumber.Cli(process.argv);

global.cucumber = cucumber;

cucumberCli.run(function (succeeded) {

    var code = succeeded ? 0 : 1;

    function exitNow() {
        process.exit(code);
    }

    if (process.stdout.write('')) {
        exitNow();
    }
    else {
        // write() returned false, kernel buffer is not empty yet...
        process.stdout.on('drain', exitNow);
    }
});
<|endoftext|>


<commit_before>require('img-load')();

function Plugin() {
	/**
	 * Height which is used for comparing
	 * @type {number}
	 */
	this._extremeHeight = undefined;

	/**
	 * Window object
	 * @type {jQuery}
	 */
	this.$window = undefined;

	/**
	 * Elements to equalize
	 * @type {jQuery}
	 */
	this.$target = undefined;

	/**
	 * Main element
	 * @type {jQuery}
	 */
	this.$el = undefined;
}

Plugin.prototype = {
	constructor: Plugin,
	defaults: {
		target: '.js-equalize-target',
		breakpoint: {
			max: false,
			min: false
		},
		onImgLoad: false,
		byMaxHeight: true,
		callback: function() {}
	},

	init: function() {
		this._resolveOptions();
		this._setDataOptions();
		this._defineExtremeHeight();
		this._defineTarget();
		this.$window = $(window);
		this.$window.on('resize', this.run.bind(this));
		this.run();
	},

	run: function() {
		this.reset();
		if (!this._isAllowedWidth())
			return;
		this.onImgLoad(this.equalize.bind(this));
	},

	reset: function() {
		this.$target.css('height', null);
	},

	/**
	 * If to run the plugin for the current window width
	 * @return {Boolean}
	 */
	_isAllowedWidth: function() {
		var windowWidth = this.$window.width();
		if (this.options.breakpoint.min !== false && windowWidth <= this.options.breakpoint.min)
			return false;
		if (this.options.breakpoint.max !== false && windowWidth >= this.options.breakpoint.max)
			return false;
		return true;
	},

	onImgLoad: function(callback) {
		if (this.options.onImgLoad === false) {
			callback();
		} else {
			var imgSelector = $.type(this.options.onImgLoad) == 'string' ? this.options.onImgLoad : 'img';
			this.$el.imgLoad({
				callback: callback,
				imgSelector: imgSelector
			});
		}
	},

	_defineExtremeHeight: function() {
		this._extremeHeight = this.options.byMaxHeight ? 0 : 100000;
	},

	_defineTarget: function() {
		this.$target = this.options.target instanceof $ ?
			this.options.target : this.$el.find(this.options.target);
	},

	_getHeights: function() {
		return this.$target.map(function() {
			return $(this).outerHeight();
		}).get();
	},

	equalize: function() {
		var heights = this._getHeights();
		this.$target.outerHeight(this._defineHeight(heights));
		this.options.callback();
	},

	_defineHeight: function(heights) {
		heights.push(this._extremeHeight);
		return this.options.byMaxHeight ? Math.max.apply(null, heights) : Math.min.apply(null, heights);
	},

	_resolveOptions: function() {
		this.$el = this.options.$el;
	},

	_setDataOptions: function() {
		this.setOptions(this.$el.data(Plugin._name));
	},

	setOptions: function(options) {
		this.options = $.extend(true, {}, this.defaults, this.options, options);
		if (!this.options.$el)
			throw new Error('$el must be set in options');
	},

};

Plugin.options = {
	// Selector which will be used by plugin as default for target at init
	autoSelector: '.js-equalize-auto',
	pluginName: 'equalize'
};

Plugin._name = 'equalizer';

Plugin.init = function(options) {
	var inst = new this;
	inst.setOptions(options);
	this.instance(options.$el[0], inst);
	inst.init();
};

Plugin.boot = function() {
	this.setJqueryProps();
	$(this.options.autoSelector).each(function() {
		$(this)[Plugin.options.pluginName]();
	});
	return this;
};

Plugin.setJqueryProps = function() {
	$.equalize = Plugin;
	$.fn[Plugin.options.pluginName] = Plugin.jqueryInit;
};

/**
 * JQuery plugin entry
 * @param  {Object} options
 * @return {jQuery} jquery instance
 */
Plugin.jqueryInit = function(options) {
	var constructor = Plugin.jqueryConstructor.bind(Plugin, options);
	return this.each(constructor);
};

/**
 * JQuery constuctor
 * @param  {Object} options Options
 * @param  {number} index   Element index
 * @param  {HTMLElement} el Html element
 */
Plugin.jqueryConstructor = function(options, index, el) {
	var inst = Plugin.instance(el);
	if (inst) inst.run();
	else
		Plugin.init(Plugin.resolveOptions($(el), options));
};

/**
 * Get/set instance to element
 * @param  {HTMLElement} el
 * @param  {Plugin} inst
 * @return {(Plugin|void)}
 */
Plugin.instance = function(el, inst) {
	var dataName = this._name + '_instance';
	if (inst)
		$.data(el, dataName, inst);
	else return $.data(el, dataName);
};

/**
 * Make options copy and set $el property
 * @param  {jQuery} $el
 * @param  {Object} options Original options
 * @return {Object}         Resolved options
 */
Plugin.resolveOptions = function($el, options) {
	options = $.extend(true, {}, options);
	options.$el = $el;
	return options;
};

module.exports = Plugin;<commit_msg>feat: use jquery 'height' to support <1.8.0 version<commit_after>require('img-load')();

function Plugin() {
	/**
	 * Height which is used for comparing
	 * @type {number}
	 */
	this._extremeHeight = undefined;

	/**
	 * Window object
	 * @type {jQuery}
	 */
	this.$window = undefined;

	/**
	 * Elements to equalize
	 * @type {jQuery}
	 */
	this.$target = undefined;

	/**
	 * Main element
	 * @type {jQuery}
	 */
	this.$el = undefined;
}

Plugin.prototype = {
	constructor: Plugin,
	defaults: {
		target: '.js-equalize-target',
		breakpoint: {
			max: false,
			min: false
		},
		onImgLoad: false,
		byMaxHeight: true,
		callback: function() {}
	},

	init: function() {
		this._resolveOptions();
		this._setDataOptions();
		this._defineExtremeHeight();
		this._defineTarget();
		this.$window = $(window);
		this.$window.on('resize', this.run.bind(this));
		this.run();
	},

	run: function() {
		this.reset();
		if (!this._isAllowedWidth())
			return;
		this.onImgLoad(this.equalize.bind(this));
	},

	reset: function() {
		this.$target.css('height', null);
	},

	/**
	 * If to run the plugin for the current window width
	 * @return {Boolean}
	 */
	_isAllowedWidth: function() {
		var windowWidth = this.$window.width();
		if (this.options.breakpoint.min !== false && windowWidth <= this.options.breakpoint.min)
			return false;
		if (this.options.breakpoint.max !== false && windowWidth >= this.options.breakpoint.max)
			return false;
		return true;
	},

	onImgLoad: function(callback) {
		if (this.options.onImgLoad === false) {
			callback();
		} else {
			var imgSelector = $.type(this.options.onImgLoad) == 'string' ? this.options.onImgLoad : 'img';
			this.$el.imgLoad({
				callback: callback,
				imgSelector: imgSelector
			});
		}
	},

	_defineExtremeHeight: function() {
		this._extremeHeight = this.options.byMaxHeight ? 0 : 100000;
	},

	_defineTarget: function() {
		this.$target = this.options.target instanceof $ ?
			this.options.target : this.$el.find(this.options.target);
	},

	_getHeights: function() {
		return this.$target.map(function() {
			return $(this).outerHeight();
		}).get();
	},

	equalize: function() {
		var heights = this._getHeights();
		this.$target.height(this._defineHeight(heights));
		this.options.callback();
	},

	_defineHeight: function(heights) {
		heights.push(this._extremeHeight);
		return this.options.byMaxHeight ? Math.max.apply(null, heights) : Math.min.apply(null, heights);
	},

	_resolveOptions: function() {
		this.$el = this.options.$el;
	},

	_setDataOptions: function() {
		this.setOptions(this.$el.data(Plugin._name));
	},

	setOptions: function(options) {
		this.options = $.extend(true, {}, this.defaults, this.options, options);
		if (!this.options.$el)
			throw new Error('$el must be set in options');
	},

};

Plugin.options = {
	// Selector which will be used by plugin as default for target at init
	autoSelector: '.js-equalize-auto',
	pluginName: 'equalize'
};

Plugin._name = 'equalizer';

Plugin.init = function(options) {
	var inst = new this;
	inst.setOptions(options);
	this.instance(options.$el[0], inst);
	inst.init();
};

Plugin.boot = function() {
	this.setJqueryProps();
	$(this.options.autoSelector).each(function() {
		$(this)[Plugin.options.pluginName]();
	});
	return this;
};

Plugin.setJqueryProps = function() {
	$.equalize = Plugin;
	$.fn[Plugin.options.pluginName] = Plugin.jqueryInit;
};

/**
 * JQuery plugin entry
 * @param  {Object} options
 * @return {jQuery} jquery instance
 */
Plugin.jqueryInit = function(options) {
	var constructor = Plugin.jqueryConstructor.bind(Plugin, options);
	return this.each(constructor);
};

/**
 * JQuery constuctor
 * @param  {Object} options Options
 * @param  {number} index   Element index
 * @param  {HTMLElement} el Html element
 */
Plugin.jqueryConstructor = function(options, index, el) {
	var inst = Plugin.instance(el);
	if (inst) inst.run();
	else
		Plugin.init(Plugin.resolveOptions($(el), options));
};

/**
 * Get/set instance to element
 * @param  {HTMLElement} el
 * @param  {Plugin} inst
 * @return {(Plugin|void)}
 */
Plugin.instance = function(el, inst) {
	var dataName = this._name + '_instance';
	if (inst)
		$.data(el, dataName, inst);
	else return $.data(el, dataName);
};

/**
 * Make options copy and set $el property
 * @param  {jQuery} $el
 * @param  {Object} options Original options
 * @return {Object}         Resolved options
 */
Plugin.resolveOptions = function($el, options) {
	options = $.extend(true, {}, options);
	options.$el = $el;
	return options;
};

module.exports = Plugin;<|endoftext|>


<commit_before>'use strict';

var fs = require('fs');
var _ = require('lodash');

/**
 *
 * @param {String} filename - GPIO Pins file in the ArchLinux
 * @returns {Array}
 *                 - {Int} pin
 *                 - {String} gpio
 */
function getPins(filename) {

    var list = [];

    if (!filename) return list;

    var lines = fs.readFileSync(filename).toString().split("\n").filter(function (line) {
        return _.isString(line);
    });
    var pinLines = lines.slice(1, lines.length);

    for (var i = 0; i < pinLines.length; i++) {
        var words = _.words(pinLines[i]);
        list[i] = {pin: _.parseInt(words[1]), gpio: words[2] + words[3]};
    }

    return list;
}

/**
 *
 * @param {String} direction - "in" or "out", default: "out"
 * @returns {*}
 */
function sanitizeDirection(direction) {
    direction = (direction || "").toLowerCase().trim();
    if (direction === "in" || direction === "input") {
        return "in";
    } else if (direction === "out" || direction === "output" || !direction) {
        return "out";
    } else {
        throw new Error("Direction must be 'input' or 'output'");
    }
}

/**
 * @class
 * @param {Array} options
 *                     - pinsFilename
 */
function gpio(options) {

    this.pinsFilename = '/sys/kernel/debug/pinctrl/1c20800.pinctrl/pins';
    this.gpioFilename = '/sys/class/gpio';
    this.options = options;

    if (this.options && this.options.pinsFilename) {
        this.pinsFilename = this.options.pinsFilename;
    }

    this.pins = getPins(this.pinsFilename);

    this.activatePinsOutput = function (gpioKeys) {
        var self = this;
        _(gpioKeys).forEach(function (key) {
            self.setDirection(key, 'out');
        });
    }

    this.setDirection = function (gpioKey, direction) {
        var pin = this.getPin(gpioKey);
        if (_.isNull(pin)) {
            throw new Error(gpioKey + ' not found');
        }

        fs.writeFile(this.gpioFilename + "/gpio" + pin + "/direction", sanitizeDirection(direction), function (err) {
            if (err) throw err;
        });
    }

    this.getPin = function (gpioKey) {
        var found = _.find(this.pins, _.matchesProperty('gpio', gpioKey));
        if (_.isObject(found)) {
            return found.pin;
        }
        return null;
    }

    this.write = function (gpioKey, signal) {
        if (_.isEmpty(signal))
            signal = '0';
        var pin = this.getPin(gpioKey);
        if (_.isNull(pin)) {
            throw new Error(gpioKey + ' not found');
        }
        fs.writeFile(this.gpioFilename + "/gpio" + pin + "/value", signal, 'utf8', function (err) {
            if (err) throw err;
        });
    }
}

module.exports = gpio;<commit_msg>fix(JSDoc): class gpio<commit_after>'use strict';

var fs = require('fs');
var _ = require('lodash');

/**
 *
 * @param {String} filename - GPIO Pins file in the ArchLinux
 * @returns {Array}
 *                 - {Int} pin
 *                 - {String} gpio
 */
function getPins(filename) {

    var list = [];

    if (!filename) return list;

    var lines = fs.readFileSync(filename).toString().split("\n").filter(function (line) {
        return _.isString(line);
    });
    var pinLines = lines.slice(1, lines.length);

    for (var i = 0; i < pinLines.length; i++) {
        var words = _.words(pinLines[i]);
        list[i] = {pin: _.parseInt(words[1]), gpio: words[2] + words[3]};
    }

    return list;
}

/**
 *
 * @param {String} direction - "in" or "out", default: "out"
 * @returns {*}
 */
function sanitizeDirection(direction) {
    direction = (direction || "").toLowerCase().trim();
    if (direction === "in" || direction === "input") {
        return "in";
    } else if (direction === "out" || direction === "output" || !direction) {
        return "out";
    } else {
        throw new Error("Direction must be 'input' or 'output'");
    }
}

/**
 * @class
 * @param {Object} options - settings
 * @param {String} [options.pinsFilename ='/sys/kernel/debug/pinctrl/1c20800.pinctrl/pins'] - registered pins
 */
function gpio(options) {

    this.pinsFilename = '/sys/kernel/debug/pinctrl/1c20800.pinctrl/pins';
    this.gpioFilename = '/sys/class/gpio';
    this.options = options;

    if (this.options && this.options.pinsFilename) {
        this.pinsFilename = this.options.pinsFilename;
    }

    this.pins = getPins(this.pinsFilename);

    this.activatePinsOutput = function (gpioKeys) {
        var self = this;
        _(gpioKeys).forEach(function (key) {
            self.setDirection(key, 'out');
        });
    }

    this.setDirection = function (gpioKey, direction) {
        var pin = this.getPin(gpioKey);
        if (_.isNull(pin)) {
            throw new Error(gpioKey + ' not found');
        }

        fs.writeFile(this.gpioFilename + "/gpio" + pin + "/direction", sanitizeDirection(direction), function (err) {
            if (err) throw err;
        });
    }

    this.getPin = function (gpioKey) {
        var found = _.find(this.pins, _.matchesProperty('gpio', gpioKey));
        if (_.isObject(found)) {
            return found.pin;
        }
        return null;
    }

    this.write = function (gpioKey, signal) {
        if (_.isEmpty(signal))
            signal = '0';
        var pin = this.getPin(gpioKey);
        if (_.isNull(pin)) {
            throw new Error(gpioKey + ' not found');
        }
        fs.writeFile(this.gpioFilename + "/gpio" + pin + "/value", signal, 'utf8', function (err) {
            if (err) throw err;
        });
    }
}

module.exports = gpio;<|endoftext|>


<commit_before>const path = require('path')
const loaderUtils = require('loader-utils')

module.exports = function process(content) {
  if (this.cacheable) {
    this.cacheable()
  }

  const query = loaderUtils.parseQuery(this.query)
  const configKey = query.config || "nodeNativeLoader";
  const options = this.options[configKey] || {};

  const config = {
    name: "[hash].[ext]"
  };

  // options takes precedence over config
  Object.keys(options).forEach(function(attr) {
    config[attr] = options[attr];
  });

  // query takes precedence over config and options
  Object.keys(query).forEach(function(attr) {
    config[attr] = query[attr];
  });

  let outfile = loaderUtils.interpolateName(this, config.name, {
    context: config.context || this.options.context,
    content,
  })
  outfile = outfile.replace(/[\\/]/g, '_')
  this.emitFile(outfile, content)
  let relativePath = config.from ?
      path.relative(config.from, path.resolve(this.options.output.path, outfile)) : outfile
  if (path.sep !== '/') {
    // require always uses posix separators
    relativePath = relativePath.replace('\\', '/')
  }
  if (relativePath[0] !== '.') {
    // Node needs all relative paths to start with a '.'
    relativePath = './' + relativePath
  }
  const modulePath = JSON.stringify(relativePath)
  return 'module.exports = __non_webpack_require__(' + modulePath + ')'
}
module.exports.raw = true
<commit_msg>Update index.js<commit_after>const path = require('path')
const loaderUtils = require('loader-utils')

module.exports = function process(content) {
  if (this.cacheable) {
    this.cacheable()
  }

  const query = loaderUtils.getOptions(this) || {};
  const configKey = query.config || "nodeNativeLoader";
  const options = this.options[configKey] || {};

  const config = {
    name: "[hash].[ext]"
  };

  // options takes precedence over config
  Object.keys(options).forEach(function(attr) {
    config[attr] = options[attr];
  });

  // query takes precedence over config and options
  Object.keys(query).forEach(function(attr) {
    config[attr] = query[attr];
  });

  let outfile = loaderUtils.interpolateName(this, config.name, {
    context: config.context || this.options.context,
    content,
  })
  outfile = outfile.replace(/[\\/]/g, '_')
  this.emitFile(outfile, content)
  let relativePath = config.from ?
      path.relative(config.from, path.resolve(this.options.output.path, outfile)) : outfile
  if (path.sep !== '/') {
    // require always uses posix separators
    relativePath = relativePath.replace('\\', '/')
  }
  if (relativePath[0] !== '.') {
    // Node needs all relative paths to start with a '.'
    relativePath = './' + relativePath
  }
  const modulePath = JSON.stringify(relativePath)
  return 'module.exports = __non_webpack_require__(' + modulePath + ')'
}
module.exports.raw = true
<|endoftext|>


<commit_before>var fs = require('fs')
  , zlib = require('zlib')
  , path = require('path');

function series(jobs, cb) {
  (function next(err) {
    if (err) return cb(err);
    var job = jobs.shift();
    job ? job(next) : cb(null);
  })();
}

function zip(file, cb) {
  fs.createReadStream(file)
    .pipe( zlib.createGzip() )
    .pipe( fs.createWriteStream(file +'.gz') )
    .on('finish', function() {
      fs.unlink(file, function(err){
        cb(err, file +'.gz');
      });
    });
}

module.exports = function(file, options, cb) {
  if (typeof cb === 'undefined') {
    cb = options;
    options = {}
  }

  var dir   = path.dirname(file)
    , name  = path.basename(file)
    , count = options.count ? (options.count - 1) : null
    // regex for matching rotations of the current log
    , reg   = (options.matcher || new RegExp(name + "\\.\\d+\\.?"))

  fs.readdir(dir, function(err, files) {
    if (err) return cb(err);
    var toShift = []
      , i, l;

    // get matching files from dir
    for (i = 0, l = files.length; i < l; i++) {
      if (reg.test(files[i]) === true) { toShift.push(files[i]) }
    }

    // reverse sort files by name
    toShift.sort(function(a, b) { return b > a ? 1 : -1; });

    var jobs = [];

    // increment each files index
    for (i = 0, l = toShift.length; i < l; i++) {
      var curr = toShift[i];
      // remove log files outside of the `count` limit
      if (count !== null && l >= count && i <= (l - count)) {
        jobs.push(function(done) {
          fs.unlink(path.join(dir, '/', curr), done);
        });
      } else {
        var parts = toShift[i].split('.');
        // increment the log file index
        for (var j = parts.length; j >= 0; j--) {
          if ( isNaN(parts[j]) === false ) {
            parts[j] = +parts[j] + 1; break;
          }
        }
        // move the file to the new index
        jobs.push(function(done) {
          fs.rename(
            path.join(dir, '/', curr),
            path.join(dir, '/', parts.join('.')),
            done
          );
        });
      }
    }

    series(jobs, function(err) {
      // move the original log file
      var rotated = file + '.0';
      fs.rename(file, rotated, function(err) {
        // compress the newly rotated file
        if (options.compress === true) {
          zip(rotated, cb);
        } else {
          cb(null, rotated);
        }
      });
    });
  });
}
<commit_msg>simplify series execution logic<commit_after>var fs = require('fs')
  , zlib = require('zlib')
  , path = require('path');

function series(jobs, cb) {
  (function next(err) {
    if (err) return cb(err);
    var job = jobs.shift();
    job ? job(next) : cb(null);
  })();
}

function zip(file, cb) {
  fs.createReadStream(file)
    .pipe( zlib.createGzip() )
    .pipe( fs.createWriteStream(file +'.gz') )
    .on('finish', function() {
      fs.unlink(file, function(err){
        cb(err, file +'.gz');
      });
    });
}

module.exports = function(file, options, cb) {
  if (typeof cb === 'undefined') {
    cb = options;
    options = {}
  }

  var dir   = path.dirname(file)
    , name  = path.basename(file)
    , count = options.count ? (options.count - 1) : null
    // regex for matching rotations of the current log
    , reg   = (options.matcher || new RegExp(name + "\\.\\d+\\.?"))

  function remove(name) {
    return function(done) {
      fs.unlink(path.join(dir, '/', name), done);
    }
  }

  function rename(name, target) {
    return function(done) {
      fs.rename(path.join(dir, '/', name), path.join(dir, '/', target), done);
    }
  }

  fs.readdir(dir, function(err, files) {
    if (err) return cb(err);
    var toShift = []
      , jobs, i, l;

    // get matching files from dir
    for (i = 0, l = files.length; i < l; i++) {
      if (reg.test(files[i]) === true) { toShift.push(files[i]) }
    }

    // reverse sort files by name
    toShift.sort(function(a, b) { return b > a ? 1 : -1; });

    jobs = toShift.map(function(target, i) {
      if (count !== null && toShift.length > count && i <= (toShift.length - count)) {
        return remove(target);
      }

      var parts = target.split('.');
      // increment the log file index
      for (var j = parts.length; j >= 0; j--) {
        if ( isNaN(parts[j]) === false ) { parts[j] = +parts[j] + 1; break; }
      }
      return rename(target, parts.join('.'));
    });

    var rotated = file +'.0';
    series(jobs, function(err) {
      fs.rename(file, rotated, function(err) {
        // compress the newly rotated file
        if (options.compress === true) {
          zip(rotated, cb);
        } else {
          cb(null, rotated);
        }
      });
    });
  });
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var required = require('./validators/required');
var email = require('./validators/email');
var numeric = require('./validators/numeric');
var image = require('./validators/image');
var alpha = require('./validators/alpha');
var alphanumeric = require('./validators/alphanumeric');
var date = require('./validators/date');
var url = require('./validators/url');
var string = require('./validators/string');
var nonBlank = require('./validators/non-blank');
var maxLength = require('./validators/max-length');
var minLength = require('./validators/min-length');
var minValue = require('./validators/min-value');
var maxValue = require('./validators/max-value');
var memberOf = require('./validators/member-of');
var beginWith = require('./validators/begin-with');
var regex = require('./validators/regex');

/*
 * Rules should have format:
 * {
 *   name        : ['required']
 *   officeEmail : ['email'],
 *   phone       : ['required', 'numeric']
 * }
 *
 * Example input:
 * { name: 'Sendy', title: 'Lord', officeEmail: 'invalid email', phone: 'hi there123'}
 *
 * messageObj will be like this
 * {
 *   officeEmail: {
 *     email: 'OfficeEmail must be email'
 *   }
 *   phone: {
 *     number: 'Phone must be numeric'
 *   }
 * }
 *
 */

var validations = {
  required: required.validator,
  numeric: numeric.validator,
  email: email.validator,
  image: image.validator,
  alpha: alpha.validator,
  alphanumeric: alphanumeric.validator,
  date: date.validator,
  url: url.validator,
  string: string.validator,
  nonBlank: nonBlank.validator,
  'maxLength:$1': maxLength.validator,
  'minLength:$1': minLength.validator,
  'maxValue:$1': maxValue.validator,
  'minValue:$1': minValue.validator,
  'memberOf:$1': memberOf.validator,
  'beginWith:$1': beginWith.validator,
  'regex:$1:$2': regex.validator
};

var validationMessages = {
  required: required.message,
  numeric: numeric.message,
  email: email.message,
  image: image.message,
  alpha: alpha.message,
  alphanumeric: alphanumeric.message,
  date: date.message,
  url: url.message,
  string: string.message,
  nonBlank: nonBlank.message,
  'maxValue:$1': maxValue.message,
  'minValue:$1': minValue.message,
  'maxLength:$1': maxLength.message,
  'minLength:$1': minLength.message,
  'memberOf:$1': memberOf.message,
  'beginWith:$1': beginWith.message,
  'regex:$1:$2': regex.message
};

var ValidationMessage = function () {
  this.messageArray = [];
};

var Validator = function () {

};

Validator.prototype.validation = {
  rules: validations,
  messages: validationMessages
};

Validator.prototype.validate = function (rules, obj) {
  var result = true;
  var messageObj = new ValidationMessage();
  var validator = this;

  // Loop through the given rules
  _.forEach(rules, function (ruleArray, propertyName) {
    var val = obj[propertyName];
    // ruleArray should be something like ['required', 'email']
    ruleArray.forEach(function (rule) {
      var ruleObj = {};

      if (_.isString(rule)) {
        // First variant, everything is embedded as string
        var splitted = rule.split(':');
        ruleObj = {
          // Property fullName is the generic full name of validation rule
          // e.g range:1:3 -> range:$1:$2, required -> required
          fullName: _.first(splitted),

          // Get only the first part of full rule e.g if range:1:3 then
          // we will get 'range'
          name: _.first(splitted),

          // Get the rule params if e.g range:1:3 -> [1, 3]
          params: splitted.slice(1)
        };
      } else {
        // Second variant, it is already parsed
        ruleObj.name = rule.name;
        ruleObj.fullName = rule.name;
        ruleObj.params = rule.params;
      }

      ruleObj.fullName = ruleObj.params.reduce(function (ruleName, val, index) {
        return ruleName + ':$' + (index + 1).toString();
      }, ruleObj.fullName);

      var validationRuleFn = validator.validation.rules[ruleObj.fullName];
      var validationResult = validationRuleFn(val, ruleObj, propertyName, obj);

      if (!validationResult) {
        result = false;

        // Set messageObj initial value
        messageObj[propertyName] = messageObj[propertyName] || {};

        // Set the validation message
        var msg = validator.getValidationMessage(ruleObj, propertyName, val);
        messageObj[propertyName][ruleObj.fullName] = msg;
        messageObj.messageArray.push(msg);
      }
    });
  });

  return {
    success: result,
    messages: messageObj
  };
};

Validator.prototype.getValidationMessage = function (ruleObj, propertyName, val) {
  var compiled = _.template(this.validation.messages[ruleObj.fullName]);
  propertyName = _.startCase(propertyName);

  return compiled({
    propertyName: propertyName,
    ruleName: ruleObj.fullName,
    ruleParams: ruleObj.params,
    value: val
  });
};

exports = module.exports = {
  create: function () {
    return new Validator();
  },
  validate: function (rules, obj) {
    var validator = new Validator();
    return validator.validate(rules, obj);
  },
  validations: validations,
  addCustomValidation: function (ruleName, fn) {
    validations[ruleName] = fn;
  },
  setValidationMessage: function (ruleName, message) {
    validationMessages[ruleName] = message;
  }
};
<commit_msg>Clone deep validation rules and messages for each validator instance<commit_after>'use strict';

var _ = require('lodash');
var required = require('./validators/required');
var email = require('./validators/email');
var numeric = require('./validators/numeric');
var image = require('./validators/image');
var alpha = require('./validators/alpha');
var alphanumeric = require('./validators/alphanumeric');
var date = require('./validators/date');
var url = require('./validators/url');
var string = require('./validators/string');
var nonBlank = require('./validators/non-blank');
var maxLength = require('./validators/max-length');
var minLength = require('./validators/min-length');
var minValue = require('./validators/min-value');
var maxValue = require('./validators/max-value');
var memberOf = require('./validators/member-of');
var beginWith = require('./validators/begin-with');
var regex = require('./validators/regex');

/*
 * Rules should have format:
 * {
 *   name        : ['required']
 *   officeEmail : ['email'],
 *   phone       : ['required', 'numeric']
 * }
 *
 * Example input:
 * { name: 'Sendy', title: 'Lord', officeEmail: 'invalid email', phone: 'hi there123'}
 *
 * messageObj will be like this
 * {
 *   officeEmail: {
 *     email: 'OfficeEmail must be email'
 *   }
 *   phone: {
 *     number: 'Phone must be numeric'
 *   }
 * }
 *
 */

var validations = {
  required: required.validator,
  numeric: numeric.validator,
  email: email.validator,
  image: image.validator,
  alpha: alpha.validator,
  alphanumeric: alphanumeric.validator,
  date: date.validator,
  url: url.validator,
  string: string.validator,
  nonBlank: nonBlank.validator,
  'maxLength:$1': maxLength.validator,
  'minLength:$1': minLength.validator,
  'maxValue:$1': maxValue.validator,
  'minValue:$1': minValue.validator,
  'memberOf:$1': memberOf.validator,
  'beginWith:$1': beginWith.validator,
  'regex:$1:$2': regex.validator
};

var validationMessages = {
  required: required.message,
  numeric: numeric.message,
  email: email.message,
  image: image.message,
  alpha: alpha.message,
  alphanumeric: alphanumeric.message,
  date: date.message,
  url: url.message,
  string: string.message,
  nonBlank: nonBlank.message,
  'maxValue:$1': maxValue.message,
  'minValue:$1': minValue.message,
  'maxLength:$1': maxLength.message,
  'minLength:$1': minLength.message,
  'memberOf:$1': memberOf.message,
  'beginWith:$1': beginWith.message,
  'regex:$1:$2': regex.message
};

var ValidationMessage = function () {
  this.messageArray = [];
};

var Validator = function () {
  this.validation = {
    rules: _.cloneDeep(validations),
    messages: _.cloneDeep(validationMessages)
  };
};

Validator.prototype.validate = function (rules, obj) {
  var result = true;
  var messageObj = new ValidationMessage();
  var validator = this;

  // Loop through the given rules
  _.forEach(rules, function (ruleArray, propertyName) {
    var val = obj[propertyName];
    // ruleArray should be something like ['required', 'email']
    ruleArray.forEach(function (rule) {
      var ruleObj = {};

      if (_.isString(rule)) {
        // First variant, everything is embedded as string
        var splitted = rule.split(':');
        ruleObj = {
          // Property fullName is the generic full name of validation rule
          // e.g range:1:3 -> range:$1:$2, required -> required
          fullName: _.first(splitted),

          // Get only the first part of full rule e.g if range:1:3 then
          // we will get 'range'
          name: _.first(splitted),

          // Get the rule params if e.g range:1:3 -> [1, 3]
          params: splitted.slice(1)
        };
      } else {
        // Second variant, it is already parsed
        ruleObj.name = rule.name;
        ruleObj.fullName = rule.name;
        ruleObj.params = rule.params;
      }

      ruleObj.fullName = ruleObj.params.reduce(function (ruleName, val, index) {
        return ruleName + ':$' + (index + 1).toString();
      }, ruleObj.fullName);

      var validationRuleFn = validator.validation.rules[ruleObj.fullName];
      var validationResult = validationRuleFn(val, ruleObj, propertyName, obj);

      if (!validationResult) {
        result = false;

        // Set messageObj initial value
        messageObj[propertyName] = messageObj[propertyName] || {};

        // Set the validation message
        var msg = validator.getValidationMessage(ruleObj, propertyName, val);
        messageObj[propertyName][ruleObj.fullName] = msg;
        messageObj.messageArray.push(msg);
      }
    });
  });

  return {
    success: result,
    messages: messageObj
  };
};

Validator.prototype.getValidationMessage = function (ruleObj, propertyName, val) {
  var compiled = _.template(this.validation.messages[ruleObj.fullName]);
  propertyName = _.startCase(propertyName);

  return compiled({
    propertyName: propertyName,
    ruleName: ruleObj.fullName,
    ruleParams: ruleObj.params,
    value: val
  });
};

Validator.prototype.addCustomValidation = function (ruleName, fn) {
  this.validation.rules[ruleName] = fn;
};

Validator.prototype.setValidationMessage = function (ruleName, message) {
  this.validation.messages[ruleName] = message;
};

exports = module.exports = {
  create: function () {
    return new Validator();
  },
  validate: function (rules, obj) {
    var validator = new Validator();
    return validator.validate(rules, obj);
  },
  validations: validations,
  addCustomValidation: function (ruleName, fn) {
    validations[ruleName] = fn;
  },
  setValidationMessage: function (ruleName, message) {
    validationMessages[ruleName] = message;
  }
};
<|endoftext|>


<commit_before>module.exports = {
  extends: [
    'airbnb-base',
    'plugin:promise/recommended',
    'plugin:unicorn/recommended',
    'prettier',
  ],
  plugins: [
    'babel',
    'eslint-comments',
    'no-use-extend-native',
    'prettier',
    'promise',
    'unicorn',
  ],
  rules: {
    complexity: [2, 11],
    'max-depth': [2, 4],
    'max-nested-callbacks': [2, 3],
    'max-params': [2, 3],
    'max-statements-per-line': [2, {max: 1}],
    'max-statements': [2, 15],
    'no-compare-neg-zero': 2,
    'no-implicit-coercion': [2, {boolean: false, number: true, string: true}],
    'no-magic-numbers': [
      2,
      {
        ignore: [-1, 0, 1],
        ignoreArrayIndexes: true,
        enforceConst: true,
        detectObjects: false,
      },
    ],
    semi: 0, // deprecated in favor of `babel/semi`
    // https://github.com/babel/eslint-plugin-babel
    'babel/array-bracket-spacing': 0,
    'babel/arrow-parens': 0,
    'babel/flow-object-type': 0,
    'babel/func-params-comma-dangle': 0,
    'babel/generator-star-spacing': 0,
    'babel/new-cap': [2, {newIsCap: true, capIsNew: true}],
    'babel/no-await-in-loop': 0,
    'babel/no-invalid-this': 2,
    'babel/object-curly-spacing': 0,
    'babel/object-shorthand': 0,
    'babel/semi': [2, 'always'],
    // https://github.com/mysticatea/eslint-plugin-eslint-comments
    'eslint-comments/disable-enable-pair': 2,
    'eslint-comments/no-duplicate-disable': 2,
    'eslint-comments/no-unlimited-disable': 2,
    'eslint-comments/no-unused-disable': 2,
    'eslint-comments/no-unused-enable': 2,
    'eslint-comments/no-use': [
      2,
      {
        allow: [
          'eslint-disable',
          'eslint-disable-line',
          'eslint-disable-next-line',
          'eslint-enable',
        ],
      },
    ],
    // https://github.com/benmosher/eslint-plugin-import
    'import/order': [
      2,
      {
        groups: [
          'builtin',
          'external',
          'internal',
          ['parent', 'sibling', 'index'],
        ],
        'newlines-between': 'always',
      },
    ],
    'import/prefer-default-export': 0,
    // https://github.com/dustinspecker/eslint-plugin-no-use-extend-native
    'no-use-extend-native/no-use-extend-native': 2,
    // https://github.com/not-an-aardvark/eslint-plugin-prettier
    'prettier/prettier': [
      2,
      {
        useTabs: false,
        printWidth: 80,
        tabWidth: 2,
        singleQuote: true,
        trailingComma: 'all',
        bracketSpacing: false,
        jsxBracketSameLine: false,
        parser: 'babylon',
        semi: true,
      },
    ],
    // https://github.com/xjamundx/eslint-plugin-promise
    'promise/avoid-new': 0,
    'promise/prefer-await-to-callbacks': 0,
    'promise/prefer-await-to-then': 2,
    // https://github.com/sindresorhus/eslint-plugin-unicorn
    'unicorn/catch-error-name': 0,
    'unicorn/custom-error-definition': 0,
    'unicorn/filename-case': 0,
    'unicorn/no-abusive-eslint-disable': 0, // in favor of `eslint-comments/no-unlimited-disable`
    'unicorn/prefer-type-error': 0,
  },
};
<commit_msg>feat(base): remove `babel/new-cap` rule<commit_after>module.exports = {
  extends: [
    'airbnb-base',
    'plugin:promise/recommended',
    'plugin:unicorn/recommended',
    'prettier',
  ],
  plugins: [
    'babel',
    'eslint-comments',
    'no-use-extend-native',
    'prettier',
    'promise',
    'unicorn',
  ],
  rules: {
    complexity: [2, 11],
    'max-depth': [2, 4],
    'max-nested-callbacks': [2, 3],
    'max-params': [2, 3],
    'max-statements-per-line': [2, {max: 1}],
    'max-statements': [2, 15],
    'no-compare-neg-zero': 2,
    'no-implicit-coercion': [2, {boolean: false, number: true, string: true}],
    'no-magic-numbers': [
      2,
      {
        ignore: [-1, 0, 1],
        ignoreArrayIndexes: true,
        enforceConst: true,
        detectObjects: false,
      },
    ],
    semi: 0, // deprecated in favor of `babel/semi`
    // https://github.com/babel/eslint-plugin-babel
    'babel/array-bracket-spacing': 0,
    'babel/arrow-parens': 0,
    'babel/flow-object-type': 0,
    'babel/func-params-comma-dangle': 0,
    'babel/generator-star-spacing': 0,
    'babel/new-cap': 0,
    'babel/no-await-in-loop': 0,
    'babel/no-invalid-this': 2,
    'babel/object-curly-spacing': 0,
    'babel/object-shorthand': 0,
    'babel/semi': [2, 'always'],
    // https://github.com/mysticatea/eslint-plugin-eslint-comments
    'eslint-comments/disable-enable-pair': 2,
    'eslint-comments/no-duplicate-disable': 2,
    'eslint-comments/no-unlimited-disable': 2,
    'eslint-comments/no-unused-disable': 2,
    'eslint-comments/no-unused-enable': 2,
    'eslint-comments/no-use': [
      2,
      {
        allow: [
          'eslint-disable',
          'eslint-disable-line',
          'eslint-disable-next-line',
          'eslint-enable',
        ],
      },
    ],
    // https://github.com/benmosher/eslint-plugin-import
    'import/order': [
      2,
      {
        groups: [
          'builtin',
          'external',
          'internal',
          ['parent', 'sibling', 'index'],
        ],
        'newlines-between': 'always',
      },
    ],
    'import/prefer-default-export': 0,
    // https://github.com/dustinspecker/eslint-plugin-no-use-extend-native
    'no-use-extend-native/no-use-extend-native': 2,
    // https://github.com/not-an-aardvark/eslint-plugin-prettier
    'prettier/prettier': [
      2,
      {
        useTabs: false,
        printWidth: 80,
        tabWidth: 2,
        singleQuote: true,
        trailingComma: 'all',
        bracketSpacing: false,
        jsxBracketSameLine: false,
        parser: 'babylon',
        semi: true,
      },
    ],
    // https://github.com/xjamundx/eslint-plugin-promise
    'promise/avoid-new': 0,
    'promise/prefer-await-to-callbacks': 0,
    'promise/prefer-await-to-then': 2,
    // https://github.com/sindresorhus/eslint-plugin-unicorn
    'unicorn/catch-error-name': 0,
    'unicorn/custom-error-definition': 0,
    'unicorn/filename-case': 0,
    'unicorn/no-abusive-eslint-disable': 0, // in favor of `eslint-comments/no-unlimited-disable`
    'unicorn/prefer-type-error': 0,
  },
};
<|endoftext|>


<commit_before>'use strict';
var through = require('through2'),
	chalk = require('chalk'),
	gutil = require('gulp-util'),
	fs = require('fs');

module.exports = function () {
	var completedArray  = [];

	return through.obj(transform, finishCount);

	function transform(file, enc, cb) {
		var fileArray = [];

		if(file.isNull()) {
			return cb(null, file);
		}
		var fileContent = file.contents.toString('ascii').split('\n');

		fileContent.forEach(function (line, i) {
			if(line.match(/function\s?\w*\((.)*\)/)) {
				incrementLineCount();
				fileArray.push(new FunctionClass(++i, getFunctionName(line), 0, file.relative));
				return;
			}

			checkLineCharacters(line, i);

			incrementLineCount();
		});

		cb(null, file);

		function getFunctionName(line) {
			var functionName = line.match(/function\s?(\w+)/);
			return functionName !== null ? functionName[1] : 'anonymous';
		}

		function checkLineCharacters(line, i) {
			for(var a = 0; a < line.length; a++) {
				if(line.charAt(a).match(/{/)) {
					fileArray.push('{');
				} else if(line.charAt(a).match(/}/)) {
					popArray(i);
				}
			}
		}

		function popArray(i) {
			var element = fileArray.pop();
			if(element instanceof FunctionClass) {
				element.end = ++i;
				completedArray.push(element);
			}
		}

		function incrementLineCount() {
			fileArray.forEach(function (item) {
				if(item === '{') { return;}
				item.count++;
			});
		}
	}

	function finishCount(cb) {
		var result = calculateResults(),
            converter = new PercentConverter(result.total),
            lines = [
                chalk.underline.bold.magenta('Total Function Sizes'),
                chalk.blue('Function Count:', result.total),
                chalk.red('\t76+ lines:', converter.percent(result.line76)),
                chalk.yellow('51 - 75  lines:', converter.percent(result.line75)),
                chalk.blue('26 - 50  lines:', converter.percent(result.line50)),
                chalk.green(' 1 - 25  lines:', converter.percent(result.line25))
            ];

        lines.forEach(function(line) { gutil.log(line); });
		cb();
	}

	function calculateResults() {
		var result = {
			line25: 0,
			line50: 0,
			line75: 0,
			line76: 0,
			total: 0
		};

		completedArray.forEach(function(item) {
			if(item.count <= 25) {
				result.line25++;
			} else if(item.count <= 50) {
				result.line50++;
			} else if(item.count <= 75) {
				result.line75++;
			} else {
				result.line76++;
			}
			result.total++;
		});

		return result;
	}

    function PercentConverter(total) {
        var _total = total,
            obj = this;

        obj.percent = function(fraction) {
            var percent = Math.round((fraction / _total) * 100);
            return percent < 10 ? '0' + percent + '%' : percent + '%';
        };
    }

	function FunctionClass(lineStart, name, count, fileName) {
		this.lineStart = lineStart;
		this.name = name;
		this.count = count;
		this.fileName = fileName;
	}
};
<commit_msg>Allow matching of single-line functions and functions with space before parenthesis<commit_after>'use strict';
var through = require('through2'),
	chalk = require('chalk'),
	gutil = require('gulp-util'),
	fs = require('fs');

module.exports = function () {
	var completedArray  = [];

	return through.obj(transform, finishCount);

	function transform(file, enc, cb) {
		var fileArray = [];

		if(file.isNull()) {
			return cb(null, file);
		}
		var fileContent = file.contents.toString('ascii').split('\n');

		fileContent.forEach(function (line, i) {
			if(line.match(/function(.)*?\((.)*?\)\s*\{\s*$/)) {
				incrementLineCount();
				fileArray.push(new FunctionClass(++i, getFunctionName(line), 0, file.relative));
				return;
			} else if(line.match(/function(.)*?\((.)*?\)\s*\{(.)*?\}\s*$/)) {
                incrementLineCount();
                completedArray.push(new FunctionClass(i, getFunctionName(line), 1, file.relative));
            } else {
                checkLineCharacters(line, i);
                incrementLineCount();
            }
		});

		cb(null, file);

		function getFunctionName(line) {
			var functionName = line.match(/function\s?(\w+)/);
			return functionName !== null ? functionName[1] : 'anonymous';
		}

		function checkLineCharacters(line, i) {
			for(var a = 0; a < line.length; a++) {
				if(line.charAt(a).match(/{/)) {
					fileArray.push('{');
				} else if(line.charAt(a).match(/}/)) {
					popArray(i);
				}
			}
		}

		function popArray(i) {
			var element = fileArray.pop();
			if(element instanceof FunctionClass) {
				element.end = ++i;
				completedArray.push(element);
			}
		}

		function incrementLineCount() {
			fileArray.forEach(function (item) {
                if(item === '{') { return;}
				item.count++;
			});
		}
	}

	function finishCount(cb) {
		var result = calculateResults(),
            converter = new PercentConverter(result.total),
            lines = [
                chalk.underline.bold.magenta('Total Function Sizes'),
                chalk.blue('Function Count:', result.total),
                chalk.red('\t76+ lines:', converter.percent(result.line76)),
                chalk.yellow('51 - 75  lines:', converter.percent(result.line75)),
                chalk.blue('26 - 50  lines:', converter.percent(result.line50)),
                chalk.green(' 1 - 25  lines:', converter.percent(result.line25))
            ];

        lines.forEach(function(line) { gutil.log(line); });
		cb();
	}

	function calculateResults() {
		var result = {
			line25: 0,
			line50: 0,
			line75: 0,
			line76: 0,
			total: 0
		};

		completedArray.forEach(function(item) {
			if(item.count <= 25) {
				result.line25++;
			} else if(item.count <= 50) {
				result.line50++;
			} else if(item.count <= 75) {
				result.line75++;
			} else {
				result.line76++;
			}
			result.total++;
		});

		return result;
	}

    function PercentConverter(total) {
        var _total = total,
            obj = this;

        obj.percent = function(fraction) {
            var percent = Math.round((fraction / _total) * 100);
            return percent < 10 ? '0' + percent + '%' : percent + '%';
        };
    }

	function FunctionClass(lineStart, name, count, fileName) {
		this.lineStart = lineStart;
		this.name = name;
		this.count = count;
		this.fileName = fileName;
	}
};
<|endoftext|>


<commit_before>var fs = require( 'fs' );
var path = require( 'path' );
var shasum = require( 'shasum' );
var pathMapper = require( 'path-mapper' );
var _ = require( 'underscore' );

var kMetaDataFileName = 'metaData.json';
var kOldPackageMapName = 'package_map.json';

var kMetaDataFormatVersion = 3;

module.exports = CarteroNodeHook;

function CarteroNodeHook( outputDirPath, options ) {
	if( ! ( this instanceof CarteroNodeHook ) ) return new CarteroNodeHook( outputDirPath, options );

	if( outputDirPath === undefined )
		throw new Error( 'outputDirPath is required' );

	options = _.defaults( {}, options, {
		appRootDir : undefined,
		outputDirUrl : '/',
		cache : true
	} );

	this.appRootDir = options.appRootDir;
	this.outputDirPath = path.resolve( path.dirname( require.main.filename ), outputDirPath );
	this.outputDirUrl = options.outputDirUrl;
	this.cache = options.cache;

	this.metaData = this.getMetaData();
	this.parcelAssetsCache = {};
}

CarteroNodeHook.prototype.getTagsForEntryPoint = function( entryPointPath, cb ) {
	var _this = this;

	this.getAssetsForEntryPoint( entryPointPath, function( err, assetUrls ) {
		if( err ) return cb( err );

		var scriptTags = assetUrls.script.map( function( assetPath ) {
			return '<script type="text/javascript" src="' + path.join( _this.outputDirUrl, assetPath ) + '"></script>';
		} ).join( '\n' );

		var styleTags = assetUrls.style.map( function( assetPath ) {
			return '<link rel="stylesheet" href="' + path.join( _this.outputDirUrl, assetPath ) + '"></link>';
		} ).join( '\n' );

		cb( null, scriptTags, styleTags );
	} );
};

CarteroNodeHook.prototype.getAssetsForEntryPoint = function( entryPointPath, cb ) {
	//TODO perhaps impl so entryPointPath can be dir OR path (that may end in an ext such as .js)?
	//if using packageMap instead of entryPoint (with option to be dir or entryPoint):
	//if (path.extname(entryPointPath)) entryPointPath = path.dirname(entryPointPath); //test for an extension
	//var parcelId = this.metaData.packageMap[ _this.getPackageMapKeyFromPath( entryPointPath ) ];
	var _this = this;

	if( ! _this.cache ) this.metaData = this.getMetaData();

	if( ! this.metaData ) {
		return cb( new Error( 'Cartero meta data file could not be read.' ) );
	}

	var parcelId = this.metaData.entryPointMap[ _this.getPackageMapKeyFromPath( entryPointPath ) ];
	if( ! parcelId ) return cb( new Error( 'Could not find assets for entry point with absolute path "' + entryPointPath + '"' ) );

	if( _this.cache && this.parcelAssetsCache[ parcelId ] )
		cb( null, this.parcelAssetsCache[ parcelId ] );
	else {
		fs.readFile( path.join( this.outputDirPath, parcelId, 'assets.json' ), function( err, contents ) {
			if( err ) return cb( err );

			var parcelAssets = JSON.parse( contents );

			if( _this.cache )
				_this.parcelAssetsCache[ parcelId ] = parcelAssets;

			cb( null, parcelAssets );
		} );
	}
};

CarteroNodeHook.prototype.getAssetUrl = function( assetSrcPath, cb ) {
	var _this = this;

	var assetPath = _this.metaData.assetMap && _this.metaData.assetMap[ assetSrcPath ];
  return _this.outputDirUrl && assetPath ? path.join( _this.outputDirUrl, assetPath ) : assetPath;
};

CarteroNodeHook.prototype.getPackageMapKeyFromPath = function( packagePath ) {
	if( this.appRootDir ) return './' + path.relative( this.appRootDir, packagePath );
	else return packagePath;
};

CarteroNodeHook.prototype.getMetaData = function() {
	var _this = this;
	var metaData;

	try {
		var data = fs.readFileSync( path.join( this.outputDirPath, kMetaDataFileName ), 'utf8' );
		metaData = JSON.parse( data );
	} catch( err ) {
		if( fs.existsSync( path.join( this.outputDirPath, kOldPackageMapName ) ) )
			throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook.\n' + err );

		if( _this.cache ) {
			throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. (Have you run cartero yet?)\n' + err );
		} else {
			console.log( 'WARNING: Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. (Have you run cartero yet?)\n' + err );
		}
	}

	if( metaData && metaData.formatVersion < kMetaDataFormatVersion ) {
		throw new Error( 'It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook. Please update your version of cartero to the most recent release.' );
	}

	return metaData;
};
<commit_msg>Fix fn signature, not async<commit_after>var fs = require( 'fs' );
var path = require( 'path' );
var shasum = require( 'shasum' );
var pathMapper = require( 'path-mapper' );
var _ = require( 'underscore' );

var kMetaDataFileName = 'metaData.json';
var kOldPackageMapName = 'package_map.json';

var kMetaDataFormatVersion = 3;

module.exports = CarteroNodeHook;

function CarteroNodeHook( outputDirPath, options ) {
	if( ! ( this instanceof CarteroNodeHook ) ) return new CarteroNodeHook( outputDirPath, options );

	if( outputDirPath === undefined )
		throw new Error( 'outputDirPath is required' );

	options = _.defaults( {}, options, {
		appRootDir : undefined,
		outputDirUrl : '/',
		cache : true
	} );

	this.appRootDir = options.appRootDir;
	this.outputDirPath = path.resolve( path.dirname( require.main.filename ), outputDirPath );
	this.outputDirUrl = options.outputDirUrl;
	this.cache = options.cache;

	this.metaData = this.getMetaData();
	this.parcelAssetsCache = {};
}

CarteroNodeHook.prototype.getTagsForEntryPoint = function( entryPointPath, cb ) {
	var _this = this;

	this.getAssetsForEntryPoint( entryPointPath, function( err, assetUrls ) {
		if( err ) return cb( err );

		var scriptTags = assetUrls.script.map( function( assetPath ) {
			return '<script type="text/javascript" src="' + path.join( _this.outputDirUrl, assetPath ) + '"></script>';
		} ).join( '\n' );

		var styleTags = assetUrls.style.map( function( assetPath ) {
			return '<link rel="stylesheet" href="' + path.join( _this.outputDirUrl, assetPath ) + '"></link>';
		} ).join( '\n' );

		cb( null, scriptTags, styleTags );
	} );
};

CarteroNodeHook.prototype.getAssetsForEntryPoint = function( entryPointPath, cb ) {
	//TODO perhaps impl so entryPointPath can be dir OR path (that may end in an ext such as .js)?
	//if using packageMap instead of entryPoint (with option to be dir or entryPoint):
	//if (path.extname(entryPointPath)) entryPointPath = path.dirname(entryPointPath); //test for an extension
	//var parcelId = this.metaData.packageMap[ _this.getPackageMapKeyFromPath( entryPointPath ) ];
	var _this = this;

	if( ! _this.cache ) this.metaData = this.getMetaData();

	if( ! this.metaData ) {
		return cb( new Error( 'Cartero meta data file could not be read.' ) );
	}

	var parcelId = this.metaData.entryPointMap[ _this.getPackageMapKeyFromPath( entryPointPath ) ];
	if( ! parcelId ) return cb( new Error( 'Could not find assets for entry point with absolute path "' + entryPointPath + '"' ) );

	if( _this.cache && this.parcelAssetsCache[ parcelId ] )
		cb( null, this.parcelAssetsCache[ parcelId ] );
	else {
		fs.readFile( path.join( this.outputDirPath, parcelId, 'assets.json' ), function( err, contents ) {
			if( err ) return cb( err );

			var parcelAssets = JSON.parse( contents );

			if( _this.cache )
				_this.parcelAssetsCache[ parcelId ] = parcelAssets;

			cb( null, parcelAssets );
		} );
	}
};

CarteroNodeHook.prototype.getAssetUrl = function( assetSrcAbsPath) {
	var _this = this;

	var assetPath = _this.metaData.assetMap && _this.metaData.assetMap[ assetSrcAbsPath ];
  return _this.outputDirUrl && assetPath ? path.join( _this.outputDirUrl, assetPath ) : assetPath;
};

CarteroNodeHook.prototype.getPackageMapKeyFromPath = function( packagePath ) {
	if( this.appRootDir ) return './' + path.relative( this.appRootDir, packagePath );
	else return packagePath;
};

CarteroNodeHook.prototype.getMetaData = function() {
	var _this = this;
	var metaData;

	try {
		var data = fs.readFileSync( path.join( this.outputDirPath, kMetaDataFileName ), 'utf8' );
		metaData = JSON.parse( data );
	} catch( err ) {
		if( fs.existsSync( path.join( this.outputDirPath, kOldPackageMapName ) ) )
			throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook.\n' + err );

		if( _this.cache ) {
			throw new Error( 'Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. (Have you run cartero yet?)\n' + err );
		} else {
			console.log( 'WARNING: Error while reading ' + kMetaDataFileName + ' file from ' + this.outputDirPath + '. (Have you run cartero yet?)\n' + err );
		}
	}

	if( metaData && metaData.formatVersion < kMetaDataFormatVersion ) {
		throw new Error( 'It looks like your assets were compiled with an old version of cartero incompatible with this cartero hook. Please update your version of cartero to the most recent release.' );
	}

	return metaData;
};
<|endoftext|>


<commit_before>/*!
 * handlebars-delimiters <https://github.com/jonschlinkert/handlebars-delimiters>
 *
 * Copyright (c) 2014 Jon Schlinkert, contributors.
 * Licensed under the MIT License
 */

'use strict';

module.exports = function(Handlebars, delims) {
  if (delims[0].indexOf('=') === -1) {
    delims[0] = delims[0] + '(?!=)';
  }

  var re = new RegExp(delims[0] + '([\\s\\S]+?)' + delims[1], 'g');

  // Idea for compile method from http://stackoverflow.com/a/19181804/1267639
  if (!Handlebars._compile) {
    Handlebars._compile = Handlebars.compile;
  }

  Handlebars.compile = function() {
    var args = [].slice.call(arguments);

    if (typeof args[0] !== 'string') {
      throw new Error('The first argument must be a string.');
    }

    if(delims[0] !== '{{' && delims[1] !== '}}') {
      args[0] = escapeDelims(args[0], delims);
    }

    var match;
    while (match = re.exec(args[0])) {
      args[0] = args[0].replace(re, '{{' + match[1] + '}}');
    }
    return Handlebars._compile.apply(null, args);
  };
};

var escapeDelims = module.exports.escapeDelims = function(str, delims) {
  var defaults = /\{{([\s\S]+?)}}/ig;
  var match;

  while (match = defaults.exec(str)) {
    str = str.replace(match[0], '\\{{' + match[1] + '}}');
  }
  return str;
};
<commit_msg>remove global flag from the re<commit_after>/*!
 * handlebars-delimiters <https://github.com/jonschlinkert/handlebars-delimiters>
 *
 * Copyright (c) 2014 Jon Schlinkert, contributors.
 * Licensed under the MIT License
 */

'use strict';

module.exports = function(Handlebars, delims) {
  if (delims[0].indexOf('=') === -1) {
    delims[0] = delims[0] + '(?!=)';
  }

  var re = new RegExp(delims[0] + '([\\s\\S]+?)' + delims[1]);

  // Idea for compile method from http://stackoverflow.com/a/19181804/1267639
  if (!Handlebars._compile) {
    Handlebars._compile = Handlebars.compile;
  }

  Handlebars.compile = function() {
    var args = [].slice.call(arguments);

    if (typeof args[0] !== 'string') {
      throw new Error('The first argument must be a string.');
    }

    if(delims[0] !== '{{' && delims[1] !== '}}') {
      args[0] = escapeDelims(args[0], delims);
    }

    var match;
    while (match = re.exec(args[0])) {
      args[0] = args[0].replace(re, '{{' + match[1] + '}}');
    }
    return Handlebars._compile.apply(null, args);
  };
};

var escapeDelims = module.exports.escapeDelims = function(str, delims) {
  var defaults = /\{{([\s\S]+?)}}/ig;
  var match;

  while (match = defaults.exec(str)) {
    str = str.replace(match[0], '\\{{' + match[1] + '}}');
  }
  return str;
};
<|endoftext|>


<commit_before>'use strict'

const inherits = require('util').inherits

module.exports = function(socket, callback) {
  var readLength
  var readCallback
  var readBuffer = []

  socket.on('error', error)
  read(5, onHeader)

  function error(err) {
    socket.removeListener('readable', readable)
    finish(err)
  }

  function finish(err, sn) {
    socket.removeListener('error', error)

    for (var i = readBuffer.length - 1; i >= 0; i--) {
      socket.unshift(readBuffer[i])
    }
    readBuffer = null

    callback(err, sn)
  }

  function read(length, cb) {
    var chunk = socket.read(length)

    if (!chunk) {
      readLength = length
      readCallback = cb
      socket.once('readable', readable)
      return
    }

    // If there is less bytes than requested means EOF.
    // That means we got a protocol error.
    if (chunk.length !== length)
      return error(new ProtocolError())

    readBuffer.push(chunk)
    cb(chunk)
  }

  function readable() {
    read(readLength, readCallback)
  }

  function onHeader(chunk) {
    var pos = 0

    // enum[255] ContentType
    var type = chunk[pos]
    pos += 1

    if (type !== 22) // Not TLS Handshake
      return error(new ProtocolError())

    // ProtocolVersion
    pos += 2 // version

    // uint16 TLSPlaintext.length
    var length = chunk.readUInt16BE(pos)
    pos += 2

    read(length, onFragment)
  }

  function onFragment(chunk) {
    var pos = 0
    var length
    var value

    // enum[255] HandshakeType
    value = chunk[pos]
    pos += 1

    if (value !== 1) // Not ClientHello
      return error(new ProtocolError())

    pos += 3 // Handshake.Length

    pos += 2 // ProtocolVersion
    pos += 28 // Random.random_bytes
    pos += 4 // Random.gmt_unix_time
    pos += 1 + chunk.readUInt8(pos, true) // SessionID
    pos += 2 + chunk.readUInt16BE(pos, true) // CipherSuite
    pos += 1 + chunk.readUInt8(pos, true) // CompressionMethod

    // Check lenghts above
    // Instead of having an if after each length read above, we just ignore
    // oob errors and check it here.
    if (isNaN(pos) || pos > chunk.length)
      return error(new ProtocolError())

    // If this is the end of the chunk, then there is no extensions
    if (chunk.length === pos)
      return finish()

    // Check that there is at least two bytes left
    if (chunk.length < (pos + 2))
      return error(new ProtocolError())

    // Extension extensions<0..2^16-1>
    length = chunk.readUInt16BE(pos)
    pos += 2

    // The rest of the handshake should be extensions
    if (length !== chunk.length - pos)
      return error(new ProtocolError())

    // Loop throught extensions
    while (pos < chunk.length) {
      // enum ExtensionType
      value = chunk.readInt16BE(pos)
      pos += 2

      // uint16 Extension.extension_data.length
      length = chunk.readUInt16BE(pos)
      pos += 2

      // Length can not be bigger than the rest of the packet
      if (length > chunk.length - pos)
        return error(new ProtocolError())

      if (value !== 0) { // some other extension
        pos += length
        continue
      }

      // uint16 ServerNameList.length
      length = chunk.readUInt16BE(pos)
      pos += 2

      // Length can not be bigger than the rest of the packet
      if (length > chunk.length - pos)
        return error(new ProtocolError())

      // enum NameType
      value = chunk[pos]
      pos += 1

      // uint16 HostName.length
      length = chunk.readUInt16BE(pos)
      pos += 2

      // Length can not be bigger than the rest of the packet
      if (length > chunk.length - pos)
        return error(new ProtocolError()) // protocol error

      // Unknown Name Type
      if (value !== 0) {
        pos += length
        continue
      }

      // opaque HostName
      value = chunk.toString('utf8', pos, pos + length)
      return finish(null, value)
    }

    // SNI Not present
    finish()
  }
}

inherits(ProtocolError, Error)
module.exports.ProtocolError = ProtocolError
function ProtocolError() {
  Error.captureStackTrace(this, ProtocolError)
  Error.call(this)
}
<commit_msg>fix test 14<commit_after>'use strict'

const inherits = require('util').inherits

module.exports = function(socket, callback) {
  var readLength
  var readCallback
  var readBuffer = []

  socket.on('error', error)
  read(5, onHeader)

  function error(err) {
    socket.removeListener('readable', readable)
    finish(err)
  }

  function finish(err, sn) {
    socket.removeListener('error', error)

    for (var i = readBuffer.length - 1; i >= 0; i--) {
      socket.unshift(readBuffer[i])
    }
    readBuffer = null

    callback(err, sn)
  }

  function read(length, cb) {
    var chunk = socket.read(length)

    if (!chunk) {
      readLength = length
      readCallback = cb
      socket.once('readable', readable)
      return
    }

    // If there is less bytes than requested means EOF.
    // That means we got a protocol error.
    if (chunk.length !== length)
      return error(new ProtocolError())

    readBuffer.push(chunk)
    cb(chunk)
  }

  function readable() {
    read(readLength, readCallback)
  }

  function onHeader(chunk) {
    var pos = 0

    // enum[255] ContentType
    var type = chunk[pos]
    pos += 1

    if (type !== 22) // Not TLS Handshake
      return error(new ProtocolError())

    // ProtocolVersion
    pos += 2 // version

    // uint16 TLSPlaintext.length
    var length = chunk.readUInt16BE(pos)
    pos += 2

    // We must at least read something
    if (length === 0)
      return error(new ProtocolError())

    read(length, onFragment)
  }

  function onFragment(chunk) {
    var pos = 0
    var length
    var value

    // enum[255] HandshakeType
    value = chunk[pos]
    pos += 1

    if (value !== 1) // Not ClientHello
      return error(new ProtocolError())

    pos += 3 // Handshake.Length

    pos += 2 // ProtocolVersion
    pos += 28 // Random.random_bytes
    pos += 4 // Random.gmt_unix_time
    pos += 1 + chunk.readUInt8(pos, true) // SessionID
    pos += 2 + chunk.readUInt16BE(pos, true) // CipherSuite
    pos += 1 + chunk.readUInt8(pos, true) // CompressionMethod

    // Check lenghts above
    // Instead of having an if after each length read above, we just ignore
    // oob errors and check it here.
    if (isNaN(pos) || pos > chunk.length)
      return error(new ProtocolError())

    // If this is the end of the chunk, then there is no extensions
    if (chunk.length === pos)
      return finish()

    // Check that there is at least two bytes left
    if (chunk.length < (pos + 2))
      return error(new ProtocolError())

    // Extension extensions<0..2^16-1>
    length = chunk.readUInt16BE(pos)
    pos += 2

    // The rest of the handshake should be extensions
    if (length !== chunk.length - pos)
      return error(new ProtocolError())

    // Loop throught extensions
    while (pos < chunk.length) {
      // enum ExtensionType
      value = chunk.readInt16BE(pos)
      pos += 2

      // uint16 Extension.extension_data.length
      length = chunk.readUInt16BE(pos)
      pos += 2

      // Length can not be bigger than the rest of the packet
      if (length > chunk.length - pos)
        return error(new ProtocolError())

      if (value !== 0) { // some other extension
        pos += length
        continue
      }

      // uint16 ServerNameList.length
      length = chunk.readUInt16BE(pos)
      pos += 2

      // Length can not be bigger than the rest of the packet
      if (length > chunk.length - pos)
        return error(new ProtocolError())

      // enum NameType
      value = chunk[pos]
      pos += 1

      // uint16 HostName.length
      length = chunk.readUInt16BE(pos)
      pos += 2

      // Length can not be bigger than the rest of the packet
      if (length > chunk.length - pos)
        return error(new ProtocolError()) // protocol error

      // Unknown Name Type
      if (value !== 0) {
        pos += length
        continue
      }

      // opaque HostName
      value = chunk.toString('utf8', pos, pos + length)
      return finish(null, value)
    }

    // SNI Not present
    finish()
  }
}

inherits(ProtocolError, Error)
module.exports.ProtocolError = ProtocolError
function ProtocolError() {
  Error.captureStackTrace(this, ProtocolError)
  Error.call(this)
}
<|endoftext|>


<commit_before>var util = require('util');
var urlLib = require('url');

var async = require('async');
var request = require('request');
var cheerio = require('cheerio');
var Bitly = require('bitly');

var log = require('logmagic').local('treslek.plugins.url');
var config = require('./config.json');

request = request.defaults({
  sendImmediately: true,
  timeout: 10000,
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36"
  }
});

/*
 * URL plugin
 *   - creates a hook that checks for urls. It then grabs the title
 *     and outputs that to the channel.
 *   Thanks to https://github.com/Floobits/floobot for scraping logic
 */
var Url = function() {
  this.hooks = ['url'];
};

/*
 * Helper function for shortening a url with bitly.
 */
var shortenUrl = function(bitly, url, callback) {
  if (!bitly) {
    callback(null, url);
    return;
  }

  bitly.shorten(url, function(err, resp) {
    if (err) {
      log.error('Error shortening url', {err: err, url: url});
      callback(err);
      return;
    }

    callback(null, resp.data.url || url);
  });
};

function parseYoutube(path, parsed) {
  var title, views, likes, dislikes, rating;

  if (path.match(/^\/watch/) === null) {
    return;
  }

  title = parsed('#eow-title').text().replace(/\n/g, '').replace(/^\s+/, '').replace(/\s+$/, '');
  views = parsed('#watch7-views-info > div.watch-view-count').text().replace(/[\s]/g, '') || 0;
  likes = parsed('#watch-like > span.yt-uix-button-content').text().replace(/[\s,]/g, '') || 0;
  dislikes = parsed('#watch-dislike > span.yt-uix-button-content').text().replace(/[\s,]/g, '') || 0;
  likes = parseInt(likes, 10);
  dislikes = parseInt(dislikes, 10);
  console.log(likes, dislikes);
  rating = Math.round(100 * likes / (likes + dislikes));

  return util.format("%s | %s views %s%% like", title, views, rating);
}

function parseTwitter(path, parsed) {
  var user, title, retweets, favorites;

  if (path.match("^\\/\\w+\\/status\\/\\d+") === null) {
    return;
  }

  user = parsed("div.permalink-tweet-container div.permalink-header a > span.username.js-action-profile-name > b").text();
  title = parsed("div.permalink-tweet-container p.tweet-text").text().replace(/\n/g, '').replace(/^\s+/, '').replace(/\s+$/, '');
  retweets = parsed("div.tweet-stats-container > ul.stats > li.js-stat-count.js-stat-retweets.stat-count > a > strong").text().replace(/\s/g, "") || 0;
  favorites = parsed("div.tweet-stats-container > ul.stats > li.js-stat-count.js-stat-favorites.stat-count > a > strong").text().replace(/\s/g, "") || 0;

  return util.format("<@%s> %s (%s retweets, %s favorites)", user, title, retweets, favorites);
}

/*
 * URL hook.
 *   Searchs a message for any urls, and then request each url.
 *   If the url returns a content-type of 'text/html', attempt
 *   to get the page title. If not, return the content type. If
 *   bitly is configured, shorten urls as well.
 */
Url.prototype.url = function(bot, to, from, msg, callback) {
  var urlReg = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi,
      matches = msg.match(urlReg),
      bitly;

  if (!matches) {
    callback();
    return;
  }

  if (config.bitlyUser !== '' && config.bitlyApiKey !== '') {
    bitly = new Bitly(config.bitlyUser, config.bitlyApiKey);
  }

  async.forEach(matches, function(url, callback) {
    request(url, function(err, res, body) {
      var response,
          parsed,
          parsedUrl,
          title,
          contentType;

      if (err || res.statusCode === 404) {
        if (err) {
          log.error('Error retrieving url', {url: url, err: err});
          callback();
          return;
        } else {
          log.error('Error retrieving url. Got response.', {url: url, err: err});
          callback();
          return;
        }
      }

      if (res.statusCode === 200) {
        contentType = res.headers['content-type'].split(';')[0];
        if (contentType !== 'text/html') {
          title = contentType;
        } else {
          parsed = cheerio.load(body);
          title = parsed('title').text().replace(/\n/g, '').replace(/^\s+/, '');
        }
      }

      title = title || contentType;

      shortenUrl(bitly, url, function(err, shortUrl) {
        parsedUrl = urlLib.parse(url);
        domain = parsedUrl.hostname.split('.').slice(-2).join('.');
        if (domain === 'youtube.com') {
          response = parseYoutube(parsedUrl.path, parsed) + ' | ' + shortUrl;
        } else if (domain === 'twitter.com') {
          response = parseTwitter(parsedUrl.path, parsed) + ' | ' + shortUrl;
        } else {
          response = title + ' | ' + shortUrl;
        }
        bot.say(to, response);
        callback();
      });

    });
  }, callback);
};

exports.Plugin = Url;
<commit_msg>Replace newlines with spaces.<commit_after>var util = require('util');
var urlLib = require('url');

var async = require('async');
var request = require('request');
var cheerio = require('cheerio');
var Bitly = require('bitly');

var log = require('logmagic').local('treslek.plugins.url');
var config = require('./config.json');

request = request.defaults({
  sendImmediately: true,
  timeout: 10000,
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36"
  }
});

/*
 * URL plugin
 *   - creates a hook that checks for urls. It then grabs the title
 *     and outputs that to the channel.
 *   Thanks to https://github.com/Floobits/floobot for scraping logic
 */
var Url = function() {
  this.hooks = ['url'];
};

/*
 * Helper function for shortening a url with bitly.
 */
var shortenUrl = function(bitly, url, callback) {
  if (!bitly) {
    callback(null, url);
    return;
  }

  bitly.shorten(url, function(err, resp) {
    if (err) {
      log.error('Error shortening url', {err: err, url: url});
      callback(err);
      return;
    }

    callback(null, resp.data.url || url);
  });
};

function parseYoutube(path, parsed) {
  var title, views, likes, dislikes, rating;

  if (path.match(/^\/watch/) === null) {
    return;
  }

  title = parsed('#eow-title').text().replace(/\n/g, ' ').replace(/^\s+/, '').replace(/\s+$/, '');
  views = parsed('#watch7-views-info > div.watch-view-count').text().replace(/[\s]/g, '') || 0;
  likes = parsed('#watch-like > span.yt-uix-button-content').text().replace(/[\s,]/g, '') || 0;
  dislikes = parsed('#watch-dislike > span.yt-uix-button-content').text().replace(/[\s,]/g, '') || 0;
  likes = parseInt(likes, 10);
  dislikes = parseInt(dislikes, 10);
  console.log(likes, dislikes);
  rating = Math.round(100 * likes / (likes + dislikes));

  return util.format("%s | %s views %s%% like", title, views, rating);
}

function parseTwitter(path, parsed) {
  var user, title, retweets, favorites;

  if (path.match("^\\/\\w+\\/status\\/\\d+") === null) {
    return;
  }

  user = parsed("div.permalink-tweet-container div.permalink-header a > span.username.js-action-profile-name > b").text();
  title = parsed("div.permalink-tweet-container p.tweet-text").text().replace(/\n/g, ' ').replace(/^\s+/, '').replace(/\s+$/, '');
  retweets = parsed("div.tweet-stats-container > ul.stats > li.js-stat-count.js-stat-retweets.stat-count > a > strong").text().replace(/\s/g, "") || 0;
  favorites = parsed("div.tweet-stats-container > ul.stats > li.js-stat-count.js-stat-favorites.stat-count > a > strong").text().replace(/\s/g, "") || 0;

  return util.format("<@%s> %s (%s retweets, %s favorites)", user, title, retweets, favorites);
}

/*
 * URL hook.
 *   Searchs a message for any urls, and then request each url.
 *   If the url returns a content-type of 'text/html', attempt
 *   to get the page title. If not, return the content type. If
 *   bitly is configured, shorten urls as well.
 */
Url.prototype.url = function(bot, to, from, msg, callback) {
  var urlReg = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi,
      matches = msg.match(urlReg),
      bitly;

  if (!matches) {
    callback();
    return;
  }

  if (config.bitlyUser !== '' && config.bitlyApiKey !== '') {
    bitly = new Bitly(config.bitlyUser, config.bitlyApiKey);
  }

  async.forEach(matches, function(url, callback) {
    request(url, function(err, res, body) {
      var response,
          parsed,
          parsedUrl,
          title,
          contentType;

      if (err || res.statusCode === 404) {
        if (err) {
          log.error('Error retrieving url', {url: url, err: err});
          callback();
          return;
        } else {
          log.error('Error retrieving url. Got response.', {url: url, err: err});
          callback();
          return;
        }
      }

      if (res.statusCode === 200) {
        contentType = res.headers['content-type'].split(';')[0];
        if (contentType !== 'text/html') {
          title = contentType;
        } else {
          parsed = cheerio.load(body);
          title = parsed('title').text().replace(/\n/g, ' ').replace(/^\s+/, '');
        }
      }

      title = title || contentType;

      shortenUrl(bitly, url, function(err, shortUrl) {
        parsedUrl = urlLib.parse(url);
        domain = parsedUrl.hostname.split('.').slice(-2).join('.');
        if (domain === 'youtube.com') {
          response = parseYoutube(parsedUrl.path, parsed) + ' | ' + shortUrl;
        } else if (domain === 'twitter.com') {
          response = parseTwitter(parsedUrl.path, parsed) + ' | ' + shortUrl;
        } else {
          response = title + ' | ' + shortUrl;
        }
        bot.say(to, response);
        callback();
      });

    });
  }, callback);
};

exports.Plugin = Url;
<|endoftext|>


<commit_before>/* global Promise */
var postcss = require('postcss');

function indentResolve(str, options) {
    if (options.length === undefined) {
        if (str.match(/\n(?!\n)\s*/g) === null) {
            return str;
        }

        options.length = Math.min.apply(Math, str.match(/\n(?!\n)\s*/g).filter(function(space) {
            return space.length > 2;
        }).map(function(space) {
            return space.length;
        }));

        options.match = new Array(options.length).join(' ');
        str = str.replace(new RegExp(options.match,'g'), '');
    } else {
        str = str.replace(/\n/g, '\n' + options.match);
    }

    return str;
}

module.exports = function(plugins, options) {
    plugins = [].concat(plugins);
    options = options || {};

    var css = postcss(plugins);

    return function posthtmlPostcss(tree) {
        var promises = [];

        tree.walk(function(node) {
            var promise,
                indent = {
                type: 'space',
                length: undefined,
                match: ''
            };

            if (node.tag === 'style' && node.content) {
                var styles = indentResolve([].concat(node.content).join(''), indent);
                promise = css.process(styles, options)
                    .then(function(result) {
                        node.content = indentResolve(result.css, indent);
                    });

                promises.push(promise);
            }

            if (node.attrs && node.attrs.style) {
                promise = css.process(node.attrs.style, options)
                    .then(function(result) {
                        node.attrs.style = result.css;
                    });

                promises.push(promise);
            }

            return node;
        });

        return Promise.all(promises).then(function() {
            return tree;
        });
    };
};
<commit_msg>fixed incorrect resolve because of last line<commit_after>/* global Promise */
var postcss = require('postcss');

function indentResolve(str, options) {
    if (options.length === undefined) {
        if (str.match(/\n(?!\n)\s*/g) === null) {
            return str;
        }

        options.lastLine = str.substr(str.lastIndexOf('\n') + 1);
        str = str.substr(0, str.lastIndexOf('\n') + 1);
        options.length = Math.min.apply(Math, str.match(/\n(?!\n)\s*/g).filter(function(space) {
            return space.length > 2;
        }).map(function(space) {
            return space.length;
        }));

        options.match = new Array(options.length).join(' ');
        str = str.replace(new RegExp(options.match,'g'), '');
    } else {
        str = str.replace(/\n/g, '\n' + options.match);
        str = str.substr(0, str.lastIndexOf('\n') + 1) + options.lastLine;
    }
    return str;
}

module.exports = function(plugins, options) {
    plugins = [].concat(plugins);
    options = options || {};

    var css = postcss(plugins);

    return function posthtmlPostcss(tree) {
        var promises = [];

        tree.walk(function(node) {
            var promise,
                indent = {
                type: 'space',
                length: undefined,
                match: '',
                lastLine: ''
            };

            if (node.tag === 'style' && node.content) {
                var styles = indentResolve([].concat(node.content).join(''), indent);
                promise = css.process(styles, options)
                    .then(function(result) {
                        node.content = indentResolve(result.css, indent);
                    });

                promises.push(promise);
            }

            if (node.attrs && node.attrs.style) {
                promise = css.process(node.attrs.style, options)
                    .then(function(result) {
                        node.attrs.style = result.css;
                    });

                promises.push(promise);
            }

            return node;
        });

        return Promise.all(promises).then(function() {
            return tree;
        });
    };
};
<|endoftext|>