<commit_before>(function () {
	var isNode = typeof module !== 'undefined' && module.exports;
	var setImmediate = setImmediate || function (cb) {
		setTimeout(cb, 0);
	};
	var Worker = isNode ? require(__dirname + '/Worker.js') : self.Worker;
	var URL = typeof self !== 'undefined' ? (self.URL ? self.URL : self.webkitURL) : null;

	function extend(from, to) {
		if (!to) to = {};
		for (var i in from) {
			if (to[i] === undefined) to[i] = from[i];
		}
		return to;
	}

	function Operation() {
		this._callbacks = [];
		this._errCallbacks = [];

		this._resolved = 0;
		this._result = null;
	}

	Operation.prototype.resolve = function (err, res) {
		if (!err) {
			this._resolved = 1;
			this._result = res;

			for (var i = 0; i < this._callbacks.length; ++i) {
				this._callbacks[i](res);
			}
		} else {
			this._resolved = 2;
			this._result = err;

			for (var iE = 0; iE < this._errCallbacks.length; ++iE) {
				this._errCallbacks[iE](res);
			}
		}

		this._callbacks = [];
		this._errCallbacks = [];
	};

	Operation.prototype.then = function (cb, errCb) {
		if (this._resolved === 1) { // result
			if (cb) {
				cb(this._result);
			}

			return;
		} else if (this._resolved === 2) { // error
			if (errCb) {
				errCb(this._result);
			}
			return;
		}

		if (cb) {
			this._callbacks[this._callbacks.length] = cb;
		}

		if (errCb) {
			this._errCallbacks[this._errCallbacks.length] = errCb;
		}
		return this;
	};

	var defaults = {
		evalPath: isNode ? __dirname + '/eval.js' : null,
		maxWorkers: isNode ? require('os').cpus().length : 4,
		synchronous: true
	};

	function Parallel(data, options) {
		this.data = data;
		this.options = extend(defaults, options);
		this.operation = new Operation();
		this.operation.resolve(null, this.data);
		this.requiredScripts = [];
		this.requiredFunctions = [];
	}

	Parallel.prototype.getWorkerSource = function (cb) {
		var preStr = '';
		var i = 0;
		if (!isNode && this.requiredScripts.length !== 0) {
			preStr += 'importScripts("' + this.requiredScripts.join('","') + '");\r\n';
		}

		for (i = 0; i < this.requiredFunctions.length; ++i) {
			if (this.requiredFunctions[i].name) {
				preStr += 'var ' + this.requiredFunctions[i].name + ' = ' + this.requiredFunctions[i].fn.toString() + ';';
			} else {
				preStr += this.requiredFunctions[i].fn.toString();
			}
		}

		if (isNode) {
			return preStr + 'process.on("message", function(e) {process.send(JSON.stringify((' + cb.toString() + ')(JSON.parse(e).data)))})';
		} else {
			return preStr + 'self.onmessage = function(e) {self.postMessage((' + cb.toString() + ')(e.data))}';
		}
	};

	Parallel.prototype.require = function () {
		var args = Array.prototype.slice.call(arguments, 0),
			func;

		for (var i = 0; i < args.length; i++) {
			func = args[i];

			if (typeof func === 'string') {
				this.requiredScripts.push(func);
			} else if (typeof func === 'function') {
				this.requiredFunctions.push({ fn: func });
			} else if (typeof func === 'object') {
				this.requiredFunctions.push(func);
			}
		}

		return this;
	};

	Parallel.prototype._spawnWorker = function (cb) {
		var wrk;
		var src = this.getWorkerSource(cb);
		if (isNode) {
			wrk = new Worker(this.options.evalPath);
			wrk.postMessage(src);
		} else {
			if (Worker === undefined) {
				return undefined;
			}

			try {
				if (this.requiredScripts.length !== 0) {
					if (this.options.evalPath !== null) {
						wrk = new Worker(this.options.evalPath);
						wrk.postMessage(src);
					} else {
						throw new Error('Can\'t use required scripts without eval.js!');
					}
				} else if (!URL) {
					throw new Error('Can\'t create a blob URL in this browser!');
				} else {
					var blob = new Blob([src], { type: 'text/javascript' });
					var url = URL.createObjectURL(blob);

					wrk = new Worker(url);
				}
			} catch (e) {
				if (this.options.evalPath !== null) { // blob/url unsupported, cross-origin error
					wrk = new Worker(this.options.evalPath);
					wrk.postMessage(src);
				} else {
					throw e;
				}
			}
		}

		return wrk;
	};

	Parallel.prototype.spawn = function (cb) {
		var that = this;
		var newOp = new Operation();
		this.operation.then(function () {
			var wrk = that._spawnWorker(cb);
			if (wrk !== undefined) {
				wrk.onmessage = function (msg) {
					wrk.terminate();
					that.data = msg.data;
					newOp.resolve(null, that.data);
				};
				wrk.postMessage(that.data);
			} else if (that.options.synchronous) {
				setImmediate(function () {
					that.data = cb(that.data);
					newOp.resolve(null, that.data);
				});
			} else {
				throw new Error('Workers do not exist and synchronous operation not allowed!');
			}
		});
		this.operation = newOp;
		return this;
	};

	Parallel.prototype._spawnMapWorker = function (i, cb, done) {
		var that = this;
		var wrk = that._spawnWorker(cb);
		if (wrk !== undefined) {
			wrk.onmessage = function (msg) {
				wrk.terminate();
				that.data[i] = msg.data;
				done();
			};
			wrk.postMessage(that.data[i]);
		} else if (that.options.synchronous) {
			setImmediate(function () {
				that.data[i] = cb(that.data[i]);
				done();
			});
		} else {
			throw new Error('Workers do not exist and synchronous operation not allowed!');
		}
	};

	Parallel.prototype.map = function (cb) {
		if (!this.data.length) {
			return this.spawn(cb);
		}

		var that = this;
		var startedOps = 0;
		var doneOps = 0;
		function done() {
			if (++doneOps === that.data.length) {
				newOp.resolve(null, that.data);
			} else if (startedOps < that.data.length) {
				that._spawnMapWorker(startedOps++, cb, done);
			}
		}

		var newOp = new Operation();
		this.operation.then(function () {
			for (; startedOps - doneOps < that.options.maxWorkers && startedOps < that.data.length; ++startedOps) {
				that._spawnMapWorker(startedOps, cb, done);
			}
		});
		this.operation = newOp;
		return this;
	};

	Parallel.prototype._spawnReduceWorker = function (data, cb, done) {
		var that = this;
		var wrk = that._spawnWorker(cb);
		if (wrk !== undefined) {
			wrk.onmessage = function (msg) {
				wrk.terminate();
				that.data[that.data.length] = msg.data;
				done();
			};
			wrk.postMessage(data);
		} else if (that.options.synchronous) {
			setImmediate(function () {
				that.data[that.data.length] = cb(data);
				done();
			});
		} else {
			throw new Error('Workers do not exist and synchronous operation not allowed!');
		}
	};

	Parallel.prototype.reduce = function (cb) {
		if (!this.data.length) {
			throw new Error('Can\'t reduce non-array data');
		}

		var runningWorkers = 0;
		var that = this;
		function done(data) {
			--runningWorkers;
			if (that.data.length === 1 && runningWorkers === 0) {
				that.data = that.data[0];
				newOp.resolve(null, that.data);
			} else if (that.data.length > 1) {
				++runningWorkers;
				that._spawnReduceWorker([that.data[0], that.data[1]], cb, done);
				that.data.splice(0, 2);
			}
		}

		var newOp = new Operation();
		this.operation.then(function () {
			if (that.data.length === 1) {
				newOp.resolve(null, that.data[0]);
			} else {
				for (var i = 0; i < that.options.maxWorkers && i < Math.floor(that.data.length / 2); ++i) {
					++runningWorkers;
					that._spawnReduceWorker([that.data[i * 2], that.data[i * 2 + 1]], cb, done);
				}

				that.data.splice(0, i * 2);
			}
		});
		this.operation = newOp;
		return this;
	};

	Parallel.prototype.then = function (cb, errCb) {
		var that = this;
		var newOp = new Operation();
		this.operation.then(function () {
			var retData = cb(that.data);
			if (retData !== undefined) {
				that.data = retData;
			}
			newOp.resolve(null, that.data);
		}, errCb);
		this.operation = newOp;
		return this;
	};

	if (isNode) {
		module.exports = Parallel;
	} else {
		self.Parallel = Parallel;
	}
})();<commit_msg>add static method isSupported()<commit_after>(function () {
	var isNode = typeof module !== 'undefined' && module.exports;
	var setImmediate = setImmediate || function (cb) {
		setTimeout(cb, 0);
	};
	var Worker = isNode ? require(__dirname + '/Worker.js') : self.Worker;
	var URL = typeof self !== 'undefined' ? (self.URL ? self.URL : self.webkitURL) : null;
    var _supports= isNode || self.Worker; // node always supports parallel

	function extend(from, to) {
		if (!to) to = {};
		for (var i in from) {
			if (to[i] === undefined) to[i] = from[i];
		}
		return to;
	}

	function Operation() {
		this._callbacks = [];
		this._errCallbacks = [];

		this._resolved = 0;
		this._result = null;
	}

	Operation.prototype.resolve = function (err, res) {
		if (!err) {
			this._resolved = 1;
			this._result = res;

			for (var i = 0; i < this._callbacks.length; ++i) {
				this._callbacks[i](res);
			}
		} else {
			this._resolved = 2;
			this._result = err;

			for (var iE = 0; iE < this._errCallbacks.length; ++iE) {
				this._errCallbacks[iE](res);
			}
		}

		this._callbacks = [];
		this._errCallbacks = [];
	};

	Operation.prototype.then = function (cb, errCb) {
		if (this._resolved === 1) { // result
			if (cb) {
				cb(this._result);
			}

			return;
		} else if (this._resolved === 2) { // error
			if (errCb) {
				errCb(this._result);
			}
			return;
		}

		if (cb) {
			this._callbacks[this._callbacks.length] = cb;
		}

		if (errCb) {
			this._errCallbacks[this._errCallbacks.length] = errCb;
		}
		return this;
	};

	var defaults = {
		evalPath: isNode ? __dirname + '/eval.js' : null,
		maxWorkers: isNode ? require('os').cpus().length : 4,
		synchronous: true
	};

	function Parallel(data, options) {
		this.data = data;
		this.options = extend(defaults, options);
		this.operation = new Operation();
		this.operation.resolve(null, this.data);
		this.requiredScripts = [];
		this.requiredFunctions = [];
	}

    // static method
    Parallel.isSupported=function(){ return _supports; }

	Parallel.prototype.getWorkerSource = function (cb) {
		var preStr = '';
		var i = 0;
		if (!isNode && this.requiredScripts.length !== 0) {
			preStr += 'importScripts("' + this.requiredScripts.join('","') + '");\r\n';
		}

		for (i = 0; i < this.requiredFunctions.length; ++i) {
			if (this.requiredFunctions[i].name) {
				preStr += 'var ' + this.requiredFunctions[i].name + ' = ' + this.requiredFunctions[i].fn.toString() + ';';
			} else {
				preStr += this.requiredFunctions[i].fn.toString();
			}
		}

		if (isNode) {
			return preStr + 'process.on("message", function(e) {process.send(JSON.stringify((' + cb.toString() + ')(JSON.parse(e).data)))})';
		} else {
			return preStr + 'self.onmessage = function(e) {self.postMessage((' + cb.toString() + ')(e.data))}';
		}
	};

	Parallel.prototype.require = function () {
		var args = Array.prototype.slice.call(arguments, 0),
			func;

		for (var i = 0; i < args.length; i++) {
			func = args[i];

			if (typeof func === 'string') {
				this.requiredScripts.push(func);
			} else if (typeof func === 'function') {
				this.requiredFunctions.push({ fn: func });
			} else if (typeof func === 'object') {
				this.requiredFunctions.push(func);
			}
		}

		return this;
	};

	Parallel.prototype._spawnWorker = function (cb) {
		var wrk;
		var src = this.getWorkerSource(cb);
		if (isNode) {
			wrk = new Worker(this.options.evalPath);
			wrk.postMessage(src);
		} else {
			if (Worker === undefined) {
				return undefined;
			}

			try {
				if (this.requiredScripts.length !== 0) {
					if (this.options.evalPath !== null) {
						wrk = new Worker(this.options.evalPath);
						wrk.postMessage(src);
					} else {
						throw new Error('Can\'t use required scripts without eval.js!');
					}
				} else if (!URL) {
					throw new Error('Can\'t create a blob URL in this browser!');
				} else {
					var blob = new Blob([src], { type: 'text/javascript' });
					var url = URL.createObjectURL(blob);

					wrk = new Worker(url);
				}
			} catch (e) {
				if (this.options.evalPath !== null) { // blob/url unsupported, cross-origin error
					wrk = new Worker(this.options.evalPath);
					wrk.postMessage(src);
				} else {
					throw e;
				}
			}
		}

		return wrk;
	};

	Parallel.prototype.spawn = function (cb) {
		var that = this;
		var newOp = new Operation();
		this.operation.then(function () {
			var wrk = that._spawnWorker(cb);
			if (wrk !== undefined) {
				wrk.onmessage = function (msg) {
					wrk.terminate();
					that.data = msg.data;
					newOp.resolve(null, that.data);
				};
				wrk.postMessage(that.data);
			} else if (that.options.synchronous) {
				setImmediate(function () {
					that.data = cb(that.data);
					newOp.resolve(null, that.data);
				});
			} else {
				throw new Error('Workers do not exist and synchronous operation not allowed!');
			}
		});
		this.operation = newOp;
		return this;
	};

	Parallel.prototype._spawnMapWorker = function (i, cb, done) {
		var that = this;
		var wrk = that._spawnWorker(cb);
		if (wrk !== undefined) {
			wrk.onmessage = function (msg) {
				wrk.terminate();
				that.data[i] = msg.data;
				done();
			};
			wrk.postMessage(that.data[i]);
		} else if (that.options.synchronous) {
			setImmediate(function () {
				that.data[i] = cb(that.data[i]);
				done();
			});
		} else {
			throw new Error('Workers do not exist and synchronous operation not allowed!');
		}
	};

	Parallel.prototype.map = function (cb) {
		if (!this.data.length) {
			return this.spawn(cb);
		}

		var that = this;
		var startedOps = 0;
		var doneOps = 0;
		function done() {
			if (++doneOps === that.data.length) {
				newOp.resolve(null, that.data);
			} else if (startedOps < that.data.length) {
				that._spawnMapWorker(startedOps++, cb, done);
			}
		}

		var newOp = new Operation();
		this.operation.then(function () {
			for (; startedOps - doneOps < that.options.maxWorkers && startedOps < that.data.length; ++startedOps) {
				that._spawnMapWorker(startedOps, cb, done);
			}
		});
		this.operation = newOp;
		return this;
	};

	Parallel.prototype._spawnReduceWorker = function (data, cb, done) {
		var that = this;
		var wrk = that._spawnWorker(cb);
		if (wrk !== undefined) {
			wrk.onmessage = function (msg) {
				wrk.terminate();
				that.data[that.data.length] = msg.data;
				done();
			};
			wrk.postMessage(data);
		} else if (that.options.synchronous) {
			setImmediate(function () {
				that.data[that.data.length] = cb(data);
				done();
			});
		} else {
			throw new Error('Workers do not exist and synchronous operation not allowed!');
		}
	};

	Parallel.prototype.reduce = function (cb) {
		if (!this.data.length) {
			throw new Error('Can\'t reduce non-array data');
		}

		var runningWorkers = 0;
		var that = this;
		function done(data) {
			--runningWorkers;
			if (that.data.length === 1 && runningWorkers === 0) {
				that.data = that.data[0];
				newOp.resolve(null, that.data);
			} else if (that.data.length > 1) {
				++runningWorkers;
				that._spawnReduceWorker([that.data[0], that.data[1]], cb, done);
				that.data.splice(0, 2);
			}
		}

		var newOp = new Operation();
		this.operation.then(function () {
			if (that.data.length === 1) {
				newOp.resolve(null, that.data[0]);
			} else {
				for (var i = 0; i < that.options.maxWorkers && i < Math.floor(that.data.length / 2); ++i) {
					++runningWorkers;
					that._spawnReduceWorker([that.data[i * 2], that.data[i * 2 + 1]], cb, done);
				}

				that.data.splice(0, i * 2);
			}
		});
		this.operation = newOp;
		return this;
	};

	Parallel.prototype.then = function (cb, errCb) {
		var that = this;
		var newOp = new Operation();
		this.operation.then(function () {
			var retData = cb(that.data);
			if (retData !== undefined) {
				that.data = retData;
			}
			newOp.resolve(null, that.data);
		}, errCb);
		this.operation = newOp;
		return this;
	};

	if (isNode) {
		module.exports = Parallel;
	} else {
		self.Parallel = Parallel;
	}
})();<|endoftext|>


