<commit_before>/**
 * attr dico
 *      partials="html::.... || swig::....  || views::myView || ..."
 *
 *      edit-on-click="true"
 *
 *
 *      data-bind="mp3::id/my/path"
 *
 *      required, minLength, maxLength, .. or any json-schema related stuffs
 *
 *
my custom message

 *
 *
 */
"use strict";
if (typeof define !== 'function') {
	var define = require('amdefine')(module);
}
define(["require", "../deep"], function(require, deep) {

	jQuery.fn.outerHTML = function(s) {
	    return s
	        ? this.before(s).remove()
	        : jQuery("
").append(this.eq(0).clone()).html();
	};

	deep.ui.View = deep.compose.Classes(function(layer) {
		deep.utils.up(layer, this);
	}, {
		//what:"this::!",
		_deep_view_: true,
		how: function(what, routeParams) {
			return this.toString();
		},
		//where:"dom.appendTo::#ng-view",
		done: function(success) {
			// success == { what:.., rendered:"...", placed:jQuery }
			// should seek after particular deep.ui html attributs and tag to interpret as 'partials' or 'data-bind')...
		},
		fail: function(e) {
			console.error("error while rendering : ", e);
		},
		load: function(params) {
			// console.log("LOAD VIEW")
			var self = this;
			if (!this.how || this.condition === false)
				return null;
			if (this.condition)
				if (typeof this.condition === "function" && !this.condition.apply(params))
					return null;

			var promises = [];
			if(this.what)
				promises.push(deep(this).query("./what").load(params, false));
			else
				promises.push(null);

			if(typeof this.how === 'string')
				promises.push(deep(this).query("./how").load(params, false));
			else
				promises.push(this.how);

			if(this.where)
				if(typeof this.where === 'string')
					promises.push(deep(this).query("./where").load(params, false));
				else
					promises.push(this.where);

			// console.log("launch deep load");
			return deep.all(promises)
				.done(function(res) {
					//console.log("view deep load : res  : ", res);
					var res = {
						_deep_render_node_:true,
						what:res[0] || self,
						how:res[1],
						where:res[2],
						params:params,
						controller:self
					}
					//console.log("view deep load done : ", res);
					return res;
				});
		},
		refresh: function(params, loaded) {
			// console.log("view refresh : params : ", params, " - loaded : ", loaded);
			var self = this;
			params = params || this.params;
			if (params && !deep.isNode)
				this.params = params;
			var render = function(loaded) {
				// console.log("view render : ", loaded)
				if (!loaded)
					return;
				var what = loaded.controller, how=null, where=null,rendered = null,placed = null;
				if(loaded.what)
					what = loaded.what;
				if(loaded.how)
					how = loaded.how;
				if(loaded.where)
					where = loaded.where;
				what = (what && what._deep_query_node_) ? what.value : what;
				how = (how && how._deep_query_node_) ? how.value : how;
				where = (where && where._deep_query_node_) ? where.value : where;
				placed = self.placed ? self.placed() : null;

				loaded.placed =  placed;
				// console.log("render with : how : ", how, what)
				if(!how)
					return loaded;
				try {
					what.dp = {
						params:params,
						getRoute:self.getRoute
					};
					if(typeof how === 'function')
						rendered = loaded.rendered = how.call(self, what);
					else
						rendered = loaded.rendered = how;
					if (where)
						placed = loaded.placed = where.call(self, loaded.rendered, loaded.placed);
					else
						placed = loaded.placed = null;
				} catch (e) {
					// console.log("error while rendering")
					if (typeof self.fail === 'function')
						return self.fail(e) || e;
					return e;
				}

				if (placed && !deep.isNode)
					self.placed = function() {
						return placed;
					};

				var promises = [];
				if (placed)
				{
					//console.log("View placed");
					for(var i in deep.ui.View.htmlEnhancers)
					{
						//console.log("run enhancer :", i);
						var enhancer = deep.ui.View.htmlEnhancers[i];
						promises.push(enhancer.call(self,loaded));
					}
				}
				// console.log("rendered : ", loaded);
				if(promises.length > 0)
					return deep.all(promises)
					.done(function(){
						if (typeof self.done === "function")
							return self.done(loaded) || loaded;
						return loaded;
					});
				if (typeof self.done === "function")
					return self.done(loaded) || loaded;
				return loaded;
			};
			if (loaded)
				return render(loaded);
			return deep.when(this.load(params))
			.done(render)
			.fail(function(e){
				if (typeof self.fail === 'function')
					return self.fail(e) || e;
			});
		},
		toString: function(pretty) {
			return "default view render.";
		}
	});

	deep.View = function (layer) {
		return new deep.ui.View(layer);
	};

	deep.Chain.addHandle("refresh", function()
	{
		var args= arguments;
		var self = this;
		var func = function(s,e)
		{
			var alls = [];
			deep.chain.each(self, function (v) {
				if(typeof v.refresh === "function")
					alls.push(v.refresh.apply(v,args));
				else
					alls.push(v);
			});
			return deep.all(alls)
			.done(function(alls){
				if(!self._queried)
					return alls.shift();
				return alls;
			});
		};
		func._isDone_ = true;
		deep.chain.addInChain.call(self,func);
		return this;
	});

	deep.ui.View.htmlEnhancers = {
		partials:function(success){
			//console.log("PARTIALS : descriptor = ", success);
			var promises = [];
			success.placed
			.find("div[partials]") //

			.each(function() {
				//console.log("inside a partial tag :", $(this));
				var node = $(this);
				promises.push(deep.get(node.attr("partials"))
				.done(function(partials) {
					if (typeof partials === 'function')
						node.html(partials());
					node.html(partials);
				}));
			});
			return deep.all(promises);
		},
		"dprepeat":function(success){
			//console.log("DP-REPEAT : descriptor = ", success);
			var promises = [];
			success.placed
			.find("div[dprepeat]") //

			.each(function() {
				//console.log("inside a repeat tag");
				var rowNode = $(this);
				var rowHtml = deep.ui.swig(rowNode.outerHTML());

				success.controller.myDatas.forEach(function (data) {
					rowNode.after(rowHtml(data));
				});
			});
		}
	};
	return deep.View;
});

<commit_msg>work on todo on view<commit_after>/**
 * attr dico
 *      partials="html::.... || swig::....  || views::myView || ..."
 *
 *      edit-on-click="true"
 *
 *
 *      data-bind="mp3::id/my/path"
 *
 *      required, minLength, maxLength, .. or any json-schema related stuffs
 *
 *
my custom message

 *
 *
 */
"use strict";
if (typeof define !== 'function') {
	var define = require('amdefine')(module);
}
define(["require", "../deep"], function(require, deep) {

/*
	TODO
    put a map in Views that says :
    destructive : {
        what:false,
        how:true,
        where:true
    }
    interpretable : {
        what:true,
        how:true,
        where:true
    }
    loadable:{
        what:"deepload::func,string",
        how:"load::string",
        where:"load::string"
    }
    ==> or similar (maybe one only map that contains both parameters)
*/
	jQuery.fn.outerHTML = function(s) {
	    return s
	        ? this.before(s).remove()
	        : jQuery("
").append(this.eq(0).clone()).html();
	};

	deep.ui.View = deep.compose.Classes(function(layer) {
		deep.utils.up(layer, this);
	}, {
		//what:"this::!",
		_deep_view_: true,
		how: function(what, routeParams) {
			return this.toString();
		},
		//where:"dom.appendTo::#ng-view",
		done: function(success) {
			// success == { what:.., rendered:"...", placed:jQuery }
			// should seek after particular deep.ui html attributs and tag to interpret as 'partials' or 'data-bind')...
		},
		fail: function(e) {
			console.error("error while rendering : ", e);
		},
		load: function(params) {
			// console.log("LOAD VIEW")
			var self = this;
			if (!this.how || this.condition === false)
				return null;
			if (this.condition)
				if (typeof this.condition === "function" && !this.condition.apply(params))
					return null;

			var promises = [];
			if(this.what)
				promises.push(deep(this).query("./what").load(params, false));
			else
				promises.push(null);

			if(typeof this.how === 'string')
				promises.push(deep(this).query("./how").load(params, false));
			else
				promises.push(this.how);

			if(this.where)
				if(typeof this.where === 'string')
					promises.push(deep(this).query("./where").load(params, false));
				else
					promises.push(this.where);

			// console.log("launch deep load");
			return deep.all(promises)
				.done(function(res) {
					//console.log("view deep load : res  : ", res);
					var res = {
						_deep_render_node_:true,
						what:res[0] || self,
						how:res[1],
						where:res[2],
						params:params,
						controller:self
					}
					//console.log("view deep load done : ", res);
					return res;
				});
		},
		refresh: function(params, loaded) {
			// console.log("view refresh : params : ", params, " - loaded : ", loaded);
			var self = this;
			params = params || this.params;
			if (params && !deep.isNode)
				this.params = params;
			var render = function(loaded) {
				// console.log("view render : ", loaded)
				if (!loaded)
					return;
				var what = loaded.controller, how=null, where=null,rendered = null,placed = null;
				if(loaded.what)
					what = loaded.what;
				if(loaded.how)
					how = loaded.how;
				if(loaded.where)
					where = loaded.where;
				what = (what && what._deep_query_node_) ? what.value : what;
				how = (how && how._deep_query_node_) ? how.value : how;
				where = (where && where._deep_query_node_) ? where.value : where;
				placed = self.placed ? self.placed() : null;

				loaded.placed =  placed;
				// console.log("render with : how : ", how, what)
				if(!how)
					return loaded;
				try {
					what.dp = {
						params:params,
						getRoute:self.getRoute
					};
					if(typeof how === 'function')
						rendered = loaded.rendered = how.call(self, what);
					else
						rendered = loaded.rendered = how;
					if (where)
						placed = loaded.placed = where.call(self, loaded.rendered, loaded.placed);
					else
						placed = loaded.placed = null;
				} catch (e) {
					// console.log("error while rendering")
					if (typeof self.fail === 'function')
						return self.fail(e) || e;
					return e;
				}

				if (placed && !deep.isNode)
					self.placed = function() {
						return placed;
					};

				var promises = [];
				if (placed)
				{
					//console.log("View placed");
					for(var i in deep.ui.View.htmlEnhancers)
					{
						//console.log("run enhancer :", i);
						var enhancer = deep.ui.View.htmlEnhancers[i];
						promises.push(enhancer.call(self,loaded));
					}
				}
				// console.log("rendered : ", loaded);
				if(promises.length > 0)
					return deep.all(promises)
					.done(function(){
						if (typeof self.done === "function")
							return self.done(loaded) || loaded;
						return loaded;
					});
				if (typeof self.done === "function")
					return self.done(loaded) || loaded;
				return loaded;
			};
			if (loaded)
				return render(loaded);
			return deep.when(this.load(params))
			.done(render)
			.fail(function(e){
				if (typeof self.fail === 'function')
					return self.fail(e) || e;
			});
		},
		toString: function(pretty) {
			return "default view render.";
		}
	});

	deep.View = function (layer) {
		return new deep.ui.View(layer);
	};

	deep.Chain.addHandle("refresh", function()
	{
		var args= arguments;
		var self = this;
		var func = function(s,e)
		{
			var alls = [];
			deep.chain.each(self, function (v) {
				if(typeof v.refresh === "function")
					alls.push(v.refresh.apply(v,args));
				else
					alls.push(v);
			});
			return deep.all(alls)
			.done(function(alls){
				if(!self._queried)
					return alls.shift();
				return alls;
			});
		};
		func._isDone_ = true;
		deep.chain.addInChain.call(self,func);
		return this;
	});

	deep.ui.View.htmlEnhancers = {
		partials:function(success){
			//console.log("PARTIALS : descriptor = ", success);
			var promises = [];
			success.placed
			.find("div[partials]") //

			.each(function() {
				//console.log("inside a partial tag :", $(this));
				var node = $(this);
				promises.push(deep.get(node.attr("partials"))
				.done(function(partials) {
					if (typeof partials === 'function')
						node.html(partials());
					node.html(partials);
				}));
			});
			return deep.all(promises);
		},
		"dprepeat":function(success){
			//console.log("DP-REPEAT : descriptor = ", success);
			var promises = [];
			success.placed
			.find("div[dprepeat]") //

			.each(function() {
				//console.log("inside a repeat tag");
				var rowNode = $(this);
				var rowHtml = deep.ui.swig(rowNode.outerHTML());

				success.controller.myDatas.forEach(function (data) {
					rowNode.after(rowHtml(data));
				});
			});
		}
	};
	return deep.View;
});

<|endoftext|>


<commit_before>(function(console){
    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'console.json'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)
window.onload = function() {
  // Check for browser support
  if(!(window.performance && window.performance.timing)) {
    return;
  }
 //console.log(console.save(performance.timing));
 //This allows us to get the excate times we are wanting, but there are issues with loadEventEnd time being set to 0.
 console.log(console.save([performance.timing.connectEnd - performance.timing.navigationStart,
 performance.timing.responseEnd - performance.timing.requestStart,
 performance.timing.domComplete - performance.timing.domLoading,
 performance.timing.loadEventEnd - performance.timing.navigationStart,
 performance.timing.responseEnd - performance.timing.fetchStart,
 performance.timing.loadEventEnd - performance.timing.responseEnd]));
};
setTimeout(function(){window.location=window.location;},5000);
<commit_msg>Update AutoTestingMRK2.js<commit_after>//The following code is from https://github.com/bgrins/devtools-snippets
(function(console){
    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'dataTime.json'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)
window.onload = function() {
  // Check for browser support
  if(!(window.performance && window.performance.timing)) {
    return;
  }
  //This function will send the performance timing to a JSON file to be downloaded.
 //console.log(console.save(performance.timing));

 //This allows us to get the excate times we are wanting, but there are issues with loadEventEnd time being set to 0.
 console.log(console.save([performance.timing.connectEnd - performance.timing.navigationStart,
 performance.timing.responseEnd - performance.timing.requestStart,
 performance.timing.domComplete - performance.timing.domLoading,
 performance.timing.loadEventEnd - performance.timing.navigationStart,
 performance.timing.responseEnd - performance.timing.fetchStart,
 performance.timing.loadEventEnd - performance.timing.responseEnd]));
};
//Allows you to set a time(in seconds) for refreshing the page.
setTimeout(function(){window.location=window.location;},5000);
<|endoftext|>


<commit_before>//<script src="https://rawgit.com/mshoote/BTJSC/master/Markup/AutoTestingMRK4.js"></script>
(function(console){
    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'pagingTime.txt'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)
window.onload = function() {
	window.setTimeout(function(){
  // Check for browser support
    if(!(window.performance && window.performance.timing)) {
    return;
  }
  console.log(console.save([
  performance.timing.loadEventEnd - performance.timing.fetchStart,
  performance.timing.fetchStart - performance.timing.navigationStart,
  performance.timing.redirectEnd - performance.timing.redirectStart,
  performance.timing.domainLookupStart - performance.timing.fetchStart,
  performance.timing.domainLookupEnd - performance.timing.domainLookupStart,
  performance.timing.connectEnd - performance.timing.connectStart,
  performance.timing.responseEnd - performance.timing.requestStart,
  performance.timing.unloadEventEnd - performance.timing.unloadEventStart,
  performance.timing.domContentLoadedEventEnd - performance.timing.domContentLoadedEventStart,
  performance.timing.domComplete - performance.timing.domInteractive,
  performance.timing.loadEventEnd - performance.timing.responseEnd,
  performance.timing.domInteractive - performance.timing.responseEnd,
  performance.timing.loadEventEnd - performance.timing.loadEventStart,
  performance.timing.domComplete - performance.timing.domLoading,
  performance.timing.domContentLoadedEventStart - performance.timing.domLoading,
  null
  ]));
  }, 0);
};
//setTimeout(function(){window.location=window.location;},60000);
//setTimeout(function(){window.location=window.location;},30000);
setTimeout(function(){window.location=window.location;},10000);
<commit_msg>Update AutoTestingMRK4.js<commit_after>//<script src="https://rawgit.com/mshoote/BTJSC/master/Markup/AutoTestingMRK4.js"></script>
(function(console){
    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'pagingTime.txt'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)
window.onload = function() {
	window.setTimeout(function(){
  // Check for browser support
    if(!(window.performance && window.performance.timing)) {
    return;
  }
  console.log(console.save([
  performance.timing.loadEventEnd - performance.timing.fetchStart,
  performance.timing.fetchStart - performance.timing.navigationStart,
  performance.timing.redirectEnd - performance.timing.redirectStart,
  performance.timing.domainLookupStart - performance.timing.fetchStart,
  performance.timing.domainLookupEnd - performance.timing.domainLookupStart,
  performance.timing.connectEnd - performance.timing.connectStart,
  performance.timing.responseEnd - performance.timing.requestStart,
  performance.timing.unloadEventEnd - performance.timing.unloadEventStart,
  performance.timing.domContentLoadedEventEnd - performance.timing.domContentLoadedEventStart,
  performance.timing.domComplete - performance.timing.domInteractive,
  performance.timing.loadEventEnd - performance.timing.responseEnd,
  performance.timing.domInteractive - performance.timing.responseEnd,
  performance.timing.loadEventEnd - performance.timing.loadEventStart,
  performance.timing.domComplete - performance.timing.domLoading,
  performance.timing.domContentLoadedEventStart - performance.timing.domLoading,
  null
  ]));
  }, 0);
};
//setTimeout(function(){window.location=window.location;},60000);
//setTimeout(function(){window.location=window.location;},30000);
setTimeout(function(){window.location=window.location;},20000);
//setTimeout(function(){window.location=window.location;},10000);
<|endoftext|>


<commit_before>/**
Bout dat work.
@module work
*/

function l(msg){console.log(msg)}

var EventEmitter = require("events").EventEmitter,
    Timer = require("../../general").Timer,
    util = require("util"),
    cm = require("../../config-master");

function Queue(options){
    var config = new cm.Config()
        .define({ name: "name", type: "string", required: true })
        .define({ name: "onComplete", type: Queue })
        .set(options);

    if (!config.isValid) {
        this.emitError(new Error(JSON.stringify(config.errors)));
    }

    var _jobs = [];
    var self = this;

    /**
    @property timer
    @type Timer
    */
    this.timer = null;

    /**
    @property name
    @type string
    */
    this.name = config.get("name");

    /**
    @property complete
    @type boolean
    */
    this.complete = false;

    /**
    @property jobs
    @type Array
    */
    Object.defineProperty(this, "jobs", { enumerable: true, get: getJobs });
    function getJobs(){
        return _jobs.map(function(job){ return job; });
    }

    /**
    @method add
    @param Job job
    */
    this.add = function(job){
        var self = this;
        if (job instanceof Job){
            _jobs.push(job);
        } else if (Array.isArray(job)){
            var jobs = job;
            jobs.forEach(function(job){
                self.add(job);
            });

        } else {
            _jobs.push(new Job(job));
        }
        return this;
    };

    /**
    @method start
    */
    this.start = function(){
        self.emitStarting();
        var i = 0;
        var waitingFor = [];

        // need to reduce `start` and `startQueue` to just `start`.. one execution queue.
        function runNext(){
            var job = _jobs[i++];
            if (job){
               job .on("queue-starting", function(queue){
                       self.emit("queue-starting", queue);
                       waitingFor.push[queue];
                   })
                   .on("queue-complete", function(queue){
                       self.emit("queue-complete", queue);
                       var index = waitingFor.indexOf(queue);
                       if (index > -1){
                           waitingFor.splice(index, 1);
                           runNext();
                       }
                   })
                   .on("job-starting", function(job){ self.emit("job-starting", job); })
                   .on("job-progress", function(job, progress){ self.emit("job-progress", job, progress); })
                   .on("job-complete", function(job){
                       self.emit("job-complete", job);
                       if (!self.complete && _jobs.every(function(job){ return job.complete })){
                           self.emitComplete();
                       }
                   })
                   .on("job-success", function(job){
                       self.emit("job-success", job);
                   })
                   .on("job-fail", function(job){ self.emit("job-fail", job); })
                   .on("job-info", function(job, msg){ self.emit("job-info", job, msg); })
                   .on("job-warning", function(job, msg){ self.emit("job-warning", job, msg); })
                   .on("job-error", function(job, err){ self.emit("job-error", job, err); })
                   .on("job-terminated", function(job){ self.emit("job-terminated", job); });

               if (job.async){
                   job.run();
                   if (waitingFor.length == 0) runNext();
               } else {
                   job.on("job-complete", function(j){
                       if (j === job && waitingFor.length == 0) runNext();
                   })
                   job.run();
               }
            }
        }

        runNext();
        return this;
    };
}
util.inherits(Queue, EventEmitter);

/**
@event queue-starting
@param queue
*/
Queue.prototype.emitStarting = function(queue){
    this.timer = new Timer().start();
    this.emit("queue-starting", queue || this);
};
/**
@event queue-complete
@param queue
*/
Queue.prototype.emitComplete = function(queue){
    this.timer.stop();
    this.complete = true;
    this.emit("queue-complete", queue || this);
};
/**
@event queue-info
@param queue
@param msg
*/
Queue.prototype.emitInfo = function(msg){
    this.emit("queue-info", this, msg);
};
/**
@event error
@param queue
@param error
*/
Queue.prototype.emitError = function(error){
    this.emit("error", error);
};
Queue.prototype.toString = function(){
    return this.name;
};

/**
@method print
*/
Queue.prototype.print = function(){
    this.jobs.forEach(function(job){
        console.log("job: %s, async: %s", job.name, job.async);
        if (job.onSuccess.jobs.length){
            console.log("onSuccess Queue:");
        }
        job.onSuccess.jobs.forEach(function(job){
            console.log("    job: %s, async: %s", job.name, job.async);
        });
        if (job.onFail.jobs.length){
            console.log("onFail Queue:");
        }
        job.onFail.jobs.forEach(function(job){
            console.log("    job: %s, async: %s", job.name, job.async);
        });
    });
}

/**
@class Job
@constructor
*/
function Job(options){
    var self = this;
    var config = new cm.Config()
        .define({ name: "name", type: "string", required: true })
        .define({ name: "command", type: "function" })
        .define({ name: "commandSync", type: "function" })
        .define({ name: "args", type: Array })
        .define({ name: "data" })
        .define({ name: "async", type: "boolean", default: false })
        .define({ name: "onSuccess", type: Queue })
        .set(options);

    if (!config.isValid) {
        this.emitError(new Error(JSON.stringify(config.errors)));
    }

    /**
    @property name
    @type string
    */
    this.name = config.get("name");

    /**
    @property data
    @type Any
    */
    this.data = config.get("data");

    /**
    @property command
    @type function
    */
    this.command = config.get("command");

    /**
    @property commandSync
    @type function
    */
    this.commandSync = config.get("commandSync");

    /**
    @property args
    @type Array
    */
    this.args = config.get("args");

    /**
    @property complete
    @type boolean
    */
    this.complete = false;

    /**
    @property timer
    @type Timer
    */
    this.timer = null;

    /**
    @property async
    @type boolean
    */
    this.async = config.get("async");

    /**
    @property onSuccess
    @type Queue
    */
    this.onSuccess = config.hasValue("onSuccess") ? config.get("onSuccess") : new Queue({ name: this.name + " onSuccess" });

    /**
    @property onFail
    @type Queue
    */
    this.onFail = new Queue({ name: this.name + " onFail" });

    /**
    @property onTerminate
    @type Queue
    */
    this.onTerminate = new Queue({ name: this.name + " onTerminate" });
}
util.inherits(Job, EventEmitter);

Job.prototype.command = function(){
    throw new Error("Job has no command: " + this.name);
}

Job.prototype.run = function(){
    this.emitStarting();
    try{
        if (this.command){
            this.command.apply(this, this.args);
        } else if (this.commandSync){
            this.commandSync.apply(this, this.args);
            // if the above command called `emitSuccess/Fail` then `complete` will already be set,
            // if not set, assume success
            if (!this.complete){
                this.emitSuccess();
            }
        }

    } catch(e){
        this.emitError(e);
    }
};

Job.prototype.startQueue = function(queue, done){
    var self = this;
    if (queue.jobs.length){
        queue
            .on("queue-starting", function(queue){ self.emit("queue-starting", queue); })
            .on("queue-complete", function(queue){
                self.emit("queue-complete", queue);
                done();
            })
            .on("job-starting", function(job){ self.emit("job-starting", job); })
            .on("job-progress", function(job, progress){ self.emit("job-starting", job, progress); })
            .on("job-complete", function(job){ self.emit("job-complete", job); })
            .on("job-success", function(job){ self.emit("job-success", job); })
            .on("job-fail", function(job){ self.emit("job-fail", job); })
            .on("job-terminated", function(job){ self.emit("job-terminated", job); })
            .on("job-info", function(job, msg){ self.emit("job-info", job, msg); })
            .on("job-warning", function(job, msg){ self.emit("job-warning", job, msg); })
            .on("job-verbose", function(job, msg){ self.emit("job-verbose", job, msg); })
            .on("job-error", function(job, error){ self.emit("job-error", job, error); })
            .start();
    } else {
        done();
    }
};

/**
@event job-starting
@param Object job
*/
Job.prototype.emitStarting = function(){
    this.timer = new Timer().start();
    this.emit("job-starting", this);
};

/**
@event job-info
@param Object job
@param String message
*/
Job.prototype.emitInfo = function(msg){
    this.emit("job-info", this, msg);
};

/**
@event job-verbose
@param Object job
@param String message
*/
Job.prototype.emitVerbose = function(msg){
    this.emit("job-verbose", this, msg);
};

/**
@event job-complete
@param Object job
*/
Job.prototype.emitComplete = function(){
    this.timer && this.timer.stop();
    this.complete = true;
    this.emit("job-complete", this);
};

/**
@event job-success
@param Object job
*/
Job.prototype.emitSuccess = function(){
    var self = this;
    this.emit("job-success", this);
    this.startQueue(this.onSuccess, function(){
        self.emitComplete();
    });
};

/**
@event job-fail
@param Object job
*/
Job.prototype.emitFail = function(){
    var self = this;
    this.emit("job-fail", this);
    this.startQueue(this.onFail, function(){
        self.emitComplete();
    });
};

/**
@event job-warning
@param Object job
*/
Job.prototype.emitWarning = function(msg){
    this.emit("job-warning", this, msg);
};

/**
@event job-error
@param Object job
@param Error error
*/
Job.prototype.emitError = function(err){
    this.emit("job-error", this, err);
    this.emitFail();
};

/**
@event job-terminated
@param Object job
*/
Job.prototype.emitTerminated = function(){
    var self = this;
    this.emit("job-terminated", this);
    this.startQueue(this.onTerminate, function(){
        self.emitComplete();
    });
};

/**
@event job-progress
@param Object job
@param Object progress
*/
Job.prototype.emitProgress = function(progress){
    this.emit("job-progress", this, progress);
};

exports.Job = Job;
exports.Queue = Queue;<commit_msg>valid<commit_after>/**
Bout dat work.
@module work
*/

function l(msg){console.log(msg)}

var EventEmitter = require("events").EventEmitter,
    Timer = require("../../general").Timer,
    util = require("util"),
    cm = require("../../config-master");

function Queue(options){
    var config = new cm.Config()
        .define({ name: "name", type: "string", required: true })
        .define({ name: "onComplete", type: Queue })
        .set(options);

    if (!config.valid) {
        this.emitError(new Error(JSON.stringify(config.errors)));
    }

    var _jobs = [];
    var self = this;

    /**
    @property timer
    @type Timer
    */
    this.timer = null;

    /**
    @property name
    @type string
    */
    this.name = config.get("name");

    /**
    @property complete
    @type boolean
    */
    this.complete = false;

    /**
    @property jobs
    @type Array
    */
    Object.defineProperty(this, "jobs", { enumerable: true, get: getJobs });
    function getJobs(){
        return _jobs.map(function(job){ return job; });
    }

    /**
    @method add
    @param Job job
    */
    this.add = function(job){
        var self = this;
        if (job instanceof Job){
            _jobs.push(job);
        } else if (Array.isArray(job)){
            var jobs = job;
            jobs.forEach(function(job){
                self.add(job);
            });

        } else {
            _jobs.push(new Job(job));
        }
        return this;
    };

    /**
    @method start
    */
    this.start = function(){
        self.emitStarting();
        var i = 0;
        var waitingFor = [];

        // need to reduce `start` and `startQueue` to just `start`.. one execution queue.
        function runNext(){
            var job = _jobs[i++];
            if (job){
               job .on("queue-starting", function(queue){
                       self.emit("queue-starting", queue);
                       waitingFor.push[queue];
                   })
                   .on("queue-complete", function(queue){
                       self.emit("queue-complete", queue);
                       var index = waitingFor.indexOf(queue);
                       if (index > -1){
                           waitingFor.splice(index, 1);
                           runNext();
                       }
                   })
                   .on("job-starting", function(job){ self.emit("job-starting", job); })
                   .on("job-progress", function(job, progress){ self.emit("job-progress", job, progress); })
                   .on("job-complete", function(job){
                       self.emit("job-complete", job);
                       if (!self.complete && _jobs.every(function(job){ return job.complete })){
                           self.emitComplete();
                       }
                   })
                   .on("job-success", function(job){
                       self.emit("job-success", job);
                   })
                   .on("job-fail", function(job){ self.emit("job-fail", job); })
                   .on("job-info", function(job, msg){ self.emit("job-info", job, msg); })
                   .on("job-warning", function(job, msg){ self.emit("job-warning", job, msg); })
                   .on("job-error", function(job, err){ self.emit("job-error", job, err); })
                   .on("job-terminated", function(job){ self.emit("job-terminated", job); });

               if (job.async){
                   job.run();
                   if (waitingFor.length == 0) runNext();
               } else {
                   job.on("job-complete", function(j){
                       if (j === job && waitingFor.length == 0) runNext();
                   })
                   job.run();
               }
            }
        }

        runNext();
        return this;
    };
}
util.inherits(Queue, EventEmitter);

/**
@event queue-starting
@param queue
*/
Queue.prototype.emitStarting = function(queue){
    this.timer = new Timer().start();
    this.emit("queue-starting", queue || this);
};
/**
@event queue-complete
@param queue
*/
Queue.prototype.emitComplete = function(queue){
    this.timer.stop();
    this.complete = true;
    this.emit("queue-complete", queue || this);
};
/**
@event queue-info
@param queue
@param msg
*/
Queue.prototype.emitInfo = function(msg){
    this.emit("queue-info", this, msg);
};
/**
@event error
@param queue
@param error
*/
Queue.prototype.emitError = function(error){
    this.emit("error", error);
};
Queue.prototype.toString = function(){
    return this.name;
};

/**
@method print
*/
Queue.prototype.print = function(){
    this.jobs.forEach(function(job){
        console.log("job: %s, async: %s", job.name, job.async);
        if (job.onSuccess.jobs.length){
            console.log("onSuccess Queue:");
        }
        job.onSuccess.jobs.forEach(function(job){
            console.log("    job: %s, async: %s", job.name, job.async);
        });
        if (job.onFail.jobs.length){
            console.log("onFail Queue:");
        }
        job.onFail.jobs.forEach(function(job){
            console.log("    job: %s, async: %s", job.name, job.async);
        });
    });
}

/**
@class Job
@constructor
*/
function Job(options){
    var self = this;
    var config = new cm.Config()
        .define({ name: "name", type: "string", required: true })
        .define({ name: "command", type: "function" })
        .define({ name: "commandSync", type: "function" })
        .define({ name: "args", type: Array })
        .define({ name: "data" })
        .define({ name: "async", type: "boolean", default: false })
        .define({ name: "onSuccess", type: Queue })
        .set(options);

    if (!config.valid) {
        this.emitError(new Error(JSON.stringify(config.errors)));
    }

    /**
    @property name
    @type string
    */
    this.name = config.get("name");

    /**
    @property data
    @type Any
    */
    this.data = config.get("data");

    /**
    @property command
    @type function
    */
    this.command = config.get("command");

    /**
    @property commandSync
    @type function
    */
    this.commandSync = config.get("commandSync");

    /**
    @property args
    @type Array
    */
    this.args = config.get("args");

    /**
    @property complete
    @type boolean
    */
    this.complete = false;

    /**
    @property timer
    @type Timer
    */
    this.timer = null;

    /**
    @property async
    @type boolean
    */
    this.async = config.get("async");

    /**
    @property onSuccess
    @type Queue
    */
    this.onSuccess = config.hasValue("onSuccess") ? config.get("onSuccess") : new Queue({ name: this.name + " onSuccess" });

    /**
    @property onFail
    @type Queue
    */
    this.onFail = new Queue({ name: this.name + " onFail" });

    /**
    @property onTerminate
    @type Queue
    */
    this.onTerminate = new Queue({ name: this.name + " onTerminate" });
}
util.inherits(Job, EventEmitter);

Job.prototype.command = function(){
    throw new Error("Job has no command: " + this.name);
}

Job.prototype.run = function(){
    this.emitStarting();
    try{
        if (this.command){
            this.command.apply(this, this.args);
        } else if (this.commandSync){
            this.commandSync.apply(this, this.args);
            // if the above command called `emitSuccess/Fail` then `complete` will already be set,
            // if not set, assume success
            if (!this.complete){
                this.emitSuccess();
            }
        }

    } catch(e){
        this.emitError(e);
    }
};

Job.prototype.startQueue = function(queue, done){
    var self = this;
    if (queue.jobs.length){
        queue
            .on("queue-starting", function(queue){ self.emit("queue-starting", queue); })
            .on("queue-complete", function(queue){
                self.emit("queue-complete", queue);
                done();
            })
            .on("job-starting", function(job){ self.emit("job-starting", job); })
            .on("job-progress", function(job, progress){ self.emit("job-starting", job, progress); })
            .on("job-complete", function(job){ self.emit("job-complete", job); })
            .on("job-success", function(job){ self.emit("job-success", job); })
            .on("job-fail", function(job){ self.emit("job-fail", job); })
            .on("job-terminated", function(job){ self.emit("job-terminated", job); })
            .on("job-info", function(job, msg){ self.emit("job-info", job, msg); })
            .on("job-warning", function(job, msg){ self.emit("job-warning", job, msg); })
            .on("job-verbose", function(job, msg){ self.emit("job-verbose", job, msg); })
            .on("job-error", function(job, error){ self.emit("job-error", job, error); })
            .start();
    } else {
        done();
    }
};

/**
@event job-starting
@param Object job
*/
Job.prototype.emitStarting = function(){
    this.timer = new Timer().start();
    this.emit("job-starting", this);
};

/**
@event job-info
@param Object job
@param String message
*/
Job.prototype.emitInfo = function(msg){
    this.emit("job-info", this, msg);
};

/**
@event job-verbose
@param Object job
@param String message
*/
Job.prototype.emitVerbose = function(msg){
    this.emit("job-verbose", this, msg);
};

/**
@event job-complete
@param Object job
*/
Job.prototype.emitComplete = function(){
    this.timer && this.timer.stop();
    this.complete = true;
    this.emit("job-complete", this);
};

/**
@event job-success
@param Object job
*/
Job.prototype.emitSuccess = function(){
    var self = this;
    this.emit("job-success", this);
    this.startQueue(this.onSuccess, function(){
        self.emitComplete();
    });
};

/**
@event job-fail
@param Object job
*/
Job.prototype.emitFail = function(){
    var self = this;
    this.emit("job-fail", this);
    this.startQueue(this.onFail, function(){
        self.emitComplete();
    });
};

/**
@event job-warning
@param Object job
*/
Job.prototype.emitWarning = function(msg){
    this.emit("job-warning", this, msg);
};

/**
@event job-error
@param Object job
@param Error error
*/
Job.prototype.emitError = function(err){
    this.emit("job-error", this, err);
    this.emitFail();
};

/**
@event job-terminated
@param Object job
*/
Job.prototype.emitTerminated = function(){
    var self = this;
    this.emit("job-terminated", this);
    this.startQueue(this.onTerminate, function(){
        self.emitComplete();
    });
};

/**
@event job-progress
@param Object job
@param Object progress
*/
Job.prototype.emitProgress = function(progress){
    this.emit("job-progress", this, progress);
};

exports.Job = Job;
exports.Queue = Queue;<|endoftext|>


<commit_before>var HID = require('HID'),
    util = require('util'),
    chalk = require('chalk'),
    events = require('events');

var dead = 6000;

var buttons = {
  'dup': {
    'block': 2,
    'bitwise': 0x01
  },
  'ddown':{
    'block': 2,
    'bitwise': 0x02
  },
  'dleft':{
    'block': 2,
    'bitwise': 0x04
  },
  'dright':{
    'block': 2,
    'bitwise': 0x08
  },
  'start':{
    'block': 2,
    'bitwise': 0x10
  },
  'back':{
    'block': 2,
    'bitwise': 0x20
  },
  'leftstick':{
    'block': 2,
    'bitwise': 0x40
  },
  'rightstick':{
    'block': 2,
    'bitwise': 0x80
  },
  'leftshoulder':{
    'block': 3,
    'bitwise': 0x1
  },
  'rightshoulder':{
    'block': 3,
    'bitwise': 0x2
  },
  'xboxbutton':{
    'block': 3,
    'bitwise': 0x4
  },
  'a':{
    'block': 3,
    'bitwise': 0x10
  },
  'b':{
    'block': 3,
    'bitwise': 0x20
  },
  'x':{
    'block': 3,
    'bitwise': 0x40
  },
  'y':{
    'block': 3,
    'bitwise': 0x80
  }
};

var triggers = {
  'left':{
    'block': 4
  },
  'right':{
    'block': 5
  }
};

function uint8Toint16(low, high) {
  var buffer = new ArrayBuffer(4);
  var int8View = new Uint8Array(buffer);
  var int16View = new Int16Array(buffer);

  int8View[0] = low;
  int8View[1] = high;
  return int16View[0];
}

function XboxController(name) {
    this.name = name || 'controller';
    this.position = 0;

    for (var button in buttons) {
      this[button] = 0;
    }
    for (var trigger in triggers) {
      this[trigger] = 0;
    }
    this.leftx = 0;
    this.lefty = 0;
    this.rightx = 0;
    this.righty = 0;
    this.hid = false;
    this._controllerLoadingInterval = false;
    this.loadController();
  }

var ultra,bufferStore = [],original=1,count=0,leftxState=6,leftxPos=7,leftyState=8,leftyPos=9,rightxState=10,rightxPos=11,rightyState=12,rightyPos=13;

XboxController.analyze = function analyze (key, type, axis)
{
	if (original === 1) {
	  original = bufferStore[bufferStore.length-1];
	}
	if (type === 'key') {
		for(i=0; i<bufferStore.length; i++) {
			for(n=0; n<bufferStore[i].length; n++) {
				if (bufferStore[i][n] !== original[n]) {
				  buttons[key].block = n;
				  buttons[key].bitwise = parseInt("0x"+parseInt(bufferStore[i][n].toString(16),10),16);
				  bufferStore = [];
				  console.log(buttons[key].block,buttons[key].bitwise,bufferStore);
				  count+=1;
				  XboxController.configure();
				  break;
				}
			}
		}
	}
	else if(type==='trigger'){
		for(i=0; i<bufferStore.length; i++) {
			for(n=0; n<bufferStore[i].length; n++) {
				if(bufferStore[i][n] !== original[n] && bufferStore[bufferStore.length-1][n] !== 128 && bufferStore[bufferStore.length-1][n] !==0) {
				  console.log(bufferStore[bufferStore.length-1][n]);
				  triggers[key].block = n;
				  bufferStore = [];
				  console.log(triggers[key].block,bufferStore);
				  count+=1;
				  XboxController.configure();
				  break;
				}
			}
		}
	}
	else if(type==='joystick') {
		for(i=0;i<bufferStore.length;i++){
			for(n=0;n<bufferStore[i].length;n++){
				if(bufferStore[i][n] !== original[n] && axis === 'leftx' && bufferStore[i][n]-original[n]>70) {
				  leftxPos = n;
				  leftxState = (n-1);
				  bufferStore = [];
				  console.log(leftxPos,leftxState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
				if(bufferStore[i][n] !== original[n] && axis === 'rightx' && bufferStore[i][n]-original[n]>70) {
				  rightxPos=n;
				  rightxState=(n-1);
				  bufferStore = [];
				  console.log(rightxPos,rightxState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
				if(bufferStore[i][n] !== original[n] && axis === 'lefty' && original[n]-bufferStore[i][n]>70) {
				  leftyPos=n;
				  leftyState=(n-1);
				  bufferStore = [];
				  console.log(leftyPos,leftyState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
				if(bufferStore[i][n] !== original[n] && axis === 'righty' && original[n]-bufferStore[i][n]>70) {
				  rightyPos=n;
				  rightyState=(n-1);
				  bufferStore = [];
				  console.log(rightyPos,rightyState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
			}
		}
	}
};

XboxController.reader = function read(key, inputLength, type, axis)
{
	ultra.read(onRead = function(err,data) {
	  bufferStore.push(data);
		if(bufferStore.length<inputLength) {
		  ultra.read(onRead);
		}
		else {
		  XboxController.analyze(key,type,axis);
		}
	});
};

XboxController.configure = function() {
	switch(count) {
	case 0:
	  console.log('Press and release the A button');
	  XboxController.reader('a',2,'key',0);
	  break;
	case 1:
	  console.log('Press and release the Y Button');
	  XboxController.reader('y',2,'key',0);
	  break;
	case 2:
	  console.log('Press and release the B Button');
	  XboxController.reader('b',2,'key',0);
	  break;
	case 3:
	  console.log('Press and release the X Button');
	  XboxController.reader('x',2,'key',0);
	  break;
	case 4:
	  console.log('Press and release the Left Shoulder');
	  XboxController.reader('leftshoulder',2,'key',0);
	  break;
	case 5:
	  console.log('Press and release the Right Shoulder');
	  XboxController.reader('rightshoulder',2,'key',0);
	  break;
	case 6:
	  console.log('Press and release D-pad up','key');
	  XboxController.reader('dup',2,'key');
	  break;
	case 7:
	  console.log('Press and release D-pad down');
	  XboxController.reader('ddown',2,'key',0);
	  break;
	case 8:
	  console.log('Press and release D-pad left');
	  XboxController.reader('dleft',2,'key',0);
	  break;
	case 9:
	  console.log('Press and release D-pad right');
	  XboxController.reader('dright',2,'key',0);
	  break;
	case 10:
	  console.log('Wiggle the right trigger');
	  XboxController.reader('right',50,'trigger',0);
	  break;
	case 11:
	  console.log('Wiggle the left trigger');
	  XboxController.reader('left',50,'trigger',0);
	  break;
	case 12:
	  console.log('Keep wiggling the left trigger');
	  XboxController.reader('left',50,'trigger',0);
	  break;
	case 13:
	  console.log('Move the left joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','leftx');
	  break;
	case 14:
	  console.log('Keep moving the left joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','leftx');
	  break;
	case 15:
	  console.log('Move the right joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','rightx');
	  break;
	case 16:
	  console.log('Keep moving the right joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','rightx');
	  break;
	case 17:
	  console.log('Move the right joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','righty');
	  break;
	case 18:
	  console.log('Keep moving the right joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','righty');
	  break;
	case 19:
	  console.log('Move the left joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','lefty');
	  break;
	case 20:
	  console.log('Keep moving the left joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','lefty');
	  break;
	case 21:
	  console.log("done");
	  break;
	default:
	  console.log('error try again');
	}
}

util.inherits(XboxController, events.EventEmitter);

XboxController.prototype.loadController = function() {

  HID.devices().forEach((function(d) {
    if(typeof d === 'object' && d.product.toLowerCase().indexOf(this.name) !== -1) {
      this.hid = new HID.HID(d.path);
      console.log( chalk.green('notice: '), 'Xbox controller connected.' );
	  ultra = this.hid;
    }
  }).bind(this));

  if(this.hid === false && !this._controllerLoadingInterval) {
    this._controllerLoadingInterval = setInterval(function() {
      this.loadController();
    }.bind(this), 2000);
  }

  try {
    this.hid.read(this.interpretData.bind(this));
  }
  catch ( ex ) {
    console.log( chalk.red('error: '), 'Xbox controller could not be found.' );
  }

};

XboxController.prototype.interpretData = function(error, data) {
    if(error && this.hid) {
      console.log(chalk.red('error:'), error);
      this.hid = false;
      this.loadController();
      return false;
    } else {
      clearInterval(this._controllerLoadingInterval);
      this._controllerLoadingInterval = false;
    }

    for (var key in buttons) {
      var address = buttons[key];
      var state = data[address.block] & address.bitwise;

      if(state ^ this[key]){
        this.emit((state ? key+':press': key+':release'), key);
        this[key] = state;
      }
    }

    for (var trigger in triggers) {
      var address = triggers[trigger];
      var state = data[address.block];
      if(state ^ this[trigger]){
        this.emit(trigger+'trigger', state);
        this[trigger] = state;
      }
    }

    var leftx = uint8Toint16(data[6], data[7]);
    var lefty = uint8Toint16(data[8], data[9]);

    if(leftx ^ this.leftx | lefty ^ this.lefty){
      if (leftx > -1*dead && leftx < dead ){
        leftx = 0;
      }
      if (lefty > -1*dead && lefty < dead ){
        lefty = 0;
      }

      this.emit('left:move', {x: leftx, y: lefty});
      this.leftx = leftx;
      this.lefty = lefty;
    }

    var rightx = uint8Toint16(data[10], data[11]);
    var righty = uint8Toint16(data[12], data[13]);

    if(rightx ^ this.rightx | righty ^ this.righty){
      if (rightx > -1*dead && rightx < dead ){
        rightx = 0;
      }
      if (righty > -1*dead && righty < dead ){
        righty = 0;
      }
      this.emit('right:move', {x: rightx, y: righty});
      this.rightx = rightx;
      this.righty = righty;
    }

    this.hid.read(this.interpretData.bind(this));
  };

XboxController.prototype.sendCommand = function(command, errorMsg) {
  try{
      this.hid.write(command);
    }
  catch ( ex ){
    console.log( chalk.red('error: '), errorMsg );
  }
};

/*

Pattern  Description
0x00   All off
0x01   All blinking
0x02   1 flashes, then on
0x03   2 flashes, then on
0x04   3 flashes, then on
0x05   4 flashes, then on
0x06   1 on
0x07   2 on
0x08   3 on
0x09   4 on
0x0A   Rotating (e.g. 1-2-4-3)
0x0B   Blinking*
0x0C   Slow blinking*
0x0D   Alternating (e.g. 1+4-2+3), then back to previous*

 */
// input one of the patterns abov
XboxController.prototype.setLed = function(flag) {
  this.sendCommand([0x01, 0x03, flag ], 'Xbox cant set LED to HEX ' + flag);
};

XboxController.prototype.powerOff = function() {
  this.sendCommand([0x02, 0x02 ], 'Xbox controller wont poweroff');
};

XboxController.prototype.rumble = function(left, right) {
  if (typeof left === "undefined" || left===null) {left = 0xff;}
  if (typeof right === "undefined" || right===null) {right = 0xff;}
  this.sendCommand([0x00, 0x00, 0x04, left, right], 'Xbox controller wont rumble');
};

module.exports = XboxController;<commit_msg>Renamed HID to node-hid<commit_after>var HID = require('node-hid'),
    util = require('util'),
    chalk = require('chalk'),
    events = require('events');

var dead = 6000;

var buttons = {
  'dup': {
    'block': 2,
    'bitwise': 0x01
  },
  'ddown':{
    'block': 2,
    'bitwise': 0x02
  },
  'dleft':{
    'block': 2,
    'bitwise': 0x04
  },
  'dright':{
    'block': 2,
    'bitwise': 0x08
  },
  'start':{
    'block': 2,
    'bitwise': 0x10
  },
  'back':{
    'block': 2,
    'bitwise': 0x20
  },
  'leftstick':{
    'block': 2,
    'bitwise': 0x40
  },
  'rightstick':{
    'block': 2,
    'bitwise': 0x80
  },
  'leftshoulder':{
    'block': 3,
    'bitwise': 0x1
  },
  'rightshoulder':{
    'block': 3,
    'bitwise': 0x2
  },
  'xboxbutton':{
    'block': 3,
    'bitwise': 0x4
  },
  'a':{
    'block': 3,
    'bitwise': 0x10
  },
  'b':{
    'block': 3,
    'bitwise': 0x20
  },
  'x':{
    'block': 3,
    'bitwise': 0x40
  },
  'y':{
    'block': 3,
    'bitwise': 0x80
  }
};

var triggers = {
  'left':{
    'block': 4
  },
  'right':{
    'block': 5
  }
};

function uint8Toint16(low, high) {
  var buffer = new ArrayBuffer(4);
  var int8View = new Uint8Array(buffer);
  var int16View = new Int16Array(buffer);

  int8View[0] = low;
  int8View[1] = high;
  return int16View[0];
}

function XboxController(name) {
    this.name = name || 'controller';
    this.position = 0;

    for (var button in buttons) {
      this[button] = 0;
    }
    for (var trigger in triggers) {
      this[trigger] = 0;
    }
    this.leftx = 0;
    this.lefty = 0;
    this.rightx = 0;
    this.righty = 0;
    this.hid = false;
    this._controllerLoadingInterval = false;
    this.loadController();
  }

var ultra,bufferStore = [],original=1,count=0,leftxState=6,leftxPos=7,leftyState=8,leftyPos=9,rightxState=10,rightxPos=11,rightyState=12,rightyPos=13;

XboxController.analyze = function analyze (key, type, axis)
{
	if (original === 1) {
	  original = bufferStore[bufferStore.length-1];
	}
	if (type === 'key') {
		for(i=0; i<bufferStore.length; i++) {
			for(n=0; n<bufferStore[i].length; n++) {
				if (bufferStore[i][n] !== original[n]) {
				  buttons[key].block = n;
				  buttons[key].bitwise = parseInt("0x"+parseInt(bufferStore[i][n].toString(16),10),16);
				  bufferStore = [];
				  console.log(buttons[key].block,buttons[key].bitwise,bufferStore);
				  count+=1;
				  XboxController.configure();
				  break;
				}
			}
		}
	}
	else if(type==='trigger'){
		for(i=0; i<bufferStore.length; i++) {
			for(n=0; n<bufferStore[i].length; n++) {
				if(bufferStore[i][n] !== original[n] && bufferStore[bufferStore.length-1][n] !== 128 && bufferStore[bufferStore.length-1][n] !==0) {
				  console.log(bufferStore[bufferStore.length-1][n]);
				  triggers[key].block = n;
				  bufferStore = [];
				  console.log(triggers[key].block,bufferStore);
				  count+=1;
				  XboxController.configure();
				  break;
				}
			}
		}
	}
	else if(type==='joystick') {
		for(i=0;i<bufferStore.length;i++){
			for(n=0;n<bufferStore[i].length;n++){
				if(bufferStore[i][n] !== original[n] && axis === 'leftx' && bufferStore[i][n]-original[n]>70) {
				  leftxPos = n;
				  leftxState = (n-1);
				  bufferStore = [];
				  console.log(leftxPos,leftxState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
				if(bufferStore[i][n] !== original[n] && axis === 'rightx' && bufferStore[i][n]-original[n]>70) {
				  rightxPos=n;
				  rightxState=(n-1);
				  bufferStore = [];
				  console.log(rightxPos,rightxState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
				if(bufferStore[i][n] !== original[n] && axis === 'lefty' && original[n]-bufferStore[i][n]>70) {
				  leftyPos=n;
				  leftyState=(n-1);
				  bufferStore = [];
				  console.log(leftyPos,leftyState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
				if(bufferStore[i][n] !== original[n] && axis === 'righty' && original[n]-bufferStore[i][n]>70) {
				  rightyPos=n;
				  rightyState=(n-1);
				  bufferStore = [];
				  console.log(rightyPos,rightyState);
				  count+=1;
				  XboxController.configure();
				  break;
				}
			}
		}
	}
};

XboxController.reader = function read(key, inputLength, type, axis)
{
	ultra.read(onRead = function(err,data) {
	  bufferStore.push(data);
		if(bufferStore.length<inputLength) {
		  ultra.read(onRead);
		}
		else {
		  XboxController.analyze(key,type,axis);
		}
	});
};

XboxController.configure = function() {
	switch(count) {
	case 0:
	  console.log('Press and release the A button');
	  XboxController.reader('a',2,'key',0);
	  break;
	case 1:
	  console.log('Press and release the Y Button');
	  XboxController.reader('y',2,'key',0);
	  break;
	case 2:
	  console.log('Press and release the B Button');
	  XboxController.reader('b',2,'key',0);
	  break;
	case 3:
	  console.log('Press and release the X Button');
	  XboxController.reader('x',2,'key',0);
	  break;
	case 4:
	  console.log('Press and release the Left Shoulder');
	  XboxController.reader('leftshoulder',2,'key',0);
	  break;
	case 5:
	  console.log('Press and release the Right Shoulder');
	  XboxController.reader('rightshoulder',2,'key',0);
	  break;
	case 6:
	  console.log('Press and release D-pad up','key');
	  XboxController.reader('dup',2,'key');
	  break;
	case 7:
	  console.log('Press and release D-pad down');
	  XboxController.reader('ddown',2,'key',0);
	  break;
	case 8:
	  console.log('Press and release D-pad left');
	  XboxController.reader('dleft',2,'key',0);
	  break;
	case 9:
	  console.log('Press and release D-pad right');
	  XboxController.reader('dright',2,'key',0);
	  break;
	case 10:
	  console.log('Wiggle the right trigger');
	  XboxController.reader('right',50,'trigger',0);
	  break;
	case 11:
	  console.log('Wiggle the left trigger');
	  XboxController.reader('left',50,'trigger',0);
	  break;
	case 12:
	  console.log('Keep wiggling the left trigger');
	  XboxController.reader('left',50,'trigger',0);
	  break;
	case 13:
	  console.log('Move the left joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','leftx');
	  break;
	case 14:
	  console.log('Keep moving the left joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','leftx');
	  break;
	case 15:
	  console.log('Move the right joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','rightx');
	  break;
	case 16:
	  console.log('Keep moving the right joystick a bit to the right');
	  XboxController.reader('left',200,'joystick','rightx');
	  break;
	case 17:
	  console.log('Move the right joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','righty');
	  break;
	case 18:
	  console.log('Keep moving the right joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','righty');
	  break;
	case 19:
	  console.log('Move the left joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','lefty');
	  break;
	case 20:
	  console.log('Keep moving the left joystick upwards a bit');
	  XboxController.reader('left',200,'joystick','lefty');
	  break;
	case 21:
	  console.log("done");
	  break;
	default:
	  console.log('error try again');
	}
}

util.inherits(XboxController, events.EventEmitter);

XboxController.prototype.loadController = function() {

  HID.devices().forEach((function(d) {
    if(typeof d === 'object' && d.product.toLowerCase().indexOf(this.name) !== -1) {
      this.hid = new HID.HID(d.path);
      console.log( chalk.green('notice: '), 'Xbox controller connected.' );
	  ultra = this.hid;
    }
  }).bind(this));

  if(this.hid === false && !this._controllerLoadingInterval) {
    this._controllerLoadingInterval = setInterval(function() {
      this.loadController();
    }.bind(this), 2000);
  }

  try {
    this.hid.read(this.interpretData.bind(this));
  }
  catch ( ex ) {
    console.log( chalk.red('error: '), 'Xbox controller could not be found.' );
  }

};

XboxController.prototype.interpretData = function(error, data) {
    if(error && this.hid) {
      console.log(chalk.red('error:'), error);
      this.hid = false;
      this.loadController();
      return false;
    } else {
      clearInterval(this._controllerLoadingInterval);
      this._controllerLoadingInterval = false;
    }

    for (var key in buttons) {
      var address = buttons[key];
      var state = data[address.block] & address.bitwise;

      if(state ^ this[key]){
        this.emit((state ? key+':press': key+':release'), key);
        this[key] = state;
      }
    }

    for (var trigger in triggers) {
      var address = triggers[trigger];
      var state = data[address.block];
      if(state ^ this[trigger]){
        this.emit(trigger+'trigger', state);
        this[trigger] = state;
      }
    }

    var leftx = uint8Toint16(data[6], data[7]);
    var lefty = uint8Toint16(data[8], data[9]);

    if(leftx ^ this.leftx | lefty ^ this.lefty){
      if (leftx > -1*dead && leftx < dead ){
        leftx = 0;
      }
      if (lefty > -1*dead && lefty < dead ){
        lefty = 0;
      }

      this.emit('left:move', {x: leftx, y: lefty});
      this.leftx = leftx;
      this.lefty = lefty;
    }

    var rightx = uint8Toint16(data[10], data[11]);
    var righty = uint8Toint16(data[12], data[13]);

    if(rightx ^ this.rightx | righty ^ this.righty){
      if (rightx > -1*dead && rightx < dead ){
        rightx = 0;
      }
      if (righty > -1*dead && righty < dead ){
        righty = 0;
      }
      this.emit('right:move', {x: rightx, y: righty});
      this.rightx = rightx;
      this.righty = righty;
    }

    this.hid.read(this.interpretData.bind(this));
  };

XboxController.prototype.sendCommand = function(command, errorMsg) {
  try{
      this.hid.write(command);
    }
  catch ( ex ){
    console.log( chalk.red('error: '), errorMsg );
  }
};

/*

Pattern  Description
0x00   All off
0x01   All blinking
0x02   1 flashes, then on
0x03   2 flashes, then on
0x04   3 flashes, then on
0x05   4 flashes, then on
0x06   1 on
0x07   2 on
0x08   3 on
0x09   4 on
0x0A   Rotating (e.g. 1-2-4-3)
0x0B   Blinking*
0x0C   Slow blinking*
0x0D   Alternating (e.g. 1+4-2+3), then back to previous*

 */
// input one of the patterns abov
XboxController.prototype.setLed = function(flag) {
  this.sendCommand([0x01, 0x03, flag ], 'Xbox cant set LED to HEX ' + flag);
};

XboxController.prototype.powerOff = function() {
  this.sendCommand([0x02, 0x02 ], 'Xbox controller wont poweroff');
};

XboxController.prototype.rumble = function(left, right) {
  if (typeof left === "undefined" || left===null) {left = 0xff;}
  if (typeof right === "undefined" || right===null) {right = 0xff;}
  this.sendCommand([0x00, 0x00, 0x04, left, right], 'Xbox controller wont rumble');
};

module.exports = XboxController;
<|endoftext|>


<commit_before>
'use strict';

module.exports = function(kbox, pantheon) {

  // Intrinsic modules.
  var path = require('path');
  var fs = require('fs');

  // Npm modulez
  var _ = require('lodash');
  var Promise = require('bluebird');
  var fingerprint = require('ssh-fingerprint');
  var keygen = require('ssh-keygen');
  Promise.longStackTraces();

  // "CONSTANTS"
  var SSH_DIR = path.join(kbox.core.deps.lookup('globalConfig').home, '.ssh');
  var PRIVATE_KEY_PATH = path.join(SSH_DIR, 'pantheon.kalabox.id_rsa');
  var PUBLIC_KEY_PATH = path.join(SSH_DIR, 'pantheon.kalabox.id_rsa.pub');

  /*
   * Load our pantheon public key and return it and a non-coloned
   * fingerprint
   */
  var loadPubKey = function() {
    var data = fs.readFileSync(PUBLIC_KEY_PATH, 'utf-8');
    return {
      data: data,
      print: fingerprint(data).replace(/:/g, '')
    };
  };

  /*
   * Helper method to promisigy fs.exists
   */
  var existsAsync = function(path) {
    return new Promise(function(resolve) {
      fs.exists(path, resolve);
    });
  };

  /*
   * Parse our sites from terminus into a choices array
   */
  var parseSites = function(sites) {
    var choices = [];
    _.map(sites, function(val, key) {
      choices.push({
        name: val.information.name,
        value: key
      });
    });
    return _.sortBy(choices, 'name');
  };

  /*
   * Parse our products from terminus into a choices array
   */
  var parseEnvironments = function(envs) {
    var choices = [];

    // @todo:
    // This is best practices but maybe we want to open it up?
    delete envs.live;
    delete envs.test;

    _.map(envs, function(val, key) {
      choices.push({
        name: key,
        value: key
      });
    });
    return _.sortBy(choices, 'name');
  };

  // Add an option
  // @todo: Add a when function to this that checks for a valid cached token
  // and only prompts user if it needs to refresh
  kbox.create.add('pantheon', {
    option: {
      name: 'email',
      weight: -99,
      task: {
        kind: 'string',
        description: 'Pantheon dashboard email.',
      },
      inquire: {
        type: 'input',
        message: 'Pantheon dashboard email',
        validate: function(value) {
          // @todo some actual validation here
          return true;
        }
      }
    }
  });

  // Add an option
  // @todo: Add a when function to this that checks for a valid cached token
  // and only prompts user if it needs to refresh
  kbox.create.add('pantheon', {
    option: {
      name: 'password',
      weight: -98,
      task: {
        kind: 'string',
        description: 'Pantheon dashboard password.',
      },
      inquire: {
        type: 'password',
        message: 'Pantheon dashboard password'
      }
    }
  });

  // Add an option
  kbox.create.add('pantheon', {
    option: {
      name: 'uuid',
      weight: -90,
      task: {
        kind: 'string',
        description: 'Pantheon site machine name.',
      },
      inquire: {
        type: 'list',
        message: 'Which site?',
        choices: function(answers) {

          // Make this async cause we need to hit the terminus
          var done = this.async();

          // Login to the pantheon, set up SSH keys if needed
          // and pull a list of sites
          // @todo: ERROR HANDLING
          // @todo: better debug logging
          // @toto: AFRICA
          pantheon.login(answers.email, answers.password)

          // We've got a session!
          .then(function(session) {

            kbox.core.log.debug('PANTHEON LOGIN => WE GOOD', session);

            // Now check to see whether we have a pantheon SSH key already
            // @todo: we shouldnt assume that because a private key exists that a
            // public one does as well
            return existsAsync(PRIVATE_KEY_PATH)

            // Generate a new SSH key if eneded
            .then(function(exists) {
              if (!exists) {
                kbox.core.log.debug('PANTHEON SSHKEY => GENERATING KEY');
                var keyOpts = {
                  location: PRIVATE_KEY_PATH,
                  comment: answers.email,
                  read: false,
                  destroy: false
                };
                return Promise.fromNode(function(callback) {
                  keygen(keyOpts, callback);
                });
              }
            })

            // Look to see if pantheon has our pubkey
            .then(function() {

              // Grab our public key
              var pubKey = loadPubKey();

              // Grab public key fingerprints from pantheon
              return pantheon.getSSHKeys()

              // IF THE GLOVE FITS! YOU MUST ACQUIT!
              .then(function(keys) {
                return _.has(keys, pubKey.print);
              })

              // Post a key to pantheon if needed
              .then(function(hasKey) {
                if (!hasKey) {
                  kbox.core.log.debug('PANTHEON SSHKEY => POSTING KEY');
                  return pantheon.postSSHKey(pubKey.data);
                }
              });
            })

            // Grab a list of sites from pantheon
            .then(function() {
              return pantheon.getSites();
            })

            // Parse the list
            .then(function(sites) {
              done(parseSites(sites));
            });

          });
        },
        when: function(answers) {
          // @todo some actual validation here
          return true;
        }
      },
      conf: {
        type: 'plugin',
        plugin: 'kalabox-plugin-pantheon',
        key: 'uuid'
      }
    }
  });

  // Add an option
  kbox.create.add('pantheon', {
    option: {
      name: 'env',
      weight: -85,
      task: {
        kind: 'string',
        description: 'Pantheon site environment.',
      },
      inquire: {
        type: 'list',
        message: 'Which environment?',
        choices: function(answers) {

          // Make this async cause we need to hit the terminus
          var done = this.async();

          // Login to the pantheon
          pantheon.login(answers.email, answers.password)
          .then(function(session) {

            // grab our sites environments
            var uuid = answers.uuid;
            return pantheon.getEnvironments(uuid)
            .then(function(envs) {
              done(parseEnvironments(envs));
            });
          });
        },
        when: function(answers) {
          // @todo some actual validation here
          return true;
        }
      },
      conf: {
        type: 'plugin',
        plugin: 'kalabox-plugin-pantheon',
        key: 'env'
      }
    }
  });

  // Add an option
  kbox.create.add('pantheon', {
    option: {
      name: 'name',
      weight: -80,
      task: {
        kind: 'string',
        description: 'The name of your app.',
      },
      inquire: {
        type: 'input',
        message: 'What will you call this monster you have created',
        validate: function(value) {
          // @todo some actual validation here
          return true;
        },
        filter: function(value) {
          return _.kebabCase(value);
        },
        default: function(answers) {
          return pantheon.sites[answers.uuid].information.name;
        }
      },
      conf: {
        type: 'global',
        key: 'appName'
      }
    }
  });

};
<commit_msg>#7: On windows we need to modify the path so that ssh-keygen is avail<commit_after>
'use strict';

module.exports = function(kbox, pantheon) {

  // Intrinsic modules.
  var path = require('path');
  var fs = require('fs');

  // Npm modulez
  var _ = require('lodash');
  var Promise = require('bluebird');
  var fingerprint = require('ssh-fingerprint');
  var keygen = require('ssh-keygen');
  Promise.longStackTraces();

  // "CONSTANTS"
  var SSH_DIR = path.join(kbox.core.deps.lookup('globalConfig').home, '.ssh');
  var PRIVATE_KEY_PATH = path.join(SSH_DIR, 'pantheon.kalabox.id_rsa');
  var PUBLIC_KEY_PATH = path.join(SSH_DIR, 'pantheon.kalabox.id_rsa.pub');

  /*
   * Load our pantheon public key and return it and a non-coloned
   * fingerprint
   */
  var loadPubKey = function() {
    var data = fs.readFileSync(PUBLIC_KEY_PATH, 'utf-8');
    return {
      data: data,
      print: fingerprint(data).replace(/:/g, '')
    };
  };

  /*
   * Helper method to promisigy fs.exists
   */
  var existsAsync = function(path) {
    return new Promise(function(resolve) {
      fs.exists(path, resolve);
    });
  };

  /*
   * Parse our sites from terminus into a choices array
   */
  var parseSites = function(sites) {
    var choices = [];
    _.map(sites, function(val, key) {
      choices.push({
        name: val.information.name,
        value: key
      });
    });
    return _.sortBy(choices, 'name');
  };

  /*
   * Parse our products from terminus into a choices array
   */
  var parseEnvironments = function(envs) {
    var choices = [];

    // @todo:
    // This is best practices but maybe we want to open it up?
    delete envs.live;
    delete envs.test;

    _.map(envs, function(val, key) {
      choices.push({
        name: key,
        value: key
      });
    });
    return _.sortBy(choices, 'name');
  };

  // Add an option
  // @todo: Add a when function to this that checks for a valid cached token
  // and only prompts user if it needs to refresh
  kbox.create.add('pantheon', {
    option: {
      name: 'email',
      weight: -99,
      task: {
        kind: 'string',
        description: 'Pantheon dashboard email.',
      },
      inquire: {
        type: 'input',
        message: 'Pantheon dashboard email',
        validate: function(value) {
          // @todo some actual validation here
          return true;
        }
      }
    }
  });

  // Add an option
  // @todo: Add a when function to this that checks for a valid cached token
  // and only prompts user if it needs to refresh
  kbox.create.add('pantheon', {
    option: {
      name: 'password',
      weight: -98,
      task: {
        kind: 'string',
        description: 'Pantheon dashboard password.',
      },
      inquire: {
        type: 'password',
        message: 'Pantheon dashboard password'
      }
    }
  });

  // Add an option
  kbox.create.add('pantheon', {
    option: {
      name: 'uuid',
      weight: -90,
      task: {
        kind: 'string',
        description: 'Pantheon site machine name.',
      },
      inquire: {
        type: 'list',
        message: 'Which site?',
        choices: function(answers) {

          // Make this async cause we need to hit the terminus
          var done = this.async();

          // Login to the pantheon, set up SSH keys if needed
          // and pull a list of sites
          // @todo: ERROR HANDLING
          // @todo: better debug logging
          // @toto: AFRICA
          pantheon.login(answers.email, answers.password)

          // We've got a session!
          .then(function(session) {

            kbox.core.log.debug('PANTHEON LOGIN => WE GOOD', session);

            // Now check to see whether we have a pantheon SSH key already
            // @todo: we shouldnt assume that because a private key exists that a
            // public one does as well
            return existsAsync(PRIVATE_KEY_PATH)

            // Generate a new SSH key if eneded
            .then(function(exists) {
              if (!exists) {

                kbox.core.log.debug('PANTHEON SSHKEY => GENERATING KEY');

                // Set Path environmental variable if we are on windows.
                // We need this because ssh-keygen is not in the path by default
                if (process.platform === 'win32') {

                  // Get needed vars
                  var gitBin = 'C:\\Program Files (x86)\\Git\\bin;';
                  var path = process.env.path;

                  // Only add the gitbin to the path if the path doesn't start with
                  // it. We want to make sure gitBin is first so other things like
                  // putty don't F with it.
                  // See https://github.com/kalabox/kalabox/issues/342
                  if (!_.startsWith(path, gitBin)) {
                    kbox.core.env.setEnv('Path', gitBin + path);
                  }
                }

                var keyOpts = {
                  location: PRIVATE_KEY_PATH,
                  comment: answers.email,
                  read: false,
                  destroy: false
                };

                return Promise.fromNode(function(callback) {
                  keygen(keyOpts, callback);
                });
              }
            })

            // Look to see if pantheon has our pubkey
            .then(function() {

              // Grab our public key
              var pubKey = loadPubKey();

              // Grab public key fingerprints from pantheon
              return pantheon.getSSHKeys()

              // IF THE GLOVE FITS! YOU MUST ACQUIT!
              .then(function(keys) {
                return _.has(keys, pubKey.print);
              })

              // Post a key to pantheon if needed
              .then(function(hasKey) {
                if (!hasKey) {
                  kbox.core.log.debug('PANTHEON SSHKEY => POSTING KEY');
                  return pantheon.postSSHKey(pubKey.data);
                }
              });
            })

            // Grab a list of sites from pantheon
            .then(function() {
              return pantheon.getSites();
            })

            // Parse the list
            .then(function(sites) {
              done(parseSites(sites));
            });

          });
        },
        when: function(answers) {
          // @todo some actual validation here
          return true;
        }
      },
      conf: {
        type: 'plugin',
        plugin: 'kalabox-plugin-pantheon',
        key: 'uuid'
      }
    }
  });

  // Add an option
  kbox.create.add('pantheon', {
    option: {
      name: 'env',
      weight: -85,
      task: {
        kind: 'string',
        description: 'Pantheon site environment.',
      },
      inquire: {
        type: 'list',
        message: 'Which environment?',
        choices: function(answers) {

          // Make this async cause we need to hit the terminus
          var done = this.async();

          // Login to the pantheon
          pantheon.login(answers.email, answers.password)
          .then(function(session) {

            // grab our sites environments
            var uuid = answers.uuid;
            return pantheon.getEnvironments(uuid)
            .then(function(envs) {
              done(parseEnvironments(envs));
            });
          });
        },
        when: function(answers) {
          // @todo some actual validation here
          return true;
        }
      },
      conf: {
        type: 'plugin',
        plugin: 'kalabox-plugin-pantheon',
        key: 'env'
      }
    }
  });

  // Add an option
  kbox.create.add('pantheon', {
    option: {
      name: 'name',
      weight: -80,
      task: {
        kind: 'string',
        description: 'The name of your app.',
      },
      inquire: {
        type: 'input',
        message: 'What will you call this monster you have created',
        validate: function(value) {
          // @todo some actual validation here
          return true;
        },
        filter: function(value) {
          return _.kebabCase(value);
        },
        default: function(answers) {
          return pantheon.sites[answers.uuid].information.name;
        }
      },
      conf: {
        type: 'global',
        key: 'appName'
      }
    }
  });

};
<|endoftext|>


<commit_before>#!/usr/bin/env node

/* jshint node: true */

'use strict';

var timer, pattern, interval;
var rotate = require('./rotate-wallpaper');
var notify = false;

process.on('message', function(params) {
  pattern  = params.pattern;
  interval = params.interval;
  timer    = setInterval(rotate, interval, pattern);
  notify   = params.notify;

  rotate(pattern, params.notify).then(function() {
    process.send({ running: true });
  });
});

process.on('SIGUSR1', function() {
  if (timer) {
    clearInterval(timer);
    timer = 0;
  } else {
    rotate(pattern).then(function() {
      timer = setInterval(rotate, interval, pattern);
    });
  }
});

process.on('SIGUSR2', function() {
  if (pattern) {
    rotate(pattern, notify);
  }
});

process.on('SIGTERM', function() {
  clearInterval(timer);
  process.exit();
});
<commit_msg>Fix notifications on pause/unpause<commit_after>#!/usr/bin/env node

/* jshint node: true */

'use strict';

var timer, pattern, interval;
var rotate   = require('./rotate-wallpaper');
var notifier = require('node-notifier');
var notify   = false;

process.on('message', function(params) {
  pattern  = params.pattern;
  interval = params.interval;
  timer    = setInterval(rotate, interval, pattern);
  notify   = params.notify;

  rotate(pattern, params.notify).then(function() {
    process.send({ running: true });
  });
});

process.on('SIGUSR1', function() {
  if (timer) {
    clearInterval(timer);
    timer = 0;
    notifier.notify({
      title: 'Wallpaper Shuffle',
      message: 'Paused!'
    });
  } else {
    rotate(pattern, notify).then(function() {
      timer = setInterval(rotate, interval, pattern, notify);
    });
  }
});

process.on('SIGUSR2', function() {
  if (pattern) {
    rotate(pattern, notify);
  }
});

process.on('SIGTERM', function() {
  clearInterval(timer);
  process.exit();
});
<|endoftext|>


<commit_before>const mongoose     = require('mongoose');
const Schema       = mongoose.Schema;

const ObjectId = mongoose.Schema.Types.ObjectId;
const Organisation = require("./organisation_model");
const Membership = require("./membership_model");
const Discount = require("./discount_model");
const User = require("./user_model");
const Invoice = require("./invoice_model");
const Space = require("./space_model");
const Location = require("./location_model");
const Claytag = require("./claytag_model");
const LineItem = require("./lineitem_model");
const diff = require('deep-diff').diff;
const Log = require("./log_model");

const LicenseSchema   = new Schema({
	organisation_id: { type: ObjectId, ref: 'Organisation', index: true, required: true },
	membership_id: { type: ObjectId, ref: 'Membership', required: true },
	xero_account: String,
	user_id: { type: ObjectId, ref: 'User', index: true },
	claytag_id: { type: ObjectId, ref: "Claytag" },
	date_created: { type: Date, default: Date.now },
	invoice_id: { type: ObjectId, ref: 'Invoice', index: true },
	space_id: { type: ObjectId, ref: 'Space', index: true },
	location_id: { type: ObjectId, ref: 'Location', index: true },
	lineitem_id: { type: ObjectId, ref: 'LineItem', index: true },
	date_start: Date,
	date_end: Date,
	price: {
		type: Number,
		validate: function(v) {
			return v >= 0;
		},
	},
	discount: { type: Number, default: 0 },
	discount_date_start: Date,
	discount_date_end: Date,
	discount_description: String,
	discount_comment: String,
	_owner_id: ObjectId,
	_deleted: { type: Boolean, default: false, index: true },
}, {
	toObject: {
		virtuals: true
	},
	toJSON: {
		virtuals: true
	},
	timestamps: true
});

LicenseSchema.set("_perms", {
	finance: "crud",
	line_manager: "crud",
	"managers": "cr",
	admin: "r",
	primary_member: "r",
	user: "r"
});

// Discounts
LicenseSchema.pre("save", async function () {
	const LineItem = require("./lineitem_model");
	const User = require("./user_model");
	let discount = await Discount.findOne({ license_id: this._id, _deleted: false }).exec();
	let lineitem = await LineItem.findOne({ license_id: this._id, _deleted: false }).exec();
	if ((!this.discount) && (discount)) {
		// Delete existing discount and bail
		discount._deleted = true;
		discount.save();
		return;
	}
	if (!this.discount) return; // No discount to set
	if (discount) {
		// Update existing discount
		let description = "LICENSE - No User";
		if (this.user_id) {
			const user = await User.findOne({ _id: this.user_id });
			description = `LICENSE - ${user.name} (${user.email})`;
		}
		discount.discount = this.discount;
		discount.date_start = this.discount_date_start;
		discount.date_end = this.discount_date_end;
		discount.description = description;
		if (discount_comment)
			discount.comment = this.discount_comment;
	} else {
		// Create a new discount
		let description = "LICENSE - No User";
		if (this.user_id) {
			const user = await User.findOne({ _id: this.user_id });
			description = `LICENSE - ${ user.name } (${ user.email })`;
		}
		discount = new Discount({
			discount: this.discount,
			license_id: this._id,
			organisation_id: this.organisation_id,
			date_start: this.discount_date_start,
			date_end: this.discount_date_end,
			comment: this.discount_comment,
			description,
			_owner_id: this.sender._id
		});
		if (lineitem) {
			discount.lineitem_id = lineitem._id;
		}
	}
	await discount.save();
});

LicenseSchema.post("update", async function (doc) {
	console.log({doc});
});

/*
 * Log changes
 */
LicenseSchema.post('validate', function(doc) {
	var self = this;
	var log = null;
	var LicenseModel = mongoose.model('License', LicenseSchema);
	LicenseModel.findOne({ _id: doc._id }, function(err, original) {
		if (!original) {
			log = new Log({
				id: doc._id,
				model: "license",
				level: 3,
				user_id: self.__user,
				title: "License created",
				message: "License created",
				code: "license-create",
				data: doc,
			}).save();
		} else {
			var d = diff(original.toObject(), doc.toObject());
			if (d) {
				log = new Log({
					id: doc._id,
					model: "license",
					level: 3,
					user_id: self.__user,
					title: "License changed",
					message: "License changed",
					code: "license-change",
					data: d,
				}).save();
			}
		}
	});
});

LicenseSchema.virtual("status").get(function() {
	var now = new Date();
	if (!this.date_start) return "current";
	var date_start = +new Date(this.date_start);
	if (date_start > now) return "pending";
	if (!this.date_end) return "current";
	var date_end = +new Date(this.date_end);
	if (date_end && date_end < now) return "expired";
	return "current";
});

LicenseSchema.virtual("__user").set(function (user) {
	this.sender = user;
});

module.exports = mongoose.model('License', LicenseSchema);
<commit_msg>Include discounts with license<commit_after>const mongoose     = require('mongoose');
const Schema       = mongoose.Schema;

const ObjectId = mongoose.Schema.Types.ObjectId;
const Organisation = require("./organisation_model");
const Membership = require("./membership_model");
const Discount = require("./discount_model");
const User = require("./user_model");
const Invoice = require("./invoice_model");
const Space = require("./space_model");
const Location = require("./location_model");
const Claytag = require("./claytag_model");
const LineItem = require("./lineitem_model");
const diff = require('deep-diff').diff;
const Log = require("./log_model");

const LicenseSchema   = new Schema({
	organisation_id: { type: ObjectId, ref: 'Organisation', index: true, required: true },
	membership_id: { type: ObjectId, ref: 'Membership', required: true },
	xero_account: String,
	user_id: { type: ObjectId, ref: 'User', index: true },
	claytag_id: { type: ObjectId, ref: "Claytag" },
	date_created: { type: Date, default: Date.now },
	invoice_id: { type: ObjectId, ref: 'Invoice', index: true },
	space_id: { type: ObjectId, ref: 'Space', index: true },
	location_id: { type: ObjectId, ref: 'Location', index: true },
	lineitem_id: { type: ObjectId, ref: 'LineItem', index: true },
	date_start: Date,
	date_end: Date,
	price: {
		type: Number,
		validate: function(v) {
			return v >= 0;
		},
	},
	discount: { type: Number, default: 0 },
	discount_date_start: Date,
	discount_date_end: Date,
	discount_description: String,
	discount_comment: String,
	_owner_id: ObjectId,
	_deleted: { type: Boolean, default: false, index: true },
}, {
	toObject: {
		virtuals: true
	},
	toJSON: {
		virtuals: true
	},
	timestamps: true
});

LicenseSchema.set("_perms", {
	finance: "crud",
	line_manager: "crud",
	"managers": "cr",
	admin: "r",
	primary_member: "r",
	user: "r"
});

const applyDiscount = (discount, row) => {
	discount = discount || {};
	row._doc.discount_date_start = discount.date_start || null;
	row._doc.discount_date_end = discount.date_end || null;
	row._doc.discount = discount.discount || 0;
	row._doc.discount_comment = discount.comment || "";
	return row;
}

LicenseSchema.post("findOne", async function (row) {
	const discount = await Discount.findOne({ _deleted: false, license_id: row._id });
	console.log({ discount });
	applyDiscount(discount, row);
});

LicenseSchema.post("find", async function(rows, next) {
	const discounts = await Discount.find({ _deleted: false, license_id: { $exists: true } });
	for (let row of rows) {
		const discount = discounts.find(discount => discount.license_id + "" === row._id + "");
		console.log({ discount });
		applyDiscount(discount, row);
	}
	next();
})

// Discounts
LicenseSchema.pre("save", async function () {
	const LineItem = require("./lineitem_model");
	const User = require("./user_model");
	let discount = await Discount.findOne({ license_id: this._id, _deleted: false }).exec();
	let lineitem = await LineItem.findOne({ license_id: this._id, _deleted: false }).exec();
	if ((!this.discount) && (discount)) {
		// Delete existing discount and bail
		discount._deleted = true;
		discount.save();
		return;
	}
	if (!this.discount) return; // No discount to set
	if (discount) {
		// Update existing discount
		let description = "LICENSE - No User";
		if (this.user_id) {
			const user = await User.findOne({ _id: this.user_id });
			description = `LICENSE - ${user.name} (${user.email})`;
		}
		discount.discount = this.discount;
		discount.date_start = this.discount_date_start;
		discount.date_end = this.discount_date_end;
		discount.description = description;
		if (this.discount_comment)
			discount.comment = this.discount_comment;
	} else {
		// Create a new discount
		let description = "LICENSE - No User";
		if (this.user_id) {
			const user = await User.findOne({ _id: this.user_id });
			description = `LICENSE - ${ user.name } (${ user.email })`;
		}
		discount = new Discount({
			discount: this.discount,
			license_id: this._id,
			organisation_id: this.organisation_id,
			date_start: this.discount_date_start,
			date_end: this.discount_date_end,
			comment: this.discount_comment,
			description,
			_owner_id: this.sender._id
		});
		if (lineitem) {
			discount.lineitem_id = lineitem._id;
		}
	}
	await discount.save();
});

LicenseSchema.post("update", async function (doc) {
	console.log({doc});
});

/*
 * Log changes
 */
LicenseSchema.post('validate', function(doc) {
	var self = this;
	var log = null;
	var LicenseModel = mongoose.model('License', LicenseSchema);
	LicenseModel.findOne({ _id: doc._id }, function(err, original) {
		if (!original) {
			log = new Log({
				id: doc._id,
				model: "license",
				level: 3,
				user_id: self.__user,
				title: "License created",
				message: "License created",
				code: "license-create",
				data: doc,
			}).save();
		} else {
			var d = diff(original.toObject(), doc.toObject());
			if (d) {
				log = new Log({
					id: doc._id,
					model: "license",
					level: 3,
					user_id: self.__user,
					title: "License changed",
					message: "License changed",
					code: "license-change",
					data: d,
				}).save();
			}
		}
	});
});

LicenseSchema.virtual("status").get(function() {
	var now = new Date();
	if (!this.date_start) return "current";
	var date_start = +new Date(this.date_start);
	if (date_start > now) return "pending";
	if (!this.date_end) return "current";
	var date_end = +new Date(this.date_end);
	if (date_end && date_end < now) return "expired";
	return "current";
});

LicenseSchema.virtual("__user").set(function (user) {
	this.sender = user;
});

module.exports = mongoose.model('License', LicenseSchema);
<|endoftext|>


<commit_before>let subscriptions = {};

function getSubscriptionsFor(message) {
  if (!subscriptions[message]) subscriptions[message] = [];
  return subscriptions[message];
}

function beforeMessage(message) {
  return `before ${message}`;
}

function afterMessage(message) {
  return `after ${message}`;
}

function on(message, fn) {
  getSubscriptionsFor(message).push(fn);
}

function before(message, fn) {
  on(beforeMessage(message), fn);
}

function after(message, fn) {
  on(afterMessage(message), fn);
}

function off(message, fn) {
  let messages = [beforeMessage(message), message, afterMessage(message)];
  if (fn) {
    for (let i = 0; i < messages.length; i++) {
      let set = getSubscriptionsFor(messages[i]);
      let index = set.indexOf(fn);
      if (index !== -1) {
        set.splice(index, 1);
        break;
      }
    }
  } else {
    messages.forEach(message => getSubscriptionsFor(message).length = 0);
  }
}

function once(message, fn) {
  let subscription = (...args) => {
    off(message, subscription);
    return fn(...args);
  };
  on(message, subscription);
}

function onceBefore(message, fn) {
  return once(beforeMessage(message), fn);
}

function onceAfter(message, fn) {
  return once(afterMessage(message), fn);
}

function createEmitter(data) {
  return message => Promise.all(
    getSubscriptionsFor(message).map(fn => fn(message, data))
  );
}

function emit(message, data) {
  let emit = createEmitter(data);
  return emit(beforeMessage(message))
    .then(() => emit(message))
    .then(() => emit(afterMessage(message)));
}

Object.assign(exports, {
  after, before, emit, off, on, once, onceAfter, onceBefore
});
<commit_msg>Forgot about strict mode for node 4<commit_after>'use strict';

let subscriptions = {};

function getSubscriptionsFor(message) {
  if (!subscriptions[message]) subscriptions[message] = [];
  return subscriptions[message];
}

function beforeMessage(message) {
  return `before ${message}`;
}

function afterMessage(message) {
  return `after ${message}`;
}

function on(message, fn) {
  getSubscriptionsFor(message).push(fn);
}

function before(message, fn) {
  on(beforeMessage(message), fn);
}

function after(message, fn) {
  on(afterMessage(message), fn);
}

function off(message, fn) {
  let messages = [beforeMessage(message), message, afterMessage(message)];
  if (fn) {
    for (let i = 0; i < messages.length; i++) {
      let set = getSubscriptionsFor(messages[i]);
      let index = set.indexOf(fn);
      if (index !== -1) {
        set.splice(index, 1);
        break;
      }
    }
  } else {
    messages.forEach(message => getSubscriptionsFor(message).length = 0);
  }
}

function once(message, fn) {
  let subscription = (...args) => {
    off(message, subscription);
    return fn(...args);
  };
  on(message, subscription);
}

function onceBefore(message, fn) {
  return once(beforeMessage(message), fn);
}

function onceAfter(message, fn) {
  return once(afterMessage(message), fn);
}

function createEmitter(data) {
  return message => Promise.all(
    getSubscriptionsFor(message).map(fn => fn(message, data))
  );
}

function emit(message, data) {
  let emit = createEmitter(data);
  return emit(beforeMessage(message))
    .then(() => emit(message))
    .then(() => emit(afterMessage(message)));
}

Object.assign(exports, {
  after, before, emit, off, on, once, onceAfter, onceBefore
});
<|endoftext|>