<commit_before>'use strict';

const EventEmitter = require('events').EventEmitter;
const ANY_EVENT = 0xFF; // A representative for any event

class ExecStack {

    /**
     * @author schroffl
     *
     * @constructor
     *
     * @returns A new instance of ExecStack
     */

    constructor() {
        this._stack = [];
    }

    /**
     * Push a middleware to the stack
     *
     * @author schroffl
     *
     * @param {String} [event=ANY_EVENT] - The specific event to listen for
     * @param {Function} callback - A function to be called on execution of the stack
     *
     * @returns The position of the middleware in the stack
     */

    use() {
        const args = Array.from(arguments);

        let event = typeof args[0] === 'function' ? ANY_EVENT : args.shift(),
            callback = typeof args[0] === 'function' ? args.shift() : () => {};

        return this._stack.push({ event, callback });
    }

    /**
     * Remove a middleware from the stack
     *
     * @author schroffl
     *
     * @param {Number} position - The position of the middleware in the stack
     */

    unuse() {
        this._stack.splice(arguments[0], 1);
    }

    /**
     * Execute the stack
     *
     * @author schroffl
     *
     * @param {String} [event=ANY_EVENT] - The event to propagate
     *
     * @returns A promise being resolved when the stack has been fully traversed
     */

    run() {
        const args = Array.from(arguments),
              controller = new EventEmitter();

        let event = typeof args[0] === 'function' ? ANY_EVENT : args.shift(),
            resolve = null,
            reject = null,
            promise = new Promise((res, rej) => {
                resolve = res;
                reject = rej;
            });

        controller.on('next', i => {
            let current = this._stack[i];

            // If i exceeds the amount of functions on the stack => abort
            if(i > this._stack.length)
                return resolve();
            else if(!current)
                return controller.emit('next', i + 1);
            // If the middleware is neither listening for all events nor the specified one => continue
            else if(current.event !== ANY_EVENT && current.event !== event)
                return controller.emit('next', i + 1);

            let passArgs = args.slice();

            // If the middleware is listening for all events tell it what it's getting notified about
            if(current.event === ANY_EVENT) passArgs.unshift(event);

            const next = () => controller.emit('next', i + 1);
            next.throw = err => reject(err);

            // Push the "next" function
            passArgs.push(next);

            current.callback.apply({}, passArgs);
        });

        // Start the snowball
        controller.emit('next', 0);

        return promise;
    }
}

module.exports = ExecStack;<commit_msg>Promise resolves with passed arguments<commit_after>'use strict';

const EventEmitter = require('events').EventEmitter;
const ANY_EVENT = 0xFF; // A representative for any event

class ExecStack {

    /**
     * @author schroffl
     *
     * @constructor
     *
     * @returns A new instance of ExecStack
     */

    constructor() {
        this._stack = [];
        this._context = {};
    }

    /**
     * Set the context to be applied to middleware
     *
     * @author schroffl
     *
     * @param {Object} [context={}] - The context to be applied to middleware
     */

    context(context) {
        // Clear to context to an empty object if the parameter is ommitted
        this._context = typeof context === 'object' ? context : {};
        return this;
    }

    /**
     * Push a middleware to the stack
     *
     * @author schroffl
     *
     * @param {String} [event=ANY_EVENT] - The specific event to listen for
     * @param {Function} callback - A function to be called on execution of the stack
     *
     * @returns The position of the middleware in the stack
     */

    use() {
        const args = Array.from(arguments);

        let event = typeof args[0] === 'function' ? ANY_EVENT : args.shift(),
            callback = typeof args[0] === 'function' ? args.shift() : () => {};

        return this._stack.push({ event, callback });
    }

    /**
     * Remove a middleware from the stack
     *
     * @author schroffl
     *
     * @param {Number} position - The position of the middleware in the stack
     */

    unuse() {
        this._stack.splice(arguments[0], 1);
    }

    /**
     * Execute the stack
     *
     * @author schroffl
     *
     * @param {String} [event=ANY_EVENT] - The event to propagate
     *
     * @returns A promise being resolved when the stack has been fully traversed
     */

    run() {
        const args = Array.from(arguments),
              controller = new EventEmitter();

        let event = typeof args[0] === 'function' ? ANY_EVENT : args.shift();

        return new Promise((resolve, reject) => {
            controller.on('next', i => {
                let current = this._stack[i];

                // If i exceeds the amount of functions on the stack and none has thrown => resolve
                if(i > this._stack.length)
                    return resolve({ event, 'arguments': args.slice() });
                // current is undefined ?! => continue
                else if(!current)
                    return controller.emit('next', i + 1);
                // If the middleware is neither listening for all events nor the specified one => continue
                else if(current.event !== ANY_EVENT && current.event !== event)
                    return controller.emit('next', i + 1);

                let passArgs = args.slice();

                // If the middleware is listening for all events tell it what it's getting notified about
                if(current.event === ANY_EVENT) passArgs.unshift(event);

                const next = () => controller.emit('next', i + 1);
                next.throw = err => reject(err);

                // Push the "next" function
                passArgs.push(next);

                current.callback.apply(this._context, passArgs);
            });

            // Start the snowball
            controller.emit('next', 0);
        });
    }
}

module.exports = ExecStack;<|endoftext|>


<commit_before>
var storage = {};

module.exports = function(key, value) {
	if(!value) return getter(key);
	setter(key, value);
};

function setter(key, value) {
	var model = storage[key] || factory(key, value);
	var nb =  (model.values[value] || 0) + 1;
	model.values[value] = nb;
	var max = model.values[model.entity];
	if(nb > max) storage[key].entity = value;
}

function factory(key, value) {
	var model = {
		entity: value,
		values: {}
	};
	storage[key] = model;
	return model;
}

function getter(key) {
	return storage[key].entity;
}
<commit_msg>add documentation<commit_after>
var storage = {};

/**
 * Predictive analytics.
 *
 * Examples:
 *
 *   intuit('glasses', 'view');
 *   intuit('glasses', 'sun');
 *   intuit('glasses', 'sun');
 *
 *   intuit('glasses');
 *   //=> sun
 *
 * @param  {String} key
 * @param  {Atring} value
 * @return {String}
 * @api public
 */

module.exports = function(key, value) {
	if(!value) return storage[key].entity
	setter(key, value);
};

/**
 * Setter.
 *
 * Increment the number of times a value
 * has been set and also calculate the preferred
 * value.
 *
 * @param  {String} key
 * @param  {String} value
 * @api private
 */

function setter(key, value) {
	var model = storage[key] || factory(key, value);
	var nb =  (model.values[value] || 0) + 1;
	model.values[value] = nb;
	if(nb > model.values[model.entity]) storage[key].entity = value;
}

/**
 * Create data representation of
 * and unknown key.
 *
 * @param  {String} key
 * @param  {String} value
 * @return {Object}
 * @api private
 */

function factory(key, value) {
	var model = {
		entity: value,
		values: {}
	};
	storage[key] = model;
	return model;
}

<|endoftext|>


<commit_before>const crypto = require('crypto'),
    debug = require('debug'),
    minimatch = require('minimatch'),
    path = require('path');

const defaultOptions = {
    algo: 'sha1',       // see crypto.getHashes() for options
    encoding: 'base64', // 'base64', 'hex' or 'binary'
    files: {
        exclude: [],
        include: [],
        matchBasename: true,
        matchPath: false,
        ignoreBasename: false,
        ignoreRootName: false
    },
    folders: {
        exclude: [],
        include: [],
        matchBasename: true,
        matchPath: false,
        ignoreBasename: false,
        ignoreRootName: false
    },
    symbolicLinks: {
        follow: 'resolve', // 'resolve', 'ignore-target-content', 'skip'
        ignoreBasename: false,
        hashTargetPath: false,
        // the following only have an effect if follow == 'resolve'
        ignoreMissingTarget: false,
        ignoreAllErrors: false
    }
};

// Use the environment variable DEBUG to log output, e.g. `set DEBUG=fhash:*`
const log = {
    match: debug('fhash:match'),
    params: (params) => {
        debug('fhash:parameters')(params);
        return params;
    },
    err: debug('fhash:err'),
    symlink: debug('fhash:symlink')
};

