Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

switchboard-automation

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

switchboard-automation - npm Package Compare versions

Comparing version 0.1.2 to 0.1.3

apps/homeWatch.js

5

app.js

@@ -54,3 +54,3 @@ /**

case '--config' :
configFile = __dirname + '/' + process.argv[parseInt(arg, 10) + 1];
configFile = process.argv[parseInt(arg, 10) + 1];
break;

@@ -113,2 +113,3 @@ }

console.log('\x1b[31mError\x1b[0m: No controllers found. Is your config file setup correctly?');
process.exit(1);
}

@@ -121,3 +122,3 @@

if (settings.config.config.ssl.disabled !== true) {
if (settings.config.config.ssl && settings.config.config.ssl.disabled !== true) {
try {

@@ -124,0 +125,0 @@ key = fs.statSync(__dirname + '/cache/key.pem');

10

apps/doorKnock.js

@@ -34,3 +34,3 @@ /**

return {
version : 20151012,
version : 20160516,

@@ -41,3 +41,3 @@ lastEvents : { knock : 0, open : 0, close: 0 },

var now = new Date().getTime(),
delay = config.delay || 5,
delay = (config.delay || 5) * 1000,
that = this;

@@ -66,4 +66,4 @@

if ((that.lastEvents.open <= that.lastEvents.close) &&
(Math.abs(that.lastEvents.knock - that.lastEvents.open) > (config.delay * 1000)) &&
(Math.abs(that.lastEvents.knock - that.lastEvents.close) > (config.delay * 1000))) {
(Math.abs(that.lastEvents.knock - that.lastEvents.open) > delay) &&
(Math.abs(that.lastEvents.knock - that.lastEvents.close) > delay)) {
message = translate.translate('{{i18n_DOOR_KNOCK}}', 'smartthings', controllers.config.language).split('{{LABEL}}').join(config.contact);

@@ -79,3 +79,3 @@

}
}, delay * 1000);
}, delay);
}

@@ -82,0 +82,0 @@ }

@@ -1,1 +0,1 @@

1460063136445
1468879158356

@@ -46,2 +46,12 @@ exports.config = {

/*
* The name of the screensaver should remain "screenSaver" to work properly.
*/
screenSaver : {
typeClass : 'clientScreenSaver',
title : 'Screen Saver',
timeout : 60,
disabled : true
},
clientMp3 : {

@@ -400,3 +410,9 @@ typeClass : 'clientMp3',

delay : 15,
macro : '' }
macro : '' },
'Home Watch' : { id : 'homeWatch',
contact : ['Front Door'],
motion : ['Living Room Motion'],
secureModes : ['Away'],
delay : 15,
controllerIds : ['pushover', 'sms', 'clientSpeech', 'clientNotify', 'gerty'] }
},

@@ -580,2 +596,6 @@ */

title : 'Gerty',
// Number of comments to remain visible in Gerty's chat log.
maxCount : 250,
// The higher the number, the more likely he is to change emojis and act
// out.
personality : 80,

@@ -602,6 +622,8 @@ // Gerty will only act on inputted text that addresses him based on his

apps : { 'Gerty' : { id : 'gerty',
macros : { 'Watch A Movie' : 'ps3=PowerOn,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,Circle,sleep,sleep,sleep,sleep,Left;samsung=sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,HDMI4,sleep,RIGHT,sleep,RIGHT,sleep,RIGHT,sleep,RIGHT,sleep,RIGHT,sleep,DOWN,sleep,ENTER',
macros : { 'Watch A Movie' : 'ps3=PowerOn;samsung=sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,sleep,HDMI4,sleep,RIGHT,sleep,RIGHT,sleep,RIGHT,sleep,RIGHT,sleep,RIGHT,sleep,DOWN,sleep,ENTER,sleep,RETURN,sleep,sleep,sleep,LEFT',
'Goodnight' : 'smartthings=subdevice-mode-Night',
'Good Night' : 'smartthings=subdevice-mode-Night',
'Goodbye' : 'smartthings=subdevice-mode-Away;nest=Away',
'Good Bye' : 'smartthings=subdevice-mode-Away;nest=Away',
'I\'m Back' : 'smartthings=subdevice-mode-Home;nest=Home',
'Welcome Home' : 'smartthings=subdevice-mode-Home;nest=Home' },

@@ -616,7 +638,6 @@ controllerIds : ['samsung', 'roku', 'ps3', 'panasonic', 'lg', 'pioneer', 'denon', 'speech', 'stocks', 'weather', 'foscam', 'mp3', 'sms', 'pushover', 'smartthings', 'nest', 'switchBoardCI', 'xbmc', 'raspberryRemote', 'wemo', 'activeBuilding', 'clientMp3', 'clientNotify', 'clientSpeech'] } },

debug : {
typeClass : 'debug',
title : 'Debug',
disabled : true,
disabledMarkup : true
typeClass : 'debug',
title : 'Debug',
disabled : true
}
};

