com.phloxui
Version:
PhloxUI Ng2+ Framework
513 lines (512 loc) • 57 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { Injectable } from '@angular/core';
import { Http, RequestOptions } from '@angular/http';
import { CONNECTION_DATA } from '../share/IConnectionManager';
import { BackgroundProcessManager } from './BackgroundProcessManager.service';
import { ConnectionManager } from './ConnectionManager.service';
import { DefaultConnectionManager } from '../share/DefaultConnectionManager';
const /** @type {?} */ RUNNING = 'RUNNING';
const /** @type {?} */ BASE_URL = 'http://10.10.2.22/api';
/**
* <p style="text-indent: 2em;">
* A <code>ng</code> service class implementing [[InstanceConnectionManager]] service interface. Please see [[InstanceConnectionManager]] for more details.
* </p>
*
* @author shiorin, tee4cute
*/
export class InstanceConnectionManager {
/**
* @param {?} connectionManager
* @param {?} http
* @param {?} bgProcessMgr
*/
constructor(connectionManager, http, bgProcessMgr) {
this.seletedInstanceId = "";
this.http = http;
this.bgProcessMgr = bgProcessMgr;
this.connectionManager = connectionManager;
this.instanceConnectionManagerMap = {};
}
/**
* @param {?} instanceUUID
* @return {?}
*/
getNodes(instanceUUID) {
if (this.connectionManager !== null && typeof this.connectionManager !== 'undefined') {
let /** @type {?} */ url = BASE_URL + "/instance/" + instanceUUID + "/node";
let /** @type {?} */ requestOptionsArgs = new RequestOptions();
return this.connectionManager.getWithHttpInfo(url, requestOptionsArgs);
}
else {
return Promise.reject(null);
}
}
/**
* @param {?} instanceUUID
* @param {?=} loginData
* @return {?}
*/
setUpInstance(instanceUUID, loginData) {
return new Promise((resolve, reject) => {
this.getNodes(instanceUUID).then((res) => {
let /** @type {?} */ itemNodes = JSON.parse(res._body).items;
let /** @type {?} */ runnintMode = false;
for (let /** @type {?} */ itemNode of itemNodes) {
if (itemNode.status === RUNNING) {
runnintMode = true;
let /** @type {?} */ conMgr = new DefaultConnectionManager(null, this.http, this.bgProcessMgr);
conMgr.setName(itemNode._uuid);
//Set for test.
let /** @type {?} */ url = itemNode.serverNode.hostName == "localhost" ? "http://10.10.2.22" : itemNode.serverNode.hostName;
url += ":" + itemNode.servicePort + "/api";
conMgr.addBaseURLs(url);
if (loginData !== undefined) {
url += "/user/login";
this.connectionManager.postWithHttpInfo(url, loginData, new RequestOptions()).then((res) => {
let /** @type {?} */ sessionId = JSON.parse((/** @type {?} */ (res))._body).sessionId;
conMgr.setDefaultHeader('Session-Id', sessionId);
this.instanceConnectionManagerMap[instanceUUID] = conMgr;
resolve(itemNodes);
}).catch((error) => {
this.instanceConnectionManagerMap[instanceUUID] = conMgr;
reject(error);
});
}
else {
this.instanceConnectionManagerMap[instanceUUID] = conMgr;
}
}
}
if (loginData === undefined) {
if (runnintMode) {
resolve(itemNodes);
}
reject(itemNodes);
}
}).catch((error) => {
reject(error);
});
});
}
/**
* @param {?} instanced
* @return {?}
*/
setUpInstances(instanced) {
if (instanced === undefined || instanced === null) {
return Promise.resolve([]);
}
let /** @type {?} */ proms = [];
for (let /** @type {?} */ instanceUUID in instanced) {
if (instanceUUID === null || instanceUUID === undefined) {
continue;
}
proms.push(this.setUpInstance(instanceUUID, instanced[instanceUUID]));
}
return Promise.all(proms);
}
/**
* @param {?} instanceUUID
* @return {?}
*/
tearDownInstance(instanceUUID) {
delete this.instanceConnectionManagerMap[instanceUUID];
}
/**
* @return {?}
*/
getInstanceConnectionManager() {
if (this.seletedInstanceId === undefined || this.seletedInstanceId === null) {
return null;
}
return this.instanceConnectionManagerMap[this.seletedInstanceId];
}
/**
* @param {?} instanceUUID
* @return {?}
*/
selectInstance(instanceUUID) {
this.seletedInstanceId = instanceUUID;
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
get(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().get(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
getWithHttpInfo(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().getWithHttpInfo(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} body
* @param {?} requestOptionsArgs
* @return {?}
*/
post(url, body, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().post(url, body, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} body
* @param {?} requestOptionsArgs
* @return {?}
*/
postWithHttpInfo(url, body, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().postWithHttpInfo(url, body, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} body
* @param {?} requestOptionsArgs
* @return {?}
*/
put(url, body, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().put(url, body, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} body
* @param {?} requestOptionsArgs
* @return {?}
*/
putWithHttpInfo(url, body, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().putWithHttpInfo(url, body, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
delete(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().delete(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
deleteWithHttpInfo(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().deleteWithHttpInfo(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} body
* @param {?} requestOptionsArgs
* @return {?}
*/
patch(url, body, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().patch(url, body, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} body
* @param {?} requestOptionsArgs
* @return {?}
*/
patchWithHttpInfo(url, body, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().patchWithHttpInfo(url, body, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
head(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().head(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
headWithHttpInfo(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().headWithHttpInfo(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
options(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().options(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
optionsWithHttpInfo(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().optionsWithHttpInfo(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
request(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().request(url, requestOptionsArgs);
}
/**
* @param {?} url
* @param {?} requestOptionsArgs
* @return {?}
*/
requestWithHttpInfo(url, requestOptionsArgs) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
return Promise.reject('Connection Manager is not setup yes.');
}
return this.getInstanceConnectionManager().requestWithHttpInfo(url, requestOptionsArgs);
}
/**
* @return {?}
*/
getRunningProcessesCount() {
if (this.seletedInstanceId === null || this.seletedInstanceId === undefined) {
return null;
}
if (this.bgProcessMgr != null && typeof this.bgProcessMgr !== 'undefined') {
this.bgProcessMgr.getRunningProcessesCount(CONNECTION_DATA, this.seletedInstanceId);
}
return 0;
}
/**
* @return {?}
*/
getRunningProcesses() {
if (this.seletedInstanceId === null || this.seletedInstanceId === undefined) {
return null;
}
if (this.bgProcessMgr != null && typeof this.bgProcessMgr !== 'undefined') {
this.bgProcessMgr.getRunningProcesses(CONNECTION_DATA, this.seletedInstanceId);
}
return [];
}
/**
* @return {?}
*/
getConnectionQuality() {
// TODO
return this.connectionManager.getConnectionQuality();
}
/**
* @param {?} urls
* @return {?}
*/
setBaseURLs(urls) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().setBaseURLs(urls);
}
/**
* @return {?}
*/
resetBaseURLs() {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().resetBaseURLs();
}
/**
* @param {?} key
* @param {?} value
* @return {?}
*/
setDefaultHeader(key, value) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().setDefaultHeader(key, value);
}
/**
* @param {?} key
* @return {?}
*/
removeDefaultHeader(key) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().removeDefaultHeader(key);
}
/**
* @return {?}
*/
resetDefaultHeaders() {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().resetDefaultHeaders();
}
/**
* @param {?} key
* @param {?} value
* @return {?}
*/
setSearch(key, value) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().setSearch(key, value);
}
/**
* @param {?} key
* @return {?}
*/
removeSearch(key) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().removeSearch(key);
}
/**
* @return {?}
*/
resetSearch() {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().resetSearch();
}
/**
* @param {?} key
* @param {?} value
* @return {?}
*/
setParam(key, value) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().setParam(key, value);
}
/**
* @param {?} key
* @return {?}
*/
removeParam(key) {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().removeParam(key);
}
/**
* @return {?}
*/
resetParams() {
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().resetParams();
}
/**
* @return {?}
*/
getName() {
return this.name;
}
/**
* @param {?} name
* @return {?}
*/
setName(name) {
this.name = name;
if (this.getInstanceConnectionManager() === null || this.getInstanceConnectionManager() === undefined) {
throw ('Connection Manager is not setup yes.');
}
this.getInstanceConnectionManager().setName(name);
}
/**
* @template R
* @param {?} type
* @return {?}
*/
createResource(type) {
return this.getInstanceConnectionManager().createResource(type);
}
}
InstanceConnectionManager.decorators = [
{ type: Injectable },
];
/** @nocollapse */
InstanceConnectionManager.ctorParameters = () => [
{ type: ConnectionManager, },
{ type: Http, },
{ type: BackgroundProcessManager, },
];
function InstanceConnectionManager_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
InstanceConnectionManager.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
InstanceConnectionManager.ctorParameters;
/** @type {?} */
InstanceConnectionManager.prototype.instanceConnectionManagerMap;
/** @type {?} */
InstanceConnectionManager.prototype.connectionManager;
/** @type {?} */
InstanceConnectionManager.prototype.http;
/** @type {?} */
InstanceConnectionManager.prototype.bgProcessMgr;
/** @type {?} */
InstanceConnectionManager.prototype.seletedInstanceId;
/** @type {?} */
InstanceConnectionManager.prototype.name;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlci5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vY29tLnBobG94dWkvIiwic291cmNlcyI6WyJsaWIvc2VydmljZS9JbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLElBQUksRUFBWSxjQUFjLEVBQStCLE1BQU0sZUFBZSxDQUFDO0FBQzVGLE9BQU8sRUFBc0IsZUFBZSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDbEYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDOUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFaEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFN0UsdUJBQU0sT0FBTyxHQUFXLFNBQVMsQ0FBQztBQUNsQyx1QkFBTSxRQUFRLEdBQVcsdUJBQXVCLENBQUM7Ozs7Ozs7O0FBV2pELE1BQU07Ozs7OztJQVNGLFlBQVksaUJBQW9DLEVBQUUsSUFBVSxFQUFFLFlBQXNDO1FBRWhHLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFDakMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDO1FBQzNDLElBQUksQ0FBQyw0QkFBNEIsR0FBRyxFQUFFLENBQUM7S0FFMUM7Ozs7O0lBRU8sUUFBUSxDQUFDLFlBQW9CO1FBQ2pDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsS0FBSyxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsaUJBQWlCLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZ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QUFDLDRCQUE0QixFQUFFLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsTUFBTSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7U0FDbEQ7UUFDRCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7Ozs7SUFHMUQsbUJBQW1CO1FBQ3RCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3BHLE1BQU0sQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQ2xEO1FBQ0QsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUMsbUJBQW1CLEVBQUUsQ0FBQzs7Ozs7OztJQUd2RCxTQUFTLENBQUMsR0FBVyxFQUFFLEtBQVU7UUFDcEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLDRCQUE0QixFQUFFLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsTUFBTSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7U0FDbEQ7UUFDRCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDOzs7Ozs7SUFHdkQsWUFBWSxDQUFDLEdBQVc7UUFDM0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLDRCQUE0QixFQUFFLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsTUFBTSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7U0FDbEQ7UUFDRCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7Ozs7O0lBR25ELFdBQVc7UUFDZCxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLDRCQUE0QixFQUFFLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNwRyxNQUFNLENBQUMsc0NBQXNDLENBQUMsQ0FBQztTQUNsRDtRQUNELElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDOzs7Ozs7O0lBRy9DLFFBQVEsQ0FBQyxHQUFXLEVBQUUsS0FBVTtRQUNuQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLDRCQUE0QixFQUFFLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNwRyxNQUFNLENBQUMsc0NBQXNDLENBQUMsQ0FBQztTQUNsRDtRQUNELElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7Ozs7OztJQUd0RCxXQUFXLENBQUMsR0FBVztRQUMxQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLDRCQUE0QixFQUFFLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNwRyxNQUFNLENBQUMsc0NBQXNDLENBQUMsQ0FBQztTQUNsRDtRQUNELElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQzs7Ozs7SUFHbEQsV0FBVztRQUNkLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3BHLE1BQU0sQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQ2xEO1FBQ0QsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7Ozs7O0lBRy9DLE9BQU87UUFDVixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzs7Ozs7O0lBR2QsT0FBTyxDQUFDLElBQVk7UUFDdkIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLDRCQUE0QixFQUFFLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDcEcsTUFBTSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7U0FDbEQ7UUFDRCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7Ozs7Ozs7SUFHL0MsY0FBYyxDQUFtQyxJQUEyQztRQUNqRyxNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixFQUFFLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDOzs7O1lBbFdyRSxVQUFVOzs7O1lBZkYsaUJBQWlCO1lBSGpCLElBQUk7WUFFSix3QkFBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwLCBSZXNwb25zZSwgUmVxdWVzdE9wdGlvbnMsIFJlcXVlc3RPcHRpb25zQXJncywgSGVhZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2h0dHAnO1xuaW1wb3J0IHsgSUNvbm5lY3Rpb25NYW5hZ2VyLCBDT05ORUNUSU9OX0RBVEEgfSBmcm9tICcuLi9zaGFyZS9JQ29ubmVjdGlvbk1hbmFnZXInO1xuaW1wb3J0IHsgQmFja2dyb3VuZFByb2Nlc3NNYW5hZ2VyIH0gZnJvbSAnLi9CYWNrZ3JvdW5kUHJvY2Vzc01hbmFnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBDb25uZWN0aW9uTWFuYWdlciB9IGZyb20gJy4vQ29ubmVjdGlvbk1hbmFnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBBYnN0cmFjdFNlcnZlclJlc291cmNlIH0gZnJvbSAnLi4vc2hhcmUvQWJzdHJhY3RTZXJ2ZXJSZXNvdXJjZSc7XG5pbXBvcnQgeyBEZWZhdWx0Q29ubmVjdGlvbk1hbmFnZXIgfSBmcm9tICcuLi9zaGFyZS9EZWZhdWx0Q29ubmVjdGlvbk1hbmFnZXInO1xuXG5jb25zdCBSVU5OSU5HOiBzdHJpbmcgPSAnUlVOTklORyc7XG5jb25zdCBCQVNFX1VSTDogc3RyaW5nID0gJ2h0dHA6Ly8xMC4xMC4yLjIyL2FwaSc7XG5cblxuLyoqXG4gKiA8cCBzdHlsZT1cInRleHQtaW5kZW50OiAyZW07XCI+XG4gKiBBIDxjb2RlPm5nPC9jb2RlPiBzZXJ2aWNlIGNsYXNzIGltcGxlbWVudGluZyBbW0luc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJdXSBzZXJ2aWNlIGludGVyZmFjZS4gUGxlYXNlIHNlZSBbW0luc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJdXSBmb3IgbW9yZSBkZXRhaWxzLlxuICogPC9wPlxuICpcbiAqIEBhdXRob3Igc2hpb3JpbiwgdGVlNGN1dGVcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIgaW1wbGVtZW50cyBJQ29ubmVjdGlvbk1hbmFnZXIge1xuXG4gICAgcHJpdmF0ZSBpbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyTWFwOiBhbnk7XG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uTWFuYWdlcjogQ29ubmVjdGlvbk1hbmFnZXI7XG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwO1xuICAgIHByaXZhdGUgYmdQcm9jZXNzTWdyOiBCYWNrZ3JvdW5kUHJvY2Vzc01hbmFnZXI7XG4gICAgcHJpdmF0ZSBzZWxldGVkSW5zdGFuY2VJZDogc3RyaW5nO1xuICAgIHByaXZhdGUgbmFtZTogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IoY29ubmVjdGlvbk1hbmFnZXI6IENvbm5lY3Rpb25NYW5hZ2VyLCBodHRwOiBIdHRwLCBiZ1Byb2Nlc3NNZ3I6IEJhY2tncm91bmRQcm9jZXNzTWFuYWdlcikge1xuXG4gICAgICAgIHRoaXMuc2VsZXRlZEluc3RhbmNlSWQgPSBcIlwiO1xuICAgICAgICB0aGlzLmh0dHAgPSBodHRwO1xuICAgICAgICB0aGlzLmJnUHJvY2Vzc01nciA9IGJnUHJvY2Vzc01ncjtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uTWFuYWdlciA9IGNvbm5lY3Rpb25NYW5hZ2VyO1xuICAgICAgICB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXAgPSB7fTtcblxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Tm9kZXMoaW5zdGFuY2VVVUlEOiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uTWFuYWdlciAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5jb25uZWN0aW9uTWFuYWdlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGxldCB1cmw6IGFueSA9IEJBU0VfVVJMICsgXCIvaW5zdGFuY2UvXCIgKyBpbnN0YW5jZVVVSUQgKyBcIi9ub2RlXCI7XG5cbiAgICAgICAgICAgIGxldCByZXF1ZXN0T3B0aW9uc0FyZ3MgPSBuZXcgUmVxdWVzdE9wdGlvbnMoKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbk1hbmFnZXIuZ2V0V2l0aEh0dHBJbmZvKHVybCwgcmVxdWVzdE9wdGlvbnNBcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChudWxsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXRVcEluc3RhbmNlKGluc3RhbmNlVVVJRDogc3RyaW5nLCBsb2dpbkRhdGE/OiBhbnkpOiBQcm9taXNlPGFueT4ge1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldE5vZGVzKGluc3RhbmNlVVVJRCkudGhlbigocmVzKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGl0ZW1Ob2RlcyA9IEpTT04ucGFyc2UocmVzLl9ib2R5KS5pdGVtcztcblxuICAgICAgICAgICAgICAgIGxldCBydW5uaW50TW9kZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGl0ZW1Ob2RlIG9mIGl0ZW1Ob2Rlcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXRlbU5vZGUuc3RhdHVzID09PSBSVU5OSU5HKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5pbnRNb2RlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb25NZ3IgPSBuZXcgRGVmYXVsdENvbm5lY3Rpb25NYW5hZ2VyKG51bGwsIHRoaXMuaHR0cCwgdGhpcy5iZ1Byb2Nlc3NNZ3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uTWdyLnNldE5hbWUoaXRlbU5vZGUuX3V1aWQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvL1NldCBmb3IgdGVzdC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB1cmw6IHN0cmluZyA9IGl0ZW1Ob2RlLnNlcnZlck5vZGUuaG9zdE5hbWUgPT0gXCJsb2NhbGhvc3RcIiA/IFwiaHR0cDovLzEwLjEwLjIuMjJcIiA6IGl0ZW1Ob2RlLnNlcnZlck5vZGUuaG9zdE5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmwgKz0gXCI6XCIgKyBpdGVtTm9kZS5zZXJ2aWNlUG9ydCArIFwiL2FwaVwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uTWdyLmFkZEJhc2VVUkxzKHVybCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2dpbkRhdGEgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdXJsICs9IFwiL3VzZXIvbG9naW5cIjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25NYW5hZ2VyLnBvc3RXaXRoSHR0cEluZm8odXJsLCBsb2dpbkRhdGEsIG5ldyBSZXF1ZXN0T3B0aW9ucygpKS50aGVuKChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHNlc3Npb25JZCA9IEpTT04ucGFyc2UoKHJlcyBhcyBhbnkpLl9ib2R5KS5zZXNzaW9uSWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbk1nci5zZXREZWZhdWx0SGVhZGVyKCdTZXNzaW9uLUlkJywgc2Vzc2lvbklkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyTWFwW2luc3RhbmNlVVVJRF0gPSBjb25NZ3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoaXRlbU5vZGVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyTWFwW2luc3RhbmNlVVVJRF0gPSBjb25NZ3I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlck1hcFtpbnN0YW5jZVVVSURdID0gY29uTWdyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGxvZ2luRGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChydW5uaW50TW9kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShpdGVtTm9kZXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGl0ZW1Ob2Rlcyk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9KS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfVxuXG4gICAgcHVibGljIHNldFVwSW5zdGFuY2VzKGluc3RhbmNlZDogYW55KTogUHJvbWlzZTxhbnlbXT4ge1xuXG4gICAgICAgIGlmIChpbnN0YW5jZWQgPT09IHVuZGVmaW5lZCB8fCBpbnN0YW5jZWQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoW10pO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHByb21zOiBQcm9taXNlPGFueT5bXSA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGluc3RhbmNlVVVJRCBpbiBpbnN0YW5jZWQpIHtcbiAgICAgICAgICAgIGlmIChpbnN0YW5jZVVVSUQgPT09IG51bGwgfHwgaW5zdGFuY2VVVUlEID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHJvbXMucHVzaCh0aGlzLnNldFVwSW5zdGFuY2UoaW5zdGFuY2VVVUlELCBpbnN0YW5jZWRbaW5zdGFuY2VVVUlEXSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21zKTtcblxuICAgIH1cblxuICAgIHB1YmxpYyB0ZWFyRG93bkluc3RhbmNlKGluc3RhbmNlVVVJRDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXJNYXBbaW5zdGFuY2VVVUlEXTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpOiBDb25uZWN0aW9uTWFuYWdlciB7XG4gICAgICAgIGlmICh0aGlzLnNlbGV0ZWRJbnN0YW5jZUlkID09PSB1bmRlZmluZWQgfHwgdGhpcy5zZWxldGVkSW5zdGFuY2VJZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5pbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyTWFwW3RoaXMuc2VsZXRlZEluc3RhbmNlSWRdO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZWxlY3RJbnN0YW5jZShpbnN0YW5jZVVVSUQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLnNlbGV0ZWRJbnN0YW5jZUlkID0gaW5zdGFuY2VVVUlEO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQodXJsOiBzdHJpbmcsIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLmdldCh1cmwsIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5nZXRXaXRoSHR0cEluZm8odXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwb3N0KHVybDogc3RyaW5nLCBib2R5OiBhbnksIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLnBvc3QodXJsLCBib2R5LCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwb3N0V2l0aEh0dHBJbmZvKHVybDogc3RyaW5nLCBib2R5OiBhbnksIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHllcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkucG9zdFdpdGhIdHRwSW5mbyh1cmwsIGJvZHksIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIHB1dCh1cmw6IHN0cmluZywgYm9keTogYW55LCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5wdXQodXJsLCBib2R5LCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwdXRXaXRoSHR0cEluZm8odXJsOiBzdHJpbmcsIGJvZHk6IGFueSwgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5wdXRXaXRoSHR0cEluZm8odXJsLCBib2R5LCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWxldGUodXJsOiBzdHJpbmcsIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLmRlbGV0ZSh1cmwsIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZVdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5kZWxldGVXaXRoSHR0cEluZm8odXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwYXRjaCh1cmw6IHN0cmluZywgYm9keTogYW55LCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5wYXRjaCh1cmwsIGJvZHksIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIHBhdGNoV2l0aEh0dHBJbmZvKHVybDogc3RyaW5nLCBib2R5OiBhbnksIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHllcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkucGF0Y2hXaXRoSHR0cEluZm8odXJsLCBib2R5LCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyBoZWFkKHVybDogc3RyaW5nLCByZXF1ZXN0T3B0aW9uc0FyZ3M6IFJlcXVlc3RPcHRpb25zQXJncyk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5oZWFkKHVybCwgcmVxdWVzdE9wdGlvbnNBcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGVhZFdpdGhIdHRwSW5mbyh1cmw6IHN0cmluZywgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG4gICAgICAgIGlmICh0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gbnVsbCB8fCB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ0Nvbm5lY3Rpb24gTWFuYWdlciBpcyBub3Qgc2V0dXAgeWVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlQ29ubmVjdGlvbk1hbmFnZXIoKS5oZWFkV2l0aEh0dHBJbmZvKHVybCwgcmVxdWVzdE9wdGlvbnNBcmdzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb3B0aW9ucyh1cmw6IHN0cmluZywgcmVxdWVzdE9wdGlvbnNBcmdzOiBSZXF1ZXN0T3B0aW9uc0FyZ3MpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHllcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkub3B0aW9ucyh1cmwsIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIG9wdGlvbnNXaXRoSHR0cEluZm8odXJsOiBzdHJpbmcsIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICAgICAgICBpZiAodGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IG51bGwgfHwgdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdDb25uZWN0aW9uIE1hbmFnZXIgaXMgbm90IHNldHVwIHllcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRJbnN0YW5jZUNvbm5lY3Rpb25NYW5hZ2VyKCkub3B0aW9uc1dpdGhIdHRwSW5mbyh1cmwsIHJlcXVlc3RPcHRpb25zQXJncyk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlcXVlc3QodXJsOiBzdHJpbmcsIHJlcXVlc3RPcHRpb25zQXJnczogUmVxdWVzdE9wdGlvbnNBcmdzKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSBudWxsIHx8IHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnQ29ubmVjdGlvbiBNYW5hZ2VyIGlzIG5vdCBzZXR1cCB5ZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2VDb25uZWN0aW9uTWFuYWdlcigpLnJlcXVlc3QodXJsLCByZXF1ZXN0T3B0aW9uc0FyZ3MpO1xuICAgIH1cblxuICAgIHB1YmxpYyByZXF1ZXN0V2l0aEh0dHBJbmZvKHVybDogc3RyaW5nLCByZXF