function prep(fs) {
    function hashElement(name, dir, options, callback) {
        callback = arguments[arguments.length - 1];

        return parseParameters(arguments)
            .then(({ basename, dir, options }) => {
                // this is only used for the root level
                options.skipMatching = true;
                return fs.promises.lstat(path.join(dir, basename))
                    .then(stats => { stats.name = basename; return stats; })
                    .then(stats => hashElementPromise(stats, dir, options, true));
            })
            .then(result => {
                if (isFunction(callback)) {
                    return callback(undefined, result);
                } else {
                    return result;
                }
            })
            .catch(reason => {
                log.err('Fatal error:', reason);
                if (isFunction(callback)) {
                    return callback(reason);
                } else {
                    throw reason;
                }
            });
    }

    /**
     * @param {fs.Stats} stats folder element, can also be of type fs.Dirent
     * @param {string} dirname
     * @param {Options} options
     * @param {boolean} isRootElement
     */
    function hashElementPromise(stats, dirname, options, isRootElement = false) {
        const name = stats.name;
        if (stats.isDirectory()) {
            return hashFolderPromise(name, dirname, options, isRootElement);
        } else if (stats.isFile()) {
            return hashFilePromise(name, dirname, options, isRootElement);
        } else if (stats.isSymbolicLink()) {
            return hashSymLinkPromise(name, dirname, options, isRootElement);
        } else {
            log.err('hashElementPromise cannot handle ', stats);
            return { name, hash: 'Error: unknown element type' };
        }
    }

    function hashFolderPromise(name, dir, options, isRootElement = false) {
        const folderPath = path.join(dir, name);
        let ignoreBasenameOnce = options.ignoreBasenameOnce;
        delete options.ignoreBasenameOnce;

        if (options.skipMatching) {
            // this is currently only used for the root folder
            log.match(`skipped '${folderPath}'`);
            delete options.skipMatching;
        } else if (ignore(name, folderPath, options.folders)) {
            return undefined;
        }

        return fs.promises.readdir(folderPath, { withFileTypes: true }).then(files => {
            const children = files.sort().map(child => {
                return hashElementPromise(child, folderPath, options);
            });

            return Promise.all(children).then(children => {
                if (ignoreBasenameOnce) options.ignoreBasenameOnce = true;
                const hash = new HashedFolder(name, children.filter(notUndefined), options, isRootElement);
                return hash;
            });
        });
    }

    function hashFilePromise(name, dir, options, isRootElement = false) {
        const filePath = path.join(dir, name);

        if (options.skipMatching) {
            // this is currently only used for the root folder
            log.match(`skipped '${filePath}'`);
            delete options.skipMatching;
        } else if (ignore(name, filePath, options.files)) {
            return undefined;
        }

        return new Promise((resolve, reject) => {
            try {
                const hash = crypto.createHash(options.algo);
                if (options.files.ignoreBasename ||
                    options.ignoreBasenameOnce ||
                    (isRootElement && options.files.ignoreRootName))
                {
                    delete options.ignoreBasenameOnce;
                    log.match(`omitted name of ${filePath} from hash`)
                } else {
                    hash.update(name);
                }

                const f = fs.createReadStream(filePath);
                f.pipe(hash, { end: false });

                f.on('end', () => {
                    const hashedFile = new HashedFile(name, hash, options.encoding);
                    return resolve(hashedFile);
                });
            } catch (ex) {
                return reject(ex);
            }
        });
    }

    async function hashSymLinkPromise(name, dir, options, isRootElement = false) {
        const target = await fs.promises.readlink(path.join(dir, name));
        log.symlink(`handling symbolic link ${name} -> ${target}`);
        switch (options.symbolicLinks.follow) {
            case 'skip':
                log.symlink('skipping symbolic link');
                return Promise.resolve(undefined);

            case 'ignore-target-content':
                return symLinkIgnoreTargetContent(name, target, options, isRootElement);

            case 'resolve':
                return symLinkResolve(name, dir, target, options, isRootElement);

            default:
                throw `Invalid option: symbolicLinks.follow = "${options.symbolicLinks.follow}"`;
        }
    }

    function symLinkIgnoreTargetContent(name, target, options, isRootElement) {
        delete options.skipMatching // only used for the root level
        log.symlink('ignoring symbolic link target content');
        const hash = crypto.createHash(options.algo);
        if (!options.symbolicLinks.ignoreBasename &&
            !(isRootElement && options.files.ignoreRootName)) {
            log.symlink('hash basename');
            hash.update(name);
        }
        if (options.symbolicLinks.hashTargetPath) {
            log.symlink('hash targetpath');
            hash.update(target);
        }
        return Promise.resolve(new HashedFile(name, hash, options.encoding));
    }

    async function symLinkResolve(name, dir, target, options, isRootElement) {
        delete options.skipMatching // only used for the root level
        if (options.symbolicLinks.ignoreBasename) {
            options.ignoreBasenameOnce = true;
        }

        try {
            const stats = await fs.promises.stat(path.join(dir, name));
            stats.name = name;
            const temp = await hashElementPromise(stats, dir, options, isRootElement);

            if (options.symbolicLinks.hashTargetPath) {
                const hash = crypto.createHash(options.algo);
                hash.update(temp.hash);
                log.symlink('hash targetpath');
                hash.update(target);
                temp.hash = hash.digest(options.encoding);
            }
            return temp;
        } catch (err) {
            if ((err.code === 'ENOENT' && options.symbolicLinks.ignoreMissingTarget) ||
                options.symbolicLinks.ignoreAllErrors)
            {
                log.symlink(`Ignoring error "${err.code}" when hashing symbolic link ${name}`, err);
                const hash = crypto.createHash(options.algo);
                if (!options.symbolicLinks.ignoreBasename &&
                    !(isRootElement && options.files.ignoreRootName)) {
                    hash.update(name);
                }
                if (options.symbolicLinks.hashTargetPath) {
                    hash.update(target);
                }
                return new HashedFile(name, hash, options.encoding);
            } else {
                log.symlink(`Error "${err.code}": When hashing symbolic link ${name}`, err);
                throw err;
            }
        }
    }

    function ignore(name, path, rules) {
        if (rules.exclude) {
            if (rules.matchBasename && rules.exclude(name)) {
                log.match(`exclude basename '${path}'`);
                return true;
            } else if (rules.matchPath && rules.exclude(path)) {
                log.match(`exclude path '${path}'`);
                return true;
            }
        } else if (rules.include) {
            if (rules.matchBasename && rules.include(name)) {
                log.match(`include basename '${path}'`);
                return false;
            } else if (rules.matchPath && rules.include(path)) {
                log.match(`include path '${path}'`);
                return false;
            } else {
                return true;
            }
        }

        log.match(`Will not ignore unmatched '${path}'`);
        return false;
    }

    const HashedFolder = function HashedFolder(name, children, options, isRootElement = false) {
        this.name = name;
        this.children = children;

        const hash = crypto.createHash(options.algo);
        if (options.folders.ignoreBasename ||
            options.ignoreBasenameOnce ||
            (isRootElement && options.folders.ignoreRootName))
        {
            delete options.ignoreBasenameOnce;
            log.match(`omitted name of folder ${name} from hash`)
        } else {
            hash.update(name);
        }
        children.forEach(child => {
            if (child.hash) {
                hash.update(child.hash);
            }
        });

        this.hash = hash.digest(options.encoding);
    };

    HashedFolder.prototype.toString = function (padding = '') {
        const first = `${padding}{ name: '${this.name}', hash: '${this.hash},'\n`;
        padding += '  ';

        return `${first}${padding}children: ${this.childrenToString(padding)}}`;
    };

    HashedFolder.prototype.childrenToString = function (padding = '') {
        if (this.children.length === 0) {
            return '[]';
        } else {
            const nextPadding = padding + '  ';
            const children = this.children
                .map(child => child.toString(nextPadding))
                .join('\n');
            return `[\n${children}\n${padding}]`;
        }
    };

    const HashedFile = function HashedFile(name, hash, encoding) {
        this.name = name;
        this.hash = hash.digest(encoding);
    };

    HashedFile.prototype.toString = function (padding = '') {
        return padding + '{ name: \'' + this.name + '\', hash: \'' + this.hash + '\' }';
    };

    return hashElement;
}

function parseParameters(args) {
    let basename = args[0],
        dir = args[1],
        options_ = args[2];

    if (!isString(basename)) {
        return Promise.reject(new TypeError('First argument must be a string'));
    }

    if (!isString(dir)) {
        dir = path.dirname(basename);
        basename = path.basename(basename);
        options_ = args[1];
    }

    // parse options (fallback default options)
    if (!isObject(options_)) options_ = {};
    const options = {
        algo: options_.algo || defaultOptions.algo,
        encoding: options_.encoding || defaultOptions.encoding,
        files: Object.assign({}, defaultOptions.files, options_.files),
        folders: Object.assign({}, defaultOptions.folders, options_.folders),
        match: Object.assign({}, defaultOptions.match, options_.match),
        symbolicLinks: Object.assign({}, defaultOptions.symbolicLinks, options_.symbolicLinks)
    };

    // transform match globs to Regex
    options.files.exclude = reduceGlobPatterns(options.files.exclude);
    options.files.include = reduceGlobPatterns(options.files.include);
    options.folders.exclude = reduceGlobPatterns(options.folders.exclude);
    options.folders.include = reduceGlobPatterns(options.folders.include);

    return Promise.resolve(log.params({ basename, dir, options }));
}

function isFunction(any) {
    return typeof any === 'function';
}

function isString(str) {
    return typeof str === 'string' || str instanceof String;
}

function isObject(obj) {
    return obj !== null && typeof obj === 'object';
}

function notUndefined(obj) {
    return typeof obj !== 'undefined';
}

function reduceGlobPatterns(globs) {
    if (isFunction(globs)) {
      return globs;
    }
    else if (!globs || !Array.isArray(globs) || globs.length === 0) {
        return undefined;
    } else {
        // combine globs into one single RegEx
        const regex = new RegExp(globs.reduce((acc, exclude) => {
            return acc + '|' + minimatch.makeRe(exclude).source;
        }, '').substr(1));
        return param => regex.test(param);
    }
}

module.exports = {
    defaults: defaultOptions,
    hashElement: prep(require('graceful-fs')),
    // exposed for testing
    prep,
    parseParameters
};
<commit_msg>Extract HashedFile and HashedFolder from closure<commit_after>const crypto = require('crypto'),
    debug = require('debug'),
    minimatch = require('minimatch'),
    path = require('path');

const defaultOptions = {
    algo: 'sha1',       // see crypto.getHashes() for options
    encoding: 'base64', // 'base64', 'hex' or 'binary'
    files: {
        exclude: [],
        include: [],
        matchBasename: true,
        matchPath: false,
        ignoreBasename: false,
        ignoreRootName: false
    },
    folders: {
        exclude: [],
        include: [],
        matchBasename: true,
        matchPath: false,
        ignoreBasename: false,
        ignoreRootName: false
    },
    symbolicLinks: {
        follow: 'resolve', // 'resolve', 'ignore-target-content', 'skip'
        ignoreBasename: false,
        hashTargetPath: false,
        // the following only have an effect if follow == 'resolve'
        ignoreMissingTarget: false,
        ignoreAllErrors: false
    }
};

// Use the environment variable DEBUG to log output, e.g. `set DEBUG=fhash:*`
const log = {
    match: debug('fhash:match'),
    params: (params) => {
        debug('fhash:parameters')(params);
        return params;
    },
    err: debug('fhash:err'),
    symlink: debug('fhash:symlink')
};

function prep(fs) {
    function hashElement(name, dir, options, callback) {
        callback = arguments[arguments.length - 1];

        return parseParameters(arguments)
            .then(({ basename, dir, options }) => {
                // this is only used for the root level
                options.skipMatching = true;
                return fs.promises.lstat(path.join(dir, basename))
                    .then(stats => { stats.name = basename; return stats; })
                    .then(stats => hashElementPromise(stats, dir, options, true));
            })
            .then(result => {
                if (isFunction(callback)) {
                    return callback(undefined, result);
                } else {
                    return result;
                }
            })
            .catch(reason => {
                log.err('Fatal error:', reason);
                if (isFunction(callback)) {
                    return callback(reason);
                } else {
                    throw reason;
                }
            });
    }

    /**
     * @param {fs.Stats} stats folder element, can also be of type fs.Dirent
     * @param {string} dirname
     * @param {Options} options
     * @param {boolean} isRootElement
     */
    function hashElementPromise(stats, dirname, options, isRootElement = false) {
        const name = stats.name;
        if (stats.isDirectory()) {
            return hashFolderPromise(name, dirname, options, isRootElement);
        } else if (stats.isFile()) {
            return hashFilePromise(name, dirname, options, isRootElement);
        } else if (stats.isSymbolicLink()) {
            return hashSymLinkPromise(name, dirname, options, isRootElement);
        } else {
            log.err('hashElementPromise cannot handle ', stats);
            return { name, hash: 'Error: unknown element type' };
        }
    }

    function hashFolderPromise(name, dir, options, isRootElement = false) {
        const folderPath = path.join(dir, name);
        let ignoreBasenameOnce = options.ignoreBasenameOnce;
        delete options.ignoreBasenameOnce;

        if (options.skipMatching) {
            // this is currently only used for the root folder
            log.match(`skipped '${folderPath}'`);
            delete options.skipMatching;
        } else if (ignore(name, folderPath, options.folders)) {
            return undefined;
        }

        return fs.promises.readdir(folderPath, { withFileTypes: true }).then(files => {
            const children = files.sort().map(child => {
                return hashElementPromise(child, folderPath, options);
            });

            return Promise.all(children).then(children => {
                if (ignoreBasenameOnce) options.ignoreBasenameOnce = true;
                const hash = new HashedFolder(name, children.filter(notUndefined), options, isRootElement);
                return hash;
            });
        });
    }

    function hashFilePromise(name, dir, options, isRootElement = false) {
        const filePath = path.join(dir, name);

        if (options.skipMatching) {
            // this is currently only used for the root folder
            log.match(`skipped '${filePath}'`);
            delete options.skipMatching;
        } else if (ignore(name, filePath, options.files)) {
            return undefined;
        }

        return new Promise((resolve, reject) => {
            try {
                const hash = crypto.createHash(options.algo);
                if (options.files.ignoreBasename ||
                    options.ignoreBasenameOnce ||
                    (isRootElement && options.files.ignoreRootName))
                {
                    delete options.ignoreBasenameOnce;
                    log.match(`omitted name of ${filePath} from hash`)
                } else {
                    hash.update(name);
                }

                const f = fs.createReadStream(filePath);
                f.pipe(hash, { end: false });

                f.on('end', () => {
                    const hashedFile = new HashedFile(name, hash, options.encoding);
                    return resolve(hashedFile);
                });
            } catch (ex) {
                return reject(ex);
            }
        });
    }

    async function hashSymLinkPromise(name, dir, options, isRootElement = false) {
        const target = await fs.promises.readlink(path.join(dir, name));
        log.symlink(`handling symbolic link ${name} -> ${target}`);
        switch (options.symbolicLinks.follow) {
            case 'skip':
                log.symlink('skipping symbolic link');
                return Promise.resolve(undefined);

            case 'ignore-target-content':
                return symLinkIgnoreTargetContent(name, target, options, isRootElement);

            case 'resolve':
                return symLinkResolve(name, dir, target, options, isRootElement);

            default:
                throw `Invalid option: symbolicLinks.follow = "${options.symbolicLinks.follow}"`;
        }
    }

    function symLinkIgnoreTargetContent(name, target, options, isRootElement) {
        delete options.skipMatching // only used for the root level
        log.symlink('ignoring symbolic link target content');
        const hash = crypto.createHash(options.algo);
        if (!options.symbolicLinks.ignoreBasename &&
            !(isRootElement && options.files.ignoreRootName)) {
            log.symlink('hash basename');
            hash.update(name);
        }
        if (options.symbolicLinks.hashTargetPath) {
            log.symlink('hash targetpath');
            hash.update(target);
        }
        return Promise.resolve(new HashedFile(name, hash, options.encoding));
    }

    async function symLinkResolve(name, dir, target, options, isRootElement) {
        delete options.skipMatching // only used for the root level
        if (options.symbolicLinks.ignoreBasename) {
            options.ignoreBasenameOnce = true;
        }

        try {
            const stats = await fs.promises.stat(path.join(dir, name));
            stats.name = name;
            const temp = await hashElementPromise(stats, dir, options, isRootElement);

            if (options.symbolicLinks.hashTargetPath) {
                const hash = crypto.createHash(options.algo);
                hash.update(temp.hash);
                log.symlink('hash targetpath');
                hash.update(target);
                temp.hash = hash.digest(options.encoding);
            }
            return temp;
        } catch (err) {
            if ((err.code === 'ENOENT' && options.symbolicLinks.ignoreMissingTarget) ||
                options.symbolicLinks.ignoreAllErrors)
            {
                log.symlink(`Ignoring error "${err.code}" when hashing symbolic link ${name}`, err);
                const hash = crypto.createHash(options.algo);
                if (!options.symbolicLinks.ignoreBasename &&
                    !(isRootElement && options.files.ignoreRootName)) {
                    hash.update(name);
                }
                if (options.symbolicLinks.hashTargetPath) {
                    hash.update(target);
                }
                return new HashedFile(name, hash, options.encoding);
            } else {
                log.symlink(`Error "${err.code}": When hashing symbolic link ${name}`, err);
                throw err;
            }
        }
    }

    function ignore(name, path, rules) {
        if (rules.exclude) {
            if (rules.matchBasename && rules.exclude(name)) {
                log.match(`exclude basename '${path}'`);
                return true;
            } else if (rules.matchPath && rules.exclude(path)) {
                log.match(`exclude path '${path}'`);
                return true;
            }
        } else if (rules.include) {
            if (rules.matchBasename && rules.include(name)) {
                log.match(`include basename '${path}'`);
                return false;
            } else if (rules.matchPath && rules.include(path)) {
                log.match(`include path '${path}'`);
                return false;
            } else {
                return true;
            }
        }

        log.match(`Will not ignore unmatched '${path}'`);
        return false;
    }

    return hashElement;
}

function parseParameters(args) {
    let basename = args[0],
        dir = args[1],
        options_ = args[2];

    if (!isString(basename)) {
        return Promise.reject(new TypeError('First argument must be a string'));
    }

    if (!isString(dir)) {
        dir = path.dirname(basename);
        basename = path.basename(basename);
        options_ = args[1];
    }

    // parse options (fallback default options)
    if (!isObject(options_)) options_ = {};
    const options = {
        algo: options_.algo || defaultOptions.algo,
        encoding: options_.encoding || defaultOptions.encoding,
        files: Object.assign({}, defaultOptions.files, options_.files),
        folders: Object.assign({}, defaultOptions.folders, options_.folders),
        match: Object.assign({}, defaultOptions.match, options_.match),
        symbolicLinks: Object.assign({}, defaultOptions.symbolicLinks, options_.symbolicLinks)
    };

    // transform match globs to Regex
    options.files.exclude = reduceGlobPatterns(options.files.exclude);
    options.files.include = reduceGlobPatterns(options.files.include);
    options.folders.exclude = reduceGlobPatterns(options.folders.exclude);
    options.folders.include = reduceGlobPatterns(options.folders.include);

    return Promise.resolve(log.params({ basename, dir, options }));
}

const HashedFolder = function HashedFolder(name, children, options, isRootElement = false) {
    this.name = name;
    this.children = children;

    const hash = crypto.createHash(options.algo);
    if (options.folders.ignoreBasename ||
        options.ignoreBasenameOnce ||
        (isRootElement && options.folders.ignoreRootName))
    {
        delete options.ignoreBasenameOnce;
        log.match(`omitted name of folder ${name} from hash`)
    } else {
        hash.update(name);
    }
    children.forEach(child => {
        if (child.hash) {
            hash.update(child.hash);
        }
    });

    this.hash = hash.digest(options.encoding);
};

HashedFolder.prototype.toString = function (padding = '') {
    const first = `${padding}{ name: '${this.name}', hash: '${this.hash},'\n`;
    padding += '  ';

    return `${first}${padding}children: ${this.childrenToString(padding)}}`;
};

HashedFolder.prototype.childrenToString = function (padding = '') {
    if (this.children.length === 0) {
        return '[]';
    } else {
        const nextPadding = padding + '  ';
        const children = this.children
            .map(child => child.toString(nextPadding))
            .join('\n');
        return `[\n${children}\n${padding}]`;
    }
};

const HashedFile = function HashedFile(name, hash, encoding) {
    this.name = name;
    this.hash = hash.digest(encoding);
};

HashedFile.prototype.toString = function (padding = '') {
    return padding + '{ name: \'' + this.name + '\', hash: \'' + this.hash + '\' }';
};

function isFunction(any) {
    return typeof any === 'function';
}

function isString(str) {
    return typeof str === 'string' || str instanceof String;
}

function isObject(obj) {
    return obj !== null && typeof obj === 'object';
}

function notUndefined(obj) {
    return typeof obj !== 'undefined';
}

function reduceGlobPatterns(globs) {
    if (isFunction(globs)) {
      return globs;
    }
    else if (!globs || !Array.isArray(globs) || globs.length === 0) {
        return undefined;
    } else {
        // combine globs into one single RegEx
        const regex = new RegExp(globs.reduce((acc, exclude) => {
            return acc + '|' + minimatch.makeRe(exclude).source;
        }, '').substr(1));
        return param => regex.test(param);
    }
}

module.exports = {
    defaults: defaultOptions,
    hashElement: prep(require('graceful-fs')),
    // exposed for testing
    prep,
    parseParameters
};
<|endoftext|>


<commit_before>
var co = require('co');

module.exports = function(timeout) {
  return function *(next) {
    var ctx = this;
    yield Promise.race([
      new Promise(function(resolve, reject) {
        setTimeout(function() {
          var e = new Error('Request timeout')
          e.status = 408;
          reject(e);
        }, timeout);
      }),
      new Promise(function(resolve, reject) {
        co(function*() {
          yield *next;
        }).call(ctx, function(err) {
          if(err) reject(err);
          resolve();
        });
      })
    ]);
  };
};
<commit_msg>Clear the timeout when the request does not timeout<commit_after>
var co = require('co');

module.exports = function(timeout) {
  return function *(next) {
    var ctx = this;
    var tmr = null;
    yield Promise.race([
      new Promise(function(resolve, reject) {
        tmr = setTimeout(function() {
          var e = new Error('Request timeout');
          e.status = 408;
          reject(e);
        }, timeout);
      }),
      new Promise(function(resolve, reject) {
        co(function*() {
          yield *next;
        }).call(ctx, function(err) {
          clearTimeout(tmr);
          if(err) reject(err);
          resolve();
        });
      })
    ]);
  };
};
<|endoftext|>


<commit_before>/**
 * Constructor for the inter-tab manager
 *
 * @param {Object} options
 * @api public
 */

function Manager(opts) {
	this.id = Math.random();

	var tabs = this.getTabs();
	tabs[this.id] = {};

	try {
        localStorage.setItem('tabs', JSON.stringify(tabs));
    } catch (error) {}

	// Listen to event when tab is closed or storage changes
	window.addEventListener('storage', this, false);
	window.addEventListener('unload', this, false);
}

Manager.prototype.destroy = function () {
	var tabs = this.getTabs();

	delete tabs[this.id];

	try {
        localStorage.setItem('tabs', JSON.stringify(tabs));
    } catch (error) {}

    window.removeEventListener( 'storage', this, false );
    window.removeEventListener( 'unload', this, false );
};

Manager.prototype.getTabs = function () {
	var currentTabs = localStorage.tabs;

	if (currentTabs) {
		return JSON.parse(currentTabs);
	} else {
		return {};
	}
};

/**
 * Broadcast message to all managed tabs
 *
 */

Manager.prototype.broadcast = function (key, value) {
	var data = {
		key: key,
		value: value
	};

    try {
        localStorage.setItem('broadcast', JSON.stringify(data));
    } catch (error) {}
};

Manager.prototype.handleEvent = function (event) {
    if (event.type === 'unload') {
        this.destroy();
    } else if (event.key === 'broadcast') {
        try {
            console.log(event);
        } catch ( error ) {}
    } else if (event.key === 'message') {
		var data = JSON.parse(event.newValue);
		if (data.id === this.id) {
			try {
				console.log(data);
			} catch ( error ) {}
		}
    }
};

/**
 * Send message to a specific tab
 *
 */

Manager.prototype.send = function (id, key, value) {
	var data = {
		id: id,
		key: key,
		value: value
	};

	try {
        localStorage.setItem('message', JSON.stringify(data));
    } catch (error) {}

    try {
        localStorage.setItem('message', JSON.stringify({}));
    } catch (error) {}
};

/**
 * Associate data with a specific tab
 *
 */

Manager.prototype.set = function (id, key, value) {
	var tabs = this.getTabs();

	if (tabs[id]) {
		tabs[id][key] = value;

		try {
			localStorage.setItem('tabs', JSON.stringify(tabs));
        } catch (error) {}
	}
};

/**
 * Retrieve data for a specific tab
 *
 */

Manager.prototype.get = function (id, key) {
	var tabs = this.getTabs();

	if (tabs[id]) {
		return tabs[id][key];
	}

	return;
};

// Expose the inter-tab manager

// if (typeof module === 'object' && module.exports) {
//     module.exports = Manager;
// } else {
//     this.it = Manager;
// }<commit_msg>Style fix<commit_after>/**
 * Constructor for the inter-tab manager
 *
 * @param {Object} options
 * @api public
 */

function Manager(opts) {
	this.id = Math.random();

	var tabs = this.getTabs();
	tabs[this.id] = {};

	try {
        localStorage.setItem('tabs', JSON.stringify(tabs));
    } catch (error) {}

	// Listen to event when tab is closed or storage changes
	window.addEventListener('storage', this, false);
	window.addEventListener('unload', this, false);
}

Manager.prototype.destroy = function () {
	var tabs = this.getTabs();

	delete tabs[this.id];

	try {
        localStorage.setItem('tabs', JSON.stringify(tabs));
    } catch (error) {}

    window.removeEventListener( 'storage', this, false );
    window.removeEventListener( 'unload', this, false );
};

Manager.prototype.getTabs = function () {
	var currentTabs = localStorage.tabs;

	if (currentTabs) {
		return JSON.parse(currentTabs);
	} else {
		return {};
	}
};

/**
 * Broadcast message to all managed tabs
 *
 */

Manager.prototype.broadcast = function (key, value) {
	var data = {
		key: key,
		value: value
	};

    try {
        localStorage.setItem('broadcast', JSON.stringify(data));
    } catch (error) {}
};

Manager.prototype.handleEvent = function (event) {
    if (event.type === 'unload') {
        this.destroy();
    } else if (event.key === 'broadcast') {
        try {
            console.log(event);
        } catch ( error ) {}
    } else if (event.key === 'message') {
		var data = JSON.parse(event.newValue);
		if (data.id === this.id) {
			try {
				console.log(data);
			} catch ( error ) {}
		}
    }
};

/**
 * Send message to a specific tab
 *
 */

Manager.prototype.send = function (id, key, value) {
	var data = {
		id: id,
		key: key,
		value: value
	};

	try {
        localStorage.setItem('message', JSON.stringify(data));
    } catch (error) {}

    try {
        localStorage.setItem('message', JSON.stringify({}));
    } catch (error) {}
};

/**
 * Associate data with a specific tab
 *
 */

Manager.prototype.set = function (id, key, value) {
	var tabs = this.getTabs();

	if (tabs[id]) {
		tabs[id][key] = value;

		try {
			localStorage.setItem('tabs', JSON.stringify(tabs));
        } catch (error) {}
	}
};

/**
 * Retrieve data for a specific tab
 *
 */

Manager.prototype.get = function (id, key) {
	var tabs = this.getTabs();

	if (tabs[id]) {
		return tabs[id][key];
	} else {
		return;
	}
};

// Expose the inter-tab manager

// if (typeof module === 'object' && module.exports) {
//     module.exports = Manager;
// } else {
//     this.it = Manager;
// }<|endoftext|>


<commit_before>var url = require('url');
var http = require('http');
var querystring = require('querystring');

var Alchemy = function(api_key, options) {
	options = options || {
		 format: "json"
		,api_url: "access.alchemyapi.com"
		,protocol: "http"
	};

	this.config = {
	    	 api_key: api_key
	    	,format: options.format
	    	,api_url: options.api_url
		,protocol: options.protocol
	};

	return this;
};

/**
 * Returns API path depending on method being called
 * @param {String} method The Alchemy API method to call with the request
 * @return {String}
 */
Alchemy.prototype._getMethodType = function(method){
	var regex = new RegExp("^(text|html|url)", "i");
	var results = regex.exec(method);
	if(results != null){
		return results[0].toLowerCase();
	}

	return "";
};

Alchemy.prototype._getPathFromMethod = function(method){
	var results = this._getMethodType(method);
	if(results != ""){
		return "/" + results;
	}
	return "";
};

/**
 * Generates the URL object to be passed to the HTTP request for a specific
 * API method call
 * @param  {Object} query  The query object
 * @param  {String} method The Alchemy API method to call with the request
 * @return {Object} The URL object for this request
 */
Alchemy.prototype._generateNiceUrl = function(query, method) {
  var result = url.parse(url.format({
    protocol: this.config.protocol,
    hostname: this.config.api_url,
    pathname: '/calls' + this._getPathFromMethod(method) + '/' + method,
	method: "POST",
    query: query
  }));
  // HACK: Fixes the redirection issue in node 0.4.x
  if (!result.path) { result.path = result.pathname + result.search; }
  //console.log(result);
  //if (this._urlCheck())
  return result;
};

/**
 * Function to do a HTTP Get request with the current query
 * @param  {Object} request_query The current query object
 * @param  {Function} cb The callback function for the returned data
 * @return {void}
 */
Alchemy.prototype._doRequest = function(request_query, cb) {
  // Pass the requested URL as an object to the get request
  //console.log(request_query.nice);
  var req = http.request(request_query.nice, function(res) {
     var data = [];
     res
      .on('data', function(chunk) { data.push(chunk); })
      .on('end', function() {
          var urldata = data.join('').trim();
		  //console.log(urldata);
          var result;
          try {
            result = JSON.parse(urldata);
          } catch (exp) {
			console.log(request_query.nice.href);
			console.log(querystring.stringify(request_query.post));
			console.log(urldata);
            result = {'status_code': 500, 'status_text': 'JSON Parse Failed'};
          }
          cb(null, result);
      });
  });

  req.on('error', function(e) {
      cb(e);
  });

  if(req.method == "POST") {
		req.write(querystring.stringify(request_query.post));
  }

  req.end();

};

/**
 * Function to check if a passed string is a valid URL
 * @param  {String} str The URL string to be checked
 * @return {Boolean}
 */
Alchemy.prototype._urlCheck = function(str) {
    var v = new RegExp();
    v.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\\?\/.=]+$");
    if (!v.test(str)) return false;
    return true;
};

/**
 *
 */
Alchemy.prototype._htmlCheck = function(str) {
    var v = new RegExp();
    v.compile("<[A-Za-z][A-Za-z0-9][^>]*>");
	//var v = new RegExp("</\?([a-z][a-z0-9]*)\b[^>]*>", "i");
	//var v = //
	//console.log(v.test(str));
	//console.log(str);
	if (!v.test(str)) return false;
    return true;
};

Alchemy.prototype._getQuery = function(data, method) {
	var query = {};
	query.url = {
	     apikey: this.config.api_key
	    ,outputMode: this.config.format
	};
	query.data = data;
	query.post = {};
	query.apimethod = "HTML" + method;
	var httpMethod = "POST";
	if(this._urlCheck(data)){
		query.apimethod = "URL" + method;
		httpMethod = "GET";
		query.url.url = data;

	}
	else if(!this._htmlCheck(data)){
	    query.apimethod = "Text" + method;
		query.post = {text: data};
		query.headers = {'content-length': data.length};
	}
	else {
		query.post = {html: data};
		query.headers = {'content-length': data.length};
	}

	query.nice = this._generateNiceUrl(query.url, query.apimethod);
	query.nice.method = httpMethod;
	query.nice.headers = query.headers;

	return query;

};

Alchemy.prototype.sentiment = function(data, cb) {
    this._doRequest(this._getQuery(data, "GetTextSentiment"), cb);
};

Alchemy.prototype.relations = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRelations"), cb);
};

Alchemy.prototype.concepts = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRankedConcepts"), cb);
};

Alchemy.prototype.entities = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRankedNamedEntities"), cb);
};

Alchemy.prototype.keywords = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRankedKeywords"), cb);
};

Alchemy.prototype.category = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetCategory"), cb);
};

Alchemy.prototype.language = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetLanguage"), cb);
};

Alchemy.prototype.author = function(data, cb) {
	if (!this._urlCheck(data) && !this._htmlCheck(data)) {
		cb(new Error('The author method can only be used a URL or HTML encoded text.  Plain text is not supported.'), null);
		return;
	}
	this._doRequest(this._getQuery(data, "GetAuthor"), cb);
};

Alchemy.prototype.text = function(data, cb) {
	if (!this._urlCheck(data) && !this._htmlCheck(data)) {
		cb(new Error('The text method can only be used a URL or HTML encoded text.  Plain text is not supported.'), null);
		return;
	}
	this._doRequest(this._getQuery(data, "GetText"), cb);
};

Alchemy.prototype.scrape = function(data, cb) {
	if (!this._urlCheck(data) && !this._htmlCheck(data)) {
		cb(new Error('The scrape method can only be used a URL or HTML encoded text.  Plain text is not supported.'), null);
		return;
	}
	this._doRequest(this._getQuery(data, "GetConstraintQuery"), cb);
};

// Export as main entry point in this module
module.exports = Alchemy;<commit_msg>Trying to fix travis error<commit_after>var url = require('url');
var http = require('http');
var querystring = require('querystring');

var Alchemy = function(api_key, options) {
	options = options || {
		 format: "json"
		,api_url: "access.alchemyapi.com"
		,protocol: "http"
	};

	this.config = {
	    	 api_key: api_key
	    	,format: options.format
	    	,api_url: options.api_url
		,protocol: options.protocol
	};

	return this;
};

/**
 * Returns API path depending on method being called
 * @param {String} method The Alchemy API method to call with the request
 * @return {String}
 */
Alchemy.prototype._getMethodType = function(method){
	var regex = new RegExp("^(text|html|url)", "i");
	var results = regex.exec(method);
	if(results != null){
		return results[0].toLowerCase();
	}

	return "";
};

Alchemy.prototype._getPathFromMethod = function(method){
	var results = this._getMethodType(method);
	if(results != ""){
		return "/" + results;
	}
	return "";
};

/**
 * Generates the URL object to be passed to the HTTP request for a specific
 * API method call
 * @param  {Object} query  The query object
 * @param  {String} method The Alchemy API method to call with the request
 * @return {Object} The URL object for this request
 */
Alchemy.prototype._generateNiceUrl = function(query, method) {
  var result = url.parse(url.format({
    protocol: this.config.protocol,
    hostname: this.config.api_url,
    pathname: '/calls' + this._getPathFromMethod(method) + '/' + method,
	method: "POST",
    query: query
  }));
  // HACK: Fixes the redirection issue in node 0.4.x
  if (!result.path) { result.path = result.pathname + result.search; }
  //console.log(result);
  //if (this._urlCheck())
  return result;
};