@@ -63,19 +63,19 @@ /**

case 'EXCITED' :
emojis = ['😋', '😂', '😁']; // ' Comments to fix Atoms syntax highlighter on Linux
emojis = ['😋', '😂', '😁'];
break;
case 'HAPPY' :
emojis = ['😄', '😃', '😀', '😊', '😉', '😎', '😋', '😁', '😛', '😝', '😜']; // '''
emojis = ['😄', '😃', '😀', '😊', '😉', '😎', '😋', '😁', '😛', '😝', '😜'];
break;
case 'INDIFFERENT' :
emojis = ['😑', '😶', '😐', '😒', '😌']; // '
emojis = ['😑', '😶', '😐', '😒', '😌'];
break;
case 'LOVE' :
emojis = ['😍', '😘', '😚', '😗', '😙', '😏', '😇']; // ''
emojis = ['😍', '😘', '😚', '😗', '😙', '😏', '😇'];
break;
case 'PLAYFUL' :
emojis = ['😜', '😝', '😏', '😇', '😈', '😎', '😋', '😛']; // '
emojis = ['😜', '😝', '😏', '😇', '😈', '😎', '😋', '😛'];
break;

@@ -88,3 +88,3 @@

case 'SCARED' :
emojis = ['😕', '😮', '😧', '😦', '😟', '😲', '😵', '😱']; // '
emojis = ['😕', '😮', '😧', '😦', '😟', '😲', '😵', '😱'];
break;

@@ -91,0 +91,0 @@

@@ -166,3 +166,3 @@ /**

if (city.title.indexOf('Error') === -1) {
if (city && city.title && city.title.indexOf('Error') === -1) {
errMessage = null;

@@ -169,0 +169,0 @@

@@ -48,89 +48,67 @@ /**

// https://developer.yahoo.com/weather/#codes
// https://developer.yahoo.com/weather/documentation.html#codes
translateCode = function (code) {
var icon = '';
var warning = 'warning', // Tropical Storm
lightning = 'bolt', // Thunderstorm
snow = 'asterisk', // Snow
rain = 'tint', // Rain
smoke = 'fire', // Smoke
wind = 'flag', // Wind
cloud = 'cloud', // Cloudy
clearNight = 'moon-o', // Clear Night
clearDay = 'sun-o', // Clear Day
codes = {
0 : warning,
1 : warning,
2 : warning,
3 : lightning,
4 : lightning,
5 : snow,
6 : snow,
7 : snow,
8 : snow,
9 : rain,
10 : rain,
11 : rain,
12 : rain,
13 : snow,
14 : snow,
15 : snow,
16 : snow,
17 : snow,
18 : snow,
19 : smoke,
20 : smoke,
21 : smoke,
22 : smoke,
23 : wind,
24 : wind,
25 : snow,
26 : cloud,
27 : cloud,
28 : cloud,
29 : cloud,
30 : cloud,
31 : clearNight,
32 : clearDay,
33 : clearNight,
34 : clearDay,
35 : snow,
36 : clearDay,
37 : lightning,
38 : lightning,
39 : lightning,
40 : rain,
41 : snow,
42 : snow,
43 : snow,
44 : cloud,
45 : lightning,
46 : snow,
47 : lightning
};
code = parseInt(code, 10);
if (code <= 2) {
icon = 'warning';
}
else if (code <= 4) {
icon = 'bolt';
}
else if (code <= 8) {
icon = 'asterisk';
}
else if (code <= 12) {
icon = 'tint';
}
else if (code <= 18) {
icon = 'asterisk';
}
else if (code <= 22) {
icon = 'fire';
}
else if (code <= 24) {
icon = 'flag';
}
else if (code === 25 ||
code === 35) {
icon = 'asterisk';
}
else if (code <= 30) {
icon = 'cloud';
}
else if (code === 31 ||
code === 33) {
icon = 'moon-o';
}
else if (code === 32 ||
code === 34 ||
code === 36) {
icon = 'sun-o';
}
else if (code <= 39) {
icon = 'bolt';
}
else if (code === 40) {
icon = 'tint';
}
else if (code <= 43) {
icon = 'asterisk';
}
else if (code === 44) {
icon = 'cloud';
}
else if (code === 45) {
icon = 'bolt';
}
else if (code === 46) {
icon = 'asterisk';
}
else if (code === 47) {
icon = 'bolt';
}
else {
icon = 'question';
}
return icon;
return codes[code] || 'question';
};

@@ -137,0 +115,0 @@

@@ -194,3 +194,4 @@ module.exports = function (grunt) {

grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['update-version', 'concat', 'cssmin', 'jshint', 'nodeunit', 'uglify', 'translation', 'install-precommit']);
grunt.registerTask('test-suite', ['jshint', 'nodeunit', 'translation']);
grunt.registerTask('default', ['update-version', 'concat', 'cssmin', 'jshint', 'nodeunit', 'uglify', 'translation', 'install-precommit']);
};

@@ -1,3 +0,3 @@

/* 20160407 */
SB=function(){"use strict";return{version:20160329,cancelBubble:function(a){a=a||window.event,a.cancelBubble=!0,a.stopPropagation&&a.stopPropagation()},isChildOf:function(a,b){if(b===a)return!1;for(;a&&a!==b&&a!==document.body;)a=a.parentNode;return a===b},event:{list:[],add:function(a,b,c,d){d=d||!1,a.addEventListener?a.addEventListener(b,c,d):a.attachEvent?a.attachEvent("on"+b,c):a["on"+b]=c,SB.event.list.push([a,b,c])},remove:function(a,b,c,d){d=d||!1;var e=0;for(a.removeEventListener?a.removeEventListener(b,c,d):a.detachEvent?a.detachEvent("on"+b,c):a["on"+b]=null,e;e<SB.event.list.length;e+=1)if(SB.event.list[e]&&SB.event.list[e]&&SB.event.list[e][0]===a&&SB.event.list[e][1]===b&&SB.event.list[e][2]===c){SB.event.list.splice(e,1);break}},removeAll:function(a){a=a||document;var b=SB.event.list.length-1;for(b;b>=0;b-=1)SB.event.list[b]&&(SB.event.list[b][0]!==a&&a!==document||SB.event.remove(SB.event.list[b][0],SB.event.list[b][1],SB.event.list[b][2]))}},getTarget:function(a){return a=a||window.event,a.target?a.target:a.srcElement},hasAttribute:function(a,b,c){return a[b]?!!a[b].match(new RegExp("(\\s|^)"+c+"(\\s|$)")):void 0},hasClass:function(a,b){var c=!1;return a&&a.className&&(c=!!SB.hasAttribute(a,"className",b)),c},addClass:function(a,b){a&&b&&(SB.hasClass(a,b)||(a.className=SB.trim(a.className+" "+b)))},removeClass:function(a,b){SB.hasClass(a,b)&&(a.className=a.className.replace(new RegExp("(\\s|^)"+b+"(\\s|$)")," "),a.className=SB.trim(a.className))},toggleClass:function(a,b){SB.hasClass(a,b)?SB.removeClass(a,b):SB.addClass(a,b)},setFocus:function(a){"function"==typeof a.setActive?a.setActive():"function"==typeof a.focus&&a.focus()},get:function(a){return document.getElementById(a)},getByTag:function(a,b){return b=b||document,b.getElementsByTagName(a)},getByClass:function(a,b,c){var d=[],e=[],f=0,g=0;if(b=b||document,c=c.toLowerCase()||"*","*"===c&&document.getElementsByClassName)return b.getElementsByClassName(a);if(b.getElementsByClassName)if(e=b.getElementsByClassName(a),c&&e.length)for(f in e)e[f].tagName&&e[f].tagName.toLowerCase()===c&&(d[g]=e[f],g+=1);else d=e;else{e=SB.getByTag(c,b);for(f in e)SB.hasClass(e[f],a)&&(d[g]=e[f],g+=1)}return d},getText:function(a){return a.textContent?a.textContent:a.innerText?a.innerText:a.text?a.text:a.innerHTML},putText:function(a,b){a.textContent?a.textContent=b:a.innerText?a.innerText=b:a.text?a.text=b:a.innerHTML=b},stripUnits:function(a){var b="";return b="string"==typeof a?parseInt(a.replace(new RegExp("(%|px|em)"),""),10):a},trim:function(a){return a=a||"",a.toString().replace(/^\s\s*/,"").replace(/\s\s*$/,"")},replaceAll:function(a,b,c){var d=a;return"string"==typeof a&&(d=a.replace(new RegExp(b,"g"),c)),d},decode:function(a){var b="";return"object"==typeof JSON&&(b=JSON.parse(a)),b},encode:function(a){var b="";return"object"==typeof JSON&&(b=JSON.stringify(a)),b},log:function(a,b,c){var d=new Date,e="color: white";if("object"==typeof console&&"function"==typeof console.log)if(b&&"object"!=typeof a){switch(a="%c"+b+"%c: "+a+" ("+d.getHours()+":"+(d.getMinutes()<10?"0":"")+d.getMinutes()+")",c){case"success":e="color: green";break;case"info":e="color: aqua";break;case"error":e="color: red"}console.log(a,"background: black; "+e,"background: black; color: white")}else console.log(a)},vibrate:function(a){a=a||20,window.navigator&&window.navigator.vibrate?window.navigator.vibrate(a):SB.log("Not supported","Vibrate","error")},notify:function(a,b,c){var d,e;return"function"==typeof Notification&&("granted"===Notification.permission?(d=new Notification(a,b),setTimeout(function(){d.close(),SB.event.remove(d,"click",e)},1e4),e=function(a){window.focus(),c(a),SB.event.remove(d,"click",e)},SB.event.add(d,"click",e)):SB.notifyAsk()),d},notifyAsk:function(){"function"==typeof Notification&&"denied"!==Notification.permission&&Notification.requestPermission(function(a){Notification.permission!==a&&(Notification.permission=a)})},sound:{sounds:{},play:function(a){"function"==typeof Audio&&(SB.sound.sounds[a]||(SB.sound.sounds[a]=new Audio(a)),SB.sound.sounds[a].play())}},speak:function(a,b,c){var d,e;window.speechSynthesis?(d=new SpeechSynthesisUtterance,e=window.speechSynthesis.getVoices(),d.text=a,d.lang=b||"en-US",e&&e[10]&&"Alex"===e[10].name&&(d.voice=e[10],"female"===c&&(d.voice=e[30])),window.speechSynthesis.speak(d)):SB.log("Not supported","Speak","error")},transcribe:function(a){var b,c;return"webkitSpeechRecognition"in window?(SB.log("Supported","Transcribe","info"),b=new webkitSpeechRecognition,c=function(b){a(b.results[0][0].transcript,b.results[0][0].confidence),SB.event.remove(document,"result",c)},SB.event.add(b,"result",c)):SB.log("Not supported","Transcribe","error"),b},storage:function(a,b){var c;return a&&("undefined"!=typeof localStorage?(void 0!==b&&("object"==typeof b&&(b=SB.encode(b)),localStorage.setItem(a,b)),c=localStorage.getItem(a)):SB.log("Not supported","Local Storage","error")),c},ajax:{request:function(a){a.method=a.method||"GET",a.onStart=a.onStart||function(){},a.onComplete=a.onComplete||function(){};var b,c,d="?";if(c=function(){switch(a.onStart(),typeof a.onComplete){case"object":a.onComplete.value?a.onComplete.value=a.response:a.onComplete.childNodes[0]&&SB.putText(a.onComplete,a.response);break;case"function":a.onComplete()}},window.XMLHttpRequest)b=new XMLHttpRequest;else{if(!window.ActiveXObject)return!1;b=new ActiveXObject("Microsoft.XMLHTTP")}"GET"===a.method&&(-1===a.path.indexOf("?")&&-1===a.param.indexOf("?")||(d="&"),a.path=a.path+d+a.param,a.param=""),b.open(a.method.toUpperCase(),a.path,!0),"POST"===a.method&&b.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),b.setRequestHeader("rest","true"),SB.event.add(b,"readystatechange",function(){if(4===b.readyState){if(200!==b.status)return!1;a.response=b.responseText,c()}}),b.send(a.param)}},findMousePosition:function(a){var b;return b=a.touches&&a.touches.length?{positionX:a.touches[0].clientX,positionY:a.touches[0].clientY}:window.event?{positionX:window.event.clientX,positionY:window.event.clientY}:{positionX:a.clientX,positionY:a.clientY}},findStyle:function(a,b){var c="";if(a.currentStyle)b=b.replace(/-\w/g,function(a){return a.charAt(1).toUpperCase()}),c=a.currentStyle[b];else{if(!window.getComputedStyle)return 0;c=document.defaultView.getComputedStyle(a,null).getPropertyValue(b)}return c&&(-1===c.indexOf("px")&&-1===c.indexOf("em")&&-1===c.indexOf("%")||(c=SB.stripUnits(c)),"opacity"===b&&(c=parseFloat(c,10))),c},findScroll:function(){var a=0;return"number"==typeof window.pageYOffset?a={positionX:window.pageXOffset,positionY:window.pageYOffset}:document.body&&document.body.scrollTop?a={positionX:document.body.scrollWidth,positionY:document.body.scrollTop}:document.documentElement&&document.documentElement.scrollTop&&(a={positionX:document.documentElement.scrollWidth,positionY:document.documentElement.scrollTop}),a},clickDrag:function(a){a.dragElm=a.dragElm||a.elm,a.restrict=a.restrict||!1,a.onStart=a.onStart||function(){},a.onTween=a.onTween||function(){},a.onComplete=a.onComplete||function(){};var b,c,d=void 0===document.body.ontouchstart?"mousedown":"touchstart",e=void 0===document.body.ontouchmove?"mousemove":"touchmove",f=void 0===document.body.ontouchend?"mouseup":"touchend",g=SB.findStyle(a.elm.parentNode,"border-left-width")+SB.findStyle(a.elm.parentNode,"border-right-width"),h=SB.findStyle(a.elm.parentNode,"border-top-width")+SB.findStyle(a.elm.parentNode,"border-bottom-width");b=function(b){if(SB.hasClass(a.elm,"active")){SB.cancelBubble(b),b.preventDefault&&b.preventDefault();var c,d,e=SB.findMousePosition(b),f=e.positionX,i=e.positionY,j=a.dragElm.offsetWidth,k=a.dragElm.offsetHeight;return a.newX=f-a.clickOffsetX+a.startOffsetX-(a.startWidth-SB.findScroll().positionX),a.newY=i-a.clickOffsetY+a.startOffsetY-(a.startHeight-SB.findScroll().positionY),a.restrict&&(c=a.elm.parentNode.offsetWidth-j-g,d=a.elm.parentNode.offsetHeight-k-h,a.newX>c&&(a.newX=c),a.newX<0&&(a.newX=0),a.newY>d&&(a.newY=d),a.newY<0&&(a.newY=0)),a.elm.style.margin=0,a.elm.style.left=a.newX+"px",a.elm.style.top=a.newY+"px",a.onTween(a),!1}},c=function(){SB.hasClass(a.elm,"active")&&(SB.removeClass(a.elm,"active"),SB.event.remove(document,"mousemove",b),SB.event.remove(document,"mouseup",c),a.onComplete(a))},SB.event.add(a.dragElm,d,function(d){var g=SB.findMousePosition(d);SB.clickDrag.zindex=SB.clickDrag.zindex||1,SB.cancelBubble(d),a.clickOffsetX=g.positionX,a.clickOffsetY=g.positionY,a.startOffsetX=a.elm.offsetLeft,a.startOffsetY=a.elm.offsetTop,a.startWidth=SB.findScroll().positionX,a.startHeight=SB.findScroll().positionY,a.elm.style.zIndex=SB.clickDrag.zindex+=1,a.elm.style.margin=0,a.elm.style.bottom="auto",a.elm.style.right="auto",a.elm.style.position="absolute",SB.addClass(a.elm,"active"),a.onStart(),d.preventDefault&&d.preventDefault(),SB.event.add(document,e,b),SB.event.add(document,f,c),b(d)})},init:function(){SB.spec&&SB.spec.init&&SB.spec.init(),SB.addClass(document.body,"rich")}}}(),document.addEventListener&&document.addEventListener("DOMContentLoaded",SB.init,!1),SB.event.add(window,"load",function(){"use strict";document.addEventListener||SB.init()}),SB.event.add(window,"unload",function(){"use strict";SB.event.removeAll()}),"object"==typeof module&&(module.exports=SB),SB.spec=function(){"use strict";return{version:20160314,state:{},parsers:{},templates:{},strings:{},socket:{},uiComponents:{header:{},body:{},indicator:{},templates:[]},navChange:function(a){var b=SB.getByClass(a,SB.spec.uiComponents.header,"li")[0],c=SB.get(a),d=SB.getByClass("selected",SB.spec.uiComponents.header,"li")[0],e=SB.getByClass("selected",SB.spec.uiComponents.body,"section")[0];b&&!SB.hasClass(b,"selected")&&(SB.removeClass(d,"selected"),SB.removeClass(e,"selected"),SB.spec.lazyLoad(a),SB.storage("selected",a),SB.addClass(b,"selected"),SB.addClass(c,"selected"),SB.spec.sliderSetWidths(),SB.spec.lazyUnLoad(e))},updateTemplate:function(a){var b,c,d,e,f=SB.get(a.deviceId),g=SB.spec.parsers[a.typeClass],h=a.value,i=a.state,j=document.createElement("div");SB.spec.state[a.deviceId]=a,SB.log("Updated",a.deviceId,"success"),f&&(d=SB.spec.uiComponents.templates[a.typeClass].markup,c=SB.hasClass(f,"selected")?" selected":"",e=f.cloneNode(!0),b=SB.getByTag("h1",e)[0],b.parentNode.removeChild(b),e=e.innerHTML,g&&(d=g(a.deviceId,d,i,h,SB.spec.uiComponents.templates[a.typeClass].fragments)),"ok"===i?(d=d.split("{{DEVICE_ACTIVE}}").join(SB.spec.strings.ACTIVE),SB.hasClass(f,"device-off")&&(SB.removeClass(f,"device-off"),SB.addClass(f,"device-on"),SB.putText(SB.getByTag("em",SB.getByTag("h1",f)[0])[0],SB.spec.strings.ACTIVE))):(d=d.split("{{DEVICE_ACTIVE}}").join(SB.spec.strings.INACTIVE),SB.hasClass(f,"device-on")&&(SB.removeClass(f,"device-on"),SB.addClass(f,"device-off"),SB.putText(SB.getByTag("em",SB.getByTag("h1",f)[0])[0],SB.spec.strings.INACTIVE))),f&&d&&a&&(SB.storage("state",SB.spec.state),d=d.split("{{DEVICE_ID}}").join(a.deviceId),d=d.split("{{DEVICE_TYPE}}").join(a.typeClass),d=d.split("{{DEVICE_SELECTED}}").join(c),d="ok"===a.state?d.split("{{DEVICE_STATE}}").join(" device-on"):d.split("{{DEVICE_STATE}}").join(" device-off"),d=c?d.split("{{LAZY_LOAD_IMAGE}}").join("src"):d.split("{{LAZY_LOAD_IMAGE}}").join("data-src")),d&&(j.innerHTML=d,j=SB.getByTag("section",j)[0],b=SB.getByTag("h1",j)[0],b.parentNode.removeChild(b),j.innerHTML!==e&&(SB.getByClass("sliderBar",f,"div")[0]?(SB.event.removeAll(SB.getByClass("sliderBar",f,"div")[0].getElementsByTagName("span")[0]),f.outerHTML=d,SB.spec.buildSliders(a.deviceId)):f.outerHTML=d)))},buildIndicator:function(){var a;SB.get("indicator")||(a=document.createElement("span"),a.id="indicator",SB.addClass(a,"connecting"),SB.putText(a,SB.spec.strings.CONNECTING),SB.spec.uiComponents.indicator=a,SB.spec.uiComponents.header.appendChild(a))},checkConnection:function(){var a=SB.spec.socket.readyState<=1;return a||(SB.spec.socketConnect(0),a=SB.spec.socket.readyState<=1),a},socketConnect:function(a){var b,c,d,e,f,g,h="https:"===window.location.protocol?"wss":"ws";SB.spec.socket.readyState&&3!==SB.spec.socket.readyState||(SB.log("Connecting","WebSocket","info"),SB.spec.socket=new WebSocket(h+"://"+window.location.host,"echo-protocol"),a+=1,b=function(){var b=Math.round(Math.min(Math.max(a*(15*Math.random()),10),60));SB.log("Retrying in "+b+"s","WebSocket","info"),SB.spec.uiComponents.indicator.className="disconnected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.DISCONNECTED),setTimeout(function(){SB.spec.socketConnect(a)},1e3*b)}),c=function(){var a="disconnected"===SB.spec.uiComponents.indicator.className;SB.spec.uiComponents.indicator.className="connected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.CONNECTED),SB.log("Connected","WebSocket","success"),a&&(SB.spec.socket.send("fetch state"),SB.log("Reconnected","WebSocket","success")),SB.event.add(SB.spec.socket,"close",f)},d=function(a){var b,c,d=SB.decode(a.data),e={};if("string"==typeof d.speech)d.speech&&(SB.log(d.speech,"Speech","success"),SB.speak(d.speech,d.language,d.voice));else if("string"==typeof d.sound)SB.log(d.sound,"Sound","success"),SB.sound.play("/mp3/"+d.sound+".mp3");else if("string"==typeof d.vibrate)SB.log(d.vibrate,"Vibrate","success"),SB.vibrate(100*d.vibrate);else if("string"==typeof d.title)c=function(){d.deviceId&&SB.spec.navChange(d.deviceId)},b=SB.notify(d.title,d.options,c);else if("string"==typeof d.deviceId)SB.spec.updateTemplate(d);else if("object"==typeof d){for(e in d)if(d.hasOwnProperty(e))break;if(d[e]&&d[e].deviceId){SB.log("Received","State","success");for(e in d)d.hasOwnProperty(e)&&SB.spec.updateTemplate(d[e])}else d[e]&&d[e].markup&&(SB.spec.uiComponents.templates=d,SB.storage("templates",SB.spec.uiComponents.templates))}},f=function(){SB.event.remove(SB.spec.socket,"close",f),SB.log("Disconnected","WebSocket","error"),b()},e=function(){SB.event.remove(SB.spec.socket,"error",f),SB.log("Error","WebSocket","error"),b()},g=function(){SB.event.remove(SB.spec.socket,"open",c),SB.event.remove(SB.spec.socket,"message",d),SB.event.remove(SB.spec.socket,"error",e),SB.event.remove(SB.spec.socket,"close",g)},SB.event.add(SB.spec.socket,"open",c),SB.event.add(SB.spec.socket,"message",d),SB.event.add(SB.spec.socket,"error",e),SB.event.add(SB.spec.socket,"close",g)},statePoller:function(){var a;SB.log("not supported - using polling","WebSockets","error"),a={path:"/templates/",param:"ts="+(new Date).getTime(),method:"GET",onComplete:function(){SB.spec.uiComponents.templates=SB.decode(a.response),SB.storage("templates",SB.spec.uiComponents.templates)}},SB.ajax.request(a),setInterval(function(){var a={path:"/state/",param:"ts="+(new Date).getTime(),method:"GET",onComplete:function(){var b,c=SB.decode(a.response);if(c){SB.spec.uiComponents.indicator.className="connected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.CONNECTED),setTimeout(function(){SB.spec.uiComponents.indicator.className="connecting",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.CONNECTIG)},1e3);for(b in c)c.hasOwnProperty(b)&&SB.spec.updateTemplate(c[b])}else SB.spec.uiComponents.indicator.className="disconnected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.DISCONNECTED)}};SB.ajax.request(a)},1e4)},lazyLoad:function(a){var b,c,d,e,f=0;if(SB.get(a))for(b=SB.get(a),c=Array.prototype.slice.call(SB.getByTag("img",b)),d=Array.prototype.slice.call(SB.getByTag("iframe",b)),e=c.concat(d),f=0;f<e.length;f+=1)e[f].getAttribute("data-src")&&!e[f].src&&(e[f].src=e[f].getAttribute("data-src"))},lazyUnLoad:function(a){var b,c,d,e=0;if(a)for(b=Array.prototype.slice.call(SB.getByTag("img",a)),c=Array.prototype.slice.call(SB.getByTag("iframe",a)),d=b.concat(c),e=0;e<d.length;e+=1)d[e].getAttribute("src")&&(SB.hasClass(d[e],"streaming")||"IFRAME"===d[e].tagName)&&(d[e].setAttribute("data-src",d[e].src),d[e].removeAttribute("src"))},findTextInputs:function(){return SB.spec.uiComponents.body.getElementsByTagName("input")},findNumberInputs:function(){var a,b=SB.spec.findTextInputs(),c=[];for(a=0;a<b.length;a+=1)"number"===b[a].type&&c.push(b[a]);return c},findSliderPosition:function(a,b){var c,d,e,f,g=0;return b&&(c=a.parentNode.offsetWidth-a.offsetWidth,d=parseInt(b.min,10),e=parseInt(b.max,10),f=parseInt(b.value,10),g=(f-d)*c/(e-d),g=c>g?g:c,g=g>0?g:0),Math.round(g)},findSliderValue:function(a,b){var c=a.parentNode.previousSibling,d=a.parentNode.offsetWidth-a.offsetWidth,e=parseInt(c.min,10),f=parseInt(c.max,10),g=b.newX,h=(f-e)/d*g+e;return Math.round(h)},buildSliders:function(a){var b,c,d,e=SB.spec.findNumberInputs();for(b=function(a,b){a.style.left=SB.spec.findSliderPosition(a,b)+"px",SB.clickDrag({elm:a,restrict:!0,onTween:function(c){var d=SB.spec.findSliderValue(a,c);b.value=d,a.setAttribute("aria-valuenow",d)},onComplete:function(){c(b)}})},c=function(a){var b,c=a.parentNode;if(SB.hasClass(a.nextSibling,"sliderBar")){for(b=a.nextSibling.getElementsByTagName("span")[0],b.style.left=SB.spec.findSliderPosition(b,a)+"px";c!==document&&"form"!==c.tagName.toLowerCase();)c=c.parentNode;"form"===c.tagName.toLowerCase()&&SB.spec.sendInput(c)}},d=0;d<e.length;d+=1)!function(c){var d,e;"number"===c.type&&c.min&&c.max&&(a&&!SB.isChildOf(c,SB.get(a))||(d=document.createElement("div"),d.className="sliderBar",e=document.createElement("span"),e.setAttribute("role","slider"),e.setAttribute("tabindex",0),e.setAttribute("aria-valuenow",c.value),e.setAttribute("aria-valuemin",c.min),e.setAttribute("aria-valuemax",c.max),d.appendChild(e),c.parentNode.insertBefore(d,c.nextSibling),a?b(e,c):SB.event.add(window,"load",function(){b(e,c)})))}(e[d]);a||(SB.event.add(SB.spec.uiComponents.body,"keydown",function(a){var b,c=SB.getTarget(a),d=null;SB.hasClass(c.parentNode,"sliderBar")&&(b=c.parentNode.previousSibling,38===a.keyCode||39===a.keyCode?(d=parseInt(b.value,10)+1,d=d<=b.max?d:b.max):37!==a.keyCode&&40!==a.keyCode||(d=parseInt(b.value,10)-1,d=d>=b.min?d:b.min),d&&d>=b.min&&d<=b.max&&(a.preventDefault(),b.value=d))}),SB.event.add(SB.spec.uiComponents.body,"keyup",function(a){var b=SB.getTarget(a);SB.hasClass(b.parentNode,"sliderBar")&&c(b.parentNode.previousSibling)}),SB.event.add(window,"resize",function(){SB.spec.sliderSetWidths(e)}),SB.event.add(SB.spec.uiComponents.body,"change",function(a){c(SB.getTarget(a))}))},sliderSetWidths:function(){var a,b,c=SB.spec.findNumberInputs();for(b=0;b<c.length;b+=1)SB.hasClass(c[b].nextSibling,"sliderBar")&&(a=c[b].nextSibling.getElementsByTagName("span")[0],a.style.left=SB.spec.findSliderPosition(a,c[b])+"px")},command:function(){var a=null,b=0,c=750,d=!1,e=!1,f=!1,g=!1,h=0,i=0,j=5,k=null,l=450,m=function(){a=null,c=750,b=0,f=!0,e=!1,g=!1,h=0,i=0},n=function(b){var c=a;SB.vibrate(),SB.spec.sendTextInput(b,c,"text"),m()},o=function(a){var b=SB.getTarget(a),c=b.tagName.toLowerCase(),d=null;return b="img"===c?b.parentNode:b,b="i"===c?b.parentNode:b,b="span"===c?b.parentNode:b,"a"===b.tagName.toLowerCase()&&(d=b),d},p=function(){var d,e=(new Date).getTime();a&&!f&&(SB.vibrate(),SB.spec.socket?SB.spec.checkConnection()&&(SB.log("Issued","Command","success"),SB.spec.socket.send(a)):(d={path:a,param:"ts="+e,method:"GET",onComplete:function(){SB.log(d.response)}},SB.ajax.request(d)),b>3&&(c=650),b>10&&(c=500),b+=1,setTimeout(p,c))},q=function(b,c){var d=o(b);c?(SB.vibrate(),a=SB.getTarget(b).parentNode.parentNode.id,k=SB.transcribe(n),k.start()):d&&!f&&("external"===d.rel?window.open(d.href,"_blank").focus():(a=d.href,p()))};"ontouchstart"in document.documentElement&&(SB.log("Enabled","Touch Events","info"),SB.event.add(SB.spec.uiComponents.body,"touchstart",function(a){d=!0,e=!0,o(a)&&(f=!1,h=parseInt(a.changedTouches[0].clientX,10),i=parseInt(a.changedTouches[0].clientY,10),setTimeout(function(){g||(d=!1,q(a))},l))}),SB.event.add(SB.spec.uiComponents.body,"contextmenu",function(a){a.preventDefault()}),SB.event.add(SB.spec.uiComponents.body,"touchend",function(a){!SB.hasClass(SB.getTarget(a).parentNode,"emoji")&&d&&(g=!0,q(a)),m(a)}),SB.event.add(SB.spec.uiComponents.body,"touchmove",function(a){e&&(Math.abs(parseInt(a.changedTouches[0].clientX,10)-h)>j||Math.abs(parseInt(a.changedTouches[0].clientY,10)-i)>j)&&m(a)}),SB.event.add(SB.spec.uiComponents.body,"touchcancel",function(a){m(a)})),SB.event.add(SB.spec.uiComponents.body,"mousedown",function(a){SB.hasClass(SB.getTarget(a).parentNode,"emoji")?q(a,!0):e===!1&&d===!1&&(f=!1,q(a)),d=!1}),SB.event.add(SB.spec.uiComponents.body,"mouseup",function(a){SB.hasClass(SB.getTarget(a).parentNode,"emoji")||m(a)}),SB.event.add(SB.spec.uiComponents.body,"click",function(a){o(a)&&a.preventDefault()})},sendInput:function(a){var b=SB.getByTag("input",a,"input")[0],c=b.value,d=b.name,e=SB.getByClass("input-type",a,"input")[0].value;"text"===b.type&&(b.value=""),SB.spec.sendTextInput(c,d,e)},sendTextInput:function(a,b,c){var d,e=(new Date).getTime();c=c||"text",SB.spec.socket?SB.spec.checkConnection()&&(SB.log("Issued","Text Command","success"),SB.spec.socket.send("/?"+b+"="+c+"-"+a)):(d={path:"/",param:b+"="+c+"-"+a+"&ts="+e,method:"POST",onComplete:function(){SB.log(d.response)}},SB.ajax.request(d))},formInput:function(){SB.event.add(SB.spec.uiComponents.body,"submit",function(a){var b=SB.getTarget(a);a.preventDefault(),SB.spec.sendInput(b)})},nav:function(){SB.event.add(SB.spec.uiComponents.header,"click",function(a){var b=SB.getTarget(a).parentNode,c=b.tagName.toLowerCase();"li"===c?(a.preventDefault(),SB.spec.navChange(b.className),SB.vibrate(),SB.notifyAsk()):"indicator"===SB.getTarget(a).id&&SB.hasClass(SB.getTarget(a),"disconnected")&&SB.spec.socketConnect(0)})},init:function(){var a,b,c,d=SB.storage("selected"),e=SB.storage("templates"),f=SB.storage("state");if(SB.spec.uiComponents.header=SB.getByTag("header")[0],SB.spec.uiComponents.body=SB.getByTag("main")[0],SB.spec.buildIndicator(),b=SB.spec.uiComponents.header.dataset,c=SB.spec.uiComponents.body.dataset,SB.spec.strings={CONNECTED:b.stringConnected,CONNECTING:b.stringConnecting,DISCONNECTED:b.stringDisconnected,ACTIVE:c.stringActive,INACTIVE:c.stringInactive,ON:c.stringOn,OFF:c.stringOff,AM:c.stringAm,PM:c.stringPm,SUN:c.stringSun,MON:c.stringMon,TUE:c.stringTue,WED:c.stringWed,THUR:c.stringThur,FRI:c.stringFri,SAT:c.stringSat},d&&SB.spec.navChange(d),e&&f){SB.spec.uiComponents.templates=SB.decode(e),f=SB.decode(f);for(a in f)f.hasOwnProperty(a)&&SB.spec.updateTemplate(f[a])}"function"==typeof WebSocket||"object"==typeof WebSocket?SB.spec.socketConnect(0):SB.spec.statePoller(),SB.spec.lazyLoad(document.body.className),SB.spec.buildSliders(),SB.spec.command(),SB.spec.formInput(),SB.spec.nav()}}}(),function(a){"use strict";a.activeBuilding=function(a,b,c,d,e){var f="",g="",h="",i="",j=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"activeBuilding"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"activeBuilding",e)),a},k=function(a){var b,c="";return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.arrayList(a,"activeBuilding",e):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.arrayList(a,"activeBuilding",e)),c};return c&&d&&(i=k(d)),d&&0!==d.length?1===d.length?(g="ok",h="tag",f=j("SINGLE_PACKAGE")):d.length>1&&(g="ok",h="tags",f=j("PLURAL_PACKAGES")):(g="err",h="times",f=j("NO_PACKAGES")),f=f.split("{{SENDERS}}").join(i),b=b.replace("{{ACTIVEBUILDING_STATE}}",g),b=b.replace("{{ACTIVEBUILDING_ICON}}",h),b=b.replace("{{ACTIVEBUILDING_DYNAMIC}}",f)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.debug=function(a,b,c,d,e,f){var g=(new Date).getTime(),h="",i="",j=0,k=0,l=0,m=0,n=0,o=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"debug"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"debug",f)),a},p=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,o):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,o)),c},q=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayRelativeTime(a):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayRelativeTime(a)),c};return d&&(h=q(d.uptime),i=q((g-d.startup)/1e3),j=d.memoryUsed,k=d.totalMemory,l=d.percentMemory,m=Math.round(100*d.cpuLoad[0]),n=d.clientCount),b=b.replace("{{DEBUG_UPDATE}}",p(g)),b=b.replace("{{DEBUG_UPTIME}}",h),b=b.replace("{{DEBUG_RUNTIME}}",i),b=b.replace("{{DEBUG_MEMORY_USED}}",j),b=b.replace("{{DEBUG_SYSTEM_MEMORY}}",k),b=b.replace("{{DEBUG_MEMORY_PERCENT}}",l),b=b.replace("{{DEBUG_CPU}}",m),b=b.replace("{{DEBUG_CLIENT_COUNT}}",n)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.denon=function(a,b,c,d){return d&&(b=b.split("{{DEVICE_POWER}}").join(d.power),d.ZONE1&&(b=b.split("{{DEVICE_Z1_INPUT}}").join(d.ZONE1.input),b=b.split("{{DEVICE_Z1_POWER}}").join(d.ZONE1.power),b=b.split("{{DEVICE_Z1_MUTE}}").join(d.ZONE1.mute),b=b.split("{{DEVICE_Z1_MODE}}").join(d.ZONE1.mode),b=b.split("{{DEVICE_Z1_VOLUME}}").join(d.ZONE1.volume),b=b.split("{{DEVICE_Z1_MAXVOLUME}}").join(d.ZONE1.maxvolume)),d.ZONE2&&(b=b.split("{{DEVICE_Z2_POWER}}").join(d.ZONE2.power),b=b.split("{{DEVICE_Z2_INPUT}}").join(d.ZONE2.input),b=b.split("{{DEVICE_Z2_VOLUME}}").join(d.ZONE2.volume)),d.ZONE3&&(b=b.split("{{DEVICE_Z3_POWER}}").join(d.ZONE3.power),b=b.split("{{DEVICE_Z3_INPUT}}").join(d.ZONE3.input),b=b.split("{{DEVICE_Z3_VOLUME}}").join(d.ZONE3.volume))),b=b.split("{{DEVICE_POWER}}").join(""),b=b.split("{{DEVICE_Z1_POWER}}").join(""),b=b.split("{{DEVICE_Z1_INPUT}}").join(""),b=b.split("{{DEVICE_Z1_MUTE}}").join(""),b=b.split("{{DEVICE_Z1_MODE}}").join(""),b=b.split("{{DEVICE_Z1_VOLUME}}").join(""),b=b.split("{{DEVICE_Z1_MAXVOLUME}}").join(""),b=b.split("{{DEVICE_Z2_POWER}}").join(""),b=b.split("{{DEVICE_Z2_INPUT}}").join(""),b=b.split("{{DEVICE_Z2_VOLUME}}").join(""),b=b.split("{{DEVICE_Z3_POWER}}").join(""),b=b.split("{{DEVICE_Z3_INPUT}}").join(""),b=b.split("{{DEVICE_Z3_VOLUME}}").join("")}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.foscam=function(a,b,c,d,e){var f,g,h="",i="",j="",k=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"foscam"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"foscam",e)),a};return"on"===d?(h=" device-active",j=k("CAMERA_ARMED")):"off"===d&&(i=" device-active",j=k("CAMERA_DISARMED")),b=b.split("{{DEVICE_STATE_ON}}").join(h),b=b.split("{{DEVICE_STATE_OFF}}").join(i),b=b.split("{{ARMED_STATUS}}").join(j),b=b.split("{{DISARMED_STATUS}}").join(j),"object"==typeof SB&&(f=SB.getByClass("fa-lock",SB.get(a),"a")[0],g=SB.getByClass("fa-unlock",SB.get(a),"a")[0],"on"!==d||SB.hasClass(f,"device-on")?"off"!==d||SB.hasClass(g,"device-on")?b=SB.hasClass(SB.getByClass("selected",null,"li")[0],a)?b.split("{{LAZY_LOAD_IMAGE}}").join("src"):b.split("{{LAZY_LOAD_IMAGE}}").join("data-src"):(SB.addClass(g,"device-active"),SB.removeClass(f,"device-active"),SB.putText(SB.getByTag("em",f)[0],j),SB.putText(SB.getByTag("em",g)[0],j),b=""):(SB.addClass(f,"device-active"),SB.removeClass(g,"device-active"),SB.putText(SB.getByTag("em",f)[0],j),SB.putText(SB.getByTag("em",g)[0],j),b="")),b}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.gerty=function(a,b,c,d,e,f){var g,h,i,j,k=e.comment,l="",m="",n=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"gerty"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"gerty",f)),a},o=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,n):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,n)),c};if(d.comments)for(h in d.comments)d.comments.hasOwnProperty(h)&&(g=o(d.comments[h].time),m+=k.split("{{TIME}}").join(g),m=m.split("{{CODE}}").join(d.comments[h].code),m=m.split("{{NAME}}").join(d.comments[h].name),m=m.split("{{COMMENT}}").join(d.comments[h].text));return"object"==typeof SB?(i=SB.getByTag("span",SB.get(a))[0],j=SB.getByTag("ol",SB.get(a))[0],i&&i.innerHTML!==d.emoji&&(SB.putText(i,d.emoji),i.className=d.action||""),j&&j.innerHTML!==m&&(j.innerHTML=m,j.scrollTop=j.scrollHeight),b=""):(d.action&&(l=' class="'+d.action+'"'),b=b.split("{{GERTY_ACTION}}").join(l),b=b.split("{{GERTY_DYNAMIC}}").join(d.emoji),b=b.split("{{GERTY_COMMENTS}}").join(m)),b}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.github=function(a,b,c,d,e,f){var g=e.commit,h=e.message,i="",j="",k=0,l=null,m=null,n="",o=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"github"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"github",f)),a},p=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,o,"long"):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,o,"long")),c};if(c&&d)for(k;k<d.length;k+=1)j=p(d[k].time),i+=g.split("{{GITHUB_URL}}").join(d[k].url),i=i.split("{{GITHUB_TITLE}}").join(j),i=i.split("{{GITHUB_DESCRIPTION}}").join(d[k].description),d[k].upToDate===!1?m="NEWER":d[k].upToDate===!0&&(l="LATEST");return b=b.replace("{{GITHUB_DYNAMIC}}",i),m?n=o(m):l&&(n=o(l)),i=h.replace("{{GITHUB_MESSAGE}}",n),b=b.replace("{{GITHUB_MESSAGE}}",i)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.location=function(a,b,c,d,e,f){var g=e.item,h="",i=0,j=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"location"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"location",f)),a},k=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,j):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,j)),c};if(c&&d)for(i;i<d.length;i+=1)h+=g.split("{{LOCATION_NAME}}").join(d[i].name),h=h.split("{{LOCATION_URL}}").join(d[i].url),h=h.split("{{LOCATION_TIME}}").join(k(d[i].time)),h=h.split("{{LOCATION_ALTITUDE}}").join(d[i].alt),h=h.split("{{LOCATION_SPEED}}").join(Math.ceil(d[i].speed));return b=b.replace("{{LOCATION_DYNAMIC}}",h)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.nest=function(a,b,c,d,e,f){var g,h,i,j,k=e.thermostat,l=e.protect,m=e.group,n="",o="",p="",q={},r=function(a){var b;return"object"==typeof SB?a=SB.util.encodeName(a):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.encodeName(a)),"group-"+a},s=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"nest"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"nest",f)),a};if(d){for(g in d.devices)if(d.devices.hasOwnProperty(g))if(q=d.devices[g],"thermostat"===q.type){switch("object"==typeof SB&&(SB.getByClass(r(q.label),SB.get(a),"li")[0]?(j=SB.getByClass(r(q.label),SB.get(a),"li")[0],h=SB.getByClass("fa-sun-o",j,"a")[0],i=SB.getByClass("fa-asterisk",j,"a")[0],"cool"!==q.state||SB.hasClass(i,"device-active")?"heat"!==q.state||SB.hasClass(h,"device-active")?"off"!==q.state||SB.hasClass(j,"device-off")||(SB.addClass(j,"device-off"),SB.removeClass(i,"device-active"),SB.removeClass(h,"device-active"),SB.putText(SB.getByTag("em",j)[0],s("OFF")),b=""):(SB.addClass(h,"device-active"),SB.removeClass(i,"device-active"),SB.removeClass(j,"device-off"),SB.putText(SB.getByTag("em",j)[0],s("HEAT")),b=""):(SB.addClass(i,"device-active"),SB.removeClass(h,"device-active"),SB.removeClass(j,"device-off"),SB.putText(SB.getByTag("em",j)[0],s("COOL")),b="")):SB.spec.buildSliders(a)),n+=k.split("{{SUB_DEVICE_ID}}").join(r(q.label)),n=n.split("{{SUB_DEVICE_NAME}}").join(q.label),n=n.split("{{SUB_DEVICE_TEMP}}").join(Math.round(q.temp)),n=n.split("{{SUB_DEVICE_TARGET}}").join(Math.round(q.target)),n=n.split("{{SUB_DEVICE_HUMIDITY}}").join(Math.round(q.humidity)),q.state){case"cool":n=n.split("{{DEVICE_STATE_COOL}}").join(" device-active"),n=n.split("{{SUB_DEVICE_STATUS}}").join(s("COOL"));
break;case"heat":n=n.split("{{DEVICE_STATE_HEAT}}").join(" device-active"),n=n.split("{{SUB_DEVICE_STATUS}}").join(s("HEAT"));break;default:n=n.split("{{DEVICE_STATE_OFF}}").join(" device-off"),n=n.split("{{SUB_DEVICE_STATUS}}").join(s("OFF"))}q.leaf===!0&&(n=n.split("{{DEVICE_STATE_LEAF}}").join(" device-active")),n=d.presence&&"on"===d.presence?n.split("{{DEVICE_STATE_HOME}}").join(" device-active"):n.split("{{DEVICE_STATE_AWAY}}").join(" device-active"),n=n.split("{{DEVICE_STATE_COOL}}").join(""),n=n.split("{{DEVICE_STATE_HEAT}}").join(""),n=n.split("{{DEVICE_STATE_OFF}}").join(""),n=n.split("{{DEVICE_STATE_LEAF}}").join(""),n=n.split("{{DEVICE_STATE_HOME}}").join(""),n=n.split("{{DEVICE_STATE_AWAY}}").join("")}else"protect"===q.type&&(p="","ok"!==q.smoke&&(p+="smoke "),"ok"!==q.co&&(p+="co "),"ok"!==q.battery&&(p+="batt "),p&&(p+="device-active"),o+=l.split("{{SUB_DEVICE_STATE}}").join(p),o=o.split("{{SUB_DEVICE_NAME}}").join(q.label),o=o.split("{{SUB_DEVICE_SMOKE}}").join(q.smoke),o=o.split("{{SUB_DEVICE_CO}}").join(q.co),o=o.split("{{SUB_DEVICE_BATT}}").join(q.battery));n&&(n=m.replace("{{SUB_DEVICE_LIST}}",n),n=n.replace("{{SUB_DEVICE_CLASS}}"," control-device-status"),n=n.replace("{{SUB_DEVICE_NAME}}",s("THERMOSTAT"))),o&&(o=m.replace("{{SUB_DEVICE_LIST}}",o),o=o.replace("{{SUB_DEVICE_CLASS}}"," text-device-status"),o=o.replace("{{SUB_DEVICE_NAME}}",s("PROTECT")))}return b=b.replace("{{NEST_DYNAMIC}}",n+o)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.raspberryRemote=function(a,b,c,d,e){var f,g=e["switch"],h=0,i="",j=function(a){var b=g,c="";return c=b.split("{{SUB_DEVICE_ID}}").join(a.label.split(" ").join("+")),c=c.split("{{SUB_DEVICE_NAME}}").join(a.label)};if(d&&"object"==typeof d&&(f=d.devices))for(h in f)f.hasOwnProperty(h)&&(i+=j(f[h]),i=i.split("{{SUB_DEVICE_CLASS}}").join(f[h].className||"fa-lightbulb-o"));return b.replace("{{RASPBERRY_REMOTE_DYNAMIC}}",i)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.roku=function(a,b,c,d,e){var f=e.list,g=0,h="";if(d)for(g in d)d.hasOwnProperty(g)&&(h+=f.split("{{APP_ID}}").join(d[g].id),h=h.split("{{APP_IMG}}").join(d[g].cache),h=h.split("{{APP_NAME}}").join(d[g].name));return b.replace("{{ROKU_DYNAMIC}}",h)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.rss=function(a,b,c,d,e){var f=e.item,g="",h=0,i="";if(c&&d)for(h;h<d.length;h+=1)i=d[h].description?d[h].description:d[h].text,g+=f.split("{{RSS_URL}}").join(d[h].url),g=g.split("{{RSS_TITLE}}").join(d[h].title),g=g.split("{{RSS_DESCRIPTION}}").join(i);return b=b.replace("{{RSS_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.smartthings=function(a,b,c,d,e,f){var g,h,i=e.action,j=e["static"],k=e.group,l=0,m=0,n="",o="",p="",q=function(a){var b;return"object"==typeof SB?a=SB.util.encodeName(a):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.encodeName(a)),"group-"+a},r=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"smartthings"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"smartthings",f)),a},s=function(a,b){var c={},d=[],e=0,f=0;for(e in b)b.hasOwnProperty(e)&&(c=b[e],c.label===a&&(d[f]=c,f+=1));return d},t=function(a){var b="",c="",d="",e="",f="";switch(a.type){case"switch":b=i,d="fa-lightbulb-o";break;case"lock":b=i,d="fa-unlock-alt";break;case"contact":b=j,d="fa-columns";break;case"water":b=j,d="fa-tint";break;case"motion":b=j,d="fa-paw";break;case"presence":b=j,d="fa-male"}return a.peripheral&&a.peripheral.temp&&(e=" ("+a.peripheral.temp+"&deg;)"),a.peripheral&&"on"===a.peripheral.vibrate&&(f=" device-vibrate"),b&&(c=b.split("{{SUB_DEVICE_ID}}").join(a.label.split(" ").join("+")),c=c.split("{{SUB_DEVICE_NAME}}").join(a.label+e),c=c.split("{{SUB_DEVICE_CLASS}}").join(a.className||d),"on"===a.state?(c=c.split("{{SUB_DEVICE_STATE}}").join(" device-active"+f),c=c.split("{{SUB_DEVICE_STATUS}}").join(r("ACTIVE"))):(c=c.split("{{SUB_DEVICE_STATE}}").join(f),c=c.split("{{SUB_DEVICE_STATUS}}").join(r("INACTIVE")))),c};if(d&&"object"==typeof d&&"string"==typeof d.mode){if(o=d.mode,g=d.devices)if(d.groups){for(l in d.groups)if(d.groups.hasOwnProperty(l)){n+=k,p="";for(m in d.groups[l])d.groups[l].hasOwnProperty(m)&&(h=s(d.groups[l][m],g),h&&h[0]&&(p+=t(h[0])));n=n.split("{{GROUP_CLASS}}").join(q(l)),n=n.split("{{GROUP_TITLE}}").join(l),n=n.split("{{SUB_DEVICE_LIST}}").join(p)}}else for(l in g)g.hasOwnProperty(l)&&(n+=t(g[l]));switch(o){case"Home":b=b.split("{{DEVICE_STATE_HOME}}").join(" device-active"),b=b.split("{{HOME_STATUS}}").join(r("ACTIVE"));break;case"Away":b=b.split("{{DEVICE_STATE_AWAY}}").join(" device-active"),b=b.split("{{AWAY_STATUS}}").join(r("ACTIVE"));break;case"Night":b=b.split("{{DEVICE_STATE_NIGHT}}").join(" device-active"),b=b.split("{{NIGHT_STATUS}}").join(r("ACTIVE"))}}return b=b.split("{{DEVICE_STATE_HOME}}").join(""),b=b.split("{{DEVICE_STATE_AWAY}}").join(""),b=b.split("{{DEVICE_STATE_NIGHT}}").join(""),b=b.split("{{HOME_STATUS}}").join(r("INACTIVE")),b=b.split("{{AWAY_STATUS}}").join(r("INACTIVE")),b=b.split("{{NIGHT_STATUS}}").join(r("INACTIVE")),b.replace("{{SMARTTHINGS_DYNAMIC}}",n)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.sports=function(a,b,c,d,e,f){var g=e.league,h=e.game,i=0,j=0,k={},l={},m="",n="",o="",p="",q="",r=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"sports"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"sports",f)),a},s=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,r):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,r)),c};if(c&&d)for(i in d)if(d.hasOwnProperty(i)){for(k=d[i],q="",j=0;j<k.games.length;j+=1)l=k.games[j],m=r("TITLE").split("{{AWAY}}").join(l.away.title).split("{{HOME}}").join(l.home.title),n=l.away.winner?" winner":"",o=l.home.winner?" winner":"",q+=h.split("{{GAME_LINK}}").join(l.url),q=q.split("{{GAME_TITLE}}").join(m),q=q.split("{{GAME_AWAY_WINNER}}").join(n),q=q.split("{{GAME_AWAY_TEAM}}").join(l.away.title),q=q.split("{{GAME_AWAY_IMAGE}}").join(l.away.image),q=q.split("{{GAME_AWAY_SCORE}}").join(l.away.score),q=q.split("{{GAME_HOME_WINNER}}").join(o),q=q.split("{{GAME_HOME_TEAM}}").join(l.home.title),q=q.split("{{GAME_HOME_IMAGE}}").join(l.home.image),q=q.split("{{GAME_HOME_SCORE}}").join(l.home.score),q=q.split("{{GAME_TIME}}").join(s(l.time)),q=q.split("{{GAME_STATUS}}").join((l.status||"").toLowerCase()),q=q.split("{{GAME_STATE}}").join(r(l.status));p+=g.split("{{LEAGUE_NAME}}").join(k.title),p=p.split("{{GAME_LIST}}").join(q)}return b.replace("{{SPORTS_DYNAMIC}}",p)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.stocks=function(a,b,c,d,e,f){var g=e.list,h=0,i="",j="",k="",l="",m=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"stocks"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"stocks",f)),a};if(d)for(h in d)d.hasOwnProperty(h)&&(j="neutral",k="arrows-h",l=m("NEUTRAL"),d[h].dayChangeValue&&(0===d[h].dayChangeValue.indexOf("+")?(j="gain",k="arrow-up",l=m("GAIN")):0===d[h].dayChangeValue.indexOf("-")&&(j="loss",k="arrow-down",l=m("LOSS"))),i+=g.split("{{STOCK_CHANGE}}").join(j),i=i.split("{{STOCK_ARROW}}").join(k),i=i.split("{{STOCK_DIRECTION}}").join(l),i=i.split("{{STOCK_NAME}}").join(d[h].name),i=i.split("{{STOCK_PRICE}}").join(d[h].price),i=i.split("{{STOCK_CHANGE_VALUE}}").join(d[h].dayChangeValue),i=i.split("{{STOCK_CHANGE_PERCENT}}").join(d[h].dayChangePercent));return b.replace("{{STOCKS_DYNAMIC}}",i)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.traffic=function(a,b,c,d,e){var f=e.list,g=0,h="";if(d)for(g in d)d.hasOwnProperty(g)&&(h+=f.split("{{CAM_IMG}}").join(d[g].image),h=h.split("{{CAM_NAME}}").join(d[g].title));return b.replace("{{TRAFFIC_DYNAMIC}}",h)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.travis=function(a,b,c,d,e){var f=e.build,g="",h="",i="",j=0;if(c&&d)for(j;j<d.length;j+=1)h="",i="","created"===d[j].state||"started"===d[j].state?h="cogs":"ok"===d[j].status?h="check":"err"===d[j].status&&(h="times"),d[j].duration&&(i=" ("+d[j].duration+"s)"),g+=f.split("{{TRAVIS_URL}}").join(d[j].url),g=g.split("{{TRAVIS_ICON}}").join(h),g=g.split("{{TRAVIS_STATE}}").join(d[j].status),g=g.split("{{TRAVIS_DURATION}}").join(i),g=g.split("{{TRAVIS_DESCRIPTION}}").join(d[j].label);return b=b.replace("{{TRAVIS_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.twitter=function(a,b,c,d,e){var f=e.tweet,g="",h=0;if(c&&d)for(h;h<d.length;h+=1)g+=f.split("{{TWEET_TEXT}}").join(d[h].text),g=g.split("{{TWEET_URL}}").join(d[h].url),g=g.split("{{TWEET_AUTHOR}}").join(d[h].author);return b=b.replace("{{TWITTER_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.weather=function(a,b,c,d,e,f){var g,h,i=e.forecast,j=0,k="";if(g=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"weather"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"weather",f)),a},h=function(a){var b="";return a=parseInt(a,10),b=2>=a?"warning":4>=a?"bolt":8>=a?"asterisk":12>=a?"tint":18>=a?"asterisk":22>=a?"fire":24>=a?"flag":25===a||35===a?"asterisk":30>=a?"cloud":31===a||33===a?"moon-o":32===a||34===a||36===a?"sun-o":39>=a?"bolt":40===a?"tint":43>=a?"asterisk":44===a?"cloud":45===a?"bolt":46===a?"asterisk":47===a?"bolt":"question"},d&&d.code){b=b.replace("{{WEATHER_ICON}}",h(d.code)),b=b.replace("{{WEATHER_CURRENT}}",d.city+" "+g("CURRENT")+": "+d.temp+"&deg; "+d.text),b=b.replace("{{WEATHER_SUNRISE}}",d.sunrise),b=b.replace("{{WEATHER_SUNSET}}",d.sunset);for(j in d.forecast)d.forecast.hasOwnProperty(j)&&(k+=i.split("{{WEATHER_ICON}}").join(h(d.forecast[j].code)),k=k.split("{{WEATHER_DAY}}").join(d.forecast[j].day+":"),k=k.split("{{WEATHER_TEXT}}").join(d.forecast[j].text),k=k.split("{{WEATHER_HIGH}}").join(d.forecast[j].high+"&deg;"),k=k.split("{{WEATHER_LOW}}").join(d.forecast[j].low+"&deg;"))}else b=b.replace("{{WEATHER_CURRENT}}",g("UNAVAILABLE")),b=b.replace("{{WEATHER_SUNRISE}}",""),b=b.replace("{{WEATHER_SUNSET}}",""),"string"==typeof d&&(k=d);return b.replace("{{WEATHER_DYNAMIC}}",k)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.website=function(a,b,c,d){var e="";return d&&d.source&&(e=d.source),b.replace("{{WEBSITE_DYNAMIC}}",e)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.wemo=function(a,b,c,d,e,f){var g,h=e["switch"],i=e.group,j=0,k=0,l="",m="",n="",o=function(a){var b;return"object"==typeof SB?a=SB.util.encodeName(a):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.encodeName(a)),a},p=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"wemo"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"wemo",f)),a},q=function(a,b){var c={},d=0;for(d in b)if(b[d].label===a){c=b[d];break}return c},r=function(a){var b="";return m&&(m+="device-active"),b=h.split("{{SUB_DEVICE_ID}}").join(a.label.split(" ").join("+")),b=b.split("{{SUB_DEVICE_NAME}}").join(a.label),b=b.split("{{SUB_DEVICE_CLASS}}").join(a.className||"fa-lightbulb-o"),"on"===a.state?(b=b.split("{{SUB_DEVICE_STATE}}").join(" device-active"),b=b.split("{{SUB_DEVICE_STATUS}}").join(p("ACTIVE"))):"off"===a.state?(b=b.split("{{SUB_DEVICE_STATE}}").join(""),b=b.split("{{SUB_DEVICE_STATUS}}").join(p("INACTIVE"))):(b=b.split("{{SUB_DEVICE_STATE}}").join(" device-off"),b=b.split("{{SUB_DEVICE_STATUS}}").join(p("INACTIVE"))),b};if(d&&d.devices){if(d.groups){for(j in d.groups)if(d.groups.hasOwnProperty(j)){l+=i,n="";for(k in d.groups[j])d.groups[j].hasOwnProperty(k)&&(g=q(d.groups[j][k],d.devices),g&&(n+=r(g)));l=l.split("{{GROUP_CLASS}}").join(o(j)),l=l.split("{{GROUP_TITLE}}").join(j),l=l.split("{{SUB_DEVICE_LIST}}").join(n)}}else for(j in d.devices)d.devices.hasOwnProperty(j)&&(l+=r(d.devices[j]));l&&(l=l.replace("{{SUB_DEVICE_CLASS}}"," text-device-status"))}return b.replace("{{WEMO_DYNAMIC}}",l)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.xbmc=function(a,b,c,d,e){var f=e.current,g="";return d&&d.current&&(g=f.split("{{DEVICE_CURRENT}}").join(d.current)),b.replace("{{XBMC_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.util={version:20151215,replaceAll:function(a,b,c){var d=a;return"string"==typeof a&&(d=a.replace(new RegExp(b,"g"),c)),d},stripTags:function(a){return"string"==typeof a?a.replace(/(<([^>]+)>)/gi,""):a},stripControl:function(a){return"string"==typeof a?a.replace(new RegExp("[\x00-]+","g"),""):a},sanitize:function(a){return this.stripTags(this.stripControl(a))},encodeName:function(a){return a&&"string"==typeof a&&(a=a.replace(/[\s!@#$%^&*()"'\\<>,;.:/+]/g,"_").toLowerCase()),a},translate:function(a,b,c){var d,e="";return a&&"string"==typeof a?(a=a.toUpperCase(),"object"==typeof SB?(c=document.documentElement.getAttribute("lang"),d=function(a,b){var c=SB.getByClass(b,SB.getByTag("main")[0],"section")[0];return a=a.replace("{{i18n_","").replace("}}",""),c.dataset&&c.dataset["string"+a.charAt(0)+a.substr(1).toLowerCase()]?a=c.dataset["string"+a.charAt(0)+a.substr(1).toLowerCase()]:SB.spec.strings[a]&&(a=SB.spec.strings[a]),a}):d=require(__dirname+"/translate").translate,e=d("{{i18n_"+a+"}}",b,c)):e=a,e},arrayList:function(a,b,c){var d="",e=0;for(e;e<a.length;e+=1)e&&(e===a.length-1?d=d+" "+this.translate("AND",b,c)+" ":d+=", "),d+=a[e];return d},displayRelativeTime:function(a){var b,c={day:86400,hour:3600,minute:60,second:1},d={day:"00",hour:"00",minute:"00",second:"00"};for(b in c)a>=c[b]&&(d[b]=Math.floor(a/c[b]),d[b]<10&&(d[b]="0"+d[b]),a-=d[b]*c[b]);return d.day+" "+d.hour+":"+d.minute+":"+d.second},displayTime:function(a,b,c,d){var e=d||new Date(a),f=e.getDate(),g=e.getDay(),h={0:"sun",1:"mon",2:"tue",3:"wed",4:"thur",5:"fri",6:"sat"},i=e.getHours(),j=e.getMinutes(),k=b("am"),l="";switch(i>12&&(i-=12,k=b("pm")),i=0===i?12:i,10>j&&(j="0"+j),g=b(h[g]),c){case"long":l=g+" "+f+" @ "+i+":"+j+k;break;default:l=g+" @ "+i+":"+j+k}return l}}}("undefined"==typeof exports?this.SB:exports);
/* 20160718 */
SB=function(){"use strict";return{version:20160329,cancelBubble:function(a){a=a||window.event,a.cancelBubble=!0,a.stopPropagation&&a.stopPropagation()},isChildOf:function(a,b){if(b===a)return!1;for(;a&&a!==b&&a!==document.body;)a=a.parentNode;return a===b},event:{list:[],add:function(a,b,c,d){d=d||!1,a.addEventListener?a.addEventListener(b,c,d):a.attachEvent?a.attachEvent("on"+b,c):a["on"+b]=c,SB.event.list.push([a,b,c])},remove:function(a,b,c,d){d=d||!1;var e=0;for(a.removeEventListener?a.removeEventListener(b,c,d):a.detachEvent?a.detachEvent("on"+b,c):a["on"+b]=null,e;e<SB.event.list.length;e+=1)if(SB.event.list[e]&&SB.event.list[e]&&SB.event.list[e][0]===a&&SB.event.list[e][1]===b&&SB.event.list[e][2]===c){SB.event.list.splice(e,1);break}},removeAll:function(a){a=a||document;var b=SB.event.list.length-1;for(b;b>=0;b-=1)SB.event.list[b]&&(SB.event.list[b][0]!==a&&a!==document||SB.event.remove(SB.event.list[b][0],SB.event.list[b][1],SB.event.list[b][2]))}},getTarget:function(a){return a=a||window.event,a.target?a.target:a.srcElement},hasAttribute:function(a,b,c){if(a[b])return!!a[b].match(new RegExp("(\\s|^)"+c+"(\\s|$)"))},hasClass:function(a,b){var c=!1;return a&&a.className&&(c=!!SB.hasAttribute(a,"className",b)),c},addClass:function(a,b){a&&b&&(SB.hasClass(a,b)||(a.className=SB.trim(a.className+" "+b)))},removeClass:function(a,b){SB.hasClass(a,b)&&(a.className=a.className.replace(new RegExp("(\\s|^)"+b+"(\\s|$)")," "),a.className=SB.trim(a.className))},toggleClass:function(a,b){SB.hasClass(a,b)?SB.removeClass(a,b):SB.addClass(a,b)},setFocus:function(a){"function"==typeof a.setActive?a.setActive():"function"==typeof a.focus&&a.focus()},get:function(a){return document.getElementById(a)},getByTag:function(a,b){return b=b||document,b.getElementsByTagName(a)},getByClass:function(a,b,c){var d=[],e=[],f=0,g=0;if(b=b||document,c=c.toLowerCase()||"*","*"===c&&document.getElementsByClassName)return b.getElementsByClassName(a);if(b.getElementsByClassName)if(e=b.getElementsByClassName(a),c&&e.length)for(f in e)e[f].tagName&&e[f].tagName.toLowerCase()===c&&(d[g]=e[f],g+=1);else d=e;else{e=SB.getByTag(c,b);for(f in e)SB.hasClass(e[f],a)&&(d[g]=e[f],g+=1)}return d},getText:function(a){return a.textContent?a.textContent:a.innerText?a.innerText:a.text?a.text:a.innerHTML},putText:function(a,b){a.textContent?a.textContent=b:a.innerText?a.innerText=b:a.text?a.text=b:a.innerHTML=b},stripUnits:function(a){var b="";return b="string"==typeof a?parseInt(a.replace(new RegExp("(%|px|em)"),""),10):a},trim:function(a){return a=a||"",a.toString().replace(/^\s\s*/,"").replace(/\s\s*$/,"")},replaceAll:function(a,b,c){var d=a;return"string"==typeof a&&(d=a.replace(new RegExp(b,"g"),c)),d},decode:function(a){var b="";return"object"==typeof JSON&&(b=JSON.parse(a)),b},encode:function(a){var b="";return"object"==typeof JSON&&(b=JSON.stringify(a)),b},log:function(a,b,c){var d=new Date,e="color: white";if("object"==typeof console&&"function"==typeof console.log)if(b&&"object"!=typeof a){switch(a="%c"+b+"%c: "+a+" ("+d.getHours()+":"+(d.getMinutes()<10?"0":"")+d.getMinutes()+")",c){case"success":e="color: green";break;case"info":e="color: aqua";break;case"error":e="color: red"}console.log(a,"background: black; "+e,"background: black; color: white")}else console.log(a)},vibrate:function(a){a=a||20,window.navigator&&window.navigator.vibrate?window.navigator.vibrate(a):SB.log("Not supported","Vibrate","error")},notify:function(a,b,c){var d,e;return"function"==typeof Notification&&("granted"===Notification.permission?(d=new Notification(a,b),setTimeout(function(){d.close(),SB.event.remove(d,"click",e)},1e4),e=function(a){window.focus(),c(a),SB.event.remove(d,"click",e)},SB.event.add(d,"click",e)):SB.notifyAsk()),d},notifyAsk:function(){"function"==typeof Notification&&"denied"!==Notification.permission&&Notification.requestPermission(function(a){Notification.permission!==a&&(Notification.permission=a)})},sound:{sounds:{},play:function(a){"function"==typeof Audio&&(SB.sound.sounds[a]||(SB.sound.sounds[a]=new Audio(a)),SB.sound.sounds[a].play())}},speak:function(a,b,c){var d,e;window.speechSynthesis?(d=new SpeechSynthesisUtterance,e=window.speechSynthesis.getVoices(),d.text=a,d.lang=b||"en-US",e&&e[10]&&"Alex"===e[10].name&&(d.voice=e[10],"female"===c&&(d.voice=e[30])),window.speechSynthesis.speak(d)):SB.log("Not supported","Speak","error")},transcribe:function(a){var b,c;return"webkitSpeechRecognition"in window?(SB.log("Supported","Transcribe","info"),b=new webkitSpeechRecognition,c=function(b){a(b.results[0][0].transcript,b.results[0][0].confidence),SB.event.remove(document,"result",c)},SB.event.add(b,"result",c)):SB.log("Not supported","Transcribe","error"),b},storage:function(a,b){var c;return a&&("undefined"!=typeof localStorage?(void 0!==b&&("object"==typeof b&&(b=SB.encode(b)),localStorage.setItem(a,b)),c=localStorage.getItem(a)):SB.log("Not supported","Local Storage","error")),c},ajax:{request:function(a){a.method=a.method||"GET",a.onStart=a.onStart||function(){},a.onComplete=a.onComplete||function(){};var b,c,d="?";if(c=function(){switch(a.onStart(),typeof a.onComplete){case"object":a.onComplete.value?a.onComplete.value=a.response:a.onComplete.childNodes[0]&&SB.putText(a.onComplete,a.response);break;case"function":a.onComplete()}},window.XMLHttpRequest)b=new XMLHttpRequest;else{if(!window.ActiveXObject)return!1;b=new ActiveXObject("Microsoft.XMLHTTP")}"GET"===a.method&&(a.path.indexOf("?")===-1&&a.param.indexOf("?")===-1||(d="&"),a.path=a.path+d+a.param,a.param=""),b.open(a.method.toUpperCase(),a.path,!0),"POST"===a.method&&b.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),b.setRequestHeader("rest","true"),SB.event.add(b,"readystatechange",function(){if(4===b.readyState){if(200!==b.status)return!1;a.response=b.responseText,c()}}),b.send(a.param)}},findMousePosition:function(a){var b;return b=a.touches&&a.touches.length?{positionX:a.touches[0].clientX,positionY:a.touches[0].clientY}:window.event?{positionX:window.event.clientX,positionY:window.event.clientY}:{positionX:a.clientX,positionY:a.clientY}},findStyle:function(a,b){var c="";if(a.currentStyle)b=b.replace(/-\w/g,function(a){return a.charAt(1).toUpperCase()}),c=a.currentStyle[b];else{if(!window.getComputedStyle)return 0;c=document.defaultView.getComputedStyle(a,null).getPropertyValue(b)}return c&&(c.indexOf("px")===-1&&c.indexOf("em")===-1&&c.indexOf("%")===-1||(c=SB.stripUnits(c)),"opacity"===b&&(c=parseFloat(c,10))),c},findScroll:function(){var a=0;return"number"==typeof window.pageYOffset?a={positionX:window.pageXOffset,positionY:window.pageYOffset}:document.body&&document.body.scrollTop?a={positionX:document.body.scrollWidth,positionY:document.body.scrollTop}:document.documentElement&&document.documentElement.scrollTop&&(a={positionX:document.documentElement.scrollWidth,positionY:document.documentElement.scrollTop}),a},clickDrag:function(a){a.dragElm=a.dragElm||a.elm,a.restrict=a.restrict||!1,a.onStart=a.onStart||function(){},a.onTween=a.onTween||function(){},a.onComplete=a.onComplete||function(){};var b,c,d=void 0===document.body.ontouchstart?"mousedown":"touchstart",e=void 0===document.body.ontouchmove?"mousemove":"touchmove",f=void 0===document.body.ontouchend?"mouseup":"touchend",g=SB.findStyle(a.elm.parentNode,"border-left-width")+SB.findStyle(a.elm.parentNode,"border-right-width"),h=SB.findStyle(a.elm.parentNode,"border-top-width")+SB.findStyle(a.elm.parentNode,"border-bottom-width");b=function(b){if(SB.hasClass(a.elm,"active")){SB.cancelBubble(b),b.preventDefault&&b.preventDefault();var c,d,e=SB.findMousePosition(b),f=e.positionX,i=e.positionY,j=a.dragElm.offsetWidth,k=a.dragElm.offsetHeight;return a.newX=f-a.clickOffsetX+a.startOffsetX-(a.startWidth-SB.findScroll().positionX),a.newY=i-a.clickOffsetY+a.startOffsetY-(a.startHeight-SB.findScroll().positionY),a.restrict&&(c=a.elm.parentNode.offsetWidth-j-g,d=a.elm.parentNode.offsetHeight-k-h,a.newX>c&&(a.newX=c),a.newX<0&&(a.newX=0),a.newY>d&&(a.newY=d),a.newY<0&&(a.newY=0)),a.elm.style.margin=0,a.elm.style.left=a.newX+"px",a.elm.style.top=a.newY+"px",a.onTween(a),!1}},c=function(){SB.hasClass(a.elm,"active")&&(SB.removeClass(a.elm,"active"),SB.event.remove(document,"mousemove",b),SB.event.remove(document,"mouseup",c),a.onComplete(a))},SB.event.add(a.dragElm,d,function(d){var g=SB.findMousePosition(d);SB.clickDrag.zindex=SB.clickDrag.zindex||1,SB.cancelBubble(d),a.clickOffsetX=g.positionX,a.clickOffsetY=g.positionY,a.startOffsetX=a.elm.offsetLeft,a.startOffsetY=a.elm.offsetTop,a.startWidth=SB.findScroll().positionX,a.startHeight=SB.findScroll().positionY,a.elm.style.zIndex=SB.clickDrag.zindex+=1,a.elm.style.margin=0,a.elm.style.bottom="auto",a.elm.style.right="auto",a.elm.style.position="absolute",SB.addClass(a.elm,"active"),a.onStart(),d.preventDefault&&d.preventDefault(),SB.event.add(document,e,b),SB.event.add(document,f,c),b(d)})},init:function(){SB.spec&&SB.spec.init&&SB.spec.init(),SB.addClass(document.body,"rich")}}}(),document.addEventListener&&document.addEventListener("DOMContentLoaded",SB.init,!1),SB.event.add(window,"load",function(){"use strict";document.addEventListener||SB.init()}),SB.event.add(window,"unload",function(){"use strict";SB.event.removeAll()}),"object"==typeof module&&(module.exports=SB),SB.spec=function(){"use strict";return{version:20160530,state:{},parsers:{},templates:{},strings:{},socket:{},uiComponents:{header:{},body:{},indicator:{},templates:[]},ariaDevice:function(){var a=SB.getByClass("selected",SB.spec.uiComponents.header,"li")[0],b=SB.getByTag("h2",SB.spec.uiComponents.header)[0],c=SB.spec.strings.CURRENT.split("{{DEVICE}}").join(SB.getText(a));SB.putText(b,c)},navChange:function(a){var b=SB.getByClass(a,SB.spec.uiComponents.header,"li")[0],c=SB.get(a),d=SB.getByClass("selected",SB.spec.uiComponents.header,"li")[0],e=SB.getByClass("selected",SB.spec.uiComponents.body,"section")[0];b&&!SB.hasClass(b,"selected")&&(SB.removeClass(d,"selected"),SB.removeClass(e,"selected"),SB.spec.lazyLoad(a),SB.storage("selected",a),SB.addClass(b,"selected"),SB.addClass(c,"selected"),SB.spec.sliderSetWidths(),SB.spec.lazyUnLoad(e),SB.spec.ariaDevice())},updateTemplate:function(a){var b,c,d,e,f=SB.get(a.deviceId),g=SB.spec.parsers[a.typeClass],h=a.value,i=a.state,j=document.createElement("div");SB.spec.state[a.deviceId]=a,SB.log("Updated",a.deviceId,"success"),f&&(d=SB.spec.uiComponents.templates[a.typeClass].markup,c=SB.hasClass(f,"selected")?" selected":"",e=f.cloneNode(!0),b=SB.getByTag("h1",e)[0],b.parentNode.removeChild(b),e=e.innerHTML,g&&(d=g(a.deviceId,d,i,h,SB.spec.uiComponents.templates[a.typeClass].fragments)),"ok"===i?(d=d.split("{{DEVICE_ACTIVE}}").join(SB.spec.strings.ACTIVE),SB.hasClass(f,"device-off")&&(SB.removeClass(f,"device-off"),SB.addClass(f,"device-on"),SB.putText(SB.getByTag("em",SB.getByTag("h1",f)[0])[0],SB.spec.strings.ACTIVE))):(d=d.split("{{DEVICE_ACTIVE}}").join(SB.spec.strings.INACTIVE),SB.hasClass(f,"device-on")&&(SB.removeClass(f,"device-on"),SB.addClass(f,"device-off"),SB.putText(SB.getByTag("em",SB.getByTag("h1",f)[0])[0],SB.spec.strings.INACTIVE))),f&&d&&a&&(SB.storage("state",SB.spec.state),d=d.split("{{DEVICE_ID}}").join(a.deviceId),d=d.split("{{DEVICE_TYPE}}").join(a.typeClass),d=d.split("{{DEVICE_SELECTED}}").join(c),d="ok"===a.state?d.split("{{DEVICE_STATE}}").join(" device-on"):d.split("{{DEVICE_STATE}}").join(" device-off"),d=c?d.split("{{LAZY_LOAD_IMAGE}}").join("src"):d.split("{{LAZY_LOAD_IMAGE}}").join("data-src")),d&&(j.innerHTML=d,j=SB.getByTag("section",j)[0],b=SB.getByTag("h1",j)[0],b.parentNode.removeChild(b),j.innerHTML!==e&&(SB.getByClass("sliderBar",f,"div")[0]?(SB.event.removeAll(SB.getByClass("sliderBar",f,"div")[0].getElementsByTagName("span")[0]),f.outerHTML=d,SB.spec.buildSliders(a.deviceId)):f.outerHTML=d)))},buildIndicator:function(){var a;SB.get("indicator")||(a=document.createElement("span"),a.id="indicator",SB.addClass(a,"connecting"),SB.putText(a,SB.spec.strings.CONNECTING),SB.spec.uiComponents.indicator=a,SB.spec.uiComponents.header.appendChild(a))},checkConnection:function(){var a=SB.spec.socket.readyState<=1;return a||(SB.spec.socketConnect(0),a=SB.spec.socket.readyState<=1),a},socketConnect:function(a){var b,c,d,e,f,g,h="https:"===window.location.protocol?"wss":"ws";SB.spec.socket.readyState&&3!==SB.spec.socket.readyState||(SB.log("Connecting","WebSocket","info"),SB.spec.socket=new WebSocket(h+"://"+window.location.host,"echo-protocol"),a+=1,b=function(){var b=Math.round(Math.min(Math.max(a*(15*Math.random()),10),60));SB.log("Retrying in "+b+"s","WebSocket","info"),SB.spec.uiComponents.indicator.className="disconnected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.DISCONNECTED),setTimeout(function(){SB.spec.socketConnect(a)},1e3*b)}),c=function(){var a="disconnected"===SB.spec.uiComponents.indicator.className;SB.spec.uiComponents.indicator.className="connected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.CONNECTED),SB.log("Connected","WebSocket","success"),a&&(SB.spec.socket.send("fetch state"),SB.log("Reconnected","WebSocket","success")),SB.event.add(SB.spec.socket,"close",f)},d=function(a){var b,c,d=SB.decode(a.data),e={};if("string"==typeof d.speech)d.speech&&(SB.log(d.speech,"Speech","success"),SB.speak(d.speech,d.language,d.voice));else if("string"==typeof d.sound)SB.log(d.sound,"Sound","success"),SB.sound.play("/mp3/"+d.sound+".mp3");else if("string"==typeof d.vibrate)SB.log(d.vibrate,"Vibrate","success"),SB.vibrate(100*d.vibrate);else if("string"==typeof d.title)c=function(){d.deviceId&&SB.spec.navChange(d.deviceId)},b=SB.notify(d.title,d.options,c);else if("string"==typeof d.deviceId)SB.spec.updateTemplate(d);else if("object"==typeof d){for(e in d)if(d.hasOwnProperty(e))break;if(d[e]&&d[e].deviceId){SB.log("Received","State","success");for(e in d)d.hasOwnProperty(e)&&SB.spec.updateTemplate(d[e])}else d[e]&&d[e].markup&&(SB.spec.uiComponents.templates=d,SB.storage("templates",SB.spec.uiComponents.templates))}},f=function(){SB.event.remove(SB.spec.socket,"close",f),SB.log("Disconnected","WebSocket","error"),b()},e=function(){SB.event.remove(SB.spec.socket,"error",f),SB.log("Error","WebSocket","error"),b()},g=function(){SB.event.remove(SB.spec.socket,"open",c),SB.event.remove(SB.spec.socket,"message",d),SB.event.remove(SB.spec.socket,"error",e),SB.event.remove(SB.spec.socket,"close",g)},SB.event.add(SB.spec.socket,"open",c),SB.event.add(SB.spec.socket,"message",d),SB.event.add(SB.spec.socket,"error",e),SB.event.add(SB.spec.socket,"close",g)},statePoller:function(){var a;SB.log("not supported - using polling","WebSockets","error"),a={path:"/templates/",param:"ts="+(new Date).getTime(),method:"GET",onComplete:function(){SB.spec.uiComponents.templates=SB.decode(a.response),SB.storage("templates",SB.spec.uiComponents.templates)}},SB.ajax.request(a),setInterval(function(){var a={path:"/state/",param:"ts="+(new Date).getTime(),method:"GET",onComplete:function(){var b,c=SB.decode(a.response);if(c){SB.spec.uiComponents.indicator.className="connected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.CONNECTED),setTimeout(function(){SB.spec.uiComponents.indicator.className="connecting",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.CONNECTIG)},1e3);for(b in c)c.hasOwnProperty(b)&&SB.spec.updateTemplate(c[b])}else SB.spec.uiComponents.indicator.className="disconnected",SB.putText(SB.spec.uiComponents.indicator,SB.spec.strings.DISCONNECTED)}};SB.ajax.request(a)},1e4)},lazyLoad:function(a){var b,c,d,e,f=0;if(SB.get(a))for(b=SB.get(a),c=Array.prototype.slice.call(SB.getByTag("img",b)),d=Array.prototype.slice.call(SB.getByTag("iframe",b)),e=c.concat(d),f=0;f<e.length;f+=1)e[f].getAttribute("data-src")&&!e[f].src&&(e[f].src=e[f].getAttribute("data-src"))},lazyUnLoad:function(a){var b,c,d,e=0;if(a)for(b=Array.prototype.slice.call(SB.getByTag("img",a)),c=Array.prototype.slice.call(SB.getByTag("iframe",a)),d=b.concat(c),e=0;e<d.length;e+=1)d[e].getAttribute("src")&&(SB.hasClass(d[e],"streaming")||"IFRAME"===d[e].tagName)&&(d[e].setAttribute("data-src",d[e].src),d[e].removeAttribute("src"))},findTextInputs:function(){return SB.spec.uiComponents.body.getElementsByTagName("input")},findNumberInputs:function(){var a,b=SB.spec.findTextInputs(),c=[];for(a=0;a<b.length;a+=1)"number"===b[a].type&&c.push(b[a]);return c},findSliderPosition:function(a,b){var c,d,e,f,g=0;return b&&(c=a.parentNode.offsetWidth-a.offsetWidth,d=parseInt(b.min,10),e=parseInt(b.max,10),f=parseInt(b.value,10),g=(f-d)*c/(e-d),g=g<c?g:c,g=g>0?g:0),Math.round(g)},findSliderValue:function(a,b){var c=a.parentNode.previousSibling,d=a.parentNode.offsetWidth-a.offsetWidth,e=parseInt(c.min,10),f=parseInt(c.max,10),g=b.newX,h=(f-e)/d*g+e;return Math.round(h)},buildSliders:function(a){var b,c,d,e=SB.spec.findNumberInputs();for(b=function(a,b){a.style.left=SB.spec.findSliderPosition(a,b)+"px",SB.clickDrag({elm:a,restrict:!0,onTween:function(c){var d=SB.spec.findSliderValue(a,c);b.value=d,a.setAttribute("aria-valuenow",d)},onComplete:function(){c(b)}})},c=function(a){var b,c=a.parentNode;if(SB.hasClass(a.nextSibling,"sliderBar")){for(b=a.nextSibling.getElementsByTagName("span")[0],b.style.left=SB.spec.findSliderPosition(b,a)+"px";c!==document&&"form"!==c.tagName.toLowerCase();)c=c.parentNode;"form"===c.tagName.toLowerCase()&&SB.spec.sendInput(c)}},d=0;d<e.length;d+=1)!function(c){var d,e;"number"===c.type&&c.min&&c.max&&(a&&!SB.isChildOf(c,SB.get(a))||(d=document.createElement("div"),d.className="sliderBar",e=document.createElement("span"),e.setAttribute("role","slider"),e.setAttribute("tabindex",0),e.setAttribute("aria-valuenow",c.value),e.setAttribute("aria-valuemin",c.min),e.setAttribute("aria-valuemax",c.max),d.appendChild(e),c.parentNode.insertBefore(d,c.nextSibling),a?b(e,c):SB.event.add(window,"load",function(){b(e,c)})))}(e[d]);a||(SB.event.add(SB.spec.uiComponents.body,"keydown",function(a){var b,c=SB.getTarget(a),d=null;SB.hasClass(c.parentNode,"sliderBar")&&(b=c.parentNode.previousSibling,38===a.keyCode||39===a.keyCode?(d=parseInt(b.value,10)+1,d=d<=b.max?d:b.max):37!==a.keyCode&&40!==a.keyCode||(d=parseInt(b.value,10)-1,d=d>=b.min?d:b.min),d&&d>=b.min&&d<=b.max&&(a.preventDefault(),b.value=d))}),SB.event.add(SB.spec.uiComponents.body,"keyup",function(a){var b=SB.getTarget(a);SB.hasClass(b.parentNode,"sliderBar")&&c(b.parentNode.previousSibling)}),SB.event.add(window,"resize",function(){SB.spec.sliderSetWidths(e)}),SB.event.add(SB.spec.uiComponents.body,"change",function(a){c(SB.getTarget(a))}))},sliderSetWidths:function(){var a,b,c=SB.spec.findNumberInputs();for(b=0;b<c.length;b+=1)SB.hasClass(c[b].nextSibling,"sliderBar")&&(a=c[b].nextSibling.getElementsByTagName("span")[0],a.style.left=SB.spec.findSliderPosition(a,c[b])+"px")},command:function(a){var b=null,c=0,d=750,e=!1,f=!1,g=!1,h=!1,i=0,j=0,k=5,l=null,m=450,n=function(){b=null,d=750,c=0,g=!0,f=!1,h=!1,i=0,j=0},o=function(c){var d=b;SB.vibrate(),a||SB.spec.sendTextInput(c,d,"text"),n()},p=function(a){var b=SB.getTarget(a),c=b.tagName.toLowerCase(),d=null;return b="img"===c?b.parentNode:b,b="i"===c?b.parentNode:b,b="span"===c?b.parentNode:b,"a"===b.tagName.toLowerCase()&&(d=b),d},q=function(){var e,f=(new Date).getTime();b&&!g&&(SB.vibrate(),a?SB.log("Issued","Demo Command","success"):SB.spec.socket?SB.spec.checkConnection()&&(SB.log("Issued","Command","success"),SB.spec.socket.send(b)):(e={path:b,param:"ts="+f,method:"GET",onComplete:function(){SB.log(e.response)}},SB.ajax.request(e)),c>3&&(d=650),c>10&&(d=500),c+=1,setTimeout(q,d))},r=function(a,c){var d=p(a);c?(SB.vibrate(),b=SB.getTarget(a).parentNode.parentNode.id,l=SB.transcribe(o),l.start()):d&&!g&&("external"===d.rel?window.open(d.href,"_blank").focus():(b=d.href,q()))};"ontouchstart"in document.documentElement&&(SB.log("Enabled","Touch Events","info"),SB.event.add(SB.spec.uiComponents.body,"touchstart",function(a){e=!0,f=!0,p(a)&&(g=!1,i=parseInt(a.changedTouches[0].clientX,10),j=parseInt(a.changedTouches[0].clientY,10),setTimeout(function(){h||(e=!1,r(a))},m))}),SB.event.add(SB.spec.uiComponents.body,"contextmenu",function(a){a.preventDefault()}),SB.event.add(SB.spec.uiComponents.body,"touchend",function(a){!SB.hasClass(SB.getTarget(a).parentNode,"emoji")&&e&&(h=!0,r(a)),n(a)}),SB.event.add(SB.spec.uiComponents.body,"touchmove",function(a){f&&(Math.abs(parseInt(a.changedTouches[0].clientX,10)-i)>k||Math.abs(parseInt(a.changedTouches[0].clientY,10)-j)>k)&&n(a)}),SB.event.add(SB.spec.uiComponents.body,"touchcancel",function(a){n(a)})),SB.event.add(SB.spec.uiComponents.body,"mousedown",function(a){SB.hasClass(SB.getTarget(a).parentNode,"emoji")?r(a,!0):f===!1&&e===!1&&(g=!1,r(a)),e=!1}),SB.event.add(SB.spec.uiComponents.body,"mouseup",function(a){SB.hasClass(SB.getTarget(a).parentNode,"emoji")||n(a)}),SB.event.add(SB.spec.uiComponents.body,"click",function(a){p(a)&&a.preventDefault()})},sendInput:function(a){var b=SB.getByTag("input",a,"input")[0],c=b.value,d=b.name,e=SB.getByClass("input-type",a,"input")[0].value;"text"===b.type&&(b.value=""),SB.spec.sendTextInput(c,d,e)},sendTextInput:function(a,b,c){var d,e=(new Date).getTime();c=c||"text",SB.spec.socket?SB.spec.checkConnection()&&(SB.log("Issued","Text Command","success"),SB.spec.socket.send("/?"+b+"="+c+"-"+a)):(d={path:"/",param:b+"="+c+"-"+a+"&ts="+e,method:"POST",onComplete:function(){SB.log(d.response)}},SB.ajax.request(d))},formInput:function(a){SB.event.add(SB.spec.uiComponents.body,"submit",function(b){var c=SB.getTarget(b);b.preventDefault(),a?SB.log("Issued","Demo Text Command","success"):SB.spec.sendInput(c)})},nav:function(){SB.event.add(SB.spec.uiComponents.header,"click",function(a){var b=SB.getTarget(a).parentNode,c=b.tagName.toLowerCase();"li"===c?(a.preventDefault(),SB.spec.navChange(b.className),SB.vibrate(),SB.notifyAsk()):"indicator"===SB.getTarget(a).id&&SB.hasClass(SB.getTarget(a),"disconnected")&&SB.spec.socketConnect(0)})},init:function(){var a,b,c,d=!1,e=SB.storage("selected"),f=SB.storage("templates"),g=SB.storage("state");if(SB.spec.uiComponents.header=SB.getByTag("header")[0],SB.spec.uiComponents.body=SB.getByTag("main")[0],SB.spec.buildIndicator(),b=SB.spec.uiComponents.header.dataset,c=SB.spec.uiComponents.body.dataset,SB.spec.strings={CURRENT:b.stringCurrent,CONNECTED:b.stringConnected,CONNECTING:b.stringConnecting,DISCONNECTED:b.stringDisconnected,ACTIVE:c.stringActive,INACTIVE:c.stringInactive,ON:c.stringOn,OFF:c.stringOff,AM:c.stringAm,PM:c.stringPm,SUN:c.stringSun,MON:c.stringMon,TUE:c.stringTue,WED:c.stringWed,THUR:c.stringThur,FRI:c.stringFri,SAT:c.stringSat},e&&SB.spec.navChange(e),f&&g){SB.spec.uiComponents.templates=SB.decode(f),g=SB.decode(g);for(a in g)g.hasOwnProperty(a)&&SB.spec.updateTemplate(g[a])}d||("function"==typeof WebSocket||"object"==typeof WebSocket?SB.spec.socketConnect(0):SB.spec.statePoller()),SB.spec.lazyLoad(document.body.className),SB.spec.buildSliders(),SB.spec.command(d),SB.spec.formInput(d),SB.spec.nav(),SB.spec.ariaDevice()}}}(),function(a){"use strict";a.activeBuilding=function(a,b,c,d,e){var f="",g="",h="",i="",j=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"activeBuilding"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"activeBuilding",e)),a},k=function(a){var b,c="";return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.arrayList(a,"activeBuilding",e):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.arrayList(a,"activeBuilding",e)),c};return c&&d&&(i=k(d)),d&&0!==d.length?1===d.length?(g="ok",h="tag",f=j("SINGLE_PACKAGE")):d.length>1&&(g="ok",h="tags",f=j("PLURAL_PACKAGES")):(g="err",h="times",f=j("NO_PACKAGES")),f=f.split("{{SENDERS}}").join(i),b=b.replace("{{ACTIVEBUILDING_STATE}}",g),b=b.replace("{{ACTIVEBUILDING_ICON}}",h),b=b.replace("{{ACTIVEBUILDING_DYNAMIC}}",f)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.debug=function(a,b,c,d,e,f){var g=(new Date).getTime(),h="",i="",j=0,k=0,l=0,m=0,n=0,o=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"debug"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"debug",f)),a},p=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,o):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,o)),c},q=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayRelativeTime(a):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayRelativeTime(a)),c};return d&&(h=q(d.uptime),i=q((g-d.startup)/1e3),j=d.memoryUsed,k=d.totalMemory,l=d.percentMemory,m=Math.round(100*d.cpuLoad[0]),n=d.clientCount),b=b.replace("{{DEBUG_UPDATE}}",p(g)),b=b.replace("{{DEBUG_UPTIME}}",h),b=b.replace("{{DEBUG_RUNTIME}}",i),b=b.replace("{{DEBUG_MEMORY_USED}}",j),b=b.replace("{{DEBUG_SYSTEM_MEMORY}}",k),b=b.replace("{{DEBUG_MEMORY_PERCENT}}",l),b=b.replace("{{DEBUG_CPU}}",m),b=b.replace("{{DEBUG_CLIENT_COUNT}}",n)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.denon=function(a,b,c,d){return d&&(b=b.split("{{DEVICE_POWER}}").join(d.power),d.ZONE1&&(b=b.split("{{DEVICE_Z1_INPUT}}").join(d.ZONE1.input),b=b.split("{{DEVICE_Z1_POWER}}").join(d.ZONE1.power),b=b.split("{{DEVICE_Z1_MUTE}}").join(d.ZONE1.mute),b=b.split("{{DEVICE_Z1_MODE}}").join(d.ZONE1.mode),b=b.split("{{DEVICE_Z1_VOLUME}}").join(d.ZONE1.volume),b=b.split("{{DEVICE_Z1_MAXVOLUME}}").join(d.ZONE1.maxvolume)),d.ZONE2&&(b=b.split("{{DEVICE_Z2_POWER}}").join(d.ZONE2.power),b=b.split("{{DEVICE_Z2_INPUT}}").join(d.ZONE2.input),b=b.split("{{DEVICE_Z2_VOLUME}}").join(d.ZONE2.volume)),d.ZONE3&&(b=b.split("{{DEVICE_Z3_POWER}}").join(d.ZONE3.power),b=b.split("{{DEVICE_Z3_INPUT}}").join(d.ZONE3.input),b=b.split("{{DEVICE_Z3_VOLUME}}").join(d.ZONE3.volume))),b=b.split("{{DEVICE_POWER}}").join(""),b=b.split("{{DEVICE_Z1_POWER}}").join(""),b=b.split("{{DEVICE_Z1_INPUT}}").join(""),b=b.split("{{DEVICE_Z1_MUTE}}").join(""),b=b.split("{{DEVICE_Z1_MODE}}").join(""),b=b.split("{{DEVICE_Z1_VOLUME}}").join(""),b=b.split("{{DEVICE_Z1_MAXVOLUME}}").join(""),b=b.split("{{DEVICE_Z2_POWER}}").join(""),b=b.split("{{DEVICE_Z2_INPUT}}").join(""),b=b.split("{{DEVICE_Z2_VOLUME}}").join(""),b=b.split("{{DEVICE_Z3_POWER}}").join(""),b=b.split("{{DEVICE_Z3_INPUT}}").join(""),b=b.split("{{DEVICE_Z3_VOLUME}}").join("")}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.foscam=function(a,b,c,d,e){var f,g,h="",i="",j="",k=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"foscam"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"foscam",e)),a};return"on"===d?(h=" device-active",j=k("CAMERA_ARMED")):"off"===d&&(i=" device-active",j=k("CAMERA_DISARMED")),b=b.split("{{DEVICE_STATE_ON}}").join(h),b=b.split("{{DEVICE_STATE_OFF}}").join(i),b=b.split("{{ARMED_STATUS}}").join(j),b=b.split("{{DISARMED_STATUS}}").join(j),"object"==typeof SB&&(f=SB.getByClass("fa-lock",SB.get(a),"a")[0],g=SB.getByClass("fa-unlock",SB.get(a),"a")[0],"on"!==d||SB.hasClass(f,"device-on")?"off"!==d||SB.hasClass(g,"device-on")?b=SB.hasClass(SB.getByClass("selected",null,"li")[0],a)?b.split("{{LAZY_LOAD_IMAGE}}").join("src"):b.split("{{LAZY_LOAD_IMAGE}}").join("data-src"):(SB.addClass(g,"device-active"),SB.removeClass(f,"device-active"),SB.putText(SB.getByTag("em",f)[0],j),SB.putText(SB.getByTag("em",g)[0],j),b=""):(SB.addClass(f,"device-active"),SB.removeClass(g,"device-active"),SB.putText(SB.getByTag("em",f)[0],j),SB.putText(SB.getByTag("em",g)[0],j),b="")),b}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.gerty=function(a,b,c,d,e,f){var g,h,i,j,k=e.comment,l="",m="",n=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"gerty"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"gerty",f)),a},o=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,n):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,n)),c};if(d.comments)for(h in d.comments)d.comments.hasOwnProperty(h)&&(g=o(d.comments[h].time),m+=k.split("{{TIME}}").join(g),m=m.split("{{CODE}}").join(d.comments[h].code),m=m.split("{{NAME}}").join(d.comments[h].name),m=m.split("{{COMMENT}}").join(d.comments[h].text));return"object"==typeof SB?(i=SB.getByTag("span",SB.get(a))[0],j=SB.getByTag("ol",SB.get(a))[0],i&&i.innerHTML!==d.emoji&&(SB.putText(i,d.emoji),i.className=d.action||""),j&&j.innerHTML!==m&&(j.innerHTML=m,j.scrollTop=j.scrollHeight),b=""):(d.action&&(l=' class="'+d.action+'"'),b=b.split("{{GERTY_ACTION}}").join(l),b=b.split("{{GERTY_DYNAMIC}}").join(d.emoji),b=b.split("{{GERTY_COMMENTS}}").join(m)),b}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.github=function(a,b,c,d,e,f){var g=e.commit,h=e.message,i="",j="",k=0,l=null,m=null,n="",o=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"github"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"github",f)),a},p=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,o,"long"):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,o,"long")),c};if(c&&d)for(k;k<d.length;k+=1)j=p(d[k].time),i+=g.split("{{GITHUB_URL}}").join(d[k].url),i=i.split("{{GITHUB_TITLE}}").join(j),i=i.split("{{GITHUB_DESCRIPTION}}").join(d[k].description),d[k].upToDate===!1?m="NEWER":d[k].upToDate===!0&&(l="LATEST");return b=b.replace("{{GITHUB_DYNAMIC}}",i),m?n=o(m):l&&(n=o(l)),i=h.replace("{{GITHUB_MESSAGE}}",n),b=b.replace("{{GITHUB_MESSAGE}}",i)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.location=function(a,b,c,d,e,f){var g=e.item,h="",i=0,j=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"location"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"location",f)),a},k=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,j):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,j)),c};if(c&&d)for(i;i<d.length;i+=1)h+=g.split("{{LOCATION_NAME}}").join(d[i].name),h=h.split("{{LOCATION_URL}}").join(d[i].url),h=h.split("{{LOCATION_TIME}}").join(k(d[i].time)),h=h.split("{{LOCATION_ALTITUDE}}").join(d[i].alt),h=h.split("{{LOCATION_SPEED}}").join(Math.ceil(d[i].speed));return b=b.replace("{{LOCATION_DYNAMIC}}",h)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.nest=function(a,b,c,d,e,f){var g,h,i,j,k=e.thermostat,l=e.protect,m=e.group,n="",o="",p="",q={},r=function(a){var b;return"object"==typeof SB?a=SB.util.encodeName(a):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.encodeName(a)),"group-"+a},s=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"nest"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"nest",f)),a};if(d){for(g in d.devices)if(d.devices.hasOwnProperty(g))if(q=d.devices[g],"thermostat"===q.type){switch("object"==typeof SB&&(SB.getByClass(r(q.label),SB.get(a),"li")[0]?(j=SB.getByClass(r(q.label),SB.get(a),"li")[0],h=SB.getByClass("fa-sun-o",j,"a")[0],i=SB.getByClass("fa-asterisk",j,"a")[0],"cool"!==q.state||SB.hasClass(i,"device-active")?"heat"!==q.state||SB.hasClass(h,"device-active")?"off"!==q.state||SB.hasClass(j,"device-off")||(SB.addClass(j,"device-off"),SB.removeClass(i,"device-active"),SB.removeClass(h,"device-active"),SB.putText(SB.getByTag("em",j)[0],s("OFF")),b=""):(SB.addClass(h,"device-active"),SB.removeClass(i,"device-active"),SB.removeClass(j,"device-off"),SB.putText(SB.getByTag("em",j)[0],s("HEAT")),b=""):(SB.addClass(i,"device-active"),SB.removeClass(h,"device-active"),SB.removeClass(j,"device-off"),SB.putText(SB.getByTag("em",j)[0],s("COOL")),b="")):SB.spec.buildSliders(a)),n+=k.split("{{SUB_DEVICE_ID}}").join(r(q.label)),
n=n.split("{{SUB_DEVICE_NAME}}").join(q.label),n=n.split("{{SUB_DEVICE_TEMP}}").join(Math.round(q.temp)),n=n.split("{{SUB_DEVICE_TARGET}}").join(Math.round(q.target)),n=n.split("{{SUB_DEVICE_HUMIDITY}}").join(Math.round(q.humidity)),q.state){case"cool":n=n.split("{{DEVICE_STATE_COOL}}").join(" device-active"),n=n.split("{{SUB_DEVICE_STATUS}}").join(s("COOL"));break;case"heat":n=n.split("{{DEVICE_STATE_HEAT}}").join(" device-active"),n=n.split("{{SUB_DEVICE_STATUS}}").join(s("HEAT"));break;default:n=n.split("{{DEVICE_STATE_OFF}}").join(" device-off"),n=n.split("{{SUB_DEVICE_STATUS}}").join(s("OFF"))}q.leaf===!0&&(n=n.split("{{DEVICE_STATE_LEAF}}").join(" device-active")),n=d.presence&&"on"===d.presence?n.split("{{DEVICE_STATE_HOME}}").join(" device-active"):n.split("{{DEVICE_STATE_AWAY}}").join(" device-active"),n=n.split("{{DEVICE_STATE_COOL}}").join(""),n=n.split("{{DEVICE_STATE_HEAT}}").join(""),n=n.split("{{DEVICE_STATE_OFF}}").join(""),n=n.split("{{DEVICE_STATE_LEAF}}").join(""),n=n.split("{{DEVICE_STATE_HOME}}").join(""),n=n.split("{{DEVICE_STATE_AWAY}}").join("")}else"protect"===q.type&&(p="","ok"!==q.smoke&&(p+="smoke "),"ok"!==q.co&&(p+="co "),"ok"!==q.battery&&(p+="batt "),p&&(p+="device-active"),o+=l.split("{{SUB_DEVICE_STATE}}").join(p),o=o.split("{{SUB_DEVICE_NAME}}").join(q.label),o=o.split("{{SUB_DEVICE_SMOKE}}").join(q.smoke),o=o.split("{{SUB_DEVICE_CO}}").join(q.co),o=o.split("{{SUB_DEVICE_BATT}}").join(q.battery));n&&(n=m.replace("{{SUB_DEVICE_LIST}}",n),n=n.replace("{{SUB_DEVICE_CLASS}}"," control-device-status"),n=n.replace("{{SUB_DEVICE_NAME}}",s("THERMOSTAT"))),o&&(o=m.replace("{{SUB_DEVICE_LIST}}",o),o=o.replace("{{SUB_DEVICE_CLASS}}"," text-device-status"),o=o.replace("{{SUB_DEVICE_NAME}}",s("PROTECT")))}return b=b.replace("{{NEST_DYNAMIC}}",n+o)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.raspberryRemote=function(a,b,c,d,e){var f,g=e["switch"],h=0,i="",j=function(a){var b=g,c="";return c=b.split("{{SUB_DEVICE_ID}}").join(a.label.split(" ").join("+")),c=c.split("{{SUB_DEVICE_NAME}}").join(a.label)};if(d&&"object"==typeof d&&(f=d.devices))for(h in f)f.hasOwnProperty(h)&&(i+=j(f[h]),i=i.split("{{SUB_DEVICE_CLASS}}").join(f[h].className||"fa-lightbulb-o"));return b.replace("{{RASPBERRY_REMOTE_DYNAMIC}}",i)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.roku=function(a,b,c,d,e){var f=e.list,g=0,h="";if(d)for(g in d)d.hasOwnProperty(g)&&(h+=f.split("{{APP_ID}}").join(d[g].id),h=h.split("{{APP_IMG}}").join(d[g].cache),h=h.split("{{APP_NAME}}").join(d[g].name));return b.replace("{{ROKU_DYNAMIC}}",h)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.rss=function(a,b,c,d,e){var f=e.item,g="",h=0,i="";if(c&&d)for(h;h<d.length;h+=1)i=d[h].description?d[h].description:d[h].text,g+=f.split("{{RSS_URL}}").join(d[h].url),g=g.split("{{RSS_TITLE}}").join(d[h].title),g=g.split("{{RSS_DESCRIPTION}}").join(i);return b=b.replace("{{RSS_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.smartthings=function(a,b,c,d,e,f){var g,h,i=e.action,j=e["static"],k=e.group,l=0,m=0,n="",o="",p="",q=function(a){var b;return"object"==typeof SB?a=SB.util.encodeName(a):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.encodeName(a)),"group-"+a},r=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"smartthings"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"smartthings",f)),a},s=function(a,b){var c={},d=[],e=0,f=0;for(e in b)b.hasOwnProperty(e)&&(c=b[e],c.label===a&&(d[f]=c,f+=1));return d},t=function(a){var b="",c="",d="",e="",f="";switch(a.type){case"switch":b=i,d="fa-lightbulb-o";break;case"lock":b=i,d="fa-unlock-alt";break;case"contact":b=j,d="fa-columns";break;case"water":b=j,d="fa-tint";break;case"motion":b=j,d="fa-paw";break;case"presence":b=j,d="fa-male"}return a.peripheral&&a.peripheral.temp&&(e=" ("+a.peripheral.temp+"&deg;)"),a.peripheral&&"on"===a.peripheral.vibrate&&(f=" device-vibrate"),b&&(c=b.split("{{SUB_DEVICE_ID}}").join(a.label.split(" ").join("+")),c=c.split("{{SUB_DEVICE_NAME}}").join(a.label+e),c=c.split("{{SUB_DEVICE_CLASS}}").join(a.className||d),"on"===a.state?(c=c.split("{{SUB_DEVICE_STATE}}").join(" device-active"+f),c=c.split("{{SUB_DEVICE_STATUS}}").join(r("ACTIVE"))):(c=c.split("{{SUB_DEVICE_STATE}}").join(f),c=c.split("{{SUB_DEVICE_STATUS}}").join(r("INACTIVE")))),c};if(d&&"object"==typeof d&&"string"==typeof d.mode){if(o=d.mode,g=d.devices)if(d.groups){for(l in d.groups)if(d.groups.hasOwnProperty(l)){n+=k,p="";for(m in d.groups[l])d.groups[l].hasOwnProperty(m)&&(h=s(d.groups[l][m],g),h&&h[0]&&(p+=t(h[0])));n=n.split("{{GROUP_CLASS}}").join(q(l)),n=n.split("{{GROUP_TITLE}}").join(l),n=n.split("{{SUB_DEVICE_LIST}}").join(p)}}else for(l in g)g.hasOwnProperty(l)&&(n+=t(g[l]));switch(o){case"Home":b=b.split("{{DEVICE_STATE_HOME}}").join(" device-active"),b=b.split("{{HOME_STATUS}}").join(r("ACTIVE"));break;case"Away":b=b.split("{{DEVICE_STATE_AWAY}}").join(" device-active"),b=b.split("{{AWAY_STATUS}}").join(r("ACTIVE"));break;case"Night":b=b.split("{{DEVICE_STATE_NIGHT}}").join(" device-active"),b=b.split("{{NIGHT_STATUS}}").join(r("ACTIVE"))}}return b=b.split("{{DEVICE_STATE_HOME}}").join(""),b=b.split("{{DEVICE_STATE_AWAY}}").join(""),b=b.split("{{DEVICE_STATE_NIGHT}}").join(""),b=b.split("{{HOME_STATUS}}").join(r("INACTIVE")),b=b.split("{{AWAY_STATUS}}").join(r("INACTIVE")),b=b.split("{{NIGHT_STATUS}}").join(r("INACTIVE")),b.replace("{{SMARTTHINGS_DYNAMIC}}",n)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.sports=function(a,b,c,d,e,f){var g=e.league,h=e.game,i=0,j=0,k={},l={},m="",n="",o="",p="",q="",r=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"sports"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"sports",f)),a},s=function(a){var b,c;return"object"==typeof SB&&"object"==typeof SB.util?c=SB.util.displayTime(a,r):(b=require(__dirname+"/../../lib/sharedUtil").util,c=b.displayTime(a,r)),c};if(c&&d)for(i in d)if(d.hasOwnProperty(i)){for(k=d[i],q="",j=0;j<k.games.length;j+=1)l=k.games[j],m=r("TITLE").split("{{AWAY}}").join(l.away.title).split("{{HOME}}").join(l.home.title),n=l.away.winner?" winner":"",o=l.home.winner?" winner":"",q+=h.split("{{GAME_LINK}}").join(l.url),q=q.split("{{GAME_TITLE}}").join(m),q=q.split("{{GAME_AWAY_WINNER}}").join(n),q=q.split("{{GAME_AWAY_TEAM}}").join(l.away.title),q=q.split("{{GAME_AWAY_IMAGE}}").join(l.away.image),q=q.split("{{GAME_AWAY_SCORE}}").join(l.away.score),q=q.split("{{GAME_HOME_WINNER}}").join(o),q=q.split("{{GAME_HOME_TEAM}}").join(l.home.title),q=q.split("{{GAME_HOME_IMAGE}}").join(l.home.image),q=q.split("{{GAME_HOME_SCORE}}").join(l.home.score),q=q.split("{{GAME_TIME}}").join(s(l.time)),q=q.split("{{GAME_STATUS}}").join((l.status||"").toLowerCase()),q=q.split("{{GAME_STATE}}").join(r(l.status));p+=g.split("{{LEAGUE_NAME}}").join(k.title),p=p.split("{{GAME_LIST}}").join(q)}return b.replace("{{SPORTS_DYNAMIC}}",p)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.stocks=function(a,b,c,d,e,f){var g=e.list,h=0,i="",j="",k="",l="",m=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"stocks"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"stocks",f)),a};if(d)for(h in d)d.hasOwnProperty(h)&&(j="neutral",k="arrows-h",l=m("NEUTRAL"),d[h].dayChangeValue&&(0===d[h].dayChangeValue.indexOf("+")?(j="gain",k="arrow-up",l=m("GAIN")):0===d[h].dayChangeValue.indexOf("-")&&(j="loss",k="arrow-down",l=m("LOSS"))),i+=g.split("{{STOCK_CHANGE}}").join(j),i=i.split("{{STOCK_ARROW}}").join(k),i=i.split("{{STOCK_DIRECTION}}").join(l),i=i.split("{{STOCK_NAME}}").join(d[h].name),i=i.split("{{STOCK_PRICE}}").join(d[h].price),i=i.split("{{STOCK_CHANGE_VALUE}}").join(d[h].dayChangeValue),i=i.split("{{STOCK_CHANGE_PERCENT}}").join(d[h].dayChangePercent));return b.replace("{{STOCKS_DYNAMIC}}",i)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.traffic=function(a,b,c,d,e){var f=e.list,g=0,h="";if(d)for(g in d)d.hasOwnProperty(g)&&(h+=f.split("{{CAM_IMG}}").join(d[g].image),h=h.split("{{CAM_NAME}}").join(d[g].title));return b.replace("{{TRAFFIC_DYNAMIC}}",h)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.travis=function(a,b,c,d,e){var f=e.build,g="",h="",i="",j=0;if(c&&d)for(j;j<d.length;j+=1)h="",i="","created"===d[j].state||"started"===d[j].state?h="cogs":"ok"===d[j].status?h="check":"err"===d[j].status&&(h="times"),d[j].duration&&(i=" ("+d[j].duration+"s)"),g+=f.split("{{TRAVIS_URL}}").join(d[j].url),g=g.split("{{TRAVIS_ICON}}").join(h),g=g.split("{{TRAVIS_STATE}}").join(d[j].status),g=g.split("{{TRAVIS_DURATION}}").join(i),g=g.split("{{TRAVIS_DESCRIPTION}}").join(d[j].label);return b=b.replace("{{TRAVIS_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.twitter=function(a,b,c,d,e){var f=e.tweet,g="",h=0;if(c&&d)for(h;h<d.length;h+=1)g+=f.split("{{TWEET_TEXT}}").join(d[h].text),g=g.split("{{TWEET_URL}}").join(d[h].url),g=g.split("{{TWEET_AUTHOR}}").join(d[h].author);return b=b.replace("{{TWITTER_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.weather=function(a,b,c,d,e,f){var g,h,i=e.forecast,j=0,k="";if(g=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"weather"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"weather",f)),a},h=function(a){var b="warning",c="bolt",d="asterisk",e="tint",f="fire",g="flag",h="cloud",i="moon-o",j="sun-o",k={0:b,1:b,2:b,3:c,4:c,5:d,6:d,7:d,8:d,9:e,10:e,11:e,12:e,13:d,14:d,15:d,16:d,17:d,18:d,19:f,20:f,21:f,22:f,23:g,24:g,25:d,26:h,27:h,28:h,29:h,30:h,31:i,32:j,33:i,34:j,35:d,36:j,37:c,38:c,39:c,40:e,41:d,42:d,43:d,44:h,45:c,46:d,47:c};return a=parseInt(a,10),k[a]||"question"},d&&d.code){b=b.replace("{{WEATHER_ICON}}",h(d.code)),b=b.replace("{{WEATHER_CURRENT}}",d.city+" "+g("CURRENT")+": "+d.temp+"&deg; "+d.text),b=b.replace("{{WEATHER_SUNRISE}}",d.sunrise),b=b.replace("{{WEATHER_SUNSET}}",d.sunset);for(j in d.forecast)d.forecast.hasOwnProperty(j)&&(k+=i.split("{{WEATHER_ICON}}").join(h(d.forecast[j].code)),k=k.split("{{WEATHER_DAY}}").join(d.forecast[j].day+":"),k=k.split("{{WEATHER_TEXT}}").join(d.forecast[j].text),k=k.split("{{WEATHER_HIGH}}").join(d.forecast[j].high+"&deg;"),k=k.split("{{WEATHER_LOW}}").join(d.forecast[j].low+"&deg;"))}else b=b.replace("{{WEATHER_CURRENT}}",g("UNAVAILABLE")),b=b.replace("{{WEATHER_SUNRISE}}",""),b=b.replace("{{WEATHER_SUNSET}}",""),"string"==typeof d&&(k=d);return b.replace("{{WEATHER_DYNAMIC}}",k)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.website=function(a,b,c,d){var e="";return d&&d.source&&(e=d.source),b.replace("{{WEBSITE_DYNAMIC}}",e)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.wemo=function(a,b,c,d,e,f){var g,h=e["switch"],i=e.group,j=0,k=0,l="",m="",n="",o=function(a){var b;return"object"==typeof SB?a=SB.util.encodeName(a):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.encodeName(a)),a},p=function(a){var b;return"object"==typeof SB&&"object"==typeof SB.util?a=SB.util.translate(a,"wemo"):(b=require(__dirname+"/../../lib/sharedUtil").util,a=b.translate(a,"wemo",f)),a},q=function(a,b){var c={},d=0;for(d in b)if(b[d].label===a){c=b[d];break}return c},r=function(a){var b="";return m&&(m+="device-active"),b=h.split("{{SUB_DEVICE_ID}}").join(a.label.split(" ").join("+")),b=b.split("{{SUB_DEVICE_NAME}}").join(a.label),b=b.split("{{SUB_DEVICE_CLASS}}").join(a.className||"fa-lightbulb-o"),"on"===a.state?(b=b.split("{{SUB_DEVICE_STATE}}").join(" device-active"),b=b.split("{{SUB_DEVICE_STATUS}}").join(p("ACTIVE"))):"off"===a.state?(b=b.split("{{SUB_DEVICE_STATE}}").join(""),b=b.split("{{SUB_DEVICE_STATUS}}").join(p("INACTIVE"))):(b=b.split("{{SUB_DEVICE_STATE}}").join(" device-off"),b=b.split("{{SUB_DEVICE_STATUS}}").join(p("INACTIVE"))),b};if(d&&d.devices){if(d.groups){for(j in d.groups)if(d.groups.hasOwnProperty(j)){l+=i,n="";for(k in d.groups[j])d.groups[j].hasOwnProperty(k)&&(g=q(d.groups[j][k],d.devices),g&&(n+=r(g)));l=l.split("{{GROUP_CLASS}}").join(o(j)),l=l.split("{{GROUP_TITLE}}").join(j),l=l.split("{{SUB_DEVICE_LIST}}").join(n)}}else for(j in d.devices)d.devices.hasOwnProperty(j)&&(l+=r(d.devices[j]));l&&(l=l.replace("{{SUB_DEVICE_CLASS}}"," text-device-status"))}return b.replace("{{WEMO_DYNAMIC}}",l)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.xbmc=function(a,b,c,d,e){var f=e.current,g="";return d&&d.current&&(g=f.split("{{DEVICE_CURRENT}}").join(d.current)),b.replace("{{XBMC_DYNAMIC}}",g)}}("undefined"==typeof exports?this.SB.spec.parsers:exports),function(a){"use strict";a.util={version:20151215,replaceAll:function(a,b,c){var d=a;return"string"==typeof a&&(d=a.replace(new RegExp(b,"g"),c)),d},stripTags:function(a){return"string"==typeof a?a.replace(/(<([^>]+)>)/gi,""):a},stripControl:function(a){return"string"==typeof a?a.replace(new RegExp("[\0-]+","g"),""):a},sanitize:function(a){return this.stripTags(this.stripControl(a))},encodeName:function(a){return a&&"string"==typeof a&&(a=a.replace(/[\s!@#$%^&*()"'\\<>,;.:/+]/g,"_").toLowerCase()),a},translate:function(a,b,c){var d,e="";return a&&"string"==typeof a?(a=a.toUpperCase(),"object"==typeof SB?(c=document.documentElement.getAttribute("lang"),d=function(a,b){var c=SB.getByClass(b,SB.getByTag("main")[0],"section")[0];return a=a.replace("{{i18n_","").replace("}}",""),c.dataset&&c.dataset["string"+a.charAt(0)+a.substr(1).toLowerCase()]?a=c.dataset["string"+a.charAt(0)+a.substr(1).toLowerCase()]:SB.spec.strings[a]&&(a=SB.spec.strings[a]),a}):d=require(__dirname+"/translate").translate,e=d("{{i18n_"+a+"}}",b,c)):e=a,e},arrayList:function(a,b,c){var d="",e=0;for(e;e<a.length;e+=1)e&&(e===a.length-1?d=d+" "+this.translate("AND",b,c)+" ":d+=", "),d+=a[e];return d},displayRelativeTime:function(a){var b,c={day:86400,hour:3600,minute:60,second:1},d={day:"00",hour:"00",minute:"00",second:"00"};for(b in c)a>=c[b]&&(d[b]=Math.floor(a/c[b]),d[b]<10&&(d[b]="0"+d[b]),a-=d[b]*c[b]);return d.day+" "+d.hour+":"+d.minute+":"+d.second},displayTime:function(a,b,c,d){var e=d||new Date(a),f=e.getDate(),g=e.getDay(),h={0:"sun",1:"mon",2:"tue",3:"wed",4:"thur",5:"fri",6:"sat"},i=e.getHours(),j=e.getMinutes(),k=b("am"),l="";switch(i>12&&(i-=12,k=b("pm")),i=0===i?12:i,j<10&&(j="0"+j),g=b(h[g]),c){case"long":l=g+" "+f+" @ "+i+":"+j+k;break;default:l=g+" @ "+i+":"+j+k}return l}}}("undefined"==typeof exports?this.SB:exports);

@@ -34,3 +34,3 @@ /*jshint -W020 */

return {
version : 20160314,
version : 20160530,

@@ -44,4 +44,4 @@ state : {},

uiComponents : {
header : {},
body : {},
header : {},
body : {},
indicator : {},

@@ -52,2 +52,13 @@ templates : []

/**
* Updates the Aria tag to announce the currently active device.
*/
ariaDevice : function () {
var newNav = SB.getByClass('selected', SB.spec.uiComponents.header, 'li')[0],
ariaTitle = SB.getByTag('h2', SB.spec.uiComponents.header)[0],
ariaText = SB.spec.strings.CURRENT.split('{{DEVICE}}').join(SB.getText(newNav));
SB.putText(ariaTitle, ariaText);
},
/**
* Selects the given nav item.

@@ -77,2 +88,4 @@ *

SB.spec.lazyUnLoad(selectContent);
SB.spec.ariaDevice();
}

@@ -117,3 +130,3 @@ },

if (SB.hasClass(node, 'device-off')) {
if (SB.hasClass(node, 'device-off')) {
SB.removeClass(node, 'device-off');

@@ -128,3 +141,3 @@ SB.addClass(node, 'device-on');

if (SB.hasClass(node, 'device-on')) {
if (SB.hasClass(node, 'device-on')) {
SB.removeClass(node, 'device-on');

@@ -694,3 +707,3 @@ SB.addClass(node, 'device-off');

*/
command : function () {
command : function (demoMode) {
var commandIssued = null,

@@ -726,3 +739,7 @@ commandIteration = 0,

SB.vibrate();
SB.spec.sendTextInput(text, device, 'text');
if (!demoMode) {
SB.spec.sendTextInput(text, device, 'text');
}
stopCommand();

@@ -752,3 +769,7 @@ },

if (SB.spec.socket) {
if (demoMode) {
SB.log('Issued', 'Demo Command', 'success');
}
else if (SB.spec.socket) {
if (SB.spec.checkConnection()) {

@@ -947,3 +968,3 @@ SB.log('Issued', 'Command', 'success');

*/
formInput : function () {
formInput : function (demoMode) {
SB.event.add(SB.spec.uiComponents.body, 'submit', function (e) {

@@ -954,3 +975,9 @@ var elm = SB.getTarget(e);

SB.spec.sendInput(elm);
if (demoMode) {
SB.log('Issued', 'Demo Text Command', 'success');
}
else {
SB.spec.sendInput(elm);
}
});

@@ -988,3 +1015,4 @@ },

init : function () {
var active = SB.storage('selected'),
var demoMode = false,
active = SB.storage('selected'),
templates = SB.storage('templates'),

@@ -1003,3 +1031,4 @@ state = SB.storage('state'),

SB.spec.strings = { CONNECTED : headerData.stringConnected,
SB.spec.strings = { CURRENT : headerData.stringCurrent,
CONNECTED : headerData.stringConnected,
CONNECTING : headerData.stringConnecting,

@@ -1037,10 +1066,12 @@ DISCONNECTED : headerData.stringDisconnected,

/* If we support WebSockets, we'll grab updates as they happen */
if ((typeof WebSocket === 'function') || (typeof WebSocket === 'object')) {
SB.spec.socketConnect(0);
}
if (!demoMode) {
/* If we support WebSockets, we'll grab updates as they happen */
if ((typeof WebSocket === 'function') || (typeof WebSocket === 'object')) {
SB.spec.socketConnect(0);
}
/* Otherwise, we'll poll for updates */
else {
SB.spec.statePoller();
/* Otherwise, we'll poll for updates */
else {
SB.spec.statePoller();
}
}

@@ -1051,7 +1082,8 @@

SB.spec.buildSliders();
SB.spec.command();
SB.spec.formInput();
SB.spec.command(demoMode);
SB.spec.formInput(demoMode);
SB.spec.nav();
SB.spec.ariaDevice();
}
};
}());

@@ -43,2 +43,3 @@ /**

CONNECTING : "Connecting",
CURRENT : "Current Device: {{DEVICE}}",
DISCONNECTED : "Disconnected"

@@ -129,2 +130,5 @@ },

},
clientScreenSaver : {
CLIENTSCREENSAVER : 'Screen Saver'
},
clientSpeech : {

@@ -469,2 +473,3 @@ CLIENTSPEECH : "Client Speech Synthesis"

HOME : "Home",
HOME_WATCH : "{{LABEL}} has been triggered!",
LEFT : "{{LABEL}} has just left",

@@ -471,0 +476,0 @@ NIGHT : "Night",

@@ -47,2 +47,3 @@ /**

CONNECTING : "Conectándonos",
CURRENT : "Aparato Activo: {{DEVICE}}",
DISCONNECTED : "Desconectado"

@@ -133,2 +134,5 @@ },

},
clientScreenSaver : {
CLIENTSCREENSAVER : 'Salvapantallas'
},
clientSpeech : {

@@ -462,10 +466,11 @@ CLIENTSPEECH : "Síntesis de voz del cliente"

smartthings : {
SMARTTHINGS : "SmartThings",
ARRIVED : "{{LABEL}} acabo de llegar",
AWAY : "Por fuera",
DOOR_KNOCK : "Alguien está en la {{LABEL}}",
HOME : "En Casa",
LEFT : "{{LABEL}} acabo de salir",
NIGHT : "Noche",
NOBODY_HOME : "Estatus por fuera - no hay nadie en casa",
SMARTTHINGS : "SmartThings",
ARRIVED : "{{LABEL}} acabo de llegar",
AWAY : "Por fuera",
DOOR_KNOCK : "Alguien está en la {{LABEL}}",
HOME : "En Casa",
HOME_WATCH : "{{LABEL}} se prendió!",
LEFT : "{{LABEL}} acabo de salir",
NIGHT : "Noche",
NOBODY_HOME : "Estatus por fuera - no hay nadie en casa",
SAFE_WATCH_CONTACT : "{{LABEL}} se abrió!",

@@ -475,4 +480,4 @@ SAFE_WATCH_MOTION : "{{LABEL}} detectó movimiento!",

SAFE_WATCH_VIBRATE : "{{LABEL}} detectó vibración!",
SOMEBODY_HOME : "Estatus en casa - {{PEOPLE}} {{PLURAL}} en casa",
WATER_DETECTED : "¡{{LABEL}} detecto agua!"
SOMEBODY_HOME : "Estatus en casa - {{PEOPLE}} {{PLURAL}} en casa",
WATER_DETECTED : "¡{{LABEL}} detecto agua!"
},

@@ -479,0 +484,0 @@ sms : {

@@ -56,3 +56,3 @@ /**

else if (type === 'short') {
if ((controllers[deviceId].controller) && (controllers[deviceId].controller.inputs.indexOf('state') !== -1)) {
if ((controllers[deviceId].controller) && (controllers[deviceId].controller.inputs) && (controllers[deviceId].controller.inputs.indexOf('state') !== -1)) {
runCommand.runCommand(deviceId, 'state', 'single', false);

@@ -59,0 +59,0 @@ }

{
"name": "switchboard-automation",
"description": "Universal Remote Controller powered by Node.js",
"version": "0.1.2",
"version": "0.1.3",
"author": "Brian J.",

@@ -22,5 +22,5 @@ "contributors": [

"dependencies": {
"request": "~2.71.0",
"xml2js": "~0.4.16",
"websocket": "~1.0.22"
"request": "~2.73.0",
"xml2js": "~0.4.17",
"websocket": "~1.0.23"
},

@@ -30,3 +30,3 @@ "devDependencies": {

"grunt-cli": "~1.2.0",
"grunt-contrib-concat": "~1.0.0",
"grunt-contrib-concat": "~1.0.1",
"grunt-contrib-cssmin": "~1.0.1",

@@ -40,4 +40,4 @@ "grunt-contrib-jshint": "~1.0.0",

"scripts": {
"test": "grunt nodeunit"
"test": "grunt test-suite"
}
}

@@ -5,2 +5,3 @@ [![Build Status](https://secure.travis-ci.org/imbrianj/switchBoard.png)](http://travis-ci.org/imbrianj/switchBoard)

[![npm version](https://badge.fury.io/js/switchboard-automation.svg)](https://badge.fury.io/js/switchboard-automation)
[![Known Vulnerabilities](https://snyk.io/test/npm/switchboard-automation/badge.svg)](https://snyk.io/test/npm/switchboard-automation)

@@ -34,38 +35,39 @@ SwitchBoard

| Name | Status | Notes |
|------------------|-------------|-----------------------------------------------------------------------------------|
| ActiveBuilding | Stable | Checks for arrived packages to be picked up from your concierge |
| Belkin Wemo | Stable | |
| Client MP3 | Stable | Sends an mp3 playback command to all Websocket connected clients |
| Client Notify | Stable | Sends a Desktop Notification to all Websocket connected clients |
| Client Speech | Stable | Sends text to be speech synthesized to all Websocket connected clients |
| Client Vibrate | Testing | Sends a command to vibrate all Websocket connected clients (phones, tablets, etc) |
| Debug | Stable | Display basic system information (memory, cpu, uptime) |
| Denon | Stable | New controller and still in testing |
| Foscam | Stable | Works with FI8910W (if you have another version that this does not work with, let me know and I can add support). Arm, Disarm, Go to presets, etc. *INSECURE* Exposes camera credentials to users |
| Gerty | Stable | A simple interface for all devices that reacts to natural inputs. |
| GitHub | Testing | Poll for commits to a given repository. For Switchboard, can tell you if you should update. |
| LG TVs | Development | Still need work on authentication |
| Location | Stable | Uses [switchboard-phpServer](https://github.com/imbrianj/switchboard-phpServer) and [Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm) to track your GPS position
| MP3 | Stable | Works on *nix with mpg123 or OSX with afplay. Win not supported |
| Nest | Stable | Works with Nest thermostat and Protect smoke / CO detectors |
| Panasonic | Stable | Text input and basic controls |
| Pioneer | Testing | Reportedly works, but unable to test |
| PS3 | Stable | Uses GIMX to emulate PS3 controller ([see below](https://github.com/imbrianj/switchBoard#faq)). OSX not supported |
| Pushover | Stable | Requires purchased app and token / user key |
| Raspberry Remote | Stable | Uses [Raspberry Remote](https://xkonni.github.io/raspberry-remote/) to control lighting. Only Linux is supported |
| Roku | Stable | Launch apps directly, text input and basic controls |
| RSS | Stable | Simple RSS and Atom reader |
| Samsung SmartTV | Stable | Text input and basic controls |
| SmartThings | Stable | Control devices and monitor real-time states. Requires [companion app](https://github.com/imbrianj/oauth_controller/blob/master/oauth_controller.groovy) |
| SMS | Stable | Uses Twilio. Requires ID and token |
| Speech | Stable | Uses espeak for *nix, say on OSX. Win not supported |
| Sports | Testing | Pull sports scores from ESPN (please don't hammer this endpoint) |
| Stocks | Stable | Uses Yahoo Finance |
| Traffic Cams | Stable | View multiple traffic webcams |
| Travis CI | Stable | |
| Twitter | Development | Present mentions of your Twitter handle |
| Weather | Stable | Uses Yahoo Weather |
| Website | Testing | Simple controller to load an external site as an iframe |
| XBMC | Stable | Basic controls work |
| Name | Status | Notes |
|---------------------|-------------|-----------------------------------------------------------------------------------|
| ActiveBuilding | Stable | Checks for arrived packages to be picked up from your concierge |
| Belkin Wemo | Stable | |
| Client MP3 | Stable | Sends an mp3 playback command to all Websocket connected clients |
| Client Notify | Stable | Sends a Desktop Notification to all Websocket connected clients |
| Client Screen Saver | Development | For use with OLED display fixtures - blacks out screen when not in use. |
| Client Speech | Stable | Sends text to be speech synthesized to all Websocket connected clients |
| Client Vibrate | Testing | Sends a command to vibrate all Websocket connected clients (phones, tablets, etc) |
| Debug | Stable | Display basic system information (memory, cpu, uptime) |
| Denon | Stable | New controller and still in testing |
| Foscam | Stable | Works with FI8910W (if you have another version that this does not work with, let me know and I can add support). Arm, Disarm, Go to presets, etc. *INSECURE* Exposes camera credentials to users |
| Gerty | Stable | A simple interface for all devices that reacts to natural inputs. |
| GitHub | Testing | Poll for commits to a given repository. For Switchboard, can tell you if you should update. |
| LG TVs | Development | Still need work on authentication |
| Location | Stable | Uses [switchboard-phpServer](https://github.com/imbrianj/switchboard-phpServer) and [Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm) to track your GPS position
| MP3 | Stable | Works on *nix with mpg123 or OSX with afplay. Win not supported |
| Nest | Stable | Works with Nest thermostat and Protect smoke / CO detectors |
| Panasonic | Stable | Text input and basic controls |
| Pioneer | Testing | Reportedly works, but unable to test |
| PS3 | Stable | Uses GIMX to emulate PS3 controller ([see below](https://github.com/imbrianj/switchBoard#faq)). OSX not supported |
| Pushover | Stable | Requires purchased app and token / user key |
| Raspberry Remote | Stable | Uses [Raspberry Remote](https://xkonni.github.io/raspberry-remote/) to control lighting. Only Linux is supported |
| Roku | Stable | Launch apps directly, text input and basic controls |
| RSS | Stable | Simple RSS and Atom reader |
| Samsung SmartTV | Stable | Text input and basic controls |
| SmartThings | Stable | Control devices and monitor real-time states. Requires [companion app](https://github.com/imbrianj/oauth_controller/blob/master/oauth_controller.groovy) |
| SMS | Stable | Uses Twilio. Requires ID and token |
| Speech | Stable | Uses espeak for *nix, say on OSX. Win not supported |
| Sports | Testing | Pull sports scores from ESPN (please don't hammer this endpoint) |
| Stocks | Stable | Uses Yahoo Finance |
| Traffic Cams | Stable | View multiple traffic webcams |
| Travis CI | Stable | |
| Twitter | Development | Present mentions of your Twitter handle |
| Weather | Stable | Uses Yahoo Weather |
| Website | Testing | Simple controller to load an external site as an iframe |
| XBMC | Stable | Basic controls work |

@@ -72,0 +74,0 @@ ### How to Contribute

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc