<commit_before>(function() {
    angular
        .module('angular-swaggerific', [])
        .factory('util', util)
        .factory('AngularSwaggerific', AngularSwaggerific);

    util.$inject = ['$log'];

    function util($log) {
        return {

            /**
             * Replaces path variables with associated data properties
             * @param {String} path
             * @param {Object} data
             * @returns {String}
             */
            replaceInPath: function(path, data) {
                var properties = path.match(/[^{}]+(?=\})/g) || [];
                for (var i = 0; i < properties.length; i++) {
                    var property = properties[i];
                    path = path.replace('{' + property + '}', data[property]);
                }

                return path;
            },

            /**
             * Returns true if a specified array contains a specified value.
             * @param {Object} value
             * @param {Array} array
             * @return {Boolean}
             */
            contains: function(value, array) {
                return array.indexOf(value) >= 0;
            }

        }
    }

    AngularSwaggerific.$inject = ['$log', '$http', 'util'];

    function AngularSwaggerific($log, $http, util) {

        var _json = null;

        /**
         * Represents an AngularSwaggerific object.
         * @constructor
         * @param {string} json - The generated Swagger JSON object.
         * @returns {object} api - Reference to the AngularSwaggerific API object.
         */
        var AngularSwaggerific = function(json) {
            this.api = {};
            this.host = null;

            if (!json || json === '') {
                $log.error("Invalid JSON.");
                return {};
            }

            _json = json;

            return this.init();
        }

        /**
         * Creates the AngularSwaggerific API object.
         * @returns {object} api - Reference to the AngularSwaggerific API object.
         */
        AngularSwaggerific.prototype.init = function() {
            var self = this;

            var scheme = util.contains('https', _json.schemes) ? 'https://' : 'http://';
            self.host = scheme + _json.host + (_json.basePath?_json.basePath:"");

            angular.forEach(_json.paths, function(value, key) {
                angular.forEach(value, function(innerValue, innerKey) {
                    var namespace;
                    if (!innerValue.tags) {
                        /** Set the namespace equal to the first path variable. */
                        namespace = key.split('/')[1];

                        /**
                         * If there is no path variable (i.e. '/'), then set the namespace equal to
                         * the base path.
                         */
                        if (!namespace || namespace === '') {
                            namespace = _json.basePath.split("/")[1];
                        }
                    } else {
                        /** Set the namespace equal to the associated tag. */
                        namespace = innerValue.tags[0]
                    }

                    /** Remove curly braces from the namespace. */
                    namespace = namespace.replace(/[{}]/g, "");

                    /** Create the namespace if it doesn't already exist. */
                    if (!self.api[namespace]) {
                        self.api[namespace] = {};
                    }

                    /**
                     * Map HTTP call to namespace[operationId].
                     * If there is no operationId, then use method (i.e. get, post, put)
                     */
                    if (!innerValue.operationId) {
                        innerValue.operationId = innerKey;
                    }

                    (self.api[namespace])[innerValue.operationId] = function(data, config) {
                        return self.trigger(key, innerKey, data, config);
                    };
                });
            });

            return self.api;
        }

        /**
         * Sets up and executes the HTTP request (using $http) for a specfic path.
         * @param {String} path
         * @param {String} method
         * @param {Object} data
         * @param {Object} [config]
         * @returns {Promise} - Returns a promise from $http which can be chained to by user.
         */
        AngularSwaggerific.prototype.trigger = function(path, method, data, config) {
            var self = this;

            var data = data || {};
            var config = config || {};
            var newPath = util.replaceInPath(path, data);

            var httpConfig = angular.extend({
                method: method,
                url: self.host + newPath,
                data: data
            }, config);

            return $http(httpConfig);
        }

        return AngularSwaggerific;
    }

})(angular);
<commit_msg>added support for GET from previous PR<commit_after>(function() {
    angular
        .module('angular-swaggerific', [])
        .factory('util', util)
        .factory('AngularSwaggerific', AngularSwaggerific);

    util.$inject = ['$log'];

    function util($log) {
        return {

            /**
             * Replaces path variables with associated data properties
             * @param {String} path
             * @param {Object} data
             * @returns {String}
             */
            replaceInPath: function(path, data) {
                var properties = path.match(/[^{}]+(?=\})/g) || [];
                for (var i = 0; i < properties.length; i++) {
                    var property = properties[i];
                    path = path.replace('{' + property + '}', data[property]);
                }

                return path;
            },

            /**
             * Returns true if a specified array contains a specified value.
             * @param {Object} value
             * @param {Array} array
             * @return {Boolean}
             */
            contains: function(value, array) {
                return array.indexOf(value) >= 0;
            }

        }
    }

    AngularSwaggerific.$inject = ['$log', '$http', 'util'];

    function AngularSwaggerific($log, $http, util) {

        var _json = null;

        /**
         * Represents an AngularSwaggerific object.
         * @constructor
         * @param {string} json - The generated Swagger JSON object.
         * @returns {object} api - Reference to the AngularSwaggerific API object.
         */
        var AngularSwaggerific = function(json) {
            this.api = {};
            this.host = null;

            if (!json || json === '') {
                $log.error("Invalid JSON.");
                return {};
            }

            _json = json;

            return this.init();
        }

        /**
         * Creates the AngularSwaggerific API object.
         * @returns {object} api - Reference to the AngularSwaggerific API object.
         */
        AngularSwaggerific.prototype.init = function() {
            var self = this;

            var scheme = util.contains('https', _json.schemes) ? 'https://' : 'http://';
            self.host = scheme + _json.host + (_json.basePath ? _json.basePath : "");

            angular.forEach(_json.paths, function(value, key) {
                angular.forEach(value, function(innerValue, innerKey) {
                    var namespace;
                    if (!innerValue.tags) {
                        /** Set the namespace equal to the first path variable. */
                        namespace = key.split('/')[1];

                        /**
                         * If there is no path variable (i.e. '/'), then set the namespace equal to
                         * the base path.
                         */
                        if (!namespace || namespace === '') {
                            namespace = _json.basePath.split("/")[1];
                        }
                    } else {
                        /** Set the namespace equal to the associated tag. */
                        namespace = innerValue.tags[0]
                    }

                    /** Remove curly braces from the namespace. */
                    namespace = namespace.replace(/[{}]/g, "");

                    /** Create the namespace if it doesn't already exist. */
                    if (!self.api[namespace]) {
                        self.api[namespace] = {};
                    }

                    /**
                     * Map HTTP call to namespace[operationId].
                     * If there is no operationId, then use method (i.e. get, post, put)
                     */
                    if (!innerValue.operationId) {
                        innerValue.operationId = innerKey;
                    }

                    (self.api[namespace])[innerValue.operationId] = function(data, config) {
                        return self.trigger(key, innerKey, data, config);
                    };
                });
            });

            return self.api;
        }

        /**
         * Sets up and executes the HTTP request (using $http) for a specfic path.
         * @param {String} path
         * @param {String} method
         * @param {Object} data
         * @param {Object} [config]
         * @returns {Promise} - Returns a promise from $http which can be chained to by user.
         */
        AngularSwaggerific.prototype.trigger = function(path, method, data, config) {
            var self = this;

            var getParams, postData;
            if (angular.lowercase(method) === 'get') {
                getParams = data || {};
            } else {
                postData = data || {};
            }
            var config = config || {};
            var newPath = util.replaceInPath(path, data);

            var httpConfig = angular.extend({
                method: method,
                url: self.host + newPath,
				data: postData,
				params: getParams
            }, config);

            console.debug(httpConfig);

            return $http(httpConfig);
        }

        return AngularSwaggerific;
    }

})(angular);
<|endoftext|>