/**
 * Function to do a HTTP Get request with the current query
 * @param  {Object} request_query The current query object
 * @param  {Function} cb The callback function for the returned data
 * @return {void}
 */
Alchemy.prototype._doRequest = function(request_query, cb) {
  // Pass the requested URL as an object to the get request
  //console.log(request_query.nice);
  var req = http.request(request_query.nice, function(res) {
     var data = [];
     res
      .on('data', function(chunk) { data.push(chunk); })
      .on('end', function() {
          var urldata = data.join('').trim();
		  //console.log(urldata);
          var result;
          try {
            result = JSON.parse(urldata);
          } catch (exp) {
			console.log(request_query.nice.href);
			console.log(querystring.stringify(request_query.post));
			console.log(urldata);
            result = {'status_code': 500, 'status_text': 'JSON Parse Failed'};
          }
          cb(null, result);
      })
	 .on("error", function (e) {
			console.log(e);
			cb(e);
	  });
  });

  req.on('error', function(e) {
      cb(e);
  });

  if(req.method == "POST") {
		req.write(querystring.stringify(request_query.post));
  }

  req.end();

};

/**
 * Function to check if a passed string is a valid URL
 * @param  {String} str The URL string to be checked
 * @return {Boolean}
 */
Alchemy.prototype._urlCheck = function(str) {
    var v = new RegExp();
    v.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\\?\/.=]+$");
    if (!v.test(str)) return false;
    return true;
};

/**
 *
 */
Alchemy.prototype._htmlCheck = function(str) {
    var v = new RegExp();
    v.compile("<[A-Za-z][A-Za-z0-9][^>]*>");
	//var v = new RegExp("</\?([a-z][a-z0-9]*)\b[^>]*>", "i");
	//var v = //
	//console.log(v.test(str));
	//console.log(str);
	if (!v.test(str)) return false;
    return true;
};

Alchemy.prototype._getQuery = function(data, method) {
	var query = {};
	query.url = {
	     apikey: this.config.api_key
	    ,outputMode: this.config.format
	};
	query.data = data;
	query.post = {};
	query.apimethod = "HTML" + method;
	var httpMethod = "POST";
	if(this._urlCheck(data)){
		query.apimethod = "URL" + method;
		httpMethod = "GET";
		query.url.url = data;

	}
	else if(!this._htmlCheck(data)){
	    query.apimethod = "Text" + method;
		query.post = {text: data};
		query.headers = {'content-length': data.length};
	}
	else {
		query.post = {html: data};
		query.headers = {'content-length': data.length};
	}

	query.nice = this._generateNiceUrl(query.url, query.apimethod);
	query.nice.method = httpMethod;
	query.nice.headers = query.headers;

	return query;

};

Alchemy.prototype.sentiment = function(data, cb) {
    this._doRequest(this._getQuery(data, "GetTextSentiment"), cb);
};

Alchemy.prototype.relations = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRelations"), cb);
};

Alchemy.prototype.concepts = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRankedConcepts"), cb);
};

Alchemy.prototype.entities = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRankedNamedEntities"), cb);
};

Alchemy.prototype.keywords = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetRankedKeywords"), cb);
};

Alchemy.prototype.category = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetCategory"), cb);
};

Alchemy.prototype.language = function(data, cb) {
	this._doRequest(this._getQuery(data, "GetLanguage"), cb);
};

Alchemy.prototype.author = function(data, cb) {
	if (!this._urlCheck(data) && !this._htmlCheck(data)) {
		cb(new Error('The author method can only be used a URL or HTML encoded text.  Plain text is not supported.'), null);
		return;
	}
	this._doRequest(this._getQuery(data, "GetAuthor"), cb);
};

Alchemy.prototype.text = function(data, cb) {
	if (!this._urlCheck(data) && !this._htmlCheck(data)) {
		cb(new Error('The text method can only be used a URL or HTML encoded text.  Plain text is not supported.'), null);
		return;
	}
	this._doRequest(this._getQuery(data, "GetText"), cb);
};

Alchemy.prototype.scrape = function(data, cb) {
	if (!this._urlCheck(data) && !this._htmlCheck(data)) {
		cb(new Error('The scrape method can only be used a URL or HTML encoded text.  Plain text is not supported.'), null);
		return;
	}
	this._doRequest(this._getQuery(data, "GetConstraintQuery"), cb);
};

// Export as main entry point in this module
module.exports = Alchemy;<|endoftext|>


<commit_before>'use strict';

let postcss = require('postcss');

module.exports = postcss.plugin('postcss-mediator', opts => {
    opts = opts || {};

    let mediaRegexMatch = /^((not|only)_)?(all|screen|print|speech)$/i;

    function extractOneMode(mediatorModes, rule) {
        if (rule.name === 'mediator') {
            let firstSpace = rule.params.indexOf(' ');
            let key = rule.params.substr(0, firstSpace);
            let value = rule.params.substr(firstSpace + 1);

            // Make sure mediator modes are not named after media types
            // to avoid possible conflicts
            if (mediaRegexMatch.test(key)) {
                throw rule.error('Naming a Mediator Mode after a media ' +
                    'type (all, screen, print, speech) may cause undesired ' +
                    'conflicts. Please rename it.',
                    { plugin: 'postcss-mediator' });
            }

            mediatorModes[key] = value;
            rule.remove();
        }
    }

    function extractModes(css) {
        let mediatorModes = {};
        let extractor = extractOneMode.bind(this, mediatorModes);
        css.walkAtRules(extractor);
        return mediatorModes;
    }

    function extractOneRule(mediatorModes, mediatorOutputRules, decl) {
        if (decl.prop.indexOf('.') === -1) {
            return;
        }

        // Breaks the property declaration to extract its modes
        let modes = decl.prop.split('.');
        // First element is the propety
        let prop = modes.shift();

        // Check if any of the modes is actually a media type
        let mediaTypes = modes.filter(element => {
            return mediaRegexMatch.test(element);
        });

        // If so, remove media types from modes array
        if (mediaTypes.length > 0) {
            modes = modes.filter(element => {
                return mediaTypes.indexOf(element) === -1;
            });
        } else {
            // Default media type
            mediaTypes = ['all'];
        }

        // Filter modes to make sure only pre-defined modes will be used
        modes = modes.filter(element => {
            return mediatorModes[element] !== undefined;
        });

        if (modes.length === 0) {
            return;
        }

        // Have the modes ordered to prevent mode mismatching
        modes.sort();

        // Create unique string to repesent mode
        let ruleMode = modes.join('.');
        // Currently only one media type is supported per declaration
        ruleMode = mediaTypes[0] + '.' + ruleMode;

        if (typeof mediatorOutputRules[ruleMode] === 'undefined') {
            mediatorOutputRules[ruleMode] = {};
        }

        let selector = decl.parent.selector;
        let mediatorRuleSelector = mediatorOutputRules[ruleMode][selector];
        if (typeof mediatorRuleSelector === 'undefined') {
            mediatorOutputRules[ruleMode][selector] = {};
        }

        mediatorOutputRules[ruleMode][selector][prop] = decl.value;

        if (decl.parent.nodes.length === 1) {
            decl.parent.remove();
        } else {
            decl.remove();
        }
    }

    function extractRules(mediatorModes, css) {
        let mediatorOutputRules = {};
        let extractor = extractOneRule.bind(this,
            mediatorModes,
            mediatorOutputRules);
        css.walkDecls(extractor);
        return mediatorOutputRules;
    }

    function mutateCSS(mediatorModes, mediatorOutputRules, css) {
        for (let mode in mediatorOutputRules) {
            let artifacts = mode.split('.');
            let mediaq = '@media ';
            for (let i in artifacts) {
                if (i === 0) {
                    // Media type
                    mediaq += artifacts[i] + ' ';
                } else {
                    // Mediator mode (media expression)
                    mediaq += 'and ';
                    mediaq += '(' + mediatorModes[artifacts[i]] + ') ';
                }
            }
            mediaq += '{';

            for (let element in mediatorOutputRules[mode]) {
                mediaq += element + ' {';
                for (let prop in mediatorOutputRules[mode][element]) {
                    mediaq += prop + ': ';
                    mediaq += mediatorOutputRules[mode][element][prop] + ';';
                }
                mediaq += '}';
            }

            mediaq += '}';
            css.append(mediaq);
        }
    }

    return function (css) {
        let mediatorModes = extractModes(css);

        let mediatorOutputRules =  extractRules(mediatorModes, css);

        mutateCSS(mediatorModes, mediatorOutputRules, css);
    };
});
<commit_msg>Adding support to all existing media types<commit_after>'use strict';

let postcss = require('postcss');

module.exports = postcss.plugin('postcss-mediator', opts => {
    opts = opts || {};

    let supportedMediaTypes = ['all', 'aural', 'braille', 'handheld', 'print',
            'projection', 'screen', 'tty', 'tv', 'embossed'];
    let mediaRegexMatch = new RegExp('^((not|only)_)?' +
            supportedMediaTypes.join('|') + '$', 'i');

    function extractOneMode(mediatorModes, rule) {
        if (rule.name === 'mediator') {
            let firstSpace = rule.params.indexOf(' ');
            let key = rule.params.substr(0, firstSpace);
            let value = rule.params.substr(firstSpace + 1);

            // Make sure mediator modes are not named after media types
            // to avoid possible conflicts
            if (mediaRegexMatch.test(key)) {
                throw rule.error('Naming a Mediator Mode after a media ' +
                    'type (all, screen, print, speech) may cause undesired ' +
                    'conflicts. Please rename it.',
                    { plugin: 'postcss-mediator' });
            }

            mediatorModes[key] = value;
            rule.remove();
        }
    }

    function extractModes(css) {
        let mediatorModes = {};
        let extractor = extractOneMode.bind(this, mediatorModes);
        css.walkAtRules(extractor);
        return mediatorModes;
    }

    function extractOneRule(mediatorModes, mediatorOutputRules, decl) {
        if (decl.prop.indexOf('.') === -1) {
            return;
        }

        // Breaks the property declaration to extract its modes
        let modes = decl.prop.split('.');
        // First element is the propety
        let prop = modes.shift();

        // Check if any of the modes is actually a media type
        let mediaTypes = modes.filter(element => {
            return mediaRegexMatch.test(element);
        });

        // If so, remove media types from modes array
        if (mediaTypes.length > 0) {
            modes = modes.filter(element => {
                return mediaTypes.indexOf(element) === -1;
            });
        } else {
            // Default media type
            mediaTypes = ['all'];
        }

        // Filter modes to make sure only pre-defined modes will be used
        modes = modes.filter(element => {
            return mediatorModes[element] !== undefined;
        });

        if (modes.length === 0) {
            return;
        }

        // Have the modes ordered to prevent mode mismatching
        modes.sort();

        // Create unique string to repesent mode
        let ruleMode = modes.join('.');
        // Currently only one media type is supported per declaration
        ruleMode = mediaTypes[0] + '.' + ruleMode;

        if (typeof mediatorOutputRules[ruleMode] === 'undefined') {
            mediatorOutputRules[ruleMode] = {};
        }

        let selector = decl.parent.selector;
        let mediatorRuleSelector = mediatorOutputRules[ruleMode][selector];
        if (typeof mediatorRuleSelector === 'undefined') {
            mediatorOutputRules[ruleMode][selector] = {};
        }

        mediatorOutputRules[ruleMode][selector][prop] = decl.value;

        if (decl.parent.nodes.length === 1) {
            decl.parent.remove();
        } else {
            decl.remove();
        }
    }

    function extractRules(mediatorModes, css) {
        let mediatorOutputRules = {};
        let extractor = extractOneRule.bind(this,
            mediatorModes,
            mediatorOutputRules);
        css.walkDecls(extractor);
        return mediatorOutputRules;
    }

    function mutateCSS(mediatorModes, mediatorOutputRules, css) {
        for (let mode in mediatorOutputRules) {
            let artifacts = mode.split('.');
            let mediaq = '@media ';
            for (let i in artifacts) {
                if (parseInt(i) === 0) {
                    // Media type
                    mediaq += artifacts[i] + ' ';
                } else {
                    // Mediator mode (media expression)
                    mediaq += 'and ';
                    mediaq += '(' + mediatorModes[artifacts[i]] + ') ';
                }
            }
            mediaq += '{';

            for (let element in mediatorOutputRules[mode]) {
                mediaq += element + ' {';
                for (let prop in mediatorOutputRules[mode][element]) {
                    mediaq += prop + ': ';
                    mediaq += mediatorOutputRules[mode][element][prop] + ';';
                }
                mediaq += '}';
            }

            mediaq += '}';
            css.append(mediaq);
        }
    }

    return function (css) {
        let mediatorModes = extractModes(css);

        let mediatorOutputRules =  extractRules(mediatorModes, css);

        mutateCSS(mediatorModes, mediatorOutputRules, css);
    };
});
<|endoftext|>