<commit_before>var pathToRegexp = require('path-to-regexp');
var util         = require('util');

/**
 * Comparison of the path with a mask.
 *
 * @param  {String} path Inspected path, for example: "j:test-test:test:m:1:"
 * @param  {String} rule Rule-mask to check, for example: "j:*:m:*:"
 * @param  {Object} keys
 * @param  {Boolean} sensitive
 * @param  {Boolean} strict
 */
function pathTest(path, rule, keys, sensitive, strict){
	keys = keys || [];

	if (util.isRegExp(rule)) {

		var match = rule.exec(path);
		if (!match) return false;

		if (match.length > 1) {
			match.splice(0,1);
		}
		if (Array.isArray(keys)) {
			var m = match;
			match = {length: 0};
			keys.forEach(function(el, i) {
				if (m[i]) {
					match[el] = m[i];
					match.length++;
				}
			});
		} else {
			var ret = {length: match.length};
			match.forEach(function(item, i) { ret[i] = item; });
			return ret;
		}
		return match;
	} else if (typeof rule === "string"){

		if (! (/[\*\?\+\:]/gi).test(rule)) {
			if (sensitive && path === rule) {
				return {"0": path, length: 1};
			} else if (!sensitive && path.toLowerCase() === rule.toLowerCase()) {
				return {"0": path, length: 1};
			} else {
				return false;
			}
		}
		if (rule === '' || rule === '*') {
			return  {"0": path, length: 1};
		}

		keys = [];
		var i = 0;
		return pathTest(path, pathToRegexp(rule.replace(/(\*|\?|\:[a-zA-Z0-9_]*)/gi, function(str) {
			if (str.indexOf(':') != -1) {
				keys.push(str.substring(1));
				return str;
			} else {
				i++;
				keys.push(i - 1);
				return ':' + (i - 1);
			}
		}), [], {
			sensitive: (typeof sensitive != 'undefined') ? sensitive : false,
			strict: (typeof strict != 'undefined') ? strict : true,
			end: false
		}), keys);

	}
	return false;
}

module.exports = pathTest;
<commit_msg>Routing fixed<commit_after>var pathToRegexp = require('path-to-regexp');
var util         = require('util');

/**
 * Comparison of the path with a mask.
 *
 * @param  {String} path Inspected path, for example: "j:test-test:test:m:1:"
 * @param  {String} rule Rule-mask to check, for example: "j:*:m:*:"
 * @param  {Object} keys
 * @param  {Boolean} sensitive
 * @param  {Boolean} strict
 */
function pathTest(path, rule, keys, sensitive, strict){
	keys = keys || [];

	if (util.isRegExp(rule)) {

		var match = rule.exec(path);
		if (!match) return false;

		if (match.length > 1) {
			match.splice(0,1);
		}
		if (Array.isArray(keys)) {
			var m = match;
			match = {length: 0};
			keys.forEach(function(el, i) {
				if (m[i]) {
					match[el] = m[i];
					match.length++;
				}
			});
		} else {
			var ret = {length: match.length};
			match.forEach(function(item, i) { ret[i] = item; });
			return ret;
		}
		return match;
	} else if (typeof rule === "string"){

		if (! (/[\*\?\+\:]/gi).test(rule)) {
			if (!sensitive) {
				path = path.toLowerCase();
				rule = rule.toLowerCase();
			}
			if (path === rule || (strict ? false : (path === rule + "/")) ) {
				return {"0": path, length: 1};
			} else {
				return false;
			}
		}
		if (rule === '' || rule === '*') {
			return  {"0": path, length: 1};
		}

		keys = [];
		var i = 0;
		return pathTest(path, pathToRegexp(rule.replace(/(\*|\?|\:[a-zA-Z0-9_]*)/gi, function(str) {
			if (str.indexOf(':') != -1) {
				keys.push(str.substring(1));
				return str;
			} else {
				i++;
				keys.push(i - 1);
				return ':' + (i - 1);
			}
		}), [], {
			sensitive: sensitive ? sensitive : false,
			strict: strict ? strict : false,
			end: false
		}), keys);

	}
	return false;
}

module.exports = pathTest;
<|endoftext|>


<commit_before>'use babel';
'use strict';
/* jshint node: true */
/* jshint esversion: 6 */
/* global localStorage, console, atom, module */
import fs from 'fs';

export const config = {
    verbose: {
        title: "Verbosity",
        type: "integer",
        default: 0,
        minimum: 0,
        maximum: 4,
        order: 0
    },
    phoneip: {
        title: "Phone IP",
        type: "string",
        default: '[...]',
        order: 1
    }
};

class PbBuilder {
    getNiceName() {
        return "Pebble Build";
    }

    isEligible() {
        // Based on code from: https://github.com/AtomBuild/atom-build-cargo/
        /*
            Copyright (c) 2015 Alexander Olsson

            Permission is hereby granted, free of charge, to any person
            obtaining a copy of this software and associated documentation files
            (the "Software"), to deal in the Software without restriction,
            including without limitation the rights to use, copy, modify, merge,
            publish, distribute, sublicense, and/or sell copies of the Software,
            and to permit persons to whom the Software is furnished to do so,
            subject to the following conditions:

            The above copyright notice and this permission notice shall be
            included in all copies or substantial portions of the Software.

            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
            OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
            BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
            ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
            CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
            THE SOFTWARE.
        */
        return fs.existsSync(`${atom.project.getPaths()[0]}/appinfo.json`);
    }

    settings() {
        var verbose = atom.config.get('pb-build.verbose');
        verbose = verbose ? ('-' + new Array(verbose + 1).join('v')) : '';
        var buildCmd = "echo Starting build in `pwd`; pebble build " + verbose;
        return [{"name": "Pebble Tool: Build & Install to Aplite",
                    "exec": buildCmd + " && " +
                        "pebble install --emulator aplite " + verbose,
                    "cwd": "{PROJECT_PATH}"},

                {"name": "Pebble Tool: Build & Install to Basalt",
                    "exec": buildCmd + " && " +
                        "pebble install --emulator basalt " + verbose,
                    "cwd": "{PROJECT_PATH}"},

                {"name": "Pebble Tool: Build & Install to Chalk",
                    "exec": buildCmd + " && " +
                        "pebble install --emulator chalk " + verbose,
                    "cwd": "{PROJECT_PATH}"},

                {"name": "Pebble Tool: Build",
                    "exec": buildCmd,
                    "cwd": "{PROJECT_PATH}"},

                {"name": "Pebble Tool: Build & Install via CloudPebble",
                    "exec": buildCmd + " && " +
                        "pebble install --cloudpebble " + verbose,
                    "cwd": "{PROJECT_PATH}"},

                {"name": "Pebble Tool: Build & Install to Phone",
                    "exec": buildCmd + " && " +
                        "pebble install --phone " + verbose +
                        atom.config.get('pb-build.phoneip'),
                    "cwd": "{PROJECT_PATH}"}];
    }
}