<commit_before>/*
   Jooks
   Copyright : 2014
   Contributor : ppalludan
*/
(function() {
	var jook = this;

	// references
	jook.options = require('./options');
	jook.repositories = new Array();

	jook.main = function(args) {
		var program = require('commander');
		var colors = require('colors');
		var pjson = require('../package.json');

		// Process program arguments
		program.version(pjson.version)
	      .option('-p, --port [number]', 'Port Number (default: ' + jook.options.port)
	      .option('-c, --config [filename]', 'Configuration Filename (default: ' + jook.options.files.config);

		program.on('--help', function(){
	      console.log('  Examples:');
	      console.log('');
	      console.log('    jook --help');
	      console.log('    jook --p 9001');
	      console.log('');
	    });
	    program.parse(args);

	 	if (program.config && program.config!=true) {
	 		jook.options.files.config = program.config;
	 	}

   	 	jook.readConfig()

	 	// Set the port if none present
	 	if (!isNaN(parseInt(program.port,10))) {
			jook.options.port = parseInt(program.port, 10);
	 	}

	 	// Start the webserver to handle the webhooks
		jook.startServer();

		// writing out the status for the repositories
		console.log('['.grey +('Jook v ' + program._version + ' running').cyan + ']'.grey + ' ' +
			'['.grey + ('Port: ' + jook.options.port + ', config: ' + jook.options.files.config).cyan + ']'.grey);

		jook.repositories.map(function(rep) {
			console.log('\tRepository: ' + rep.name);
		})
	}

	jook.startServer = function(options) {
		var http = require('http');

		var server = http.createServer(jook.handleRequest).listen(jook.options.port);
	}

	jook.handleRequest = function(req, res) {
		if (req.method == 'POST') {
			var payLoad = '';

			req.on('data', function(chunk) {
				console.log('data');
				payLoad += chunk;
			});

			req.on('end', function() {
				jook.offLoad(JSON.parse(payLoad), function(err) {

					if (err) {
						res.writeHead(500, {'Content-Type':'application/json'});
						res.write('err: ' + err);
					} else {
						res.writeHead(200, {'Content-Type':'application/json'});
						res.write('ok');
					}
					res.end();
				});
			});
		} else {
			res.writeHead(200, {'Content-Type':'application/json'});
            res.write('yes hello?');
			res.end();
		}
	}

	jook.offLoad = function(payLoad, callback) {
		var exec = require('child_process').exec;

		exec('ls', function (error, stdout, stderr) {
		  	console.log(stdout);
		});
	}

	jook.readConfig = function(options) {
		var fs = require('fs');
		var path = require('path');

		var file = path.join(path.dirname(fs.realpathSync(__filename)), jook.options.files.config);

		if (!fs.existsSync(file)) {
			throw 'Config File not found: ' + jook.options.files.config;
		}

		var data = fs.readFileSync(file);
    	var json = JSON.parse(data);

		if (!isNaN(parseInt(json.port,10))) {
			jook.options.port = parseInt(json.port, 10);
	 	}

    	if (json.repositories == null || json.repositories.length == 0) {
    		throw 'Repositories not defined in config';
    	}

    	json.repositories.map(function(rep) {
    		if (rep == null || rep.name == null || rep.process==null)
    			return;

    		var process = new Array();

    		var repository = {
    			name : rep.name,
    			process : new Array()
    		};

    		rep.process.map(function(p) {
    			process.push({
    				exec : p.exec
    			});
    		});

    		jook.repositories.push(repository);
    	})
	}

	jook.main(process.argv);

}).call(this);<commit_msg>Fix to config read issue, from current work directory<commit_after>/*
   Jooks
   Copyright : 2014
   Contributor : ppalludan
*/
(function() {
	var jook = this;

	// references
	jook.options = require('./options');
	jook.repositories = new Array();

	jook.main = function(args, cwd) {
		var program = require('commander');
		var colors = require('colors');
		var pjson = require('../package.json');

		// Process program arguments
		program.version(pjson.version)
	      .option('-p, --port [number]', 'Port Number (default: ' + jook.options.port)
	      .option('-c, --config [filename]', 'Configuration Filename (default: ' + jook.options.files.config);

		program.on('--help', function(){
	      console.log('  Examples:');
	      console.log('');
	      console.log('    jook --help');
	      console.log('    jook --p 9001');
	      console.log('');
	    });
	    program.parse(args);

	 	if (program.config && program.config!=true) {
	 		jook.options.files.config = program.config;
	 	}

   	 	jook.readConfig(jook.options, cwd);

	 	// Set the port if none present
	 	if (!isNaN(parseInt(program.port,10))) {
			jook.options.port = parseInt(program.port, 10);
	 	}

	 	// Start the webserver to handle the webhooks
		jook.startServer();

		// writing out the status for the repositories
		console.log('['.grey +('Jook v ' + program._version + ' running').cyan + ']'.grey + ' ' +
			'['.grey + ('Port: ' + jook.options.port + ', config: ' + jook.options.files.config).cyan + ']'.grey);

		jook.repositories.map(function(rep) {
			console.log('\tRepository: ' + rep.name);
		})
	}

	jook.startServer = function(options) {
		var http = require('http');

		var server = http.createServer(jook.handleRequest).listen(jook.options.port);
	}

	jook.handleRequest = function(req, res) {
		if (req.method == 'POST') {
			var payLoad = '';

			req.on('data', function(chunk) {
				console.log('data');
				payLoad += chunk;
			});

			req.on('end', function() {
				jook.offLoad(JSON.parse(payLoad), function(err) {

					if (err) {
						res.writeHead(500, {'Content-Type':'application/json'});
						res.write('err: ' + err);
					} else {
						res.writeHead(200, {'Content-Type':'application/json'});
						res.write('ok');
					}
					res.end();
				});
			});
		} else {
			res.writeHead(200, {'Content-Type':'application/json'});
            res.write('yes hello?');
			res.end();
		}
	}

	jook.offLoad = function(payLoad, callback) {
		var exec = require('child_process').exec;

		exec('ls', function (error, stdout, stderr) {
		  	console.log(stdout);
		});
	}

	jook.readConfig = function(options, cwd) {
		var fs = require('fs');
		var path = require('path');

		var file = path.join(cwd, jook.options.files.config);

		if (!fs.existsSync(file)) {
			throw 'Config File not found: ' + jook.options.files.config;
		}

		var data = fs.readFileSync(file);
    	var json = JSON.parse(data);

		if (!isNaN(parseInt(json.port,10))) {
			jook.options.port = parseInt(json.port, 10);
	 	}

    	if (json.repositories == null || json.repositories.length == 0) {
    		throw 'Repositories not defined in config';
    	}

    	json.repositories.map(function(rep) {
    		if (rep == null || rep.name == null || rep.process==null)
    			return;

    		var process = new Array();

    		var repository = {
    			name : rep.name,
    			process : new Array()
    		};

    		rep.process.map(function(p) {
    			process.push({
    				exec : p.exec
    			});
    		});

    		jook.repositories.push(repository);
    	})
	}

	jook.main(process.argv, process.cwd());

}).call(this);<|endoftext|>


<commit_before>"use babel";
"use strict";

let {CompositeDisposable} = require("atom");

module.exports = {

  decorations: {},

  activate () {
    this.subscriptions = new CompositeDisposable();
  },

  deactivate () {
    this.subscriptions.dispose();
    this.subscriptions = null;
  },

  subscribe (...args) {
    this.subscriptions.add(...args);
  },

  consumeVimModePlus (service) {
    let
      { Base, observeVimStates } = service,
      self = this;

    let observer = (vimState) => {
      vimState.onDidSetMark(({ name, bufferPosition, editor }) => {
        if (name.match(/[^\w]/)) return; // only alpha

        if (self.decorations[name]) {
          let dec = self.decorations[name];
          dec.destroy();
        }

        let
          range = { start: bufferPosition, end: bufferPosition },
          marker = editor.markBufferRange(range, {invalidate: "never"}),
          decoration = editor.decorateMarker(marker, { type: "line-number", class: `vmp-mark-${name}`});

        self.decorations[name] = decoration;
      });
    };

    this.subscribe(observeVimStates(observer));
  },
};
<commit_msg>fixes #1 + added some abstraction<commit_after>"use babel";
"use strict";

let {CompositeDisposable} = require("atom");

module.exports = {

  decorations: {},

  activate () {
    this.subscriptions = new CompositeDisposable();
  },

  deactivate () {
    this.subscriptions.dispose();
    this.subscriptions = null;
  },

  subscribe (...args) {
    this.subscriptions.add(...args);
  },

  // getter / setters

  uniqueIt (name, editor) {
    return `${editor.id}${name}`; // 10a
  },

  getMark (name, editor) {
    return this.decorations[this.uniqueIt(name, editor)];
  },

  saveMark (name, editor, decoration) {
    this.decorations[this.uniqueIt(name, editor)] = decoration;
  },

  // mark listener

  consumeVimModePlus (service) {
    let
      { Base, observeVimStates } = service,
      self = this;

    let observer = (vimState) => {
      vimState.onDidSetMark(({ name, bufferPosition, editor }) => {
        if (name.match(/[^\w]/)) return; // only alpha

        let prevMark;
        if (prevMark = self.getMark(name, editor)) {
          prevMark.destroy();
        }

        let
          range = { start: bufferPosition, end: bufferPosition },
          marker = editor.markBufferRange(range, {invalidate: "never"}),
          decoration = editor.decorateMarker(marker, { type: "line-number", class: `vmp-mark-${name}`});

        self.saveMark(name, editor, decoration);
      });
    };

    this.subscribe(observeVimStates(observer));
  },
};
<|endoftext|>


<commit_before>var linter = require("./linter");
var reporter = require("./reporter");
var nopt = require("nopt");
var fs = require("fs");
var glob;
var con = console;
var pro = process;

/*jslint nomen: true*/
var currentDir = __dirname;
/*jslint nomen: false */

try {
    glob = require("glob");
    exports.glob = glob;
} catch (ignore) {}

exports.setConsole = function (c) {
    'use strict';
    con = c;
};

exports.setProcess = function (p) {
    'use strict';
    pro = p;
};

function commandOptions() {
    'use strict';

    /* flags defined in jslint-latest.js */
    var jslintFlags = [
        'ass', 'bitwise', 'browser', 'closure', 'continue',
        'debug', 'devel', 'eqeq', 'evil', 'forin', 'newcap',
        'node', 'nomen', 'passfail', 'plusplus', 'properties',
        'regexp', 'rhino', 'unparam', 'sloppy', 'stupid', 'sub',
        'todo', 'vars', 'white'
    ],
        /* flags used by node-jslint to control output */
        cliFlags = [
            'json', 'color', 'terse', 'version'
        ],
        /* not used by jslint-latest.js */
        deprecatedFlags = [
            'anon', 'es5', 'on', 'undef', 'windows'
        ],
        flags = jslintFlags.concat(cliFlags).concat(deprecatedFlags),
        commandOpts = {
            'indent' : Number,
            'maxerr' : Number,
            'maxlen' : Number,
            'predef' : [String, Array],
            'edition' : String
        };

    flags.forEach(function (option) {
        commandOpts[option] = Boolean;
    });

    return commandOpts;
}
exports.commandOptions = commandOptions;

function die(why) {
    'use strict';
    var o = commandOptions();
    con.warn(why);
    con.warn("Usage: " + pro.argv[1] +
        " [--" + Object.keys(o).sort().join("] [--") +
        "] [--] <scriptfile>...");
    pro.exit(1);
}

function parseArgs(argv) {
    'use strict';
    return nopt(commandOptions(), {}, argv);
}
exports.parseArgs = parseArgs;

exports.reportVersion = function reportVersion(callback, options) {
    'use strict';
    var path = require("path"),
        packageFile = path.join(currentDir, "../package.json");

    fs.readFile(packageFile, function (err, data) {
        if (err) {
            die(err);
        }

        var package_data = JSON.parse(data),
            version = package_data.version,
            edition = linter.loadJSLint(options).edition;

        callback("node-jslint version: " + version + "  JSLint edition " + edition);
    });

};

exports.main = function () {
    'use strict';
    exports.runMain(parseArgs());
};

function identity(pattern) {
    'use strict';
    return pattern;
}

function expandGlob(glob) {
    'use strict';
    if (!glob) {
        return identity;
    }

    return function (pattern) {
        return glob.sync(pattern);
    };
}
exports.expandGlob = expandGlob;

function noNodeModules(file) {
    'use strict';
    return file.indexOf('node_modules') === -1;
}
exports.noNodeModules = noNodeModules;

function flatten(a, b) {
    'use strict';

    return a.concat(b);
}

function globFiles(list, glob) {
    'use strict';
    var remain = [];

    remain = list.map(expandGlob(glob)).reduce(flatten, []).filter(noNodeModules);

    return remain;
}
exports.globFiles = globFiles;

function consoleReport(file, lint) {
    'use strict';
    con.log(JSON.stringify([file, lint.errors]));
}

function makeLintFile(parsed, maybeExit, reporter) {
    'use strict';
    return function lintFile(file) {
        fs.readFile(file, 'utf8', function (err, data) {
            if (err) {
                con.log(err);
                return;
            }

            var lint = linter.lint(data, parsed);

            reporter(file, lint, parsed.color, parsed.terse);

            maybeExit(lint);
        });
    };
}

function makeReporter(parsed) {
    'use strict';
    if (parsed.json) {
        return consoleReport;
    }

    return reporter.report.bind(reporter);
}

