Innovenergy_trunk/frontend/node_modules/testcafe/lib/configuration/testcafe-configuration.js

225 lines
41 KiB
JavaScript

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const configuration_base_1 = __importDefault(require("./configuration-base"));
const lodash_1 = require("lodash");
const get_options_1 = require("../utils/get-options");
const option_names_1 = __importDefault(require("./option-names"));
const get_filter_fn_1 = __importDefault(require("../utils/get-filter-fn"));
const prepare_reporters_1 = __importDefault(require("../utils/prepare-reporters"));
const string_1 = require("../utils/string");
const render_template_1 = __importDefault(require("../utils/render-template"));
const warning_message_1 = __importDefault(require("../notifications/warning-message"));
const resolve_path_relatively_cwd_1 = __importDefault(require("../utils/resolve-path-relatively-cwd"));
const default_values_1 = require("./default-values");
const option_source_1 = __importDefault(require("./option-source"));
const customizable_compilers_1 = __importDefault(require("./customizable-compilers"));
const deprecated_1 = require("../notifications/deprecated");
const pool_1 = __importDefault(require("../browser/provider/pool"));
const formats_1 = require("./formats");
const runtime_1 = require("../errors/runtime");
const types_1 = require("../errors/types");
const localhost_names_1 = require("../utils/localhost-names");
const BASE_CONFIGURATION_FILENAME = '.testcaferc';
const CONFIGURATION_FILENAMES = formats_1.CONFIGURATION_EXTENSIONS.map(ext => `${BASE_CONFIGURATION_FILENAME}${ext}`);
const DEFAULT_SCREENSHOTS_DIRECTORY = 'screenshots';
const OPTION_FLAG_NAMES = [
option_names_1.default.debugMode,
option_names_1.default.debugOnFail,
option_names_1.default.skipUncaughtErrors,
option_names_1.default.stopOnFirstFail,
option_names_1.default.takeScreenshotsOnFails,
option_names_1.default.disablePageCaching,
option_names_1.default.disablePageReloads,
option_names_1.default.disableScreenshots,
option_names_1.default.disableMultipleWindows,
];
const OPTION_INIT_FLAG_NAMES = [
option_names_1.default.developmentMode,
option_names_1.default.retryTestPages,
option_names_1.default.cache,
option_names_1.default.disableHttp2,
option_names_1.default.experimentalProxyless,
option_names_1.default.disableCrossDomain,
];
class TestCafeConfiguration extends configuration_base_1.default {
constructor(configFile = '') {
super(configFile || CONFIGURATION_FILENAMES);
this._isExplicitConfig = !!configFile;
}
async init(options) {
await super.init();
const opts = await this._load();
this._checkUnsecureDataInJSONConfiguration(opts);
if (opts) {
this._options = configuration_base_1.default._fromObj(opts);
await this._normalizeOptionsAfterLoad();
}
await this.asyncMergeOptions(options);
const proxyless = this.getOption(option_names_1.default.experimentalProxyless);
if (proxyless)
this._ensureOptionWithValue(option_names_1.default.hostname, localhost_names_1.LOCALHOST_NAMES.LOCALHOST, option_source_1.default.Input);
}
async asyncMergeOptions(options) {
options = options || {};
super.mergeOptions(options);
if (!options.isCli && this._options.browsers)
this._options.browsers.value = await this._getBrowserInfo();
}
prepare() {
this._prepareFlags();
this._setDefaultValues();
this._prepareCompilerOptions();
}
notifyAboutOverriddenOptions(warningLog) {
if (!this._overriddenOptions.length)
return;
const optionsStr = (0, string_1.getConcatenatedValuesString)(this._overriddenOptions);
const optionsSuffix = (0, string_1.getPluralSuffix)(this._overriddenOptions);
const renderedMessage = (0, render_template_1.default)(warning_message_1.default.configOptionsWereOverridden, optionsStr, optionsSuffix);
configuration_base_1.default._showConsoleWarning(renderedMessage);
if (warningLog)
warningLog.addWarning(renderedMessage);
this._overriddenOptions = [];
}
notifyAboutDeprecatedOptions(warningLog) {
const deprecatedOptions = this.getOptions((name, option) => name in deprecated_1.DEPRECATED && option.value !== void 0);
for (const optionName in deprecatedOptions)
warningLog.addWarning((0, deprecated_1.getDeprecationMessage)(deprecated_1.DEPRECATED[optionName]));
}
get startOptions() {
const proxyless = this.getOption(option_names_1.default.experimentalProxyless);
let hostname = this.getOption(option_names_1.default.hostname);
if (!hostname && proxyless)
hostname = localhost_names_1.LOCALHOST_NAMES.LOCALHOST;
const result = {
hostname,
port1: this.getOption(option_names_1.default.port1),
port2: this.getOption(option_names_1.default.port2),
options: {
ssl: this.getOption(option_names_1.default.ssl),
developmentMode: this.getOption(option_names_1.default.developmentMode),
retryTestPages: this.getOption(option_names_1.default.retryTestPages),
cache: this.getOption(option_names_1.default.cache),
disableHttp2: this.getOption(option_names_1.default.disableHttp2),
disableCrossDomain: this.getOption(option_names_1.default.disableCrossDomain),
proxyless,
},
};
return result;
}
_checkUnsecureDataInJSONConfiguration(opts) {
var _a;
if (!this._isJSONConfiguration())
return;
if ((_a = opts === null || opts === void 0 ? void 0 : opts[option_names_1.default.dashboard]) === null || _a === void 0 ? void 0 : _a.token)
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.dashboardTokenInJSON);
}
_prepareFlag(name, source = option_source_1.default.Configuration) {
const option = this._ensureOption(name, void 0, source);
option.value = !!option.value;
}
_prepareFlags() {
OPTION_FLAG_NAMES.forEach(name => this._prepareFlag(name));
}
_prepareInitFlags() {
OPTION_INIT_FLAG_NAMES.forEach(name => this._prepareFlag(name, option_source_1.default.Default));
}
async _normalizeOptionsAfterLoad() {
await this._prepareSslOptions();
this._prepareInitFlags();
this._prepareFilterFn();
this._ensureArrayOption(option_names_1.default.src);
this._ensureArrayOption(option_names_1.default.browsers);
this._ensureArrayOption(option_names_1.default.clientScripts);
this._prepareReporters();
}
_prepareFilterFn() {
const filterOption = this._ensureOption(option_names_1.default.filter, default_values_1.DEFAULT_FILTER_FN, option_source_1.default.Default);
if (!filterOption.value)
return;
const filterOptionValue = filterOption.value;
if (filterOptionValue.testGrep)
filterOptionValue.testGrep = (0, get_options_1.getGrepOptions)(option_names_1.default.filterTestGrep, filterOptionValue.testGrep);
if (filterOptionValue.fixtureGrep)
filterOptionValue.fixtureGrep = (0, get_options_1.getGrepOptions)(option_names_1.default.filterFixtureGrep, filterOptionValue.fixtureGrep);
filterOption.value = (0, get_filter_fn_1.default)(filterOption.value);
filterOption.source = option_source_1.default.Configuration;
}
_ensureScreenshotOptions() {
const path = (0, resolve_path_relatively_cwd_1.default)(DEFAULT_SCREENSHOTS_DIRECTORY);
const screenshots = this._ensureOption(option_names_1.default.screenshots, {}, option_source_1.default.Configuration).value;
if (!screenshots.path)
screenshots.path = path;
if (screenshots.thumbnails === void 0)
screenshots.thumbnails = default_values_1.DEFAULT_SCREENSHOT_THUMBNAILS;
}
_ensureSkipJsOptions() {
const option = this._ensureOption(option_names_1.default.skipJsErrors, void 0, option_source_1.default.Configuration);
if (option.value === void 0)
option.value = !!option.value;
}
_prepareReporters() {
const reporterOption = this._options[option_names_1.default.reporter];
if (!reporterOption)
return;
const optionValue = (0, lodash_1.castArray)(reporterOption.value);
reporterOption.value = (0, prepare_reporters_1.default)(optionValue);
}
async _prepareSslOptions() {
const sslOptions = this._options[option_names_1.default.ssl];
if (!sslOptions)
return;
sslOptions.value = await (0, get_options_1.getSSLOptions)(sslOptions.value);
}
_setDefaultValues() {
this._ensureOptionWithValue(option_names_1.default.selectorTimeout, default_values_1.DEFAULT_TIMEOUT.selector, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.assertionTimeout, default_values_1.DEFAULT_TIMEOUT.assertion, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.pageLoadTimeout, default_values_1.DEFAULT_TIMEOUT.pageLoad, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.speed, default_values_1.DEFAULT_SPEED_VALUE, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.appInitDelay, default_values_1.DEFAULT_APP_INIT_DELAY, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.concurrency, default_values_1.DEFAULT_CONCURRENCY_VALUE, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.src, default_values_1.DEFAULT_SOURCE_DIRECTORIES, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.developmentMode, default_values_1.DEFAULT_DEVELOPMENT_MODE, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.retryTestPages, default_values_1.DEFAULT_RETRY_TEST_PAGES, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.disableHttp2, default_values_1.DEFAULT_DISABLE_HTTP2, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.experimentalProxyless, default_values_1.DEFAULT_PROXYLESS, option_source_1.default.Configuration);
this._ensureOptionWithValue(option_names_1.default.disableCrossDomain, default_values_1.DEFAULT_DISABLE_CROSS_DOMAIN, option_source_1.default.Configuration);
this._ensureScreenshotOptions();
this._ensureSkipJsOptions();
}
_prepareCompilerOptions() {
const compilerOptions = this._ensureOption(option_names_1.default.compilerOptions, (0, default_values_1.getDefaultCompilerOptions)(), option_source_1.default.Configuration);
compilerOptions.value = compilerOptions.value || (0, default_values_1.getDefaultCompilerOptions)();
const tsConfigPath = this.getOption(option_names_1.default.tsConfigPath);
if (tsConfigPath) {
const compilerOptionValue = compilerOptions.value;
let typeScriptCompilerOptions = compilerOptionValue[customizable_compilers_1.default.typescript];
typeScriptCompilerOptions = Object.assign({
configPath: tsConfigPath,
}, typeScriptCompilerOptions);
compilerOptions.value[customizable_compilers_1.default.typescript] = typeScriptCompilerOptions;
}
}
async _getBrowserInfo() {
if (!this._options.browsers.value)
return [];
const browsers = Array.isArray(this._options.browsers.value) ? [...this._options.browsers.value] : [this._options.browsers.value];
const browserInfo = await Promise.all(browsers.map(browser => pool_1.default.getBrowserInfo(browser)));
return (0, lodash_1.flatten)(browserInfo);
}
async _isConfigurationFileExists(filePath = this.filePath) {
const fileExists = await super._isConfigurationFileExists(filePath);
if (!fileExists && this._isExplicitConfig)
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.cannotFindTestcafeConfigurationFile, filePath);
return fileExists;
}
static get FILENAMES() {
return CONFIGURATION_FILENAMES;
}
}
exports.default = TestCafeConfiguration;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdGNhZmUtY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWd1cmF0aW9uL3Rlc3RjYWZlLWNvbmZpZ3VyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4RUFBaUQ7QUFDakQsbUNBQTRDO0FBQzVDLHNEQUFxRTtBQUNyRSxrRUFBMEM7QUFDMUMsMkVBQWlEO0FBQ2pELG1GQUEwRDtBQUMxRCw0Q0FBK0U7QUFDL0UsK0VBQXNEO0FBQ3RELHVGQUFnRTtBQUNoRSx1R0FBNEU7QUFFNUUscURBYzBCO0FBRTFCLG9FQUEyQztBQVMzQyxzRkFBNkQ7QUFDN0QsNERBQWdGO0FBRWhGLG9FQUEyRDtBQUUzRCx1Q0FBcUQ7QUFDckQsK0NBQWlEO0FBQ2pELDJDQUFpRDtBQUNqRCw4REFBMkQ7QUFFM0QsTUFBTSwyQkFBMkIsR0FBRyxhQUFhLENBQUM7QUFDbEQsTUFBTSx1QkFBdUIsR0FBTyxrQ0FBd0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLDJCQUEyQixHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUM7QUFFaEgsTUFBTSw2QkFBNkIsR0FBRyxhQUFhLENBQUM7QUFFcEQsTUFBTSxpQkFBaUIsR0FBRztJQUN0QixzQkFBWSxDQUFDLFNBQVM7SUFDdEIsc0JBQVksQ0FBQyxXQUFXO0lBQ3hCLHNCQUFZLENBQUMsa0JBQWtCO0lBQy9CLHNCQUFZLENBQUMsZUFBZTtJQUM1QixzQkFBWSxDQUFDLHNCQUFzQjtJQUNuQyxzQkFBWSxDQUFDLGtCQUFrQjtJQUMvQixzQkFBWSxDQUFDLGtCQUFrQjtJQUMvQixzQkFBWSxDQUFDLGtCQUFrQjtJQUMvQixzQkFBWSxDQUFDLHNCQUFzQjtDQUN0QyxDQUFDO0FBRUYsTUFBTSxzQkFBc0IsR0FBRztJQUMzQixzQkFBWSxDQUFDLGVBQWU7SUFDNUIsc0JBQVksQ0FBQyxjQUFjO0lBQzNCLHNCQUFZLENBQUMsS0FB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QUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRWxJLE1BQU0sV0FBVyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsY0FBbUIsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTVHLE9BQU8sSUFBQSxnQkFBTyxFQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFUyxLQUFLLENBQUMsMEJBQTBCLENBQUUsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRO1FBQ2hFLE1BQU0sVUFBVSxHQUFHLE1BQU0sS0FBSyxDQUFDLDBCQUEwQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXBFLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLGlCQUFpQjtZQUNyQyxNQUFNLElBQUksc0JBQVksQ0FBQyxzQkFBYyxDQUFDLG1DQUFtQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBRXpGLE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFFTSxNQUFNLEtBQUssU0FBUztRQUN2QixPQUFPLHVCQUF1QixDQUFDO0lBQ25DLENBQUM7Q0FDSjtBQWpQRCx3Q0FpUEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ29uZmlndXJhdGlvbiBmcm9tICcuL2NvbmZpZ3VyYXRpb24tYmFzZSc7XG5pbXBvcnQgeyBjYXN0QXJyYXksIGZsYXR0ZW4gfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZ2V0R3JlcE9wdGlvbnMsIGdldFNTTE9wdGlvbnMgfSBmcm9tICcuLi91dGlscy9nZXQtb3B0aW9ucyc7XG5pbXBvcnQgT1BUSU9OX05BTUVTIGZyb20gJy4vb3B0aW9uLW5hbWVzJztcbmltcG9ydCBnZXRGaWx0ZXJGbiBmcm9tICcuLi91dGlscy9nZXQtZmlsdGVyLWZuJztcbmltcG9ydCBwcmVwYXJlUmVwb3J0ZXJzIGZyb20gJy4uL3V0aWxzL3ByZXBhcmUtcmVwb3J0ZXJzJztcbmltcG9ydCB7IGdldENvbmNhdGVuYXRlZFZhbHVlc1N0cmluZywgZ2V0UGx1cmFsU3VmZml4IH0gZnJvbSAnLi4vdXRpbHMvc3RyaW5nJztcbmltcG9ydCByZW5kZXJUZW1wbGF0ZSBmcm9tICcuLi91dGlscy9yZW5kZXItdGVtcGxhdGUnO1xuaW1wb3J0IFdBUk5JTkdfTUVTU0FHRVMgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuaW1wb3J0IHJlc29sdmVQYXRoUmVsYXRpdmVseUN3ZCBmcm9tICcuLi91dGlscy9yZXNvbHZlLXBhdGgtcmVsYXRpdmVseS1jd2QnO1xuXG5pbXBvcnQge1xuICAgIERFRkFVTFRfQVBQX0lOSVRfREVMQVksXG4gICAgREVGQVVMVF9DT05DVVJSRU5DWV9WQUxVRSxcbiAgICBERUZBVUxUX0RFVkVMT1BNRU5UX01PREUsXG4gICAgREVGQVVMVF9ESVNBQkxFX0NST1NTX0RPTUFJTixcbiAgICBERUZBVUxUX0RJU0FCTEVfSFRUUDIsXG4gICAgREVGQVVMVF9GSUxURVJfRk4sXG4gICAgREVGQVVMVF9QUk9YWUxFU1MsXG4gICAgREVGQVVMVF9SRVRSWV9URVNUX1BBR0VTLFxuICAgIERFRkFVTFRfU0NSRUVOU0hPVF9USFVNQk5BSUxTLFxuICAgIERFRkFVTFRfU09VUkNFX0RJUkVDVE9SSUVTLFxuICAgIERFRkFVTFRfU1BFRURfVkFMVUUsXG4gICAgREVGQVVMVF9USU1FT1VULFxuICAgIGdldERlZmF1bHRDb21waWxlck9wdGlvbnMsXG59IGZyb20gJy4vZGVmYXVsdC12YWx1ZXMnO1xuXG5pbXBvcnQgT3B0aW9uU291cmNlIGZyb20gJy4vb3B0aW9uLXNvdXJjZSc7XG5cbmltcG9ydCB7XG4gICAgRGljdGlvbmFyeSxcbiAgICBGaWx0ZXJPcHRpb24sXG4gICAgUmVwb3J0ZXJPcHRpb24sXG4gICAgVHlwZVNjcmlwdENvbXBpbGVyT3B0aW9ucyxcbn0gZnJvbSAnLi9pbnRlcmZhY2VzJztcblxuaW1wb3J0IEN1c3RvbWl6YWJsZUNvbXBpbGVycyBmcm9tICcuL2N1c3RvbWl6YWJsZS1jb21waWxlcnMnO1xuaW1wb3J0IHsgREVQUkVDQVRFRCwgZ2V0RGVwcmVjYXRpb25NZXNzYWdlIH0gZnJvbSAnLi4vbm90aWZpY2F0aW9ucy9kZXByZWNhdGVkJztcbmltcG9ydCBXYXJuaW5nTG9nIGZyb20gJy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1sb2cnO1xuaW1wb3J0IGJyb3dzZXJQcm92aWRlclBvb2wgZnJvbSAnLi4vYnJvd3Nlci9wcm92aWRlci9wb29sJztcbmltcG9ydCBCcm93c2VyQ29ubmVjdGlvbiwgeyBCcm93c2VySW5mbyB9IGZyb20gJy4uL2Jyb3dzZXIvY29ubmVjdGlvbic7XG5pbXBvcnQgeyBDT05GSUdVUkFUSU9OX0VYVEVOU0lPTlMgfSBmcm9tICcuL2Zvcm1hdHMnO1xuaW1wb3J0IHsgR2VuZXJhbEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHsgUlVOVElNRV9FUlJPUlMgfSBmcm9tICcuLi9lcnJvcnMvdHlwZXMnO1xuaW1wb3J0IHsgTE9DQUxIT1NUX05BTUVTIH0gZnJvbSAnLi4vdXRpbHMvbG9jYWxob3N0LW5hbWVzJztcblxuY29uc3QgQkFTRV9DT05GSUdVUkFUSU9OX0ZJTEVOQU1FID0gJy50ZXN0Y2FmZXJjJztcbmNvbnN0IENPTkZJR1VSQVRJT05fRklMRU5BTUVTICAgICA9IENPTkZJR1VSQVRJT05fRVhURU5TSU9OUy5tYXAoZXh0ID0+IGAke0JBU0VfQ09ORklHVVJBVElPTl9GSUxFTkFNRX0ke2V4dH1gKTtcblxuY29uc3QgREVGQVVMVF9TQ1JFRU5TSE9UU19ESVJFQ1RPUlkgPSAnc2NyZWVuc2hvdHMnO1xuXG5jb25zdCBPUFRJT05fRkxBR19OQU1FUyA9IFtcbiAgICBPUFRJT05fTkFNRVMuZGVidWdNb2RlLFxuICAgIE9QVElPTl9OQU1FUy5kZWJ1Z09uRmFpbCxcbiAgICBPUFRJT05fTkFNRVMuc2tpcFVuY2F1Z2h0RXJyb3JzLFxuICAgIE9QVElPTl9OQU1FUy5zdG9wT25GaXJzdEZhaWwsXG4gICAgT1BUSU9OX05BTUVTLnRha2VTY3JlZW5zaG90c09uRmFpbHMsXG4gICAgT1BUSU9OX05BTUVTLmRpc2FibGVQYWdlQ2FjaGluZyxcbiAgICBPUFRJT05fTkFNRVMuZGlzYWJsZVBhZ2VSZWxvYWRzLFxuICAgIE9QVElPTl9OQU1FUy5kaXNhYmxlU2NyZWVuc2hvdHMsXG4gICAgT1BUSU9OX05BTUVTLmRpc2FibGVNdWx0aXBsZVdpbmRvd3MsXG5dO1xuXG5jb25zdCBPUFRJT05fSU5JVF9GTEFHX05BTUVTID0gW1xuICAgIE9QVElPTl9OQU1FUy5kZXZlbG9wbWVudE1vZGUsXG4gICAgT1BUSU9OX05BTUVTLnJldHJ5VGVzdFBhZ2VzLFxuICAgIE9QVElPTl9OQU1FUy5jYWNoZSxcbiAgICBPUFRJT05fTkFNRVMuZGlzYWJsZUh0dHAyLFxuICAgIE9QVElPTl9OQU1FUy5leHBlcmltZW50YWxQcm94eWxlc3MsXG4gICAgT1BUSU9OX05BTUVTLmRpc2FibGVDcm9zc0RvbWFpbixcbl07XG5cbmludGVyZmFjZSBUZXN0Q2FmZUFkZGl0aW9uYWxTdGFydE9wdGlvbnMge1xuICAgIHJldHJ5VGVzdFBhZ2VzOiBib29sZWFuO1xuICAgIHNzbDogc3RyaW5nO1xuICAgIGRldmVsb3BtZW50TW9kZTogYm9vbGVhbjtcbiAgICBjYWNoZTogYm9vbGVhbjtcbiAgICBkaXNhYmxlSHR0cDI6IGJvb2xlYW47XG4gICAgcHJveHlsZXNzOiBib29sZWFuO1xuICAgIGRpc2FibGVDcm9zc0RvbWFpbjogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIFRlc3RDYWZlU3RhcnRPcHRpb25zIHtcbiAgICBob3N0bmFtZT86IHN0cmluZztcbiAgICBwb3J0MT86IG51bWJlcjtcbiAgICBwb3J0Mj86IG51bWJlcjtcbiAgICBvcHRpb25zOiBUZXN0Q2FmZUFkZGl0aW9uYWxTdGFydE9wdGlvbnM7XG59XG5cbnR5cGUgQnJvd3NlckluZm9Tb3VyY2UgPSBCcm93c2VySW5mbyB8IEJyb3dzZXJDb25uZWN0aW9uO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0Q2FmZUNvbmZpZ3VyYXRpb24gZXh0ZW5kcyBDb25maWd1cmF0aW9uIHtcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2lzRXhwbGljaXRDb25maWc6IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKGNvbmZpZ0ZpbGUgPSAnJykge1xuICAgICAgICBzdXBlcihjb25maWdGaWxlIHx8IENPTkZJR1VSQVRJT05fRklMRU5BTUVTKTtcblxuICAgICAgICB0aGlzLl9pc0V4cGxpY2l0Q29uZmlnID0gISFjb25maWdGaWxlO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBpbml0IChvcHRpb25zPzogRGljdGlvbmFyeTxvYmplY3Q+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IHN1cGVyLmluaXQoKTtcblxuICAgICAgICBjb25zdCBvcHRzID0gYXdhaXQgdGhpcy5fbG9hZCgpO1xuXG4gICAgICAgIHRoaXMuX2NoZWNrVW5zZWN1cmVEYXRhSW5KU09OQ29uZmlndXJhdGlvbihvcHRzKTtcblxuICAgICAgICBpZiAob3B0cykge1xuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IENvbmZpZ3VyYXRpb24uX2Zyb21PYmoob3B0cyk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX25vcm1hbGl6ZU9wdGlvbnNBZnRlckxvYWQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMuYXN5bmNNZXJnZU9wdGlvbnMob3B0aW9ucyk7XG5cbiAgICAgICAgY29uc3QgcHJveHlsZXNzID0gdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLmV4cGVyaW1lbnRhbFByb3h5bGVzcyk7XG5cbiAgICAgICAgaWYgKHByb3h5bGVzcylcbiAgICAgICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMuaG9zdG5hbWUsIExPQ0FMSE9TVF9OQU1FUy5MT0NBTEhPU1QsIE9wdGlvblNvdXJjZS5JbnB1dCk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGFzeW5jTWVyZ2VPcHRpb25zIChvcHRpb25zPzogRGljdGlvbmFyeTxvYmplY3Q+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgICAgIHN1cGVyLm1lcmdlT3B0aW9ucyhvcHRpb25zKTtcblxuICAgICAgICBpZiAoIW9wdGlvbnMuaXNDbGkgJiYgdGhpcy5fb3B0aW9ucy5icm93c2VycylcbiAgICAgICAgICAgIHRoaXMuX29wdGlvbnMuYnJvd3NlcnMudmFsdWUgPSBhd2FpdCB0aGlzLl9nZXRCcm93c2VySW5mbygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBwcmVwYXJlICgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fcHJlcGFyZUZsYWdzKCk7XG4gICAgICAgIHRoaXMuX3NldERlZmF1bHRWYWx1ZXMoKTtcbiAgICAgICAgdGhpcy5fcHJlcGFyZUNvbXBpbGVyT3B0aW9ucygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBub3RpZnlBYm91dE92ZXJyaWRkZW5PcHRpb25zICh3YXJuaW5nTG9nPzogV2FybmluZ0xvZyk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuX292ZXJyaWRkZW5PcHRpb25zLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBvcHRpb25zU3RyICAgID0gZ2V0Q29uY2F0ZW5hdGVkVmFsdWVzU3RyaW5nKHRoaXMuX292ZXJyaWRkZW5PcHRpb25zKTtcbiAgICAgICAgY29uc3Qgb3B0aW9uc1N1ZmZpeCA9IGdldFBsdXJhbFN1ZmZpeCh0aGlzLl9vdmVycmlkZGVuT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTWVzc2FnZSA9IHJlbmRlclRlbXBsYXRlKFdBUk5JTkdfTUVTU0FHRVMuY29uZmlnT3B0aW9uc1dlcmVPdmVycmlkZGVuLCBvcHRpb25zU3RyLCBvcHRpb25zU3VmZml4KTtcblxuICAgICAgICBDb25maWd1cmF0aW9uLl9zaG93Q29uc29sZVdhcm5pbmcocmVuZGVyZWRNZXNzYWdlKTtcblxuICAgICAgICBpZiAod2FybmluZ0xvZylcbiAgICAgICAgICAgIHdhcm5pbmdMb2cuYWRkV2FybmluZyhyZW5kZXJlZE1lc3NhZ2UpO1xuXG4gICAgICAgIHRoaXMuX292ZXJyaWRkZW5PcHRpb25zID0gW107XG4gICAgfVxuXG4gICAgcHVibGljIG5vdGlmeUFib3V0RGVwcmVjYXRlZE9wdGlvbnMgKHdhcm5pbmdMb2c6IFdhcm5pbmdMb2cpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGVwcmVjYXRlZE9wdGlvbnMgPSB0aGlzLmdldE9wdGlvbnMoKG5hbWUsIG9wdGlvbikgPT4gbmFtZSBpbiBERVBSRUNBVEVEICYmIG9wdGlvbi52YWx1ZSAhPT0gdm9pZCAwKTtcblxuICAgICAgICBmb3IgKGNvbnN0IG9wdGlvbk5hbWUgaW4gZGVwcmVjYXRlZE9wdGlvbnMpXG4gICAgICAgICAgICB3YXJuaW5nTG9nLmFkZFdhcm5pbmcoZ2V0RGVwcmVjYXRpb25NZXNzYWdlKERFUFJFQ0FURURbb3B0aW9uTmFtZV0pKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IHN0YXJ0T3B0aW9ucyAoKTogVGVzdENhZmVTdGFydE9wdGlvbnMge1xuICAgICAgICBjb25zdCBwcm94eWxlc3MgPSB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuZXhwZXJpbWVudGFsUHJveHlsZXNzKSBhcyBib29sZWFuO1xuICAgICAgICBsZXQgaG9zdG5hbWUgICAgPSB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuaG9zdG5hbWUpIGFzIHN0cmluZztcblxuICAgICAgICBpZiAoIWhvc3RuYW1lICYmIHByb3h5bGVzcylcbiAgICAgICAgICAgIGhvc3RuYW1lID0gTE9DQUxIT1NUX05BTUVTLkxPQ0FMSE9TVDtcblxuICAgICAgICBjb25zdCByZXN1bHQ6IFRlc3RDYWZlU3RhcnRPcHRpb25zID0ge1xuICAgICAgICAgICAgaG9zdG5hbWUsXG4gICAgICAgICAgICBwb3J0MTogdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnBvcnQxKSBhcyBudW1iZXIsXG4gICAgICAgICAgICBwb3J0MjogdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnBvcnQyKSBhcyBudW1iZXIsXG5cbiAgICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgICBzc2w6ICAgICAgICAgICAgICAgIHRoaXMuZ2V0T3B0aW9uKE9QVElPTl9OQU1FUy5zc2wpIGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICBkZXZlbG9wbWVudE1vZGU6ICAgIHRoaXMuZ2V0T3B0aW9uKE9QVElPTl9OQU1FUy5kZXZlbG9wbWVudE1vZGUpIGFzIGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgcmV0cnlUZXN0UGFnZXM6ICAgICB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMucmV0cnlUZXN0UGFnZXMpIGFzIGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgY2FjaGU6ICAgICAgICAgICAgICB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuY2FjaGUpIGFzIGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgZGlzYWJsZUh0dHAyOiAgICAgICB0aGlzLmdldE9wdGlvbihPUFRJT05fTkFNRVMuZGlzYWJsZUh0dHAyKSBhcyBib29sZWFuLFxuICAgICAgICAgICAgICAgIGRpc2FibGVDcm9zc0RvbWFpbjogdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLmRpc2FibGVDcm9zc0RvbWFpbikgYXMgYm9vbGVhbixcbiAgICAgICAgICAgICAgICBwcm94eWxlc3MsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfY2hlY2tVbnNlY3VyZURhdGFJbkpTT05Db25maWd1cmF0aW9uIChvcHRzOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLl9pc0pTT05Db25maWd1cmF0aW9uKCkpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgaWYgKG9wdHM/LltPUFRJT05fTkFNRVMuZGFzaGJvYXJkXT8udG9rZW4pXG4gICAgICAgICAgICB0aHJvdyBuZXcgR2VuZXJhbEVycm9yKFJVTlRJTUVfRVJST1JTLmRhc2hib2FyZFRva2VuSW5KU09OKTtcbiAgICB9XG4gICAgcHJpdmF0ZSBfcHJlcGFyZUZsYWcgKG5hbWU6IHN0cmluZywgc291cmNlID0gT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5fZW5zdXJlT3B0aW9uKG5hbWUsIHZvaWQgMCwgc291cmNlKTtcblxuICAgICAgICBvcHRpb24udmFsdWUgPSAhIW9wdGlvbi52YWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wcmVwYXJlRmxhZ3MgKCk6IHZvaWQge1xuICAgICAgICBPUFRJT05fRkxBR19OQU1FUy5mb3JFYWNoKG5hbWUgPT4gdGhpcy5fcHJlcGFyZUZsYWcobmFtZSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3ByZXBhcmVJbml0RmxhZ3MgKCk6IHZvaWQge1xuICAgICAgICBPUFRJT05fSU5JVF9GTEFHX05BTUVTLmZvckVhY2gobmFtZSA9PiB0aGlzLl9wcmVwYXJlRmxhZyhuYW1lLCBPcHRpb25Tb3VyY2UuRGVmYXVsdCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX25vcm1hbGl6ZU9wdGlvbnNBZnRlckxvYWQgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLl9wcmVwYXJlU3NsT3B0aW9ucygpO1xuICAgICAgICB0aGlzLl9wcmVwYXJlSW5pdEZsYWdzKCk7XG4gICAgICAgIHRoaXMuX3ByZXBhcmVGaWx0ZXJGbigpO1xuICAgICAgICB0aGlzLl9lbnN1cmVBcnJheU9wdGlvbihPUFRJT05fTkFNRVMuc3JjKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlQXJyYXlPcHRpb24oT1BUSU9OX05BTUVTLmJyb3dzZXJzKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlQXJyYXlPcHRpb24oT1BUSU9OX05BTUVTLmNsaWVudFNjcmlwdHMpO1xuICAgICAgICB0aGlzLl9wcmVwYXJlUmVwb3J0ZXJzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcHJlcGFyZUZpbHRlckZuICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmlsdGVyT3B0aW9uID0gdGhpcy5fZW5zdXJlT3B0aW9uKE9QVElPTl9OQU1FUy5maWx0ZXIsIERFRkFVTFRfRklMVEVSX0ZOLCBPcHRpb25Tb3VyY2UuRGVmYXVsdCk7XG5cbiAgICAgICAgaWYgKCFmaWx0ZXJPcHRpb24udmFsdWUpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3QgZmlsdGVyT3B0aW9uVmFsdWUgPSBmaWx0ZXJPcHRpb24udmFsdWUgYXMgRmlsdGVyT3B0aW9uO1xuXG4gICAgICAgIGlmIChmaWx0ZXJPcHRpb25WYWx1ZS50ZXN0R3JlcClcbiAgICAgICAgICAgIGZpbHRlck9wdGlvblZhbHVlLnRlc3RHcmVwID0gZ2V0R3JlcE9wdGlvbnMoT1BUSU9OX05BTUVTLmZpbHRlclRlc3RHcmVwLCBmaWx0ZXJPcHRpb25WYWx1ZS50ZXN0R3JlcCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGlmIChmaWx0ZXJPcHRpb25WYWx1ZS5maXh0dXJlR3JlcClcbiAgICAgICAgICAgIGZpbHRlck9wdGlvblZhbHVlLmZpeHR1cmVHcmVwID0gZ2V0R3JlcE9wdGlvbnMoT1BUSU9OX05BTUVTLmZpbHRlckZpeHR1cmVHcmVwLCBmaWx0ZXJPcHRpb25WYWx1ZS5maXh0dXJlR3JlcCBhcyBzdHJpbmcpO1xuXG4gICAgICAgIGZpbHRlck9wdGlvbi52YWx1ZSAgPSBnZXRGaWx0ZXJGbihmaWx0ZXJPcHRpb24udmFsdWUpIGFzIEZ1bmN0aW9uO1xuICAgICAgICBmaWx0ZXJPcHRpb24uc291cmNlID0gT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb247XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZW5zdXJlU2NyZWVuc2hvdE9wdGlvbnMgKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBwYXRoICAgICAgICA9IHJlc29sdmVQYXRoUmVsYXRpdmVseUN3ZChERUZBVUxUX1NDUkVFTlNIT1RTX0RJUkVDVE9SWSk7XG4gICAgICAgIGNvbnN0IHNjcmVlbnNob3RzID0gdGhpcy5fZW5zdXJlT3B0aW9uKE9QVElPTl9OQU1FUy5zY3JlZW5zaG90cywge30sIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKS52YWx1ZSBhcyBEaWN0aW9uYXJ5PHN0cmluZ3xib29sZWFuPjtcblxuICAgICAgICBpZiAoIXNjcmVlbnNob3RzLnBhdGgpXG4gICAgICAgICAgICBzY3JlZW5zaG90cy5wYXRoID0gcGF0aDtcblxuICAgICAgICBpZiAoc2NyZWVuc2hvdHMudGh1bWJuYWlscyA9PT0gdm9pZCAwKVxuICAgICAgICAgICAgc2NyZWVuc2hvdHMudGh1bWJuYWlscyA9IERFRkFVTFRfU0NSRUVOU0hPVF9USFVNQk5BSUxTO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2Vuc3VyZVNraXBKc09wdGlvbnMgKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLl9lbnN1cmVPcHRpb24oT1BUSU9OX05BTUVTLnNraXBKc0Vycm9ycywgdm9pZCAwLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG5cbiAgICAgICAgaWYgKG9wdGlvbi52YWx1ZSA9PT0gdm9pZCAwKVxuICAgICAgICAgICAgb3B0aW9uLnZhbHVlID0gISFvcHRpb24udmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcHJlcGFyZVJlcG9ydGVycyAoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHJlcG9ydGVyT3B0aW9uID0gdGhpcy5fb3B0aW9uc1tPUFRJT05fTkFNRVMucmVwb3J0ZXJdO1xuXG4gICAgICAgIGlmICghcmVwb3J0ZXJPcHRpb24pXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY29uc3Qgb3B0aW9uVmFsdWUgPSBjYXN0QXJyYXkocmVwb3J0ZXJPcHRpb24udmFsdWUgYXMgUmVwb3J0ZXJPcHRpb24pO1xuXG4gICAgICAgIHJlcG9ydGVyT3B0aW9uLnZhbHVlID0gcHJlcGFyZVJlcG9ydGVycyhvcHRpb25WYWx1ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfcHJlcGFyZVNzbE9wdGlvbnMgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBzc2xPcHRpb25zID0gdGhpcy5fb3B0aW9uc1tPUFRJT05fTkFNRVMuc3NsXTtcblxuICAgICAgICBpZiAoIXNzbE9wdGlvbnMpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgc3NsT3B0aW9ucy52YWx1ZSA9IGF3YWl0IGdldFNTTE9wdGlvbnMoc3NsT3B0aW9ucy52YWx1ZSBhcyBzdHJpbmcpIGFzIERpY3Rpb25hcnk8c3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlcj47XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2V0RGVmYXVsdFZhbHVlcyAoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMuc2VsZWN0b3JUaW1lb3V0LCBERUZBVUxUX1RJTUVPVVQuc2VsZWN0b3IsIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5hc3NlcnRpb25UaW1lb3V0LCBERUZBVUxUX1RJTUVPVVQuYXNzZXJ0aW9uLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMucGFnZUxvYWRUaW1lb3V0LCBERUZBVUxUX1RJTUVPVVQucGFnZUxvYWQsIE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKTtcbiAgICAgICAgdGhpcy5fZW5zdXJlT3B0aW9uV2l0aFZhbHVlKE9QVElPTl9OQU1FUy5zcGVlZCwgREVGQVVMVF9TUEVFRF9WQUxVRSwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLmFwcEluaXREZWxheSwgREVGQVVMVF9BUFBfSU5JVF9ERUxBWSwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLmNvbmN1cnJlbmN5LCBERUZBVUxUX0NPTkNVUlJFTkNZX1ZBTFVFLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMuc3JjLCBERUZBVUxUX1NPVVJDRV9ESVJFQ1RPUklFUywgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLmRldmVsb3BtZW50TW9kZSwgREVGQVVMVF9ERVZFTE9QTUVOVF9NT0RFLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMucmV0cnlUZXN0UGFnZXMsIERFRkFVTFRfUkVUUllfVEVTVF9QQUdFUywgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLmRpc2FibGVIdHRwMiwgREVGQVVMVF9ESVNBQkxFX0hUVFAyLCBPcHRpb25Tb3VyY2UuQ29uZmlndXJhdGlvbik7XG4gICAgICAgIHRoaXMuX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZShPUFRJT05fTkFNRVMuZXhwZXJpbWVudGFsUHJveHlsZXNzLCBERUZBVUxUX1BST1hZTEVTUywgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuICAgICAgICB0aGlzLl9lbnN1cmVPcHRpb25XaXRoVmFsdWUoT1BUSU9OX05BTUVTLmRpc2FibGVDcm9zc0RvbWFpbiwgREVGQVVMVF9ESVNBQkxFX0NST1NTX0RPTUFJTiwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuXG4gICAgICAgIHRoaXMuX2Vuc3VyZVNjcmVlbnNob3RPcHRpb25zKCk7XG4gICAgICAgIHRoaXMuX2Vuc3VyZVNraXBKc09wdGlvbnMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wcmVwYXJlQ29tcGlsZXJPcHRpb25zICgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29tcGlsZXJPcHRpb25zID0gdGhpcy5fZW5zdXJlT3B0aW9uKE9QVElPTl9OQU1FUy5jb21waWxlck9wdGlvbnMsIGdldERlZmF1bHRDb21waWxlck9wdGlvbnMoKSwgT3B0aW9uU291cmNlLkNvbmZpZ3VyYXRpb24pO1xuXG4gICAgICAgIGNvbXBpbGVyT3B0aW9ucy52YWx1ZSA9IGNvbXBpbGVyT3B0aW9ucy52YWx1ZSB8fCBnZXREZWZhdWx0Q29tcGlsZXJPcHRpb25zKCk7XG5cbiAgICAgICAgY29uc3QgdHNDb25maWdQYXRoID0gdGhpcy5nZXRPcHRpb24oT1BUSU9OX05BTUVTLnRzQ29uZmlnUGF0aCk7XG5cbiAgICAgICAgaWYgKHRzQ29uZmlnUGF0aCkge1xuICAgICAgICAgICAgY29uc3QgY29tcGlsZXJPcHRpb25WYWx1ZSAgICAgPSBjb21waWxlck9wdGlvbnMudmFsdWUgYXMgQ29tcGlsZXJPcHRpb25zO1xuICAgICAgICAgICAgbGV0IHR5cGVTY3JpcHRDb21waWxlck9wdGlvbnMgPSBjb21waWxlck9wdGlvblZhbHVlW0N1c3RvbWl6YWJsZUNvbXBpbGVycy50eXBlc2NyaXB0XSBhcyBUeXBlU2NyaXB0Q29tcGlsZXJPcHRpb25zO1xuXG4gICAgICAgICAgICB0eXBlU2NyaXB0Q29tcGlsZXJPcHRpb25zID0gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICAgICAgY29uZmlnUGF0aDogdHNDb25maWdQYXRoLFxuICAgICAgICAgICAgfSwgdHlwZVNjcmlwdENvbXBpbGVyT3B0aW9ucyk7XG5cbiAgICAgICAgICAgIChjb21waWxlck9wdGlvbnMudmFsdWUgYXMgQ29tcGlsZXJPcHRpb25zKVtDdXN0b21pemFibGVDb21waWxlcnMudHlwZXNjcmlwdF0gPSB0eXBlU2NyaXB0Q29tcGlsZXJPcHRpb25zO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfZ2V0QnJvd3NlckluZm8gKCk6IFByb21pc2U8QnJvd3NlckluZm9Tb3VyY2VbXT4ge1xuICAgICAgICBpZiAoIXRoaXMuX29wdGlvbnMuYnJvd3NlcnMudmFsdWUpXG4gICAgICAgICAgICByZXR1cm4gW107XG5cbiAgICAgICAgY29uc3QgYnJvd3NlcnMgPSBBcnJheS5pc0FycmF5KHRoaXMuX29wdGlvbnMuYnJvd3NlcnMudmFsdWUpID8gWy4uLnRoaXMuX29wdGlvbnMuYnJvd3NlcnMudmFsdWVdIDogW3RoaXMuX29wdGlvbnMuYnJvd3NlcnMudmFsdWVdO1xuXG4gICAgICAgIGNvbnN0IGJyb3dzZXJJbmZvID0gYXdhaXQgUHJvbWlzZS5hbGwoYnJvd3NlcnMubWFwKGJyb3dzZXIgPT4gYnJvd3NlclByb3ZpZGVyUG9vbC5nZXRCcm93c2VySW5mbyhicm93c2VyKSkpO1xuXG4gICAgICAgIHJldHVybiBmbGF0dGVuKGJyb3dzZXJJbmZvKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgX2lzQ29uZmlndXJhdGlvbkZpbGVFeGlzdHMgKGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICBjb25zdCBmaWxlRXhpc3RzID0gYXdhaXQgc3VwZXIuX2lzQ29uZmlndXJhdGlvbkZpbGVFeGlzdHMoZmlsZVBhdGgpO1xuXG4gICAgICAgIGlmICghZmlsZUV4aXN0cyAmJiB0aGlzLl9pc0V4cGxpY2l0Q29uZmlnKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEdlbmVyYWxFcnJvcihSVU5USU1FX0VSUk9SUy5jYW5ub3RGaW5kVGVzdGNhZmVDb25maWd1cmF0aW9uRmlsZSwgZmlsZVBhdGgpO1xuXG4gICAgICAgIHJldHVybiBmaWxlRXhpc3RzO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0IEZJTEVOQU1FUyAoKTogc3RyaW5nW10ge1xuICAgICAgICByZXR1cm4gQ09ORklHVVJBVElPTl9GSUxFTkFNRVM7XG4gICAgfVxufVxuIl19