<commit_before>/* eslint-env node */
module.exports = {
    extends: [ "eslint:recommended", "plugin:import/errors", "plugin:unicorn/recommended" ],
    settings: { "import/resolver": { webpack: {}}},
    rules: {
        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
        "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",

        // Broken in eslint@6.x
        // See https://github.com/benmosher/eslint-plugin-import/issues/1341
        "import/named": "off",

        // This often has false positives for async/await style
        "require-atomic-updates": "off",

        //
        // Unicorn
        //

        "unicorn/filename-case": "off",
        "unicorn/prevent-abbreviations": "off",

        // Possible Errors

        "no-await-in-loop": "warn",
        "no-extra-parens": "error",
        "no-import-assign": "error",
        "no-template-curly-in-string": "error",

        //
        // Best Practices
        // https://eslint.org/docs/rules/#best-practices
        //

        "array-callback-return": "error",
        "consistent-return": "error",
        "curly": [ "error", "multi-line", "consistent" ],
        "default-case": "error",
        "default-param-last": "error",
        "dot-location": [ "error", "property" ],
        "dot-notation": [ "error", { allowKeywords: false, allowPattern: "^[a-z]+(_[a-z]+)+$" }],
        "eqeqeq": [ "error", "smart" ],
        "guard-for-in": "error",
        "no-alert": "error",
        "no-caller": "error",
        "no-case-declarations": "error",
        "no-div-regex": "error",
        "no-else-return": "error",
        "no-empty-function": "error",
        "no-implicit-coercion": "error",
        "no-floating-decimal": "error",
        "no-extra-label": "error",
        "no-extra-bind": "error",
        "no-extend-native": "error",
        "no-eval": "error",
        "no-implicit-globals": "error",
        "no-implied-eval": "error",
        "no-invalid-this": "error",
        "no-iterator": "error",
        "no-lone-blocks": "error",
        "no-loop-func": "error",
        "no-multi-spaces": "error",
        "no-new": "error",
        "no-new-func": "error",
        "no-new-wrappers": "error",
        "no-octal-escape": "error",
        "no-param-reassign": "error",
        "no-proto": "error",
        "no-return-assign": "error",
        "no-return-await": "error",
        "no-script-url": "error",
        "no-self-compare": "error",
        "no-sequences": "error",
        "no-throw-literal": "error",
        "no-unmodified-loop-condition": "error",
        "no-unused-expressions": "error",
        "no-useless-call": "error",
        "no-useless-concat": "error",
        "no-useless-return": "error",
        "no-void": "error",
        "no-warning-comments": "warn",
        "prefer-promise-reject-errors": "error",
        "prefer-regex-literals": "error",
        "radix": [ "error", "always" ],
        "require-await": "error",
        "require-unicode-regexp": "error",
        "wrap-iife": "error",
        "yoda": [ "error", "never" ],

        //
        // Variables
        // https://eslint.org/docs/rules/#variables
        //

        "no-label-var": "error",
        "no-undef-init": "error",

        //
        // Node.js and CommonJS
        // https://eslint.org/docs/rules/#nodejs-and-commonjs
        //

        "callback-return": "error",
        "handle-callback-err": "error",
        "no-buffer-constructor": "error",
        "no-mixed-requires": "error",
        "no-new-require": "error",
        "no-path-concat": "error",
        "no-process-env": "warn",
        "no-process-exit": "error",
        "no-sync": [ "error", { allowAtRootLevel: true }],

        //
        // Stylistic Issues
        // https://eslint.org/docs/rules/#stylistic-issues
        //

        "array-bracket-newline": [ "error", { multiline: true }],
        "array-bracket-spacing": [ "error", "always", { objectsInArrays: false, arraysInArrays: false }],
        "array-element-newline": [ "error", { multiline: true }],
        "block-spacing": [ "error", "always" ],
        "brace-style": [ "error", "1tbs", { allowSingleLine: false }],
        "camelcase": [ "error" ],
        "comma-dangle": [ "error", "never" ],
        "comma-spacing": [ "error", { before: false, after: true }],
        "comma-style": [ "error", "last" ],
        "consistent-this": [ "error", "this_" ],
        "computed-property-spacing": [ "error", "always", { enforceForClassMembers: true }],
        "eol-last": [ "error", "always" ],
        "func-call-spacing": [ "error", "never" ],
        "func-name-matching": [ "error", "always" ],
        "function-call-argument-newline": [ "error", "consistent" ],
        "function-paren-newline": [ "error", "multiline" ],
        "implicit-arrow-linebreak": [ "error", "beside" ],
        "indent": [ "error", 4 ],
        "key-spacing": [
            "error",
            {
                beforeColon: false,
                afterColon: true,
                mode: "strict"
            }
        ],
        "keyword-spacing": [ "error", { before: true, after: true }],
        "linebreak-style": [ "error", "unix" ],
        "lines-between-class-members": [ "error", "always", { exceptAfterSingleLine: true }],
        "multiline-comment-style": [ "error", "separate-lines" ],
        "new-cap": "error",
        "new-parens": "error",
        "newline-per-chained-call": [ "error", { ignoreChainWithDepth: 3 }],
        "no-array-constructor": "error",
        "no-lonely-if": "error",
        "no-mixed-operators": "error",
        "no-multi-assign": "error",
        "no-multiple-empty-lines": [ "error", { max: 1 }],
        "no-negated-condition": "error",
        "no-nested-ternary": "error",
        "no-new-object": "error",
        "no-plusplus": "error",
        "no-tabs": "error",
        "no-trailing-spaces": "error",
        "no-unneeded-ternary": "error",
        "no-whitespace-before-property": "error",
        "nonblock-statement-body-position": "error",
        "object-curly-newline": [ "error", { multiline: true }],
        "object-curly-spacing": [ "error", "always", { arraysInObjects: false, objectsInObjects: false }],
        "operator-assignment": [ "error", "always" ],
        "operator-linebreak": [ "error", "after" ],
        "padded-blocks": [ "error", "never" ],
        "prefer-object-spread": "error",
        "quote-props": [ "error", "consistent-as-needed" ],
        "quotes": [ "error", "double" ],
        "semi": [ "error", "always" ],
        "semi-spacing": [ "error", { before: false, after: true }],
        "semi-style": [ "error", "last" ],
        "space-before-blocks": [ "error", "always" ],
        "space-before-function-paren": [ "error", "never" ],
        "space-in-parens": [ "error", "never" ],
        "space-infix-ops": "error",
        "space-unary-ops": "error",
        "spaced-comment": [ "error", "always" ],
        "switch-colon-spacing": [ "error", { after: true, before: false }],
        "template-tag-spacing": [ "error", "never" ],
        "unicode-bom": [ "error", "never" ],

        //
        // ECMAScript 6
        // https://eslint.org/docs/rules/#ecmascript-6
        //

        "arrow-body-style": [ "error", "as-needed" ],
        "arrow-parens": [ "error", "always" ],
        "arrow-spacing": [ "error", { before: true, after: true }],
        "generator-star-spacing": [ "error", { before: true, after: false }],
        "no-duplicate-imports": "error",
        "no-useless-computed-key": "error",
        "no-useless-constructor": "error",
        "no-useless-rename": "error",
        "no-var": "error",
        "object-shorthand": [ "error", "always", { avoidExplicitReturnArrows: true }],
        "prefer-arrow-callback": "error",
        "prefer-const": "error",
        "prefer-numeric-literals": "error",
        "prefer-template": "error",
        "prefer-rest-params": "error",
        "prefer-spread": "error",
        "rest-spread-spacing": [ "error", "never" ],
        "symbol-description": "error",
        "template-curly-spacing": [ "error", "never" ],
        "yield-star-spacing": [ "error", { before: true, after: false }]
    }
};
<commit_msg>Remove no-extra-parens (false positives in TypeScript)<commit_after>/* eslint-env node */
module.exports = {
    extends: [ "eslint:recommended", "plugin:import/errors", "plugin:unicorn/recommended" ],
    settings: { "import/resolver": { webpack: {}}},
    rules: {
        "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
        "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",

        // Broken in eslint@6.x
        // See https://github.com/benmosher/eslint-plugin-import/issues/1341
        "import/named": "off",

        // This often has false positives for async/await style
        "require-atomic-updates": "off",

        //
        // Unicorn
        //

        "unicorn/filename-case": "off",
        "unicorn/prevent-abbreviations": "off",

        // Possible Errors

        "no-await-in-loop": "warn",
        "no-import-assign": "error",
        "no-template-curly-in-string": "error",

        //
        // Best Practices
        // https://eslint.org/docs/rules/#best-practices
        //

        "array-callback-return": "error",
        "consistent-return": "error",
        "curly": [ "error", "multi-line", "consistent" ],
        "default-case": "error",
        "default-param-last": "error",
        "dot-location": [ "error", "property" ],
        "dot-notation": [ "error", { allowKeywords: false, allowPattern: "^[a-z]+(_[a-z]+)+$" }],
        "eqeqeq": [ "error", "smart" ],
        "guard-for-in": "error",
        "no-alert": "error",
        "no-caller": "error",
        "no-case-declarations": "error",
        "no-div-regex": "error",
        "no-else-return": "error",
        "no-empty-function": "error",
        "no-implicit-coercion": "error",
        "no-floating-decimal": "error",
        "no-extra-label": "error",
        "no-extra-bind": "error",
        "no-extend-native": "error",
        "no-eval": "error",
        "no-implicit-globals": "error",
        "no-implied-eval": "error",
        "no-invalid-this": "error",
        "no-iterator": "error",
        "no-lone-blocks": "error",
        "no-loop-func": "error",
        "no-multi-spaces": "error",
        "no-new": "error",
        "no-new-func": "error",
        "no-new-wrappers": "error",
        "no-octal-escape": "error",
        "no-param-reassign": "error",
        "no-proto": "error",
        "no-return-assign": "error",
        "no-return-await": "error",
        "no-script-url": "error",
        "no-self-compare": "error",
        "no-sequences": "error",
        "no-throw-literal": "error",
        "no-unmodified-loop-condition": "error",
        "no-unused-expressions": "error",
        "no-useless-call": "error",
        "no-useless-concat": "error",
        "no-useless-return": "error",
        "no-void": "error",
        "no-warning-comments": "warn",
        "prefer-promise-reject-errors": "error",
        "prefer-regex-literals": "error",
        "radix": [ "error", "always" ],
        "require-await": "error",
        "require-unicode-regexp": "error",
        "wrap-iife": "error",
        "yoda": [ "error", "never" ],

        //
        // Variables
        // https://eslint.org/docs/rules/#variables
        //

        "no-label-var": "error",
        "no-undef-init": "error",

        //
        // Node.js and CommonJS
        // https://eslint.org/docs/rules/#nodejs-and-commonjs
        //

        "callback-return": "error",
        "handle-callback-err": "error",
        "no-buffer-constructor": "error",
        "no-mixed-requires": "error",
        "no-new-require": "error",
        "no-path-concat": "error",
        "no-process-env": "warn",
        "no-process-exit": "error",
        "no-sync": [ "error", { allowAtRootLevel: true }],

        //
        // Stylistic Issues
        // https://eslint.org/docs/rules/#stylistic-issues
        //

        "array-bracket-newline": [ "error", { multiline: true }],
        "array-bracket-spacing": [ "error", "always", { objectsInArrays: false, arraysInArrays: false }],
        "array-element-newline": [ "error", { multiline: true }],
        "block-spacing": [ "error", "always" ],
        "brace-style": [ "error", "1tbs", { allowSingleLine: false }],
        "camelcase": [ "error" ],
        "comma-dangle": [ "error", "never" ],
        "comma-spacing": [ "error", { before: false, after: true }],
        "comma-style": [ "error", "last" ],
        "consistent-this": [ "error", "this_" ],
        "computed-property-spacing": [ "error", "always", { enforceForClassMembers: true }],
        "eol-last": [ "error", "always" ],
        "func-call-spacing": [ "error", "never" ],
        "func-name-matching": [ "error", "always" ],
        "function-call-argument-newline": [ "error", "consistent" ],
        "function-paren-newline": [ "error", "multiline" ],
        "implicit-arrow-linebreak": [ "error", "beside" ],
        "indent": [ "error", 4 ],
        "key-spacing": [
            "error",
            {
                beforeColon: false,
                afterColon: true,
                mode: "strict"
            }
        ],
        "keyword-spacing": [ "error", { before: true, after: true }],
        "linebreak-style": [ "error", "unix" ],
        "lines-between-class-members": [ "error", "always", { exceptAfterSingleLine: true }],
        "multiline-comment-style": [ "error", "separate-lines" ],
        "new-cap": "error",
        "new-parens": "error",
        "newline-per-chained-call": [ "error", { ignoreChainWithDepth: 3 }],
        "no-array-constructor": "error",
        "no-lonely-if": "error",
        "no-mixed-operators": "error",
        "no-multi-assign": "error",
        "no-multiple-empty-lines": [ "error", { max: 1 }],
        "no-negated-condition": "error",
        "no-nested-ternary": "error",
        "no-new-object": "error",
        "no-plusplus": "error",
        "no-tabs": "error",
        "no-trailing-spaces": "error",
        "no-unneeded-ternary": "error",
        "no-whitespace-before-property": "error",
        "nonblock-statement-body-position": "error",
        "object-curly-newline": [ "error", { multiline: true }],
        "object-curly-spacing": [ "error", "always", { arraysInObjects: false, objectsInObjects: false }],
        "operator-assignment": [ "error", "always" ],
        "operator-linebreak": [ "error", "after" ],
        "padded-blocks": [ "error", "never" ],
        "prefer-object-spread": "error",
        "quote-props": [ "error", "consistent-as-needed" ],
        "quotes": [ "error", "double" ],
        "semi": [ "error", "always" ],
        "semi-spacing": [ "error", { before: false, after: true }],
        "semi-style": [ "error", "last" ],
        "space-before-blocks": [ "error", "always" ],
        "space-before-function-paren": [ "error", "never" ],
        "space-in-parens": [ "error", "never" ],
        "space-infix-ops": "error",
        "space-unary-ops": "error",
        "spaced-comment": [ "error", "always" ],
        "switch-colon-spacing": [ "error", { after: true, before: false }],
        "template-tag-spacing": [ "error", "never" ],
        "unicode-bom": [ "error", "never" ],

        //
        // ECMAScript 6
        // https://eslint.org/docs/rules/#ecmascript-6
        //

        "arrow-body-style": [ "error", "as-needed" ],
        "arrow-parens": [ "error", "always" ],
        "arrow-spacing": [ "error", { before: true, after: true }],
        "generator-star-spacing": [ "error", { before: true, after: false }],
        "no-duplicate-imports": "error",
        "no-useless-computed-key": "error",
        "no-useless-constructor": "error",
        "no-useless-rename": "error",
        "no-var": "error",
        "object-shorthand": [ "error", "always", { avoidExplicitReturnArrows: true }],
        "prefer-arrow-callback": "error",
        "prefer-const": "error",
        "prefer-numeric-literals": "error",
        "prefer-template": "error",
        "prefer-rest-params": "error",
        "prefer-spread": "error",
        "rest-spread-spacing": [ "error", "never" ],
        "symbol-description": "error",
        "template-curly-spacing": [ "error", "never" ],
        "yield-star-spacing": [ "error", { before: true, after: false }]
    }
};
<|endoftext|>