exports.runMain = function (parsed) {
    'use strict';

    var maybeExit,
        lintFile,
        remain = [];

    if (parsed.version) {
        exports.reportVersion(con.log, parsed);
        return;
    }

    if (!parsed.argv.remain.length) {
        die("No files specified.");
    }

    remain = globFiles(parsed.argv.remain, glob);

    // If there are no more files to be processed, exit with the value 1
    // if any of the files contains any lint.
    maybeExit = (function () {
        var filesLeft = remain.length,
            ok = true;

        function exitWithCode() {
            var code = ok ? 0 : 1;
            pro.exit(code);
        }

        return function (lint) {
            filesLeft -= 1;
            ok = lint.ok && ok;

            if (filesLeft === 0) {
                exitWithCode();
            }
        };
    }());

    lintFile = makeLintFile(parsed, maybeExit, makeReporter(parsed));

    remain.forEach(lintFile);
};
<commit_msg>main: remove now-unused main fn<commit_after>var linter = require("./linter");
var reporter = require("./reporter");
var nopt = require("nopt");
var fs = require("fs");
var glob;
var con = console;
var pro = process;

/*jslint nomen: true*/
var currentDir = __dirname;
/*jslint nomen: false */

try {
    glob = require("glob");
    exports.glob = glob;
} catch (ignore) {}

exports.setConsole = function (c) {
    'use strict';
    con = c;
};

exports.setProcess = function (p) {
    'use strict';
    pro = p;
};

function commandOptions() {
    'use strict';

    /* flags defined in jslint-latest.js */
    var jslintFlags = [
        'ass', 'bitwise', 'browser', 'closure', 'continue',
        'debug', 'devel', 'eqeq', 'evil', 'forin', 'newcap',
        'node', 'nomen', 'passfail', 'plusplus', 'properties',
        'regexp', 'rhino', 'unparam', 'sloppy', 'stupid', 'sub',
        'todo', 'vars', 'white'
    ],
        /* flags used by node-jslint to control output */
        cliFlags = [
            'json', 'color', 'terse', 'version'
        ],
        /* not used by jslint-latest.js */
        deprecatedFlags = [
            'anon', 'es5', 'on', 'undef', 'windows'
        ],
        flags = jslintFlags.concat(cliFlags).concat(deprecatedFlags),
        commandOpts = {
            'indent' : Number,
            'maxerr' : Number,
            'maxlen' : Number,
            'predef' : [String, Array],
            'edition' : String
        };

    flags.forEach(function (option) {
        commandOpts[option] = Boolean;
    });

    return commandOpts;
}
exports.commandOptions = commandOptions;

function die(why) {
    'use strict';
    var o = commandOptions();
    con.warn(why);
    con.warn("Usage: " + pro.argv[1] +
        " [--" + Object.keys(o).sort().join("] [--") +
        "] [--] <scriptfile>...");
    pro.exit(1);
}

function parseArgs(argv) {
    'use strict';
    return nopt(commandOptions(), {}, argv);
}
exports.parseArgs = parseArgs;

exports.reportVersion = function reportVersion(callback, options) {
    'use strict';
    var path = require("path"),
        packageFile = path.join(currentDir, "../package.json");

    fs.readFile(packageFile, function (err, data) {
        if (err) {
            die(err);
        }

        var package_data = JSON.parse(data),
            version = package_data.version,
            edition = linter.loadJSLint(options).edition;

        callback("node-jslint version: " + version + "  JSLint edition " + edition);
    });

};

function identity(pattern) {
    'use strict';
    return pattern;
}

function expandGlob(glob) {
    'use strict';
    if (!glob) {
        return identity;
    }

    return function (pattern) {
        return glob.sync(pattern);
    };
}
exports.expandGlob = expandGlob;

function noNodeModules(file) {
    'use strict';
    return file.indexOf('node_modules') === -1;
}
exports.noNodeModules = noNodeModules;

function flatten(a, b) {
    'use strict';

    return a.concat(b);
}

function globFiles(list, glob) {
    'use strict';
    var remain = [];

    remain = list.map(expandGlob(glob)).reduce(flatten, []).filter(noNodeModules);

    return remain;
}
exports.globFiles = globFiles;

function consoleReport(file, lint) {
    'use strict';
    con.log(JSON.stringify([file, lint.errors]));
}

function makeLintFile(parsed, maybeExit, reporter) {
    'use strict';
    return function lintFile(file) {
        fs.readFile(file, 'utf8', function (err, data) {
            if (err) {
                con.log(err);
                return;
            }

            var lint = linter.lint(data, parsed);

            reporter(file, lint, parsed.color, parsed.terse);

            maybeExit(lint);
        });
    };
}

function makeReporter(parsed) {
    'use strict';
    if (parsed.json) {
        return consoleReport;
    }

    return reporter.report.bind(reporter);
}

exports.runMain = function (parsed) {
    'use strict';

    var maybeExit,
        lintFile,
        remain = [];

    if (parsed.version) {
        exports.reportVersion(con.log, parsed);
        return;
    }

    if (!parsed.argv.remain.length) {
        die("No files specified.");
    }

    remain = globFiles(parsed.argv.remain, glob);

    // If there are no more files to be processed, exit with the value 1
    // if any of the files contains any lint.
    maybeExit = (function () {
        var filesLeft = remain.length,
            ok = true;

        function exitWithCode() {
            var code = ok ? 0 : 1;
            pro.exit(code);
        }

        return function (lint) {
            filesLeft -= 1;
            ok = lint.ok && ok;

            if (filesLeft === 0) {
                exitWithCode();
            }
        };
    }());

    lintFile = makeLintFile(parsed, maybeExit, makeReporter(parsed));

    remain.forEach(lintFile);
};
<|endoftext|>


<commit_before>"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(e){if("object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.GitHubCalendar=e()}}(function(){return function e(t,n,r){function a(u,s){if(!n[u]){if(!t[u]){var c="function"==typeof require&&require;if(!s&&c)return c(u,!0);if(o)return o(u,!0);var i=new Error("Cannot find module '"+u+"'");throw i.code="MODULE_NOT_FOUND",i}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return a(n?n:e)},l,l.exports,e,t,n,r)}return n[u].exports}for(var o="function"==typeof require&&require,u=0;u<r.length;u++)a(r[u]);return a}({1:[function(e,t){var n=e("github-calendar-parser"),r=e("elly"),a=e("add-subtract-date"),o=e("formatoid"),u="MMM D, YYYY";t.exports=function(e,t,s){"string"==typeof e&&(e=document.querySelector(e)),s=s||{},s.summary_text=s.summary_text||'Summary of pull requests, issues opened, and commits made by @'+t+"",s.proxy=s.proxy||function(e){return"https://urlreq.appspot.com/req?method=GET&url="+e};var c=function i(){return fetch(s.proxy("https://github.com/"+t)).then(function(e){return e.text()}).then(function(t){var c=document.createElement("div");c.innerHTML=t;var l=c.querySelector("#contributions-calendar");if(l.querySelector(".left.text-muted").innerHTML=s.summary_text,l.querySelector("include-fragment"))setTimeout(i,500);else{if(s.global_stats!==!1){var f=n(r("svg",l).outerHTML),d=f.current_streak?o(f.current_streak_range[0],u)+" – "+o(f.current_streak_range[1],u):f.last_contributed?"Last contributed in "+o(f.last_contributed,u)+".":"Rock - Hard Place",p=f.longest_streak?o(f.longest_streak_range[0],u)+" – "+o(f.longest_streak_range[1],u):f.last_contributed?"Last contributed in "+o(f.last_contributed,u)+".":"Rock - Hard Place",g=r("
",{"class":"contrib-column contrib-column-first table-column",html:'Contributions in the last year\n                               '+f.last_year+' total\n                               '+o(a.subtract(new Date,1,"year"),u)+" – "+o(new Date,u)+""}),y=r("
",{"class":"contrib-column table-column",html:'Longest streak\n                               '+f.longest_streak+' days\n                               '+p+""}),m=r("
",{"class":"contrib-column table-column",html:'Current streak\n                               '+f.current_streak+' days\n                               '+d+""});l.appendChild(g),l.appendChild(y),l.appendChild(m)}e.innerHTML=l.innerHTML}})};return c()}},{"add-subtract-date":2,elly:4,formatoid:6,"github-calendar-parser":8}],2:[function(e,t){function n(e){return function t(n,r,a){switch(r=e*r,a){case"years":case"year":n.setFullYear(n.getFullYear()+r);break;case"months":case"month":n.setMonth(n.getMonth()+r);break;case"weeks":case"week":return t(n,7*r,"days");case"days":case"day":n.setDate(n.getDate()+r);break;case"hours":case"hour":n.setHours(n.getHours()+r);break;case"minutes":case"minute":n.setMinutes(n.getMinutes()+r);break;case"seconds":case"second":n.setSeconds(n.getSeconds()+r);break;case"milliseconds":case"millisecond":n.setMilliseconds(n.getMilliseconds()+r);break;default:throw new Error("Invalid range: "+a)}return n}}t.exports={add:n(1),subtract:n(-1)}},{}],3:[function(e,t){t.exports=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],t.exports.abbr=["Sun","Mon","Tue","Wed","Thur","Fri","Sat"],t.exports["short"]=["Su","Mo","Tu","We","Th","Fr","Sa"]},{}],4:[function(e,t){function n(e,t){return"string"==typeof e?"<"===e.charAt(0)?(e=document.createElement(e.slice(1,-1)),r(t||{},function(t,n){switch(n){case"text":return void(e.textContent=t);case"html":return void(e.innerHTML=t)}e.setAttribute(n,t)}),e):(t=t||document,t.querySelector(e)):e}var r=e("iterate-object");n.$$=function(e,t){return t=t||document,t.querySelectorAll(e)},t.exports=n},{"iterate-object":9}],5:[function(e,t){t.exports=function(e,t,n){t=t||2,n=n||"0",e=e.toString();var r=t-e.length;return(0>=r?"":n.repeat(r))+e}},{}],6:[function(e,t){var n=e("months"),r=e("days"),a=e("fillo"),o=e("parse-it").Parser,u=new o({YYYY:function(e){return e.getFullYear()},YY:function(e){return e.getFullYear()%100},MMMM:function(e){return n[e.getMonth()]},MMM:function(e){return n.abbr[e.getMonth()]},MM:function(e){return a(e.getMonth()+1)},M:function(e){return e.getMonth()+1},dddd:function(e){return r[e.getDay()]},ddd:function(e){return r.abbr[e.getDay()]},dd:function(e){return r["short"][e.getDay()]},d:function(e){return e.getDay()},DD:function(e){return a(e.getDate())},D:function(e){return e.getDate()},A:function(e){return e.getHours()>=12?"PM":"AM"},a:function(e){return e.getHours()>=12?"pm":"am"},hh:function(e){return a(e.getHours()%12||12)},h:function(e){return e.getHours()%12||12},HH:function(e){return a(e.getHours())},H:function(e){return e.getHours()},mm:function(e){return a(e.getMinutes())},m:function(e){return e.getMinutes()},ss:function(e){return a(e.getSeconds())},s:function(e){return e.getSeconds()}});t.exports=function(e,t){return u.run(t,[e])}},{days:3,fillo:5,months:10,"parse-it":11}],7:[function(e,t){t.exports=["#eee","#d6e685","#8cc665","#44a340","#1e6823"]},{}],8:[function(e,t){var n=e("github-calendar-legend");t.exports=function(e){var t={last_year:0,longest_streak:-1,longest_streak_range:[],current_streak:0,current_streak_range:[],weeks:[],days:[],last_contributed:null},r=[],a=function(){t.current_streak>t.longest_streak&&(t.longest_streak=t.current_streak,t.longest_streak_range[0]=t.current_streak_range[0],t.longest_streak_range[1]=t.current_streak_range[1])};return e.split("\n").slice(2).map(function(e){return e.trim()}).forEach(function(e){if(e.startsWith("<g transform"))return r.length&&t.weeks.push(r)&&(r=[]);var o=e.match(/fill="(#[a-z0-9]+)"/),u=e.match(/data-date="([0-9\-]+)"/),s=e.match(/data-count="([0-9]+)"/);if(o=o&&o[1],u=u&&u[1],s=s&&+s[1],o){var c={fill:o,date:new Date(u),count:s,level:n.indexOf(o)};0===t.current_streak&&(t.current_streak_range[0]=c.date),c.count?(++t.current_streak,t.last_year+=c.count,t.last_contributed=c.date,t.current_streak_range[1]=c.date):(a(),t.current_streak=0),r.push(c),t.days.push(c)}}),a(),t}},{"github-calendar-legend":7}],9:[function(e,t){function n(e,t){var n=0,r=[];if(Array.isArray(e))for(;n<e.length&&t(e[n],n,e)!==!1;++n);else if("object"===("undefined"==typeof e?"undefined":_typeof(e))&&null!==e)for(r=Object.keys(e);n<r.length&&t(e[r[n]],r[n],e)!==!1;++n);}t.exports=n},{}],10:[function(e,t){t.exports=["January","February","March","April","May","June","July","August","September","October","November","December"],t.exports.abbr=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},{}],11:[function(e,t){function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t,n){return new u(t).run(e,n)}var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=e("regex-escape"),u=function(){function e(t){n(this,e),this.obj=t||{},this.re=new RegExp("^("+Object.keys(t).map(o).join("|")+")")}return a(e,[{key:"run",value:function(e,t){var n="";t=t||[];do{var r=e.match(this.re),a=r&&r[1],o=a||e.charAt(0);if(a){var u=this.obj[a];"function"==typeof u&&(u=u.apply(this,t)),n+=u}else n+=o;e=e.substring(o.length)}while(e);return n}}]),e}();r.Parser=u,t.exports=r},{"regex-escape":12}],12:[function(e,t){function n(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}n.proto=function(){return RegExp.escape=n,n},t.exports=n},{}]},{},[1])(1)});<commit_msg>Rebuild<commit_after>"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(e){if("object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.GitHubCalendar=e()}}(function(){return function e(t,n,r){function a(u,s){if(!n[u]){if(!t[u]){var c="function"==typeof require&&require;if(!s&&c)return c(u,!0);if(o)return o(u,!0);var i=new Error("Cannot find module '"+u+"'");throw i.code="MODULE_NOT_FOUND",i}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return a(n?n:e)},l,l.exports,e,t,n,r)}return n[u].exports}for(var o="function"==typeof require&&require,u=0;u<r.length;u++)a(r[u]);return a}({1:[function(e,t){var n=e("github-calendar-parser"),r=e("elly"),a=e("add-subtract-date"),o=e("formatoid"),u="MMM D, YYYY";t.exports=function(e,t,s){e=r(e),s=s||{},s.summary_text=s.summary_text||'Summary of pull requests, issues opened, and commits made by @'+t+"",s.global_stats!==!1&&(e.style.minHeight="auto"),s.proxy=s.proxy||function(e){return"https://urlreq.appspot.com/req?method=GET&url="+e};var c=function i(){return fetch(s.proxy("https://github.com/"+t)).then(function(e){return e.text()}).then(function(t){var c=document.createElement("div");c.innerHTML=t;var l=c.querySelector("#contributions-calendar");if(l.querySelector(".left.text-muted").innerHTML=s.summary_text,l.querySelector("include-fragment"))setTimeout(i,500);else{if(s.global_stats!==!1){var f=n(r("svg",l).outerHTML),d=f.current_streak?o(f.current_streak_range[0],u)+" – "+o(f.current_streak_range[1],u):f.last_contributed?"Last contributed in "+o(f.last_contributed,u)+".":"Rock - Hard Place",p=f.longest_streak?o(f.longest_streak_range[0],u)+" – "+o(f.longest_streak_range[1],u):f.last_contributed?"Last contributed in "+o(f.last_contributed,u)+".":"Rock - Hard Place",g=r("
",{"class":"contrib-column contrib-column-first table-column",html:'Contributions in the last year\n                               '+f.last_year+' total\n                               '+o(a.subtract(new Date,1,"year"),u)+" – "+o(new Date,u)+""}),m=r("
",{"class":"contrib-column table-column",html:'Longest streak\n                               '+f.longest_streak+' days\n                               '+p+""}),y=r("
",{"class":"contrib-column table-column",html:'Current streak\n                               '+f.current_streak+' days\n                               '+d+""});l.appendChild(g),l.appendChild(m),l.appendChild(y)}e.innerHTML=l.innerHTML}})};return c()}},{"add-subtract-date":2,elly:4,formatoid:6,"github-calendar-parser":8}],2:[function(e,t){function n(e){return function t(n,r,a){switch(r=e*r,a){case"years":case"year":n.setFullYear(n.getFullYear()+r);break;case"months":case"month":n.setMonth(n.getMonth()+r);break;case"weeks":case"week":return t(n,7*r,"days");case"days":case"day":n.setDate(n.getDate()+r);break;case"hours":case"hour":n.setHours(n.getHours()+r);break;case"minutes":case"minute":n.setMinutes(n.getMinutes()+r);break;case"seconds":case"second":n.setSeconds(n.getSeconds()+r);break;case"milliseconds":case"millisecond":n.setMilliseconds(n.getMilliseconds()+r);break;default:throw new Error("Invalid range: "+a)}return n}}t.exports={add:n(1),subtract:n(-1)}},{}],3:[function(e,t){t.exports=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],t.exports.abbr=["Sun","Mon","Tue","Wed","Thur","Fri","Sat"],t.exports["short"]=["Su","Mo","Tu","We","Th","Fr","Sa"]},{}],4:[function(e,t){function n(e,t){return"string"==typeof e?"<"===e.charAt(0)?(e=document.createElement(e.slice(1,-1)),r(t||{},function(t,n){switch(n){case"text":return void(e.textContent=t);case"html":return void(e.innerHTML=t)}e.setAttribute(n,t)}),e):(t=t||document,t.querySelector(e)):e}var r=e("iterate-object");n.$$=function(e,t){return t=t||document,t.querySelectorAll(e)},t.exports=n},{"iterate-object":9}],5:[function(e,t){t.exports=function(e,t,n){t=t||2,n=n||"0",e=e.toString();var r=t-e.length;return(0>=r?"":n.repeat(r))+e}},{}],6:[function(e,t){var n=e("months"),r=e("days"),a=e("fillo"),o=e("parse-it").Parser,u=new o({YYYY:function(e){return e.getFullYear()},YY:function(e){return e.getFullYear()%100},MMMM:function(e){return n[e.getMonth()]},MMM:function(e){return n.abbr[e.getMonth()]},MM:function(e){return a(e.getMonth()+1)},M:function(e){return e.getMonth()+1},dddd:function(e){return r[e.getDay()]},ddd:function(e){return r.abbr[e.getDay()]},dd:function(e){return r["short"][e.getDay()]},d:function(e){return e.getDay()},DD:function(e){return a(e.getDate())},D:function(e){return e.getDate()},A:function(e){return e.getHours()>=12?"PM":"AM"},a:function(e){return e.getHours()>=12?"pm":"am"},hh:function(e){return a(e.getHours()%12||12)},h:function(e){return e.getHours()%12||12},HH:function(e){return a(e.getHours())},H:function(e){return e.getHours()},mm:function(e){return a(e.getMinutes())},m:function(e){return e.getMinutes()},ss:function(e){return a(e.getSeconds())},s:function(e){return e.getSeconds()}});t.exports=function(e,t){return u.run(t,[e])}},{days:3,fillo:5,months:10,"parse-it":11}],7:[function(e,t){t.exports=["#eee","#d6e685","#8cc665","#44a340","#1e6823"]},{}],8:[function(e,t){var n=e("github-calendar-legend");t.exports=function(e){var t={last_year:0,longest_streak:-1,longest_streak_range:[],current_streak:0,current_streak_range:[],weeks:[],days:[],last_contributed:null},r=[],a=function(){t.current_streak>t.longest_streak&&(t.longest_streak=t.current_streak,t.longest_streak_range[0]=t.current_streak_range[0],t.longest_streak_range[1]=t.current_streak_range[1])};return e.split("\n").slice(2).map(function(e){return e.trim()}).forEach(function(e){if(e.startsWith("<g transform"))return r.length&&t.weeks.push(r)&&(r=[]);var o=e.match(/fill="(#[a-z0-9]+)"/),u=e.match(/data-date="([0-9\-]+)"/),s=e.match(/data-count="([0-9]+)"/);if(o=o&&o[1],u=u&&u[1],s=s&&+s[1],o){var c={fill:o,date:new Date(u),count:s,level:n.indexOf(o)};0===t.current_streak&&(t.current_streak_range[0]=c.date),c.count?(++t.current_streak,t.last_year+=c.count,t.last_contributed=c.date,t.current_streak_range[1]=c.date):(a(),t.current_streak=0),r.push(c),t.days.push(c)}}),a(),t}},{"github-calendar-legend":7}],9:[function(e,t){function n(e,t){var n=0,r=[];if(Array.isArray(e))for(;n<e.length&&t(e[n],n,e)!==!1;++n);else if("object"===("undefined"==typeof e?"undefined":_typeof(e))&&null!==e)for(r=Object.keys(e);n<r.length&&t(e[r[n]],r[n],e)!==!1;++n);}t.exports=n},{}],10:[function(e,t){t.exports=["January","February","March","April","May","June","July","August","September","October","November","December"],t.exports.abbr=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},{}],11:[function(e,t){function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t,n){return new u(t).run(e,n)}var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),o=e("regex-escape"),u=function(){function e(t){n(this,e),this.obj=t||{},this.re=new RegExp("^("+Object.keys(t).map(o).join("|")+")")}return a(e,[{key:"run",value:function(e,t){var n="";t=t||[];do{var r=e.match(this.re),a=r&&r[1],o=a||e.charAt(0);if(a){var u=this.obj[a];"function"==typeof u&&(u=u.apply(this,t)),n+=u}else n+=o;e=e.substring(o.length)}while(e);return n}}]),e}();r.Parser=u,t.exports=r},{"regex-escape":12}],12:[function(e,t){function n(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}n.proto=function(){return RegExp.escape=n,n},t.exports=n},{}]},{},[1])(1)});<|endoftext|>


<commit_before>// Load in dependencies
var EventEmitter = require('events').EventEmitter;
var inherits = require('inherits');
var Keyboard = require('./keyboard');
var Mouse = require('./mouse');

// Define selector constants
var SELECTORS = {};
SELECTORS.info = {
  id: 'playerSongInfo'
};
SELECTORS.shuffle = {
  buttonSelector: '#player sj-icon-button[data-id="shuffle"]'
};
SELECTORS.repeat = {
  buttonSelector: '#player sj-icon-button[data-id="repeat"]'
};
SELECTORS.playPause = {
  buttonSelector: '#player sj-icon-button[data-id="play-pause"]'
};
SELECTORS.slider = {
  id: 'material-player-progress'
};
SELECTORS.rating = {
  containerSelector: '#player .player-rating-container'
};

// Define bind method
function bind(context, fn) {
  return function bindFn () {
    return fn.apply(context, arguments);
  };
}

// Define our constructor
function GoogleMusic(win) {
  // If win was not provided, complain
  if (!win) {
    throw new Error('`win` was not provided to the `GoogleMusic` constructor');
  }

  // Inherit from EventEmitter
  EventEmitter.call(this);

  // Localize reference to window and document
  this.win = win;
  this.doc = win.document;

  // Initialize a keyboard and mouse
  this.keyboard = new Keyboard(win);
  this.mouse = new Mouse(win);

  // For each of the prototype sections
  var proto = GoogleMusic._protoObj;
  for (var protoKey in proto) {
    if (proto.hasOwnProperty(protoKey)) {
      // Define a key on our object
      this[protoKey] = {};

      // For each of the keys on the section, define a function that invokes on this original context
      var section = proto[protoKey];
      for (var sectionKey in section) {
        if (section.hasOwnProperty(sectionKey)) {
          this[protoKey][sectionKey] = bind(this, section[sectionKey]);
        }
      }

      // If there was an `init` method, run it
      if (this[protoKey].init) {
        this[protoKey].init();
      }
    }
  }
}
// Inherit from EventEmitter normally
inherits(GoogleMusic, EventEmitter);

// Define a "prototype" that will have magical invocation
var proto = GoogleMusic._protoObj = {};

// Create a volume API
proto.volume = {
  // Query required elements
  init: function () {
    this.volume._sliderEl = this.doc.querySelector('#vslider');
  },

  // Get the current volume level.
  getVolume: function () {
    return parseInt(this.volume._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  // Set the volume level (0 - 100).
  setVolume: function (vol) {
    var current = this.volume.getVolume();

    if (vol > current) {
      this.volume.increaseVolume(vol - current);
    } else if (vol < current) {
      this.volume.decreaseVolume(current - vol);
    }
  },

  // Increase the volume by an amount (default of 1)
  increaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_UP);
    }
  },

  // Decrease the volume by an amount (default of 1)
  decreaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_DOWN);
    }
  }
};

// Create a playback API and constants
GoogleMusic.Playback = {
  // Playback states
  STOPPED: 0,
  PAUSED: 1,
  PLAYING: 2,

  // Repeat modes
  LIST_REPEAT: 'LIST_REPEAT',
  SINGLE_REPEAT: 'SINGLE_REPEAT',
  NO_REPEAT: 'NO_REPEAT',

  // Shuffle modes
  ALL_SHUFFLE: 'ALL_SHUFFLE',
  NO_SHUFFLE: 'NO_SHUFFLE'
};
proto.playback = {
  // Query references to the media playback elements
  init: function () {
    this.playback._sliderEl = this.doc.getElementById('material-player-progress');
    this.playback._playPauseEl = this.doc.querySelector('button[data-id="play-pause"]');
    this.playback._forwardEl = this.doc.querySelector('button[data-id="forward"]');
    this.playback._rewindEl = this.doc.querySelector('button[data-id="rewind"]');
    this.playback._shuffleEl = this.doc.querySelector('button[data-id="shuffle"]');
    this.playback._repeatEl = this.doc.querySelector('button[data-id="repeat"]');
  },

  // Time functions
  getPlaybackTime: function () {
    return parseInt(this.playback._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  setPlaybackTime: function (milliseconds) {
    var percent = milliseconds / parseFloat(this.playback._sliderEl.getAttribute('aria-valuemax'));
    var lower = this.playback._sliderEl.offsetLeft + 6;
    var upper = this.playback._sliderEl.offsetLeft + this.playback._sliderEl.clientWidth - 6;
    var x = lower + percent * (upper - lower);

    this.mouse.clickAtLocation(this.playback._sliderEl, x, 0);
  },

  // Playback functions
  playPause: function () { this.playback._playPauseEl.click(); },
  forward: function () { this.playback._forwardEl.click(); },
  rewind: function () { this.playback._rewindEl.click(); },

  getShuffle: function () { return this.playback._shuffleEl.value; },
  toggleShuffle: function () { this.playback._shuffleEl.click(); },

  getRepeat: function () {
    return this.playback._repeatEl.value;
  },

  toggleRepeat: function (mode) {
    if (!mode) {
      // Toggle between repeat modes once
      this.playback._repeatEl.click();
    } else {
      // Toggle between repeat modes until the desired mode is activated
      while (this.playback.getRepeat() !== mode) {
        this.playback._repeatEl.click();
      }
    }
  },

  // Taken from the Google Play Music page
  toggleVisualization: function () {
    this.win.SJBpost('toggleVisualization');
  }
};

// Create a rating API
proto.rating = {
  // Determine whether the rating system is thumbs or stars
  isStarsRatingSystem: function () {
    return this.doc.querySelector('.rating-container.stars') !== null;
  },

  // Get current rating
  getRating: function () {
    var el = this.doc.querySelector('.player-rating-container li.selected');

    if (el) {
      return el.getAttribute('data-rating');
    } else {
      return 0;
    }
  },

  // Thumbs up
  toggleThumbsUp: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="5"]');

    if (el) {
      el.click();
    }
  },

  // Thumbs down
  toggleThumbsDown: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="1"]');

    if (el) {
      el.click();
    }
  },

  // Set a rating
  setRating: function (rating) {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="' + rating + '"]');

    if (el && !el.classList.contains('selected')) {
      el.click();
    }
  }
};

// Miscellaneous functions
proto.extras = {
  // Get a shareable URL of the song on Google Play Music
  getSongURL: function () {
    var albumEl = this.doc.querySelector('.player-album');
    var artistEl = this.doc.querySelector('.player-artist');

    var urlTemplate = 'https://play.google.com/music/m/';
    var url = null;

    var parseID = function (id) {
      return id.substring(0, id.indexOf('/'));
    };

    if (albumEl === null && artistEl === null) {
      return null;
    }

    var albumId = parseID(albumEl.dataset.id);
    var artistId = parseID(artistEl.dataset.id);

    if (albumId) {
      url = urlTemplate + albumId;
    } else if (artistId) {
      url = urlTemplate + artistId;
    }

    return url;
  }
};

proto.hooks = {
  init: function () {
    // Save context for bindings
    var that = this;

    // Define mutation observer for reuse
    var MutationObserver = this.win.MutationObserver || this.win.WebKitMutationObserver;

    var lastTitle = '';
    var lastArtist = '';
    var lastAlbum = '';

    var addObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        for (var i = 0; i < m.addedNodes.length; i++) {
          var target = m.addedNodes[i];
          var name = target.id || target.className;

          if (name === 'text-wrapper')  {
            var title = that.doc.querySelector('#playerSongTitle');
            var artist = that.doc.querySelector('#player-artist');
            var album = that.doc.querySelector('.player-album');
            var art = that.doc.querySelector('#playingAlbumArt');
            var duration = parseInt(that.doc.querySelector('#player #slider').getAttribute('aria-valuemax'), 10);

            title = (title) ? title.innerText : 'Unknown';
            artist = (artist) ? artist.innerText : 'Unknown';
            album = (album) ? album.innerText : 'Unknown';
            art = (art) ? art.src : null;

            // The art may be a protocol-relative URL, so normalize it to HTTPS
            if (art && art.slice(0, 2) === '//') {
              art = 'https:' + art;
            }

            // Make sure that this is the first of the notifications for the
            // insertion of the song information elements.
            if (lastTitle !== title || lastArtist !== artist || lastAlbum !== album) {
              that.emit('change:song', {
                title: title,
                artist: artist,
                album: album,
                art: art,
                duration: duration
              });

              lastTitle = title;
              lastArtist = artist;
              lastAlbum = album;
            }
          }
        }
      });
    });

    var shuffleObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'shuffle') {
          that.emit('change:shuffle', target.value);
        }
      });
    });

    var repeatObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'repeat') {
          that.emit('change:repeat', target.value);
        }
      });
    });

    var playbackObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'play-pause') {
          var mode;
          var playing = target.classList.contains('playing');

          if (playing) {
            mode = GoogleMusic.Playback.PLAYING;
          } else {
            // If there is a current song, then the player is paused
            if (that.doc.querySelector('#playerSongInfo').childNodes.length) {
              mode = GoogleMusic.Playback.PAUSED;
            } else {
              mode = GoogleMusic.Playback.STOPPED;
            }
          }

          that.emit('change:playback', mode);
        }
      });
    });

    var playbackTimeObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.id;

        if (id === SELECTORS.shuffle.buttonSelector) {
          var currentTime = parseInt(target.getAttribute('aria-valuenow'), 10);
          var totalTime = parseInt(target.getAttribute('aria-valuemax'), 10);
          that.emit('change:playback-time', {current: currentTime, total: totalTime});
        }
      });
    });

    var ratingObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;

        if (target.classList.contains('selected')) {
          that.emit('change:rating', target.dataset.rating);
        }
      });
    });

    addObserver.observe(this.doc.getElementById(SELECTORS.info.id), {
      childList: true,
      subtree: true
    });
    shuffleObserver.observe(this.doc.querySelector(SELECTORS.shuffle.buttonSelector), {
      attributes: true
    });
    repeatObserver.observe(this.doc.querySelector(SELECTORS.repeat.buttonSelector), {
      attributes: true
    });
    playbackObserver.observe(this.doc.querySelector(SELECTORS.playPause.buttonSelector), {
      attributes: true
    });
    playbackTimeObserver.observe(this.doc.getElementById(SELECTORS.slider.id), {
      attributes: true
    });
    ratingObserver.observe(this.doc.querySelector(SELECTORS.rating.containerSelector), {
      attributes: true,
      subtree: true
    });
  }
};

