"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = require("path"); const debug_1 = __importDefault(require("debug")); const json5_1 = __importDefault(require("json5")); const lodash_1 = require("lodash"); const promisified_functions_1 = require("../utils/promisified-functions"); const option_1 = __importDefault(require("./option")); const option_source_1 = __importDefault(require("./option-source")); const resolve_path_relatively_cwd_1 = __importDefault(require("../utils/resolve-path-relatively-cwd")); const render_template_1 = __importDefault(require("../utils/render-template")); const warning_message_1 = __importDefault(require("../notifications/warning-message")); const log_1 = __importDefault(require("../cli/log")); const formats_1 = require("./formats"); const DEBUG_LOGGER = (0, debug_1.default)('testcafe:configuration'); class Configuration { constructor(configurationFilesNames) { var _a; this._options = {}; this._defaultPaths = this._resolveFilePaths(configurationFilesNames); this._filePath = (_a = this._defaultPaths) === null || _a === void 0 ? void 0 : _a[0]; this._overriddenOptions = []; } static _fromObj(obj) { const result = Object.create(null); Object.entries(obj).forEach(([key, value]) => { result[key] = new option_1.default(key, value); }); return result; } static _showConsoleWarning(message) { log_1.default.write(message); } static _showWarningForError(error, warningTemplate, ...args) { const message = (0, render_template_1.default)(warningTemplate, ...args); Configuration._showConsoleWarning(message); DEBUG_LOGGER(message); DEBUG_LOGGER(error); } static _resolveFilePath(path) { if (!path) return null; return (0, path_1.isAbsolute)(path) ? path : (0, resolve_path_relatively_cwd_1.default)(path); } _resolveFilePaths(filesNames) { if (!filesNames) return void 0; return (0, lodash_1.castArray)(filesNames).reduce((result, name) => { const resolveFilePath = Configuration._resolveFilePath(name); if (resolveFilePath) result.push(resolveFilePath); return result; }, []); } async init() { this._overriddenOptions = []; } mergeOptions(options) { Object.entries(options).map(([key, value]) => { const option = this._ensureOption(key, value, option_source_1.default.Input); if (value === void 0) return; this._setOptionValue(option, value); }); } mergeDeep(option, source) { (0, lodash_1.mergeWith)(option.value, source, (targetValue, sourceValue, property) => { this._addOverriddenOptionIfNecessary(targetValue, sourceValue, option.source, `${option.name}.${property}`); return sourceValue !== void 0 ? sourceValue : targetValue; }); } getOption(key) { if (!key) return void 0; const option = this._options[key]; if (!option) return void 0; return option.value; } getOptions(predicate) { const result = Object.create(null); let includeInResult = true; Object.entries(this._options).forEach(([name, option]) => { includeInResult = predicate ? predicate(name, option) : true; if (includeInResult) result[name] = option.value; }); return result; } clone(nonClonedOptions) { const configuration = (0, lodash_1.cloneDeep)(this); if (nonClonedOptions) { (0, lodash_1.castArray)(nonClonedOptions).forEach(key => { if (configuration._options[key]) configuration._options[key].value = this._options[key].value; }); } return configuration; } get filePath() { return this._filePath; } get defaultPaths() { return this._defaultPaths; } async _load() { var _a; if (!((_a = this.defaultPaths) === null || _a === void 0 ? void 0 : _a.length)) return null; const configs = await Promise.all(this.defaultPaths.map(async (filePath) => { if (!await this._isConfigurationFileExists(filePath)) return { filePath, options: null }; let options = null; if (this._isJSConfiguration(filePath)) options = this._readJsConfigurationFileContent(filePath); else { const configurationFileContent = await this._readConfigurationFileContent(filePath); if (configurationFileContent) options = this._parseConfigurationFileContent(configurationFileContent, filePath); } return { filePath, options }; })); const existedConfigs = configs.filter(config => !!config.options); if (!existedConfigs.length) return null; this._filePath = existedConfigs[0].filePath; if (existedConfigs.length > 1) Configuration._showConsoleWarning((0, render_template_1.default)(warning_message_1.default.multipleConfigurationFilesFound, this._filePath)); return existedConfigs[0].options; } async _isConfigurationFileExists(filePath = this.filePath) { try { await (0, promisified_functions_1.stat)(filePath); return true; } catch (error) { DEBUG_LOGGER((0, render_template_1.default)(warning_message_1.default.cannotFindConfigurationFile, filePath, error.stack)); return false; } } static _hasExtention(filePath, extention) { return !!filePath && (0, path_1.extname)(filePath) === extention; } _isJSConfiguration(filePath = this.filePath) { return Configuration._hasExtention(filePath, formats_1.JS_CONFIGURATION_EXTENSION); } _isJSONConfiguration(filePath = this.filePath) { return Configuration._hasExtention(filePath, formats_1.JSON_CONFIGURATION_EXTENSION); } _readJsConfigurationFileContent(filePath = this.filePath) { if (filePath) { try { delete require.cache[filePath]; return require(filePath); } catch (error) { Configuration._showWarningForError(error, warning_message_1.default.cannotReadConfigFile, filePath); } } return null; } async _readConfigurationFileContent(filePath = this.filePath) { try { return await (0, promisified_functions_1.readFile)(filePath); } catch (error) { Configuration._showWarningForError(error, warning_message_1.default.cannotReadConfigFile, filePath); } return null; } _parseConfigurationFileContent(configurationFileContent, filePath = this.filePath) { try { return json5_1.default.parse(configurationFileContent.toString()); } catch (error) { Configuration._showWarningForError(error, warning_message_1.default.cannotParseConfigFile, filePath); } return null; } _ensureArrayOption(name) { const options = this._options[name]; if (!options) return; // NOTE: a hack to fix lodash type definitions // @ts-ignore options.value = (0, lodash_1.castArray)(options.value); } _ensureOption(name, value, source) { let option = null; if (name in this._options) option = this._options[name]; else { option = new option_1.default(name, value, source); this._options[name] = option; } return option; } _ensureOptionWithValue(name, defaultValue, source) { const option = this._ensureOption(name, defaultValue, source); if (option.value !== void 0) return; option.value = defaultValue; option.source = source; } _addOverriddenOptionIfNecessary(value1, value2, source, optionName) { if (source === option_source_1.default.Default) return; if (value1 === void 0 || value2 === void 0 || value1 === value2 || source !== option_source_1.default.Configuration) return; this._overriddenOptions.push(optionName); } _setOptionValue(option, value) { if ((0, lodash_1.isPlainObject)(option.value) && (0, lodash_1.isPlainObject)(value)) this.mergeDeep(option, value); else { this._addOverriddenOptionIfNecessary(option.value, value, option.source, option.name); option.value = value; } option.source = option_source_1.default.Input; } } exports.default = Configuration; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi1iYXNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZ3VyYXRpb24vY29uZmlndXJhdGlvbi1iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQTJDO0FBQzNDLGtEQUEwQjtBQUMxQixrREFBMEI7QUFFMUIsbUNBS2dCO0FBRWhCLDBFQUFnRTtBQUNoRSxzREFBOEI7QUFDOUIsb0VBQTJDO0FBQzNDLHVHQUE0RTtBQUM1RSwrRUFBc0Q7QUFDdEQsdUZBQWdFO0FBQ2hFLHFEQUE2QjtBQUU3Qix1Q0FBcUY7QUFFckYsTUFBTSxZQUFZLEdBQUcsSUFBQSxlQUFLLEVBQUMsd0JBQXdCLENBQUMsQ0FBQztBQUVyRCxNQUFxQixhQUFhO0lBTTlCLFlBQW9CLHVCQUFpRDs7UUFDakUsSUFBSSxDQUFDLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBUSxJQUFJLENBQUMsaUJBQWlCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsU0FBUyxHQUFZLE1BQUEsSUFBSSxDQUFDLGFBQWEsMENBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRVMsTUFBTSxDQUFDLFFBQVEsQ0FBRSxHQUFXO1FBQ2xDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFbkMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFO1lBQ3pDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLGdCQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxNQUFNLENBQUM7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SSxJQUFBLHNCQUFhLEVBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUEsc0JBQWEsRUFBQyxLQUFLLENBQUM7WUFDbkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsS0FBZSxDQUFDLENBQUM7YUFDdkM7WUFDRCxJQUFJLENBQUMsK0JBQStCLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFdEYsTUFBTSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7U0FDeEI7UUFFRCxNQUFNLENBQUMsTUFBTSxHQUFHLHVCQUFZLENBQUMsS0FBSyxDQUFDO0lBQ3ZDLENBQUM7Q0FDSjtBQXhSRCxnQ0F3UkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleHRuYW1lLCBpc0Fic29sdXRlIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgZGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IEpTT041IGZyb20gJ2pzb241JztcblxuaW1wb3J0IHtcbiAgICBjYXN0QXJyYXksXG4gICAgY2xvbmVEZWVwLFxuICAgIGlzUGxhaW5PYmplY3QsXG4gICAgbWVyZ2VXaXRoLFxufSBmcm9tICdsb2Rhc2gnO1xuXG5pbXBvcnQgeyByZWFkRmlsZSwgc3RhdCB9IGZyb20gJy4uL3V0aWxzL3Byb21pc2lmaWVkLWZ1bmN0aW9ucyc7XG5pbXBvcnQgT3B0aW9uIGZyb20gJy4vb3B0aW9uJztcbmltcG9ydCBPcHRpb25Tb3VyY2UgZnJvbSAnLi9vcHRpb24tc291cmNlJztcbmltcG9ydCByZXNvbHZlUGF0aFJlbGF0aXZlbHlDd2QgZnJvbSAnLi4vdXRpbHMvcmVzb2x2ZS1wYXRoLXJlbGF0aXZlbHktY3dkJztcbmltcG9ydCByZW5kZXJUZW1wbGF0ZSBmcm9tICcuLi91dGlscy9yZW5kZXItdGVtcGxhdGUnO1xuaW1wb3J0IFdBUk5JTkdfTUVTU0FHRVMgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuaW1wb3J0IGxvZyBmcm9tICcuLi9jbGkvbG9nJztcbmltcG9ydCB7IERpY3Rpb25hcnkgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgSlNfQ09ORklHVVJBVElPTl9FWFRFTlNJT04sIEpTT05fQ09ORklHVVJBVElPTl9FWFRFTlNJT04gfSBmcm9tICcuL2Zvcm1hdHMnO1xuXG5jb25zdCBERUJVR19MT0dHRVIgPSBkZWJ1ZygndGVzdGNhZmU6Y29uZmlndXJhdGlvbicpO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb25maWd1cmF0aW9uIHtcbiAgICBwcm90ZWN0ZWQgX29wdGlvbnM6IERpY3Rpb25hcnk8T3B0aW9uPjtcbiAgICBwcm90ZWN0ZWQgX2ZpbGVQYXRoPzogc3RyaW5nO1xuICAgIHByb3RlY3RlZCByZWFkb25seSBfZGVmYXVsdFBhdGhzPzogc3RyaW5nW107XG4gICAgcHJvdGVjdGVkIF9vdmVycmlkZGVuT3B0aW9uczogc3RyaW5nW107XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKGNvbmZpZ3VyYXRpb25GaWxlc05hbWVzOiBzdHJpbmcgfCBudWxsIHwgc3RyaW5nW10pIHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucyAgICAgICAgICAgPSB7fTtcbiAgICAgICAgdGhpcy5fZGVmYXVsdFBhdGhzICAgICAgPSB0aGlzLl9yZXNvbHZlRmlsZVBhdGhzKGNvbmZpZ3VyYXRpb25GaWxlc05hbWVzKTtcbiAgICAgICAgdGhpcy5fZmlsZVBhdGggICAgICAgICAgPSB0aGlzLl9kZWZhdWx0UGF0aHM/LlswXTtcbiAgICAgICAgdGhpcy5fb3ZlcnJpZGRlbk9wdGlvbnMgPSBbXTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF9mcm9tT2JqIChvYmo6IG9iamVjdCk6IERpY3Rpb25hcnk8T3B0aW9uPiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgICAgICAgT2JqZWN0LmVudHJpZXMob2JqKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgIHJlc3VsdFtrZXldID0gbmV3IE9wdGlvbihrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc3RhdGljIF9zaG93Q29uc29sZVdhcm5pbmcgKG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBsb2cud3JpdGUobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX3Nob3dXYXJuaW5nRm9yRXJyb3IgKGVycm9yOiBFcnJvciwgd2FybmluZ1RlbXBsYXRlOiBzdHJpbmcsIC4uLmFyZ3M6IFRlbXBsYXRlQXJndW1lbnRzKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSByZW5kZXJUZW1wbGF0ZSh3YXJuaW5nVGVtcGxhdGUsIC4uLmFyZ3MpO1xuXG4gICAgICAgIENvbmZpZ3VyYXRpb24uX3Nob3dDb25zb2xlV2FybmluZyhtZXNzYWdlKTtcblxuICAgICAgICBERUJVR19MT0dHRVIobWVzc2FnZSk7XG4gICAgICAgIERFQlVHX0xPR0dFUihlcnJvcik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX3Jlc29sdmVGaWxlUGF0aCAocGF0aDogc3RyaW5nIHwgbnVsbCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBpZiAoIXBhdGgpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICByZXR1cm4gaXNBYnNvbHV0ZShwYXRoKSA/IHBhdGggOiByZXNvbHZlUGF0aFJlbGF0aXZlbHlDd2QocGF0aCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVzb2x2ZUZpbGVQYXRocyAoZmlsZXNOYW1lczogc3RyaW5nIHwgbnVsbCB8IHN0cmluZ1tdKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAoIWZpbGVzTmFtZXMpXG4gICAgICAgICAgICByZXR1cm4gdm9pZCAwO1xuXG4gICAgICAgIHJldHVybiBjYXN0QXJyYXkoZmlsZXNOYW1lcykucmVkdWNlKChyZXN1bHQsIG5hbWUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVGaWxlUGF0aCA9IENvbmZpZ3VyYXRpb24uX3Jlc29sdmVGaWxlUGF0aChuYW1lKTtcblxuICAgICAgICAgICAgaWYgKHJlc29sdmVGaWxlUGF0aClcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChyZXNvbHZlRmlsZVBhdGgpO1xuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9LCBbXSBhcyBzdHJpbmdbXSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGluaXQgKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLl9vdmVycmlkZGVuT3B0aW9ucyA9IFtdO1xuICAgIH1cblxuICAgIHB1YmxpYyBtZXJnZU9wdGlvbnMgKG9wdGlvbnM6IG9iamVjdCk6IHZvaWQge1xuICAgICAgICBPYmplY3QuZW50cmllcyhvcHRpb25zKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3B0aW9uID0gdGhpcy5fZW5zdXJlT3B0aW9uKGtleSwgdmFsdWUsIE9wdGlvblNvdXJjZS5JbnB1dCk7XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gdm9pZCAwKVxuICAgICAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgICAgdGhpcy5fc2V0T3B0aW9uVmFsdWUob3B0aW9uLCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBtZXJnZURlZXAgKG9wdGlvbjogT3B0aW9uLCBzb3VyY2U6IG9iamVjdCk6IHZvaWQge1xuICAgICAgICBtZXJnZVdpdGgob3B0aW9uLnZhbHVlLCBzb3VyY2UsICh0YXJnZXRWYWx1ZTogT3B0aW9uVmFsdWUsIHNvdXJjZVZhbHVlOiBPcHRpb25WYWx1ZSwgcHJvcGVydHk6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgdGhpcy5fYWRkT3ZlcnJpZGRlbk9wdGlvbklmTmVjZXNzYXJ5KHRhcmdldFZhbHVlLCBzb3VyY2VWYWx1ZSwgb3B0aW9uLnNvdXJjZSwgYCR7b3B0aW9uLm5hbWV9LiR7cHJvcGVydHl9YCk7XG5cbiAgICAgICAgICAgIHJldHVybiBzb3VyY2VWYWx1ZSAhPT0gdm9pZCAwID8gc291cmNlVmFsdWUgOiB0YXJnZXRWYWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldE9wdGlvbiAoa2V5OiBzdHJpbmcpOiBPcHRpb25WYWx1ZSB7XG4gICAgICAgIGlmICgha2V5KVxuICAgICAgICAgICAgcmV0dXJuIHZvaWQgMDtcblxuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLl9vcHRpb25zW2tleV07XG5cbiAgICAgICAgaWYgKCFvcHRpb24pXG4gICAgICAgICAgICByZXR1cm4gdm9pZCAwO1xuXG4gICAgICAgIHJldHVybiBvcHRpb24udmFsdWU7XG4gICAgfVxuXG4gICAgcHVibGljIGdldE9wdGlvbnMgKHByZWRpY2F0ZT86IChuYW1lOiBzdHJpbmcsIG9wdGlvbjogT3B0aW9uKSA9PiBib29sZWFuKTogRGljdGlvbmFyeTxPcHRpb25WYWx1ZT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgICAgICAgID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgbGV0IGluY2x1ZGVJblJlc3VsdCA9IHRydWU7XG5cbiAgICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5fb3B0aW9ucykuZm9yRWFjaCgoW25hbWUsIG9wdGlvbl0pID0+IHtcbiAgICAgICAgICAgIGluY2x1ZGVJblJlc3VsdCA9IHByZWRpY2F0ZSA/IHByZWRpY2F0ZShuYW1lLCBvcHRpb24pIDogdHJ1ZTtcblxuICAgICAgICAgICAgaWYgKGluY2x1ZGVJblJlc3VsdClcbiAgICAgICAgICAgICAgICByZXN1bHRbbmFtZV0gPSBvcHRpb24udmFsdWU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgcHVibGljIGNsb25lIChub25DbG9uZWRPcHRpb25zPzogc3RyaW5nIHwgc3RyaW5nW10pOiBDb25maWd1cmF0aW9uIHtcbiAgICAgICAgY29uc3QgY29uZmlndXJhdGlvbiA9IGNsb25lRGVlcCh0aGlzKTtcblxuICAgICAgICBpZiAobm9uQ2xvbmVkT3B0aW9ucykge1xuICAgICAgICAgICAgY2FzdEFycmF5KG5vbkNsb25lZE9wdGlvbnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5fb3B0aW9uc1trZXldKVxuICAgICAgICAgICAgICAgICAgICBjb25maWd1cmF0aW9uLl9vcHRpb25zW2tleV0udmFsdWUgPSB0aGlzLl9vcHRpb25zW2tleV0udmFsdWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb25maWd1cmF0aW9uO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgZmlsZVBhdGggKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWxlUGF0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0IGRlZmF1bHRQYXRocyAoKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFBhdGhzO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBfbG9hZCAoKTogUHJvbWlzZTxudWxsIHwgb2JqZWN0PiB7XG4gICAgICAgIGlmICghdGhpcy5kZWZhdWx0UGF0aHM/Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IGNvbmZpZ3MgPSBhd2FpdCBQcm9taXNlLmFsbCh0aGlzLmRlZmF1bHRQYXRocy5tYXAoYXN5bmMgZmlsZVBhdGggPT4ge1xuICAgICAgICAgICAgaWYgKCFhd2FpdCB0aGlzLl9pc0NvbmZpZ3VyYXRpb25GaWxlRXhpc3RzKGZpbGVQYXRoKSlcbiAgICAgICAgICAgICAgICByZXR1cm4geyBmaWxlUGF0aCwgb3B0aW9uczogbnVsbCB9O1xuXG4gICAgICAgICAgICBsZXQgb3B0aW9ucyA9IG51bGwgYXMgb2JqZWN0IHwgbnVsbDtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzSlNDb25maWd1cmF0aW9uKGZpbGVQYXRoKSlcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gdGhpcy5fcmVhZEpzQ29uZmlndXJhdGlvbkZpbGVDb250ZW50KGZpbGVQYXRoKTtcbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbmZpZ3VyYXRpb25GaWxlQ29udGVudCA9IGF3YWl0IHRoaXMuX3JlYWRDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQoZmlsZVBhdGgpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZ3VyYXRpb25GaWxlQ29udGVudClcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHRoaXMuX3BhcnNlQ29uZmlndXJhdGlvbkZpbGVDb250ZW50KGNvbmZpZ3VyYXRpb25GaWxlQ29udGVudCwgZmlsZVBhdGgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4geyBmaWxlUGF0aCwgb3B0aW9ucyB9O1xuICAgICAgICB9KSk7XG5cbiAgICAgICAgY29uc3QgZXhpc3RlZENvbmZpZ3MgPSBjb25maWdzLmZpbHRlcihjb25maWcgPT4gISFjb25maWcub3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKCFleGlzdGVkQ29uZmlncy5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICB0aGlzLl9maWxlUGF0aCA9IGV4aXN0ZWRDb25maWdzWzBdLmZpbGVQYXRoO1xuXG4gICAgICAgIGlmIChleGlzdGVkQ29uZmlncy5sZW5ndGggPiAxKVxuICAgICAgICAgICAgQ29uZmlndXJhdGlvbi5fc2hvd0NvbnNvbGVXYXJuaW5nKHJlbmRlclRlbXBsYXRlKFdBUk5JTkdfTUVTU0FHRVMubXVsdGlwbGVDb25maWd1cmF0aW9uRmlsZXNGb3VuZCwgdGhpcy5fZmlsZVBhdGgpKTtcblxuICAgICAgICByZXR1cm4gZXhpc3RlZENvbmZpZ3NbMF0ub3B0aW9ucztcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgX2lzQ29uZmlndXJhdGlvbkZpbGVFeGlzdHMgKGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgc3RhdChmaWxlUGF0aCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgICBERUJVR19MT0dHRVIocmVuZGVyVGVtcGxhdGUoV0FSTklOR19NRVNTQUdFUy5jYW5ub3RGaW5kQ29uZmlndXJhdGlvbkZpbGUsIGZpbGVQYXRoLCBlcnJvci5zdGFjaykpO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfaGFzRXh0ZW50aW9uIChmaWxlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLCBleHRlbnRpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISFmaWxlUGF0aCAmJiBleHRuYW1lKGZpbGVQYXRoKSA9PT0gZXh0ZW50aW9uO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfaXNKU0NvbmZpZ3VyYXRpb24gKGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gQ29uZmlndXJhdGlvbi5faGFzRXh0ZW50aW9uKGZpbGVQYXRoLCBKU19DT05GSUdVUkFUSU9OX0VYVEVOU0lPTik7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9pc0pTT05Db25maWd1cmF0aW9uIChmaWxlUGF0aCA9IHRoaXMuZmlsZVBhdGgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIENvbmZpZ3VyYXRpb24uX2hhc0V4dGVudGlvbihmaWxlUGF0aCwgSlNPTl9DT05GSUdVUkFUSU9OX0VYVEVOU0lPTik7XG4gICAgfVxuXG4gICAgcHVibGljIF9yZWFkSnNDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQgKGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IG9iamVjdCB8IG51bGwge1xuICAgICAgICBpZiAoZmlsZVBhdGgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbZmlsZVBhdGhdO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVpcmUoZmlsZVBhdGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgICAgICBDb25maWd1cmF0aW9uLl9zaG93V2FybmluZ0ZvckVycm9yKGVycm9yLCBXQVJOSU5HX01FU1NBR0VTLmNhbm5vdFJlYWRDb25maWdGaWxlLCBmaWxlUGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgX3JlYWRDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQgKGZpbGVQYXRoID0gdGhpcy5maWxlUGF0aCk6IFByb21pc2U8QnVmZmVyIHwgbnVsbD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAgICAgQ29uZmlndXJhdGlvbi5fc2hvd1dhcm5pbmdGb3JFcnJvcihlcnJvciwgV0FSTklOR19NRVNTQUdFUy5jYW5ub3RSZWFkQ29uZmlnRmlsZSwgZmlsZVBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcGFyc2VDb25maWd1cmF0aW9uRmlsZUNvbnRlbnQgKGNvbmZpZ3VyYXRpb25GaWxlQ29udGVudDogQnVmZmVyLCBmaWxlUGF0aCA9IHRoaXMuZmlsZVBhdGgpOiBvYmplY3QgfCBudWxsIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBKU09ONS5wYXJzZShjb25maWd1cmF0aW9uRmlsZUNvbnRlbnQudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIENvbmZpZ3VyYXRpb24uX3Nob3dXYXJuaW5nRm9yRXJyb3IoZXJyb3IsIFdBUk5JTkdfTUVTU0FHRVMuY2Fubm90UGFyc2VDb25maWdGaWxlLCBmaWxlUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX2Vuc3VyZUFycmF5T3B0aW9uIChuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuX29wdGlvbnNbbmFtZV07XG5cbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIC8vIE5PVEU6IGEgaGFjayB0byBmaXggbG9kYXNoIHR5cGUgZGVmaW5pdGlvbnNcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBvcHRpb25zLnZhbHVlID0gY2FzdEFycmF5KG9wdGlvbnMudmFsdWUpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfZW5zdXJlT3B0aW9uIChuYW1lOiBzdHJpbmcsIHZhbHVlOiBPcHRpb25WYWx1ZSwgc291cmNlOiBPcHRpb25Tb3VyY2UpOiBPcHRpb24ge1xuICAgICAgICBsZXQgb3B0aW9uID0gbnVsbDtcblxuICAgICAgICBpZiAobmFtZSBpbiB0aGlzLl9vcHRpb25zKVxuICAgICAgICAgICAgb3B0aW9uID0gdGhpcy5fb3B0aW9uc1tuYW1lXTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBvcHRpb24gPSBuZXcgT3B0aW9uKG5hbWUsIHZhbHVlLCBzb3VyY2UpO1xuXG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zW25hbWVdID0gb3B0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgX2Vuc3VyZU9wdGlvbldpdGhWYWx1ZSAobmFtZTogc3RyaW5nLCBkZWZhdWx0VmFsdWU6IE9wdGlvblZhbHVlLCBzb3VyY2U6IE9wdGlvblNvdXJjZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBvcHRpb24gPSB0aGlzLl9lbnN1cmVPcHRpb24obmFtZSwgZGVmYXVsdFZhbHVlLCBzb3VyY2UpO1xuXG4gICAgICAgIGlmIChvcHRpb24udmFsdWUgIT09IHZvaWQgMClcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBvcHRpb24udmFsdWUgID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICBvcHRpb24uc291cmNlID0gc291cmNlO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfYWRkT3ZlcnJpZGRlbk9wdGlvbklmTmVjZXNzYXJ5ICh2YWx1ZTE6IE9wdGlvblZhbHVlLCB2YWx1ZTI6IE9wdGlvblZhbHVlLCBzb3VyY2U6IE9wdGlvblNvdXJjZSwgb3B0aW9uTmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmIChzb3VyY2UgPT09IE9wdGlvblNvdXJjZS5EZWZhdWx0KVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGlmICh2YWx1ZTEgPT09IHZvaWQgMCB8fCB2YWx1ZTIgPT09IHZvaWQgMCB8fCB2YWx1ZTEgPT09IHZhbHVlMiB8fCBzb3VyY2UgIT09IE9wdGlvblNvdXJjZS5Db25maWd1cmF0aW9uKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMuX292ZXJyaWRkZW5PcHRpb25zLnB1c2gob3B0aW9uTmFtZSk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9zZXRPcHRpb25WYWx1ZSAob3B0aW9uOiBPcHRpb24sIHZhbHVlOiBPcHRpb25WYWx1ZSk6IHZvaWQge1xuICAgICAgICBpZiAoaXNQbGFpbk9iamVjdChvcHRpb24udmFsdWUpICYmIGlzUGxhaW5PYmplY3QodmFsdWUpKVxuICAgICAgICAgICAgdGhpcy5tZXJnZURlZXAob3B0aW9uLCB2YWx1ZSBhcyBvYmplY3QpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2FkZE92ZXJyaWRkZW5PcHRpb25JZk5lY2Vzc2FyeShvcHRpb24udmFsdWUsIHZhbHVlLCBvcHRpb24uc291cmNlLCBvcHRpb24ubmFtZSk7XG5cbiAgICAgICAgICAgIG9wdGlvbi52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgb3B0aW9uLnNvdXJjZSA9IE9wdGlvblNvdXJjZS5JbnB1dDtcbiAgICB9XG59XG4iXX0=