<commit_before>/*! linoleum.js - 0.1.6 - Bernard McManus - 2014-04-08 */
!function(){function a(a,b,c,d){function e(a,b){b=b||function(){},$(a).hx(g),$(a).find(".inner").hx(h).done(b)}function f(){var b=a.getIncluded(),c=[];b.forEach(function(a){c.push(new Promise(function(b){e(a,b)}))}),Promise.all(c).then(d.bind(a))}var g=$.extend({type:"transform",translate:b},c),h=$.extend({type:"transform",rotate:{x:1,a:80}},c);f()}function b(a,b,e){function f(d,e,f,g){g=g||function(){};var h=c(a,d,l,b),i={x:f*d.dims.width+b.margin.left*(f+1)+b.margin.right*(f+1)+h,y:e*d.dims.height+b.margin.bottom*e+b.margin.top*(e+1)};d.setHome(i),$(d).hx({type:"transform",translate:i,easing:b.easing,duration:b.duration}),$(d).find(".inner").hx({type:"transform",rotate:null,duration:b.duration,easing:b.easing}).done(g)}function i(){var c=d(a,b);l=h(a,c,k),m=g(a,l);for(var i=0,j=a.getIncluded(),n=[],o=0;m>o;o++)for(var p=0;l>p;p++)i>=a.count()||(n.push(new Promise(function(a){f(j[i],o,p,a)})),i++);Promise.all(n).then(e.bind(a))}e=e||function(){};var j=document.querySelector(a.distroSelector),k=j.getBoundingClientRect(),l=0,m=0;return i(),{Columns:l,Rows:m}}function c(a,b,c,d){var e=document.querySelector(a.distroSelector),f=e.getBoundingClientRect(),g=d.margin.left+d.margin.right;return(f.width-b.dims.width*c-g*(c+1))/2}function d(a,b){var c=b.margin.left+b.margin.right;return a[0].dims.width*a.count()+c*(a.count()+1)}function e(a,b,c){var d=c.margin.top+c.margin.bottom;return a[0].dims.height*b+d*(b+1)}function f(a,b){return b/a.count()}function g(a,b){return Math.ceil(a.count()/b)}function h(a,b,c){for(var d=f(a,b),e=0;e*d<c.width;)e++;return e*d>c.width&&(e-=1),e}var i={enabled:!0,margin:{left:10,right:10,top:10,bottom:10},stackPosition:{x:0,y:0},distroDelay:200,distroSelector:null,duration:300,easing:"ease",tile:{perspective:1e4,thickness:1e-4,modal:{x:null,y:null,z:5e3}}},j={onTileInclude:function(){},onTileExclude:function(){},beforeFilter:function(){},afterFilter:function(){},beforeSort:function(){},afterSort:function(){}};window.linoleum=function(a,b){var c=document.querySelectorAll(a);if(c.length<1)throw"Error: You must pass a valid selector to the linoleum constructor.";$.extend(this,j),this.options=$.extend(!0,i,b||{}),this.listeners={};var d=[];Array.prototype.forEach.call(c,function(a){d.push(new linoleum.tile(a,this.options.tile))}.bind(this));var e=$.extend(d,this);return e.options.enabled?e.enable():e.disable(),e},linoleum.prototype={distribute:function(a,c,d){if(a=a||this.distroSelector,this._setView("distribute")&&!(this.count(!0)<1)){if(!a||""===a)throw"Error: You must pass a valid selector to linoleum.distribute.";this.distroSelector=a;{document.querySelector(a)}if(!document.querySelector(a))throw"Error: You must pass a valid selector to linoleum.distribute.";this._startListen("sizer"),c=$.extend({margin:this.options.margin,duration:this.options.duration,easing:this.options.easing},c||{});var e=b(this,c,function(){this.enable(),this.sizeSizer(),d.call(this)});return this.Columns=e.Columns,this.Rows=e.Rows,this}},stack:function(b,c,d){if(this._setView("stack")){this._stopListen("sizer"),b=$.extend(i.stackPosition,b||{}),c=$.extend({duration:this.options.duration,easing:this.options.easing},c||{}),d=d||function(){};for(var e=null,f=0;f<this.count(!0);f++)if("home"!==this[f].view){e=f;break}return null!==e?this[e].setView("home",c,function(){a(this,b,c,d)}.bind(this)):a(this,b,c,d),this}},sort:function(a){console.log(a)},filter:function(a){a=a||[],this.beforeFilter(),this.forEach(function(b,c){a.indexOf(c)>=0?(b.exclude(),this.onTileExclude(b)):b.isIncluded()||(b.include(),this.onTileInclude(b))}.bind(this)),this.afterFilter()},count:function(a){a="undefined"!=typeof a?a:!1;var b=0;return this.forEach(function(c){(c.isIncluded()||a)&&b++}),b},getIncluded:function(){var a=[];return this.forEach(function(b){b.isIncluded()&&a.push(b)}),a},getExcluded:function(){var a=[];return this.forEach(function(b){b.isIncluded()||a.push(b)}),a},_setView:function(a){return this.view===a?!0:(this._stopListen(this.view),"distribute"===a?this._activate():this._deactivate(),this._startListen(a),this.view=a,!0)},_startListen:function(a){this.listeners[a]||"function"!=typeof k[a]||(this.listeners[a]=k[a].bind(this),l[a].call(this,this.listeners[a]))},_stopListen:function(a){a&&this.listeners[a]&&"function"==typeof k[a]&&(m[a].call(this,this.listeners[a]),delete this.listeners[a])},isEnabled:function(){return this.enabled===!0},enable:function(){this.forEach(function(a){a.enable()}),this.enabled=!0},disable:function(a){this.forEach(function(b){(a||!$(b).hasClass("active"))&&b.disable()}),this.enabled=!1},_activate:function(){$(this).css("pointer-events","")},_deactivate:function(){$(this).css("pointer-events","none")},sizeSizer:function(a){if("undefined"!=typeof this.Rows){a=$.extend({margin:this.options.margin},a||{});var b=document.querySelector(this.distroSelector),c=e(this,this.Rows,a);$(b).children(".sizer").css("height",c+"px")}}};var k={distribute:function(){var a=document.querySelector(this.distroSelector),c=a.getBoundingClientRect(),e=d(this,this.options),f=h(this,e,c);if(this.Columns===f){var g=$.extend({},this.options,{duration:0,fallback:!1});return void b(this,g)}var i=null,j=function(){var a=b(this,i);this.Columns=a.Columns,this.Rows=a.Rows}.bind(this);if(this.options.distroDelay){i=this.options;var k=setTimeout(j,this.options.distroDelay);$(window).on("resize orientationchange",function l(){$(window).off("resize orientationchange",l),clearTimeout(k)})}else i={duration:0,fallback:!1,margin:this.options.margin},$(window).on("resize orientationchange",j)},sizer:function(){function a(a){a="undefined"!=typeof a&&"object"!=typeof a?a:$(window).height()-c.top-$(window).scrollTop(),$(b).children(".sizer").css("min-height",a+"px")}{var b=document.querySelector(this.distroSelector),c=b.getBoundingClientRect();parseInt(getComputedStyle(b).top,10)}a()}},l={distribute:function(a){$(window).on("resize orientationchange",a)},sizer:function(a){$(window).on("resize orientationchange",a),a()}},m={distribute:function(a){$(window).off("resize orientationchange",a)},sizer:function(a){$(window).off("resize orientationchange",a)}}}(),function(a){function b(a){var b=a.getBoundingClientRect(),c={width:parseInt(getComputedStyle(a).width,10),height:parseInt(getComputedStyle(a).height,10),left:b.left,top:b.top};return c.right=c.left+c.width,c.bottom=c.top+c.height,c}function c(a,b,c){$(a).hx({type:"transform",translate:{z:b},rotateY:c||null,duration:0,fallback:!1})}function d(a,b){b=b||{};var c=h[a].call(this,b);return delete b.modal,c.xform.tile=$.extend(c.xform.tile,b),c.xform.inner=$.extend(c.xform.inner,b),c}function e(a,b){var c={x:0,y:0};return a?(b=$.extend(this.modal,b||{}),c.x=null!==b.x?b.x:a.width/2-this.dims.width/2,c.y=null!==b.y?b.y:$(window).height()/2-a.top-this.dims.height/2,c):c}var f={enabled:!0,view:"home",home:{},Include:!0},g=function(a,b){if(!a)throw"Error: You must pass an element to the linoleum.tile constructor.";return $.extend(this,f,b),this._init(a)};g.prototype={_init:function(a){this.dims=b(a),a.style.webkitPerspective=this.perspective+"px",a.style.perspective=this.perspective+"px";var d=$(a).find(".face.front").get(0),e=$(a).find(".face.back").get(0),f=this.thickness*this.perspective/1;return c(d,f),c(e,-f,180),$.extend(a,this)},setView:function(a,b,c){if(this.view!==a&&this.enabled){if("function"!=typeof h[a])throw"Error: linoleum.tile has no view '"+a+"'.";c=c||function(){};var e=d.call(this,a,b);e.callback=e.callback||function(){},$(this).hx(e.xform.tile),$(this).find(".inner").hx(e.xform.inner).done(function(){this.view=a,e.callback.call(this),c.call(this)}.bind(this))}},setHome:function(a){this.home=a},isEnabled:function(){return this.enabled===!0},isIncluded:function(){return this.Include===!0},exclude:function(){this.Include=!1,this.disable()},include:function(){this.Include=!0,this.enable()},enable:function(){this.isIncluded()&&(this.enabled=!0,$(this).css("pointer-events",""))},disable:function(){this.enabled=!1,$(this).css("pointer-events","none")},_activate:function(){$(this).addClass("active")},_deactivate:function(){$(this).removeClass("active")}};var h={home:function(){function a(){this._deactivate()}var b={type:"transform",translate:this.home},c={type:"transform",translate:null,rotate:null};return{callback:a,xform:{tile:b,inner:c}}},modal:function(a){a=a||{};var b=this.parentNode.getBoundingClientRect(),c=e.call(this,b,a.modal),d={type:"transform",translate:c},f=this.modal.z;"undefined"!=typeof a.modal&&"undefined"!=typeof a.modal.z&&(f=a.modal.z);var g={type:"transform",translate:{z:f},rotate:{y:1,a:180}};return this._activate(),{xform:{tile:d,inner:g}}}};$.extend(a,{tile:g})}(linoleum);<commit_msg>updating when sizer is sized<commit_after>/*! linoleum.js - 0.1.6 - Bernard McManus - 2014-04-08 */
!function(){function a(a,b,c,d){function e(a,b){b=b||function(){},$(a).hx(g),$(a).find(".inner").hx(h).done(b)}function f(){var b=a.getIncluded(),c=[];b.forEach(function(a){c.push(new Promise(function(b){e(a,b)}))}),Promise.all(c).then(d.bind(a))}var g=$.extend({type:"transform",translate:b},c),h=$.extend({type:"transform",rotate:{x:1,a:80}},c);f()}function b(a,b,e){function f(d,e,f,g){g=g||function(){};var h=c(a,d,l,b),i={x:f*d.dims.width+b.margin.left*(f+1)+b.margin.right*(f+1)+h,y:e*d.dims.height+b.margin.bottom*e+b.margin.top*(e+1)};d.setHome(i),$(d).hx({type:"transform",translate:i,easing:b.easing,duration:b.duration}),$(d).find(".inner").hx({type:"transform",rotate:null,duration:b.duration,easing:b.easing}).done(g)}function i(){var c=d(a,b);l=h(a,c,k),m=g(a,l);for(var i=0,j=a.getIncluded(),n=[],o=0;m>o;o++)for(var p=0;l>p;p++)i>=a.count()||(n.push(new Promise(function(a){f(j[i],o,p,a)})),i++);Promise.all(n).then(e.bind(a))}e=e||function(){};var j=document.querySelector(a.distroSelector),k=j.getBoundingClientRect(),l=0,m=0;return i(),{Columns:l,Rows:m}}function c(a,b,c,d){var e=document.querySelector(a.distroSelector),f=e.getBoundingClientRect(),g=d.margin.left+d.margin.right;return(f.width-b.dims.width*c-g*(c+1))/2}function d(a,b){var c=b.margin.left+b.margin.right;return a[0].dims.width*a.count()+c*(a.count()+1)}function e(a,b,c){var d=c.margin.top+c.margin.bottom;return a[0].dims.height*b+d*(b+1)}function f(a,b){return b/a.count()}function g(a,b){return Math.ceil(a.count()/b)}function h(a,b,c){for(var d=f(a,b),e=0;e*d<c.width;)e++;return e*d>c.width&&(e-=1),e}var i={enabled:!0,margin:{left:10,right:10,top:10,bottom:10},stackPosition:{x:0,y:0},distroDelay:200,distroSelector:null,duration:300,easing:"ease",tile:{perspective:1e4,thickness:1e-4,modal:{x:null,y:null,z:5e3}}},j={onTileInclude:function(){},onTileExclude:function(){},beforeFilter:function(){},afterFilter:function(){},beforeSort:function(){},afterSort:function(){}};window.linoleum=function(a,b){var c=document.querySelectorAll(a);if(c.length<1)throw"Error: You must pass a valid selector to the linoleum constructor.";$.extend(this,j),this.options=$.extend(!0,i,b||{}),this.listeners={};var d=[];Array.prototype.forEach.call(c,function(a){d.push(new linoleum.tile(a,this.options.tile))}.bind(this));var e=$.extend(d,this);return e.options.enabled?e.enable():e.disable(),e},linoleum.prototype={distribute:function(a,c,d){if(a=a||this.distroSelector,this._setView("distribute")&&!(this.count(!0)<1)){if(!a||""===a)throw"Error: You must pass a valid selector to linoleum.distribute.";this.distroSelector=a;{document.querySelector(a)}if(!document.querySelector(a))throw"Error: You must pass a valid selector to linoleum.distribute.";this._startListen("sizer"),c=$.extend({margin:this.options.margin,duration:this.options.duration,easing:this.options.easing},c||{});var e=b(this,c,function(){this.enable(),d.call(this)});return this.Columns=e.Columns,this.Rows=e.Rows,this.sizeSizer(),this}},stack:function(b,c,d){if(this._setView("stack")){this._stopListen("sizer"),b=$.extend(i.stackPosition,b||{}),c=$.extend({duration:this.options.duration,easing:this.options.easing},c||{}),d=d||function(){};for(var e=null,f=0;f<this.count(!0);f++)if("home"!==this[f].view){e=f;break}return null!==e?this[e].setView("home",c,function(){a(this,b,c,d)}.bind(this)):a(this,b,c,d),this}},sort:function(a){console.log(a)},filter:function(a){a=a||[],this.beforeFilter(),this.forEach(function(b,c){a.indexOf(c)>=0?(b.exclude(),this.onTileExclude(b)):b.isIncluded()||(b.include(),this.onTileInclude(b))}.bind(this)),this.afterFilter()},count:function(a){a="undefined"!=typeof a?a:!1;var b=0;return this.forEach(function(c){(c.isIncluded()||a)&&b++}),b},getIncluded:function(){var a=[];return this.forEach(function(b){b.isIncluded()&&a.push(b)}),a},getExcluded:function(){var a=[];return this.forEach(function(b){b.isIncluded()||a.push(b)}),a},_setView:function(a){return this.view===a?!0:(this._stopListen(this.view),"distribute"===a?this._activate():this._deactivate(),this._startListen(a),this.view=a,!0)},_startListen:function(a){this.listeners[a]||"function"!=typeof k[a]||(this.listeners[a]=k[a].bind(this),l[a].call(this,this.listeners[a]))},_stopListen:function(a){a&&this.listeners[a]&&"function"==typeof k[a]&&(m[a].call(this,this.listeners[a]),delete this.listeners[a])},isEnabled:function(){return this.enabled===!0},enable:function(){this.forEach(function(a){a.enable()}),this.enabled=!0},disable:function(a){this.forEach(function(b){(a||!$(b).hasClass("active"))&&b.disable()}),this.enabled=!1},_activate:function(){$(this).css("pointer-events","")},_deactivate:function(){$(this).css("pointer-events","none")},sizeSizer:function(a){if("undefined"!=typeof this.Rows){a=$.extend({margin:this.options.margin},a||{});var b=document.querySelector(this.distroSelector),c=e(this,this.Rows,a);$(b).children(".sizer").css("height",c+"px")}}};var k={distribute:function(){var a=document.querySelector(this.distroSelector),c=a.getBoundingClientRect(),e=d(this,this.options),f=h(this,e,c);if(this.Columns===f){var g=$.extend({},this.options,{duration:0,fallback:!1});return void b(this,g)}var i=null,j=function(){var a=b(this,i);this.Columns=a.Columns,this.Rows=a.Rows,this.sizeSizer()}.bind(this);if(this.options.distroDelay){i=this.options;var k=setTimeout(j,this.options.distroDelay);$(window).on("resize orientationchange",function l(){$(window).off("resize orientationchange",l),clearTimeout(k)})}else i={duration:0,fallback:!1,margin:this.options.margin},$(window).on("resize orientationchange",j)},sizer:function(){function a(a){a="undefined"!=typeof a&&"object"!=typeof a?a:$(window).height()-c.top-$(window).scrollTop(),$(b).children(".sizer").css("min-height",a+"px")}{var b=document.querySelector(this.distroSelector),c=b.getBoundingClientRect();parseInt(getComputedStyle(b).top,10)}a()}},l={distribute:function(a){$(window).on("resize orientationchange",a)},sizer:function(a){$(window).on("resize orientationchange",a),a()}},m={distribute:function(a){$(window).off("resize orientationchange",a)},sizer:function(a){$(window).off("resize orientationchange",a)}}}(),function(a){function b(a){var b=a.getBoundingClientRect(),c={width:parseInt(getComputedStyle(a).width,10),height:parseInt(getComputedStyle(a).height,10),left:b.left,top:b.top};return c.right=c.left+c.width,c.bottom=c.top+c.height,c}function c(a,b,c){$(a).hx({type:"transform",translate:{z:b},rotateY:c||null,duration:0,fallback:!1})}function d(a,b){b=b||{};var c=h[a].call(this,b);return delete b.modal,c.xform.tile=$.extend(c.xform.tile,b),c.xform.inner=$.extend(c.xform.inner,b),c}function e(a,b){var c={x:0,y:0};return a?(b=$.extend(this.modal,b||{}),c.x=null!==b.x?b.x:a.width/2-this.dims.width/2,c.y=null!==b.y?b.y:$(window).height()/2-a.top-this.dims.height/2,c):c}var f={enabled:!0,view:"home",home:{},Include:!0},g=function(a,b){if(!a)throw"Error: You must pass an element to the linoleum.tile constructor.";return $.extend(this,f,b),this._init(a)};g.prototype={_init:function(a){this.dims=b(a),a.style.webkitPerspective=this.perspective+"px",a.style.perspective=this.perspective+"px";var d=$(a).find(".face.front").get(0),e=$(a).find(".face.back").get(0),f=this.thickness*this.perspective/1;return c(d,f),c(e,-f,180),$.extend(a,this)},setView:function(a,b,c){if(this.view!==a&&this.enabled){if("function"!=typeof h[a])throw"Error: linoleum.tile has no view '"+a+"'.";c=c||function(){};var e=d.call(this,a,b);e.callback=e.callback||function(){},$(this).hx(e.xform.tile),$(this).find(".inner").hx(e.xform.inner).done(function(){this.view=a,e.callback.call(this),c.call(this)}.bind(this))}},setHome:function(a){this.home=a},isEnabled:function(){return this.enabled===!0},isIncluded:function(){return this.Include===!0},exclude:function(){this.Include=!1,this.disable()},include:function(){this.Include=!0,this.enable()},enable:function(){this.isIncluded()&&(this.enabled=!0,$(this).css("pointer-events",""))},disable:function(){this.enabled=!1,$(this).css("pointer-events","none")},_activate:function(){$(this).addClass("active")},_deactivate:function(){$(this).removeClass("active")}};var h={home:function(){function a(){this._deactivate()}var b={type:"transform",translate:this.home},c={type:"transform",translate:null,rotate:null};return{callback:a,xform:{tile:b,inner:c}}},modal:function(a){a=a||{};var b=this.parentNode.getBoundingClientRect(),c=e.call(this,b,a.modal),d={type:"transform",translate:c},f=this.modal.z;"undefined"!=typeof a.modal&&"undefined"!=typeof a.modal.z&&(f=a.modal.z);var g={type:"transform",translate:{z:f},rotate:{y:1,a:180}};return this._activate(),{xform:{tile:d,inner:g}}}};$.extend(a,{tile:g})}(linoleum);<|endoftext|>