// Export our constructor
module.exports = GoogleMusic;
<commit_msg>FIxed up logic for ratings<commit_after>// Load in dependencies
var EventEmitter = require('events').EventEmitter;
var inherits = require('inherits');
var Keyboard = require('./keyboard');
var Mouse = require('./mouse');

// Define selector constants
var SELECTORS = {};
SELECTORS.info = {
  id: 'playerSongInfo'
};
SELECTORS.shuffle = {
  buttonSelector: '#player sj-icon-button[data-id="shuffle"]'
};
SELECTORS.repeat = {
  buttonSelector: '#player sj-icon-button[data-id="repeat"]'
};
SELECTORS.playPause = {
  buttonSelector: '#player sj-icon-button[data-id="play-pause"]'
};
SELECTORS.slider = {
  id: 'material-player-progress'
};
SELECTORS.rating = {
  containerSelector: '#player .player-rating-container'
};

// Define bind method
function bind(context, fn) {
  return function bindFn () {
    return fn.apply(context, arguments);
  };
}

// Define our constructor
function GoogleMusic(win) {
  // If win was not provided, complain
  if (!win) {
    throw new Error('`win` was not provided to the `GoogleMusic` constructor');
  }

  // Inherit from EventEmitter
  EventEmitter.call(this);

  // Localize reference to window and document
  this.win = win;
  this.doc = win.document;

  // Initialize a keyboard and mouse
  this.keyboard = new Keyboard(win);
  this.mouse = new Mouse(win);

  // For each of the prototype sections
  var proto = GoogleMusic._protoObj;
  for (var protoKey in proto) {
    if (proto.hasOwnProperty(protoKey)) {
      // Define a key on our object
      this[protoKey] = {};

      // For each of the keys on the section, define a function that invokes on this original context
      var section = proto[protoKey];
      for (var sectionKey in section) {
        if (section.hasOwnProperty(sectionKey)) {
          this[protoKey][sectionKey] = bind(this, section[sectionKey]);
        }
      }

      // If there was an `init` method, run it
      if (this[protoKey].init) {
        this[protoKey].init();
      }
    }
  }
}
// Inherit from EventEmitter normally
inherits(GoogleMusic, EventEmitter);