export function providingFunction() {
    return PbBuilder;
}
<commit_msg>Add error matching capability<commit_after>'use babel';
'use strict';
/* jshint node: true */
/* jshint esversion: 6 */
/* global localStorage, console, atom, module */
import fs from 'fs';

export const config = {
    verbose: {
        title: "Verbosity",
        type: "integer",
        default: 0,
        minimum: 0,
        maximum: 4,
        order: 0
    },
    phoneip: {
        title: "Phone IP",
        type: "string",
        default: '[...]',
        order: 1
    }
};

class PbBuilder {
    getNiceName() {
        return "Pebble Build";
    }

    isEligible() {
        // Based on code from: https://github.com/AtomBuild/atom-build-cargo/
        /*
            Copyright (c) 2015 Alexander Olsson

            Permission is hereby granted, free of charge, to any person
            obtaining a copy of this software and associated documentation files
            (the "Software"), to deal in the Software without restriction,
            including without limitation the rights to use, copy, modify, merge,
            publish, distribute, sublicense, and/or sell copies of the Software,
            and to permit persons to whom the Software is furnished to do so,
            subject to the following conditions:

            The above copyright notice and this permission notice shall be
            included in all copies or substantial portions of the Software.

            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
            OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
            BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
            ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
            CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
            THE SOFTWARE.
        */
        return fs.existsSync(`${atom.project.getPaths()[0]}/appinfo.json`);
    }

    settings() {
        let verbose = atom.config.get('pb-build.verbose');
            verbose = verbose ? ('-' + new Array(verbose + 1).join('v')) : '';
        let buildCmd = "echo Starting build in `pwd`; pebble build " + verbose;
        let errorMatch = '../(?<file>.+):(?<line>\\d+):(?<col>\\d+): error:';
        return [{name: "Pebble Tool: Build & Install to Aplite",
                    exec: buildCmd + " && " +
                        "pebble install --emulator aplite " + verbose,
                    cwd: "{PROJECT_PATH}",
                    errorMatch: errorMatch},

                {name: "Pebble Tool: Build & Install to Basalt",
                    exec: buildCmd + " && " +
                        "pebble install --emulator basalt " + verbose,
                    cwd: "{PROJECT_PATH}",
                    errorMatch: errorMatch},

                {name: "Pebble Tool: Build & Install to Chalk",
                    exec: buildCmd + " && " +
                        "pebble install --emulator chalk " + verbose,
                    cwd: "{PROJECT_PATH}",
                    errorMatch: errorMatch},

                {name: "Pebble Tool: Build",
                    exec: buildCmd,
                    cwd: "{PROJECT_PATH}",
                    errorMatch: errorMatch},

                {name: "Pebble Tool: Build & Install via CloudPebble",
                    exec: buildCmd + " && " +
                        "pebble install --cloudpebble " + verbose,
                    cwd: "{PROJECT_PATH}",
                    errorMatch: errorMatch},

                {name: "Pebble Tool: Build & Install to Phone",
                    exec: buildCmd + " && " +
                        "pebble install --phone " + verbose +
                        atom.config.get('pb-build.phoneip'),
                    cwd: "{PROJECT_PATH}",
                    errorMatch: errorMatch}];
    }
}

export function providingFunction() {
    return PbBuilder;
}
<|endoftext|>


<commit_before>// Setup
const currentDir = process.cwd()
const path = require('path')
var appInfo
try {
  appInfo = require(path.join(currentDir, 'package.json'))
} catch (e) {
  console.log('pgFuncs command needs to be run in an OACP API directory')
  process.exit(0)
}
const oacpConf = appInfo.oacp || {jwt: {}, env: {}}
const fs = require('fs')
const PG = require('./pg')
const assets = path.resolve(__dirname, '../', 'assets')
const outBase = path.join(currentDir, 'db', 'pg_funcs')
var bpFuncs = {}
bpFuncs.search = fs.readFileSync(path.join(assets, '_pgfunc_search.sql'))
bpFuncs.create = fs.readFileSync(path.join(assets, '_pgfunc_create.sql'))
bpFuncs.read = fs.readFileSync(path.join(assets, '_pgfunc_read.sql'))
bpFuncs.update = fs.readFileSync(path.join(assets, '_pgfunc_update.sql'))
bpFuncs.delete = fs.readFileSync(path.join(assets, '_pgfunc_delete.sql'))
// Variable setup
var namespace = oacpConf.namespace
var schema = 'public'
var resources

module.exports = (resourceList, options) => {
  resources = resourceList
  schema = (typeof options.name === 'function') ? schema : options.name
  console.log('made it here')
  makePgFunctions()
}

// Iterate over all resources
function makePgFunctions () {
  resources.forEach((r) => new PgFunc(r))
}

// PgFunc class
function PgFunc (resource) {
  console.log(`Started on pgfuncs for ${resource}`)
  var self = this
  self.columns = {core: []}
  self.resource = resource
  self.pg = new PG()
  function runGetColumns () { self.getColumns() }
  self.pg.on('ready', runGetColumns)
  return self
}

// Make that isht
PgFunc.prototype.getColumns = function () {
  var self = this
  var resource = self.resource
  var query = '' +
    'SELECT column_name, column_default, udt_name::regtype AS data_type ' +
    'FROM information_schema.columns ' +
    'WHERE table_schema = $1 AND table_name = $2;'
  self.pg
    .query(query, [schema, resource])
    .on('error', (err) => console.log(err))
    .on('data', (data) => self.setColumnObject(data.rows))
}

PgFunc.prototype.setColumnObject = function (rawCols) {
  var self = this
  var columns = self.columns
  var typed = (t) => t === 'USER-DEFINED' ? 'citext' : t
  rawCols.forEach((c) => {
    if ((c.column_default || '').match(/nextval/)) {
      columns.primary = {name: c.column_name, type: typed(c.data_type)}
    } else {
      columns.core.push({name: c.column_name, type: typed(c.data_type)})
    }
  })
  return self.writePgFunctions()
}

PgFunc.prototype.writePgFunctions = function () {
  var self = this
  if (self.columns.core.length === 0) {
    return console.error(`No columns found for ${self.resource}`)
  }
  var resource = self.resource
  var columns = self.columns
  var columnList, columnListB, columnListC, columnListD
  ['search', 'create', 'read', 'update', 'delete'].forEach((action) => {
    if (!bpFuncs[action]) {
      return console.error(`No matching asset found for ${action}`)
    }
    columnList =
      [columns.primary].concat(columns.core)
        .map((c) => `      ${c.name}`).join(',\n').trim()
    switch (action) {
      case 'search':
        columnList =
          columns.core.map((c) =>
            `  v_${c.name} ${c.type}`
          ).join(';\n').trim()
        columnListB =
          columns.core.map((c) =>
            c.type.match(/text|char/)
            ? `    NULLIF(BTRIM((p_jsonb->>'${c.name}')::${c.type}), '')`
            : `    (p_jsonb->>'${c.name}')::${c.type}`
          ).join(',\n').trim()
        columnListC =
          columns.core.map((c) =>
            `    v_${c.name}`
          ).join(',\n').trim()
        columnListD =
          columns.core.map((c) =>
            c.type.match(/text|char/)
            ? `    (v_${c.name} IS null OR ${c.name} ` +
              `LIKE '%' || v_${c.name} || '%')`
            : `    (v_${c.name} IS null OR ${c.name} = v_${c.name})`
          ).join(' AND\n').trim()
        break
      case 'create':
        columnList =
          columns.core
            .map((c) => `    ${c.name}`).join(',\n').trim()
        columnListB =
          columns.core.map((c) =>
            `      (p_jsonb->>'${c.name}')::${c.type}`
          ).join(',\n').trim()
        break
      case 'update':
        columnList =
          columns.core.map((c) =>
            `    ${c.name} = ` +
            `coalesce((p_jsonb->>'${c.name}')::${c.type}, ${c.name})`
          ).join(',\n').trim()
        break
    }
    var pathOut = path.join(outBase, `${namespace}_${resource}_${action}.sql`)
    var out =
      bpFuncs[action].toString()
        .replace(/{{namespace}}/g, namespace)
        .replace(/{{resource}}/g, resource)
        .replace(/{{primary_key}}/g, columns.primary.name)
        .replace(/{{pkey_type}}/g, columns.primary.type)
        .replace(/{{column_list}}/g, columnList)
        .replace(/{{column_list_b}}/g, (columnListB || ''))
        .replace(/{{column_list_c}}/g, (columnListC || ''))
        .replace(/{{column_list_d}}/g, (columnListD || ''))
    fs.writeFileSync(pathOut, out)
    console.log(`Created ${pathOut}`)
  })
}
<commit_msg>Debug<commit_after>// Setup
const currentDir = process.cwd()
const path = require('path')
var appInfo
try {
  appInfo = require(path.join(currentDir, 'package.json'))
} catch (e) {
  console.log('pgFuncs command needs to be run in an OACP API directory')
  process.exit(0)
}
const oacpConf = appInfo.oacp || {jwt: {}, env: {}}
const fs = require('fs')
const PG = require('./pg')
const assets = path.resolve(__dirname, '../', 'assets')
const outBase = path.join(currentDir, 'db', 'pg_funcs')
var bpFuncs = {}
bpFuncs.search = fs.readFileSync(path.join(assets, '_pgfunc_search.sql'))
bpFuncs.create = fs.readFileSync(path.join(assets, '_pgfunc_create.sql'))
bpFuncs.read = fs.readFileSync(path.join(assets, '_pgfunc_read.sql'))
bpFuncs.update = fs.readFileSync(path.join(assets, '_pgfunc_update.sql'))
bpFuncs.delete = fs.readFileSync(path.join(assets, '_pgfunc_delete.sql'))
// Variable setup
var namespace = oacpConf.namespace
var schema = 'public'
var resources

module.exports = (resourceList, options) => {
  resources = resourceList
  schema = (typeof options.name === 'function') ? schema : options.name
  console.log('made it here')
  makePgFunctions()
}

// Iterate over all resources
function makePgFunctions () {
  resources.forEach((r) => new PgFunc(r))
}

// PgFunc class
function PgFunc (resource) {
  console.log(`Started on pgfuncs for ${resource}`)
  var self = this
  self.columns = {core: []}
  self.resource = resource
  self.pg = new PG()
  function runGetColumns () { self.getColumns() }
  self.pg.on('ready', runGetColumns)
  return self
}

// Make that isht
PgFunc.prototype.getColumns = function () {
  var self = this
  var resource = self.resource
  var query = '' +
    'SELECT column_name, column_default, udt_name::regtype AS data_type ' +
    'FROM information_schema.columns ' +
    'WHERE table_schema = $1 AND table_name = $2;'
  console.log(query)
  self.pg
    .query(query, [schema, resource])
    .on('error', (err) => console.log(err))
    .on('data', (data) => self.setColumnObject(data.rows))
}

PgFunc.prototype.setColumnObject = function (rawCols) {
  var self = this
  var columns = self.columns
  var typed = (t) => t === 'USER-DEFINED' ? 'citext' : t
  rawCols.forEach((c) => {
    if ((c.column_default || '').match(/nextval/)) {
      columns.primary = {name: c.column_name, type: typed(c.data_type)}
    } else {
      columns.core.push({name: c.column_name, type: typed(c.data_type)})
    }
  })
  return self.writePgFunctions()
}

PgFunc.prototype.writePgFunctions = function () {
  var self = this
  if (self.columns.core.length === 0) {
    return console.error(`No columns found for ${self.resource}`)
  }
  var resource = self.resource
  var columns = self.columns
  var columnList, columnListB, columnListC, columnListD
  ['search', 'create', 'read', 'update', 'delete'].forEach((action) => {
    if (!bpFuncs[action]) {
      return console.error(`No matching asset found for ${action}`)
    }
    columnList =
      [columns.primary].concat(columns.core)
        .map((c) => `      ${c.name}`).join(',\n').trim()
    switch (action) {
      case 'search':
        columnList =
          columns.core.map((c) =>
            `  v_${c.name} ${c.type}`
          ).join(';\n').trim()
        columnListB =
          columns.core.map((c) =>
            c.type.match(/text|char/)
            ? `    NULLIF(BTRIM((p_jsonb->>'${c.name}')::${c.type}), '')`
            : `    (p_jsonb->>'${c.name}')::${c.type}`
          ).join(',\n').trim()
        columnListC =
          columns.core.map((c) =>
            `    v_${c.name}`
          ).join(',\n').trim()
        columnListD =
          columns.core.map((c) =>
            c.type.match(/text|char/)
            ? `    (v_${c.name} IS null OR ${c.name} ` +
              `LIKE '%' || v_${c.name} || '%')`
            : `    (v_${c.name} IS null OR ${c.name} = v_${c.name})`
          ).join(' AND\n').trim()
        break
      case 'create':
        columnList =
          columns.core
            .map((c) => `    ${c.name}`).join(',\n').trim()
        columnListB =
          columns.core.map((c) =>
            `      (p_jsonb->>'${c.name}')::${c.type}`
          ).join(',\n').trim()
        break
      case 'update':
        columnList =
          columns.core.map((c) =>
            `    ${c.name} = ` +
            `coalesce((p_jsonb->>'${c.name}')::${c.type}, ${c.name})`
          ).join(',\n').trim()
        break
    }
    var pathOut = path.join(outBase, `${namespace}_${resource}_${action}.sql`)
    var out =
      bpFuncs[action].toString()
        .replace(/{{namespace}}/g, namespace)
        .replace(/{{resource}}/g, resource)
        .replace(/{{primary_key}}/g, columns.primary.name)
        .replace(/{{pkey_type}}/g, columns.primary.type)
        .replace(/{{column_list}}/g, columnList)
        .replace(/{{column_list_b}}/g, (columnListB || ''))
        .replace(/{{column_list_c}}/g, (columnListC || ''))
        .replace(/{{column_list_d}}/g, (columnListD || ''))
    fs.writeFileSync(pathOut, out)
    console.log(`Created ${pathOut}`)
  })
}
<|endoftext|>


<commit_before>import { ajax } from 'discourse/lib/ajax';
import { default as computed, observes } from "ember-addons/ember-computed-decorators";

export default Ember.Controller.extend({
  isMultiple: Ember.computed.equal("poll.type", "multiple"),
  isNumber: Ember.computed.equal("poll.type", "number"),
  isRandom : Ember.computed.equal("poll.order", "random"),
  isClosed: Ember.computed.equal("poll.status", "closed"),
  isPublic: Ember.computed.equal("poll.public", "true"),

  // shows the results when
  //   - poll is closed
  //   - topic is archived
  //   - user wants to see the results
  showingResults: Em.computed.or("isClosed", "post.topic.archived", "showResults"),

  showResultsDisabled: Em.computed.equal("poll.voters", 0),
  hideResultsDisabled: Em.computed.or("isClosed", "post.topic.archived"),

  @observes("post.polls")
  _updatePoll() {
    this.set("model", this.get("post.pollsObject")[this.get("model.name")]);
  },

  @computed("model", "vote", "model.voters", "model.options", "model.status")
  poll(poll, vote) {
    if (poll) {
      const options = _.map(poll.get("options"), o => Em.Object.create(o));

      if (vote) {
        options.forEach(o => o.set("selected", vote.indexOf(o.get("id")) >= 0));
      }

      poll.set("options", options);
    }

    return poll;
  },

  @computed("poll.options.@each.selected")
  selectedOptions() {
    return _.map(this.get("poll.options").filterBy("selected"), o => o.get("id"));
  },

  @computed("poll.min")
  min(min) {
    min = parseInt(min, 10);
    if (isNaN(min) || min < 1) { min = 1; }
    return min;
  },

  @computed("poll.max", "poll.options.length")
  max(max, options) {
    max = parseInt(max, 10);
    if (isNaN(max) || max > options) { max = options; }
    return max;
  },

  @computed("poll.voters")
  votersText(count) {
    return I18n.t("poll.voters", { count });
  },

  @computed("poll.options.@each.votes")
  totalVotes() {
    return _.reduce(this.get("poll.options"), function(total, o) {
      return total + parseInt(o.get("votes"), 10);
    }, 0);
  },

  @computed("totalVotes")
  totalVotesText(count) {
    return I18n.t("poll.total_votes", { count });
  },

  @computed("min", "max", "poll.options.length")
  multipleHelpText(min, max, options) {
    if (max > 0) {
      if (min === max) {
        if (min > 1) {
          return I18n.t("poll.multiple.help.x_options", { count: min });
        }
      } else if (min > 1) {
        if (max < options) {
          return I18n.t("poll.multiple.help.between_min_and_max_options", { min, max });
        } else {
          return I18n.t("poll.multiple.help.at_least_min_options", { count: min });
        }
      } else if (max <= options) {
        return I18n.t("poll.multiple.help.up_to_max_options", { count: max });
      }
    }
  },

  @computed("isClosed", "showResults", "loading", "isMultiple", "selectedOptions.length", "min", "max")
  canCastVotes(isClosed, showResults, loading, isMultiple, selectedOptionCount, min, max) {
    if (isClosed || showResults || loading) {
      return false;
    }

    if (isMultiple) {
      return selectedOptionCount >= min && selectedOptionCount <= max;
    } else {
      return selectedOptionCount > 0;
    }
  },

  castVotesDisabled: Em.computed.not("canCastVotes"),

  @computed("castVotesDisabled")
  castVotesButtonClass(castVotesDisabled) {
    return `cast-votes ${castVotesDisabled ? '' : 'btn-primary'}`;
  },

  @computed("loading", "post.user_id", "post.topic.archived")
  canToggleStatus(loading, userId, topicArchived) {
    return this.currentUser &&
           (this.currentUser.get("id") === userId || this.currentUser.get("staff")) &&
           !loading &&
           !topicArchived;
  },

  actions: {

    toggleOption(option) {
      if (this.get("isClosed")) { return; }
      if (!this.currentUser) { return this.send("showLogin"); }

      const wasSelected = option.get("selected");

      if (!this.get("isMultiple")) {
        this.get("poll.options").forEach(o => o.set("selected", false));
      }

      option.toggleProperty("selected");

      if (!this.get("isMultiple") && !wasSelected) { this.send("castVotes"); }
    },

    castVotes() {
      if (!this.get("canCastVotes")) { return; }
      if (!this.currentUser) { return this.send("showLogin"); }

      this.set("loading", true);

      ajax("/polls/vote", {
        type: "PUT",
        data: {
          post_id: this.get("post.id"),
          poll_name: this.get("poll.name"),
          options: this.get("selectedOptions"),
        }
      }).then(results => {
        const poll = results.poll;
        const votes = results.vote;

        this.setProperties({ vote: votes, showResults: true });
        this.set("model", Em.Object.create(poll));
      }).catch(() => {
        bootbox.alert(I18n.t("poll.error_while_casting_votes"));
      }).finally(() => {
        this.set("loading", false);
      });
    },

    toggleResults() {
      this.toggleProperty("showResults");
    },

    toggleStatus() {
      if (!this.get("canToggleStatus")) { return; }

      const self = this,
            confirm = this.get("isClosed") ? "poll.open.confirm" : "poll.close.confirm";

      bootbox.confirm(
        I18n.t(confirm),
        I18n.t("no_value"),
        I18n.t("yes_value"),
        function(confirmed) {
          if (confirmed) {
            self.set("loading", true);

            ajax("/polls/toggle_status", {
              type: "PUT",
              data: {
                post_id: self.get("post.id"),
                poll_name: self.get("poll.name"),
                status: self.get("isClosed") ? "open" : "closed",
              }
            }).then(results => {
              self.set("model", Em.Object.create(results.poll));
            }).catch(() => {
              bootbox.alert(I18n.t("poll.error_while_toggling_status"));
            }).finally(() => {
              self.set("loading", false);
            });
          }
        }
      );

    },
  }

});
<commit_msg>Remove unused property.<commit_after>import { ajax } from 'discourse/lib/ajax';
import { default as computed, observes } from "ember-addons/ember-computed-decorators";

export default Ember.Controller.extend({
  isMultiple: Ember.computed.equal("poll.type", "multiple"),
  isNumber: Ember.computed.equal("poll.type", "number"),
  isClosed: Ember.computed.equal("poll.status", "closed"),
  isPublic: Ember.computed.equal("poll.public", "true"),

  // shows the results when
  //   - poll is closed
  //   - topic is archived
  //   - user wants to see the results
  showingResults: Em.computed.or("isClosed", "post.topic.archived", "showResults"),

  showResultsDisabled: Em.computed.equal("poll.voters", 0),
  hideResultsDisabled: Em.computed.or("isClosed", "post.topic.archived"),

  @observes("post.polls")
  _updatePoll() {
    this.set("model", this.get("post.pollsObject")[this.get("model.name")]);
  },

  @computed("model", "vote", "model.voters", "model.options", "model.status")
  poll(poll, vote) {
    if (poll) {
      const options = _.map(poll.get("options"), o => Em.Object.create(o));

      if (vote) {
        options.forEach(o => o.set("selected", vote.indexOf(o.get("id")) >= 0));
      }

      poll.set("options", options);
    }

    return poll;
  },

  @computed("poll.options.@each.selected")
  selectedOptions() {
    return _.map(this.get("poll.options").filterBy("selected"), o => o.get("id"));
  },

  @computed("poll.min")
  min(min) {
    min = parseInt(min, 10);
    if (isNaN(min) || min < 1) { min = 1; }
    return min;
  },

  @computed("poll.max", "poll.options.length")
  max(max, options) {
    max = parseInt(max, 10);
    if (isNaN(max) || max > options) { max = options; }
    return max;
  },

  @computed("poll.voters")
  votersText(count) {
    return I18n.t("poll.voters", { count });
  },

  @computed("poll.options.@each.votes")
  totalVotes() {
    return _.reduce(this.get("poll.options"), function(total, o) {
      return total + parseInt(o.get("votes"), 10);
    }, 0);
  },

  @computed("totalVotes")
  totalVotesText(count) {
    return I18n.t("poll.total_votes", { count });
  },

  @computed("min", "max", "poll.options.length")
  multipleHelpText(min, max, options) {
    if (max > 0) {
      if (min === max) {
        if (min > 1) {
          return I18n.t("poll.multiple.help.x_options", { count: min });
        }
      } else if (min > 1) {
        if (max < options) {
          return I18n.t("poll.multiple.help.between_min_and_max_options", { min, max });
        } else {
          return I18n.t("poll.multiple.help.at_least_min_options", { count: min });
        }
      } else if (max <= options) {
        return I18n.t("poll.multiple.help.up_to_max_options", { count: max });
      }
    }
  },

  @computed("isClosed", "showResults", "loading", "isMultiple", "selectedOptions.length", "min", "max")
  canCastVotes(isClosed, showResults, loading, isMultiple, selectedOptionCount, min, max) {
    if (isClosed || showResults || loading) {
      return false;
    }

    if (isMultiple) {
      return selectedOptionCount >= min && selectedOptionCount <= max;
    } else {
      return selectedOptionCount > 0;
    }
  },

  castVotesDisabled: Em.computed.not("canCastVotes"),

  @computed("castVotesDisabled")
  castVotesButtonClass(castVotesDisabled) {
    return `cast-votes ${castVotesDisabled ? '' : 'btn-primary'}`;
  },

  @computed("loading", "post.user_id", "post.topic.archived")
  canToggleStatus(loading, userId, topicArchived) {
    return this.currentUser &&
           (this.currentUser.get("id") === userId || this.currentUser.get("staff")) &&
           !loading &&
           !topicArchived;
  },

  actions: {

    toggleOption(option) {
      if (this.get("isClosed")) { return; }
      if (!this.currentUser) { return this.send("showLogin"); }

      const wasSelected = option.get("selected");

      if (!this.get("isMultiple")) {
        this.get("poll.options").forEach(o => o.set("selected", false));
      }

      option.toggleProperty("selected");

      if (!this.get("isMultiple") && !wasSelected) { this.send("castVotes"); }
    },

    castVotes() {
      if (!this.get("canCastVotes")) { return; }
      if (!this.currentUser) { return this.send("showLogin"); }

      this.set("loading", true);

      ajax("/polls/vote", {
        type: "PUT",
        data: {
          post_id: this.get("post.id"),
          poll_name: this.get("poll.name"),
          options: this.get("selectedOptions"),
        }
      }).then(results => {
        const poll = results.poll;
        const votes = results.vote;

        this.setProperties({ vote: votes, showResults: true });
        this.set("model", Em.Object.create(poll));
      }).catch(() => {
        bootbox.alert(I18n.t("poll.error_while_casting_votes"));
      }).finally(() => {
        this.set("loading", false);
      });
    },

    toggleResults() {
      this.toggleProperty("showResults");
    },

    toggleStatus() {
      if (!this.get("canToggleStatus")) { return; }

      const self = this,
            confirm = this.get("isClosed") ? "poll.open.confirm" : "poll.close.confirm";

      bootbox.confirm(
        I18n.t(confirm),
        I18n.t("no_value"),
        I18n.t("yes_value"),
        function(confirmed) {
          if (confirmed) {
            self.set("loading", true);

            ajax("/polls/toggle_status", {
              type: "PUT",
              data: {
                post_id: self.get("post.id"),
                poll_name: self.get("poll.name"),
                status: self.get("isClosed") ? "open" : "closed",
              }
            }).then(results => {
              self.set("model", Em.Object.create(results.poll));
            }).catch(() => {
              bootbox.alert(I18n.t("poll.error_while_toggling_status"));
            }).finally(() => {
              self.set("loading", false);
            });
          }
        }
      );

    },
  }

});
<|endoftext|>


