A self hosted chat application with end-to-end encrypted messaging.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

794 lines
81 KiB

(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("../model/AbstractModel");
require("../model/UserModel");
require("../view/AbstractView");
require("../view/UserView");
var ChatMessageViewModel_1 = require("../viewmodel/ChatMessageViewModel");
var ChatController = /** @class */ (function () {
function ChatController(model, view) {
this._model = model;
this._view = view;
}
Object.defineProperty(ChatController.prototype, "model", {
/**
* Getter model
* @return {Model}
*/
get: function () {
return this._model;
},
/**
* Setter model
* @param {Model} value
*/
set: function (value) {
this._model = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ChatController.prototype, "view", {
/**
* Getter view
* @return {View}
*/
get: function () {
return this._view;
},
/**
* Setter view
* @param {View} value
*/
set: function (value) {
this._view = value;
},
enumerable: true,
configurable: true
});
/**
* eventHandler
*/
ChatController.prototype.eventHandler = function (vm) {
this.model.someBusinessMethod(vm);
};
ChatController.prototype.test = function () {
var chatMessageViewModels = [];
var chatMessageViewModelMock = new ChatMessageViewModel_1.ChatMessageViewModel();
chatMessageViewModelMock.fromUser = "user1";
chatMessageViewModelMock.toUser = "user2";
chatMessageViewModelMock.messageCipher = "";
chatMessageViewModelMock.messageTime = new Date();
chatMessageViewModels.push(chatMessageViewModelMock);
};
return ChatController;
}());
exports.ChatController = ChatController;
},{"../model/AbstractModel":4,"../model/UserModel":7,"../view/AbstractView":12,"../view/UserView":14,"../viewmodel/ChatMessageViewModel":16}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("../model/AbstractModel");
require("../model/UserModel");
require("../view/AbstractView");
require("../view/UserView");
var ActiveUserViewModel_1 = require("../viewmodel/ActiveUserViewModel");
var UserController = /** @class */ (function () {
function UserController(model, view) {
this._model = model;
this._view = view;
}
Object.defineProperty(UserController.prototype, "model", {
/**
* Getter model
* @return {Model}
*/
get: function () {
return this._model;
},
/**
* Setter model
* @param {Model} value
*/
set: function (value) {
this._model = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(UserController.prototype, "view", {
/**
* Getter view
* @return {View}
*/
get: function () {
return this._view;
},
/**
* Setter view
* @param {View} value
*/
set: function (value) {
this._view = value;
},
enumerable: true,
configurable: true
});
/**
* eventHandler
*/
UserController.prototype.eventHandler = function (vm) {
this.model.someBusinessMethod(vm);
};
UserController.prototype.test = function () {
var activeUsersMock = [];
var activeUserViewModelMock = new ActiveUserViewModel_1.ActiveUserViewModel();
activeUserViewModelMock.userName = "some user";
activeUserViewModelMock.lastActive = "3 hrs ago";
activeUserViewModelMock.online = true;
activeUsersMock.push(activeUserViewModelMock);
activeUserViewModelMock = new ActiveUserViewModel_1.ActiveUserViewModel();
activeUserViewModelMock.lastActive = "3 hrs ago";
activeUserViewModelMock.online = true;
activeUserViewModelMock.userName = "some user 2";
activeUsersMock.push(activeUserViewModelMock);
this.eventHandler(activeUsersMock);
};
return UserController;
}());
exports.UserController = UserController;
},{"../model/AbstractModel":4,"../model/UserModel":7,"../view/AbstractView":12,"../view/UserView":14,"../viewmodel/ActiveUserViewModel":15}],3:[function(require,module,exports){
(function (global){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var UserModel_1 = require("./model/UserModel");
var UserView_1 = require("./view/UserView");
var UserController_1 = require("./controller/UserController");
var loglevel_1 = __importDefault((typeof window !== "undefined" ? window['log'] : typeof global !== "undefined" ? global['log'] : null));
var handlebars_1 = __importDefault((typeof window !== "undefined" ? window['Handlebars'] : typeof global !== "undefined" ? global['Handlebars'] : null));
var markdown_it_1 = __importDefault((typeof window !== "undefined" ? window['markdownit'] : typeof global !== "undefined" ? global['markdownit'] : null));
var ChatModel_1 = require("./model/ChatModel");
var ChatView_1 = require("./view/ChatView");
var ChatController_1 = require("./controller/ChatController");
var JsonAPI_1 = require("./singleton/JsonAPI");
var SJCLEncryptionService_1 = require("./service/SJCLEncryptionService");
var LogLevelLoggerService_1 = require("./service/LogLevelLoggerService");
// import { logger } from "./singleton/Logger";
// var markdownit = require('markdown-it');
var md = new markdown_it_1.default();
var logger = new LogLevelLoggerService_1.LogLevelLogger();
var userBox = document.getElementById('contacts-box');
loglevel_1.default.setLevel("TRACE");
var userModel = new UserModel_1.UserModel();
// const userModel = ModelFactory.createModel("USER");
// @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
var userView = new UserView_1.UserView(userModel, userBox);
// console.log(userBox);
userModel.attach(userView);
// userView.model
var userController = new UserController_1.UserController(userModel, userView);
userController.test();
// userModel.someBusinessMethod(activeUsersMock);
loglevel_1.default.info("hello");
var chatModel = new ChatModel_1.ChatModel();
// @ts-ignore: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'HTMLElement'. Type 'null' is not assignable to type 'HTMLElement'.
var chatView = new ChatView_1.ChatView(chatModel, userBox);
var chatController = new ChatController_1.ChatController(chatModel, chatView);
function someFunc(vm) {
// log.info(vm);
// logger.info(vm)
}
logger.info("test");
// someFunc(activeUserViewModelMock);
// @ts-ignore: Object is possibly 'null'.
var source = document.getElementById("msg_container_template").innerHTML;
var msgContainerTemplate = handlebars_1.default.compile(source);
JsonAPI_1.JsonAPI.ActiveUsersGET;
var encryptionService = new SJCLEncryptionService_1.SJCLEncryptionService();
var ct = encryptionService.encrypt("password", "data");
console.log(encryptionService.decrypt("password", ct));
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./controller/ChatController":1,"./controller/UserController":2,"./model/ChatModel":5,"./model/UserModel":7,"./service/LogLevelLoggerService":8,"./service/SJCLEncryptionService":9,"./singleton/JsonAPI":10,"./view/ChatView":13,"./view/UserView":14}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
},{}],5:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var FetchErrorHandler_1 = require("./FetchErrorHandler");
var ChatModel = /** @class */ (function () {
function ChatModel() {
/**
* @type {Observer[]} List of subscribers. In real life, the list of
* subscribers can be stored more comprehensively (categorized by event
* type, etc.).
*/
this.observers = [];
// @ts-ignore: Cannot find name 'hostAddress'.
this.getActiveUsersUrl = "";
}
/**
* The subscription management methods.
*/
ChatModel.prototype.attach = function (observer) {
console.log('Subject: Attached an observer.');
this.observers.push(observer);
};
ChatModel.prototype.detach = function (observer) {
var observerIndex = this.observers.indexOf(observer);
this.observers.splice(observerIndex, 1);
console.log('Subject: Detached an observer.');
};
/**
* Trigger an update in each subscriber.
*/
ChatModel.prototype.notify = function () {
console.log('Subject: Notifying observers...');
for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {
var observer = _a[_i];
observer.update(this.state);
}
};
ChatModel.prototype.someBusinessMethod = function (activeuserList) {
this.state = activeuserList;
this.helperMethod();
console.log("Subject: My state has just changed");
console.log(activeuserList);
this.notify();
};
/**
* getActiveUsers
*/
ChatModel.prototype.getActiveUsers = function () {
var _this = this;
this.getActiveUsersAjax(":")
.then(function (data) {
// // activeUsers = data;
// sessionStorage.setItem('activeUsers', JSON.stringify(data));
// console.log(sessionStorage.getItem('activeUsers'));
console.log("Subject: received ajax active users");
_this.state = data;
_this.notify();
});
};
ChatModel.prototype.getActiveUsersAjax = function (authToken2) {
return __awaiter(this, void 0, void 0, function () {
var headers, response, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
headers = new Headers();
// headers.append('Authorization', basicAuthToken);
headers.append('X-AUTH-TOKEN', authToken2);
return [4 /*yield*/, fetch(this.getActiveUsersUrl, {
method: 'GET',
headers: headers
})];
case 1:
response = _a.sent();
console.log(response.clone());
if (FetchErrorHandler_1.fetchErrorHandler(response.clone())) {
return [2 /*return*/, null];
}
return [4 /*yield*/, response.json()];
case 2:
data = _a.sent();
return [2 /*return*/, data];
}
});
});
};
ChatModel.prototype.helperMethod = function () { };
return ChatModel;
}());
exports.ChatModel = ChatModel;
},{"./FetchErrorHandler":6}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function fetchErrorHandler(response) {
// alertify.success('Current position : ' + alertify.get('notifier', 'position'));
if (!response.ok) {
return response.text().catch(function (err) {
// the status was not ok and there is no json body
// throw new Error(response.statusText);
// window.alert(sprintf('Some error occured. Http code is %s', response.status));
// alertify.error(sprintf('Some error occured. Http code is %s', response.status));
return true;
}).then(function (json) {
// the status was not ok but there is a json body
// throw new Error(json.error.message); // example error message returned by a REST API
// window.alert(sprintf('Error: %s (Http code %s)', json, response.status));
// alertify.error(sprintf('Some error occured. Http code is %s', response.status));
console.log(json);
return true;
});
}
}
exports.fetchErrorHandler = fetchErrorHandler;
},{}],7:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var FetchErrorHandler_1 = require("./FetchErrorHandler");
var UserModel = /** @class */ (function () {
function UserModel() {
/**
* @type {Observer[]} List of subscribers. In real life, the list of
* subscribers can be stored more comprehensively (categorized by event
* type, etc.).
*/
this.observers = [];
// @ts-ignore: Cannot find name 'hostAddress'.
this.getActiveUsersUrl = "";
}
/**
* The subscription management methods.
*/
UserModel.prototype.attach = function (observer) {
console.log('Subject: Attached an observer.');
this.observers.push(observer);
};
UserModel.prototype.detach = function (observer) {
var observerIndex = this.observers.indexOf(observer);
this.observers.splice(observerIndex, 1);
console.log('Subject: Detached an observer.');
};
/**
* Trigger an update in each subscriber.
*/
UserModel.prototype.notify = function () {
console.log('Subject: Notifying observers...');
for (var _i = 0, _a = this.observers; _i < _a.length; _i++) {
var observer = _a[_i];
observer.update(this.state);
}
};
UserModel.prototype.someBusinessMethod = function (activeuserList) {
this.state = activeuserList;
this.helperMethod();
console.log("Subject: My state has just changed");
console.log(activeuserList);
this.notify();
};
/**
* getActiveUsers
*/
UserModel.prototype.getActiveUsers = function () {
var _this = this;
this.getActiveUsersAjax(":")
.then(function (data) {
// // activeUsers = data;
// sessionStorage.setItem('activeUsers', JSON.stringify(data));
// console.log(sessionStorage.getItem('activeUsers'));
console.log("Subject: received ajax active users");
_this.state = data;
_this.notify();
});
};
UserModel.prototype.getActiveUsersAjax = function (authToken2) {
return __awaiter(this, void 0, void 0, function () {
var headers, response, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
headers = new Headers();
// headers.append('Authorization', basicAuthToken);
headers.append('X-AUTH-TOKEN', authToken2);
return [4 /*yield*/, fetch(this.getActiveUsersUrl, {
method: 'GET',
headers: headers
})];
case 1:
response = _a.sent();
console.log(response.clone());
if (FetchErrorHandler_1.fetchErrorHandler(response.clone())) {
return [2 /*return*/, null];
}
return [4 /*yield*/, response.json()];
case 2:
data = _a.sent();
return [2 /*return*/, data];
}
});
});
};
UserModel.prototype.helperMethod = function () { };
return UserModel;
}());
exports.UserModel = UserModel;
},{"./FetchErrorHandler":6}],8:[function(require,module,exports){
(function (global){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var loglevel_1 = __importDefault((typeof window !== "undefined" ? window['log'] : typeof global !== "undefined" ? global['log'] : null));
var LogLevelLogger = /** @class */ (function () {
function LogLevelLogger() {
loglevel_1.default.setLevel("DEBUG");
}
LogLevelLogger.prototype.info = function (message) {
loglevel_1.default.info(message);
};
LogLevelLogger.prototype.warn = function (message) {
loglevel_1.default.warn(message);
};
LogLevelLogger.prototype.error = function (message) {
loglevel_1.default.error(message);
};
LogLevelLogger.prototype.debug = function (message) {
loglevel_1.default.debug(message);
};
return LogLevelLogger;
}());
exports.LogLevelLogger = LogLevelLogger;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],9:[function(require,module,exports){
(function (global){
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var sjcl_1 = __importDefault((typeof window !== "undefined" ? window['sjcl'] : typeof global !== "undefined" ? global['sjcl'] : null));
var SJCLEncryptionService = /** @class */ (function () {
function SJCLEncryptionService() {
this.params = { mode: "gcm", ts: 128, adata: "", iter: 10000 };
}
SJCLEncryptionService.prototype.encrypt = function (passphrase, plainText) {
return sjcl_1.default.encrypt(passphrase, plainText, this.params);
};
SJCLEncryptionService.prototype.decrypt = function (passphrase, cipher) {
return sjcl_1.default.decrypt(passphrase, cipher, undefined, undefined);
};
return SJCLEncryptionService;
}());
exports.SJCLEncryptionService = SJCLEncryptionService;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var JsonAPI;
(function (JsonAPI) {
// @ts-ignore: Cannot find name 'hostAddress'.
JsonAPI.ActiveUsersGET = "/api/chat/get/active-users/";
})(JsonAPI = exports.JsonAPI || (exports.JsonAPI = {}));
},{}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var TemplateFactory = /** @class */ (function () {
function TemplateFactory() {
}
TemplateFactory.getTemplate = function () {
// @ts-ignore: Object is possibly 'null'.
var source = document.getElementById("user-contact-online-template").innerHTML;
var msgContainerTemplate = Handlebars.compile(source);
return msgContainerTemplate;
};
return TemplateFactory;
}());
exports.TemplateFactory = TemplateFactory;
},{}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
},{}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var TemplateFactory_1 = require("../template/TemplateFactory");
var ChatView = /** @class */ (function () {
// private userBoxes: any[] = [];
function ChatView(model, element) {
this._model = model;
this._element = element;
}
Object.defineProperty(ChatView.prototype, "model", {
/**
* Getter model
* @return {Model}
*/
get: function () {
return this._model;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ChatView.prototype, "element", {
/**
* Getter element
* @return {any}
*/
get: function () {
return this._element;
},
enumerable: true,
configurable: true
});
// /**
// * Setter model
// * @param {Model} value
// */
// public set model(value: Model) {
// this._model = value;
// }
// /**
// * Setter element
// * @param {any} value
// */
// public set element(value: any) {
// this._element = value;
// }
ChatView.prototype.update = function (data) {
var template = TemplateFactory_1.TemplateFactory.getTemplate();
var html = "";
data.forEach(function (element) {
html += template(element);
});
this.element.innerHTML = html;
this.addUserCallBacks();
console.log(this.element.innerHTML);
};
ChatView.prototype.helper = function () {
};
ChatView.prototype.addUserCallBacks = function () {
var userBoxes = document.getElementsByClassName('user-box');
for (var i = 0; i < userBoxes.length; i++) {
var userBox = userBoxes[i];
userBoxes[i].addEventListener('click', this.userCallBack.bind(this, userBox));
}
};
ChatView.prototype.userCallBack = function (el) {
var current = document.getElementsByClassName('user-box active');
var passphrase = "";
if (current.length > 0) {
if (passphrase == '') {
// alert('Please input passphrase')
// alertify.error('Please enter a passphrase');
// return;
}
current[0].className = current[0].className.replace(" active", "");
}
// Add the active class to the current/clicked button
else if (current.length == 0) {
var elem_1 = document.getElementById('passphrase-initial');
passphrase = "";
if (passphrase == '') {
// // alert('Please input passphrase')
// // alertify.error('Please enter a passphrase');
// return;
}
// @ts-ignore: Object is possibly 'null'.
document.getElementById('no-user-selected').hidden = true;
// @ts-ignore: Object is possibly 'null'.
document.getElementById('chat-card').hidden = false;
// @ts-ignore: Object is possibly 'null'.
elem_1.hidden = true;
}
// console.log(this.getElementsByClassName('to-user-span'));
var elem = el.getElementsByClassName('to-user-span')[0];
var userName = elem.innerText;
// @ts-ignore: Object is possibly 'null'.
document.getElementById('user-name-span').innerText = userName;
// populateMessages(userName, passphrase);
sessionStorage.setItem('selectedUser', userName);
el.className += " active";
};
return ChatView;
}());
exports.ChatView = ChatView;
},{"../template/TemplateFactory":11}],14:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var TemplateFactory_1 = require("../template/TemplateFactory");
var UserView = /** @class */ (function () {
// private userBoxes: any[] = [];
function UserView(model, element) {
this._model = model;
this._element = element;
}
Object.defineProperty(UserView.prototype, "model", {
/**
* Getter model
* @return {Model}
*/
get: function () {
return this._model;
},
enumerable: true,
configurable: true
});
Object.defineProperty(UserView.prototype, "element", {
/**
* Getter element
* @return {any}
*/
get: function () {
return this._element;
},
enumerable: true,
configurable: true
});
// /**
// * Setter model
// * @param {Model} value
// */
// public set model(value: Model) {
// this._model = value;
// }
// /**
// * Setter element
// * @param {any} value
// */
// public set element(value: any) {
// this._element = value;
// }
UserView.prototype.update = function (data) {
var template = TemplateFactory_1.TemplateFactory.getTemplate();
var html = "";
data.forEach(function (element) {
html += template(element);
});
this.element.innerHTML = html;
this.addUserCallBacks();
console.log(this.element.innerHTML);
};
UserView.prototype.helper = function () {
};
UserView.prototype.addUserCallBacks = function () {
var userBoxes = document.getElementsByClassName('user-box');
for (var i = 0; i < userBoxes.length; i++) {
var userBox = userBoxes[i];
userBoxes[i].addEventListener('click', this.userCallBack.bind(this, userBox));
}
};
UserView.prototype.userCallBack = function (el) {
var current = document.getElementsByClassName('user-box active');
var passphrase = "";
if (current.length > 0) {
if (passphrase == '') {
// alert('Please input passphrase')
// alertify.error('Please enter a passphrase');
// return;
}
current[0].className = current[0].className.replace(" active", "");
}
// Add the active class to the current/clicked button
else if (current.length == 0) {
var elem_1 = document.getElementById('passphrase-initial');
passphrase = "";
if (passphrase == '') {
// // alert('Please input passphrase')
// // alertify.error('Please enter a passphrase');
// return;
}
// @ts-ignore: Object is possibly 'null'.
document.getElementById('no-user-selected').hidden = true;
// @ts-ignore: Object is possibly 'null'.
document.getElementById('chat-card').hidden = false;
// @ts-ignore: Object is possibly 'null'.
elem_1.hidden = true;
}
// console.log(this.getElementsByClassName('to-user-span'));
var elem = el.getElementsByClassName('to-user-span')[0];
var userName = elem.innerText;
// @ts-ignore: Object is possibly 'null'.
document.getElementById('user-name-span').innerText = userName;
// populateMessages(userName, passphrase);
sessionStorage.setItem('selectedUser', userName);
el.className += " active";
};
return UserView;
}());
exports.UserView = UserView;
},{"../template/TemplateFactory":11}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ActiveUserViewModel = /** @class */ (function () {
function ActiveUserViewModel() {
}
return ActiveUserViewModel;
}());
exports.ActiveUserViewModel = ActiveUserViewModel;
},{}],16:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ChatMessageViewModel = /** @class */ (function () {
function ChatMessageViewModel() {
}
return ChatMessageViewModel;
}());
exports.ChatMessageViewModel = ChatMessageViewModel;
},{}]},{},[3])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvY29udHJvbGxlci9DaGF0Q29udHJvbGxlci50cyIsInNyYy9jb250cm9sbGVyL1VzZXJDb250cm9sbGVyLnRzIiwic3JjL21haW4udHMiLCJzcmMvbW9kZWwvQ2hhdE1vZGVsLnRzIiwic3JjL21vZGVsL0ZldGNoRXJyb3JIYW5kbGVyLnRzIiwic3JjL21vZGVsL1VzZXJNb2RlbC50cyIsInNyYy9zZXJ2aWNlL0xvZ0xldmVsTG9nZ2VyU2VydmljZS50cyIsInNyYy9zZXJ2aWNlL1NKQ0xFbmNyeXB0aW9uU2VydmljZS50cyIsInNyYy9zaW5nbGV0b24vSnNvbkFQSS50cyIsInNyYy90ZW1wbGF0ZS9UZW1wbGF0ZUZhY3RvcnkudHMiLCJzcmMvdmlldy9DaGF0Vmlldy50cyIsInNyYy92aWV3L1VzZXJWaWV3LnRzIiwic3JjL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsLnRzIiwic3JjL3ZpZXdtb2RlbC9DaGF0TWVzc2FnZVZpZXdNb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQ0Esa0NBQStCO0FBQy9CLDhCQUEyQjtBQUMzQixnQ0FBNkI7QUFDN0IsNEJBQXlCO0FBR3pCLDBFQUF5RTtBQUV6RTtJQUtJLHdCQUFZLEtBQVksRUFBRSxJQUFVO1FBQ2hDLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQ3RCLENBQUM7SUFNRCxzQkFBVyxpQ0FBSztRQUpoQjs7O1dBR0c7YUFDSDtZQUNJLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUN2QixDQUFDO1FBVUQ7OztXQUdHO2FBQ0gsVUFBaUIsS0FBWTtZQUN6QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUss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SUFBSSxDQUFDO1lBQzFELHlDQUF5QztZQUN6QyxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7WUFDcEQseUNBQXlDO1lBQ3pDLE1BQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1NBQ3RCO1FBQ0QsNERBQTREO1FBQzVELElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQWdCLENBQUM7UUFDdkUsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM5Qix5Q0FBeUM7UUFDekMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7UUFDL0QsMENBQTBDO1FBQzFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELEVBQUUsQ0FBQyxTQUFTLElBQUksU0FBUyxDQUFDO0lBQzlCLENBQUM7SUFFTCxlQUFDO0FBQUQsQ0FqSEEsQUFpSEMsSUFBQTtBQWpIWSw0QkFBUTs7Ozs7QUNSckI7SUFBQTtJQUlBLENBQUM7SUFBRCwwQkFBQztBQUFELENBSkEsQUFJQyxJQUFBO0FBSlksa0RBQW1COzs7OztBQ0FoQztJQUFBO0lBT0EsQ0FBQztJQUFELDJCQUFDO0FBQUQsQ0FQQSxBQU9DLElBQUE7QUFQWSxvREFBb0IiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJpbXBvcnQgeyBDb250cm9sbGVyIH0gZnJvbSBcIi4vQWJzdHJhY3RDb250cm9sbGVyXCI7XG5pbXBvcnQgXCIuLi9tb2RlbC9BYnN0cmFjdE1vZGVsXCJcbmltcG9ydCBcIi4uL21vZGVsL1VzZXJNb2RlbFwiXG5pbXBvcnQgXCIuLi92aWV3L0Fic3RyYWN0Vmlld1wiXG5pbXBvcnQgXCIuLi92aWV3L1VzZXJWaWV3XCJcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL0Fic3RyYWN0TW9kZWxcIjtcbmltcG9ydCB7IFZpZXcgfSBmcm9tIFwiLi4vdmlldy9BYnN0cmFjdFZpZXdcIjtcbmltcG9ydCB7IENoYXRNZXNzYWdlVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9DaGF0TWVzc2FnZVZpZXdNb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgQ2hhdENvbnRyb2xsZXIgaW1wbGVtZW50cyBDb250cm9sbGVye1xuICAgIHByaXZhdGUgX21vZGVsOiBNb2RlbDtcbiAgICBwcml2YXRlIF92aWV3OiBWaWV3O1xuXG5cbiAgICBjb25zdHJ1Y3Rvcihtb2RlbDogTW9kZWwsIHZpZXc6IFZpZXcpIHtcbiAgICAgICAgdGhpcy5fbW9kZWwgPSBtb2RlbDtcbiAgICAgICAgdGhpcy5fdmlldyA9IHZpZXc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0dGVyIG1vZGVsXG4gICAgICogQHJldHVybiB7TW9kZWx9XG4gICAgICovXG4gICAgcHVibGljIGdldCBtb2RlbCgpOiBNb2RlbCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2RlbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXR0ZXIgdmlld1xuICAgICAqIEByZXR1cm4ge1ZpZXd9XG4gICAgICovXG4gICAgcHVibGljIGdldCB2aWV3KCk6IFZpZXcge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmlldztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXR0ZXIgbW9kZWxcbiAgICAgKiBAcGFyYW0ge01vZGVsfSB2YWx1ZVxuICAgICAqL1xuICAgIHB1YmxpYyBzZXQgbW9kZWwodmFsdWU6IE1vZGVsKSB7XG4gICAgICAgIHRoaXMuX21vZGVsID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0dGVyIHZpZXdcbiAgICAgKiBAcGFyYW0ge1ZpZXd9IHZhbHVlXG4gICAgICovXG4gICAgcHVibGljIHNldCB2aWV3KHZhbHVlOiBWaWV3KSB7XG4gICAgICAgIHRoaXMuX3ZpZXcgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBldmVudEhhbmRsZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgZXZlbnRIYW5kbGVyKHZtOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMubW9kZWwuc29tZUJ1c2luZXNzTWV0aG9kKHZtKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdGVzdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY2hhdE1lc3NhZ2VWaWV3TW9kZWxzOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdID0gW107XG4gICAgICAgIGxldCBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2sgPSBuZXcgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwoKTtcbiAgICAgICAgY2hhdE1lc3NhZ2VWaWV3TW9kZWxNb2NrLmZyb21Vc2VyID0gXCJ1c2VyMVwiO1xuICAgICAgICBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2sudG9Vc2VyID0gXCJ1c2VyMlwiO1xuICAgICAgICBjaGF0TWVzc2FnZVZpZXdNb2RlbE1vY2subWVzc2FnZUNpcGhlciA9IFwiXCI7XG4gICAgICAgIGNoYXRNZXNzYWdlVmlld01vZGVsTW9jay5tZXNzYWdlVGltZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGNoYXRNZXNzYWdlVmlld01vZGVscy5wdXNoKGNoYXRNZXNzYWdlVmlld01vZGVsTW9jayk7XG4gICAgfVxuXG4gICAgXG59IiwiaW1wb3J0IHsgQ29udHJvbGxlciB9IGZyb20gXCIuL0Fic3RyYWN0Q29udHJvbGxlclwiO1xuaW1wb3J0IFwiLi4vbW9kZWwvQWJzdHJhY3RNb2RlbFwiXG5pbXBvcnQgXCIuLi9tb2RlbC9Vc2VyTW9kZWxcIlxuaW1wb3J0IFwiLi4vdmlldy9BYnN0cmFjdFZpZXdcIlxuaW1wb3J0IFwiLi4vdmlldy9Vc2VyVmlld1wiXG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9tb2RlbC9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4uL3ZpZXcvQWJzdHJhY3RWaWV3XCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyQ29udHJvbGxlciBpbXBsZW1lbnRzIENvbnRyb2xsZXJ7XG4gICAgcHJpdmF0ZSBfbW9kZWw6IE1vZGVsO1xuICAgIHByaXZhdGUgX3ZpZXc6IFZpZXc7XG5cblxuICAgIGNvbnN0cnVjdG9yKG1vZGVsOiBNb2RlbCwgdmlldzogVmlldykge1xuICAgICAgICB0aGlzLl9tb2RlbCA9IG1vZGVsO1xuICAgICAgICB0aGlzLl92aWV3ID0gdmlldztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXR0ZXIgbW9kZWxcbiAgICAgKiBAcmV0dXJuIHtNb2RlbH1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG1vZGVsKCk6IE1vZGVsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vZGVsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHRlciB2aWV3XG4gICAgICogQHJldHVybiB7Vmlld31cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHZpZXcoKTogVmlldyB7XG4gICAgICAgIHJldHVybiB0aGlzLl92aWV3O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHRlciBtb2RlbFxuICAgICAqIEBwYXJhbSB7TW9kZWx9IHZhbHVlXG4gICAgICovXG4gICAgcHVibGljIHNldCBtb2RlbCh2YWx1ZTogTW9kZWwpIHtcbiAgICAgICAgdGhpcy5fbW9kZWwgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXR0ZXIgdmlld1xuICAgICAqIEBwYXJhbSB7Vmlld30gdmFsdWVcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IHZpZXcodmFsdWU6IFZpZXcpIHtcbiAgICAgICAgdGhpcy5fdmlldyA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGV2ZW50SGFuZGxlclxuICAgICAqL1xuICAgIHB1YmxpYyBldmVudEhhbmRsZXIodm06IEFjdGl2ZVVzZXJWaWV3TW9kZWxbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLm1vZGVsLnNvbWVCdXNpbmVzc01ldGhvZCh2bSk7XG4gICAgfVxuXG4gICAgcHVibGljIHRlc3QoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZVVzZXJzTW9jazogQWN0aXZlVXNlclZpZXdNb2RlbFtdID0gW107XG4gICAgICAgIGxldCBhY3RpdmVVc2VyVmlld01vZGVsTW9jayA9IG5ldyBBY3RpdmVVc2VyVmlld01vZGVsKCk7XG4gICAgICAgIGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrLnVzZXJOYW1lID0gXCJzb21lIHVzZXJcIjtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2subGFzdEFjdGl2ZSA9IFwiMyBocnMgYWdvXCI7XG4gICAgICAgIGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrLm9ubGluZSA9IHRydWU7XG4gICAgICAgIGFjdGl2ZVVzZXJzTW9jay5wdXNoKGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrKTtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sgPSBuZXcgQWN0aXZlVXNlclZpZXdNb2RlbCgpO1xuICAgICAgICBhY3RpdmVVc2VyVmlld01vZGVsTW9jay5sYXN0QWN0aXZlID0gXCIzIGhycyBhZ29cIjtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sub25saW5lID0gdHJ1ZTtcbiAgICAgICAgYWN0aXZlVXNlclZpZXdNb2RlbE1vY2sudXNlck5hbWUgPSBcInNvbWUgdXNlciAyXCI7XG4gICAgICAgIGFjdGl2ZVVzZXJzTW9jay5wdXNoKGFjdGl2ZVVzZXJWaWV3TW9kZWxNb2NrKTtcbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIoYWN0aXZlVXNlcnNNb2NrKTtcbiAgICB9XG5cbiAgICBcbn0iLCJpbXBvcnQgeyBDb250cm9sbGVyIH0gZnJvbSBcIi4vY29udHJvbGxlci9BYnN0cmFjdENvbnRyb2xsZXJcIjtcbmltcG9ydCB7IFVzZXJNb2RlbCB9IGZyb20gXCIuL21vZGVsL1VzZXJNb2RlbFwiXG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL21vZGVsL0Fic3RyYWN0TW9kZWxcIjtcbmltcG9ydCB7IFZpZXcgfSBmcm9tIFwiLi92aWV3L0Fic3RyYWN0Vmlld1wiO1xuaW1wb3J0IHsgVXNlclZpZXcgfSBmcm9tIFwiLi92aWV3L1VzZXJWaWV3XCI7XG5pbXBvcnQgeyBVc2VyQ29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXIvVXNlckNvbnRyb2xsZXJcIjtcbmltcG9ydCBsb2cgZnJvbSBcImxvZ2xldmVsXCI7XG5pbXBvcnQgeyBNb2RlbEZhY3RvcnkgfSBmcm9tIFwiLi9tb2RlbC9Nb2RlbEZhY3RvcnlcIjtcbmltcG9ydCB7IEFjdGl2ZVVzZXJWaWV3TW9kZWwgfSBmcm9tIFwiLi92aWV3bW9kZWwvQWN0aXZlVXNlclZpZXdNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdE1lc3NhZ2VWaWV3TW9kZWwgfSBmcm9tIFwiLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcbmltcG9ydCBIYW5kbGViYXJzIGZyb20gXCJoYW5kbGViYXJzXCI7XG5pbXBvcnQgbWFya2Rvd25pdCBmcm9tIFwibWFya2Rvd24taXRcIjtcbmltcG9ydCB7IENoYXRNb2RlbCB9IGZyb20gXCIuL21vZGVsL0NoYXRNb2RlbFwiO1xuaW1wb3J0IHsgQ2hhdFZpZXcgfSBmcm9tIFwiLi92aWV3L0NoYXRWaWV3XCI7XG5pbXBvcnQgeyBDaGF0Q29udHJvbGxlciB9IGZyb20gXCIuL2NvbnRyb2xsZXIvQ2hhdENvbnRyb2xsZXJcIjtcbmltcG9ydCB7IEpzb25BUEkgfSBmcm9tIFwiLi9zaW5nbGV0b24vSnNvbkFQSVwiO1xuaW1wb3J0IHsgU0pDTEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZS9TSkNMRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZS9FbmNyeXB0aW9uU2VydmljZVwiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vc2VydmljZS9Mb2dnZXJTZXJ2aWNlXCI7XG5pbXBvcnQgeyBMb2dMZXZlbExvZ2dlciB9IGZyb20gXCIuL3NlcnZpY2UvTG9nTGV2ZWxMb2dnZXJTZXJ2aWNlXCI7XG4vLyBpbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwiLi9zaW5nbGV0b24vTG9nZ2VyXCI7XG4vLyB2YXIgbWFya2Rvd25pdCA9IHJlcXVpcmUoJ21hcmtkb3duLWl0Jyk7XG52YXIgbWQgPSBuZXcgbWFya2Rvd25pdCgpO1xuXG5jb25zdCBsb2dnZXI6IExvZ2dlciA9IG5ldyBMb2dMZXZlbExvZ2dlcigpO1xuXG5sZXQgdXNlckJveCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjb250YWN0cy1ib3gnKTtcblxubG9nLnNldExldmVsKFwiVFJBQ0VcIilcbmxldCB1c2VyTW9kZWwgPSBuZXcgVXNlck1vZGVsKCk7XG4vLyBjb25zdCB1c2VyTW9kZWwgPSBNb2RlbEZhY3RvcnkuY3JlYXRlTW9kZWwoXCJVU0VSXCIpO1xuLy8gQHRzLWlnbm9yZTogQXJndW1lbnQgb2YgdHlwZSAnSFRNTEVsZW1lbnQgfCBudWxsJyBpcyBub3QgYXNzaWduYWJsZSB0byBwYXJhbWV0ZXIgb2YgdHlwZSAnSFRNTEVsZW1lbnQnLiBUeXBlICdudWxsJyBpcyBub3QgYXNzaWduYWJsZSB0byB0eXBlICdIVE1MRWxlbWVudCcuXG5jb25zdCB1c2VyVmlldyA9IG5ldyBVc2VyVmlldyh1c2VyTW9kZWwsIHVzZXJCb3gpO1xuXG4vLyBjb25zb2xlLmxvZyh1c2VyQm94KTtcblxudXNlck1vZGVsLmF0dGFjaCh1c2VyVmlldyk7XG4vLyB1c2VyVmlldy5tb2RlbFxuY29uc3QgdXNlckNvbnRyb2xsZXIgPSBuZXcgVXNlckNvbnRyb2xsZXIodXNlck1vZGVsLCB1c2VyVmlldyk7XG51c2VyQ29udHJvbGxlci50ZXN0KCk7XG5cblxuXG4vLyB1c2VyTW9kZWwuc29tZUJ1c2luZXNzTWV0aG9kKGFjdGl2ZVVzZXJzTW9jayk7XG5sb2cuaW5mbyhcImhlbGxvXCIpO1xuXG5jb25zdCBjaGF0TW9kZWwgPSBuZXcgQ2hhdE1vZGVsKCk7XG4vLyBAdHMtaWdub3JlOiBBcmd1bWVudCBvZiB0eXBlICdIVE1MRWxlbWVudCB8IG51bGwnIGlzIG5vdCBhc3NpZ25hYmxlIHRvIHBhcmFtZXRlciBvZiB0eXBlICdIVE1MRWxlbWVudCcuIFR5cGUgJ251bGwnIGlzIG5vdCBhc3NpZ25hYmxlIHRvIHR5cGUgJ0hUTUxFbGVtZW50Jy5cbmNvbnN0IGNoYXRWaWV3ID0gbmV3IENoYXRWaWV3KGNoYXRNb2RlbCwgdXNlckJveCk7XG5jb25zdCBjaGF0Q29udHJvbGxlciA9IG5ldyBDaGF0Q29udHJvbGxlcihjaGF0TW9kZWwsIGNoYXRWaWV3KTtcblxuXG5mdW5jdGlvbiBzb21lRnVuYyh2bTogQWN0aXZlVXNlclZpZXdNb2RlbCk6IHZvaWQge1xuICAgIC8vIGxvZy5pbmZvKHZtKTtcbiAgICAvLyBsb2dnZXIuaW5mbyh2bSlcbn1cblxubG9nZ2VyLmluZm8oXCJ0ZXN0XCIpO1xuLy8gc29tZUZ1bmMoYWN0aXZlVXNlclZpZXdNb2RlbE1vY2spO1xuXG4vLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxudmFyIHNvdXJjZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwibXNnX2NvbnRhaW5lcl90ZW1wbGF0ZVwiKS5pbm5lckhUTUw7XG5cbnZhciBtc2dDb250YWluZXJUZW1wbGF0ZSA9IEhhbmRsZWJhcnMuY29tcGlsZShzb3VyY2UpO1xuXG5Kc29uQVBJLkFjdGl2ZVVzZXJzR0VUXG5cbmxldCBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UgPSBuZXcgU0pDTEVuY3J5cHRpb25TZXJ2aWNlKCk7XG5sZXQgY3QgPSBlbmNyeXB0aW9uU2VydmljZS5lbmNyeXB0KFwicGFzc3dvcmRcIixcImRhdGFcIik7XG5jb25zb2xlLmxvZyhlbmNyeXB0aW9uU2VydmljZS5kZWNyeXB0KFwicGFzc3dvcmRcIiwgY3QpKTsiLCJpbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2YWJsZVwiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi9BYnN0cmFjdE1vZGVsXCI7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmVyXCI7XG5pbXBvcnQgeyBmZXRjaEVycm9ySGFuZGxlciB9IGZyb20gXCIuL0ZldGNoRXJyb3JIYW5kbGVyXCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZVZpZXdNb2RlbCB9IGZyb20gXCIuLi92aWV3bW9kZWwvQ2hhdE1lc3NhZ2VWaWV3TW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIENoYXRNb2RlbCBpbXBsZW1lbnRzIE1vZGVsLCBTdWJqZWN0IHtcbiAgICAvKipcbiAgKiBAdHlwZSB7T2JzZXJ2ZXJbXX0gTGlzdCBvZiBzdWJzY3JpYmVycy4gSW4gcmVhbCBsaWZlLCB0aGUgbGlzdCBvZlxuICAqIHN1YnNjcmliZXJzIGNhbiBiZSBzdG9yZWQgbW9yZSBjb21wcmVoZW5zaXZlbHkgKGNhdGVnb3JpemVkIGJ5IGV2ZW50XG4gICogdHlwZSwgZXRjLikuXG4gICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBvYnNlcnZlcnM6IE9ic2VydmVyW10gPSBbXTtcbiAgICBwcml2YXRlIHN0YXRlOiBDaGF0TWVzc2FnZVZpZXdNb2RlbFtdIHwgdW5kZWZpbmVkO1xuICAgIC8vIEB0cy1pZ25vcmU6IENhbm5vdCBmaW5kIG5hbWUgJ2hvc3RBZGRyZXNzJy5cbiAgICBnZXRBY3RpdmVVc2Vyc1VybCA9IFwiXCI7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHsgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdWJzY3JpcHRpb24gbWFuYWdlbWVudCBtZXRob2RzLlxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2gob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBBdHRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgcHVibGljIGRldGFjaChvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXJJbmRleCA9IHRoaXMub2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2Uob2JzZXJ2ZXJJbmRleCwgMSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBEZXRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGFuIHVwZGF0ZSBpbiBlYWNoIHN1YnNjcmliZXIuXG4gICAgICovXG4gICAgcHVibGljIG5vdGlmeSgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1N1YmplY3Q6IE5vdGlmeWluZyBvYnNlcnZlcnMuLi4nKTtcbiAgICAgICAgZm9yIChjb25zdCBvYnNlcnZlciBvZiB0aGlzLm9ic2VydmVycykge1xuICAgICAgICAgICAgb2JzZXJ2ZXIudXBkYXRlKHRoaXMuc3RhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHNvbWVCdXNpbmVzc01ldGhvZChhY3RpdmV1c2VyTGlzdDogQ2hhdE1lc3NhZ2VWaWV3TW9kZWxbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLnN0YXRlID0gYWN0aXZldXNlckxpc3Q7XG4gICAgICAgIHRoaXMuaGVscGVyTWV0aG9kKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGBTdWJqZWN0OiBNeSBzdGF0ZSBoYXMganVzdCBjaGFuZ2VkYCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGFjdGl2ZXVzZXJMaXN0KTtcbiAgICAgICAgdGhpcy5ub3RpZnkoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBnZXRBY3RpdmVVc2Vyc1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRBY3RpdmVVc2VycygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRBY3RpdmVVc2Vyc0FqYXgoXCI6XCIpXG4gICAgICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgICAgICAgLy8gLy8gYWN0aXZlVXNlcnMgPSBkYXRhO1xuICAgICAgICAgICAgLy8gc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnYWN0aXZlVXNlcnMnLCBKU09OLnN0cmluZ2lmeShkYXRhKSk7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdhY3RpdmVVc2VycycpKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBTdWJqZWN0OiByZWNlaXZlZCBhamF4IGFjdGl2ZSB1c2Vyc2ApO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IGRhdGE7XG4gICAgICAgICAgICB0aGlzLm5vdGlmeSgpO1xuICAgICAgICB9KVxuICAgIH1cblxuICAgIGFzeW5jIGdldEFjdGl2ZVVzZXJzQWpheChhdXRoVG9rZW4yOiBzdHJpbmcpIHtcbiAgICAgICAgbGV0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICAgICAgICAvLyBoZWFkZXJzLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsIGJhc2ljQXV0aFRva2VuKTtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQoJ1gtQVVUSC1UT0tFTicsIGF1dGhUb2tlbjIpO1xuICAgICAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmdldEFjdGl2ZVVzZXJzVXJsLCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5sb2cocmVzcG9uc2UuY2xvbmUoKSk7XG4gICAgICAgIGlmIChmZXRjaEVycm9ySGFuZGxlcihyZXNwb25zZS5jbG9uZSgpKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICBcbiAgICBwcml2YXRlIGhlbHBlck1ldGhvZCgpIHt9XG5cbn0iLCJleHBvcnQgZnVuY3Rpb24gZmV0Y2hFcnJvckhhbmRsZXIocmVzcG9uc2U6IFJlc3BvbnNlKSB7XG4gICAgLy8gYWxlcnRpZnkuc3VjY2VzcygnQ3VycmVudCBwb3NpdGlvbiA6ICcgKyBhbGVydGlmeS5nZXQoJ25vdGlmaWVyJywgJ3Bvc2l0aW9uJykpO1xuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXR1cyB3YXMgbm90IG9rIGFuZCB0aGVyZSBpcyBubyBqc29uIGJvZHlcbiAgICAgICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihyZXNwb25zZS5zdGF0dXNUZXh0KTtcbiAgICAgICAgICAgIC8vIHdpbmRvdy5hbGVydChzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3Ioc3ByaW50ZignU29tZSBlcnJvciBvY2N1cmVkLiBIdHRwIGNvZGUgaXMgJXMnLCByZXNwb25zZS5zdGF0dXMpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KS50aGVuKGpzb24gPT4ge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXR1cyB3YXMgbm90IG9rIGJ1dCB0aGVyZSBpcyBhIGpzb24gYm9keVxuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGpzb24uZXJyb3IubWVzc2FnZSk7IC8vIGV4YW1wbGUgZXJyb3IgbWVzc2FnZSByZXR1cm5lZCBieSBhIFJFU1QgQVBJXG4gICAgICAgICAgICAvLyB3aW5kb3cuYWxlcnQoc3ByaW50ZignRXJyb3I6ICVzIChIdHRwIGNvZGUgJXMpJywganNvbiwgcmVzcG9uc2Uuc3RhdHVzKSk7XG4gICAgICAgICAgICAvLyBhbGVydGlmeS5lcnJvcihzcHJpbnRmKCdTb21lIGVycm9yIG9jY3VyZWQuIEh0dHAgY29kZSBpcyAlcycsIHJlc3BvbnNlLnN0YXR1cykpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coanNvbik7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxufSIsImltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZhYmxlXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuL0Fic3RyYWN0TW9kZWxcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2ZXJcIjtcbmltcG9ydCB7IGZldGNoRXJyb3JIYW5kbGVyIH0gZnJvbSBcIi4vRmV0Y2hFcnJvckhhbmRsZXJcIjtcbmltcG9ydCB7IEFjdGl2ZVVzZXJWaWV3TW9kZWwgfSBmcm9tIFwiLi4vdmlld21vZGVsL0FjdGl2ZVVzZXJWaWV3TW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIFVzZXJNb2RlbCBpbXBsZW1lbnRzIE1vZGVsLCBTdWJqZWN0IHtcbiAgICAvKipcbiAgKiBAdHlwZSB7T2JzZXJ2ZXJbXX0gTGlzdCBvZiBzdWJzY3JpYmVycy4gSW4gcmVhbCBsaWZlLCB0aGUgbGlzdCBvZlxuICAqIHN1YnNjcmliZXJzIGNhbiBiZSBzdG9yZWQgbW9yZSBjb21wcmVoZW5zaXZlbHkgKGNhdGVnb3JpemVkIGJ5IGV2ZW50XG4gICogdHlwZSwgZXRjLikuXG4gICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBvYnNlcnZlcnM6IE9ic2VydmVyW10gPSBbXTtcbiAgICBwcml2YXRlIHN0YXRlOiBBY3RpdmVVc2VyVmlld01vZGVsW10gfCB1bmRlZmluZWQ7XG4gICAgLy8gQHRzLWlnbm9yZTogQ2Fubm90IGZpbmQgbmFtZSAnaG9zdEFkZHJlc3MnLlxuICAgIGdldEFjdGl2ZVVzZXJzVXJsID0gYGA7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHsgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdWJzY3JpcHRpb24gbWFuYWdlbWVudCBtZXRob2RzLlxuICAgICAqL1xuICAgIHB1YmxpYyBhdHRhY2gob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBBdHRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XG4gICAgfVxuXG4gICAgcHVibGljIGRldGFjaChvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXJJbmRleCA9IHRoaXMub2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgICAgICB0aGlzLm9ic2VydmVycy5zcGxpY2Uob2JzZXJ2ZXJJbmRleCwgMSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCdTdWJqZWN0OiBEZXRhY2hlZCBhbiBvYnNlcnZlci4nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIGFuIHVwZGF0ZSBpbiBlYWNoIHN1YnNjcmliZXIuXG4gICAgICovXG4gICAgcHVibGljIG5vdGlmeSgpOiB2b2lkIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1N1YmplY3Q6IE5vdGlmeWluZyBvYnNlcnZlcnMuLi4nKTtcbiAgICAgICAgZm9yIChjb25zdCBvYnNlcnZlciBvZiB0aGlzLm9ic2VydmVycykge1xuICAgICAgICAgICAgb2JzZXJ2ZXIudXBkYXRlKHRoaXMuc3RhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHNvbWVCdXNpbmVzc01ldGhvZChhY3RpdmV1c2VyTGlzdDogQWN0aXZlVXNlclZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBhY3RpdmV1c2VyTGlzdDtcbiAgICAgICAgdGhpcy5oZWxwZXJNZXRob2QoKTtcbiAgICAgICAgY29uc29sZS5sb2coYFN1YmplY3Q6IE15IHN0YXRlIGhhcyBqdXN0IGNoYW5nZWRgKTtcbiAgICAgICAgY29uc29sZS5sb2coYWN0aXZldXNlckxpc3QpO1xuICAgICAgICB0aGlzLm5vdGlmeSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIGdldEFjdGl2ZVVzZXJzXG4gICAgICovXG4gICAgcHVibGljIGdldEFjdGl2ZVVzZXJzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmdldEFjdGl2ZVVzZXJzQWpheChcIjpcIilcbiAgICAgICAgLnRoZW4oZGF0YSA9PiB7XG4gICAgICAgICAgICAvLyAvLyBhY3RpdmVVc2VycyA9IGRhdGE7XG4gICAgICAgICAgICAvLyBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdhY3RpdmVVc2VycycsIEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ2FjdGl2ZVVzZXJzJykpO1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFN1YmplY3Q6IHJlY2VpdmVkIGFqYXggYWN0aXZlIHVzZXJzYCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gZGF0YTtcbiAgICAgICAgICAgIHRoaXMubm90aWZ5KCk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgYXN5bmMgZ2V0QWN0aXZlVXNlcnNBamF4KGF1dGhUb2tlbjI6IHN0cmluZykge1xuICAgICAgICBsZXQgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgICAgIC8vIGhlYWRlcnMuYXBwZW5kKCdBdXRob3JpemF0aW9uJywgYmFzaWNBdXRoVG9rZW4pO1xuICAgICAgICBoZWFkZXJzLmFwcGVuZCgnWC1BVVRILVRPS0VOJywgYXV0aFRva2VuMik7XG4gICAgICAgIGxldCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuZ2V0QWN0aXZlVXNlcnNVcmwsIHtcbiAgICAgICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgICAgICBoZWFkZXJzOiBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zb2xlLmxvZyhyZXNwb25zZS5jbG9uZSgpKTtcbiAgICAgICAgaWYgKGZldGNoRXJyb3JIYW5kbGVyKHJlc3BvbnNlLmNsb25lKCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIFxuICAgIHByaXZhdGUgaGVscGVyTWV0aG9kKCkge31cblxufSIsImltcG9ydCB7IExvZ2dlciB9IGZyb20gXCIuL0xvZ2dlclNlcnZpY2VcIjtcbmltcG9ydCBsb2cgZnJvbSBcImxvZ2xldmVsXCJcblxuZXhwb3J0IGNsYXNzIExvZ0xldmVsTG9nZ2VyIGltcGxlbWVudHMgTG9nZ2Vye1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBsb2cuc2V0TGV2ZWwoXCJERUJVR1wiKTtcbiAgICB9XG4gICAgaW5mbyhtZXNzYWdlOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgbG9nLmluZm8obWVzc2FnZSlcbiAgICB9XG4gICAgd2FybihtZXNzYWdlOiBhbnkpXG4gICAge1xuICAgICAgICBsb2cud2FybihtZXNzYWdlKVxuICAgIH1cbiAgICBlcnJvcihtZXNzYWdlOiBhbnkpXG4gICAge1xuICAgICAgICBsb2cuZXJyb3IobWVzc2FnZSlcbiAgICB9XG4gICAgZGVidWcobWVzc2FnZTogYW55KVxuICAgIHtcbiAgICAgICAgbG9nLmRlYnVnKG1lc3NhZ2UpXG4gICAgfVxufSIsImltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vRW5jcnlwdGlvblNlcnZpY2VcIjtcbmltcG9ydCBzamNsIGZyb20gXCJzamNsXCI7XG5cbmV4cG9ydCBjbGFzcyBTSkNMRW5jcnlwdGlvblNlcnZpY2UgaW1wbGVtZW50cyBFbmNyeXB0aW9uU2VydmljZSB7XG4gICAgcHVibGljIHBhcmFtczogYW55ID0geyBtb2RlOiBcImdjbVwiLCB0czogMTI4LCBhZGF0YTogXCJcIiwgaXRlcjogMTAwMDB9XG4gICAgcHVibGljIGVuY3J5cHQocGFzc3BocmFzZTogc3RyaW5nLCBwbGFpblRleHQ6IHN0cmluZyk6IE9iamVjdCB7XG4gICAgICAgIHJldHVybiBzamNsLmVuY3J5cHQocGFzc3BocmFzZSwgcGxhaW5UZXh0LCB0aGlzLnBhcmFtcyk7XG4gICAgfSBcbiAgICBcbiAgICBwdWJsaWMgZGVjcnlwdChwYXNzcGhyYXNlOiBzdHJpbmcsIGNpcGhlcjogT2JqZWN0KTogT2JqZWN0IHtcbiAgICAgICAgcmV0dXJuIHNqY2wuZGVjcnlwdChwYXNzcGhyYXNlLCBjaXBoZXIgYXMgc2pjbC5TamNsQ2lwaGVyRW5jcnlwdGVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG4gICAgfVxufSIsImV4cG9ydCBuYW1lc3BhY2UgSnNvbkFQSSB7XG4gICAgLy8gQHRzLWlnbm9yZTogQ2Fubm90IGZpbmQgbmFtZSAnaG9zdEFkZHJlc3MnLlxuICAgIGV4cG9ydCBjb25zdCBBY3RpdmVVc2Vyc0dFVCA9IGAvYXBpL2NoYXQvZ2V0L2FjdGl2ZS11c2Vycy9gO1xuICAgIFxufSIsImV4cG9ydCBjbGFzcyBUZW1wbGF0ZUZhY3Rvcnkge1xuICAgIHN0YXRpYyBnZXRUZW1wbGF0ZSgpOiBIYW5kbGViYXJzLlRlbXBsYXRlRGVsZWdhdGU8YW55PiB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG4gICAgICAgIHZhciBzb3VyY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChcInVzZXItY29udGFjdC1vbmxpbmUtdGVtcGxhdGVcIikuaW5uZXJIVE1MOyBcbiAgICAgICAgdmFyIG1zZ0NvbnRhaW5lclRlbXBsYXRlID0gSGFuZGxlYmFycy5jb21waWxlKHNvdXJjZSk7XG4gICAgICAgIHJldHVybiBtc2dDb250YWluZXJUZW1wbGF0ZTtcbiAgICB9XG59IiwiaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZlclwiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWwvQWJzdHJhY3RNb2RlbFwiO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCIuLi9vYnNlcnZlL09ic2VydmFibGVcIjtcbmltcG9ydCB7IFZpZXcgfSBmcm9tIFwiLi9BYnN0cmFjdFZpZXdcIjtcbmltcG9ydCB7IENvbnRyb2xsZXIgfSBmcm9tIFwiLi4vY29udHJvbGxlci9BYnN0cmFjdENvbnRyb2xsZXJcIjtcbmltcG9ydCB7IFRlbXBsYXRlRmFjdG9yeSB9IGZyb20gXCIuLi90ZW1wbGF0ZS9UZW1wbGF0ZUZhY3RvcnlcIjtcbmltcG9ydCB7IEFjdGl2ZVVzZXJWaWV3TW9kZWwgfSBmcm9tIFwiLi4vdmlld21vZGVsL0FjdGl2ZVVzZXJWaWV3TW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIENoYXRWaWV3IGltcGxlbWVudHMgT2JzZXJ2ZXIsIFZpZXcge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX21vZGVsOiBNb2RlbDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9lbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvLyBwcml2YXRlIHVzZXJCb3hlczogYW55W10gPSAgW107XG5cblxuICAgIGNvbnN0cnVjdG9yKG1vZGVsOiBNb2RlbCwgZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5fbW9kZWwgPSBtb2RlbDtcbiAgICAgICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG5cblxuICAgIC8qKlxuICAgICAqIEdldHRlciBtb2RlbFxuICAgICAqIEByZXR1cm4ge01vZGVsfVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgbW9kZWwoKTogTW9kZWwge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kZWw7XG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBHZXR0ZXIgZWxlbWVudFxuICAgICAqIEByZXR1cm4ge2FueX1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgICByZXR1cm4gdGhpcy5fZWxlbWVudDtcbiAgICB9XG5cbiAgICAvLyAvKipcbiAgICAvLyAgKiBTZXR0ZXIgbW9kZWxcbiAgICAvLyAgKiBAcGFyYW0ge01vZGVsfSB2YWx1ZVxuICAgIC8vICAqL1xuICAgIC8vIHB1YmxpYyBzZXQgbW9kZWwodmFsdWU6IE1vZGVsKSB7XG4gICAgLy8gICAgIHRoaXMuX21vZGVsID0gdmFsdWU7XG4gICAgLy8gfVxuXG5cbiAgICAvLyAvKipcbiAgICAvLyAgKiBTZXR0ZXIgZWxlbWVudFxuICAgIC8vICAqIEBwYXJhbSB7YW55fSB2YWx1ZVxuICAgIC8vICAqL1xuICAgIC8vIHB1YmxpYyBzZXQgZWxlbWVudCh2YWx1ZTogYW55KSB7XG4gICAgLy8gICAgIHRoaXMuX2VsZW1lbnQgPSB2YWx1ZTtcbiAgICAvLyB9XG5cblxuXG5cblxuICAgIHVwZGF0ZShkYXRhOiBBY3RpdmVVc2VyVmlld01vZGVsW10pOiB2b2lkIHtcbiAgICAgICAgbGV0IHRlbXBsYXRlID0gVGVtcGxhdGVGYWN0b3J5LmdldFRlbXBsYXRlKCk7XG4gICAgICAgIGxldCBodG1sOiBzdHJpbmcgPSBcIlwiO1xuICAgICAgICBkYXRhLmZvckVhY2goKGVsZW1lbnQ6IEFjdGl2ZVVzZXJWaWV3TW9kZWwpID0+IHtcbiAgICAgICAgICAgIGh0bWwgKz0gdGVtcGxhdGUoZWxlbWVudCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgICAgICAgdGhpcy5hZGRVc2VyQ2FsbEJhY2tzKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMuZWxlbWVudC5pbm5lckhUTUwpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGVscGVyKCk6IHZvaWQge1xuICAgICAgICBcbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZFVzZXJDYWxsQmFja3MoKTogdm9pZCB7XG4gICAgICAgIGxldCB1c2VyQm94ZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd1c2VyLWJveCcpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVzZXJCb3hlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHVzZXJCb3ggPSB1c2VyQm94ZXNbaV07XG4gICAgICAgICAgICB1c2VyQm94ZXNbaV0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLnVzZXJDYWxsQmFjay5iaW5kKHRoaXMsIHVzZXJCb3gpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBcblxuICAgIHByaXZhdGUgdXNlckNhbGxCYWNrKGVsOiBFbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGxldCBjdXJyZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndXNlci1ib3ggYWN0aXZlJyk7XG4gICAgICAgIGxldCBwYXNzcGhyYXNlID0gXCJcIlxuICAgICAgICBpZiAoY3VycmVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBpZiAocGFzc3BocmFzZSA9PSAnJykge1xuICAgICAgICAgICAgICAgIC8vIGFsZXJ0KCdQbGVhc2UgaW5wdXQgcGFzc3BocmFzZScpXG4gICAgICAgICAgICAgICAgLy8gYWxlcnRpZnkuZXJyb3IoJ1BsZWFzZSBlbnRlciBhIHBhc3NwaHJhc2UnKTtcbiAgICAgICAgICAgICAgICAvLyByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50WzBdLmNsYXNzTmFtZSA9IGN1cnJlbnRbMF0uY2xhc3NOYW1lLnJlcGxhY2UoXCIgYWN0aXZlXCIsIFwiXCIpO1xuICAgIFxuICAgICAgICB9XG4gICAgICAgIC8vIEFkZCB0aGUgYWN0aXZlIGNsYXNzIHRvIHRoZSBjdXJyZW50L2NsaWNrZWQgYnV0dG9uXG4gICAgICAgIGVsc2UgaWYgKGN1cnJlbnQubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIGxldCBlbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Bhc3NwaHJhc2UtaW5pdGlhbCcpO1xuICAgICAgICAgICAgcGFzc3BocmFzZSA9IFwiXCI7XG4gICAgICAgICAgICBpZiAocGFzc3BocmFzZSA9PSAnJykge1xuICAgICAgICAgICAgLy8gICAgIC8vIGFsZXJ0KCdQbGVhc2UgaW5wdXQgcGFzc3BocmFzZScpXG4gICAgICAgICAgICAvLyAgICAgLy8gYWxlcnRpZnkuZXJyb3IoJ1BsZWFzZSBlbnRlciBhIHBhc3NwaHJhc2UnKTtcbiAgICAgICAgICAgIC8vICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ25vLXVzZXItc2VsZWN0ZWQnKS5oaWRkZW4gPSB0cnVlO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGF0LWNhcmQnKS5oaWRkZW4gPSBmYWxzZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG4gICAgICAgICAgICBlbGVtLmhpZGRlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd0by11c2VyLXNwYW4nKSk7XG4gICAgICAgIGxldCBlbGVtID0gZWwuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndG8tdXNlci1zcGFuJylbMF0gYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGxldCB1c2VyTmFtZSA9IGVsZW0uaW5uZXJUZXh0O1xuICAgICAgICAvLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXNlci1uYW1lLXNwYW4nKS5pbm5lclRleHQgPSB1c2VyTmFtZTtcbiAgICAgICAgLy8gcG9wdWxhdGVNZXNzYWdlcyh1c2VyTmFtZSwgcGFzc3BocmFzZSk7XG4gICAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ3NlbGVjdGVkVXNlcicsIHVzZXJOYW1lKTtcbiAgICAgICAgZWwuY2xhc3NOYW1lICs9IFwiIGFjdGl2ZVwiO1xuICAgIH1cblxufSIsImltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL29ic2VydmUvT2JzZXJ2ZXJcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4uL21vZGVsL0Fic3RyYWN0TW9kZWxcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwiLi4vb2JzZXJ2ZS9PYnNlcnZhYmxlXCI7XG5pbXBvcnQgeyBWaWV3IH0gZnJvbSBcIi4vQWJzdHJhY3RWaWV3XCI7XG5pbXBvcnQgeyBDb250cm9sbGVyIH0gZnJvbSBcIi4uL2NvbnRyb2xsZXIvQWJzdHJhY3RDb250cm9sbGVyXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZUZhY3RvcnkgfSBmcm9tIFwiLi4vdGVtcGxhdGUvVGVtcGxhdGVGYWN0b3J5XCI7XG5pbXBvcnQgeyBBY3RpdmVVc2VyVmlld01vZGVsIH0gZnJvbSBcIi4uL3ZpZXdtb2RlbC9BY3RpdmVVc2VyVmlld01vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBVc2VyVmlldyBpbXBsZW1lbnRzIE9ic2VydmVyLCBWaWV3IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9tb2RlbDogTW9kZWw7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLy8gcHJpdmF0ZSB1c2VyQm94ZXM6IGFueVtdID0gIFtdO1xuXG5cbiAgICBjb25zdHJ1Y3Rvcihtb2RlbDogTW9kZWwsIGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHRoaXMuX21vZGVsID0gbW9kZWw7XG4gICAgICAgIHRoaXMuX2VsZW1lbnQgPSBlbGVtZW50O1xuICAgIH1cblxuXG5cbiAgICAvKipcbiAgICAgKiBHZXR0ZXIgbW9kZWxcbiAgICAgKiBAcmV0dXJuIHtNb2RlbH1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IG1vZGVsKCk6IE1vZGVsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vZGVsO1xuICAgIH1cblxuXG4gICAgLyoqXG4gICAgICogR2V0dGVyIGVsZW1lbnRcbiAgICAgKiBAcmV0dXJuIHthbnl9XG4gICAgICovXG4gICAgcHVibGljIGdldCBlbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQ7XG4gICAgfVxuXG4gICAgLy8gLyoqXG4gICAgLy8gICogU2V0dGVyIG1vZGVsXG4gICAgLy8gICogQHBhcmFtIHtNb2RlbH0gdmFsdWVcbiAgICAvLyAgKi9cbiAgICAvLyBwdWJsaWMgc2V0IG1vZGVsKHZhbHVlOiBNb2RlbCkge1xuICAgIC8vICAgICB0aGlzLl9tb2RlbCA9IHZhbHVlO1xuICAgIC8vIH1cblxuXG4gICAgLy8gLyoqXG4gICAgLy8gICogU2V0dGVyIGVsZW1lbnRcbiAgICAvLyAgKiBAcGFyYW0ge2FueX0gdmFsdWVcbiAgICAvLyAgKi9cbiAgICAvLyBwdWJsaWMgc2V0IGVsZW1lbnQodmFsdWU6IGFueSkge1xuICAgIC8vICAgICB0aGlzLl9lbGVtZW50ID0gdmFsdWU7XG4gICAgLy8gfVxuXG5cblxuXG5cbiAgICB1cGRhdGUoZGF0YTogQWN0aXZlVXNlclZpZXdNb2RlbFtdKTogdm9pZCB7XG4gICAgICAgIGxldCB0ZW1wbGF0ZSA9IFRlbXBsYXRlRmFjdG9yeS5nZXRUZW1wbGF0ZSgpO1xuICAgICAgICBsZXQgaHRtbDogc3RyaW5nID0gXCJcIjtcbiAgICAgICAgZGF0YS5mb3JFYWNoKChlbGVtZW50OiBBY3RpdmVVc2VyVmlld01vZGVsKSA9PiB7XG4gICAgICAgICAgICBodG1sICs9IHRlbXBsYXRlKGVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gICAgICAgIHRoaXMuYWRkVXNlckNhbGxCYWNrcygpO1xuICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmVsZW1lbnQuaW5uZXJIVE1MKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGhlbHBlcigpOiB2b2lkIHtcbiAgICAgICAgXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGRVc2VyQ2FsbEJhY2tzKCk6IHZvaWQge1xuICAgICAgICBsZXQgdXNlckJveGVzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndXNlci1ib3gnKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1c2VyQm94ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB1c2VyQm94ID0gdXNlckJveGVzW2ldO1xuICAgICAgICAgICAgdXNlckJveGVzW2ldLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy51c2VyQ2FsbEJhY2suYmluZCh0aGlzLCB1c2VyQm94KSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgXG5cbiAgICBwcml2YXRlIHVzZXJDYWxsQmFjayhlbDogRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBsZXQgY3VycmVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3VzZXItYm94IGFjdGl2ZScpO1xuICAgICAgICBsZXQgcGFzc3BocmFzZSA9IFwiXCJcbiAgICAgICAgaWYgKGN1cnJlbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgaWYgKHBhc3NwaHJhc2UgPT0gJycpIHtcbiAgICAgICAgICAgICAgICAvLyBhbGVydCgnUGxlYXNlIGlucHV0IHBhc3NwaHJhc2UnKVxuICAgICAgICAgICAgICAgIC8vIGFsZXJ0aWZ5LmVycm9yKCdQbGVhc2UgZW50ZXIgYSBwYXNzcGhyYXNlJyk7XG4gICAgICAgICAgICAgICAgLy8gcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VycmVudFswXS5jbGFzc05hbWUgPSBjdXJyZW50WzBdLmNsYXNzTmFtZS5yZXBsYWNlKFwiIGFjdGl2ZVwiLCBcIlwiKTtcbiAgICBcbiAgICAgICAgfVxuICAgICAgICAvLyBBZGQgdGhlIGFjdGl2ZSBjbGFzcyB0byB0aGUgY3VycmVudC9jbGlja2VkIGJ1dHRvblxuICAgICAgICBlbHNlIGlmIChjdXJyZW50Lmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICBsZXQgZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdwYXNzcGhyYXNlLWluaXRpYWwnKTtcbiAgICAgICAgICAgIHBhc3NwaHJhc2UgPSBcIlwiO1xuICAgICAgICAgICAgaWYgKHBhc3NwaHJhc2UgPT0gJycpIHtcbiAgICAgICAgICAgIC8vICAgICAvLyBhbGVydCgnUGxlYXNlIGlucHV0IHBhc3NwaHJhc2UnKVxuICAgICAgICAgICAgLy8gICAgIC8vIGFsZXJ0aWZ5LmVycm9yKCdQbGVhc2UgZW50ZXIgYSBwYXNzcGhyYXNlJyk7XG4gICAgICAgICAgICAvLyAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCduby11c2VyLXNlbGVjdGVkJykuaGlkZGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmU6IE9iamVjdCBpcyBwb3NzaWJseSAnbnVsbCcuXG4gICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hhdC1jYXJkJykuaGlkZGVuID0gZmFsc2U7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlOiBPYmplY3QgaXMgcG9zc2libHkgJ251bGwnLlxuICAgICAgICAgICAgZWxlbS5oaWRkZW4gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndG8tdXNlci1zcGFuJykpO1xuICAgICAgICBsZXQgZWxlbSA9IGVsLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ3RvLXVzZXItc3BhbicpWzBdIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBsZXQgdXNlck5hbWUgPSBlbGVtLmlubmVyVGV4dDtcbiAgICAgICAgLy8gQHRzLWlnbm9yZTogT2JqZWN0IGlzIHBvc3NpYmx5ICdudWxsJy5cbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VzZXItbmFtZS1zcGFuJykuaW5uZXJUZXh0ID0gdXNlck5hbWU7XG4gICAgICAgIC8vIHBvcHVsYXRlTWVzc2FnZXModXNlck5hbWUsIHBhc3NwaHJhc2UpO1xuICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdzZWxlY3RlZFVzZXInLCB1c2VyTmFtZSk7XG4gICAgICAgIGVsLmNsYXNzTmFtZSArPSBcIiBhY3RpdmVcIjtcbiAgICB9XG5cbn0iLCJleHBvcnQgY2xhc3MgQWN0aXZlVXNlclZpZXdNb2RlbCB7XG4gICAgdXNlck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBvbmxpbmU6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICAgbGFzdEFjdGl2ZTogc3RyaW5nfCB1bmRlZmluZWQ7XG59IiwiZXhwb3J0IGNsYXNzIENoYXRNZXNzYWdlVmlld01vZGVsIHtcbiAgICBwdWJsaWMgdG9Vc2VyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgcHVibGljIGZyb21Vc2VyOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgcHVibGljIG1lc3NhZ2VDaXBoZXI6IGFueTtcbiAgICBwdWJsaWMgbWVzc2FnZVRpbWUhOiBEYXRlO1xuXG4gICAgXG59Il19