// Define a "prototype" that will have magical invocation
var proto = GoogleMusic._protoObj = {};

// Create a volume API
proto.volume = {
  // Query required elements
  init: function () {
    this.volume._sliderEl = this.doc.querySelector('#vslider');
  },

  // Get the current volume level.
  getVolume: function () {
    return parseInt(this.volume._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  // Set the volume level (0 - 100).
  setVolume: function (vol) {
    var current = this.volume.getVolume();

    if (vol > current) {
      this.volume.increaseVolume(vol - current);
    } else if (vol < current) {
      this.volume.decreaseVolume(current - vol);
    }
  },

  // Increase the volume by an amount (default of 1)
  increaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_UP);
    }
  },

  // Decrease the volume by an amount (default of 1)
  decreaseVolume: function (amount) {
    if (amount === undefined) {
      amount = 1;
    }

    for (var i = 0; i < amount; i++) {
      this.keyboard.sendKey(this.volume._sliderEl, Keyboard.KEY_DOWN);
    }
  }
};

// Create a playback API and constants
GoogleMusic.Playback = {
  // Playback states
  STOPPED: 0,
  PAUSED: 1,
  PLAYING: 2,

  // Repeat modes
  LIST_REPEAT: 'LIST_REPEAT',
  SINGLE_REPEAT: 'SINGLE_REPEAT',
  NO_REPEAT: 'NO_REPEAT',

  // Shuffle modes
  ALL_SHUFFLE: 'ALL_SHUFFLE',
  NO_SHUFFLE: 'NO_SHUFFLE'
};
proto.playback = {
  // Query references to the media playback elements
  init: function () {
    this.playback._sliderEl = this.doc.getElementById('material-player-progress');
    this.playback._playPauseEl = this.doc.querySelector('button[data-id="play-pause"]');
    this.playback._forwardEl = this.doc.querySelector('button[data-id="forward"]');
    this.playback._rewindEl = this.doc.querySelector('button[data-id="rewind"]');
    this.playback._shuffleEl = this.doc.querySelector('button[data-id="shuffle"]');
    this.playback._repeatEl = this.doc.querySelector('button[data-id="repeat"]');
  },

  // Time functions
  getPlaybackTime: function () {
    return parseInt(this.playback._sliderEl.getAttribute('aria-valuenow'), 10);
  },

  setPlaybackTime: function (milliseconds) {
    var percent = milliseconds / parseFloat(this.playback._sliderEl.getAttribute('aria-valuemax'));
    var lower = this.playback._sliderEl.offsetLeft + 6;
    var upper = this.playback._sliderEl.offsetLeft + this.playback._sliderEl.clientWidth - 6;
    var x = lower + percent * (upper - lower);

    this.mouse.clickAtLocation(this.playback._sliderEl, x, 0);
  },

  // Playback functions
  playPause: function () { this.playback._playPauseEl.click(); },
  forward: function () { this.playback._forwardEl.click(); },
  rewind: function () { this.playback._rewindEl.click(); },

  getShuffle: function () { return this.playback._shuffleEl.value; },
  toggleShuffle: function () { this.playback._shuffleEl.click(); },

  getRepeat: function () {
    return this.playback._repeatEl.value;
  },

  toggleRepeat: function (mode) {
    if (!mode) {
      // Toggle between repeat modes once
      this.playback._repeatEl.click();
    } else {
      // Toggle between repeat modes until the desired mode is activated
      while (this.playback.getRepeat() !== mode) {
        this.playback._repeatEl.click();
      }
    }
  },

  // Taken from the Google Play Music page
  toggleVisualization: function () {
    this.win.SJBpost('toggleVisualization');
  }
};

// Create a rating API
proto.rating = {
  // Determine whether the rating system is thumbs or stars
  isStarsRatingSystem: function () {
    return this.doc.querySelector('.rating-container.stars') !== null;
  },

  // Get current rating
  getRating: function () {
    var el = this.doc.querySelector('.player-rating-container li.selected');

    if (el) {
      return el.getAttribute('data-rating');
    } else {
      return 0;
    }
  },

  // Thumbs up
  toggleThumbsUp: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="5"]');

    if (el) {
      el.click();
    }
  },

  // Thumbs down
  toggleThumbsDown: function () {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="1"]');

    if (el) {
      el.click();
    }
  },

  // Set a rating
  setRating: function (rating) {
    var el = this.doc.querySelector('.player-rating-container li[data-rating="' + rating + '"]');

    if (el && !el.classList.contains('selected')) {
      el.click();
    }
  }
};

// Miscellaneous functions
proto.extras = {
  // Get a shareable URL of the song on Google Play Music
  getSongURL: function () {
    var albumEl = this.doc.querySelector('.player-album');
    var artistEl = this.doc.querySelector('.player-artist');

    var urlTemplate = 'https://play.google.com/music/m/';
    var url = null;

    var parseID = function (id) {
      return id.substring(0, id.indexOf('/'));
    };

    if (albumEl === null && artistEl === null) {
      return null;
    }

    var albumId = parseID(albumEl.dataset.id);
    var artistId = parseID(artistEl.dataset.id);

    if (albumId) {
      url = urlTemplate + albumId;
    } else if (artistId) {
      url = urlTemplate + artistId;
    }

    return url;
  }
};

proto.hooks = {
  init: function () {
    // Save context for bindings
    var that = this;

    // Define mutation observer for reuse
    var MutationObserver = this.win.MutationObserver || this.win.WebKitMutationObserver;

    var lastTitle = '';
    var lastArtist = '';
    var lastAlbum = '';

    var addObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        for (var i = 0; i < m.addedNodes.length; i++) {
          var target = m.addedNodes[i];
          var name = target.id || target.className;

          if (name === 'text-wrapper')  {
            var title = that.doc.querySelector('#playerSongTitle');
            var artist = that.doc.querySelector('#player-artist');
            var album = that.doc.querySelector('.player-album');
            var art = that.doc.querySelector('#playingAlbumArt');
            var duration = parseInt(that.doc.querySelector('#player #slider').getAttribute('aria-valuemax'), 10);

            title = (title) ? title.innerText : 'Unknown';
            artist = (artist) ? artist.innerText : 'Unknown';
            album = (album) ? album.innerText : 'Unknown';
            art = (art) ? art.src : null;

            // The art may be a protocol-relative URL, so normalize it to HTTPS
            if (art && art.slice(0, 2) === '//') {
              art = 'https:' + art;
            }

            // Make sure that this is the first of the notifications for the
            // insertion of the song information elements.
            if (lastTitle !== title || lastArtist !== artist || lastAlbum !== album) {
              that.emit('change:song', {
                title: title,
                artist: artist,
                album: album,
                art: art,
                duration: duration
              });

              lastTitle = title;
              lastArtist = artist;
              lastAlbum = album;
            }
          }
        }
      });
    });

    var shuffleObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'shuffle') {
          that.emit('change:shuffle', target.value);
        }
      });
    });

    var repeatObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'repeat') {
          that.emit('change:repeat', target.value);
        }
      });
    });

    var playbackObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.dataset.id;

        if (id === 'play-pause') {
          var mode;
          var playing = target.classList.contains('playing');

          if (playing) {
            mode = GoogleMusic.Playback.PLAYING;
          } else {
            // If there is a current song, then the player is paused
            if (that.doc.querySelector('#playerSongInfo').childNodes.length) {
              mode = GoogleMusic.Playback.PAUSED;
            } else {
              mode = GoogleMusic.Playback.STOPPED;
            }
          }

          that.emit('change:playback', mode);
        }
      });
    });

    var playbackTimeObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;
        var id = target.id;

        if (id === SELECTORS.shuffle.buttonSelector) {
          var currentTime = parseInt(target.getAttribute('aria-valuenow'), 10);
          var totalTime = parseInt(target.getAttribute('aria-valuemax'), 10);
          that.emit('change:playback-time', {current: currentTime, total: totalTime});
        }
      });
    });

    var ratingObserver = new MutationObserver(function (mutations) {
      mutations.forEach(function (m) {
        var target = m.target;

        // If the target is no longer outlined in its shadow DOM
        // DEV: Access shadow DOM via `$`
        //   Selected thumbs up:
        //   <core-icon relative="" id="icon" src="{{src}}" icon="{{icon}}" aria-label="thumb-up" role="img"></core-icon>
        //   Unselected thumbs down:
        //   <core-icon relative="" id="icon" src="{{src}}" icon="{{icon}}" aria-label="thumb-down-outline" role="img"></core-icon>
        if (target.ariaLabel.indexOf('-outline') !== -1) {
          that.emit('change:rating', target.dataset.rating);
        }
      });
    });

    addObserver.observe(this.doc.getElementById(SELECTORS.info.id), {
      childList: true,
      subtree: true
    });
    shuffleObserver.observe(this.doc.querySelector(SELECTORS.shuffle.buttonSelector), {
      attributes: true
    });
    repeatObserver.observe(this.doc.querySelector(SELECTORS.repeat.buttonSelector), {
      attributes: true
    });
    playbackObserver.observe(this.doc.querySelector(SELECTORS.playPause.buttonSelector), {
      attributes: true
    });
    playbackTimeObserver.observe(this.doc.getElementById(SELECTORS.slider.id), {
      attributes: true
    });
    ratingObserver.observe(this.doc.querySelector(SELECTORS.rating.containerSelector), {
      attributes: true,
      subtree: true
    });
  }
};

// Export our constructor
module.exports = GoogleMusic;
<|endoftext|>


<commit_before>"use strict"; // run code in ES5 strict mode

var Finder = require("fshelpers").Finder,
    pathHelpers = require("../shared/helpers/pathHelpers"),
    isSchemaOnly = pathHelpers.chain.filter("onlySchemaFiles"),
    isServerOnlyAndSchema = pathHelpers.chain.filter("onlyServerFiles", "onlySchemaFiles"),
    isClientOnlyAndSchema = pathHelpers.chain.filter("onlyClientFiles", "onlySchemaFiles");

function collectSchemas(modelsPath, callback) {
    var finder = new Finder(),
        schemas = {
            server: {},
            shared : {},
            client: {}
        };

    function onFile(path) {

        var fullPath = path,
            pathSplit;

        //we only want the model-path without the path to ".../models"
        path = path.substr(modelsPath.length);

        //and strip slash at the beginning
        if(path.charAt(0) === "/") {
            path = path.substr(1);
        }

        //we only want the path without fs-specific stuff
        pathSplit = path.split("/");
        pathSplit.pop();

        path = pathSplit.join("/");
        path = path.toLowerCase();

        if (isServerOnlyAndSchema(fullPath)) {
            schemas.server[path] = require(fullPath);
        }
        else if (isClientOnlyAndSchema(fullPath)) {
            //remove the fs-specific ending
            schemas.client[path] = require(fullPath);
        }
        else {
            //in case it's a model used for both
            //create the entries for .server and .client
            //would be overwritten by actual .server and .client files if existent
            if (isSchemaOnly(fullPath)) {

                var schemaDefinition = require(fullPath);

                //we store the shared model as well
                schemas.shared[path] = schemaDefinition;

                if(schemas.server[path] === undefined) {
                    schemas.server[path] = schemaDefinition;
                }

                if(schemas.client[path] === undefined) {
                    schemas.client[path] = true;
                }
            }
        }
    }

    function onEnd() {
        callback(null, schemas);
    }

    function onError(err) {
        finder.reset(); // abort current operation
        callback(err);
    }

    finder
        .on("file", onFile)
        .on("error", onError)
        .on("end", onEnd)
        .walk(modelsPath);
}

module.exports = collectSchemas;<commit_msg>- added merging for schemas.<commit_after>"use strict"; // run code in ES5 strict mode

var Finder = require("fshelpers").Finder,
    _ = require("underscore"),
    pathHelpers = require("../shared/helpers/pathHelpers"),
    isSchemaOnly = pathHelpers.chain.filter("onlySchemaFiles"),
    isServerOnlyAndSchema = pathHelpers.chain.filter("onlyServerFiles", "onlySchemaFiles"),
    isClientOnlyAndSchema = pathHelpers.chain.filter("onlyClientFiles", "onlySchemaFiles");

/**
 * extends the shared schema with the env-specific schema
 * overwrites methods that are defined env-specific
 * @param {Object} schemas
 */
function extendSchemas(schemas) {

    function extendSchema(sharedSchema, envSchema) {
        if(sharedSchema === undefined) {
            throw new Error("(alamid) No shared Schema defined for '" + path + "'");
        }
        _(sharedSchema).extend(envSchema);
    }

    var path;

    //extend server-schemas
    for(path in schemas.server) {
        if(schemas.server.hasOwnProperty(path)){
            extendSchema(schemas.shared[path], schemas.server[path]);
        }
    }

    //extend client-schemas
    for(path in schemas.client) {
        if(schemas.client.hasOwnProperty(path)){
            extendSchema(schemas.shared[path], schemas.client[path]);
        }
    }
}

function collectSchemas(modelsPath, callback) {
    var finder = new Finder(),
        schemas = {
            server: {},
            shared : {},
            client: {}
        };

    function onFile(path) {

        var fullPath = path,
            pathSplit;

        //we only want the model-path without the path to ".../models"
        path = path.substr(modelsPath.length);

        //and strip slash at the beginning
        if(path.charAt(0) === "/") {
            path = path.substr(1);
        }

        //we only want the path without fs-specific stuff
        pathSplit = path.split("/");
        pathSplit.pop();

        path = pathSplit.join("/");
        path = path.toLowerCase();

        if (isServerOnlyAndSchema(fullPath)) {
            schemas.server[path] = require(fullPath);
        }
        else if (isClientOnlyAndSchema(fullPath)) {
            //remove the fs-specific ending
            schemas.client[path] = require(fullPath);
        }
        else {
            //in case it's a model used for both
            //create the entries for .server and .client
            //would be overwritten by actual .server and .client files if existent
            if (isSchemaOnly(fullPath)) {

                var schemaDefinition = require(fullPath);

                //we store the shared model as well
                schemas.shared[path] = schemaDefinition;

                if(schemas.server[path] === undefined) {
                    schemas.server[path] = schemaDefinition;
                }

                if(schemas.client[path] === undefined) {
                    schemas.client[path] = true;
                }
            }
        }
    }

    function onEnd() {
        extendSchemas(schemas);
        callback(null, schemas);
    }

    function onError(err) {
        finder.reset(); // abort current operation
        callback(err);
    }

    finder
        .on("file", onFile)
        .on("error", onError)
        .on("end", onEnd)
        .walk(modelsPath);
}

module.exports = collectSchemas;<|endoftext|>


<commit_before>var clipboard = require("clipboard").clipboard,
    contextMenu = require("context-menu"),
    tabs = require("tabs"),
    xhr = require("xhr");
var selectors = 'link[rev=canonical],link[rel=shorturl],link[rel=shortlink]';

/** Find short URL in the page */
function findShortUrl(ctx) {
    let doc = ctx.document,
        short = doc.querySelector(selectors),
        link;
    if (short && (link = short.getAttribute('href')))
        return link;
    return false;
}

/** Create a short URL from tinyurl.com */
function createShortUrl(ctx) {
    let req = new xhr.XMLHttpRequest(),
        url = ctx.document.URL;
    req.open("GET", "http://tinyurl.com/api-create.php?url="
             +encodeURIComponent(url), false);
    req.send(null);
    if (req.status == 200) {
        console.log(url + ' --> ' + req.responseText);
        return req.responseText;
    } else {
        console.warning('ZOMG, could not create short URL.');
        return false;
    }
}

exports.main = function() {
    var item = contextMenu.Item({
        label: 'Copy ShortURL',
        onClick: function(ctx, item) {
            url = findShortUrl(ctx);
            if (!url) {
                url = createShortUrl(ctx);
            }
            if (url) clipboard.set(url);
        }
    });
    contextMenu.add(item);
}