<commit_before>// ==UserScript==
// @id             iitc-plugin-highlight-portals-with-L8-resonators@superd
// @name           IITC plugin: highlight portals with L8 resonators
// @version        0.1.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill red of the portals, if portal has L8 res
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

function wrapper() {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.portalsWithL8Resonators = function() {};

window.plugin.portalsWithL8Resonators.highlight = function(data) {
  var d = data.portal.options.details;
  var has_L8 = 0;
  var portal_weakness = 0;
  if(getTeam(d) !== 0) {
    //Ding the portal for every missing resonator.
    var resCount = 0;
    $.each(d.resonatorArray.resonators, function(ind, reso) {
      if(reso === null) {
        portal_weakness += .125;
      } else {
        var level = parseInt(reso.level);
        if(level == 8)
        {
          has_L8+=1;
        }
        resCount++;
      }
    });

    //alert("has L8 res"+has_L8);

    if(has_L8 > 0)
    {
      var color = 'red';
      var params = {fillColor: color, fillOpacity: 0.5};
      data.portal.setStyle(params);
    }else
    {
      /* var color = 'blue';
      var params = {fillColor: color, fillOpacity: 0.5};
      data.portal.setStyle(params);
      */
    }
  }
  window.COLOR_SELECTED_PORTAL = '#f0f';
}

var setup =  function() {
  window.addPortalHighlighter('Portals with L8 Resonators', window.plugin.portalsWithL8Resonators.highlight);
}

// PLUGIN END //////////////////////////////////////////////////////////

if(window.iitcLoaded && typeof setup === 'function') {
  setup();
} else {
  if(window.bootPlugins)
    window.bootPlugins.push(setup);
  else
    window.bootPlugins = [setup];
}
} // wrapper end
// inject code into site context
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ wrapper +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
<commit_msg>Update portal-highlighter-with-lvl8-resonators.user.js<commit_after>// ==UserScript==
// @id             iitc-plugin-highlight-portals-with-L8-resonators@superd
// @name           IITC plugin: highlight portals with L8 resonators
// @version        0.1.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill red of the portals, if portal has L8 res
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

function wrapper() {
// ensure plugin framework is there, even if iitc is not yet loaded
if(typeof window.plugin !== 'function') window.plugin = function() {};

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.portalsWithL8Resonators = function() {};

window.plugin.portalsWithL8Resonators.highlight = function(data) {
  var d = data.portal.options.details;
  var has_L8 = 0;
  if(getTeam(d) !== 0) {
    $.each(d.resonatorArray.resonators, function(ind, reso) {
      if(reso) {
        var level = parseInt(reso.level);
        if(level == 8)
        {
          has_L8+=1;
        }
      }
    });
  }

  if(has_L8 > 0)
  {
    var color = 'red';
    var opa = has_L8 * 0.125;
    var params = {fillColor: color, fillOpacity: opa};
    data.portal.setStyle(params);
   }
  window.COLOR_SELECTED_PORTAL = '#f0f';
}

var setup =  function() {
  window.addPortalHighlighter('Portals with L8 Resonators', window.plugin.portalsWithL8Resonators.highlight);
}

// PLUGIN END //////////////////////////////////////////////////////////

if(window.iitcLoaded && typeof setup === 'function') {
  setup();
} else {
  if(window.bootPlugins)
    window.bootPlugins.push(setup);
  else
    window.bootPlugins = [setup];
}
} // wrapper end
// inject code into site context
var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ wrapper +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
<|endoftext|>


<commit_before>'use strict';

var path = require('path'),
    url = require('url');

var Q = require('q');

var manifoldjsLib = require('manifoldjs-lib');

var PlatformBase = manifoldjsLib.PlatformBase,
    manifestTools = manifoldjsLib.manifestTools,
    CustomError = manifoldjsLib.CustomError,
    fileTools = manifoldjsLib.fileTools,
    iconTools = manifoldjsLib.iconTools;

var constants = require('./constants'),
    manifest = require('./manifest');

function Platform (packageName, platforms) {

  var self = this;
  Object.assign(this, PlatformBase.prototype);
  PlatformBase.apply(this, [constants.platform.id, constants.platform.name, packageName, __dirname]);

  // save platform list
  self.platforms = platforms;

  // override create function
  self.create = function (w3cManifestInfo, rootDir, options, callback) {

    self.info('Generating the ' + constants.platform.name + ' app...');

    var platformDir = path.join(rootDir, constants.platform.id);

    // convert the W3C manifest to a platform-specific manifest
    var platformManifestInfo;
    return manifest.convertFromBase(w3cManifestInfo)
      // if the platform dir doesn't exist, create it
      .then(function (manifestInfo) {
        platformManifestInfo = manifestInfo;
        self.debug('Creating the ' + constants.platform.name + ' app folder...');
        return fileTools.mkdirp(platformDir);
      })
      // download icons to the app's folder
      .then(function () {
        self.debug('Downloading the ' + constants.platform.name + ' icons...');
        var icons = platformManifestInfo.content.icons;
        if (icons) {
          var downloadTasks = Object.keys(icons).map(function (size) {
            var iconPath = icons[size];
            var iconUrl = url.resolve(w3cManifestInfo.content.start_url, iconPath);
            var iconFilePath = path.join(platformDir, iconPath);
            return iconTools.getIcon(iconUrl, iconFilePath);
          });

          return Q.allSettled(downloadTasks).then(function (results) {
            results.forEach(function (result) {
              if (result.state === 'rejected') {
                self.warn('Error downloading an icon file. ' + result.reason.message);
              }
            })
          });
        }
      })
      // copy default platform icon
      .then(function () {
        return self.copyDefaultPlatformIcon(platformManifestInfo, '128', platformDir)
      })
      // copy the documentation
      .then(function () {
        return self.copyDocumentation(platformDir);
      })
      // create generation info
      .then(function () {
        return self.createGenerationInfo(platformDir);
      })
      // persist the platform-specific manifest
      .then(function () {
        self.debug('Copying the ' + constants.platform.name + ' manifest to the app folder...');
        var manifestFilePath = path.join(platformDir, 'manifest.json');
        return manifestTools.writeToFile(platformManifestInfo, manifestFilePath);
      })
      .then(function () {
        self.info('Created the ' + constants.platform.name + ' app!');
      })
      .catch(function (err) {
        return Q.reject(new CustomError('The ' + constants.platform.name + ' app could not be created successfully.', err));
      })
      .nodeify(callback);
  };
}

module.exports = Platform;
<commit_msg>Fixed invalid icon path when manifest specifies a full URL<commit_after>'use strict';

var path = require('path'),
    url = require('url');

var Q = require('q');

var manifoldjsLib = require('manifoldjs-lib');

var PlatformBase = manifoldjsLib.PlatformBase,
    manifestTools = manifoldjsLib.manifestTools,
    CustomError = manifoldjsLib.CustomError,
    fileTools = manifoldjsLib.fileTools,
    iconTools = manifoldjsLib.iconTools;

var constants = require('./constants'),
    manifest = require('./manifest');

function Platform (packageName, platforms) {

  var self = this;
  Object.assign(this, PlatformBase.prototype);
  PlatformBase.apply(this, [constants.platform.id, constants.platform.name, packageName, __dirname]);

  // save platform list
  self.platforms = platforms;

  // override create function
  self.create = function (w3cManifestInfo, rootDir, options, callback) {

    self.info('Generating the ' + constants.platform.name + ' app...');

    var platformDir = path.join(rootDir, constants.platform.id);

    // convert the W3C manifest to a platform-specific manifest
    var platformManifestInfo;
    return manifest.convertFromBase(w3cManifestInfo)
      // if the platform dir doesn't exist, create it
      .then(function (manifestInfo) {
        platformManifestInfo = manifestInfo;
        self.debug('Creating the ' + constants.platform.name + ' app folder...');
        return fileTools.mkdirp(platformDir);
      })
      // download icons to the app's folder
      .then(function () {
        self.debug('Downloading the ' + constants.platform.name + ' icons...');
        var icons = platformManifestInfo.content.icons;
        if (icons) {
          var downloadTasks = Object.keys(icons).map(function (size) {
            var iconPath = icons[size];
            var iconUrl = url.resolve(w3cManifestInfo.content.start_url, iconPath);
            var iconFilePath = path.join(platformDir, url.parse(icons[size]).pathname);
            return iconTools.getIcon(iconUrl, iconFilePath);
          });

          return Q.allSettled(downloadTasks).then(function (results) {
            results.forEach(function (result) {
              if (result.state === 'rejected') {
                self.warn('Error downloading an icon file. ' + result.reason.message);
              }
            })
          });
        }
      })
      // copy default platform icon
      .then(function () {
        return self.copyDefaultPlatformIcon(platformManifestInfo, '128', platformDir)
      })
      // copy the documentation
      .then(function () {
        return self.copyDocumentation(platformDir);
      })
      // create generation info
      .then(function () {
        return self.createGenerationInfo(platformDir);
      })
      // persist the platform-specific manifest
      .then(function () {
        self.debug('Copying the ' + constants.platform.name + ' manifest to the app folder...');
        var manifestFilePath = path.join(platformDir, 'manifest.json');
        return manifestTools.writeToFile(platformManifestInfo, manifestFilePath);
      })
      .then(function () {
        self.info('Created the ' + constants.platform.name + ' app!');
      })
      .catch(function (err) {
        return Q.reject(new CustomError('The ' + constants.platform.name + ' app could not be created successfully.', err));
      })
      .nodeify(callback);
  };
}