<commit_before>require('cloud/app.js');
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("hello", function(request, response) {
  	response.success("Hello world!");
});

// Send push to users from determined location
// TODO: add more fields: https://www.parse.com/docs/js/guide#push-notifications-sending-options
Parse.Cloud.define("sendPushToLocation", function(request, response) {
  	var userObjectId = request.params.userObjectId;

  	// FIXME: this is only temporary. We need to find a way to do this with roles!
  	if(userObjectId != "dpbBxLtkMY" && userObjectId != "4r1i9gZkYD") {
  		response.error("Permission denied! User is not an admin.");
  		return;
  	}

	var latitude = request.params.latitude;
	var longitude = request.params.longitude;
	if(latitude != null && longitude != null) {
		var locationGeoPoint = new Parse.GeoPoint({latitude: latitude, longitude: longitude});
	}

	// Validate the message text.
	var message = request.params.message;

	// Make sure it is under 140 characters
	if (message.length > 140) {
		// Truncate and add a ...
		message = message.substring(0, 137) + "...";
	}

	var title = request.params.title;
	var uri = request.params.uri;
	var recipientUserId = request.params.recipientId;

	// Push query
	var pushQuery = new Parse.Query(Parse.Installation);

	if(recipientUserId != null) {
		var recipientUser = new Parse.User();
		recipientUser.id = recipientUserId;
		pushQuery.equalTo("user", recipientUser);
	}
	else if(locationGeoPoint != null) {
		// Find users near given location (100 miles)
		var userQuery = new Parse.Query(Parse.User);
		userQuery.withinMiles("location", locationGeoPoint, 100.0);
		pushQuery.matchesQuery('user', userQuery);
		// TODO: confirm that this works with more than 1000 users!
	}

	// Send the push notification to results of the query
	Parse.Push.send({
		where: pushQuery,
		data: {
	 		alert: message, // the notification's message.
	 		title: title, //(Android, Windows 8, & Windows Phone 8 only) the value displayed in the Android system tray or Windows 8 toast notification.
	 		uri: uri // (Android only) an optional field that contains a URI. When the notification is opened, an Activity associated with opening the URI is launched.
		}
	}).then(function() {
	 	response.success("Push foi enviado com sucesso!");
	}, function(error) {
	 	response.error("Falha ao enviar o push: " + error.message);
	});
});
<commit_msg>Added event object id to push<commit_after>require('cloud/app.js');
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("hello", function(request, response) {
  	response.success("Hello world!");
});