<commit_msg>Use canonical URL for tinyurl creation (closes #3).<commit_after>var clipboard = require("clipboard").clipboard,
    contextMenu = require("context-menu"),
    tabs = require("tabs"),
    xhr = require("xhr");
var selectors = 'link[rev=canonical],link[rel=shorturl],link[rel=shortlink]';

/** Find short URL in the page */
function findShortUrl(ctx) {
    let doc = ctx.document,
        short = doc.querySelector(selectors),
        link;
    if (short && (link = short.getAttribute('href')))
        return link;
    return false;
}

/** Create a short URL from tinyurl.com */
function createShortUrl(ctx) {
    let req = new xhr.XMLHttpRequest(),
        url, canonical;
    // use canonical URL if it exists, current URL otherwise.
    canonical = ctx.document.querySelector('link[rel=canonical]');
    if (!(canonical && (url = canonical.getAttribute('href'))))
        url = ctx.document.URL;
    req.open("GET", "http://tinyurl.com/api-create.php?url="
             +encodeURIComponent(url), false);
    req.send(null);
    if (req.status == 200) {
        console.log(url + ' --> ' + req.responseText);
        return req.responseText;
    } else {
        console.warning('ZOMG, could not create short URL.');
        return false;
    }
}

exports.main = function() {
    var item = contextMenu.Item({
        label: 'Copy ShortURL',
        onClick: function(ctx, item) {
            url = findShortUrl(ctx);
            if (!url) {
                url = createShortUrl(ctx);
            }
            if (url) clipboard.set(url);
        }
    });
    contextMenu.add(item);
}

<|endoftext|>


<commit_before>'use strict';

const util = require('util'),
  Promise = require('bluebird'),
  log = require('intel'),
  merge = require('lodash.merge'),
  webdriver = require('selenium-webdriver'),
  Condition = require('selenium-webdriver/lib/webdriver').Condition,
  WebDriverError = webdriver.error.WebDriverError,
  encodeError = webdriver.error.encodeError,
  builder = require('./webdriverBuilder'),
  UrlLoadError = require('../support/errors').UrlLoadError,
  BrowserError = require('../support/errors').BrowserError;

const defaultPageCompleteCheck = 'return (function() {try { return (Date.now() - window.performance.timing.loadEventEnd) > 2000;} catch(e) {} return true;})()';
const defaults = {
  timeouts: {
    browserStart: 60000,
    pageLoad: 300000,
    script: 40000,
    pageCompleteCheck: 300000
  }
};

class SeleniumRunner {
  constructor(options) {
    this.options = merge({}, defaults, options);
  }

  start() {
    function startBrowser() {
      return Promise.try(() => builder.createWebDriver(this.options)
        .tap((driver) => {
          this.driver = driver;
        }))
        .timeout(this.options.timeouts.browserStart,
          util.format('Failed to start browser in %d seconds.',
            this.options.timeouts.browserStart / 1000));
    }

    return startBrowser.call(this)
      .catch(Promise.TimeoutError, () => {
        log.info('Browser failed to start in time, trying one more time.');
        return startBrowser.call(this)
          .catch(Promise.TimeoutError, (e) => {
            throw new BrowserError(e.message, {
              cause: e
            });
          });
      })
      .tap(() => {
        let timeouts = this.driver.manage().timeouts(),
          pageLoadTimeout = this.options.timeouts.pageLoad,
          scriptTimeout = this.options.timeouts.script;

        return timeouts.pageLoadTimeout(pageLoadTimeout)
          .then(() => timeouts.setScriptTimeout(scriptTimeout));
      })
      .tap(() => {
        let viewPort = this.options.viewPort;
        if (viewPort) {
          viewPort = viewPort.split('x');

          const window = this.driver.manage().window();
          return window.setPosition(0, 0)
            .then(() => window.setSize(Number(viewPort[0]), Number(viewPort[1])));
        }
      })
      .catch(BrowserError, (e) => {
        throw e;
      })
      .catch((e) => {
        throw new BrowserError(e.message, {
          cause: e
        });
      });
  }

  loadAndWait(url, pageCompleteCheck) {
    pageCompleteCheck = pageCompleteCheck || defaultPageCompleteCheck;

    let driver = this.driver,
      pageCompleteCheckTimeout = this.options.timeouts.pageCompleteCheck;

    function getUrl() {
      return Promise.try(function() {
        log.debug('Requesting url %s', url);
        return driver.get(url);
      });
    }

    function confirmUrlSuccessfullyLoaded() {
      if (!url.match(/^http(s)?:\/\//i)) {
        // E.g. when loading about:blank for the info page.
        return Promise.resolve();
      }

      return Promise.resolve(driver.executeScript('return document.documentURI;'))
        .then((uri) => {
          if (!uri.match(/^http(s)?:\/\//i))
            throw new UrlLoadError('Failed to load ' + url, url);
        });
    }

    function waitForPageCompletion() {
      let pageCompleteCheckCondition = new Condition(
        'for page complete check script to return true',
        function(d) {
          return d.executeScript(pageCompleteCheck)
            .then(function(t) {
              return t === true;
            });
        });

      return Promise
        .try(function() {
          log.debug('Waiting for script \'%s\' at most %d ms', pageCompleteCheck, pageCompleteCheckTimeout);
          return driver.wait(pageCompleteCheckCondition, pageCompleteCheckTimeout);
        })
        .timeout(pageCompleteCheckTimeout, 'Running page complete check \'' + pageCompleteCheck + '\' took too long.');
    }

    return getUrl()
      .then(confirmUrlSuccessfullyLoaded)
      .then(waitForPageCompletion)
      .catch(WebDriverError, (e) => {
        log.error('WebDriverError:' + e);
        throw new UrlLoadError('Failed to load ' + url + ', cause: ' + encodeError(e).message, url, {
          cause: e
        })
      }).catch((e) => {
        log.error('Could not load URL' + e);
        throw new UrlLoadError('Failed to load ' + url, url, {
          cause: e
        })
      });
  }

  takeScreenshot() {
    return Promise.resolve(this.driver.takeScreenshot())
      .then((base64EncodedPng) =>
        new Buffer(base64EncodedPng, 'base64'));
  }

  runScript(script, name, args) {
    let scriptTimeout = this.options.timeouts.script;

    return Promise
      .try(() => {
        if (log.isEnabledFor(log.TRACE)) {
          log.verbose('Executing script %s', script);
        } else if (log.isEnabledFor(log.VERBOSE)) {
          log.verbose('Executing script %s', name);
        }
        return this.driver.executeScript(script, args);
      })
      .timeout(scriptTimeout, 'Running script \'' + script + '\' took too long.');
  }

  runAsyncScript(script, name, args) {
    return Promise
      .try(() => {
        if (log.isEnabledFor(log.TRACE)) {
          log.verbose('Executing async script %s', script);
        } else if (log.isEnabledFor(log.VERBOSE)) {
          log.verbose('Executing async script %s', name);
        }
        return this.driver.executeAsyncScript(script, args);
      });
  }

  runWithDriver(driverScript) {
    return driverScript(this.driver);
  }

  getLogs(logType) {
    return Promise.resolve(this.driver.manage().logs().get(logType));
  }

  stop() {
    if (this.driver) {
      return Promise.try(() => {
        log.debug('Telling browser to quit.');
        return this.driver.quit();
      })
        .catch((e) => {
          throw new BrowserError(e.message, {
            cause: e
          });
        });
    }
    return Promise.resolve();
  }
}

module.exports = SeleniumRunner;
<commit_msg>do not set window position until https://github.com/mozilla/geckodriver/issues/113 is fixed<commit_after>'use strict';

const util = require('util'),
  Promise = require('bluebird'),
  log = require('intel'),
  merge = require('lodash.merge'),
  webdriver = require('selenium-webdriver'),
  Condition = require('selenium-webdriver/lib/webdriver').Condition,
  WebDriverError = webdriver.error.WebDriverError,
  encodeError = webdriver.error.encodeError,
  builder = require('./webdriverBuilder'),
  UrlLoadError = require('../support/errors').UrlLoadError,
  BrowserError = require('../support/errors').BrowserError;

const defaultPageCompleteCheck = 'return (function() {try { return (Date.now() - window.performance.timing.loadEventEnd) > 2000;} catch(e) {} return true;})()';
const defaults = {
  timeouts: {
    browserStart: 60000,
    pageLoad: 300000,
    script: 40000,
    pageCompleteCheck: 300000
  }
};

class SeleniumRunner {
  constructor(options) {
    this.options = merge({}, defaults, options);
  }

  start() {
    function startBrowser() {
      return Promise.try(() => builder.createWebDriver(this.options)
        .tap((driver) => {
          this.driver = driver;
        }))
        .timeout(this.options.timeouts.browserStart,
          util.format('Failed to start browser in %d seconds.',
            this.options.timeouts.browserStart / 1000));
    }

    return startBrowser.call(this)
      .catch(Promise.TimeoutError, () => {
        log.info('Browser failed to start in time, trying one more time.');
        return startBrowser.call(this)
          .catch(Promise.TimeoutError, (e) => {
            throw new BrowserError(e.message, {
              cause: e
            });
          });
      })
      .tap(() => {
        let timeouts = this.driver.manage().timeouts(),
          pageLoadTimeout = this.options.timeouts.pageLoad,
          scriptTimeout = this.options.timeouts.script;

        return timeouts.pageLoadTimeout(pageLoadTimeout)
          .then(() => timeouts.setScriptTimeout(scriptTimeout));
      })
      .tap(() => {
        let viewPort = this.options.viewPort;
        if (viewPort) {
          viewPort = viewPort.split('x');

          const window = this.driver.manage().window();
          // Do not set position until this is fixed in Geckodriver
          // https://github.com/mozilla/geckodriver/issues/113
          if (this.options.browser === 'firefox') {
            return window.setSize(Number(viewPort[0]), Number(viewPort[1]));
          }
          else return window.setPosition(0, 0)
            .then(() => window.setSize(Number(viewPort[0]), Number(viewPort[1])));
        }
      })
      .catch(BrowserError, (e) => {
        throw e;
      })
      .catch((e) => {
        throw new BrowserError(e.message, {
          cause: e
        });
      });
  }

  loadAndWait(url, pageCompleteCheck) {
    pageCompleteCheck = pageCompleteCheck || defaultPageCompleteCheck;

    let driver = this.driver,
      pageCompleteCheckTimeout = this.options.timeouts.pageCompleteCheck;

    function getUrl() {
      return Promise.try(function() {
        log.debug('Requesting url %s', url);
        return driver.get(url);
      });
    }

    function confirmUrlSuccessfullyLoaded() {
      if (!url.match(/^http(s)?:\/\//i)) {
        // E.g. when loading about:blank for the info page.
        return Promise.resolve();
      }

      return Promise.resolve(driver.executeScript('return document.documentURI;'))
        .then((uri) => {
          if (!uri.match(/^http(s)?:\/\//i))
            throw new UrlLoadError('Failed to load ' + url, url);
        });
    }

    function waitForPageCompletion() {
      let pageCompleteCheckCondition = new Condition(
        'for page complete check script to return true',
        function(d) {
          return d.executeScript(pageCompleteCheck)
            .then(function(t) {
              return t === true;
            });
        });

      return Promise
        .try(function() {
          log.debug('Waiting for script \'%s\' at most %d ms', pageCompleteCheck, pageCompleteCheckTimeout);
          return driver.wait(pageCompleteCheckCondition, pageCompleteCheckTimeout);
        })
        .timeout(pageCompleteCheckTimeout, 'Running page complete check \'' + pageCompleteCheck + '\' took too long.');
    }

    return getUrl()
      .then(confirmUrlSuccessfullyLoaded)
      .then(waitForPageCompletion)
      .catch(WebDriverError, (e) => {
        log.error('WebDriverError:' + e);
        throw new UrlLoadError('Failed to load ' + url + ', cause: ' + encodeError(e).message, url, {
          cause: e
        })
      }).catch((e) => {
        log.error('Could not load URL' + e);
        throw new UrlLoadError('Failed to load ' + url, url, {
          cause: e
        })
      });
  }

  takeScreenshot() {
    return Promise.resolve(this.driver.takeScreenshot())
      .then((base64EncodedPng) =>
        new Buffer(base64EncodedPng, 'base64'));
  }

  runScript(script, name, args) {
    let scriptTimeout = this.options.timeouts.script;

    return Promise
      .try(() => {
        if (log.isEnabledFor(log.TRACE)) {
          log.verbose('Executing script %s', script);
        } else if (log.isEnabledFor(log.VERBOSE)) {
          log.verbose('Executing script %s', name);
        }
        return this.driver.executeScript(script, args);
      })
      .timeout(scriptTimeout, 'Running script \'' + script + '\' took too long.');
  }

  runAsyncScript(script, name, args) {
    return Promise
      .try(() => {
        if (log.isEnabledFor(log.TRACE)) {
          log.verbose('Executing async script %s', script);
        } else if (log.isEnabledFor(log.VERBOSE)) {
          log.verbose('Executing async script %s', name);
        }
        return this.driver.executeAsyncScript(script, args);
      });
  }

  runWithDriver(driverScript) {
    return driverScript(this.driver);
  }

  getLogs(logType) {
    return Promise.resolve(this.driver.manage().logs().get(logType));
  }

  stop() {
    if (this.driver) {
      return Promise.try(() => {
        log.debug('Telling browser to quit.');
        return this.driver.quit();
      })
        .catch((e) => {
          throw new BrowserError(e.message, {
            cause: e
          });
        });
    }
    return Promise.resolve();
  }
}

module.exports = SeleniumRunner;
<|endoftext|>