var mqtt = require('mqtt'), url = require('url');
var user = "USER DEVICES GEEKNESIA";
var pass = "PASS DEVICES GEEKNESIA";
var devID= "DEV ID ";
var apiKey = "API KEY";
var topic = "TOPIC";
var mqtt_url = url.parse('mqtt://'+user+':'+pass+'@geeknesia.com:1883');
var auth = (mqtt_url.auth || ':').split(':');
var five = require("johnny-five");
var Edison = require("edison-io");
var board = new five.Board({
io: new Edison()
});
var gcm = require('node-gcm');
function sendNotif(message1,message2){
var message = new gcm.Message({
data: {
title: message1,
message: message2
}
});
//Token dari device Android
var regTokens = ['TOKEN DARI LOG ANDROID'];
//Replace your developer API key with GCM enabled here
var sender = new gcm.Sender('API KEY GCM');
sender.send(message, regTokens, function (err, response) {
if(err) {
console.error(err);
} else {
console.log(response);
}
});
}
var ledBiru = new five.Led(13);
var ledKuning = new five.Led(12);
var ledPutih = new five.Led(11);
var temperature = new five.Temperature({
controller: "BMP180",
freq: 5000
});
var motion = new five.Motion({
controller: "HC-SR501",
pin: 7
});
var gas = new five.Sensor("A0");
var suhu;
var statusBiru = "Off";
var statusKuning = "Off";
var statusPutih = "Off";
var motionStatus = "On";
var gasStatus = "On";
var pushBool = false;
var pushBoolGas = false;
var client = mqtt.createClient(mqtt_url.port, mqtt_url.hostname, {
username: auth[0],
password: auth[1]
});
client.on('connect', function () {
client.publish('iot/live', devID, function() {
console.log("Terhubung ke Geeknesia");
});
client.publish('iot/will',devID,function(){
console.log("Aktif");
});
client.subscribe(topic, function() {
console.log("Subscribe");
});
});
client.on('message', function(topic, message, packet) {
console.log(message.toString());
if(message.toString()=="onBiru"){
//console.log("On Lamp");
statusBiru = "On";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
ledBiru.on();
}
else if(message.toString()=="offBiru"){
//console.log("Off Lamp");
statusBiru = "Off";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
ledBiru.off();
}
else if(message.toString()=="onKuning"){
//console.log("On Lamp");
statusKuning = "On";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
ledKuning.on();
}
else if(message.toString()=="offKuning"){
//console.log("Off Lamp");
statusKuning = "Off";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
ledKuning.off();
}
else if(message.toString()=="onPutih"){
//console.log("On Lamp");
statusPutih ="On";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
ledPutih.on();
}
else if(message.toString()=="offPutih"){
//console.log("Off Lamp");
statusPutih ="Off";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
ledPutih.off();
}
else if(message.toString()=="offAlarmMotion"){
//console.log("Off Lamp");
motionStatus ="Off";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
}
else if(message.toString()=="onAlarmMotion"){
//console.log("Off Lamp");
motionStatus ="On";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
}
else if(message.toString()=="offAlarmGas"){
//console.log("Off Lamp");
gasStatus ="Off";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
}
else if(message.toString()=="onAlarmGas"){
//console.log("Off Lamp");
gasStatus ="On";
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log("updated");
});
}
});
board.on("ready", function() {
// "calibrated" occurs once, at the beginning of a session,
motion.on("calibrated", function() {
console.log("calibrated");
});
// "motionstart" events are fired when the "calibrated"
// proximal area is disrupted, generally by some form of movement
motion.on("motionstart", function() {
console.log("motionstart");
if (motionStatus=="On"){
//send GCM
sendNotif('Bahaya!!!','Gerakan Terdeteksi!!!');
}
});
// "motionend" events are fired following a "motionstart" event
// when no movement has occurred in X ms
motion.on("motionend", function() {
console.log("motionend");
});
//gas.
gas.scale(0, 100).on("change", function() {
if(gasStatus=="On"){
if (this.value > 25 && !pushBoolGas) {
//console.log("Gas Detected");
pushBoolGas = true;
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Bahaya"}}', function() {
console.log(" celsius : ", suhu);
});
//Send GCM
sendNotif('Bahaya!!!','Gas LPG Terdeteksi!!!');
}else{
pushBoolGas = false;
}
}
});
temperature.on("change", function() {
suhu = parseFloat(Math.round(this.celsius * 100)/100).toFixed(2);
client.publish('iot/data', '{"code":"'+user+':'+pass+'","attributes":{"Suhu":"'+suhu+' Celcius","LampuBiru":"'+statusBiru+'","LampuKuning":"'+statusKuning+'","LampuPutih":"'+statusPutih+'","MotionStatus":"'+motionStatus+'","GasStatus":"'+gasStatus+'","GasInfo":"Aman"}}', function() {
console.log("updated");
});
});
});
dmFyIG1xdHQgPSByZXF1aXJlKCdtcXR0JyksIHVybCA9IHJlcXVpcmUoJ3VybCcpOwp2YXIgdXNlciA9ICJVU0VSIERFVklDRVMgR0VFS05FU0lBIjsKdmFyIHBhc3MgPSAiUEFTUyBERVZJQ0VTIEdFRUtORVNJQSI7CnZhciBkZXZJRD0gIkRFViBJRCAiOwp2YXIgYXBpS2V5ID0gIkFQSSBLRVkiOwp2YXIgdG9waWMgPSAiVE9QSUMiOwp2YXIgbXF0dF91cmwgPSB1cmwucGFyc2UoJ21xdHQ6Ly8nK3VzZXIrJzonK3Bhc3MrJ0BnZWVrbmVzaWEuY29tOjE4ODMnKTsKdmFyIGF1dGggPSAobXF0dF91cmwuYXV0aCB8fCAnOicpLnNwbGl0KCc6Jyk7CnZhciBmaXZlID0gcmVxdWlyZSgiam9obm55LWZpdmUiKTsKdmFyIEVkaXNvbiA9IHJlcXVpcmUoImVkaXNvbi1pbyIpOwp2YXIgYm9hcmQgPSBuZXcgZml2ZS5Cb2FyZCh7CiAgaW86IG5ldyBFZGlzb24oKQp9KTsKdmFyIGdjbSA9IHJlcXVpcmUoJ25vZGUtZ2NtJyk7CgpmdW5jdGlvbiBzZW5kTm90aWYobWVzc2FnZTEsbWVzc2FnZTIpewogICAgdmFyIG1lc3NhZ2UgPSBuZXcgZ2NtLk1lc3NhZ2UoewogICAgICAgIGRhdGE6IHsKICAgICAgICAgICAgdGl0bGU6IG1lc3NhZ2UxLAogICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlMgogICAgICAgIH0KICAgIH0pOwoKICAgIC8vVG9rZW4gZGFyaSBkZXZpY2UgQW5kcm9pZAogICAgdmFyIHJlZ1Rva2VucyA9IFsnVE9LRU4gREFSSSBMT0cgQU5EUk9JRCddOwogICAgCiAgICAvL1JlcGxhY2UgeW91ciBkZXZlbG9wZXIgQVBJIGtleSB3aXRoIEdDTSBlbmFibGVkIGhlcmUKICAgIHZhciBzZW5kZXIgPSBuZXcgZ2NtLlNlbmRlcignQVBJIEtFWSBHQ00nKTsKCiAgICBzZW5kZXIuc2VuZChtZXNzYWdlLCByZWdUb2tlbnMsIGZ1bmN0aW9uIChlcnIsIHJlc3BvbnNlKSB7CiAgICAgICAgaWYoZXJyKSB7CiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3BvbnNlKTsKICAgICAgICB9CiAgICB9KTsKfQoKdmFyIGxlZEJpcnUgPSBuZXcgZml2ZS5MZWQoMTMpOwp2YXIgbGVkS3VuaW5nID0gbmV3IGZpdmUuTGVkKDEyKTsKdmFyIGxlZFB1dGloID0gbmV3IGZpdmUuTGVkKDExKTsKdmFyIHRlbXBlcmF0dXJlID0gbmV3IGZpdmUuVGVtcGVyYXR1cmUoewogICAgY29udHJvbGxlcjogIkJNUDE4MCIsCiAgICBmcmVxOiA1MDAwCiAgfSk7CnZhciBtb3Rpb24gPSBuZXcgZml2ZS5Nb3Rpb24oewogICAgICAgICAgY29udHJvbGxlcjogIkhDLVNSNTAxIiwgCiAgICAgICAgICBwaW46IDcKfSk7ICAKdmFyIGdhcyA9IG5ldyBmaXZlLlNlbnNvcigiQTAiKTsKCnZhciBzdWh1Owp2YXIgc3RhdHVzQmlydSA9ICJPZmYiOwp2YXIgc3RhdHVzS3VuaW5nID0gIk9mZiI7CnZhciBzdGF0dXNQdXRpaCA9ICJPZmYiOwp2YXIgbW90aW9uU3RhdHVzID0gIk9uIjsKdmFyIGdhc1N0YXR1cyA9ICJPbiI7Cgp2YXIgcHVzaEJvb2wgPSBmYWxzZTsKdmFyIHB1c2hCb29sR2FzID0gZmFsc2U7Cgp2YXIgY2xpZW50ID0gbXF0dC5jcmVhdGVDbGllbnQobXF0dF91cmwucG9ydCwgbXF0dF91cmwuaG9zdG5hbWUsIHsKICB1c2VybmFtZTogYXV0aFswXSwKICBwYXNzd29yZDogYXV0aFsxXQp9KTsKCiAKY2xpZW50Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24gKCkgewogICAgY2xpZW50LnB1Ymxpc2goJ2lvdC9saXZlJywgZGV2SUQsIGZ1bmN0aW9uKCkgewogICAgICAgIGNvbnNvbGUubG9nKCJUZXJodWJ1bmcga2UgR2Vla25lc2lhIik7CiAgICB9KTsKICAgIAogICAgY2xpZW50LnB1Ymxpc2goJ2lvdC93aWxsJyxkZXZJRCxmdW5jdGlvbigpewogICAgICAgIGNvbnNvbGUubG9nKCJBa3RpZiIpOwogICAgfSk7CiAgICAgCiAgICBjbGllbnQuc3Vic2NyaWJlKHRvcGljLCBmdW5jdGlvbigpIHsKICAgICAgIGNvbnNvbGUubG9nKCJTdWJzY3JpYmUiKTsKICAgIH0pOwp9KTsKCiBjbGllbnQub24oJ21lc3NhZ2UnLCBmdW5jdGlvbih0b3BpYywgbWVzc2FnZSwgcGFja2V0KSB7CiAgICAgICAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UudG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgIGlmKG1lc3NhZ2UudG9TdHJpbmcoKT09Im9uQmlydSIpewogICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiT24gTGFtcCIpOwogICAgICAgICAgICAgICAgc3RhdHVzQmlydSA9ICJPbiI7CiAgICAgICAgICAgICAgICBjbGllbnQucHVibGlzaCgnaW90L2RhdGEnLCAneyJjb2RlIjoiJyt1c2VyKyc6JytwYXNzKyciLCJhdHRyaWJ1dGVzIjp7IlN1aHUiOiInK3N1aHUrJyAgICAgICAgICAgIENlbGNpdXMiLCJMYW1wdUJpcnUiOiInK3N0YXR1c0JpcnUrJyIsIkxhbXB1S3VuaW5nIjoiJytzdGF0dXNLdW5pbmcrJyIsIkxhbXB1UHV0aWgiOiInK3N0YXR1c1B1dGloKyciLCJNb3Rpb25TdGF0dXMiOiInK21vdGlvblN0YXR1cysnIiwiR2FzU3RhdHVzIjoiJytnYXNTdGF0dXMrJyIsIkdhc0luZm8iOiJCYWhheWEifX0nLCBmdW5jdGlvbigpIHsgCiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coInVwZGF0ZWQiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgbGVkQmlydS5vbigpOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIGVsc2UgaWYobWVzc2FnZS50b1N0cmluZygpPT0ib2ZmQmlydSIpewogICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiT2ZmIExhbXAiKTsKICAgICAgICAgICAgICAgIHN0YXR1c0JpcnUgPSAiT2ZmIjsKICAgICAgICAgICAgICAgIGNsaWVudC5wdWJsaXNoKCdpb3QvZGF0YScsICd7ImNvZGUiOiInK3VzZXIrJzonK3Bhc3MrJyIsImF0dHJpYnV0ZXMiOnsiU3VodSI6Iicrc3VodSsnIENlbGNpdXMiLCJMYW1wdUJpcnUiOiInK3N0YXR1c0JpcnUrJyIsIkxhbXB1S3VuaW5nIjoiJytzdGF0dXNLdW5pbmcrJyIsIkxhbXB1UHV0aWgiOiInK3N0YXR1c1B1dGloKyciLCJNb3Rpb25TdGF0dXMiOiInK21vdGlvblN0YXR1cysnIiwiR2FzU3RhdHVzIjoiJytnYXNTdGF0dXMrJyIsIkdhc0luZm8iOiJCYWhheWEifX0nLCBmdW5jdGlvbigpIHsgCiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygidXBkYXRlZCIpOwogICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGxlZEJpcnUub2ZmKCk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlIGlmKG1lc3NhZ2UudG9TdHJpbmcoKT09Im9uS3VuaW5nIil7CiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJPbiBMYW1wIik7CiAgICAgICAgICAgICAgICBzdGF0dXNLdW5pbmcgPSAiT24iOwogICAgICAgICAgICAgICAgY2xpZW50LnB1Ymxpc2goJ2lvdC9kYXRhJywgJ3siY29kZSI6IicrdXNlcisnOicrcGFzcysnIiwiYXR0cmlidXRlcyI6eyJTdWh1IjoiJytzdWh1KycgQ2VsY2l1cyIsIkxhbXB1QmlydSI6Iicrc3RhdHVzQmlydSsnIiwiTGFtcHVLdW5pbmciOiInK3N0YXR1c0t1bmluZysnIiwiTGFtcHVQdXRpaCI6Iicrc3RhdHVzUHV0aWgrJyIsIk1vdGlvblN0YXR1cyI6IicrbW90aW9uU3RhdHVzKyciLCJHYXNTdGF0dXMiOiInK2dhc1N0YXR1cysnIiwiR2FzSW5mbyI6IkJhaGF5YSJ9fScsIGZ1bmN0aW9uKCkgeyAKICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCJ1cGRhdGVkIik7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGxlZEt1bmluZy5vbigpOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIGVsc2UgaWYobWVzc2FnZS50b1N0cmluZygpPT0ib2ZmS3VuaW5nIil7CiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJPZmYgTGFtcCIpOyAgCiAgICAgICAgICAgICAgICBzdGF0dXNLdW5pbmcgPSAiT2ZmIjsKICAgICAgICAgICAgICAgIGNsaWVudC5wdWJsaXNoKCdpb3QvZGF0YScsICd7ImNvZGUiOiInK3VzZXIrJzonK3Bhc3MrJyIsImF0dHJpYnV0ZXMiOnsiU3VodSI6Iicrc3VodSsnIENlbGNpdXMiLCJMYW1wdUJpcnUiOiInK3N0YXR1c0JpcnUrJyIsIkxhbXB1S3VuaW5nIjoiJytzdGF0dXNLdW5pbmcrJyIsIkxhbXB1UHV0aWgiOiInK3N0YXR1c1B1dGloKyciLCJNb3Rpb25TdGF0dXMiOiInK21vdGlvblN0YXR1cysnIiwiR2FzU3RhdHVzIjoiJytnYXNTdGF0dXMrJyIsIkdhc0luZm8iOiJCYWhheWEifX0nLCBmdW5jdGlvbigpIHsgCiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygidXBkYXRlZCIpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICBsZWRLdW5pbmcub2ZmKCk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlIGlmKG1lc3NhZ2UudG9TdHJpbmcoKT09Im9uUHV0aWgiKXsKICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coIk9uIExhbXAiKTsKICAgICAgICAgICAgICAgIHN0YXR1c1B1dGloID0iT24iOwogICAgICAgICAgICAgICAgY2xpZW50LnB1Ymxpc2goJ2lvdC9kYXRhJywgJ3siY29kZSI6IicrdXNlcisnOicrcGFzcysnIiwiYXR0cmlidXRlcyI6eyJTdWh1IjoiJytzdWh1KycgQ2VsY2l1cyIsIkxhbXB1QmlydSI6Iicrc3RhdHVzQmlydSsnIiwiTGFtcHVLdW5pbmciOiInK3N0YXR1c0t1bmluZysnIiwiTGFtcHVQdXRpaCI6Iicrc3RhdHVzUHV0aWgrJyIsIk1vdGlvblN0YXR1cyI6IicrbW90aW9uU3RhdHVzKyciLCJHYXNTdGF0dXMiOiInK2dhc1N0YXR1cysnIiwiR2FzSW5mbyI6IkJhaGF5YSJ9fScsIGZ1bmN0aW9uKCkgeyAKICAgICAgICAgICAgICAgY29uc29sZS5sb2coInVwZGF0ZWQiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgbGVkUHV0aWgub24oKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICBlbHNlIGlmKG1lc3NhZ2UudG9TdHJpbmcoKT09Im9mZlB1dGloIil7CiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJPZmYgTGFtcCIpOyAgCiAgICAgICAgICAgICAgICBzdGF0dXNQdXRpaCA9Ik9mZiI7ICAgCiAgICAgICAgICAgICAgICBjbGllbnQucHVibGlzaCgnaW90L2RhdGEnLCAneyJjb2RlIjoiJyt1c2VyKyc6JytwYXNzKyciLCJhdHRyaWJ1dGVzIjp7IlN1aHUiOiInK3N1aHUrJyBDZWxjaXVzIiwiTGFtcHVCaXJ1IjoiJytzdGF0dXNCaXJ1KyciLCJMYW1wdUt1bmluZyI6Iicrc3RhdHVzS3VuaW5nKyciLCJMYW1wdVB1dGloIjoiJytzdGF0dXNQdXRpaCsnIiwiTW90aW9uU3RhdHVzIjoiJyttb3Rpb25TdGF0dXMrJyIsIkdhc1N0YXR1cyI6IicrZ2FzU3RhdHVzKyciLCJHYXNJbmZvIjoiQmFoYXlhIn19JywgZnVuY3Rpb24oKSB7IAogICAgICAgICAgICAgICAgY29uc29sZS5sb2coInVwZGF0ZWQiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgbGVkUHV0aWgub2ZmKCk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgZWxzZSBpZihtZXNzYWdlLnRvU3RyaW5nKCk9PSJvZmZBbGFybU1vdGlvbiIpewogICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiT2ZmIExhbXAiKTsgIAogICAgICAgICAgICAgICAgbW90aW9uU3RhdHVzID0iT2ZmIjsgICAKICAgICAgICAgICAgICAgIGNsaWVudC5wdWJsaXNoKCdpb3QvZGF0YScsICd7ImNvZGUiOiInK3VzZXIrJzonK3Bhc3MrJyIsImF0dHJpYnV0ZXMiOnsiU3VodSI6Iicrc3VodSsnIENlbGNpdXMiLCJMYW1wdUJpcnUiOiInK3N0YXR1c0JpcnUrJyIsIkxhbXB1S3VuaW5nIjoiJytzdGF0dXNLdW5pbmcrJyIsIkxhbXB1UHV0aWgiOiInK3N0YXR1c1B1dGloKyciLCJNb3Rpb25TdGF0dXMiOiInK21vdGlvblN0YXR1cysnIiwiR2FzU3RhdHVzIjoiJytnYXNTdGF0dXMrJyIsIkdhc0luZm8iOiJCYWhheWEifX0nLCBmdW5jdGlvbigpIHsgCiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygidXBkYXRlZCIpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlIGlmKG1lc3NhZ2UudG9TdHJpbmcoKT09Im9uQWxhcm1Nb3Rpb24iKXsKICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coIk9mZiBMYW1wIik7ICAKICAgICAgICAgICAgICAgIG1vdGlvblN0YXR1cyA9Ik9uIjsgICAKICAgICAgICAgICAgICAgIGNsaWVudC5wdWJsaXNoKCdpb3QvZGF0YScsICd7ImNvZGUiOiInK3VzZXIrJzonK3Bhc3MrJyIsImF0dHJpYnV0ZXMiOnsiU3VodSI6Iicrc3VodSsnIENlbGNpdXMiLCJMYW1wdUJpcnUiOiInK3N0YXR1c0JpcnUrJyIsIkxhbXB1S3VuaW5nIjoiJytzdGF0dXNLdW5pbmcrJyIsIkxhbXB1UHV0aWgiOiInK3N0YXR1c1B1dGloKyciLCJNb3Rpb25TdGF0dXMiOiInK21vdGlvblN0YXR1cysnIiwiR2FzU3RhdHVzIjoiJytnYXNTdGF0dXMrJyIsIkdhc0luZm8iOiJCYWhheWEifX0nLCBmdW5jdGlvbigpIHsgCiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygidXBkYXRlZCIpOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIGVsc2UgaWYobWVzc2FnZS50b1N0cmluZygpPT0ib2ZmQWxhcm1HYXMiKXsKICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coIk9mZiBMYW1wIik7ICAKICAgICAgICAgICAgICAgIGdhc1N0YXR1cyA9Ik9mZiI7ICAgCiAgICAgICAgICAgICAgICBjbGllbnQucHVibGlzaCgnaW90L2RhdGEnLCAneyJjb2RlIjoiJyt1c2VyKyc6JytwYXNzKyciLCJhdHRyaWJ1dGVzIjp7IlN1aHUiOiInK3N1aHUrJyBDZWxjaXVzIiwiTGFtcHVCaXJ1IjoiJytzdGF0dXNCaXJ1KyciLCJMYW1wdUt1bmluZyI6Iicrc3RhdHVzS3VuaW5nKyciLCJMYW1wdVB1dGloIjoiJytzdGF0dXNQdXRpaCsnIiwiTW90aW9uU3RhdHVzIjoiJyttb3Rpb25TdGF0dXMrJyIsIkdhc1N0YXR1cyI6IicrZ2FzU3RhdHVzKyciLCJHYXNJbmZvIjoiQmFoYXlhIn19JywgZnVuY3Rpb24oKSB7IAogICAgICAgICAgICAgICAgY29uc29sZS5sb2coInVwZGF0ZWQiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICB9CiAgICAgZWxzZSBpZihtZXNzYWdlLnRvU3RyaW5nKCk9PSJvbkFsYXJtR2FzIil7CiAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJPZmYgTGFtcCIpOyAgCiAgICAgICAgICAgICAgICBnYXNTdGF0dXMgPSJPbiI7ICAgCiAgICAgICAgICAgICAgICBjbGllbnQucHVibGlzaCgnaW90L2RhdGEnLCAneyJjb2RlIjoiJyt1c2VyKyc6JytwYXNzKyciLCJhdHRyaWJ1dGVzIjp7IlN1aHUiOiInK3N1aHUrJyBDZWxjaXVzIiwiTGFtcHVCaXJ1IjoiJytzdGF0dXNCaXJ1KyciLCJMYW1wdUt1bmluZyI6Iicrc3RhdHVzS3VuaW5nKyciLCJMYW1wdVB1dGloIjoiJytzdGF0dXNQdXRpaCsnIiwiTW90aW9uU3RhdHVzIjoiJyttb3Rpb25TdGF0dXMrJyIsIkdhc1N0YXR1cyI6IicrZ2FzU3RhdHVzKyciLCJHYXNJbmZvIjoiQmFoYXlhIn19JywgZnVuY3Rpb24oKSB7IAogICAgICAgICAgICAgICAgY29uc29sZS5sb2coInVwZGF0ZWQiKTsKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwoKCiBib2FyZC5vbigicmVhZHkiLCBmdW5jdGlvbigpIHsKCiAgLy8gImNhbGlicmF0ZWQiIG9jY3VycyBvbmNlLCBhdCB0aGUgYmVnaW5uaW5nIG9mIGEgc2Vzc2lvbiwKICBtb3Rpb24ub24oImNhbGlicmF0ZWQiLCBmdW5jdGlvbigpIHsKICAgIGNvbnNvbGUubG9nKCJjYWxpYnJhdGVkIik7CiAgfSk7CgogIC8vICJtb3Rpb25zdGFydCIgZXZlbnRzIGFyZSBmaXJlZCB3aGVuIHRoZSAiY2FsaWJyYXRlZCIKICAvLyBwcm94aW1hbCBhcmVhIGlzIGRpc3J1cHRlZCwgZ2VuZXJhbGx5IGJ5IHNvbWUgZm9ybSBvZiBtb3ZlbWVudAogIG1vdGlvbi5vbigibW90aW9uc3RhcnQiLCBmdW5jdGlvbigpIHsKICAgIGNvbnNvbGUubG9nKCJtb3Rpb25zdGFydCIpOwogICAgaWYgKG1vdGlvblN0YXR1cz09Ik9uIil7CiAgICAgICAgIC8vc2VuZCBHQ00KICAgICAgICBzZW5kTm90aWYoJ0JhaGF5YSEhIScsJ0dlcmFrYW4gVGVyZGV0ZWtzaSEhIScpOwogICAgfQogIH0pOwoKICAvLyAibW90aW9uZW5kIiBldmVudHMgYXJlIGZpcmVkIGZvbGxvd2luZyBhICJtb3Rpb25zdGFydCIgZXZlbnQKICAvLyB3aGVuIG5vIG1vdmVtZW50IGhhcyBvY2N1cnJlZCBpbiBYIG1zCiAgbW90aW9uLm9uKCJtb3Rpb25lbmQiLCBmdW5jdGlvbigpIHsKICAgIGNvbnNvbGUubG9nKCJtb3Rpb25lbmQiKTsKICB9KTsKICAgICAKCiAgLy9nYXMuICAgICAKICBnYXMuc2NhbGUoMCwgMTAwKS5vbigiY2hhbmdlIiwgZnVuY3Rpb24oKSB7CiAgICAgIGlmKGdhc1N0YXR1cz09Ik9uIil7CiAgICAgICAgaWYgKHRoaXMudmFsdWUgPiAyNSAmJiAhcHVzaEJvb2xHYXMpIHsKICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiR2FzIERldGVjdGVkIik7CiAgICAgICAgICAgIHB1c2hCb29sR2FzID0gdHJ1ZTsKICAgICAgICAgICAgY2xpZW50LnB1Ymxpc2goJ2lvdC9kYXRhJywgJ3siY29kZSI6IicrdXNlcisnOicrcGFzcysnIiwiYXR0cmlidXRlcyI6eyJTdWh1IjoiJytzdWh1KycgQ2VsY2l1cyIsIkxhbXB1QmlydSI6Iicrc3RhdHVzQmlydSsnIiwiTGFtcHVLdW5pbmciOiInK3N0YXR1c0t1bmluZysnIiwiTGFtcHVQdXRpaCI6Iicrc3RhdHVzUHV0aWgrJyIsIk1vdGlvblN0YXR1cyI6IicrbW90aW9uU3RhdHVzKyciLCJHYXNTdGF0dXMiOiInK2dhc1N0YXR1cysnIiwiR2FzSW5mbyI6IkJhaGF5YSJ9fScsIGZ1bmN0aW9uKCkgeyAKICAgICAgICAgICAgY29uc29sZS5sb2coIiAgY2Vsc2l1cyAgICAgIDogIiwgc3VodSk7CiAgICAgICAgfSk7CiAgICAgICAgICAgIC8vU2VuZCBHQ00KICAgICAgICAgICAgc2VuZE5vdGlmKCdCYWhheWEhISEnLCdHYXMgTFBHIFRlcmRldGVrc2khISEnKTsKICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgcHVzaEJvb2xHYXMgPSBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICB9KTsKICAKCiAgdGVtcGVyYXR1cmUub24oImNoYW5nZSIsIGZ1bmN0aW9uKCkgewogICAgc3VodSA9IHBhcnNlRmxvYXQoTWF0aC5yb3VuZCh0aGlzLmNlbHNpdXMgKiAxMDApLzEwMCkudG9GaXhlZCgyKTsKICAgIGNsaWVudC5wdWJsaXNoKCdpb3QvZGF0YScsICd7ImNvZGUiOiInK3VzZXIrJzonK3Bhc3MrJyIsImF0dHJpYnV0ZXMiOnsiU3VodSI6Iicrc3VodSsnIENlbGNpdXMiLCJMYW1wdUJpcnUiOiInK3N0YXR1c0JpcnUrJyIsIkxhbXB1S3VuaW5nIjoiJytzdGF0dXNLdW5pbmcrJyIsIkxhbXB1UHV0aWgiOiInK3N0YXR1c1B1dGloKyciLCJNb3Rpb25TdGF0dXMiOiInK21vdGlvblN0YXR1cysnIiwiR2FzU3RhdHVzIjoiJytnYXNTdGF0dXMrJyIsIkdhc0luZm8iOiJBbWFuIn19JywgZnVuY3Rpb24oKSB7IAogICAgICAgIGNvbnNvbGUubG9nKCJ1cGRhdGVkIik7CiAgICB9KTsKICB9KTsgICAgIAp9KTs=