// Send push to users from determined location
// TODO: add more fields: https://www.parse.com/docs/js/guide#push-notifications-sending-options
Parse.Cloud.define("sendPushToLocation", function(request, response) {
  	var userObjectId = request.params.userObjectId;

  	// FIXME: this is only temporary. We need to find a way to do this with roles!
  	if(userObjectId != "dpbBxLtkMY" && userObjectId != "4r1i9gZkYD") {
  		response.error("Permission denied! User is not an admin.");
  		return;
  	}

	var latitude = request.params.latitude;
	var longitude = request.params.longitude;
	if(latitude != null && longitude != null) {
		var locationGeoPoint = new Parse.GeoPoint({latitude: latitude, longitude: longitude});
	}

	// Validate the message text.
	var message = request.params.message;

	// Make sure it is under 140 characters
	if (message.length > 140) {
		// Truncate and add a ...
		message = message.substring(0, 137) + "...";
	}

	var title = request.params.title;
	var uri = request.params.uri;
	var recipientUserId = request.params.recipientId;
	var eventObjectId = request.params.eventObjectId;

	// Push query
	var pushQuery = new Parse.Query(Parse.Installation);

	if(recipientUserId != null) {
		var recipientUser = new Parse.User();
		recipientUser.id = recipientUserId;
		pushQuery.equalTo("user", recipientUser);
	}
	else if(locationGeoPoint != null) {
		// Find users near given location (100 miles)
		var userQuery = new Parse.Query(Parse.User);
		userQuery.withinMiles("location", locationGeoPoint, 100.0);
		pushQuery.matchesQuery('user', userQuery);
		// TODO: confirm that this works with more than 1000 users!
	}

	// Send the push notification to results of the query
	Parse.Push.send({
		where: pushQuery,
		data: {
	 		alert: message, // the notification's message.
	 		title: title, //(Android, Windows 8, & Windows Phone 8 only) the value displayed in the Android system tray or Windows 8 toast notification.
	 		uri: uri, // (Android only) an optional field that contains a URI. When the notification is opened, an Activity associated with opening the URI is launched.
	 		eventObjectId: eventObjectId
		}
	}).then(function() {
	 	response.success("Push foi enviado com sucesso!");
	}, function(error) {
	 	response.error("Falha ao enviar o push: " + error.message);
	});
});
<|endoftext|>


<commit_before>var chalk = require("chalk");
var ERROR = chalk.bold.red;

function die() {
    var msg = [].join.call(arguments, " ");
    console.error(ERROR(msg));
    process.exit(1);
}

module.exports = die;
<commit_msg>Addec blank line to match style<commit_after>var chalk = require("chalk");

var ERROR = chalk.bold.red;

function die() {
    var msg = [].join.call(arguments, " ");
    console.error(ERROR(msg));
    process.exit(1);
}

module.exports = die;
<|endoftext|>


<commit_before>var app = angular.module('odin.fileControllers', ['ngFileUpload']);

app.factory('model', function($resource) {
    return $resource();
});

function FileListController($scope, $location, rest, $rootScope, Flash, Alertify, $routeParams, modelService) {

    modelService.initService("File", "files", $scope);

    $scope.filtersView = [{
        name: 'Estado',
        model: 'statuses',
        key: 'name',
        modelInput: 'status',
        multiple: true
    }, {
        name: 'Autor',
        model: 'users',
        key: 'username',
        modelInput: 'owner',
        multiple: false
    }];
    $scope.confirmDelete = function(item) {
        modelService.confirmDelete(item);
    }

    $scope.deleteModel = function(model) {
        modelService.delete($scope, model);
    };

    $scope.edit = function(model) {
        modelService.edit($scope, model);
    }

    $scope.view = function(model) {
        modelService.view($scope, model);
    }

    modelService.loadAll($scope);
}

function FileViewController($scope, Flash, rest, $routeParams, $location, modelService) {
    modelService.initService("File", "files", $scope);

    modelService.findOne($routeParams, $scope);

    $scope.edit = function(model) {
        modelService.edit($scope, model);
    }
}

function FileCreateController($scope, $sce, rest, model, Flash, $location, Upload, $rootScope, modelService) {
    modelService.initService("File", "files", $scope);

    $scope.readURL = function(input) {

        if (input.files && input.files[0]) {
            var reader = new FileReader();

            reader.onload = function(e) {
                console.log(e);
                // $('#blah').attr('src', e.target.result);
            }

            //  reader.readAsDataURL(input.files[0]);
        }
    }

    $scope.clearUpload = function() {
        $scope.fileModel.name = "";
        $scope.fileModel.type = "";
    }

    $scope.beforeChange = function($files) {
        $scope.fileModel.name = $files[0].name;
        var type = $files[0].name.split('.').pop();
        if (type == "doc" || type == "docx") {
            $scope.fileModel.type = 'fa-file-word-o';
        } else if (type == "xlsx" || type == "xls") {
            $scope.fileModel.type = 'fa-file-excel-o';
        } else if (type == "pdf") {
            $scope.fileModel.type = 'fa-file-pdf-o';
        } else if (type == "rar" || type == "zip") {
            $scope.fileModel.type = 'fa-file-archive-o';
        } else {
            $scope.fileModel.type = 'fa-file-text-o';
        }
    }
    $scope.model = new model();
    $scope.steps = [];
    $scope.steps[0] = "active";
    $scope.steps[1] = "undone";
    $scope.steps[2] = "undone";
    $scope.stepactive = 0;

    $scope.fileModel = []
    $scope.checkstep = function(step) {
        if (($scope.fileModel.name && step == 1) || ($scope.fileModel.name && step == 2) || step == 0) {

            if (step == 0) {
                $scope.steps[0] = "active";
                $scope.steps[1] = "undone";
                $scope.steps[2] = "undone";
            } else if (step == 1) {
                $scope.steps[0] = "done";
                $scope.steps[1] = "active";
                $scope.steps[2] = "undone";
            } else {
                $scope.steps[0] = "done";
                $scope.steps[1] = "done";
                $scope.steps[2] = "active";
            }
            console.log(step);
            $scope.stepactive = step;
        }
    }
    $scope.step = function(step) {
        if (($scope.fileModel.name && step == 1) || ($scope.fileModel.name && step == 2) || step == 0) {
            var step = $scope.steps[step];
            if (step == "undone") {
                return "undone";
            } else if (step == "done") {
                return "done";
            } else {
                return "active";

            }
        }

    }
    $scope.getHtml = function(html) {
        return $sce.trustAsHtml(html);
    };

    $scope.addTag= function (name){
        $rootScope.model.filetypes = rest().save({
            type: "filetypes"
        },{name:name},function (){
            console.log("tag agregado");
        });
    }

    $scope.add = function(isValid) {
        $scope.uploadImageProgress = 10;
        var data = {
            'name': $scope.model.name,
            'type': $scope.model.type,
            'status': $scope.model.status,
            'organization': $scope.model.organization,
            'dataset': $scope.model.dataset,
            'description': $scope.model.description,
            'notes': $scope.model.notes,
            'url': $scope.model.url,
            'visibility': $scope.model.visibility,

            'uploadFile': $scope.model.uploadFile
        }

        Upload.upload({
            url: $rootScope.url + "/files",
            data: data
        }).then(function(resp) {
            var url = '/' + $scope.type;
            $location.path(url);
        }, function(resp) {
            alert(resp.status);
        }, function(evt) {
            console.log(evt.config._file.name);
            //var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
            //$scope.uploadImageProgress=progressPercentage;
        });
    };

    /*$scope.model.filetypes = rest().get({
        type: "filetypes" ,params:"sort=name DESC"
    });
    $scope.model.statuses = rest().get({
        type: "statuses" ,params:"sort=name DESC"
    });
  /*  $scope.model.organizations = rest().get({
        type: "organizations" ,params:"sort=name DESC"
    });
    $scope.model.frequencies = rest().get({
        type: "updatefrequencies" ,params:"sort=name DESC"
    });
    $scope.tagsmodel = rest().get({
        type: "tags" ,params:"sort=name DESC"
    });*/

}

function FileEditController($scope, Flash, rest, $routeParams, model, $location, modelService) {
    modelService.initService("File", "files", $scope);

    $scope.model = new model();
    $scope.update = function(isValid) {
        if (isValid) {
            rest().update({
                type: $scope.type,
                id: $scope.model.id
            }, $scope.model, function(resp) {
                var url = '/' + $scope.type;
                $location.path(url);
            });
        }
    };

    $scope.load = function() {
        $scope.model = rest().findOne({
            id: $routeParams.id,
            type: $scope.type
        });
    };

    $scope.load();
}<commit_msg>Update fileController.js<commit_after>var app = angular.module('odin.fileControllers', ['ngFileUpload']);

app.factory('model', function($resource) {
    return $resource();
});

function FileListController($scope, $location, rest, $rootScope, Flash, Alertify, $routeParams, modelService) {

    modelService.initService("File", "files", $scope);

    $scope.filtersView = [{
        name: 'Estado',
        model: 'statuses',
        key: 'name',
        modelInput: 'status',
        multiple: true
    }, {
        name: 'Autor',
        model: 'users',
        key: 'username',
        modelInput: 'owner',
        multiple: false
    }];
    $scope.confirmDelete = function(item) {
        modelService.confirmDelete(item);
    }

    $scope.deleteModel = function(model) {
        modelService.delete($scope, model);
    };

    $scope.edit = function(model) {
        modelService.edit($scope, model);
    }

    $scope.view = function(model) {
        modelService.view($scope, model);
    }

    modelService.loadAll($scope);
}

function FileViewController($scope, Flash, rest, $routeParams, $location, modelService) {
    modelService.initService("File", "files", $scope);

    modelService.findOne($routeParams, $scope);

    $scope.edit = function(model) {
        modelService.edit($scope, model);
    }
}

function FileCreateController($scope, $sce, rest, model, Flash, $location, Upload, $rootScope, modelService) {
    modelService.initService("File", "files", $scope);

    $scope.readURL = function(input) {

        if (input.files && input.files[0]) {
            var reader = new FileReader();

            reader.onload = function(e) {
                console.log(e);
                // $('#blah').attr('src', e.target.result);
            }

            //  reader.readAsDataURL(input.files[0]);
        }
    }

    $scope.clearUpload = function() {
        $scope.fileModel.name = "";
        $scope.fileModel.type = "";
    }

    $scope.beforeChange = function($files) {
        $scope.fileModel.name = $files[0].name;
        var type = $files[0].name.split('.').pop();
        if (type == "doc" || type == "docx") {
            $scope.fileModel.type = 'fa-file-word-o';
        } else if (type == "xlsx" || type == "xls") {
            $scope.fileModel.type = 'fa-file-excel-o';
        } else if (type == "pdf") {
            $scope.fileModel.type = 'fa-file-pdf-o';
        } else if (type == "rar" || type == "zip") {
            $scope.fileModel.type = 'fa-file-archive-o';
        } else {
            $scope.fileModel.type = 'fa-file-text-o';
        }
    }
    $scope.model = new model();
    $scope.steps = [];
    $scope.steps[0] = "active";
    $scope.steps[1] = "undone";
    $scope.steps[2] = "undone";
    $scope.stepactive = 0;

    $scope.fileModel = []
    $scope.checkstep = function(step) {
        if (($scope.fileModel.name && step == 1) || ($scope.fileModel.name && step == 2) || step == 0) {

            if (step == 0) {
                $scope.steps[0] = "active";
                $scope.steps[1] = "undone";
                $scope.steps[2] = "undone";
            } else if (step == 1) {
                $scope.steps[0] = "done";
                $scope.steps[1] = "active";
                $scope.steps[2] = "undone";
            } else {
                $scope.steps[0] = "done";
                $scope.steps[1] = "done";
                $scope.steps[2] = "active";
            }
            console.log(step);
            $scope.stepactive = step;
        }
    }
    $scope.step = function(step) {
        if (($scope.fileModel.name && step == 1) || ($scope.fileModel.name && step == 2) || step == 0) {
            var step = $scope.steps[step];
            if (step == "undone") {
                return "undone";
            } else if (step == "done") {
                return "done";
            } else {
                return "active";

            }
        }

    }
    $scope.getHtml = function(html) {
        return $sce.trustAsHtml(html);
    };

    $scope.addTag= function (name){
        $rootScope.model.filetypes = rest().save({
            type: "filetypes"
        },{name:name},function (){
            console.log("tag agregado");
        });
    }

    $scope.add = function(isValid) {
        $scope.uploadImageProgress = 10;
        var data = {
            'name': $scope.model.name,
            'type': $scope.model.type,
            'status': $scope.model.status,
            'organization': $scope.model.organization,
            'dataset': $scope.model.dataset,
            'description': $scope.model.description,
            'notes': $scope.model.notes,
            'url': $scope.model.url,
            'visibility': $scope.model.visibility,
            ///'fileType':$scope.fileModel.type,
            'uploadFile': $scope.model.uploadFile
        }

        Upload.upload({
            url: $rootScope.url + "/files",
            data: data
        }).then(function(resp) {
            var url = '/' + $scope.type;
            $location.path(url);
        }, function(resp) {
            alert(resp.status);
        }, function(evt) {
            var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
            $scope.uploadImageProgress=progressPercentage;
        });
    };

    /*$scope.model.filetypes = rest().get({
        type: "filetypes" ,params:"sort=name DESC"
    });
    $scope.model.statuses = rest().get({
        type: "statuses" ,params:"sort=name DESC"
    });
  /*  $scope.model.organizations = rest().get({
        type: "organizations" ,params:"sort=name DESC"
    });
    $scope.model.frequencies = rest().get({
        type: "updatefrequencies" ,params:"sort=name DESC"
    });
    $scope.tagsmodel = rest().get({
        type: "tags" ,params:"sort=name DESC"
    });*/

}

function FileEditController($scope, Flash, rest, $routeParams, model, $location, modelService) {
    modelService.initService("File", "files", $scope);

    $scope.model = new model();
    $scope.update = function(isValid) {
        if (isValid) {
            rest().update({
                type: $scope.type,
                id: $scope.model.id
            }, $scope.model, function(resp) {
                var url = '/' + $scope.type;
                $location.path(url);
            });
        }
    };

    $scope.load = function() {
        $scope.model = rest().findOne({
            id: $routeParams.id,
            type: $scope.type
        });
    };

    $scope.load();
}
<|endoftext|>


<commit_before>/**
* Connect to a MongoDB
* Read files in collections
*
* @author Bob van der Valk
*/
use("mongodb.js");

print("start");

var mongoConnector = new MongoConnector("local");
mongoConnector.setHost("localhost");
mongoConnector.connect();

var input = "{name: \"John Doe\", company: \"Mawoo\"}";

mongoConnector.getCollection("test_collection").insertOne(input);<commit_msg>Find data in MongDB collection<commit_after>/**
 * Find data in a MongoDB collection
 *
 * @author Bob van der Valk
 */
use("MongoDB");

var mongo = MongoDB.setDatabase("local").connect();

var collection = mongo.getCollection("test_collection");
var find = collection.find("{ company: \"Mawoo\"}");

while(find.hasNext()) {
    info(find.next());
}

mongo.close();
<|endoftext|>


<commit_before>/**
 *changes the text color on a click event
 **/
function clickEvent() {
	document.getElementById("click").style.Color = "blue";
}
/**
 *changes the background color when moused over
 **/
<commit_msg>1st paragraph<commit_after>/**
 *changes the background color on a click event
 **/
function clickEvent() {
	document.getElementById("click").style.backgroundColor = "blue";
}
/**
 *changes the background color when moused over
 **/
<|endoftext|>


<commit_before>// PLUGIN HOOKS ////////////////////////////////////////////////////////
// Plugins may listen to any number of events by specifying the name of
// the event to listen to and handing a function that should be exe-
// cuted when an event occurs. Callbacks will receive additional data
// the event created as their first parameter. The value is always a
// hash that contains more details.
//
// For example, this line will listen for portals to be added and print
// the data generated by the event to the console:
// window.addHook('portalAdded', function(data) { console.log(data) });
//
// Boot hook: booting is handled differently because IITC may not yet
//            be available. Have a look at the plugins in plugins/. All
//            code before “// PLUGIN START” and after “// PLUGIN END” is
//            required to successfully boot the plugin.
//
// Here’s more specific information about each event:
// portalAdded: called when a portal has been received and is about to
//              be added to its layer group. Note that this does NOT
//              mean it is already visible or will be, shortly after.
//              If a portal is added to a hidden layer it may never be
//              shown at all. Injection point is in
//              code/map_data.js#renderPortal near the end. Will hand
//              the Leaflet CircleMarker for the portal in "portal" var.
// portalDetailsUpdated: fired after the details in the sidebar have
//              been (re-)rendered Provides data about the portal that
//              has been selected.
// publicChatDataAvailable: this hook runs after data for any of the
//              public chats has been received and processed, but not
//              yet been displayed. The data hash contains both the un-
//              processed raw ajax response as well as the processed
//              chat data that is going to be used for display.
// factionChatDataAvailable: this hook runs after data for the faction
//              chat has been received and processed, but not yet been
//              displayed. The data hash contains both the unprocessed
//              raw ajax response as well as the processed chat data
//              that is going to be used for display.
// portalDataLoaded: callback is passed the argument of
//              {portals : [portal, portal, ...]} where "portal" is the
//              data element and not the leaflet object. "portal" is an
//              array [GUID, time, details]. Plugin can manipulate the
//              array to change order or add additional values to the
//              details of a portal.
// beforePortalReRender: the callback argument is
//              {portal: ent[2], oldPortal : d, reRender : false}.
//              The callback needs to update the value of reRender to
//              true if the plugin has a reason to have the portal
//              redrawn. It is called early on in the
//              code/map_data.js#renderPortal as long as there was an
//              old portal for the guid.
// checkRenderLimit: callback is passed the argument of
//              {reached : false} to indicate that the renderlimit is reached
//              set reached to true.
// requestFinished: called after each request finished. Argument is
//              {success: boolean} indicated the request success or fail.

