(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 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