<commit_before>var browserify   = require('browserify')
  , path         = require('path')
  , fs           = require('fs')
  , events       = require('events')
  , mkdirp       = require('mkdirp')
  , watchify     = require('watchify')
  , ejsify       = require('ejsify')
  , hbsfy        = require('hbsfy')
  , jadeify      = require('jadeify')
  , envify       = require('envify')
  , partialify   = require('partialify')
  , reactify     = require('reactify')
  , brfs         = require('brfs')
  , writer       = require('write-to-path')
  , emitter      = new events.EventEmitter()
  , streamBuffer = require('stream-buffers')
  , _            = require('lodash')
  , minifyify  = require('minifyify')
  , ctor

require('factor-bundle')

ctor = module.exports = function atomifyJs(opts, cb){
  if (Array.isArray(opts)) opts = {entries: opts}
  if (typeof opts === 'string') opts = {entries: [opts]}
  if (opts.entry) opts.entries = [opts.entry]
  if (!opts.entries) opts.entries = []

  if (typeof cb === 'string') opts.output = cb // js('entry.js', 'bundle.js')

  if (opts.output) {
    // we definitely have to write the file
    var outputPath = path.resolve(process.cwd(), opts.output)
      , outputDir = path.dirname(outputPath)
      , writeFile = writer(outputPath, {debug: opts.debug})

    if (!fs.existsSync(outputDir)) mkdirp.sync(outputDir)

    // we might need to call a callback also
    if (typeof cb === 'function') {
      var _outputcb = cb
      cb = function (err, src, map) {
        if (err) return _outputcb(err)
        writeFile(null, src)
        _outputcb(null, src, map)
      }
    }
    else {
      cb = writeFile
    }
  }

  var _buffercb = cb

  cb = function (err, buff, map) {
    if(typeof _buffercb == 'function')
      _buffercb(err, buff, map)
  }

  opts.debug  = opts.debug || false

  if(opts.minify === true) {
    opts.minify = {map: false}
  }
  // Debug mode must be on to get sourcemaps
  else if(typeof opts.minify == 'object') {
    opts.debug = true
  }

  var browserifyOptions = {debug: true}
    , b
    , w

  if (opts.watch) _.extend(browserifyOptions, watchify.args)

  b = browserify(browserifyOptions)
  emitter.emit('browserify', b)

  if (opts.watch) {
    w = watchify(b)
    emitter.emit('watchify', w)
  }

  if (opts.watch) {
    w.on('update', function onUpdate(ids){
      ids.forEach(function eachId(id){
        emitter.emit('changed', id)
      })

      w.bundle(cb)
    })

    w.on('time', function onTime(time){
      emitter.emit('bundle', time)
    })
  }

  b.on('package', function(pkg){
    emitter.emit('package', pkg)
  })

  opts.entries.forEach(function eachEntry(entry){
    b.add(path.resolve(process.cwd(), entry))
  })

  // Browserify modifies the transforms property once opts is passed in to bundle()
  // so we copy that prop here to ensure we only use what is passed in from config
  if (!opts._transforms) {
    opts._transforms = opts.transforms ? opts.transforms.slice(0) : []
  }

  var transforms = [
      envify
      , ejsify
      , hbsfy
      , jadeify
      , partialify
      , [reactify, {'es6': true}]
    ]
    // ensure brfs runs last because it requires valid js
    .concat(opts._transforms, [brfs])

  transforms.forEach(function eachTransform(transform){
    if (Array.isArray(transform)) {
      b.transform(transform[1], transform[0])
    }
    else {
      b.transform(transform)
    }
  })

  // reset list of global transforms every time
  opts._globalTransforms = opts.globalTransforms ? opts.globalTransforms.slice(0) : []

  if (opts.assets) {
    var assets = ['resrcify', {
      dest: opts.assets.dest || ''
      , prefix: opts.assets.prefix || ''
      , retainName: opts.assets.retainName || ''
    }]

    opts._globalTransforms.push(assets)
  }

  opts._globalTransforms.forEach(function eachGlobalTransform(gt){
    if (Array.isArray(gt)) {
      var gto = gt[1]
      gto.global = true
      b.transform(gto, gt[0])
    }
    else {
      b.transform({global: true}, gt)
    }
  })

  if(typeof opts.minify == 'object') {
    b.plugin(minifyify, opts.minify)
  }

  if (opts.require) {
    if (Array.isArray(opts.require) || typeof opts.require === 'string'){
      opts.require = {file: opts.require}
    }
    b.require(opts.require.file, opts.require.opts)
  }

  if (Array.isArray(opts.external) || typeof opts.external === 'string'){
    b.external(opts.external)
  }

  // if we've got the common option, we want to use factor bundle
  if (opts.common === true){
    if (opts.entries.length < 2) {
      var error = new Error('the `common` option requires an `entries` option with more than one entry')
      cb(error)
      // TODO: we should do this, but it casues tape to falsely see the error event on itself!?
      // emitter.emit('error', error)
      return
    }

    // for each entry, we're going to create a stream-able buffer to put the factored bundle into
    var outputs = {}
    opts.entries.forEach(function createOutputs(entry){
      outputs[path.basename(entry).replace(path.extname(entry), '')] = new streamBuffer.WritableStreamBuffer({
          // these values are arbitrary, but we don't want to require huge buffers
          initialSize: (1 * 1024)         // start as 1 kilobytes.
          , incrementAmount: (1 * 1024)    // grow by 1 kilobytes each time buffer overflows.
      })
    })

    // setup factor bundle, pass in our streamable-buffers as the output source
    b.plugin('factor-bundle', {
      o: _.values(outputs)
    })

    // we need to wrap the callback to output an object with all the bundles
    return b.bundle(function (err, common){
      var hasCallback = _.isFunction(cb)
        , out = {}

      if (err && hasCallback) return void cb(err)

      // turn the stream-able buffers into plain buffers
      out = _.mapValues(outputs, function (stream, entryName){
        var entryBuffer = stream.getContents()

        // for those using the streaming interface, emit an event with the entry
        // do this here so that we don't have to itterate through the outputs twice
        emitter.emit('entry', entryBuffer, entryName)

        return entryBuffer
      })

      // add in the common bundle
      out.common = common

      if (hasCallback) cb(err, out)
    })
  }
  // if we don't need to use factor bundle, just browserify!
  else return b.bundle(cb)
}

