UNPKG

@kubectl/caminojs

Version:
345 lines 41.4 kB
"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 __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=