module.exports = Platform;
<|endoftext|>


<commit_before>/*
The MIT License (MIT)
Copyright (c) 2013 Calvin Montgomery

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

ULList = require("./ullist").ULList;
var AsyncQueue = require("./asyncqueue");
var Media = require("./media").Media;
var AllPlaylists = {};
var Server = require("./server");
var VimeoIsADoucheCopter = require("./get-info").VimeoIsADoucheCopter;

function PlaylistItem(media, uid) {
    this.media = media;
    this.uid = uid;
    this.temp = false;
    this.queueby = "";
    this.prev = null;
    this.next = null;
}

PlaylistItem.prototype.pack = function() {
    return {
        media: this.media.pack(),
        uid: this.uid,
        temp: this.temp,
        queueby: this.queueby
    };
}

function Playlist(chan) {
    var name = chan.canonical_name;
    if(name in AllPlaylists && AllPlaylists[name]) {
        var pl = AllPlaylists[name];
        if(!pl.dead)
            pl.die();
    }
    this.items = new ULList();
    this.current = null;
    this.next_uid = 0;
    this._leadInterval = false;
    this._lastUpdate = 0;
    this._counter = 0;
    this.leading = true;
    this.callbacks = {
        "changeMedia": [],
        "mediaUpdate": [],
        "remove": [],
    };
    this.fnqueue = new AsyncQueue();
    AllPlaylists[name] = this;

    this.channel = chan;
    this.server = chan.server;
    var pl = this;
    this.on("mediaUpdate", function(m) {
        if (chan.dead) {
            pl.die();
            return;
        }
        chan.sendAll("mediaUpdate", m.timeupdate());
    });
    this.on("changeMedia", function(m) {
        if (chan.dead) {
            pl.die();
            return;
        }
        chan.onVideoChange();
        chan.sendAll("setCurrent", pl.current.uid);
        chan.sendAll("changeMedia", m.fullupdate());
    });
    this.on("remove", function(item) {
        if (chan.dead) {
            pl.die();
            return;
        }
        chan.broadcastPlaylistMeta();
        chan.sendAll("delete", {
            uid: item.uid
        });
    });
}

Playlist.prototype.dump = function() {
    var arr = this.items.toArray();
    var pos = 0;
    for(var i in arr) {
        if(this.current && arr[i].uid == this.current.uid) {
            pos = i;
            break;
        }
    }

    var time = 0;
    if(this.current)
        time = this.current.media.currentTime;

    return {
        pl: arr,
        pos: pos,
        time: time
    };
}

Playlist.prototype.die = function () {
    this.clear();
    if(this._leadInterval) {
        clearInterval(this._leadInterval);
        this._leadInterval = false;
    }
    if(this._qaInterval) {
        clearInterval(this._qaInterval);
        this._qaInterval = false;
    }
    //for(var key in this)
    //    delete this[key];
    this.dead = true;
}

Playlist.prototype.load = function(data, callback) {
    this.clear();
    for(var i in data.pl) {
        var e = data.pl[i].media;
        var m = new Media(e.id, e.title, e.seconds, e.type);
        m.object = e.object;
        m.params = e.params;
        var it = this.makeItem(m);
        it.temp = data.pl[i].temp;
        it.queueby = data.pl[i].queueby;
        this.items.append(it);
        if(i == parseInt(data.pos)) {
            this.current = it;
        }
    }

    if(callback)
        callback();
}

Playlist.prototype.on = function(ev, fn) {
    if(typeof fn === "undefined") {
        var pl = this;
        return function() {
            for(var i = 0; i < pl.callbacks[ev].length; i++) {
                pl.callbacks[ev][i].apply(this, arguments);
            }
        }
    }
    else if(typeof fn === "function") {
        this.callbacks[ev].push(fn);
    }
}

Playlist.prototype.makeItem = function(media) {
    return new PlaylistItem(media, this.next_uid++);
}

Playlist.prototype.add = function(item, pos) {
    var self = this;
    if(this.items.length >= 4000) {
        return "Playlist limit reached (4,000)";
    }

    var it = this.items.findVideoId(item.media.id);
    if(it) {
        if(pos === "append" || it == this.current) {
            return "This item is already on the playlist";
        }

        self.remove(it.uid);
        self.channel.sendAll("delete", {
            uid: it.uid
        });
        self.channel.broadcastPlaylistMeta();
    }

    if(pos == "append") {
        if(!this.items.append(item)) {
            return "Playlist failure";
        }
    } else if(pos == "prepend") {
        if(!this.items.prepend(item)) {
            return "Playlist failure";
        }
    } else {
        if(!this.items.insertAfter(item, pos)) {
            return "Playlist failure";
        }
    }

    if(this.items.length == 1) {
        this.current = item;
        this.startPlayback();
    }

    return false;
}

Playlist.prototype.addMedia = function (data) {
    var pos = data.pos;
    if (pos === "next") {
        if (this.current !== null)
            pos = this.current.uid;
        else
            pos = "append";
    }

    var m = new Media(data.id, data.title, data.seconds, data.type);
    m.object = data.object;
    m.params = data.params;
    m.direct = data.direct;
    var item = this.makeItem(m);
    item.queueby = data.queueby;
    item.temp = data.temp;
    return {
        item: item,
        error: this.add(item, pos)
    };
};

Playlist.prototype.remove = function (uid) {
    var self = this;
    var item = self.items.find(uid);
    if (item && self.items.remove(uid)) {
        if (item === self.current) {
            self._next();
        }
        return true;
    } else {
        return false;
    }
}

Playlist.prototype.move = function (from, after) {
    var it = this.items.find(from);
    if (!this.items.remove(from))
        return false;

    if (after === "prepend") {
        if (!this.items.prepend(it))
            return false;
    } else if (after === "append") {
        if (!this.items.append(it))
            return false;
    } else if (!this.items.insertAfter(it, after)) {
        return false;
    }

    return true;
}

Playlist.prototype.next = function() {
    if(!this.current)
        return;

    var it = this.current;
    it.media.reset();

    if (it.temp) {
        if (this.remove(it.uid)) {
            this.on("remove")(it);
        }
    } else {
        this._next();
    }

    return this.current;
}

Playlist.prototype._next = function() {
    if(!this.current)
        return;
    this.current = this.current.next;
    if(this.current === null && this.items.first !== null)
        this.current = this.items.first;

    if(this.current) {
        this.startPlayback();
    }
}

Playlist.prototype.jump = function(uid) {
    if(!this.current)
        return false;

    var jmp = this.items.find(uid);
    if(!jmp)
        return false;

    var it = this.current;
    it.media.reset();

    this.current = jmp;

    if(this.current) {
        this.startPlayback();
    }

    if(it.temp) {
        if (this.remove(it.uid)) {
            this.on("remove")(it);
        }
    }

    return this.current;
}

Playlist.prototype.clear = function() {
    this.items.clear();
    this.next_uid = 0;
    this.current = null;
    clearInterval(this._leadInterval);
}

Playlist.prototype.count = function (id) {
    var count = 0;
    this.items.forEach(function (i) {
        if(i.media.id === id)
            count++;
    });
    return count;
}

Playlist.prototype.lead = function(lead) {
    this.leading = lead;
    var pl = this;
    if(!this.leading && this._leadInterval) {
        clearInterval(this._leadInterval);
        this._leadInterval = false;
    }
    else if(this.leading && !this._leadInterval) {
        this._lastUpdate = Date.now();
        this._leadInterval = setInterval(function() {
            pl._leadLoop();
        }, 1000);
    }
}

Playlist.prototype.startPlayback = function (time) {
    var self = this;
    if (!self.current || !self.current.media) {
        return false;
    }

    if (self.current.media.type === "vi" &&
        !self.current.media.direct &&
        Server.getServer().cfg["vimeo-workaround"]) {
        VimeoIsADoucheCopter(self.current.media.id, function (direct) {
            self.current.media.direct = direct;
            self.startPlayback(time);
        });
        return;
    }

    if (!self.leading) {
        self.current.media.paused = false;
        self.current.media.currentTime = time || 0;
        self.on("changeMedia")(self.current.media);
        return;
    }

    time = time || -3;
    self.current.media.paused = time < 0;
    self.current.media.currentTime = time;

    if(self._leadInterval) {
        clearInterval(self._leadInterval);
        self._leadInterval = false;
    }
    self.on("changeMedia")(self.current.media);
    if(!isLive(self.current.media.type)) {
        self._lastUpdate = Date.now();
        self._leadInterval = setInterval(function() {
            self._leadLoop();
        }, 1000);
    }
}

function isLive(type) {
    return type == "li" // Livestream.com
        || type == "tw" // Twitch.tv
        || type == "jt" // Justin.tv
        || type == "rt" // RTMP
        || type == "jw" // JWPlayer
        || type == "us" // Ustream.tv
        || type == "im" // Imgur album
        || type == "cu";// Custom embed
}

const UPDATE_INTERVAL = 5;

Playlist.prototype._leadLoop = function() {
    if(this.current == null)
        return;

    if(this.channel.name == "") {
        this.die();
        return;
    }

    var dt = (Date.now() - this._lastUpdate) / 1000.0;
    var t = this.current.media.currentTime;

    // Transition from lead-in
    if (t < 0 && (t + dt) >= 0) {
        this.current.media.currentTime = 0;
        this.current.media.paused = false;
        this._counter = 0;
        this._lastUpdate = Date.now();
        this.on("mediaUpdate")(this.current.media);
        return;
    }

    this.current.media.currentTime += dt;
    this._lastUpdate = Date.now();
    this._counter++;

    if(this.current.media.currentTime >= this.current.media.seconds + 2) {
        this.next();
    }
    else if(this._counter % UPDATE_INTERVAL == 0) {
        this.on("mediaUpdate")(this.current.media);
    }
}

/*
    Delete items from the playlist for which filter(item) returns
    a truthy value

    based on code contributed by http://github.com/unbibium
*/
Playlist.prototype.clean = function (filter) {
    var self = this;
    var matches = self.items.findAll(filter);
    var count = 0;
    var deleteNext = function () {
        if (count < matches.length) {
            var uid = matches[count].uid;
            count++;
            if (self.remove(uid)) {
                self.channel.sendAll("delete", {
                    uid: uid
                });
            }
            deleteNext();
        } else {
            // refresh meta only once, at the end
            self.channel.broadcastPlaylistMeta();
        }
    };
    // start initial callback
    deleteNext();
};

module.exports = Playlist;
<commit_msg>Fix race condition<commit_after>/*
The MIT License (MIT)
Copyright (c) 2013 Calvin Montgomery

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

ULList = require("./ullist").ULList;
var AsyncQueue = require("./asyncqueue");
var Media = require("./media").Media;
var AllPlaylists = {};
var Server = require("./server");
var VimeoIsADoucheCopter = require("./get-info").VimeoIsADoucheCopter;

function PlaylistItem(media, uid) {
    this.media = media;
    this.uid = uid;
    this.temp = false;
    this.queueby = "";
    this.prev = null;
    this.next = null;
}

PlaylistItem.prototype.pack = function() {
    return {
        media: this.media.pack(),
        uid: this.uid,
        temp: this.temp,
        queueby: this.queueby
    };
}

function Playlist(chan) {
    var name = chan.canonical_name;
    if(name in AllPlaylists && AllPlaylists[name]) {
        var pl = AllPlaylists[name];
        if(!pl.dead)
            pl.die();
    }
    this.items = new ULList();
    this.current = null;
    this.next_uid = 0;
    this._leadInterval = false;
    this._lastUpdate = 0;
    this._counter = 0;
    this.leading = true;
    this.callbacks = {
        "changeMedia": [],
        "mediaUpdate": [],
        "remove": [],
    };
    this.fnqueue = new AsyncQueue();
    AllPlaylists[name] = this;

    this.channel = chan;
    this.server = chan.server;
    var pl = this;
    this.on("mediaUpdate", function(m) {
        if (chan.dead) {
            pl.die();
            return;
        }
        chan.sendAll("mediaUpdate", m.timeupdate());
    });
    this.on("changeMedia", function(m) {
        if (chan.dead) {
            pl.die();
            return;
        }
        chan.onVideoChange();
        chan.sendAll("setCurrent", pl.current.uid);
        chan.sendAll("changeMedia", m.fullupdate());
    });
    this.on("remove", function(item) {
        if (chan.dead) {
            pl.die();
            return;
        }
        chan.broadcastPlaylistMeta();
        chan.sendAll("delete", {
            uid: item.uid
        });
    });
}

Playlist.prototype.dump = function() {
    var arr = this.items.toArray();
    var pos = 0;
    for(var i in arr) {
        if(this.current && arr[i].uid == this.current.uid) {
            pos = i;
            break;
        }
    }

    var time = 0;
    if(this.current)
        time = this.current.media.currentTime;

    return {
        pl: arr,
        pos: pos,
        time: time
    };
}

Playlist.prototype.die = function () {
    this.clear();
    if(this._leadInterval) {
        clearInterval(this._leadInterval);
        this._leadInterval = false;
    }
    if(this._qaInterval) {
        clearInterval(this._qaInterval);
        this._qaInterval = false;
    }
    //for(var key in this)
    //    delete this[key];
    this.dead = true;
}

Playlist.prototype.load = function(data, callback) {
    this.clear();
    for(var i in data.pl) {
        var e = data.pl[i].media;
        var m = new Media(e.id, e.title, e.seconds, e.type);
        m.object = e.object;
        m.params = e.params;
        var it = this.makeItem(m);
        it.temp = data.pl[i].temp;
        it.queueby = data.pl[i].queueby;
        this.items.append(it);
        if(i == parseInt(data.pos)) {
            this.current = it;
        }
    }

    if(callback)
        callback();
}

Playlist.prototype.on = function(ev, fn) {
    if(typeof fn === "undefined") {
        var pl = this;
        return function() {
            for(var i = 0; i < pl.callbacks[ev].length; i++) {
                pl.callbacks[ev][i].apply(this, arguments);
            }
        }
    }
    else if(typeof fn === "function") {
        this.callbacks[ev].push(fn);
    }
}

Playlist.prototype.makeItem = function(media) {
    return new PlaylistItem(media, this.next_uid++);
}

Playlist.prototype.add = function(item, pos) {
    var self = this;
    if(this.items.length >= 4000) {
        return "Playlist limit reached (4,000)";
    }

    var it = this.items.findVideoId(item.media.id);
    if(it) {
        if(pos === "append" || it == this.current) {
            return "This item is already on the playlist";
        }

        self.remove(it.uid);
        self.channel.sendAll("delete", {
            uid: it.uid
        });
        self.channel.broadcastPlaylistMeta();
    }

    if(pos == "append") {
        if(!this.items.append(item)) {
            return "Playlist failure";
        }
    } else if(pos == "prepend") {
        if(!this.items.prepend(item)) {
            return "Playlist failure";
        }
    } else {
        if(!this.items.insertAfter(item, pos)) {
            return "Playlist failure";
        }
    }

    if(this.items.length == 1) {
        this.current = item;
        this.startPlayback();
    }

    return false;
}

Playlist.prototype.addMedia = function (data) {
    var pos = data.pos;
    if (pos === "next") {
        if (this.current !== null)
            pos = this.current.uid;
        else
            pos = "append";
    }

    var m = new Media(data.id, data.title, data.seconds, data.type);
    m.object = data.object;
    m.params = data.params;
    m.direct = data.direct;
    var item = this.makeItem(m);
    item.queueby = data.queueby;
    item.temp = data.temp;
    return {
        item: item,
        error: this.add(item, pos)
    };
};

Playlist.prototype.remove = function (uid) {
    var self = this;
    var item = self.items.find(uid);
    if (item && self.items.remove(uid)) {
        if (item === self.current) {
            self._next();
        }
        return true;
    } else {
        return false;
    }
}

Playlist.prototype.move = function (from, after) {
    var it = this.items.find(from);
    if (!this.items.remove(from))
        return false;

    if (after === "prepend") {
        if (!this.items.prepend(it))
            return false;
    } else if (after === "append") {
        if (!this.items.append(it))
            return false;
    } else if (!this.items.insertAfter(it, after)) {
        return false;
    }

    return true;
}

Playlist.prototype.next = function() {
    if(!this.current)
        return;

    var it = this.current;
    it.media.reset();

    if (it.temp) {
        if (this.remove(it.uid)) {
            this.on("remove")(it);
        }
    } else {
        this._next();
    }

    return this.current;
}

Playlist.prototype._next = function() {
    if(!this.current)
        return;
    this.current = this.current.next;
    if(this.current === null && this.items.first !== null)
        this.current = this.items.first;

    if(this.current) {
        this.startPlayback();
    }
}

Playlist.prototype.jump = function(uid) {
    if(!this.current)
        return false;

    var jmp = this.items.find(uid);
    if(!jmp)
        return false;

    var it = this.current;
    it.media.reset();

    this.current = jmp;

    if(this.current) {
        this.startPlayback();
    }

    if(it.temp) {
        if (this.remove(it.uid)) {
            this.on("remove")(it);
        }
    }

    return this.current;
}

Playlist.prototype.clear = function() {
    this.items.clear();
    this.next_uid = 0;
    this.current = null;
    clearInterval(this._leadInterval);
}

Playlist.prototype.count = function (id) {
    var count = 0;
    this.items.forEach(function (i) {
        if(i.media.id === id)
            count++;
    });
    return count;
}

Playlist.prototype.lead = function(lead) {
    this.leading = lead;
    var pl = this;
    if(!this.leading && this._leadInterval) {
        clearInterval(this._leadInterval);
        this._leadInterval = false;
    }
    else if(this.leading && !this._leadInterval) {
        this._lastUpdate = Date.now();
        this._leadInterval = setInterval(function() {
            pl._leadLoop();
        }, 1000);
    }
}

Playlist.prototype.startPlayback = function (time) {
    var self = this;
    if (!self.current || !self.current.media) {
        return false;
    }

    if (self.current.media.type === "vi" &&
        !self.current.media.direct &&
        Server.getServer().cfg["vimeo-workaround"]) {
        VimeoIsADoucheCopter(self.current.media.id, function (direct) {
            if (self.current != null && self.current.media != null) {
                self.current.media.direct = direct;
                self.startPlayback(time);
            }
        });
        return;
    }

    if (!self.leading) {
        self.current.media.paused = false;
        self.current.media.currentTime = time || 0;
        self.on("changeMedia")(self.current.media);
        return;
    }

    time = time || -3;
    self.current.media.paused = time < 0;
    self.current.media.currentTime = time;

    if(self._leadInterval) {
        clearInterval(self._leadInterval);
        self._leadInterval = false;
    }
    self.on("changeMedia")(self.current.media);
    if(!isLive(self.current.media.type)) {
        self._lastUpdate = Date.now();
        self._leadInterval = setInterval(function() {
            self._leadLoop();
        }, 1000);
    }
}

function isLive(type) {
    return type == "li" // Livestream.com
        || type == "tw" // Twitch.tv
        || type == "jt" // Justin.tv
        || type == "rt" // RTMP
        || type == "jw" // JWPlayer
        || type == "us" // Ustream.tv
        || type == "im" // Imgur album
        || type == "cu";// Custom embed
}

const UPDATE_INTERVAL = 5;

Playlist.prototype._leadLoop = function() {
    if(this.current == null)
        return;

    if(this.channel.name == "") {
        this.die();
        return;
    }

    var dt = (Date.now() - this._lastUpdate) / 1000.0;
    var t = this.current.media.currentTime;

    // Transition from lead-in
    if (t < 0 && (t + dt) >= 0) {
        this.current.media.currentTime = 0;
        this.current.media.paused = false;
        this._counter = 0;
        this._lastUpdate = Date.now();
        this.on("mediaUpdate")(this.current.media);
        return;
    }

    this.current.media.currentTime += dt;
    this._lastUpdate = Date.now();
    this._counter++;

    if(this.current.media.currentTime >= this.current.media.seconds + 2) {
        this.next();
    }
    else if(this._counter % UPDATE_INTERVAL == 0) {
        this.on("mediaUpdate")(this.current.media);
    }
}

/*
    Delete items from the playlist for which filter(item) returns
    a truthy value

    based on code contributed by http://github.com/unbibium
*/
Playlist.prototype.clean = function (filter) {
    var self = this;
    var matches = self.items.findAll(filter);
    var count = 0;
    var deleteNext = function () {
        if (count < matches.length) {
            var uid = matches[count].uid;
            count++;
            if (self.remove(uid)) {
                self.channel.sendAll("delete", {
                    uid: uid
                });
            }
            deleteNext();
        } else {
            // refresh meta only once, at the end
            self.channel.broadcastPlaylistMeta();
        }
    };
    // start initial callback
    deleteNext();
};

module.exports = Playlist;
<|endoftext|>


<commit_before>/**
 * @namespace Producer
 */
var amqp = require('amqplib'),
  utils = require('./helpers/utils'),
  uuid = require('node-uuid'),
  parsers = require('./helpers/message-parsers');

var config;
var connected = false;
var connecting = false;
var reqQueue = [];
var productions = [];
var amqpUrl, amqpConnection, amqpChannel, amqpIntervalId;
var reconnection = false;

/**
 * Create tcp coonection between producer and rabbitmq server
 * @memberOf Producer
 * @param  {String} _amqpUrl - amqp url used to connect to rabbitmq server
 * @return {Promise} - channel
 */
var connect = function(_amqpUrl) {
  if (connected) {
    return Promise.resolve(amqpChannel);
  }

  if (connecting) {
    var deferred = new Promise(function(resolve) { resolve(amqpChannel); });
    reqQueue.push(deferred);
    return deferred;
  }

  connecting = true;

  amqpUrl = utils.getValidUrl([amqpUrl, _amqpUrl, config.amqpUrl, process.env.AMQP_URL, 'amqp://localhost']);

  return amqp.connect(amqpUrl)
  .then(function (_connection) {
    amqpConnection = _connection;

    amqpIntervalId = clearInterval(amqpIntervalId);

    amqpConnection.on('close', reconnect);
    amqpConnection.on('error', reconnect);

    return createChannel();
  })
  .catch(catchError);
};

/**
 * Create channel
 * @memberOf Producer
 * @return {Promise} - channel
 */
var createChannel = function() {
  return amqpConnection.createChannel()
  .then(function (_amqpChannel) {
    Logger.info('[BMQ-PRODUCER] is now connected and ready to produce messages');

    amqpChannel = _amqpChannel;

    connected = true;
    connecting = false;

    amqpIntervalId = clearInterval(amqpIntervalId);

    amqpChannel.on('close', reconnect);
    amqpChannel.on('error', reconnect);

    while (reqQueue.length > 0) {
      Promise.resolve(reqQueue.shift());
    }

    while (productions.length > 0) {
      var prod = productions.shift();
      produce(prod.queue, prod.msg, prod.options);
    }

    return amqpChannel;
  })
  .catch(catchError);
};

/**
 * Reconnect after a timeout
 * @memberOf Producer
 * @return {Nothing}
 */
var reconnect  = function() {
  if (!amqpIntervalId) {
    Logger.info('[BMQ-PRODUCER] Try to reconnect');
    connecting = false;
    connected = false;
    reconnection = true;
    amqpIntervalId = setInterval(connect, 1000);
  }
};