ctor.emitter = emitter
<commit_msg>fix sourcemaps always on<commit_after>var browserify   = require('browserify')
  , path         = require('path')
  , fs           = require('fs')
  , events       = require('events')
  , mkdirp       = require('mkdirp')
  , watchify     = require('watchify')
  , ejsify       = require('ejsify')
  , hbsfy        = require('hbsfy')
  , jadeify      = require('jadeify')
  , envify       = require('envify')
  , partialify   = require('partialify')
  , reactify     = require('reactify')
  , brfs         = require('brfs')
  , writer       = require('write-to-path')
  , emitter      = new events.EventEmitter()
  , streamBuffer = require('stream-buffers')
  , _            = require('lodash')
  , minifyify  = require('minifyify')
  , ctor

require('factor-bundle')

ctor = module.exports = function atomifyJs(opts, cb){
  if (Array.isArray(opts)) opts = {entries: opts}
  if (typeof opts === 'string') opts = {entries: [opts]}
  if (opts.entry) opts.entries = [opts.entry]
  if (!opts.entries) opts.entries = []

  if (typeof cb === 'string') opts.output = cb // js('entry.js', 'bundle.js')

  if (opts.output) {
    // we definitely have to write the file
    var outputPath = path.resolve(process.cwd(), opts.output)
      , outputDir = path.dirname(outputPath)
      , writeFile = writer(outputPath, {debug: opts.debug})

    if (!fs.existsSync(outputDir)) mkdirp.sync(outputDir)

    // we might need to call a callback also
    if (typeof cb === 'function') {
      var _outputcb = cb
      cb = function (err, src, map) {
        if (err) return _outputcb(err)
        writeFile(null, src)
        _outputcb(null, src, map)
      }
    }
    else {
      cb = writeFile
    }
  }

  var _buffercb = cb

  cb = function (err, buff, map) {
    if(typeof _buffercb == 'function')
      _buffercb(err, buff, map)
  }

  opts.debug  = opts.debug || false

  if(opts.minify === true) {
    opts.minify = {map: false}
  }
  // Debug mode must be on to get sourcemaps
  else if(typeof opts.minify == 'object') {
    opts.debug = true
  }

  var browserifyOptions = {debug: opts.debug}
    , b
    , w

  if (opts.watch) _.extend(browserifyOptions, watchify.args)

  b = browserify(browserifyOptions)
  emitter.emit('browserify', b)

  if (opts.watch) {
    w = watchify(b)
    emitter.emit('watchify', w)
  }

  if (opts.watch) {
    w.on('update', function onUpdate(ids){
      ids.forEach(function eachId(id){
        emitter.emit('changed', id)
      })

      w.bundle(cb)
    })

    w.on('time', function onTime(time){
      emitter.emit('bundle', time)
    })
  }

  b.on('package', function(pkg){
    emitter.emit('package', pkg)
  })

  opts.entries.forEach(function eachEntry(entry){
    b.add(path.resolve(process.cwd(), entry))
  })

  // Browserify modifies the transforms property once opts is passed in to bundle()
  // so we copy that prop here to ensure we only use what is passed in from config
  if (!opts._transforms) {
    opts._transforms = opts.transforms ? opts.transforms.slice(0) : []
  }

  var transforms = [
      envify
      , ejsify
      , hbsfy
      , jadeify
      , partialify
      , [reactify, {'es6': true}]
    ]
    // ensure brfs runs last because it requires valid js
    .concat(opts._transforms, [brfs])

  transforms.forEach(function eachTransform(transform){
    if (Array.isArray(transform)) {
      b.transform(transform[1], transform[0])
    }
    else {
      b.transform(transform)
    }
  })

  // reset list of global transforms every time
  opts._globalTransforms = opts.globalTransforms ? opts.globalTransforms.slice(0) : []

  if (opts.assets) {
    var assets = ['resrcify', {
      dest: opts.assets.dest || ''
      , prefix: opts.assets.prefix || ''
      , retainName: opts.assets.retainName || ''
    }]

    opts._globalTransforms.push(assets)
  }

  opts._globalTransforms.forEach(function eachGlobalTransform(gt){
    if (Array.isArray(gt)) {
      var gto = gt[1]
      gto.global = true
      b.transform(gto, gt[0])
    }
    else {
      b.transform({global: true}, gt)
    }
  })

  if(typeof opts.minify == 'object') {
    b.plugin(minifyify, opts.minify)
  }

  if (opts.require) {
    if (Array.isArray(opts.require) || typeof opts.require === 'string'){
      opts.require = {file: opts.require}
    }
    b.require(opts.require.file, opts.require.opts)
  }

  if (Array.isArray(opts.external) || typeof opts.external === 'string'){
    b.external(opts.external)
  }

  // if we've got the common option, we want to use factor bundle
  if (opts.common === true){
    if (opts.entries.length < 2) {
      var error = new Error('the `common` option requires an `entries` option with more than one entry')
      cb(error)
      // TODO: we should do this, but it casues tape to falsely see the error event on itself!?
      // emitter.emit('error', error)
      return
    }

    // for each entry, we're going to create a stream-able buffer to put the factored bundle into
    var outputs = {}
    opts.entries.forEach(function createOutputs(entry){
      outputs[path.basename(entry).replace(path.extname(entry), '')] = new streamBuffer.WritableStreamBuffer({
          // these values are arbitrary, but we don't want to require huge buffers
          initialSize: (1 * 1024)         // start as 1 kilobytes.
          , incrementAmount: (1 * 1024)    // grow by 1 kilobytes each time buffer overflows.
      })
    })

    // setup factor bundle, pass in our streamable-buffers as the output source
    b.plugin('factor-bundle', {
      o: _.values(outputs)
    })

    // we need to wrap the callback to output an object with all the bundles
    return b.bundle(function (err, common){
      var hasCallback = _.isFunction(cb)
        , out = {}

      if (err && hasCallback) return void cb(err)

      // turn the stream-able buffers into plain buffers
      out = _.mapValues(outputs, function (stream, entryName){
        var entryBuffer = stream.getContents()

        // for those using the streaming interface, emit an event with the entry
        // do this here so that we don't have to itterate through the outputs twice
        emitter.emit('entry', entryBuffer, entryName)

        return entryBuffer
      })

      // add in the common bundle
      out.common = common

      if (hasCallback) cb(err, out)
    })
  }
  // if we don't need to use factor bundle, just browserify!
  else return b.bundle(cb)
}

ctor.emitter = emitter
<|endoftext|>


<commit_before>"use strict";

module.exports = function(graph) {
  return {
    V: function createVertexStream(startFrom) {
      var VertexPipe = require('./lib/pipes/vertexPipe');
      var VertexIterator = require('./lib/utils/vertexIterator');

      var vertexPipe = new VertexPipe(graph);
      vertexPipe.setStarts(new VertexIterator(graph, startFrom));
      return vertexPipe;
    }
  };
};

var extendIterators = require('./lib/pipeExtensions');
extendIterators();
<commit_msg>Started working on better documentation<commit_after>/**
 * # ngraph.shremlin
 * This is a graph traversal library, inspired by
 * [gremlin](https://github.com/tinkerpop/gremlin)
 *
 * It allows to create complex graph traversal patterns by using simple
 * construction blocks. To best understand shremlin, let's start with example
 *
 * ```
 *   // Let's say we have this oriented, 3x3 grid graph:
 *   // 0 → 1 → 2
 *   // ↓   ↓   ↓
 *   // 3 → 4 → 5
 *   // create graph iterator:
 *   var g = shremlin(graph);
 *
 *   // How to iterate all graph nodes?
 *   g.V()
 *    .forEach(function(node) {
 *      console.log(node.id); // prints 0..5;
 *    });
 *
 *   // How to get node with id "1"?
 *   g.V(1)
 *    .forEach(function(node) {
 *      console.log(node.id); // prints only 1;
 *    });
 *
 *   // Let's print all neighbors of node 1, reachable via
 *   // outgoing edge:
 *   g.V(1)
 *    .out() // get all outgoing neighbors.
 *    .forEach(function(node) {
 *      console.log(node.id); // prints 2, 4;
 *    });
 *
 *   // How about roots of incoming edges?
 *   g.V(1)
 *    .in() // get all "incoming" neighbors
 *    .forEach(function(node) {
 *      console.log(node.id); // prints 0;
 *    });
 * ```
 *
 * Now that you understna basics, let's move on to the file
 */

"use strict";

module.exports = createGraphIterators;

/**
 * Creates a wrapper to iterate over graph. A wrapper contains methods which
 * allows you to begin iteration. Currently we support only vertices as iterator
 * starters, but in future we can easily extend this and add edges
 *
 * @param {ngraph.graph|Viva.Graph.graph} graph source graph we want to iterate over
 *
 */
function createGraphIterators(graph) {
  return {
    /**
     * Creates a vertex iterator stream. This is an entry point for all traversal
     * starting with a node.
     *
     * @param  {string|number} [startFrom] vertex id to start iteration from.
     *  If this argument is ommitted, then all graph nodes are iterated
     *
     * @returns {VertexPipe}
     */
    V: function createVertexStream(startFrom) {
      var VertexPipe = require('./lib/pipes/vertexPipe');
      var VertexIterator = require('./lib/utils/vertexIterator');

      var vertexPipe = new VertexPipe(graph);
      vertexPipe.setStarts(new VertexIterator(graph, startFrom));
      return vertexPipe;
    }
  };
};

// Add syntatic sugar on top of each iterator, so that you can
// chain them together.
var extendIterators = require('./lib/pipeExtensions');
extendIterators();
<|endoftext|>