trimble-connect-sdk
Version:
Trimble Connect SDK for JavaScript
265 lines • 42.7 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());
});
};
import { ServiceError } from './error';
import { ServiceResponse } from './response';
export function extractEndpoint(url) {
const schemaIndex = url.indexOf('//');
const firstSeparatorIndex = url.indexOf('/', schemaIndex + 2);
return url.substring(0, firstSeparatorIndex);
}
function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
export class Service {
constructor(config) {
this.config = config;
this.defaultRetryCount = 3;
if (!this.config.serviceUri) {
throw new Error('The serviceUri is required');
}
}
makeRequest(url, method = 'GET', body, customHeaders, auth = true) {
return __awaiter(this, void 0, void 0, function* () {
const headers = new Headers({ Accept: 'application/json' });
if (customHeaders) {
customHeaders.forEach((value, key) => {
headers.append(key, value);
});
}
const response = (yield this.request(url, method, body, headers, auth));
if (response.response.status !== 204) {
const contentType = response.response.headers.get('content-type');
if (contentType === null ||
contentType.indexOf('application/json') !== -1) {
response.data = (yield response.response.json());
}
else {
throw new ServiceError(response.response, 'Cannot deserialize response body as it is not in a JSON format.');
}
}
return response;
});
}
getItemsWithPages(url, onPageRetrieved, pageSize, body, customHeaders, auth = true) {
return __awaiter(this, void 0, void 0, function* () {
const headers = customHeaders !== null && customHeaders !== void 0 ? customHeaders : new Headers();
if (headers.has('Range')) {
headers.delete('Range');
}
const range = { start: 0, end: pageSize - 1 };
headers.append('Range', `items=${range.start}-${range.end}`);
let response = yield this.makeRequest(url, 'GET', body, headers, auth);
do {
const responseRange = this.getRange(response);
const hasNextPage = Array.isArray(response.data) &&
response.data.length !== 0 &&
responseRange &&
responseRange.total &&
responseRange.end < responseRange.total - 1;
let nextPage;
if (hasNextPage && responseRange && responseRange.total) {
headers.delete('Range');
range.start = responseRange.end + 1;
range.end = Math.min(responseRange.total - 1, range.start + pageSize - 1);
headers.append('Range', `items=${range.start}-${range.end}`);
nextPage = this.makeRequest(url, 'GET', body, headers, auth);
}
onPageRetrieved(response);
if (nextPage) {
response = yield nextPage;
}
else {
break;
}
} while (true);
});
}
request(url, method = 'GET', body, customHeaders, auth = true) {
return __awaiter(this, void 0, void 0, function* () {
const requestUrl = url.startsWith('http')
? url
: url.startsWith('/')
? extractEndpoint(this.config.serviceUri) + url
: this.config.serviceUri + url;
const headers = new Headers();
const contentType = customHeaders
? customHeaders.get('Content-Type')
: undefined;
if (!contentType && body !== undefined) {
headers.set('Content-Type', 'application/json');
}
if (customHeaders) {
customHeaders.forEach((value, key) => {
headers.append(key, value);
});
}
return this.fetchWithRetry(requestUrl, {
body,
headers,
method,
redirect: 'follow',
}, auth);
});
}
maxRetries() {
if (this.config.maxRetries !== undefined) {
return this.config.maxRetries;
}
else {
return this.defaultRetryCount;
}
}
calculateRetryDelay(retryCount) {
if (retryCount === 0) {
return 0;
}
else {
const base = 100;
return Math.random() * (Math.pow(2, retryCount - 1) * base);
}
}
retryableError(error) {
if (this.timeoutError(error) ||
this.networkingError(error) ||
this.expiredCredentialsError(error) ||
this.throttledError(error) ||
error.response.status >= 500) {
return true;
}
return false;
}
networkingError(error) {
return error.errorCode === 'NetworkingError';
}
timeoutError(error) {
return error.errorCode === 'TimeoutError';
}
expiredCredentialsError(error) {
if (error.response.status === 401) {
const credentials = this.config.credentials;
if (credentials &&
typeof credentials.expired === 'boolean') {
credentials.expired = true;
}
return true;
}
return false;
}
throttledError(error) {
if (error.response.status === 429) {
return true;
}
else {
return false;
}
}
fetchWithRetry(url, params, auth = true) {
return __awaiter(this, void 0, void 0, function* () {
const logger = this.config.logger;
const result = new ServiceResponse(this, new Response(), void 0);
do {
const credentials = this.config.credentials;
if (auth && credentials) {
if (typeof credentials.get === 'function') {
try {
yield credentials.get();
}
catch (err) {
if (logger !== undefined) {
this.log(`[TID] Failed to acquire tokens: ${err.message}`);
}
throw err;
}
}
if (credentials.token) {
params.headers.set('Authorization', 'Bearer ' + credentials.token);
}
}
const startTime = Date.now();
const response = yield this.fetch(url, params);
if (logger !== undefined) {
const delta = (Date.now() - startTime) / 1000;
const isoDate = new Date(startTime).toISOString();
const requestContentLength = params.body ? params.body.length : 0;
const responseContentLength = response.headers.get('content-length');
const line = `${isoDate} [TC HTTP] ${params.method} ${url} ${response.status} ${delta} ${result.retryCount} ${requestContentLength} ${responseContentLength}`;
this.log(line);
}
result.response = response;
if (response.ok) {
return result;
}
else {
let err;
const contentType = response.headers.get('content-type');
if (contentType && contentType.indexOf('application/json') !== -1) {
const errorInfo = yield response.json();
err = new ServiceError(response, errorInfo.message, errorInfo.code || errorInfo.errorcode);
}
else {
const message = yield response.text();
err = new ServiceError(response, message);
}
if (result.retryCount + 1 < this.maxRetries() &&
this.retryableError(err)) {
const retryAfterHeader = response.headers.get('retry-after');
const retryAfterMS = retryAfterHeader
? parseInt(retryAfterHeader, 10) * 1000
: 0;
const ms = this.calculateRetryDelay(result.retryCount) + retryAfterMS;
yield delay(ms);
result.retryCount++;
}
else {
throw err;
}
}
} while (true);
});
}
fetch(url, params) {
return fetch(url, params);
}
getRange(response) {
if (!response.response.headers.has('Content-Range')) {
return undefined;
}
try {
const contentRange = response.response.headers
.get('Content-Range')
.split(' ');
const rangeTokens = contentRange[1].split('/');
const tokens = rangeTokens[0].split('-');
const start = Number(tokens[0]);
const end = Number(tokens[1]);
const total = Number(rangeTokens[1]);
return { start, end, total };
}
catch (_a) {
return undefined;
}
}
log(line) {
return __awaiter(this, void 0, void 0, function* () {
const logger = this.config.logger;
if (logger !== undefined) {
if (typeof logger.log === 'function') {
logger.log(line);
}
else if (typeof logger.write === 'function') {
logger.write(line + '\n');
}
}
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIuLyIsInNvdXJjZXMiOlsic2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFHQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFJN0MsTUFBTSxVQUFVLGVBQWUsQ0FBQyxHQUFXO0lBQ3pDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEMsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFOUQsT0FBTyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0FBQy9DLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBQyxFQUFVO0lBQ3ZCLE9BQU8sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRTtRQUNuQyxVQUFVLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzFCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQU1ELE1BQU0sT0FBTyxPQUFPO0lBUWxCLFlBQTRCLE1BQXFCO1FBQXJCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFOekMsc0JBQWlCLEdBQVcsQ0FBQyxDQUFDO1FBT3BDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRTtZQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7U0FDL0M7SUFDSCxDQUFDO0lBWVksV0FBVyxDQUN0QixHQUFXLEVBQ1gsU0FBc0QsS0FBSyxFQUMzRCxJQUF3QixFQUN4QixhQUF1QixFQUN2QixPQUFnQixJQUFJOztZQUVwQixNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxFQUFFLE1BQU0sRUFBRSxrQkFBa0Is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QUMsQ0FBQyxDQUFDO1lBQzlCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVyQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQztTQUM5QjtRQUFDLFdBQU07WUFDTixPQUFPLFNBQVMsQ0FBQztTQUNsQjtJQUNILENBQUM7SUFPYSxHQUFHLENBQUMsSUFBWTs7WUFDNUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7WUFDbEMsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO2dCQUN4QixJQUFJLE9BQU8sTUFBTSxDQUFDLEdBQUcsS0FBSyxVQUFVLEVBQUU7b0JBQ3BDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQ2xCO3FCQUFNLElBQUksT0FBTyxNQUFNLENBQUMsS0FBSyxLQUFLLFVBQVUsRUFBRTtvQkFDN0MsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7aUJBQzNCO2FBQ0Y7UUFDSCxDQUFDO0tBQUE7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbmZpZ3VyYXRpb24gfSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQgeyBDcmVkZW50aWFscyB9IGZyb20gJy4vY3JlZGVudGlhbHMnO1xuaW1wb3J0IHsgUmFuZ2UgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBTZXJ2aWNlRXJyb3IgfSBmcm9tICcuL2Vycm9yJztcbmltcG9ydCB7IFNlcnZpY2VSZXNwb25zZSB9IGZyb20gJy4vcmVzcG9uc2UnO1xuaW1wb3J0IHsgU2VydmljZUNyZWRlbnRpYWxzIH0gZnJvbSAnLi9zZXJ2aWNlX2NyZWRlbnRpYWxzJztcblxuLyoqIEBpbnRlcm5hbCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RFbmRwb2ludCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHNjaGVtYUluZGV4ID0gdXJsLmluZGV4T2YoJy8vJyk7XG4gIGNvbnN0IGZpcnN0U2VwYXJhdG9ySW5kZXggPSB1cmwuaW5kZXhPZignLycsIHNjaGVtYUluZGV4ICsgMik7XG5cbiAgcmV0dXJuIHVybC5zdWJzdHJpbmcoMCwgZmlyc3RTZXBhcmF0b3JJbmRleCk7XG59XG5cbmZ1bmN0aW9uIGRlbGF5KG1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgc2V0VGltZW91dChyZXNvbHZlLCBtcyk7XG4gIH0pO1xufVxuXG4vKipcbiAqIFRoZSBzZXJ2aWNlIGNsaWVudCB0aGF0IHJlcHJlc2VudHMgY29ubmVjdGlvbiB0byB0aGUgT3JnYW5pemVyIFNlcnZpY2UuXG4gKiBFYWNoIEFQSSBvcGVyYXRpb24gaXMgZXhwb3NlZCBhcyBhIGZ1bmN0aW9uIG9uIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlIHtcbiAgLyoqIFVzZWQgaWYgbWF4UmV0cmllcyBpcyBub3Qgc3BlY2lmaWVkIGluIHtAc2VlIENvbmZpZ3VyYXRpb24jbWF4UmV0cmllcyB9LiBUaGUgZGVmYXVsdFJldHJ5Q291bnQgY2FuIGJlIG92ZXJyaWRlbiBieSBzZXJ2aWNlIGNsYXNzZXMuICovXG4gIHByaXZhdGUgZGVmYXVsdFJldHJ5Q291bnQ6IG51bWJlciA9IDM7XG5cbiAgLyoqXG4gICAqIEBjb25zdHJ1Y3RvciBDb25zdHJ1Y3RzIGEgc2VydmljZSBvYmplY3QuXG4gICAqIEBwYXJhbSB7Q29uZmlnfSBjb25maWcgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyAoZS5nLiBzZXJ2aWNlIHVybCkuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgY29uZmlnOiBDb25maWd1cmF0aW9uKSB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zZXJ2aWNlVXJpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzZXJ2aWNlVXJpIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZWQgdGhlIG5leHQgcGFnZSBmcm9tdCBoZSBzZXF1ZW5jZSBvZiBwYWdlcyBpbml0aWF0ZWQgYnkge0BzZWUgT3JnYW5pemVyLmxpc3RUcmVlcyB9LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSB1cmwgdG8gbWFrZSByZXF1ZXN0IHRvLiBDb3VsZCBiZSBhYnNvbHV0ZSBvciByZWxhdGl2ZSB0byB0aGUgc2VydmljZSBiYXNlIHVyaS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZCBUaGUgSFRUUCBtZXRob2QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBib2R5IFRoZSBib2R5IHRvIHNlbmQgaW4gdGhlIHJlcXVlc3QgKHdpbGwgYmUgc2VyaWFsaXplZCB0byBKU09OKS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGhlYWRlcnMgVGhlIGhlYWRlcnMgdG8gYXR0YWNoIHRvIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXV0aCBUaGUgdmFsdWUgaW5kaWNhdGluZyB3ZXRoZXIgdGhlIHJlcXVlc3QgcmVxdWlyZXMgYXV0aGVudGljYXRpb24uIElmIHRydWUsIHRoZSBjcmVkZW50aWFscyB3aWxsIGJlIHJlcXVlc3RlZCBmcm9tIHRoZSBjb25maWd1cmF0aW9uIHtAc2VlIENvbmZpZyNjcmVkZW50aWFscyB9IGFuZCBBdXRob3JpemF0aW9uIGhlYWRlciB3aWxsIGJlIGF0dGFjaGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTZXJ2aWNlUmVzcG9uc2U8RD4+fSBUaGUgc2VydmljZSByZXNwb25zZS5cbiAgICogQHRocm93cyB7U2VydmljZUVycm9yfSBpbiBjYXNlIG9mIHRoZSBlcnJvciByZXNwb25zZSBmcm9tIHRoZSBzZXJ2aWNlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIG1ha2VSZXF1ZXN0PEQ+KFxuICAgIHVybDogc3RyaW5nLFxuICAgIG1ldGhvZDogJ0dFVCcgfCAnUFVUJyB8ICdQT1NUJyB8ICdQQVRDSCcgfCAnREVMRVRFJyA9ICdHRVQnLFxuICAgIGJvZHk/OiBzdHJpbmcgfCBGb3JtRGF0YSxcbiAgICBjdXN0b21IZWFkZXJzPzogSGVhZGVycyxcbiAgICBhdXRoOiBib29sZWFuID0gdHJ1ZVxuICApOiBQcm9taXNlPFNlcnZpY2VSZXNwb25zZTxEPj4ge1xuICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyh7IEFjY2VwdDogJ2FwcGxpY2F0aW9uL2pzb24nIH0pO1xuICAgIGlmIChjdXN0b21IZWFkZXJzKSB7XG4gICAgICBjdXN0b21IZWFkZXJzLmZvckVhY2goKHZhbHVlOiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3BvbnNlID0gKGF3YWl0IHRoaXMucmVxdWVzdChcbiAgICAgIHVybCxcbiAgICAgIG1ldGhvZCxcbiAgICAgIGJvZHksXG4gICAgICBoZWFkZXJzLFxuICAgICAgYXV0aFxuICAgICkpIGFzIGFueSBhcyBTZXJ2aWNlUmVzcG9uc2U8RD47XG5cbiAgICAvLyBkZXNlcmlhbGl6ZSByZXNwb25zZSBib2R5LiBJZiBzZXJ2aWNlIHJlc3BvbmRlZCB3aXRoIGFuIGVycm9yIGl0IHdhcyB0aHJvd24gYWxyZWFkeS5cbiAgICBpZiAocmVzcG9uc2UucmVzcG9uc2Uuc3RhdHVzICE9PSAyMDQpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UucmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpO1xuICAgICAgaWYgKFxuICAgICAgICBjb250ZW50VHlwZSA9PT0gbnVsbCB8fFxuICAgICAgICBjb250ZW50VHlwZS5pbmRleE9mKCdhcHBsaWNhdGlvbi9qc29uJykgIT09IC0xXG4gICAgICApIHtcbiAgICAgICAgcmVzcG9uc2UuZGF0YSA9IChhd2FpdCByZXNwb25zZS5yZXNwb25zZS5qc29uKCkpIGFzIEQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgU2VydmljZUVycm9yKFxuICAgICAgICAgIHJlc3BvbnNlLnJlc3BvbnNlLFxuICAgICAgICAgICdDYW5ub3QgZGVzZXJpYWxpemUgcmVzcG9uc2UgYm9keSBhcyBpdCBpcyBub3QgaW4gYSBKU09OIGZvcm1hdC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgYWxsIHRoZSBpdGVtcyBwYWdlIGJ5IHBhZ2UsIHJldHVybmluZyBlYWNoIHBhZ2UgcmVzdWx0cyBpbiBhIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXJsIFRoZSB1cmwgdG8gbWFrZSByZXF1ZXN0IHRvLiBDb3VsZCBiZSBhYnNvbHV0ZSBvciByZWxhdGl2ZSB0byB0aGUgc2VydmljZSBiYXNlIHVyaS5cbiAgICogQHBhcmFtIHsocmVzcG9uc2U6IFNlcnZpY2VSZXNwb25zZTxEPikgPT4gdm9pZH0gb25QYWdlUmV0cmlldmVkIFRoZSBjYWxsYmFjayB1c2VkIHRvIHJldHVybiByZXN1bHRzLCBwYWdlIGJ5IHBhZ2UuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBwYWdlU2l6ZSBUaGUgcGFnZSBzaXplIHVzZWQgdG8gcmVxdWVzdCBpdGVtcy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGJvZHkgVGhlIGJvZHkgdG8gc2VuZCBpbiB0aGUgcmVxdWVzdCAod2lsbCBiZSBzZXJpYWxpemVkIHRvIEpTT04pLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY3VzdG9tSGVhZGVycyBUaGUgaGVhZGVycyB0byBhdHRhY2ggdG8gcmVxdWVzdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBhdXRoIFRoZSB2YWx1ZSBpbmRpY2F0aW5nIHdldGhlciB0aGUgcmVxdWVzdCByZXF1aXJlcyBhdXRoZW50aWNhdGlvbi4gSWYgdHJ1ZSwgdGhlIGNyZWRlbnRpYWxzIHdpbGwgYmUgcmVxdWVzdGVkIGZyb20gdGhlIGNvbmZpZ3VyYXRpb24ge0BzZWUgQ29uZmlnI2NyZWRlbnRpYWxzIH0gYW5kIEF1dGhvcml6YXRpb24gaGVhZGVyIHdpbGwgYmUgYXR0YWNoZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFNlcnZpY2VSZXNwb25zZTxEPj59IFRoZSBzZXJ2aWNlIHJlc3BvbnNlLlxuICAgKiBAdGhyb3dzIHtTZXJ2aWNlRXJyb3J9IGluIGNhc2Ugb2YgdGhlIGVycm9yIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZpY2UuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0SXRlbXNXaXRoUGFnZXM8RD4oXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgb25QYWdlUmV0cmlldmVkOiAocmVzcG9uc2U6IFNlcnZpY2VSZXNwb25zZTxEPikgPT4gdm9pZCxcbiAgICBwYWdlU2l6ZTogbnVtYmVyLFxuICAgIGJvZHk/OiBzdHJpbmcgfCBGb3JtRGF0YSxcbiAgICBjdXN0b21IZWFkZXJzPzogSGVhZGVycyxcbiAgICBhdXRoOiBib29sZWFuID0gdHJ1ZVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBoZWFkZXJzID0gY3VzdG9tSGVhZGVycyA/PyBuZXcgSGVhZGVycygpO1xuICAgIGlmIChoZWFkZXJzLmhhcygnUmFuZ2UnKSkge1xuICAgICAgaGVhZGVycy5kZWxldGUoJ1JhbmdlJyk7XG4gICAgfVxuICAgIGNvbnN0IHJhbmdlOiBSYW5nZSA9IHsgc3RhcnQ6IDAsIGVuZDogcGFnZVNpemUgLSAxIH07XG4gICAgaGVhZGVycy5hcHBlbmQoJ1JhbmdlJywgYGl0ZW1zPSR7cmFuZ2Uuc3RhcnR9LSR7cmFuZ2UuZW5kfWApO1xuXG4gICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5tYWtlUmVxdWVzdDxEPih1cmwsICdHRVQnLCBib2R5LCBoZWFkZXJzLCBhdXRoKTtcblxuICAgIGRvIHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlUmFuZ2UgPSB0aGlzLmdldFJhbmdlKHJlc3BvbnNlKTtcblxuICAgICAgLy8gaWYgdGhlIHJlc3BvbnNlIHJldHVybnMgYW4gZW1wdHkgYXJyYXksIG9yIHdlIGhhdmUgbm8gY29udGVudCByYW5nZSBoZWFkZXIsIHdlIGhhdmUgYWNxdWlyZWQgYWxsIHRoZSBpdGVtcy5cbiAgICAgIC8vIGlmIHRoZSByZXNwb25zZSByYW5nZSBpcyBlcXVhbCB0byB0aGUgdG90YWwgbnVtYmVyIG9mIGl0ZW1zLCB3ZSBoYXZlIGFjcXVpcmVkIGFsbCB0aGUgaXRlbXMuXG4gICAgICBjb25zdCBoYXNOZXh0UGFnZSA9XG4gICAgICAgIEFycmF5LmlzQXJyYXkocmVzcG9uc2UuZGF0YSkgJiZcbiAgICAgICAgcmVzcG9uc2UuZGF0YS5sZW5ndGggIT09IDAgJiZcbiAgICAgICAgcmVzcG9uc2VSYW5nZSAmJlxuICAgICAgICByZXNwb25zZVJhbmdlLnRvdGFsICYmXG4gICAgICAgIHJlc3BvbnNlUmFuZ2UuZW5kIDwgcmVzcG9uc2VSYW5nZS50b3RhbCAtIDE7XG5cbiAgICAgIGxldCBuZXh0UGFnZTogUHJvbWlzZTxTZXJ2aWNlUmVzcG9uc2U8RD4+IHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGhhc05leHRQYWdlICYmIHJlc3BvbnNlUmFuZ2UgJiYgcmVzcG9uc2VSYW5nZS50b3RhbCkge1xuICAgICAgICBoZWFkZXJzLmRlbGV0ZSgnUmFuZ2UnKTtcbiAgICAgICAgcmFuZ2Uuc3RhcnQgPSByZXNwb25zZVJhbmdlLmVuZCArIDE7XG4gICAgICAgIHJhbmdlLmVuZCA9IE1hdGgubWluKFxuICAgICAgICAgIHJlc3BvbnNlUmFuZ2UudG90YWwgLSAxLFxuICAgICAgICAgIHJhbmdlLnN0YXJ0ICsgcGFnZVNpemUgLSAxXG4gICAgICAgICk7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKCdSYW5nZScsIGBpdGVtcz0ke3JhbmdlLnN0YXJ0fS0ke3JhbmdlLmVuZH1gKTtcblxuICAgICAgICAvLyBpbml0aWF0ZSBuZXh0IHBhZ2UgcmVxdWVzdCwgYnV0IGRvbid0IHdhaXQgb24gaXQgeWV0XG4gICAgICAgIG5leHRQYWdlID0gdGhpcy5tYWtlUmVxdWVzdDxEPih1cmwsICdHRVQnLCBib2R5LCBoZWFkZXJzLCBhdXRoKTtcbiAgICAgIH1cblxuICAgICAgb25QYWdlUmV0cmlldmVkKHJlc3BvbnNlKTtcblxuICAgICAgaWYgKG5leHRQYWdlKSB7XG4gICAgICAgIHJlc3BvbnNlID0gYXdhaXQgbmV4dFBhZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gaWYgd2UgcmVhY2hlZCB0aGlzIHBvaW50LCB3ZSBzdGlsbCBoYXZlIGl0ZW1zIHRvIGFjcXVpcmUuXG4gICAgfSB3aGlsZSAodHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgYSBzZXJ2aWNlIHJlcXVlc3Qgd2l0aCBhbGwgbmVlZGVkIGF1dGhlbnRpY2F0aW9uYW5kIHJldHJ5IGxvZ2ljLiBDb252ZXJ0cyBlcnJvciByZXNwb25zZSB0byBleGNlcHRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBtYWtlIHJlcXVlc3QgdG8uIENvdWxkIGJlIGFic29sdXRlIG9yIHJlbGF0aXZlIHRvIHRoZSBzZXJ2aWNlIGJhc2UgdXJpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kIFRoZSBIVFRQIG1ldGhvZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGJvZHkgVGhlIGJvZHkgdG8gc2VuZCBpbiB0aGUgcmVxdWVzdCAod2lsbCBiZSBzZXJpYWxpemVkIHRvIEpTT04pLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY3VzdG9tSGVhZGVycyBUaGUgY3VzdG9tIGhlYWRlcnMgdG8gYXR0YWNoIHRvIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXV0aCBUaGUgdmFsdWUgaW5kaWNhdGluZyB3ZXRoZXIgdGhlIHJlcXVlc3QgcmVxdWlyZXMgYXV0aGVudGljYXRpb24uIElmIHRydWUsIHRoZSBjcmVkZW50aWFscyB3aWxsIGJlIHJlcXVlc3RlZCBmcm9tIHRoZSBjb25maWd1cmF0aW9uIHtAc2VlIENvbmZpZyNjcmVkZW50aWFscyB9IGFuZCBBdXRob3JpemF0aW9uIGhlYWRlciB3aWxsIGJlIGF0dGFjaGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTZXJ2aWNlUmVzcG9uc2U8RD4+fSBUaGUgc2VydmljZSByZXNwb25zZS5cbiAgICogQHRocm93cyB7U2VydmljZUVycm9yfSBpbiBjYXNlIG9mIHRoZSBlcnJvciByZXNwb25zZSBmcm9tIHRoZSBzZXJ2aWNlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIHJlcXVlc3QoXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgbWV0aG9kOiAnR0VUJyB8ICdQVVQnIHwgJ1BPU1QnIHwgJ1BBVENIJyB8ICdERUxFVEUnID0gJ0dFVCcsXG4gICAgYm9keT86IHN0cmluZyB8IEZvcm1EYXRhIHwgQmxvYixcbiAgICBjdXN0b21IZWFkZXJzPzogSGVhZGVycyxcbiAgICBhdXRoOiBib29sZWFuID0gdHJ1ZVxuICApOiBQcm9taXNlPFNlcnZpY2VSZXNwb25zZTx2b2lkPj4ge1xuICAgIC8vIHRoaXMgbWV0aG9kIHN1cHBvcnRzIDMgY2FzZXM6IGFic29sdXRlIHVybCwgYWJzb2x1dGUgcGF0aCwgcmVsYXRpdmUgcGF0aFxuICAgIGNvbnN0IHJlcXVlc3RVcmwgPSB1cmwuc3RhcnRzV2l0aCgnaHR0cCcpXG4gICAgICA/IHVybFxuICAgICAgOiB1cmwuc3RhcnRzV2l0aCgnLycpXG4gICAgICA/IGV4dHJhY3RFbmRwb2ludCh0aGlzLmNvbmZpZy5zZXJ2aWNlVXJpKSArIHVybFxuICAgICAgOiB0aGlzLmNvbmZpZy5zZXJ2aWNlVXJpICsgdXJsO1xuXG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIZWFkZXJzKCk7XG4gICAgY29uc3QgY29udGVudFR5cGUgPSBjdXN0b21IZWFkZXJzXG4gICAgICA/IGN1c3RvbUhlYWRlcnMuZ2V0KCdDb250ZW50LVR5cGUnKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgaWYgKCFjb250ZW50VHlwZSAmJiBib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGhlYWRlcnMuc2V0KCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgIH1cblxuICAgIGlmIChjdXN0b21IZWFkZXJzKSB7XG4gICAgICBjdXN0b21IZWFkZXJzLmZvckVhY2goKHZhbHVlOiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKGtleSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmV0Y2hXaXRoUmV0cnkoXG4gICAgICByZXF1ZXN0VXJsLFxuICAgICAge1xuICAgICAgICBib2R5LFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHJlZGlyZWN0OiAnZm9sbG93JyxcbiAgICAgIH0sXG4gICAgICBhdXRoXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb3cgbWFueSB0aW1lcyBhIGZhaWxlZCByZXF1ZXN0IHNob3VsZCBiZSByZXRyaWVkIGJlZm9yZSBnaXZpbmcgdXAuXG4gICAqIHRoZSBkZWZhdWx0UmV0cnlDb3VudCBjYW4gYmUgb3ZlcnJpZGVuIGJ5IHNlcnZpY2UgY2xhc3Nlcy5cbiAgICpcbiAgICogQGFwaSBwcml2YXRlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwdWJsaWMgbWF4UmV0cmllcygpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmNvbmZpZy5tYXhSZXRyaWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5tYXhSZXRyaWVzO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5kZWZhdWx0UmV0cnlDb3VudDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmlyc3QgcmV0cnkgZ29lcyBpbW1lZGlhdGx5ICgwbXMgZGVsYXkpIHRoZW4gZXhwb25lbnRpYWwgZ3Jvd3RoIHdpdGggMTAwbXMgYXMgYSBiYXNlLlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHB1YmxpYyBjYWxjdWxhdGVSZXRyeURlbGF5KHJldHJ5Q291bnQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKHJldHJ5Q291bnQgPT09IDApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBiYXNlID0gMTAwO1xuICAgICAgcmV0dXJuIE1hdGgucmFuZG9tKCkgKiAoTWF0aC5wb3coMiwgcmV0cnlDb3VudCAtIDEpICogYmFzZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBhcGkgcHJpdmF0ZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSByZXRyeWFibGVFcnJvcihlcnJvcjogU2VydmljZUVycm9yKSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy50aW1lb3V0RXJyb3IoZXJyb3IpIHx8XG4gICAgICB0aGlzLm5ldHdvcmtpbmdFcnJvcihlcnJvcikgfHxcbiAgICAgIHRoaXMuZXhwaXJlZENyZWRlbnRpYWxzRXJyb3IoZXJyb3IpIHx8XG4gICAgICB0aGlzLnRocm90dGxlZEVycm9yKGVycm9yKSB8fFxuICAgICAgZXJyb3IucmVzcG9uc2Uuc3RhdHVzID49IDUwMFxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgbmV0d29ya2luZ0Vycm9yKGVycm9yOiBTZXJ2aWNlRXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IuZXJyb3JDb2RlID09PSAnTmV0d29ya2luZ0Vycm9yJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgdGltZW91dEVycm9yKGVycm9yOiBTZXJ2aWNlRXJyb3IpIHtcbiAgICByZXR1cm4gZXJyb3IuZXJyb3JDb2RlID09PSAnVGltZW91dEVycm9yJztcbiAgfVxuXG4gIC8qKlxuICAgKiBAYXBpIHByaXZhdGVcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZXhwaXJlZENyZWRlbnRpYWxzRXJyb3IoZXJyb3I6IFNlcnZpY2VFcnJvcikge1xuICAgIGlmIChlcnJvci5yZXNwb25zZS5zdGF0dXMgPT09IDQwMSkge1xuICAgICAgY29uc3QgY3JlZGVudGlhbHMgPSB0aGlzLmNvbmZpZy5jcmVkZW50aWFscztcbiAgICAgIGlmIChcbiAgICAgICAgY3JlZGVudGlhbHMgJiZcbiAgICAgICAgdHlwZW9mIChjcmVkZW50aWFscyBhcyBDcmVkZW50aWFscykuZXhwaXJlZCA9PT0gJ2Jvb2xlYW4nXG4gICAgICApIHtcbiAgICAgICAgKGNyZWRlbnRpYWxzIGFzIENyZWRlbnRpYWxzKS5leHBpcmVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQGFwaSBwcml2YXRlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHRocm90dGxlZEVycm9yKGVycm9yOiBTZXJ2aWNlRXJyb3IpIHtcbiAgICAvLyBBV1MgQVBJIEdhdGV3YXkgcmV0dXJucyA0MjkgaW4gY2FzZSBvZiB0aHJvdHRsaW5nIGVycm9yc1xuICAgIGlmIChlcnJvci5yZXNwb25zZS5zdGF0dXMgPT09IDQyOSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgYSBzZXJ2aWNlIGNhbGwgYW5kIHRha2VzIGNhcmUgYWJvdXQgcmV0cnkgbG9naWMgKHJlLWF1dGhlbnRpY2F0aW9uIGlmIG5lZWRlZCkuXG4gICAqIE5vdGUgdGhlIDx2b2lkPiBhcyBhIGdlbmVyaWMgcGFyYW1ldGVyLiBUaGlzIG1ldGhvZCBkb2VzIG5vdCByZWFkIHRoZSByZXNwb25zZSBib2R5LiBUaGUgU2VydmljZVJlc3BvbnNlIHJldHVybiB2YWx1ZSB3aWxsIGJlIGNhc2VkIHRvIG5lZWRlZCB0eXBlIG9uIHVwcGVyIGxldmVscyBvZiB0aGUgY29kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgdXJsIHRvIG1ha2UgcmVxdWVzdCB0by4gQ291bGQgYmUgYWJzb2x1dGUgb3IgcmVsYXRpdmUgdG8gdGhlIHNlcnZpY2UgYmFzZSB1cmkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXJhbXMgVGhlIGZldGNoIHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gYXV0aCBUaGUgdmFsdWUgaW5kaWNhdGluZyB3ZXRoZXIgdGhlIHJlcXVlc3QgcmVxdWlyZXMgYXV0aGVudGljYXRpb24uIElmIHRydWUsIHRoZSBjcmVkZW50aWFscyB3aWxsIGJlIHJlcXVlc3RlZCBmcm9tIHRoZSBjb25maWd1cmF0aW9uIHtAc2VlIENvbmZpZyNjcmVkZW50aWFscyB9IGFuZCBBdXRob3JpemF0aW9uIGhlYWRlciB3aWxsIGJlIGF0dGFjaGVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTZXJ2aWNlUmVzcG9uc2U8dm9pZD4+fSBUaGUgc2VydmljZSByZXNwb25zZS5cbiAgICogQHRocm93cyB7U2VydmljZUVycm9yfSBpbiBjYXNlIG9mIHRoZSBlcnJvciByZXNwb25zZSBmcm9tIHRoZSBzZXJ2aWNlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaFdpdGhSZXRyeShcbiAgICB1cmw6IHN0cmluZyxcbiAgICBwYXJhbXM6IGFueSxcbiAgICBhdXRoOiBib29sZWFuID0gdHJ1ZVxuICApOiBQcm9taXNlPFNlcnZpY2VSZXNwb25zZTx2b2lkPj4ge1xuICAgIGNvbnN0IGxvZ2dlciA9IHRoaXMuY29uZmlnLmxvZ2dlcjtcbiAgICBjb25zdCByZXN1bHQ6IFNlcnZpY2VSZXNwb25zZTx2b2lkPiA9IG5ldyBTZXJ2aWNlUmVzcG9uc2U8dm9pZD4oXG4gICAgICB0aGlzLFxuICAgICAgbmV3IFJlc3BvbnNlKCksXG4gICAgICB2b2lkIDBcbiAgICApO1xuICAgIGRvIHtcbiAgICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gdGhpcy5jb25maWcuY3JlZGVudGlhbHM7XG4gICAgICBpZiAoYXV0aCAmJiBjcmVkZW50aWFscykge1xuICAgICAgICBpZiAodHlwZW9mIChjcmVkZW50aWFscyBhcyBTZXJ2aWNlQ3JlZGVudGlhbHMpLmdldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCAoY3JlZGVudGlhbHMgYXMgU2VydmljZUNyZWRlbnRpYWxzKS5nZXQoKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgICAgaWYgKGxvZ2dlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHRoaXMubG9nKGBbVElEXSBGYWlsZWQgdG8gYWNxdWlyZSB0b2tlbnM6ICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY3JlZGVudGlhbHMudG9rZW4pIHtcbiAgICAgICAgICBwYXJhbXMuaGVhZGVycy5zZXQoJ0F1dGhvcml6YXRpb24nLCAnQmVhcmVyICcgKyBjcmVkZW50aWFscy50b2tlbik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5mZXRjaCh1cmwsIHBhcmFtcyk7XG4gICAgICBpZiAobG9nZ2VyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgZGVsdGEgPSAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSkgLyAxMDAwO1xuICAgICAgICBjb25zdCBpc29EYXRlID0gbmV3IERhdGUoc3RhcnRUaW1lKS50b0lTT1N0cmluZygpO1xuICAgICAgICBjb25zdCByZXF1ZXN0Q29udGVudExlbmd0aCA9IHBhcmFtcy5ib2R5ID8gcGFyYW1zLmJvZHkubGVuZ3RoIDogMDtcbiAgICAgICAgY29uc3QgcmVzcG9uc2VDb250ZW50TGVuZ3RoID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJyk7XG4gICAgICAgIGNvbnN0IGxpbmUgPSBgJHtpc29EYXRlfSBbVEMgSFRUUF0gJHtwYXJhbXMubWV0aG9kfSAke3VybH0gJHtyZXNwb25zZS5zdGF0dXN9ICR7ZGVsdGF9ICR7cmVzdWx0LnJldHJ5Q291bnR9ICR7cmVxdWVzdENvbnRlbnRMZW5ndGh9ICR7cmVzcG9uc2VDb250ZW50TGVuZ3RofWA7XG4gICAgICAgIHRoaXMubG9nKGxpbmUpO1xuICAgICAgfVxuXG4gICAgICByZXN1bHQucmVzcG9uc2UgPSByZXNwb25zZTtcblxuICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgZXJyOiBTZXJ2aWNlRXJyb3I7XG4gICAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpO1xuICAgICAgICBpZiAoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZignYXBwbGljYXRpb24vanNvbicpICE9PSAtMSkge1xuICAgICAgICAgIGNvbnN0IGVycm9ySW5mbyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICBlcnIgPSBuZXcgU2VydmljZUVycm9yKFxuICAgICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICAgICBlcnJvckluZm8ubWVzc2FnZSxcbiAgICAgICAgICAgIGVycm9ySW5mby5jb2RlIHx8IGVycm9ySW5mby5lcnJvcmNvZGVcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICAgICAgZXJyID0gbmV3IFNlcnZpY2VFcnJvcihyZXNwb25zZSwgbWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgcmVzdWx0LnJldHJ5Q291bnQgKyAxIDwgdGhpcy5tYXhSZXRyaWVzKCkgJiZcbiAgICAgICAgICB0aGlzLnJldHJ5YWJsZUVycm9yKGVycilcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgcmV0cnlBZnRlckhlYWRlciA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KCdyZXRyeS1hZnRlcicpO1xuICAgICAgICAgIGNvbnN0IHJldHJ5QWZ0ZXJNUyA9IHJldHJ5QWZ0ZXJIZWFkZXJcbiAgICAgICAgICAgID8gcGFyc2VJbnQocmV0cnlBZnRlckhlYWRlciwgMTApICogMTAwMFxuICAgICAgICAgICAgOiAwO1xuICAgICAgICAgIGNvbnN0IG1zID0gdGhpcy5jYWxjdWxhdGVSZXRyeURlbGF5KHJlc3VsdC5yZXRyeUNvdW50KSArIHJldHJ5QWZ0ZXJNUztcbiAgICAgICAgICBhd2FpdCBkZWxheShtcyk7XG4gICAgICAgICAgcmVzdWx0LnJldHJ5Q291bnQrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IHdoaWxlICh0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbG93ZXN0IGxldmVsIGZldGNoIGZ1bmN0aW9uIHdyYXBwZXIuXG4gICAqIFRoaXMgbWV0aG9kIGFsbG93cyB0byBzZXBhcnRlIHRoZSBzdGVwIG9mIGFjdHVhbCBzZW5kaW5nIG9mIHRoZSByZXF1ZXN0IGluIHRoZSBIVFRQIHBpcGxpbmUgYW5kIHBvdGVudGlhbGx5IGludGVyY2VwdCBpdCBhbmQgZmlyZSBldmVudHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBtYWtlIHJlcXVlc3QgdG8uIENvdWxkIGJlIGFic29sdXRlIG9yIHJlbGF0aXZlIHRvIHRoZSBzZXJ2aWNlIGJhc2UgdXJpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zIFRoZSBIVFRQIG1ldGhvZC5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgZmV0Y2godXJsOiBzdHJpbmcsIHBhcmFtczogYW55KTogUHJvbWlzZTxSZXNwb25zZT4ge1xuICAgIHJldHVybiBmZXRjaCh1cmwsIHBhcmFtcyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbmV4dCByYW5nZSBmb3IgdGhlIHJlc3Qgb2YgdGhlIHJlc3VsdHMgb2YgcmVzcG9uc2UgZGF0YS5cbiAgICogQHBhcmFtIHtTZXJ2aWNlUmVzcG9uc2U8RD59IHJlc3BvbnNlIFRoZSByZXNwb25zZSBmb3Igd2hpY2ggd2UgZ2V0IHRoZSBuZXh0IHJhbmdlLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRSYW5nZTxEPihyZXNwb25zZTogU2VydmljZVJlc3BvbnNlPEQ+KTogUmFuZ2UgfCB1bmRlZmluZWQge1xuICAgIGlmICghcmVzcG9uc2UucmVzcG9uc2UuaGVhZGVycy5oYXMoJ0NvbnRlbnQtUmFuZ2UnKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGVudFJhbmdlID0gcmVzcG9uc2UucmVzcG9uc2UuaGVhZGVyc1xuICAgICAgICAuZ2V0KCdDb250ZW50LVJhbmdlJykhXG4gICAgICAgIC5zcGxpdCgnICcpO1xuICAgICAgY29uc3QgcmFuZ2VUb2tlbnMgPSBjb250ZW50UmFuZ2VbMV0uc3BsaXQoJy8nKTtcbiAgICAgIGNvbnN0IHRva2VucyA9IHJhbmdlVG9rZW5zWzBdLnNwbGl0KCctJyk7XG5cbiAgICAgIGNvbnN0IHN0YXJ0ID0gTnVtYmVyKHRva2Vuc1swXSk7XG4gICAgICBjb25zdCBlbmQgPSBOdW1iZXIodG9rZW5zWzFdKTtcbiAgICAgIGNvbnN0IHRvdGFsID0gTnVtYmVyKHJhbmdlVG9rZW5zWzFdKTtcblxuICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZCwgdG90YWwgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFB1dCBhIGxpbmUgb2YgdGV4dCB0byB0aGUgbG9nLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGluZSBUaGUgbGluZSB0byBsb2cuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGxvZyhsaW5lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBsb2dnZXIgPSB0aGlzLmNvbmZpZy5sb2dnZXI7XG4gICAgaWYgKGxvZ2dlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGxvZ2dlci5sb2cgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgbG9nZ2VyLmxvZyhsaW5lKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxvZ2dlci53cml0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBsb2dnZXIud3JpdGUobGluZSArICdcXG4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiJdfQ==