@kubectl/caminojs
Version:
Camino Platform JS Library
345 lines • 41.4 kB
JavaScript
;
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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @packageDocumentation
* @module AvalancheCore
*/
const axios_1 = __importDefault(require("axios"));
const apibase_1 = require("./common/apibase");
const errors_1 = require("./utils/errors");
const fetchadapter_1 = require("./utils/fetchadapter");
/**
* AvalancheCore is middleware for interacting with Avalanche node RPC APIs.
*
* Example usage:
* ```js
* let avalanche = new AvalancheCore("127.0.0.1", 9650, "https")
* ```
*
*
*/
class AvalancheCore {
/**
* Creates a new Avalanche instance. Sets the address and port of the main Avalanche Client.
*
* @param host The hostname to resolve to reach the Avalanche Client APIs
* @param port The port to resolve to reach the Avalanche Client APIs
* @param protocol The protocol string to use before a "://" in a request, ex: "http", "https", "git", "ws", etc ...
* @param networkID The networkID of the network URL belongs to
*/
constructor(host, port, protocol, networkID) {
this.networkID = 0;
this.auth = undefined;
this.headers = {};
this.requestConfig = {};
this.apis = {};
this.network = undefined;
/**
* Sets the address and port of the main Avalanche Client.
*
* @param host The hostname to resolve to reach the Avalanche Client RPC APIs.
* @param port The port to resolve to reach the Avalanche Client RPC APIs.
* @param protocol The protocol string to use before a "://" in a request,
* ex: "http", "https", etc. Defaults to http
* @param baseEndpoint the base endpoint to reach the Avalanche Client RPC APIs,
* ex: "/rpc". Defaults to "/"
* The following special characters are removed from host and protocol
* &#,@+()$~%'":*?{} also less than and greater than signs
*/
this.setNetwork = (host, port, protocol, networkID, baseEndpoint = "") => {
host = host.replace(/[&#,@+()$~%'":*?<>{}]/g, "");
protocol = protocol.replace(/[&#,@+()$~%'":*?<>{}]/g, "");
const protocols = ["http", "https"];
if (!protocols.includes(protocol)) {
/* istanbul ignore next */
throw new errors_1.ProtocolError("Error - AvalancheCore.setAddress: Invalid protocol");
}
// Reset network specific
if (this.networkID !== networkID ||
this.host !== host ||
this.port !== port) {
this.network = undefined;
}
this.host = host;
this.port = port;
this.protocol = protocol;
this.baseEndpoint = baseEndpoint;
let url = `${protocol}://${host}`;
if (port !== undefined && typeof port === "number" && port >= 0) {
url = `${url}:${port}`;
}
if (baseEndpoint != undefined &&
typeof baseEndpoint == "string" &&
baseEndpoint.length > 0) {
if (baseEndpoint[0] != "/") {
baseEndpoint = `/${baseEndpoint}`;
}
url = `${url}${baseEndpoint}`;
}
this.url = url;
this.networkID = networkID;
};
/**
* Returns the network configuration.
*/
this.getNetwork = () => this.network;
/**
* Returns the protocol such as "http", "https", "git", "ws", etc.
*/
this.getProtocol = () => this.protocol;
/**
* Returns the host for the Avalanche node.
*/
this.getHost = () => this.host;
/**
* Returns the IP for the Avalanche node.
*/
this.getIP = () => this.host;
/**
* Returns the port for the Avalanche node.
*/
this.getPort = () => this.port;
/**
* Returns the base endpoint for the Avalanche node.
*/
this.getBaseEndpoint = () => this.baseEndpoint;
/**
* Returns the URL of the Avalanche node (ip + port)
*/
this.getURL = () => this.url;
/**
* Returns the custom headers
*/
this.getHeaders = () => this.headers;
/**
* Returns the custom request config
*/
this.getRequestConfig = () => this.requestConfig;
/**
* Returns the networkID
*/
this.getNetworkID = () => this.networkID;
/**
* Returns the Human-Readable-Part of the network associated with this key.
*
* @returns The [[KeyPair]]'s Human-Readable-Part of the network's Bech32 addressing scheme
*/
this.getHRP = () => this.network.hrp;
/**
* Adds a new custom header to be included with all requests.
*
* @param key Header name
* @param value Header value
*/
this.setHeader = (key, value) => {
this.headers[`${key}`] = value;
};
/**
* Removes a previously added custom header.
*
* @param key Header name
*/
this.removeHeader = (key) => {
delete this.headers[`${key}`];
};
/**
* Removes all headers.
*/
this.removeAllHeaders = () => {
for (const prop in this.headers) {
if (Object.prototype.hasOwnProperty.call(this.headers, prop)) {
delete this.headers[`${prop}`];
}
}
};
/**
* Adds a new custom config value to be included with all requests.
*
* @param key Config name
* @param value Config value
*/
this.setRequestConfig = (key, value) => {
this.requestConfig[`${key}`] = value;
};
/**
* Removes a previously added request config.
*
* @param key Header name
*/
this.removeRequestConfig = (key) => {
delete this.requestConfig[`${key}`];
};
/**
* Removes all request configs.
*/
this.removeAllRequestConfigs = () => {
for (const prop in this.requestConfig) {
if (Object.prototype.hasOwnProperty.call(this.requestConfig, prop)) {
delete this.requestConfig[`${prop}`];
}
}
};
/**
* Sets the temporary auth token used for communicating with the node.
*
* @param auth A temporary token provided by the node enabling access to the endpoints on the node.
*/
this.setAuthToken = (auth) => {
this.auth = auth;
};
this._setHeaders = (headers) => {
if (typeof this.headers === "object") {
for (const [key, value] of Object.entries(this.headers)) {
headers[`${key}`] = value;
}
}
if (typeof this.auth === "string") {
headers.Authorization = `Bearer ${this.auth}`;
}
return headers;
};
/**
* Returns the primary asset alias.
*/
this.getPrimaryAssetAlias = () => {
return this.network.X.avaxAssetAlias;
};
/**
* Adds an API to the middleware. The API resolves to a registered blockchain's RPC.
*
* In TypeScript:
* ```js
* avalanche.addAPI<MyVMClass>("mychain", MyVMClass, "/ext/bc/mychain")
* ```
*
* In Javascript:
* ```js
* avalanche.addAPI("mychain", MyVMClass, "/ext/bc/mychain")
* ```
*
* @typeparam GA Class of the API being added
* @param apiName A label for referencing the API in the future
* @param ConstructorFN A reference to the class which instantiates the API
* @param baseurl Path to resolve to reach the API
*
*/
this.addAPI = (apiName, ConstructorFN, baseurl = undefined, ...args) => {
if (typeof baseurl === "undefined") {
this.apis[`${apiName}`] = new ConstructorFN(this, undefined, ...args);
}
else {
this.apis[`${apiName}`] = new ConstructorFN(this, baseurl, ...args);
}
};
/**
* Retrieves a reference to an API by its apiName label.
*
* @param apiName Name of the API to return
*/
this.api = (apiName) => this.apis[`${apiName}`];
/**
* @ignore
*/
this._request = (xhrmethod, baseurl, getdata, postdata, headers = {}, axiosConfig = undefined) => __awaiter(this, void 0, void 0, function* () {
let config;
if (axiosConfig) {
config = Object.assign(Object.assign({}, axiosConfig), this.requestConfig);
}
else {
config = Object.assign({ baseURL: this.url, responseType: "text" }, this.requestConfig);
}
config.url = baseurl;
config.method = xhrmethod;
config.headers = headers;
config.data = postdata;
config.params = getdata;
// use the fetch adapter if fetch is available e.g. non Node<17 env
if (typeof fetch !== "undefined") {
config.adapter = fetchadapter_1.fetchAdapter;
}
const resp = yield axios_1.default.request(config);
// purging all that is axios
const xhrdata = new apibase_1.RequestResponseData(resp.data, resp.headers, resp.status, resp.statusText, resp.request);
return xhrdata;
});
/**
* Makes a GET call to an API.
*
* @param baseurl Path to the api
* @param getdata Object containing the key value pairs sent in GET
* @param headers An array HTTP Request Headers
* @param axiosConfig Configuration for the axios javascript library that will be the
* foundation for the rest of the parameters
*
* @returns A promise for [[RequestResponseData]]
*/
this.get = (baseurl, getdata, headers = {}, axiosConfig = undefined) => this._request("GET", baseurl, getdata, {}, this._setHeaders(headers), axiosConfig);
/**
* Makes a DELETE call to an API.
*
* @param baseurl Path to the API
* @param getdata Object containing the key value pairs sent in DELETE
* @param headers An array HTTP Request Headers
* @param axiosConfig Configuration for the axios javascript library that will be the
* foundation for the rest of the parameters
*
* @returns A promise for [[RequestResponseData]]
*/
this.delete = (baseurl, getdata, headers = {}, axiosConfig = undefined) => this._request("DELETE", baseurl, getdata, {}, this._setHeaders(headers), axiosConfig);
/**
* Makes a POST call to an API.
*
* @param baseurl Path to the API
* @param getdata Object containing the key value pairs sent in POST
* @param postdata Object containing the key value pairs sent in POST
* @param headers An array HTTP Request Headers
* @param axiosConfig Configuration for the axios javascript library that will be the
* foundation for the rest of the parameters
*
* @returns A promise for [[RequestResponseData]]
*/
this.post = (baseurl, getdata, postdata, headers = {}, axiosConfig = undefined) => this._request("POST", baseurl, getdata, postdata, this._setHeaders(headers), axiosConfig);
/**
* Makes a PUT call to an API.
*
* @param baseurl Path to the baseurl
* @param getdata Object containing the key value pairs sent in PUT
* @param postdata Object containing the key value pairs sent in PUT
* @param headers An array HTTP Request Headers
* @param axiosConfig Configuration for the axios javascript library that will be the
* foundation for the rest of the parameters
*
* @returns A promise for [[RequestResponseData]]
*/
this.put = (baseurl, getdata, postdata, headers = {}, axiosConfig = undefined) => this._request("PUT", baseurl, getdata, postdata, this._setHeaders(headers), axiosConfig);
/**
* Makes a PATCH call to an API.
*
* @param baseurl Path to the baseurl
* @param getdata Object containing the key value pairs sent in PATCH
* @param postdata Object containing the key value pairs sent in PATCH
* @param parameters Object containing the parameters of the API call
* @param headers An array HTTP Request Headers
* @param axiosConfig Configuration for the axios javascript library that will be the
* foundation for the rest of the parameters
*
* @returns A promise for [[RequestResponseData]]
*/
this.patch = (baseurl, getdata, postdata, headers = {}, axiosConfig = undefined) => this._request("PATCH", baseurl, getdata, postdata, this._setHeaders(headers), axiosConfig);
this.setNetwork(host, port, protocol, networkID);
}
}
exports.default = AvalancheCore;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FtaW5vLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NhbWluby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBOzs7R0FHRztBQUNILGtEQUtjO0FBRWQsOENBQStEO0FBQy9ELDJDQUE4QztBQUU5Qyx1REFBbUQ7QUFFbkQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBcUIsYUFBYTtJQThiaEM7Ozs7Ozs7T0FPRztJQUNILFlBQVksSUFBWSxFQUFFLElBQVksRUFBRSxRQUFnQixFQUFFLFNBQWlCO1FBcmNqRSxjQUFTLEdBQVcsQ0FBQyxDQUFBO1FBT3JCLFNBQUksR0FBVyxTQUFTLENBQUE7UUFDeEIsWUFBTyxHQUE0QixFQUFFLENBQUE7UUFDckMsa0JBQWEsR0FBdUIsRUFBRSxDQUFBO1FBQ3RDLFNBQUksR0FBNkIsRUFBRSxDQUFBO1FBQ25DLFlBQU8sR0FBWSxTQUFTLENBQUE7UUFFdEM7Ozs7Ozs7Ozs7O1dBV0c7UUFDSCxlQUFVLEdBQUcsQ0FDWCxJQUFZLEVBQ1osSUFBWSxFQUNaLFFBQWdCLEVBQ2hCLFNBQWlCLEVBQ2pCLGVBQXVCLEVBQUUsRUFDbkIsRUFBRTtZQUNSLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHdCQUF3QixFQUFFLEVBQUUsQ0FBQyxDQUFBO1lBQ2pELFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLHdCQUF3QixFQUFFLEVBQUUsQ0FBQyxDQUFBO1lBQ3pELE1BQU0sU0FBUyxHQUFhLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBQzdDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFO2dCQUNqQywwQkFBMEI7Z0JBQzFCLE1BQU0sSUFBSSxzQkFBYSxDQUNyQixvREFBb0QsQ0FDckQsQ0FBQTthQUNGO1lBRUQseUJBQXlCO1lBQ3pCLElBQ0UsSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTO2dCQUM1QixJQUFJ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QUksQ0FBQyxRQUFRLENBQ1gsT0FBTyxFQUNQLE9BQU8sRUFDUCxPQUFPLEVBQ1AsUUFBUSxFQUNSLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQ3pCLFdBQVcsQ0FDWixDQUFBO1FBV0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0NBQ0Y7QUF6Y0QsZ0NBeWNDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqIEBtb2R1bGUgQXZhbGFuY2hlQ29yZVxuICovXG5pbXBvcnQgYXhpb3MsIHtcbiAgQXhpb3NSZXF1ZXN0Q29uZmlnLFxuICBBeGlvc1JlcXVlc3RIZWFkZXJzLFxuICBBeGlvc1Jlc3BvbnNlLFxuICBNZXRob2Rcbn0gZnJvbSBcImF4aW9zXCJcblxuaW1wb3J0IHsgQVBJQmFzZSwgUmVxdWVzdFJlc3BvbnNlRGF0YSB9IGZyb20gXCIuL2NvbW1vbi9hcGliYXNlXCJcbmltcG9ydCB7IFByb3RvY29sRXJyb3IgfSBmcm9tIFwiLi91dGlscy9lcnJvcnNcIlxuaW1wb3J0IHsgTmV0d29yayB9IGZyb20gXCIuL3V0aWxzL25ldHdvcmtzXCJcbmltcG9ydCB7IGZldGNoQWRhcHRlciB9IGZyb20gXCIuL3V0aWxzL2ZldGNoYWRhcHRlclwiXG5cbi8qKlxuICogQXZhbGFuY2hlQ29yZSBpcyBtaWRkbGV3YXJlIGZvciBpbnRlcmFjdGluZyB3aXRoIEF2YWxhbmNoZSBub2RlIFJQQyBBUElzLlxuICpcbiAqIEV4YW1wbGUgdXNhZ2U6XG4gKiBgYGBqc1xuICogbGV0IGF2YWxhbmNoZSA9IG5ldyBBdmFsYW5jaGVDb3JlKFwiMTI3LjAuMC4xXCIsIDk2NTAsIFwiaHR0cHNcIilcbiAqIGBgYFxuICpcbiAqXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEF2YWxhbmNoZUNvcmUge1xuICBwcm90ZWN0ZWQgbmV0d29ya0lEOiBudW1iZXIgPSAwXG4gIHByb3RlY3RlZCBwcm90b2NvbDogc3RyaW5nXG4gIHByb3RlY3RlZCBpcDogc3RyaW5nXG4gIHByb3RlY3RlZCBob3N0OiBzdHJpbmdcbiAgcHJvdGVjdGVkIHBvcnQ6IG51bWJlclxuICBwcm90ZWN0ZWQgYmFzZUVuZHBvaW50OiBzdHJpbmdcbiAgcHJvdGVjdGVkIHVybDogc3RyaW5nXG4gIHByb3RlY3RlZCBhdXRoOiBzdHJpbmcgPSB1bmRlZmluZWRcbiAgcHJvdGVjdGVkIGhlYWRlcnM6IHsgW2s6IHN0cmluZ106IHN0cmluZyB9ID0ge31cbiAgcHJvdGVjdGVkIHJlcXVlc3RDb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZyA9IHt9XG4gIHByb3RlY3RlZCBhcGlzOiB7IFtrOiBzdHJpbmddOiBBUElCYXNlIH0gPSB7fVxuICBwcm90ZWN0ZWQgbmV0d29yazogTmV0d29yayA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBhZGRyZXNzIGFuZCBwb3J0IG9mIHRoZSBtYWluIEF2YWxhbmNoZSBDbGllbnQuXG4gICAqXG4gICAqIEBwYXJhbSBob3N0IFRoZSBob3N0bmFtZSB0byByZXNvbHZlIHRvIHJlYWNoIHRoZSBBdmFsYW5jaGUgQ2xpZW50IFJQQyBBUElzLlxuICAgKiBAcGFyYW0gcG9ydCBUaGUgcG9ydCB0byByZXNvbHZlIHRvIHJlYWNoIHRoZSBBdmFsYW5jaGUgQ2xpZW50IFJQQyBBUElzLlxuICAgKiBAcGFyYW0gcHJvdG9jb2wgVGhlIHByb3RvY29sIHN0cmluZyB0byB1c2UgYmVmb3JlIGEgXCI6Ly9cIiBpbiBhIHJlcXVlc3QsXG4gICAqIGV4OiBcImh0dHBcIiwgXCJodHRwc1wiLCBldGMuIERlZmF1bHRzIHRvIGh0dHBcbiAgICogQHBhcmFtIGJhc2VFbmRwb2ludCB0aGUgYmFzZSBlbmRwb2ludCB0byByZWFjaCB0aGUgQXZhbGFuY2hlIENsaWVudCBSUEMgQVBJcyxcbiAgICogZXg6IFwiL3JwY1wiLiBEZWZhdWx0cyB0byBcIi9cIlxuICAgKiBUaGUgZm9sbG93aW5nIHNwZWNpYWwgY2hhcmFjdGVycyBhcmUgcmVtb3ZlZCBmcm9tIGhvc3QgYW5kIHByb3RvY29sXG4gICAqICYjLEArKCkkfiUnXCI6Kj97fSBhbHNvIGxlc3MgdGhhbiBhbmQgZ3JlYXRlciB0aGFuIHNpZ25zXG4gICAqL1xuICBzZXROZXR3b3JrID0gKFxuICAgIGhvc3Q6IHN0cmluZyxcbiAgICBwb3J0OiBudW1iZXIsXG4gICAgcHJvdG9jb2w6IHN0cmluZyxcbiAgICBuZXR3b3JrSUQ6IG51bWJlcixcbiAgICBiYXNlRW5kcG9pbnQ6IHN0cmluZyA9IFwiXCJcbiAgKTogdm9pZCA9PiB7XG4gICAgaG9zdCA9IGhvc3QucmVwbGFjZSgvWyYjLEArKCkkfiUnXCI6Kj88Pnt9XS9nLCBcIlwiKVxuICAgIHByb3RvY29sID0gcHJvdG9jb2wucmVwbGFjZSgvWyYjLEArKCkkfiUnXCI6Kj88Pnt9XS9nLCBcIlwiKVxuICAgIGNvbnN0IHByb3RvY29sczogc3RyaW5nW10gPSBbXCJodHRwXCIsIFwiaHR0cHNcIl1cbiAgICBpZiAoIXByb3RvY29scy5pbmNsdWRlcyhwcm90b2NvbCkpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICB0aHJvdyBuZXcgUHJvdG9jb2xFcnJvcihcbiAgICAgICAgXCJFcnJvciAtIEF2YWxhbmNoZUNvcmUuc2V0QWRkcmVzczogSW52YWxpZCBwcm90b2NvbFwiXG4gICAgICApXG4gICAgfVxuXG4gICAgLy8gUmVzZXQgbmV0d29yayBzcGVjaWZpY1xuICAgIGlmIChcbiAgICAgIHRoaXMubmV0d29ya0lEICE9PSBuZXR3b3JrSUQgfHxcbiAgICAgIHRoaXMuaG9zdCAhPT0gaG9zdCB8fFxuICAgICAgdGhpcy5wb3J0ICE9PSBwb3J0XG4gICAgKSB7XG4gICAgICB0aGlzLm5ldHdvcmsgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICB0aGlzLmhvc3QgPSBob3N0XG4gICAgdGhpcy5wb3J0ID0gcG9ydFxuICAgIHRoaXMucHJvdG9jb2wgPSBwcm90b2NvbFxuICAgIHRoaXMuYmFzZUVuZHBvaW50ID0gYmFzZUVuZHBvaW50XG4gICAgbGV0IHVybDogc3RyaW5nID0gYCR7cHJvdG9jb2x9Oi8vJHtob3N0fWBcbiAgICBpZiAocG9ydCAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBwb3J0ID09PSBcIm51bWJlclwiICYmIHBvcnQgPj0gMCkge1xuICAgICAgdXJsID0gYCR7dXJsfToke3BvcnR9YFxuICAgIH1cbiAgICBpZiAoXG4gICAgICBiYXNlRW5kcG9pbnQgIT0gdW5kZWZpbmVkICYmXG4gICAgICB0eXBlb2YgYmFzZUVuZHBvaW50ID09IFwic3RyaW5nXCIgJiZcbiAgICAgIGJhc2VFbmRwb2ludC5sZW5ndGggPiAwXG4gICAgKSB7XG4gICAgICBpZiAoYmFzZUVuZHBvaW50WzBdICE9IFwiL1wiKSB7XG4gICAgICAgIGJhc2VFbmRwb2ludCA9IGAvJHtiYXNlRW5kcG9pbnR9YFxuICAgICAgfVxuICAgICAgdXJsID0gYCR7dXJsfSR7YmFzZUVuZHBvaW50fWBcbiAgICB9XG4gICAgdGhpcy51cmwgPSB1cmxcbiAgICB0aGlzLm5ldHdvcmtJRCA9IG5ldHdvcmtJRFxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIG5ldHdvcmsgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGdldE5ldHdvcmsgPSAoKTogTmV0d29yayA9PiB0aGlzLm5ldHdvcmtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcHJvdG9jb2wgc3VjaCBhcyBcImh0dHBcIiwgXCJodHRwc1wiLCBcImdpdFwiLCBcIndzXCIsIGV0Yy5cbiAgICovXG4gIGdldFByb3RvY29sID0gKCk6IHN0cmluZyA9PiB0aGlzLnByb3RvY29sXG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGhvc3QgZm9yIHRoZSBBdmFsYW5jaGUgbm9kZS5cbiAgICovXG4gIGdldEhvc3QgPSAoKTogc3RyaW5nID0+IHRoaXMuaG9zdFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBJUCBmb3IgdGhlIEF2YWxhbmNoZSBub2RlLlxuICAgKi9cbiAgZ2V0SVAgPSAoKTogc3RyaW5nID0+IHRoaXMuaG9zdFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwb3J0IGZvciB0aGUgQXZhbGFuY2hlIG5vZGUuXG4gICAqL1xuICBnZXRQb3J0ID0gKCk6IG51bWJlciA9PiB0aGlzLnBvcnRcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYmFzZSBlbmRwb2ludCBmb3IgdGhlIEF2YWxhbmNoZSBub2RlLlxuICAgKi9cbiAgZ2V0QmFzZUVuZHBvaW50ID0gKCk6IHN0cmluZyA9PiB0aGlzLmJhc2VFbmRwb2ludFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBVUkwgb2YgdGhlIEF2YWxhbmNoZSBub2RlIChpcCArIHBvcnQpXG4gICAqL1xuICBnZXRVUkwgPSAoKTogc3RyaW5nID0+IHRoaXMudXJsXG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGN1c3RvbSBoZWFkZXJzXG4gICAqL1xuICBnZXRIZWFkZXJzID0gKCk6IG9iamVjdCA9PiB0aGlzLmhlYWRlcnNcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VzdG9tIHJlcXVlc3QgY29uZmlnXG4gICAqL1xuICBnZXRSZXF1ZXN0Q29uZmlnID0gKCk6IEF4aW9zUmVxdWVzdENvbmZpZyA9PiB0aGlzLnJlcXVlc3RDb25maWdcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbmV0d29ya0lEXG4gICAqL1xuICBnZXROZXR3b3JrSUQgPSAoKTogbnVtYmVyID0+IHRoaXMubmV0d29ya0lEXG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIEh1bWFuLVJlYWRhYmxlLVBhcnQgb2YgdGhlIG5ldHdvcmsgYXNzb2NpYXRlZCB3aXRoIHRoaXMga2V5LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgW1tLZXlQYWlyXV0ncyBIdW1hbi1SZWFkYWJsZS1QYXJ0IG9mIHRoZSBuZXR3b3JrJ3MgQmVjaDMyIGFkZHJlc3Npbmcgc2NoZW1lXG4gICAqL1xuICBnZXRIUlAgPSAoKTogc3RyaW5nID0+IHRoaXMubmV0d29yay5ocnBcblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBjdXN0b20gaGVhZGVyIHRvIGJlIGluY2x1ZGVkIHdpdGggYWxsIHJlcXVlc3RzLlxuICAgKlxuICAgKiBAcGFyYW0ga2V5IEhlYWRlciBuYW1lXG4gICAqIEBwYXJhbSB2YWx1ZSBIZWFkZXIgdmFsdWVcbiAgICovXG4gIHNldEhlYWRlciA9IChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIHRoaXMuaGVhZGVyc1tgJHtrZXl9YF0gPSB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBwcmV2aW91c2x5IGFkZGVkIGN1c3RvbSBoZWFkZXIuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgSGVhZGVyIG5hbWVcbiAgICovXG4gIHJlbW92ZUhlYWRlciA9IChrZXk6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIGRlbGV0ZSB0aGlzLmhlYWRlcnNbYCR7a2V5fWBdXG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgaGVhZGVycy5cbiAgICovXG4gIHJlbW92ZUFsbEhlYWRlcnMgPSAoKTogdm9pZCA9PiB7XG4gICAgZm9yIChjb25zdCBwcm9wIGluIHRoaXMuaGVhZGVycykge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmhlYWRlcnMsIHByb3ApKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmhlYWRlcnNbYCR7cHJvcH1gXVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgbmV3IGN1c3RvbSBjb25maWcgdmFsdWUgdG8gYmUgaW5jbHVkZWQgd2l0aCBhbGwgcmVxdWVzdHMuXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgQ29uZmlnIG5hbWVcbiAgICogQHBhcmFtIHZhbHVlIENvbmZpZyB2YWx1ZVxuICAgKi9cbiAgc2V0UmVxdWVzdENvbmZpZyA9IChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICB0aGlzLnJlcXVlc3RDb25maWdbYCR7a2V5fWBdID0gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgcHJldmlvdXNseSBhZGRlZCByZXF1ZXN0IGNvbmZpZy5cbiAgICpcbiAgICogQHBhcmFtIGtleSBIZWFkZXIgbmFtZVxuICAgKi9cbiAgcmVtb3ZlUmVxdWVzdENvbmZpZyA9IChrZXk6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIGRlbGV0ZSB0aGlzLnJlcXVlc3RDb25maWdbYCR7a2V5fWBdXG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgcmVxdWVzdCBjb25maWdzLlxuICAgKi9cbiAgcmVtb3ZlQWxsUmVxdWVzdENvbmZpZ3MgPSAoKTogdm9pZCA9PiB7XG4gICAgZm9yIChjb25zdCBwcm9wIGluIHRoaXMucmVxdWVzdENvbmZpZykge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLnJlcXVlc3RDb25maWcsIHByb3ApKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnJlcXVlc3RDb25maWdbYCR7cHJvcH1gXVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSB0ZW1wb3JhcnkgYXV0aCB0b2tlbiB1c2VkIGZvciBjb21tdW5pY2F0aW5nIHdpdGggdGhlIG5vZGUuXG4gICAqXG4gICAqIEBwYXJhbSBhdXRoIEEgdGVtcG9yYXJ5IHRva2VuIHByb3ZpZGVkIGJ5IHRoZSBub2RlIGVuYWJsaW5nIGFjY2VzcyB0byB0aGUgZW5kcG9pbnRzIG9uIHRoZSBub2RlLlxuICAgKi9cbiAgc2V0QXV0aFRva2VuID0gKGF1dGg6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgIHRoaXMuYXV0aCA9IGF1dGhcbiAgfVxuXG4gIHByb3RlY3RlZCBfc2V0SGVhZGVycyA9IChoZWFkZXJzOiBhbnkpOiBBeGlvc1JlcXVlc3RIZWFkZXJzID0+IHtcbiAgICBpZiAodHlwZW9mIHRoaXMuaGVhZGVycyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5oZWFkZXJzKSkge1xuICAgICAgICBoZWFkZXJzW2Ake2tleX1gXSA9IHZhbHVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmF1dGggPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGhlYWRlcnMuQXV0aG9yaXphdGlvbiA9IGBCZWFyZXIgJHt0aGlzLmF1dGh9YFxuICAgIH1cbiAgICByZXR1cm4gaGVhZGVyc1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHByaW1hcnkgYXNzZXQgYWxpYXMuXG4gICAqL1xuICBnZXRQcmltYXJ5QXNzZXRBbGlhcyA9ICgpOiBzdHJpbmcgPT4ge1xuICAgIHJldHVybiB0aGlzLm5ldHdvcmsuWC5hdmF4QXNzZXRBbGlhc1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gQVBJIHRvIHRoZSBtaWRkbGV3YXJlLiBUaGUgQVBJIHJlc29sdmVzIHRvIGEgcmVnaXN0ZXJlZCBibG9ja2NoYWluJ3MgUlBDLlxuICAgKlxuICAgKiBJbiBUeXBlU2NyaXB0OlxuICAgKiBgYGBqc1xuICAgKiBhdmFsYW5jaGUuYWRkQVBJPE15Vk1DbGFzcz4oXCJteWNoYWluXCIsIE15Vk1DbGFzcywgXCIvZXh0L2JjL215Y2hhaW5cIilcbiAgICogYGBgXG4gICAqXG4gICAqIEluIEphdmFzY3JpcHQ6XG4gICAqIGBgYGpzXG4gICAqIGF2YWxhbmNoZS5hZGRBUEkoXCJteWNoYWluXCIsIE15Vk1DbGFzcywgXCIvZXh0L2JjL215Y2hhaW5cIilcbiAgICogYGBgXG4gICAqXG4gICAqIEB0eXBlcGFyYW0gR0EgQ2xhc3Mgb2YgdGhlIEFQSSBiZWluZyBhZGRlZFxuICAgKiBAcGFyYW0gYXBpTmFtZSBBIGxhYmVsIGZvciByZWZlcmVuY2luZyB0aGUgQVBJIGluIHRoZSBmdXR1cmVcbiAgICogQHBhcmFtIENvbnN0cnVjdG9yRk4gQSByZWZlcmVuY2UgdG8gdGhlIGNsYXNzIHdoaWNoIGluc3RhbnRpYXRlcyB0aGUgQVBJXG4gICAqIEBwYXJhbSBiYXNldXJsIFBhdGggdG8gcmVzb2x2ZSB0byByZWFjaCB0aGUgQVBJXG4gICAqXG4gICAqL1xuICBhZGRBUEkgPSA8R0EgZXh0ZW5kcyBBUElCYXNlPihcbiAgICBhcGlOYW1lOiBzdHJpbmcsXG4gICAgQ29uc3RydWN0b3JGTjogbmV3IChcbiAgICAgIGF2YXg6IEF2YWxhbmNoZUNvcmUsXG4gICAgICBiYXNldXJsPzogc3RyaW5nLFxuICAgICAgLi4uYXJnczogYW55W11cbiAgICApID0+IEdBLFxuICAgIGJhc2V1cmw6IHN0cmluZyA9IHVuZGVmaW5lZCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApID0+IHtcbiAgICBpZiAodHlwZW9mIGJhc2V1cmwgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgIHRoaXMuYXBpc1tgJHthcGlOYW1lfWBdID0gbmV3IENvbnN0cnVjdG9yRk4odGhpcywgdW5kZWZpbmVkLCAuLi5hcmdzKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwaXNbYCR7YXBpTmFtZX1gXSA9IG5ldyBDb25zdHJ1Y3RvckZOKHRoaXMsIGJhc2V1cmwsIC4uLmFyZ3MpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIHJlZmVyZW5jZSB0byBhbiBBUEkgYnkgaXRzIGFwaU5hbWUgbGFiZWwuXG4gICAqXG4gICAqIEBwYXJhbSBhcGlOYW1lIE5hbWUgb2YgdGhlIEFQSSB0byByZXR1cm5cbiAgICovXG4gIGFwaSA9IDxHQSBleHRlbmRzIEFQSUJhc2U+KGFwaU5hbWU6IHN0cmluZyk6IEdBID0+XG4gICAgdGhpcy5hcGlzW2Ake2FwaU5hbWV9YF0gYXMgR0FcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcHJvdGVjdGVkIF9yZXF1ZXN0ID0gYXN5bmMgKFxuICAgIHhocm1ldGhvZDogTWV0aG9kLFxuICAgIGJhc2V1cmw6IHN0cmluZyxcbiAgICBnZXRkYXRhOiBvYmplY3QsXG4gICAgcG9zdGRhdGE6IHN0cmluZyB8IG9iamVjdCB8IEFycmF5QnVmZmVyIHwgQXJyYXlCdWZmZXJWaWV3LFxuICAgIGhlYWRlcnM6IEF4aW9zUmVxdWVzdEhlYWRlcnMgPSB7fSxcbiAgICBheGlvc0NvbmZpZzogQXhpb3NSZXF1ZXN0Q29uZmlnID0gdW5kZWZpbmVkXG4gICk6IFByb21pc2U8UmVxdWVzdFJlc3BvbnNlRGF0YT4gPT4ge1xuICAgIGxldCBjb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZ1xuICAgIGlmIChheGlvc0NvbmZpZykge1xuICAgICAgY29uZmlnID0ge1xuICAgICAgICAuLi5heGlvc0NvbmZpZyxcbiAgICAgICAgLi4udGhpcy5yZXF1ZXN0Q29uZmlnXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbmZpZyA9IHtcbiAgICAgICAgYmFzZVVSTDogdGhpcy51cmwsXG4gICAgICAgIHJlc3BvbnNlVHlwZTogXCJ0ZXh0XCIsXG4gICAgICAgIC4uLnRoaXMucmVxdWVzdENvbmZpZ1xuICAgICAgfVxuICAgIH1cbiAgICBjb25maWcudXJsID0gYmFzZXVybFxuICAgIGNvbmZpZy5tZXRob2QgPSB4aHJtZXRob2RcbiAgICBjb25maWcuaGVhZGVycyA9IGhlYWRlcnNcbiAgICBjb25maWcuZGF0YSA9IHBvc3RkYXRhXG4gICAgY29uZmlnLnBhcmFtcyA9IGdldGRhdGFcbiAgICAvLyB1c2UgdGhlIGZldGNoIGFkYXB0ZXIgaWYgZmV0Y2ggaXMgYXZhaWxhYmxlIGUuZy4gbm9uIE5vZGU8MTcgZW52XG4gICAgaWYgKHR5cGVvZiBmZXRjaCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgY29uZmlnLmFkYXB0ZXIgPSBmZXRjaEFkYXB0ZXJcbiAgICB9XG4gICAgY29uc3QgcmVzcDogQXhpb3NSZXNwb25zZTxhbnk+ID0gYXdhaXQgYXhpb3MucmVxdWVzdChjb25maWcpXG4gICAgLy8gcHVyZ2luZyBhbGwgdGhhdCBpcyBheGlvc1xuICAgIGNvbnN0IHhocmRhdGE6IFJlcXVlc3RSZXNwb25zZURhdGEgPSBuZXcgUmVxdWVzdFJlc3BvbnNlRGF0YShcbiAgICAgIHJlc3AuZGF0YSxcbiAgICAgIHJlc3AuaGVhZGVycyxcbiAgICAgIHJlc3Auc3RhdHVzLFxuICAgICAgcmVzcC5zdGF0dXNUZXh0LFxuICAgICAgcmVzcC5yZXF1ZXN0XG4gICAgKVxuICAgIHJldHVybiB4aHJkYXRhXG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgYSBHRVQgY2FsbCB0byBhbiBBUEkuXG4gICAqXG4gICAqIEBwYXJhbSBiYXNldXJsIFBhdGggdG8gdGhlIGFwaVxuICAgKiBAcGFyYW0gZ2V0ZGF0YSBPYmplY3QgY29udGFpbmluZyB0aGUga2V5IHZhbHVlIHBhaXJzIHNlbnQgaW4gR0VUXG4gICAqIEBwYXJhbSBoZWFkZXJzIEFuIGFycmF5IEhUVFAgUmVxdWVzdCBIZWFkZXJzXG4gICAqIEBwYXJhbSBheGlvc0NvbmZpZyBDb25maWd1cmF0aW9uIGZvciB0aGUgYXhpb3MgamF2YXNjcmlwdCBsaWJyYXJ5IHRoYXQgd2lsbCBiZSB0aGVcbiAgICogZm91bmRhdGlvbiBmb3IgdGhlIHJlc3Qgb2YgdGhlIHBhcmFtZXRlcnNcbiAgICpcbiAgICogQHJldHVybnMgQSBwcm9taXNlIGZvciBbW1JlcXVlc3RSZXNwb25zZURhdGFdXVxuICAgKi9cbiAgZ2V0ID0gKFxuICAgIGJhc2V1cmw6IHN0cmluZyxcbiAgICBnZXRkYXRhOiBvYmplY3QsXG4gICAgaGVhZGVyczogb2JqZWN0ID0ge30sXG4gICAgYXhpb3NDb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZyA9IHVuZGVmaW5lZFxuICApOiBQcm9taXNlPFJlcXVlc3RSZXNwb25zZURhdGE+ID0+XG4gICAgdGhpcy5fcmVxdWVzdChcbiAgICAgIFwiR0VUXCIsXG4gICAgICBiYXNldXJsLFxuICAgICAgZ2V0ZGF0YSxcbiAgICAgIHt9LFxuICAgICAgdGhpcy5fc2V0SGVhZGVycyhoZWFkZXJzKSxcbiAgICAgIGF4aW9zQ29uZmlnXG4gICAgKVxuXG4gIC8qKlxuICAgKiBNYWtlcyBhIERFTEVURSBjYWxsIHRvIGFuIEFQSS5cbiAgICpcbiAgICogQHBhcmFtIGJhc2V1cmwgUGF0aCB0byB0aGUgQVBJXG4gICAqIEBwYXJhbSBnZXRkYXRhIE9iamVjdCBjb250YWluaW5nIHRoZSBrZXkgdmFsdWUgcGFpcnMgc2VudCBpbiBERUxFVEVcbiAgICogQHBhcmFtIGhlYWRlcnMgQW4gYXJyYXkgSFRUUCBSZXF1ZXN0IEhlYWRlcnNcbiAgICogQHBhcmFtIGF4aW9zQ29uZmlnIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBheGlvcyBqYXZhc2NyaXB0IGxpYnJhcnkgdGhhdCB3aWxsIGJlIHRoZVxuICAgKiBmb3VuZGF0aW9uIGZvciB0aGUgcmVzdCBvZiB0aGUgcGFyYW1ldGVyc1xuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgZm9yIFtbUmVxdWVzdFJlc3BvbnNlRGF0YV1dXG4gICAqL1xuICBkZWxldGUgPSAoXG4gICAgYmFzZXVybDogc3RyaW5nLFxuICAgIGdldGRhdGE6IG9iamVjdCxcbiAgICBoZWFkZXJzOiBvYmplY3QgPSB7fSxcbiAgICBheGlvc0NvbmZpZzogQXhpb3NSZXF1ZXN0Q29uZmlnID0gdW5kZWZpbmVkXG4gICk6IFByb21pc2U8UmVxdWVzdFJlc3BvbnNlRGF0YT4gPT5cbiAgICB0aGlzLl9yZXF1ZXN0KFxuICAgICAgXCJERUxFVEVcIixcbiAgICAgIGJhc2V1cmwsXG4gICAgICBnZXRkYXRhLFxuICAgICAge30sXG4gICAgICB0aGlzLl9zZXRIZWFkZXJzKGhlYWRlcnMpLFxuICAgICAgYXhpb3NDb25maWdcbiAgICApXG5cbiAgLyoqXG4gICAqIE1ha2VzIGEgUE9TVCBjYWxsIHRvIGFuIEFQSS5cbiAgICpcbiAgICogQHBhcmFtIGJhc2V1cmwgUGF0aCB0byB0aGUgQVBJXG4gICAqIEBwYXJhbSBnZXRkYXRhIE9iamVjdCBjb250YWluaW5nIHRoZSBrZXkgdmFsdWUgcGFpcnMgc2VudCBpbiBQT1NUXG4gICAqIEBwYXJhbSBwb3N0ZGF0YSBPYmplY3QgY29udGFpbmluZyB0aGUga2V5IHZhbHVlIHBhaXJzIHNlbnQgaW4gUE9TVFxuICAgKiBAcGFyYW0gaGVhZGVycyBBbiBhcnJheSBIVFRQIFJlcXVlc3QgSGVhZGVyc1xuICAgKiBAcGFyYW0gYXhpb3NDb25maWcgQ29uZmlndXJhdGlvbiBmb3IgdGhlIGF4aW9zIGphdmFzY3JpcHQgbGlicmFyeSB0aGF0IHdpbGwgYmUgdGhlXG4gICAqIGZvdW5kYXRpb24gZm9yIHRoZSByZXN0IG9mIHRoZSBwYXJhbWV0ZXJzXG4gICAqXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSBmb3IgW1tSZXF1ZXN0UmVzcG9uc2VEYXRhXV1cbiAgICovXG4gIHBvc3QgPSAoXG4gICAgYmFzZXVybDogc3RyaW5nLFxuICAgIGdldGRhdGE6IG9iamVjdCxcbiAgICBwb3N0ZGF0YTogc3RyaW5nIHwgb2JqZWN0IHwgQXJyYXlCdWZmZXIgfCBBcnJheUJ1ZmZlclZpZXcsXG4gICAgaGVhZGVyczogb2JqZWN0ID0ge30sXG4gICAgYXhpb3NDb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZyA9IHVuZGVmaW5lZFxuICApOiBQcm9taXNlPFJlcXVlc3RSZXNwb25zZURhdGE+ID0+XG4gICAgdGhpcy5fcmVxdWVzdChcbiAgICAgIFwiUE9TVFwiLFxuICAgICAgYmFzZXVybCxcbiAgICAgIGdldGRhdGEsXG4gICAgICBwb3N0ZGF0YSxcbiAgICAgIHRoaXMuX3NldEhlYWRlcnMoaGVhZGVycyksXG4gICAgICBheGlvc0NvbmZpZ1xuICAgIClcblxuICAvKipcbiAgICogTWFrZXMgYSBQVVQgY2FsbCB0byBhbiBBUEkuXG4gICAqXG4gICAqIEBwYXJhbSBiYXNldXJsIFBhdGggdG8gdGhlIGJhc2V1cmxcbiAgICogQHBhcmFtIGdldGRhdGEgT2JqZWN0IGNvbnRhaW5pbmcgdGhlIGtleSB2YWx1ZSBwYWlycyBzZW50IGluIFBVVFxuICAgKiBAcGFyYW0gcG9zdGRhdGEgT2JqZWN0IGNvbnRhaW5pbmcgdGhlIGtleSB2YWx1ZSBwYWlycyBzZW50IGluIFBVVFxuICAgKiBAcGFyYW0gaGVhZGVycyBBbiBhcnJheSBIVFRQIFJlcXVlc3QgSGVhZGVyc1xuICAgKiBAcGFyYW0gYXhpb3NDb25maWcgQ29uZmlndXJhdGlvbiBmb3IgdGhlIGF4aW9zIGphdmFzY3JpcHQgbGlicmFyeSB0aGF0IHdpbGwgYmUgdGhlXG4gICAqIGZvdW5kYXRpb24gZm9yIHRoZSByZXN0IG9mIHRoZSBwYXJhbWV0ZXJzXG4gICAqXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSBmb3IgW1tSZXF1ZXN0UmVzcG9uc2VEYXRhXV1cbiAgICovXG4gIHB1dCA9IChcbiAgICBiYXNldXJsOiBzdHJpbmcsXG4gICAgZ2V0ZGF0YTogb2JqZWN0LFxuICAgIHBvc3RkYXRhOiBzdHJpbmcgfCBvYmplY3QgfCBBcnJheUJ1ZmZlciB8IEFycmF5QnVmZmVyVmlldyxcbiAgICBoZWFkZXJzOiBvYmplY3QgPSB7fSxcbiAgICBheGlvc0NvbmZpZzogQXhpb3NSZXF1ZXN0Q29uZmlnID0gdW5kZWZpbmVkXG4gICk6IFByb21pc2U8UmVxdWVzdFJlc3BvbnNlRGF0YT4gPT5cbiAgICB0aGlzLl9yZXF1ZXN0KFxuICAgICAgXCJQVVRcIixcbiAgICAgIGJhc2V1cmwsXG4gICAgICBnZXRkYXRhLFxuICAgICAgcG9zdGRhdGEsXG4gICAgICB0aGlzLl9zZXRIZWFkZXJzKGhlYWRlcnMpLFxuICAgICAgYXhpb3NDb25maWdcbiAgICApXG5cbiAgLyoqXG4gICAqIE1ha2VzIGEgUEFUQ0ggY2FsbCB0byBhbiBBUEkuXG4gICAqXG4gICAqIEBwYXJhbSBiYXNldXJsIFBhdGggdG8gdGhlIGJhc2V1cmxcbiAgICogQHBhcmFtIGdldGRhdGEgT2JqZWN0IGNvbnRhaW5pbmcgdGhlIGtleSB2YWx1ZSBwYWlycyBzZW50IGluIFBBVENIXG4gICAqIEBwYXJhbSBwb3N0ZGF0YSBPYmplY3QgY29udGFpbmluZyB0aGUga2V5IHZhbHVlIHBhaXJzIHNlbnQgaW4gUEFUQ0hcbiAgICogQHBhcmFtIHBhcmFtZXRlcnMgT2JqZWN0IGNvbnRhaW5pbmcgdGhlIHBhcmFtZXRlcnMgb2YgdGhlIEFQSSBjYWxsXG4gICAqIEBwYXJhbSBoZWFkZXJzIEFuIGFycmF5IEhUVFAgUmVxdWVzdCBIZWFkZXJzXG4gICAqIEBwYXJhbSBheGlvc0NvbmZpZyBDb25maWd1cmF0aW9uIGZvciB0aGUgYXhpb3MgamF2YXNjcmlwdCBsaWJyYXJ5IHRoYXQgd2lsbCBiZSB0aGVcbiAgICogZm91bmRhdGlvbiBmb3IgdGhlIHJlc3Qgb2YgdGhlIHBhcmFtZXRlcnNcbiAgICpcbiAgICogQHJldHVybnMgQSBwcm9taXNlIGZvciBbW1JlcXVlc3RSZXNwb25zZURhdGFdXVxuICAgKi9cbiAgcGF0Y2ggPSAoXG4gICAgYmFzZXVybDogc3RyaW5nLFxuICAgIGdldGRhdGE6IG9iamVjdCxcbiAgICBwb3N0ZGF0YTogc3RyaW5nIHwgb2JqZWN0IHwgQXJyYXlCdWZmZXIgfCBBcnJheUJ1ZmZlclZpZXcsXG4gICAgaGVhZGVyczogb2JqZWN0ID0ge30sXG4gICAgYXhpb3NDb25maWc6IEF4aW9zUmVxdWVzdENvbmZpZyA9IHVuZGVmaW5lZFxuICApOiBQcm9taXNlPFJlcXVlc3RSZXNwb25zZURhdGE+ID0+XG4gICAgdGhpcy5fcmVxdWVzdChcbiAgICAgIFwiUEFUQ0hcIixcbiAgICAgIGJhc2V1cmwsXG4gICAgICBnZXRkYXRhLFxuICAgICAgcG9zdGRhdGEsXG4gICAgICB0aGlzLl9zZXRIZWFkZXJzKGhlYWRlcnMpLFxuICAgICAgYXhpb3NDb25maWdcbiAgICApXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgQXZhbGFuY2hlIGluc3RhbmNlLiBTZXRzIHRoZSBhZGRyZXNzIGFuZCBwb3J0IG9mIHRoZSBtYWluIEF2YWxhbmNoZSBDbGllbnQuXG4gICAqXG4gICAqIEBwYXJhbSBob3N0IFRoZSBob3N0bmFtZSB0byByZXNvbHZlIHRvIHJlYWNoIHRoZSBBdmFsYW5jaGUgQ2xpZW50IEFQSXNcbiAgICogQHBhcmFtIHBvcnQgVGhlIHBvcnQgdG8gcmVzb2x2ZSB0byByZWFjaCB0aGUgQXZhbGFuY2hlIENsaWVudCBBUElzXG4gICAqIEBwYXJhbSBwcm90b2NvbCBUaGUgcHJvdG9jb2wgc3RyaW5nIHRvIHVzZSBiZWZvcmUgYSBcIjovL1wiIGluIGEgcmVxdWVzdCwgZXg6IFwiaHR0cFwiLCBcImh0dHBzXCIsIFwiZ2l0XCIsIFwid3NcIiwgZXRjIC4uLlxuICAgKiBAcGFyYW0gbmV0d29ya0lEIFRoZSBuZXR3b3JrSUQgb2YgdGhlIG5ldHdvcmsgVVJMIGJlbG9uZ3MgdG9cbiAgICovXG4gIGNvbnN0cnVjdG9yKGhvc3Q6IHN0cmluZywgcG9ydDogbnVtYmVyLCBwcm90b2NvbDogc3RyaW5nLCBuZXR3b3JrSUQ6IG51bWJlcikge1xuICAgIHRoaXMuc2V0TmV0d29yayhob3N0LCBwb3J0LCBwcm90b2NvbCwgbmV0d29ya0lEKVxuICB9XG59XG4iXX0=