/**
 * Disconnect from server
 * @memberOf Producer
 * @return {Promise}
 */
var disconnect = function() {
  if (amqpConnection && amqpChannel) {
    return amqpChannel.close()
    .then(function () {
      return amqpConnection.close();
    })
    .then(function () {
      connecting = false;
      connected = false;
      amqpConnection = undefined;
      amqpChannel = undefined;
      rpcQueues = {};
      amqpIntervalId = clearInterval(amqpIntervalId);
      Logger.info('[BMQ-PRODUCER] is now disconnected');
    });
  }
};

var rpcQueues = {};

function catchError(err) {
  amqpIntervalId = clearInterval(amqpIntervalId);
  Logger.error('[BMQ-PRODUCER] ', err.stack, '\n    occured while connecting');
  amqpChannel = undefined;
  amqpConnection = undefined;
  connecting = false;
  connected = false;
  reconnect();
}

function createRpcQueue(queue) {
  if (rpcQueues[queue].queue && !reconnection) return Promise.resolve();

  var resQueue = queue + ':' + process.env.HOSTNAME + ':res';
  return amqpChannel.assertQueue(resQueue, { durable: true })
  .then(function (qok) { return qok.queue; })
  .then(function (_queue) {
    rpcQueues[queue].queue = _queue;
    return amqpChannel.consume(_queue, maybeAnswer(queue), { noAck: true });
  })
  .then(function() { return queue; });
}

function maybeAnswer(queue) {
  return function (msg) {
    var corrIdA = msg.properties.correlationId;
    if (rpcQueues[queue][corrIdA] !== undefined) {
      msg = parsers.in(msg);
      rpcQueues[queue][corrIdA].resolve(msg);
      Logger.info('[BMQ-PRODUCER][' + queue + '] < ', msg);
      delete rpcQueues[queue][corrIdA];
    }
  };
}

function checkRpc(queue, msg, options) {
  options.persistent = true;

  if (options.rpc) {
    if (!rpcQueues[queue]) {
      rpcQueues[queue] = {};
    }

    if (!amqpChannel || !amqpConnection) return;

    return createRpcQueue(queue)
    .then(function(){
      var corrId = uuid.v4();
      options.correlationId = corrId;
      options.replyTo = rpcQueues[queue].queue;

      amqpChannel.sendToQueue(queue, msg, options);

      rpcQueues[queue][corrId] = Promise.defer();
      return rpcQueues[queue][corrId].promise;
    });
  }

  return amqpChannel.sendToQueue(queue, msg, options);
}

/**
 * Send message to queue
 * @memberOf Producer
 * @param {String} _queue - queue name
 * @param {String} _msg - message to send
 * @param {String} _options - options
 * @return {Promise} queue
 */
var produce = function(_queue, _msg, _options) {
  if (!connected) {
    utils.pushIfNotExist('producer', productions, {
      queue: _queue,
      options: _options,
      msg: _msg
    });
  }

  if (!_msg) return;

  _options = _options || { persistent: true, durable: true };

  Logger.info('[BMQ-PRODUCER][' + _queue + '] > ', _msg);

  _msg = parsers.out(_msg, _options);

  return connect().then(function() {
    return checkRpc(_queue, _msg, _options);
  });
};

module.exports = function (_config) {
  config = _config;

  return {
    connect: connect,
    disconnect: disconnect,
    produce: produce
  };
};
<commit_msg>Rollback unique queue name<commit_after>/**
 * @namespace Producer
 */
var amqp = require('amqplib'),
  utils = require('./helpers/utils'),
  uuid = require('node-uuid'),
  parsers = require('./helpers/message-parsers');

var config;
var connected = false;
var connecting = false;
var reqQueue = [];
var productions = [];
var amqpUrl, amqpConnection, amqpChannel, amqpIntervalId;
var reconnection = false;

/**
 * Create tcp coonection between producer and rabbitmq server
 * @memberOf Producer
 * @param  {String} _amqpUrl - amqp url used to connect to rabbitmq server
 * @return {Promise} - channel
 */
var connect = function(_amqpUrl) {
  if (connected) {
    return Promise.resolve(amqpChannel);
  }

  if (connecting) {
    var deferred = new Promise(function(resolve) { resolve(amqpChannel); });
    reqQueue.push(deferred);
    return deferred;
  }

  connecting = true;

  amqpUrl = utils.getValidUrl([amqpUrl, _amqpUrl, config.amqpUrl, process.env.AMQP_URL, 'amqp://localhost']);

  return amqp.connect(amqpUrl)
  .then(function (_connection) {
    amqpConnection = _connection;

    amqpIntervalId = clearInterval(amqpIntervalId);

    amqpConnection.on('close', reconnect);
    amqpConnection.on('error', reconnect);

    return createChannel();
  })
  .catch(catchError);
};

/**
 * Create channel
 * @memberOf Producer
 * @return {Promise} - channel
 */
var createChannel = function() {
  return amqpConnection.createChannel()
  .then(function (_amqpChannel) {
    Logger.info('[BMQ-PRODUCER] is now connected and ready to produce messages');

    amqpChannel = _amqpChannel;

    connected = true;
    connecting = false;

    amqpIntervalId = clearInterval(amqpIntervalId);

    amqpChannel.on('close', reconnect);
    amqpChannel.on('error', reconnect);

    while (reqQueue.length > 0) {
      Promise.resolve(reqQueue.shift());
    }

    while (productions.length > 0) {
      var prod = productions.shift();
      produce(prod.queue, prod.msg, prod.options);
    }

    return amqpChannel;
  })
  .catch(catchError);
};

/**
 * Reconnect after a timeout
 * @memberOf Producer
 * @return {Nothing}
 */
var reconnect  = function() {
  if (!amqpIntervalId) {
    Logger.info('[BMQ-PRODUCER] Try to reconnect');
    connecting = false;
    connected = false;
    reconnection = true;
    amqpIntervalId = setInterval(connect, 1000);
  }
};

/**
 * Disconnect from server
 * @memberOf Producer
 * @return {Promise}
 */
var disconnect = function() {
  if (amqpConnection && amqpChannel) {
    return amqpChannel.close()
    .then(function () {
      return amqpConnection.close();
    })
    .then(function () {
      connecting = false;
      connected = false;
      amqpConnection = undefined;
      amqpChannel = undefined;
      rpcQueues = {};
      amqpIntervalId = clearInterval(amqpIntervalId);
      Logger.info('[BMQ-PRODUCER] is now disconnected');
    });
  }
};

var rpcQueues = {};

function catchError(err) {
  amqpIntervalId = clearInterval(amqpIntervalId);
  Logger.error('[BMQ-PRODUCER] ', err.stack, '\n    occured while connecting');
  amqpChannel = undefined;
  amqpConnection = undefined;
  connecting = false;
  connected = false;
  reconnect();
}

function createRpcQueue(queue) {
  if (rpcQueues[queue].queue && !reconnection) return Promise.resolve();

  return amqpChannel.assertQueue('', { exclusive: true })
  .then(function (qok) { return qok.queue; })
  .then(function (_queue) {
    rpcQueues[queue].queue = _queue;
    return amqpChannel.consume(_queue, maybeAnswer(queue), { noAck: true });
  })
  .then(function() { return queue; });
}

function maybeAnswer(queue) {
  return function (msg) {
    var corrIdA = msg.properties.correlationId;
    if (rpcQueues[queue][corrIdA] !== undefined) {
      msg = parsers.in(msg);
      rpcQueues[queue][corrIdA].resolve(msg);
      Logger.info('[BMQ-PRODUCER][' + queue + '] < ', msg);
      delete rpcQueues[queue][corrIdA];
    }
  };
}

function checkRpc(queue, msg, options) {
  options.persistent = true;

  if (options.rpc) {
    if (!rpcQueues[queue]) {
      rpcQueues[queue] = {};
    }

    if (!amqpChannel || !amqpConnection) return;

    return createRpcQueue(queue)
    .then(function(){
      var corrId = uuid.v4();
      options.correlationId = corrId;
      options.replyTo = rpcQueues[queue].queue;

      amqpChannel.sendToQueue(queue, msg, options);

      rpcQueues[queue][corrId] = Promise.defer();
      return rpcQueues[queue][corrId].promise;
    });
  }

  return amqpChannel.sendToQueue(queue, msg, options);
}

/**
 * Send message to queue
 * @memberOf Producer
 * @param {String} _queue - queue name
 * @param {String} _msg - message to send
 * @param {String} _options - options
 * @return {Promise} queue
 */
var produce = function(_queue, _msg, _options) {
  if (!connected) {
    utils.pushIfNotExist('producer', productions, {
      queue: _queue,
      options: _options,
      msg: _msg
    });
  }

  if (!_msg) return;

  _options = _options || { persistent: true, durable: true };

  Logger.info('[BMQ-PRODUCER][' + _queue + '] > ', _msg);

  _msg = parsers.out(_msg, _options);

  return connect().then(function() {
    return checkRpc(_queue, _msg, _options);
  });
};

module.exports = function (_config) {
  config = _config;

  return {
    connect: connect,
    disconnect: disconnect,
    produce: produce
  };
};
<|endoftext|>


<commit_before>'use babel';

import {filter} from 'fuzzaldrin';
import commands from './commands';
import variables from './variables';

export const selector = '.source.cmake';
export const disableForSelector = '.source.cmake .comment';
export const inclusionPriority = 1;

function existy(value) {
    return value != null;
}

function dispatch() {
    var funs = arguments;
    return function() {
        for (var f of funs) {
            var ret = f.apply(null, arguments);
            if (existy(ret)) {
                return ret;
            }
        }
    };
}

function variables_suggestions(prefix) {
    return filter(variables, prefix.toUpperCase()).map((variable) => ({
        text: variable,
        displayText: variable,
        type: 'variable'
    }));
}

function  commands_suggestions(prefix) {
    return filter(commands, prefix.toLowerCase()).map((command) => ({
        text: `${command}()`,
        displayText: command,
        type: 'function'
    }));
}

const suggest = dispatch(
    (prefix, scope_descriptor) => {
        if (scope_descriptor.scopes.length > 1) {
            return variables_suggestions(prefix);
        }
    },
    (prefix) => commands_suggestions(prefix)
)

export function getSuggestions({prefix, scopeDescriptor: scope_descriptor}) {
    console.log(scope_descriptor);
    return suggest(prefix, scope_descriptor);
}
<commit_msg>Update 'provider.js'<commit_after>'use babel';

import {filter} from 'fuzzaldrin';
import commands from './commands';
import variables from './variables';

export const selector = '.source.cmake';
export const disableForSelector = '.source.cmake .comment';
export const inclusionPriority = 1;

function existy(value) {
    return value != null;
}

function dispatch() {
    var funs = arguments;
    return function() {
        for (var f of funs) {
            var ret = f.apply(null, arguments);
            if (existy(ret)) {
                return ret;
            }
        }
    };
}

function variables_suggestions(prefix) {
    return filter(variables, prefix.toUpperCase()).map((variable) => ({
        text: variable,
        displayText: variable,
        type: 'variable'
    }));
}

function  commands_suggestions(prefix) {
    return filter(commands, prefix.toLowerCase()).map((command) => ({
        text: `${command}()`,
        displayText: command,
        type: 'function'
    }));
}

const suggest = dispatch(
    (prefix, scopes) => {
        if (scopes.length > 1) {
            return variables_suggestions(prefix);
        }
    },
    (prefix) => commands_suggestions(prefix)
)

export function getSuggestions({editor, bufferPosition, prefix, scopeDescriptor: scope_descriptor}) {
    console.log(editor);
    console.log(bufferPosition);
    console.log(scope_descriptor);
    return suggest(prefix, scope_descriptor.scopes);
}
<|endoftext|>