window._hooks = {}
window.VALID_HOOKS = ['portalAdded', 'portalDetailsUpdated',
  'publicChatDataAvailable', 'factionChatDataAvailable', 'portalDataLoaded',
  'beforePortalReRender', 'checkRenderLimit', 'requestFinished', 'nicknameClicked',
  'geoSearch'];

window.runHooks = function(event, data) {
  if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);

  if(!_hooks[event]) return;
  var interupted = false;
  $.each(_hooks[event], function(ind, callback) {
    if (callback(data) === false) {
      interupted = true;
      return false;
    }
  });
  return !interupted;
}

window.addHook = function(event, callback) {
  if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);
  if(typeof callback !== 'function') throw('Callback must be a function.');

  if(!_hooks[event])
    _hooks[event] = [callback];
  else
    _hooks[event].push(callback);
}
<commit_msg>Fix click on player name in chat doing nothing<commit_after>// PLUGIN HOOKS ////////////////////////////////////////////////////////
// Plugins may listen to any number of events by specifying the name of
// the event to listen to and handing a function that should be exe-
// cuted when an event occurs. Callbacks will receive additional data
// the event created as their first parameter. The value is always a
// hash that contains more details.
//
// For example, this line will listen for portals to be added and print
// the data generated by the event to the console:
// window.addHook('portalAdded', function(data) { console.log(data) });
//
// Boot hook: booting is handled differently because IITC may not yet
//            be available. Have a look at the plugins in plugins/. All
//            code before “// PLUGIN START” and after “// PLUGIN END” is
//            required to successfully boot the plugin.
//
// Here’s more specific information about each event:
// portalAdded: called when a portal has been received and is about to
//              be added to its layer group. Note that this does NOT
//              mean it is already visible or will be, shortly after.
//              If a portal is added to a hidden layer it may never be
//              shown at all. Injection point is in
//              code/map_data.js#renderPortal near the end. Will hand
//              the Leaflet CircleMarker for the portal in "portal" var.
// portalDetailsUpdated: fired after the details in the sidebar have
//              been (re-)rendered Provides data about the portal that
//              has been selected.
// publicChatDataAvailable: this hook runs after data for any of the
//              public chats has been received and processed, but not
//              yet been displayed. The data hash contains both the un-
//              processed raw ajax response as well as the processed
//              chat data that is going to be used for display.
// factionChatDataAvailable: this hook runs after data for the faction
//              chat has been received and processed, but not yet been
//              displayed. The data hash contains both the unprocessed
//              raw ajax response as well as the processed chat data
//              that is going to be used for display.
// portalDataLoaded: callback is passed the argument of
//              {portals : [portal, portal, ...]} where "portal" is the
//              data element and not the leaflet object. "portal" is an
//              array [GUID, time, details]. Plugin can manipulate the
//              array to change order or add additional values to the
//              details of a portal.
// beforePortalReRender: the callback argument is
//              {portal: ent[2], oldPortal : d, reRender : false}.
//              The callback needs to update the value of reRender to
//              true if the plugin has a reason to have the portal
//              redrawn. It is called early on in the
//              code/map_data.js#renderPortal as long as there was an
//              old portal for the guid.
// checkRenderLimit: callback is passed the argument of
//              {reached : false} to indicate that the renderlimit is reached
//              set reached to true.
// requestFinished: called after each request finished. Argument is
//              {success: boolean} indicated the request success or fail.

window._hooks = {}
window.VALID_HOOKS = ['portalAdded', 'portalDetailsUpdated',
  'publicChatDataAvailable', 'factionChatDataAvailable', 'portalDataLoaded',
  'beforePortalReRender', 'checkRenderLimit', 'requestFinished', 'nicknameClicked',
  'geoSearch'];

window.runHooks = function(event, data) {
  if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);

  if(!_hooks[event]) return true;
  var interupted = false;
  $.each(_hooks[event], function(ind, callback) {
    if (callback(data) === false) {
      interupted = true;
      return false;
    }
  });
  return !interupted;
}

window.addHook = function(event, callback) {
  if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event);
  if(typeof callback !== 'function') throw('Callback must be a function.');

  if(!_hooks[event])
    _hooks[event] = [callback];
  else
    _hooks[event].push(callback);
}
<|endoftext|>


<commit_before>/*
	Requirement insertion
*/
$(document).on("click", "#requirementInsert", function() {
	if(formIsValid('requirementInsertion')) {
		var data = [
			$('#dad').val(),
			$('#importance').val(),
			$('#type').val(),
			$('#source').val(),
			$('#description').val()
		];
		sent('requirements', 'insert', data);
		$('#requirementInsertion').closeModal();
	}
});
/*
	Requirement delete
*/
$(document).on("click", "#requirementDelete", function() {
	var data = [$("#id").text()];
	sent('requirements', 'delete', data);
});
/*
	Requirement update
*/
$(document).on("click", "#requirementUpdate", function() {
	if(formIsValid('requirementUpdate')) {
		var data = [
			$('#id').text(),
			$('#description').val(),
			$('#importance').val(),
			$('#type').val(),
			$("#source").val(),
			$("#satisfied").val()
		];
		sent('requirements', 'update', data);
	}
});
/*
	Requirement child delete
*/
$(document).on("click", ".requirementChildDelete", function() {
	var data = [$(this).parent().parent().attr('id')];
	sent('requirements', 'childDelete', data);
	$(this).parent().parent().remove();
});
/*
	Requirement class combine
*/
$(document).on("click", "#requirementClassCombine", function() {
	if(formIsValid('requirementClass')) {
		var data = [
			$("#id").text(),
			$("#requirementClassName").val()
		];
		sent('requirements', 'classCombine', data);
		$("#requirementClassName option[value='" + data[1] + "']").remove();
		$('select').material_select();
		$("#requirementClassList").append("
delete" + data[1] + "
");
	}
});
/*
	Requirement class delete
*/
$(document).on("click", ".requirementClassDelete", function() {
	var data = [
		$("#id").text(),
		$(this).parent().parent().attr('id')
	];
	sent('requirements', 'classDelete', data);
	$(this).parent().parent().remove();
	$("#requirementClassName").append("<option value=" + data[1] + ">" + data[1] + "</option>");
	$('select').material_select();
});
/*
	Requirement package combine
*/
$(document).on("click", "#requirementPackageCombine", function() {
	if(formIsValid('requirementPackage')) {
		var data = [
			$("#id").text(),
			$("#requirementPackageName").val()
		];
		sent('requirements', 'packageCombine', data);
		$("#requirementPackageName option[value='" + data[1] + "']").remove();
		$('select').material_select();
		$("#requirementPackageList").append("
delete" + data[1] + "
");
	}
});
/*
	Requirement package delete
*/
$(document).on("click", ".requirementPackageDelete", function() {
	var data = [
		$("#id").text(),
		$(this).parent().parent().attr('id')
	];
	sent('requirements', 'packageDelete', data);
	$(this).parent().parent().remove();
	$("#requirementPackageName").append("<option value=" + data[1] + ">" + data[1] + "</option>");
	$('select').material_select();
});
/*
	Requirement systemTest insert
*/
$(document).on("click", "#requirementSystemTestInsert", function() {
	if(formIsValid('requirementSystemTest')) {
		var data = [
			$("#id").text(),
			$("#systemTestDescription").val(),
			$("#systemTestImplemented").val(),
			$("#systemTestSatisfied").val()
		];
		sent('requirements', 'systemTestInsert', data);
		$("#requirementSystemTestInsert").attr('id', 'requirementSystemTestUpdate').html('UPDATE');
	}
});
/*
	Requirement systemTest udpate
*/
$(document).on("click", "#requirementSystemTestUpdate", function() {
	if(formIsValid('requirementSystemTest')) {
		var data = [
			$("#id").text(),
			$("#systemTestDescription").val(),
			$("#systemTestImplemented").val(),
			$("#systemTestSatisfied").val()
		];
		sent('requirements', 'systemTestUpdate', data);
	}
});
/*
	Requirement usecase combine
*/
$(document).on("click", "#requirementUsecaseCombine", function() {
	if(formIsValid('requirementUsecase')) {
		var data = [
			$("#id").text(),
			$("#requirementUsecaseName").val()
		];
		sent('requirements', 'usecaseCombine', data);
		$("#requirementUsecaseList").append("
delete" + $("#requirementUsecaseName option:selected").text() + "
");
		$("#requirementUsecaseName option[value='" + data[1] + "']").remove();
		$('select').material_select();
	}
});
/*
	Requirement usecase delete
*/
$(document).on("click", ".requirementUsecaseDelete", function() {
	var data = [
		$("#id").text(),
		$(this).parent().parent().attr('id')
	];
	sent('requirements', 'usecaseDelete', data);
	$(this).parent().parent().remove();
	$("#requirementUsecaseName").append("<option value=" + data[1] + ">" + text + "</option>");
	$('select').material_select();
});

$(document).on("click", "#requirementValidationTestAddStep", function() {
	var n = $("#requirementValidationTests .step").length;
	if(n == 0) {
		n++;
		$("#requirementValidationTestAddStep").after("

" + n + "°
delete<input class='col s10' type='text'>
");
	}
	else {
		n++;
		$("#requirementValidationTests .step").last().after("

" + n + "°
delete<input class='col s10' type='text'>
");
	}
});

$(document).on("click", ".stepDelete", function() {
	$(this).parent().remove();
	var n = $("requirementValidationTests .step").length;
	$("#requirementValidationTests .step").each(function(i) {
		$(this).children('p').eq(0).replaceWith("
" + (i+1) + "°
");
	});
});

$(document).on("click", "#requirementValidationTestInsertion, #requirementValidationTestUpdate", function() {
	if(formIsValid('requirementValidationTests')) {
		// remove previous test saved
		var data = [
			$("#id").text()
		];
		sent('requirements', 'validationTestDelete', data);

		// inset new test or updated test
		var data = [
			$("#id").text(),
			'TV' + $("#id").text().substr(1),
			$("#requirementValidationTestDescription").val(),
			$("#requirementValidationTestImplemented").val(),
			$("#requirementValidationTestSatisfied").val()
		];
		sent('requirements', 'validationTestInsert', data);

		$(this).attr('id', 'requirementValidationTestUpdate');
		var step = 1;

		$('#requirementValidationTests .step input').each(function(i) {
			if($(this).val() != '') {
				var data = [
					'TV' + $("#id").text().substr(1),
					step,
					$(this).val()
				];
				step++;
			sent('requirements', 'validationTestStepInsert', data);
			}
		});
	}
});

<commit_msg>BUG_FIX: modificata funzione inserimento test di validazione<commit_after>/*
	Requirement insertion
*/
$(document).on("click", "#requirementInsert", function() {
	if(formIsValid('requirementInsertion')) {
		var data = [
			$('#dad').val(),
			$('#importance').val(),
			$('#type').val(),
			$('#source').val(),
			$('#description').val()
		];
		sent('requirements', 'insert', data);
		$('#requirementInsertion').closeModal();
	}
});
/*
	Requirement delete
*/
$(document).on("click", "#requirementDelete", function() {
	var data = [$("#id").text()];
	sent('requirements', 'delete', data);
});
/*
	Requirement update
*/
$(document).on("click", "#requirementUpdate", function() {
	if(formIsValid('requirementUpdate')) {
		var data = [
			$('#id').text(),
			$('#description').val(),
			$('#importance').val(),
			$('#type').val(),
			$("#source").val(),
			$("#satisfied").val()
		];
		sent('requirements', 'update', data);
	}
});
/*
	Requirement child delete
*/
$(document).on("click", ".requirementChildDelete", function() {
	var data = [$(this).parent().parent().attr('id')];
	sent('requirements', 'childDelete', data);
	$(this).parent().parent().remove();
});
/*
	Requirement class combine
*/
$(document).on("click", "#requirementClassCombine", function() {
	if(formIsValid('requirementClass')) {
		var data = [
			$("#id").text(),
			$("#requirementClassName").val()
		];
		sent('requirements', 'classCombine', data);
		$("#requirementClassName option[value='" + data[1] + "']").remove();
		$('select').material_select();
		$("#requirementClassList").append("
delete" + data[1] + "
");
	}
});
/*
	Requirement class delete
*/
$(document).on("click", ".requirementClassDelete", function() {
	var data = [
		$("#id").text(),
		$(this).parent().parent().attr('id')
	];
	sent('requirements', 'classDelete', data);
	$(this).parent().parent().remove();
	$("#requirementClassName").append("<option value=" + data[1] + ">" + data[1] + "</option>");
	$('select').material_select();
});
/*
	Requirement package combine
*/
$(document).on("click", "#requirementPackageCombine", function() {
	if(formIsValid('requirementPackage')) {
		var data = [
			$("#id").text(),
			$("#requirementPackageName").val()
		];
		sent('requirements', 'packageCombine', data);
		$("#requirementPackageName option[value='" + data[1] + "']").remove();
		$('select').material_select();
		$("#requirementPackageList").append("
delete" + data[1] + "
");
	}
});
/*
	Requirement package delete
*/
$(document).on("click", ".requirementPackageDelete", function() {
	var data = [
		$("#id").text(),
		$(this).parent().parent().attr('id')
	];
	sent('requirements', 'packageDelete', data);
	$(this).parent().parent().remove();
	$("#requirementPackageName").append("<option value=" + data[1] + ">" + data[1] + "</option>");
	$('select').material_select();
});
/*
	Requirement systemTest insert
*/
$(document).on("click", "#requirementSystemTestInsert", function() {
	if(formIsValid('requirementSystemTest')) {
		var data = [
			$("#id").text(),
			$("#systemTestDescription").val(),
			$("#systemTestImplemented").val(),
			$("#systemTestSatisfied").val()
		];
		sent('requirements', 'systemTestInsert', data);
		$("#requirementSystemTestInsert").attr('id', 'requirementSystemTestUpdate').html('UPDATE');
	}
});
/*
	Requirement systemTest udpate
*/
$(document).on("click", "#requirementSystemTestUpdate", function() {
	if(formIsValid('requirementSystemTest')) {
		var data = [
			$("#id").text(),
			$("#systemTestDescription").val(),
			$("#systemTestImplemented").val(),
			$("#systemTestSatisfied").val()
		];
		sent('requirements', 'systemTestUpdate', data);
	}
});
/*
	Requirement usecase combine
*/
$(document).on("click", "#requirementUsecaseCombine", function() {
	if(formIsValid('requirementUsecase')) {
		var data = [
			$("#id").text(),
			$("#requirementUsecaseName").val()
		];
		sent('requirements', 'usecaseCombine', data);
		$("#requirementUsecaseList").append("
delete" + $("#requirementUsecaseName option:selected").text() + "
");
		$("#requirementUsecaseName option[value='" + data[1] + "']").remove();
		$('select').material_select();
	}
});
/*
	Requirement usecase delete
*/
$(document).on("click", ".requirementUsecaseDelete", function() {
	var data = [
		$("#id").text(),
		$(this).parent().parent().attr('id')
	];
	sent('requirements', 'usecaseDelete', data);
	$(this).parent().parent().remove();
	$("#requirementUsecaseName").append("<option value=" + data[1] + ">" + text + "</option>");
	$('select').material_select();
});

$(document).on("click", "#requirementValidationTestAddStep", function() {
	var n = $("#requirementValidationTests .step").length;
	if(n == 0) {
		n++;
		$("#requirementValidationTestAddStep").after("

" + n + "°
delete<input class='col s10' type='text'>
");
	}
	else {
		n++;
		$("#requirementValidationTests .step").last().after("

" + n + "°
delete<input class='col s10' type='text'>
");
	}
});

$(document).on("click", ".stepDelete", function() {
	$(this).parent().remove();
	var n = $("requirementValidationTests .step").length;
	$("#requirementValidationTests .step").each(function(i) {
		$(this).children('p').eq(0).replaceWith("
" + (i+1) + "°
");
	});
});

$(document).on("click", "#requirementValidationTestInsertion, #requirementValidationTestUpdate", function() {
	if(formIsValid('requirementValidationTests')) {
		// remove previous test saved
		var data = [
			$("#id").text()
		];
		sent('requirements', 'validationTestDelete', data);

		// inset new test or updated test
		var data = [
			$("#id").text(),
			'TV' + $("#id").text().substr(1),
			$("#requirementValidationTestDescription").val(),
			$("#requirementValidationTestImplemented").val(),
			$("#requirementValidationTestSatisfied").val()
		];
		sent('requirements', 'validationTestInsert', data);

		setTimeout(function() {
			$(this).attr('id', 'requirementValidationTestUpdate');
			var step = 1;

			$('#requirementValidationTests .step input').each(function(i) {
				if($(this).val() != '') {
					var data = [
						'TV' + $("#id").text().substr(1),
						step,
						$(this).val()
					];
					step++;
				sent('requirements', 'validationTestStepInsert', data);
				}
			});
		}, 500);
	}
});

<|endoftext|>


<commit_before>'use strict'

//----------------
// Includes: Self
//----------------
var dataMap = require('./data-map')

//----------
// Includes
//----------
var chalk = require('chalk')
var events = require('events')
var hid = require('node-hid')

//-----------
// Variables
//-----------
var dataPrev = Array(11)
var device = ''
var eventEmitter = new events.EventEmitter()
var ledPrev = []
var memoryPrev = {
    'wheel': {
        'turn': 50,
        'shift_left' : 0,
        'shift_right': 0,
        'button_1': 0,
        'button_2': 0,
        'button_3': 0,
        'button_4': 0,
        'button_5': 0,
        'button_6': 0
    },
    'shifter': {
        'button_1': 0,
        'button_2': 0,
        'button_3': 0,
        'button_4': 0,
        'dpad': 0,
        'button_5': 0,
        'button_6': 0,
        'button_7': 0,
        'button_8': 0,
        'gear': 0
    },
    'pedals': {
        'gas'   : 0,
        'brake' : 0,
        'clutch': 0
    }
}
var options = {
    'autocenter': true,
    'debug': false,
    'range': 900
}

//-----------
// Functions
//-----------
function clone(obj) {
    /*
    Clone an object.
    @param   {Object}  obj  Object to clone.
    @return  {Object}
    */
    if (obj === null || typeof obj !== 'object') {
        return obj
    }

    var temp = obj.constructor()

    for (var key in obj) {
        temp[key] = clone(obj[key])
    }

    return temp
} // clone

function connect(odo, callback) { // Constable Odo takes many forms.
    /*
    Connect to a Logitech G27 wheel.
    @param   {Object, Function}  odo       Options object or callback function.
    @param   {Function}          callback  Callback function.
    */
    if (typeof odo === 'function') {
        callback = odo
    } else {
        userOptions(odo)
    }

    callback = (typeof callback === 'function') ? callback : function() {}

    device = new hid.HID(findWheel())

    device.read(function(err, data) {
        if (err) {
            if (options.debug) {
                console.log(chalk.red('connect -> Error reading from device.'), err)
            }
            callback(err)
        } else {
            forceOff()

            if (data.length === 12) {
                // wheel is already in high precision mode

                if (options.debug) {
                    console.log(chalk.cyan('connect -> Wheel already in high precision mode.'))
                }

                listen(true, callback)
            } else {
                // wheel is not in high precision mode

                if (options.debug) {
                    console.log(chalk.cyan('connect -> Initing'))
                }

                try {
                    // G27 Racing Wheel init from https://www.lfs.net/forum/post/1587144#post1587144
                    device.write([0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00])
                    device.write([0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00])

                    // wait for wheel to finish calibrating
                    setTimeout(function() {
                        listen(false, callback)
                    }, 8000)
                } catch(err) {
                    callback(err)
                }
            }
        }
    })

    forceConstant(1) // move the wheel to generate a read event
} // connect

function disconnect() {
    /*
    Disconnect in preparation to connect again or to allow other software to use the wheel.
    */
    device.close()
} // disconnect

function findWheel() {
    /*
    Return the USB location of a Logitech G27 wheel.
    @return  {String}  devicePath  USB path like: USB_046d_c294_fa120000
    */
    var devices = hid.devices()
    var devicePath = ''

    for (var i in devices) {
        if (devices[i].product === 'G27 Racing Wheel' ||
           (devices[i].vendorId === 1133 && devices[i].productId === 49819)) {
            devicePath = devices[i].path
            break
        }
    }

    if (devicePath === '') {
        if (options.debug) {
            console.log(chalk.yellow('findWheel -> Oops, could not find a G27 Wheel. Is it plugged in?\n'))
            process.exit()
        }
    } else if (options.debug) {
        console.log(chalk.cyan('findWheel -> Found G27 Wheel at ') + devicePath)
    }

    return devicePath
} // findWheel

function on(str, func) {
    return eventEmitter.on(str, func)
} // on

function once(str, func) {
    return eventEmitter.once(str, func)
} // once

function relay(data) {
    /*
    Relay low level commands directly to the hardware.
    @param  {Object}  data  Array of data to write. For example: [0xf8, 0x12, 0x1f, 0x00, 0x00, 0x00, 0x01]
    */
    if (Array.isArray(data)) {
        device.write(data)
    }
} // relay

function setRange() {
    /*
    Set wheel range.
    */
    if (options.range < 270) {
        options.range = 270
    }

    if (options.range > 900) {
        options.range = 900
    }

    var range1 = options.range & 0x00ff
    var range2 = (options.range & 0xff00) >> 8

    device.write([0xf8, 0x81, range1, range2, 0x00, 0x00, 0x00])
} // setRange

function userOptions(opt) {
    /*
    Set user options.
    @param  {Object}  opt   Options object originally passed into the connect function.
    */
    if (typeof opt !== 'object') return;

    for (var i in options) {
        if (opt.hasOwnProperty(i)) {
            options[i] = opt[i]
        }
    }

    if (options.debug) {
        console.log(chalk.cyan('userOptions -> '), options)
    }
} // userOptions

//----------------
// Function: LEDs
//----------------
function leds(setting) {
    /*
    Control the shift indicator LEDs using a variety of convience methods.
    @param  {*}  setting  String, Number, or Array setting. Optional. See API documentation for more info.
    */

    // no setting
    if (typeof setting === 'undefined') {
        setting = []
    }

    // percent based settings
    if (typeof setting === 'number') {
        setting = Math.round(setting * 100)

        if (setting > 84) {
            setting = '11111'
        } else if (setting > 69) {
            setting = '1111'
        } else if (setting > 39) {
            setting = '111'
        } else if (setting > 19) {
            setting = '11'
        } else if (setting > 4) {
            setting = '1'
        } else {
            setting = ''
        }
    }

    // string based settings
    if (typeof setting === 'string') {
        setting = setting.split('')
    }

    // array based settings
    if (Array.isArray(setting)) {
        if (ledPrev === setting) {
            return
        }

        var ledValues = [1, 2, 4, 8, 16]

        var ledArray = setting

        // remove any extra elements
        ledArray.splice(5, ledArray.length - 5)

        var len = ledArray.length

        setting = 0

        for (var i = 0; i < len; i++) {
            if (parseInt(ledArray[i]) === 1) {
                setting = setting + ledValues[i]
            }
        }

        /*
        Setting should be a number from 0 to 31

            From outside in, mirrored on each side.

            0 = No LEDs
            1 = Green One
            2 = Green Two
            4 = Orange One
            8 = Orange Two
            16 = Red

            31 = All LEDs
        */

        try {
            device.write([0xf8, 0x12, setting, 0x00, 0x00, 0x00, 0x01])

            // update global variable for next time
            ledPrev = setting
        } catch(err) {
            // do nothing
        }
    }
} // leds

//------------------
// Functions: Force
//------------------
function autoCenter() {
    /*
    Set wheel autocentering based on existing options.
    */
    var option = options.autocenter

    if (option) {
        // auto-center on
        device.write([0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])

        if (Array.isArray(option) && option.length === 2) {
            // custom auto-center

            // byte 3-4 is effect strength, 0x00 to 0x0f
            option[0] = Math.round(option[0] * 15)

            // byte 5 is the rate the effect strength rises as the wheel turns, 0x00 to 0xff
            option[1] = Math.round(option[1] * 255)

            device.write([0xfe, 0x0d, option[0], option[0], option[1], 0x00, 0x00, 0x00])
        } else {
            // use default strength profile
            device.write([0xfe, 0x0d, 0x07, 0x07, 0xff, 0x00, 0x00, 0x00])
        }
    } else {
        // auto-center off
        device.write([0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    }
} // autoCenter

function forceConstant(number) {
    /*
    Set or disable a constant force effect.
    @param  {Number}  number  Number between 0 and 1. Optional.
    */
    if (typeof number === 'undefined') number = 0.5

    if (number === 0.5) {
        forceOff(1)
        return
    }

    number = Math.round(Math.abs(number - 1) * 255)

    device.write([0x11, 0x00, number, 0x00, 0x00, 0x00, 0x00])
} // forceConstant

function forceFriction(number) {
    /*
    Set or disable the ammount of friction present when turning the wheel.
    @param  {Number}  number  Number between 0 and 1. Optional.
    */
    if (typeof number === 'undefined') number = 0

    if (number === 0) {
        forceOff(2)
        return
    }

    number = Math.round(number * 15)

    device.write([0x21, 0x02, number, 0x00, number, 0x00, 0x00])
} // forceFriction

function forceOff(slot) {
    /*
    Turn off all force effects except auto-centering.
    @param  {Number}  slot  Number between 0 and 4. Optional.
    */
    // Great info at http://wiibrew.org/wiki/Logitech_USB_steering_wheel, especially about writing to more than one effect slot.
    if (typeof slot === 'undefined') {
        slot = 0xf3
    } else {
        if (slot === 0) {
            slot = 0xf3
        }
        slot = parseInt('0x' + slot + '0')
    }

    // turn off effects (except for auto-center)
    device.write([slot, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
} // forceOff

//------------------
// Function: Listen
//------------------
function listen(ready, callback) {
    /*
    @param  {Boolean}   ready     True if the wheel is ready for commands. Optional.
    @param  {Function}  callback  Optional callback function.
    */
    if (!ready) {
        device.close()
        device = new hid.HID(findWheel())
    }

    setRange()
    autoCenter()

    device.on("data", function(data) {
        // reset memory
        var memory = clone(memoryPrev)
        var memoryCache = clone(memoryPrev)

        var dataDiffPositions = []

        // find out if anything has changed since the last event
        var dataLength = data.length
        for (var i = 0; i < dataLength; i++) {
            if (data[i] !== dataPrev[i]) {
                dataDiffPositions.push(i)
            }
        }

        if (dataDiffPositions.length === 0) {
            return
        }

        memory = dataMap(dataDiffPositions, data, memory)

        //-------------------------
        // Figure out what changed
        //-------------------------
        var memoryDiff = {}
        var count = 0

        for (var o in memoryCache) {
            for (var y in memory[o]) {
                if (memory[o][y] != memoryCache[o][y]) {
                    if (!memoryDiff.hasOwnProperty(o)) {
                        memoryDiff[o] = {}
                    }
                    eventEmitter.emit(o + '-' + y, memory[o][y]) // for example, wheel-turn
                    memoryDiff[o][y] = memory[o][y]
                    count = count + 1
                }
            }
        }

        if (count > 0) {
            if (options.debug) {
                console.log(memoryDiff)
            }

            // emit changes only
            eventEmitter.emit('changes', memoryDiff)
        }

        // emit everything in all event
        eventEmitter.emit('all', memory)

        // emit raw data
        eventEmitter.emit('data', data)

        // set global variables for next event
        memoryPrev = memory
        dataPrev = data
    })

    device.on("error", function(err) {
        if (options.debug) {
            console.log(chalk.red('device error -> '), JSON.stringify(err), err)
        }
    })

    leds(0)

    if (options.debug) {
        console.log(chalk.cyan('listen -> listening'))
    }

    callback(null)
} // listen

//---------
// Exports
//---------
module.exports.connect = connect
module.exports.disconnect = disconnect

// events
module.exports.emitter = eventEmitter
module.exports.on = on
module.exports.once = once

// leds
module.exports.leds = leds

// force
module.exports.forceConstant = forceConstant
module.exports.forceFriction = forceFriction
module.exports.forceOff = forceOff

// advanced
module.exports.relay = relay
<commit_msg>more reliable detection<commit_after>'use strict'

//----------------
// Includes: Self
//----------------
var dataMap = require('./data-map')

//----------
// Includes
//----------
var chalk = require('chalk')
var events = require('events')
var hid = require('node-hid')

//-----------
// Variables
//-----------
var dataPrev = Array(11)
var device = ''
var eventEmitter = new events.EventEmitter()
var ledPrev = []
var memoryPrev = {
    'wheel': {
        'turn': 50,
        'shift_left' : 0,
        'shift_right': 0,
        'button_1': 0,
        'button_2': 0,
        'button_3': 0,
        'button_4': 0,
        'button_5': 0,
        'button_6': 0
    },
    'shifter': {
        'button_1': 0,
        'button_2': 0,
        'button_3': 0,
        'button_4': 0,
        'dpad': 0,
        'button_5': 0,
        'button_6': 0,
        'button_7': 0,
        'button_8': 0,
        'gear': 0
    },
    'pedals': {
        'gas'   : 0,
        'brake' : 0,
        'clutch': 0
    }
}
var options = {
    'autocenter': true,
    'debug': false,
    'range': 900
}

//-----------
// Functions
//-----------
function clone(obj) {
    /*
    Clone an object.
    @param   {Object}  obj  Object to clone.
    @return  {Object}
    */
    if (obj === null || typeof obj !== 'object') {
        return obj
    }

    var temp = obj.constructor()

    for (var key in obj) {
        temp[key] = clone(obj[key])
    }

    return temp
} // clone

function connect(odo, callback) { // Constable Odo takes many forms.
    /*
    Connect to a Logitech G27 wheel.
    @param   {Object, Function}  odo       Options object or callback function.
    @param   {Function}          callback  Callback function.
    */
    if (typeof odo === 'function') {
        callback = odo
    } else {
        userOptions(odo)
    }

    callback = (typeof callback === 'function') ? callback : function() {}

    device = new hid.HID(findWheel())

    device.read(function(err, data) {
        if (err) {
            if (options.debug) {
                console.log(chalk.red('connect -> Error reading from device.'), err)
            }
            callback(err)
        } else {
            forceOff()

            if (data.length === 12) {
                // wheel is already in high precision mode

                if (options.debug) {
                    console.log(chalk.cyan('connect -> Wheel already in high precision mode.'))
                }

                listen(true, callback)
            } else {
                // wheel is not in high precision mode

                if (options.debug) {
                    console.log(chalk.cyan('connect -> Initing'))
                }

                try {
                    // G27 Racing Wheel init from https://www.lfs.net/forum/post/1587144#post1587144
                    device.write([0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00])
                    device.write([0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00])

                    // wait for wheel to finish calibrating
                    setTimeout(function() {
                        listen(false, callback)
                    }, 8000)
                } catch(err) {
                    callback(err)
                }
            }
        }
    })

    forceConstant(1) // move the wheel to generate a read event
} // connect

function disconnect() {
    /*
    Disconnect in preparation to connect again or to allow other software to use the wheel.
    */
    device.close()
} // disconnect

function findWheel() {
    /*
    Return the USB location of a Logitech G27 wheel.
    @return  {String}  devicePath  USB path like: USB_046d_c294_fa120000
    */
    var devices = hid.devices()
    var devicePath = ''

    for (var i in devices) {
        // devices[i].product will be set to 'G27 Racing Wheel' on Windows and Mac. Linux will not have this key.
        // devices[i].interface should be 0 on Windows and Linux.
        // devices[i].usagePage should be 1 on Windows and Mac.
        if (devices[i].vendorId === 1133 && devices[i].productId === 49819 &&
        (devices[i].interface === 0 || devices[i].usagePage === 1)) {
            devicePath = devices[i].path
            break
        }
    }

    if (devicePath === '') {
        if (options.debug) {
            console.log(chalk.yellow('findWheel -> Oops, could not find a G27 Wheel. Is it plugged in?\n'))
            process.exit()
        }
    } else if (options.debug) {
        console.log(chalk.cyan('findWheel -> Found G27 Wheel at ') + devicePath)
    }

    return devicePath
} // findWheel

function on(str, func) {
    return eventEmitter.on(str, func)
} // on

function once(str, func) {
    return eventEmitter.once(str, func)
} // once

function relay(data) {
    /*
    Relay low level commands directly to the hardware.
    @param  {Object}  data  Array of data to write. For example: [0xf8, 0x12, 0x1f, 0x00, 0x00, 0x00, 0x01]
    */
    if (Array.isArray(data)) {
        device.write(data)
    }
} // relay

function setRange() {
    /*
    Set wheel range.
    */
    if (options.range < 270) {
        options.range = 270
    }

    if (options.range > 900) {
        options.range = 900
    }

    var range1 = options.range & 0x00ff
    var range2 = (options.range & 0xff00) >> 8

    device.write([0xf8, 0x81, range1, range2, 0x00, 0x00, 0x00])
} // setRange

function userOptions(opt) {
    /*
    Set user options.
    @param  {Object}  opt   Options object originally passed into the connect function.
    */
    if (typeof opt !== 'object') return;

    for (var i in options) {
        if (opt.hasOwnProperty(i)) {
            options[i] = opt[i]
        }
    }

    if (options.debug) {
        console.log(chalk.cyan('userOptions -> '), options)
    }
} // userOptions

//----------------
// Function: LEDs
//----------------
function leds(setting) {
    /*
    Control the shift indicator LEDs using a variety of convience methods.
    @param  {*}  setting  String, Number, or Array setting. Optional. See API documentation for more info.
    */

    // no setting
    if (typeof setting === 'undefined') {
        setting = []
    }

    // percent based settings
    if (typeof setting === 'number') {
        setting = Math.round(setting * 100)

        if (setting > 84) {
            setting = '11111'
        } else if (setting > 69) {
            setting = '1111'
        } else if (setting > 39) {
            setting = '111'
        } else if (setting > 19) {
            setting = '11'
        } else if (setting > 4) {
            setting = '1'
        } else {
            setting = ''
        }
    }

    // string based settings
    if (typeof setting === 'string') {
        setting = setting.split('')
    }

    // array based settings
    if (Array.isArray(setting)) {
        if (ledPrev === setting) {
            return
        }

        var ledValues = [1, 2, 4, 8, 16]

        var ledArray = setting

        // remove any extra elements
        ledArray.splice(5, ledArray.length - 5)

        var len = ledArray.length

        setting = 0

        for (var i = 0; i < len; i++) {
            if (parseInt(ledArray[i]) === 1) {
                setting = setting + ledValues[i]
            }
        }

        /*
        Setting should be a number from 0 to 31

            From outside in, mirrored on each side.

            0 = No LEDs
            1 = Green One
            2 = Green Two
            4 = Orange One
            8 = Orange Two
            16 = Red

            31 = All LEDs
        */

        try {
            device.write([0xf8, 0x12, setting, 0x00, 0x00, 0x00, 0x01])

            // update global variable for next time
            ledPrev = setting
        } catch(err) {
            // do nothing
        }
    }
} // leds

//------------------
// Functions: Force
//------------------
function autoCenter() {
    /*
    Set wheel autocentering based on existing options.
    */
    var option = options.autocenter

    if (option) {
        // auto-center on
        device.write([0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])

        if (Array.isArray(option) && option.length === 2) {
            // custom auto-center

            // byte 3-4 is effect strength, 0x00 to 0x0f
            option[0] = Math.round(option[0] * 15)

            // byte 5 is the rate the effect strength rises as the wheel turns, 0x00 to 0xff
            option[1] = Math.round(option[1] * 255)

            device.write([0xfe, 0x0d, option[0], option[0], option[1], 0x00, 0x00, 0x00])
        } else {
            // use default strength profile
            device.write([0xfe, 0x0d, 0x07, 0x07, 0xff, 0x00, 0x00, 0x00])
        }
    } else {
        // auto-center off
        device.write([0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    }
} // autoCenter

function forceConstant(number) {
    /*
    Set or disable a constant force effect.
    @param  {Number}  number  Number between 0 and 1. Optional.
    */
    if (typeof number === 'undefined') number = 0.5

    if (number === 0.5) {
        forceOff(1)
        return
    }

    number = Math.round(Math.abs(number - 1) * 255)

    device.write([0x11, 0x00, number, 0x00, 0x00, 0x00, 0x00])
} // forceConstant

function forceFriction(number) {
    /*
    Set or disable the ammount of friction present when turning the wheel.
    @param  {Number}  number  Number between 0 and 1. Optional.
    */
    if (typeof number === 'undefined') number = 0

    if (number === 0) {
        forceOff(2)
        return
    }

    number = Math.round(number * 15)

    device.write([0x21, 0x02, number, 0x00, number, 0x00, 0x00])
} // forceFriction

function forceOff(slot) {
    /*
    Turn off all force effects except auto-centering.
    @param  {Number}  slot  Number between 0 and 4. Optional.
    */
    // Great info at http://wiibrew.org/wiki/Logitech_USB_steering_wheel, especially about writing to more than one effect slot.
    if (typeof slot === 'undefined') {
        slot = 0xf3
    } else {
        if (slot === 0) {
            slot = 0xf3
        }
        slot = parseInt('0x' + slot + '0')
    }

    // turn off effects (except for auto-center)
    device.write([slot, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
} // forceOff

//------------------
// Function: Listen
//------------------
function listen(ready, callback) {
    /*
    @param  {Boolean}   ready     True if the wheel is ready for commands. Optional.
    @param  {Function}  callback  Optional callback function.
    */
    if (!ready) {
        device.close()
        device = new hid.HID(findWheel())
    }

    setRange()
    autoCenter()

    device.on("data", function(data) {
        // reset memory
        var memory = clone(memoryPrev)
        var memoryCache = clone(memoryPrev)

        var dataDiffPositions = []

        // find out if anything has changed since the last event
        var dataLength = data.length
        for (var i = 0; i < dataLength; i++) {
            if (data[i] !== dataPrev[i]) {
                dataDiffPositions.push(i)
            }
        }

        if (dataDiffPositions.length === 0) {
            return
        }

        memory = dataMap(dataDiffPositions, data, memory)

        //-------------------------
        // Figure out what changed
        //-------------------------
        var memoryDiff = {}
        var count = 0

        for (var o in memoryCache) {
            for (var y in memory[o]) {
                if (memory[o][y] != memoryCache[o][y]) {
                    if (!memoryDiff.hasOwnProperty(o)) {
                        memoryDiff[o] = {}
                    }
                    eventEmitter.emit(o + '-' + y, memory[o][y]) // for example, wheel-turn
                    memoryDiff[o][y] = memory[o][y]
                    count = count + 1
                }
            }
        }

        if (count > 0) {
            if (options.debug) {
                console.log(memoryDiff)
            }

            // emit changes only
            eventEmitter.emit('changes', memoryDiff)
        }

        // emit everything in all event
        eventEmitter.emit('all', memory)

        // emit raw data
        eventEmitter.emit('data', data)

        // set global variables for next event
        memoryPrev = memory
        dataPrev = data
    })

    device.on("error", function(err) {
        if (options.debug) {
            console.log(chalk.red('device error -> '), JSON.stringify(err), err)
        }
    })

    leds(0)

    if (options.debug) {
        console.log(chalk.cyan('listen -> listening'))
    }

    callback(null)
} // listen

//---------
// Exports
//---------
module.exports.connect = connect
module.exports.disconnect = disconnect

// events
module.exports.emitter = eventEmitter
module.exports.on = on
module.exports.once = once

// leds
module.exports.leds = leds

// force
module.exports.forceConstant = forceConstant
module.exports.forceFriction = forceFriction
module.exports.forceOff = forceOff

// advanced
module.exports.relay = relay
<|endoftext|>