You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
529 lines
62 KiB
529 lines
62 KiB
/*
|
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
if you want to view the source, please visit the github repository of this plugin
|
|
*/
|
|
|
|
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getProtoOf = Object.getPrototypeOf;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
var __export = (target, all) => {
|
|
__markAsModule(target);
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __reExport = (target, module2, desc) => {
|
|
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
for (let key of __getOwnPropNames(module2))
|
|
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
}
|
|
return target;
|
|
};
|
|
var __toModule = (module2) => {
|
|
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
};
|
|
var __async = (__this, __arguments, generator) => {
|
|
return new Promise((resolve, reject) => {
|
|
var fulfilled = (value) => {
|
|
try {
|
|
step(generator.next(value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
};
|
|
var rejected = (value) => {
|
|
try {
|
|
step(generator.throw(value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
};
|
|
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
});
|
|
};
|
|
|
|
// main.ts
|
|
__export(exports, {
|
|
default: () => MultiSelect
|
|
});
|
|
var import_obsidian5 = __toModule(require("obsidian"));
|
|
|
|
// src/settings/settings.ts
|
|
var DEFAULT_SETTINGS = {
|
|
queries: []
|
|
};
|
|
|
|
// src/queries/Query.ts
|
|
var Query = class {
|
|
constructor(name = "", description = "", id = "", dataviewJSQuery = null) {
|
|
this.name = name;
|
|
this.description = description;
|
|
this.id = id;
|
|
this.dataviewJSQuery = dataviewJSQuery;
|
|
}
|
|
static copyQuery(target, source) {
|
|
target.id = source.id;
|
|
target.name = source.name;
|
|
target.description = source.description;
|
|
target.dataviewJSQuery = source.dataviewJSQuery;
|
|
}
|
|
};
|
|
var Query_default = Query;
|
|
|
|
// src/queries/queryResultsModal.ts
|
|
var import_obsidian = __toModule(require("obsidian"));
|
|
var QueryResultModal = class extends import_obsidian.Modal {
|
|
constructor(app, plugin, query, cursorPosition, file) {
|
|
super(app);
|
|
this.plugin = plugin;
|
|
this.query = query;
|
|
this.cursorPosition = cursorPosition;
|
|
this.results = [];
|
|
this.selectedResults = [];
|
|
this.selectedAlias = {};
|
|
this.file = file;
|
|
this.prepend = "";
|
|
this.append = ", ";
|
|
}
|
|
onOpen() {
|
|
var _a;
|
|
const getResults = (api) => {
|
|
return new Function("dv", `return ${this.query.dataviewJSQuery}`)(api);
|
|
};
|
|
const valueGrid = this.contentEl.createDiv({
|
|
cls: "modal-results-grid"
|
|
});
|
|
if (this.app.plugins.enabledPlugins.has("dataview")) {
|
|
const api = (_a = this.app.plugins.plugins.dataview) == null ? void 0 : _a.api;
|
|
if (api) {
|
|
this.results = getResults(api);
|
|
} else
|
|
this.plugin.registerEvent(this.app.metadataCache.on("dataview:api-ready", (api2) => this.results = getResults(api2)));
|
|
}
|
|
this.populateValuesGrid(valueGrid, this.results.map((p) => p.file.path));
|
|
}
|
|
buildAliasesList(destFile) {
|
|
const frontmatter = this.app.metadataCache.getFileCache(destFile).frontmatter;
|
|
return (0, import_obsidian.parseFrontMatterAliases)(frontmatter);
|
|
}
|
|
buildValueToggler(valueGrid, destFile, aliases) {
|
|
const valueSelectorContainer = valueGrid.createDiv({
|
|
cls: "value-selector-container"
|
|
});
|
|
const valueTogglerLine = valueSelectorContainer.createDiv({
|
|
cls: "value-toggler-line"
|
|
});
|
|
const valueTogglerContainer = valueTogglerLine.createDiv({
|
|
cls: "value-selector-toggler"
|
|
});
|
|
const valueToggler = new import_obsidian.ToggleComponent(valueTogglerContainer);
|
|
valueToggler.onChange((value) => {
|
|
if (value && !this.selectedResults.includes(destFile.path)) {
|
|
this.selectedResults.push(destFile.path);
|
|
}
|
|
if (!value) {
|
|
this.selectedResults.remove(destFile.path);
|
|
delete this.selectedAlias[destFile.basename];
|
|
}
|
|
});
|
|
const valueLabel = valueTogglerLine.createDiv({
|
|
cls: "value-selector-label"
|
|
});
|
|
valueLabel.setText(destFile.basename);
|
|
valueLabel.onClickEvent((e) => valueToggler.setValue(!valueToggler.getValue()));
|
|
if (aliases) {
|
|
const aliasesSelectorContainer = valueTogglerLine.createDiv({
|
|
cls: "value-selector-aliases"
|
|
});
|
|
(0, import_obsidian.setIcon)(aliasesSelectorContainer, "three-horizontal-bars");
|
|
const aliasesListContainer = valueSelectorContainer.createDiv({
|
|
cls: "aliases-list-container"
|
|
});
|
|
aliasesListContainer.style.display = "none";
|
|
aliasesSelectorContainer.onClickEvent((e) => {
|
|
if (aliasesListContainer.style.display === "none") {
|
|
this.buildAliasSelector(aliasesListContainer, valueLabel, aliases, destFile.basename);
|
|
aliasesListContainer.style.display = "inline-block";
|
|
} else {
|
|
aliasesListContainer.innerHTML = "";
|
|
aliasesListContainer.style.display = "none";
|
|
}
|
|
});
|
|
}
|
|
}
|
|
buildAliasSelector(aliasesListContainer, valueLabel, aliases, basename) {
|
|
aliases.forEach((alias) => {
|
|
if (!Object.keys(this.selectedAlias).includes(basename) || this.selectedAlias[basename] !== alias) {
|
|
const aliasContainer = aliasesListContainer.createDiv();
|
|
aliasContainer.innerHTML = `<span>\u2022 ${alias}</span>`;
|
|
aliasContainer.onClickEvent((e) => {
|
|
valueLabel.setText(alias);
|
|
this.selectedAlias[basename] = alias;
|
|
aliasesListContainer.innerHTML = "";
|
|
aliasesListContainer.style.display = "none";
|
|
});
|
|
}
|
|
});
|
|
if (Object.keys(this.selectedAlias).includes(basename) && this.selectedAlias[basename] !== null) {
|
|
const aliasContainer = aliasesListContainer.createDiv();
|
|
aliasContainer.innerHTML = `<span>\u2022 ${basename}</span>`;
|
|
aliasContainer.onClickEvent((e) => {
|
|
valueLabel.setText(basename);
|
|
this.selectedAlias[basename] = null;
|
|
aliasesListContainer.innerHTML = "";
|
|
aliasesListContainer.style.display = "none";
|
|
});
|
|
}
|
|
}
|
|
buildMarkDownLink(path) {
|
|
const destFile = this.app.metadataCache.getFirstLinkpathDest(path, this.file.path);
|
|
const link = this.app.fileManager.generateMarkdownLink(destFile, this.file.path, null, this.selectedAlias[destFile.basename]);
|
|
return link;
|
|
}
|
|
buildNewLine() {
|
|
const leaf = this.app.workspace.activeLeaf;
|
|
if (leaf.view instanceof import_obsidian.MarkdownView && leaf.view.editor) {
|
|
const editor = leaf.view.editor;
|
|
const lineAtCursor = editor.getLine(this.cursorPosition.line);
|
|
const startLine = lineAtCursor.substr(0, this.cursorPosition.ch);
|
|
const content = this.selectedResults.map((r) => this.buildMarkDownLink(r)).map((l) => this.prepend + l).join(this.append);
|
|
const endLine = lineAtCursor.substr(this.cursorPosition.ch, lineAtCursor.length - this.cursorPosition.ch);
|
|
editor.setLine(this.cursorPosition.line, startLine + content + endLine);
|
|
}
|
|
}
|
|
populateValuesGrid(valueGrid, filePaths) {
|
|
filePaths.forEach((filePath) => {
|
|
const destFile = this.app.metadataCache.getFirstLinkpathDest(filePath, this.file.path);
|
|
this.buildValueToggler(valueGrid, destFile, this.buildAliasesList(destFile));
|
|
});
|
|
const divider = this.contentEl.createDiv();
|
|
divider.innerHTML = "<hr>";
|
|
const helper = this.contentEl.createDiv({
|
|
cls: "separator-helper-label"
|
|
});
|
|
helper.setText("prepend/append strings to the links");
|
|
const footer = this.contentEl.createDiv({
|
|
cls: "value-grid-footer"
|
|
});
|
|
const separatorContainer = footer.createDiv({
|
|
cls: "separator-container"
|
|
});
|
|
const prepend = new import_obsidian.TextComponent(separatorContainer);
|
|
prepend.inputEl.size = 10;
|
|
prepend.setValue(this.prepend);
|
|
const linkLabel = separatorContainer.createDiv({
|
|
cls: "separator-link-label"
|
|
});
|
|
linkLabel.setText(" [[Link]] ");
|
|
prepend.onChange((value) => this.prepend = value);
|
|
const append = new import_obsidian.TextAreaComponent(separatorContainer);
|
|
append.inputEl.cols = 3;
|
|
append.inputEl.rows = 2;
|
|
append.setValue(this.append);
|
|
append.onChange((value) => this.append = value);
|
|
const buttonsContainer = footer.createDiv({
|
|
cls: "buttons-container"
|
|
});
|
|
const saveButton = new import_obsidian.ButtonComponent(buttonsContainer);
|
|
saveButton.setIcon("checkmark");
|
|
saveButton.onClick(() => {
|
|
console.log(this.selectedResults, this.selectedAlias);
|
|
this.buildNewLine();
|
|
this.close();
|
|
});
|
|
const cancelButton = new import_obsidian.ExtraButtonComponent(buttonsContainer);
|
|
cancelButton.setIcon("cross");
|
|
cancelButton.onClick(() => this.close());
|
|
}
|
|
};
|
|
|
|
// src/settings/settingTab.ts
|
|
var import_obsidian4 = __toModule(require("obsidian"));
|
|
|
|
// src/settings/QuerySetting.ts
|
|
var import_obsidian3 = __toModule(require("obsidian"));
|
|
|
|
// src/settings/QuerySettingModal.ts
|
|
var import_obsidian2 = __toModule(require("obsidian"));
|
|
var QuerySettingsModal = class extends import_obsidian2.Modal {
|
|
constructor(app, plugin, parentSettingContainer, parentSetting, query) {
|
|
super(app);
|
|
this.saved = false;
|
|
this.new = true;
|
|
this.plugin = plugin;
|
|
this.parentSetting = parentSetting;
|
|
this.initialQuery = new Query_default();
|
|
this.parentSettingContainer = parentSettingContainer;
|
|
if (query) {
|
|
this.new = false;
|
|
this.query = query;
|
|
this.initialQuery.name = query.name;
|
|
this.initialQuery.id = query.id;
|
|
this.initialQuery.description = query.description;
|
|
} else {
|
|
let newId = 1;
|
|
this.plugin.initialQueries.forEach((query2) => {
|
|
if (parseInt(query2.id) && parseInt(query2.id) >= newId) {
|
|
newId = parseInt(query2.id) + 1;
|
|
}
|
|
});
|
|
this.query = new Query_default();
|
|
this.query.id = newId.toString();
|
|
this.initialQuery.id = newId.toString();
|
|
}
|
|
}
|
|
onOpen() {
|
|
if (this.query.name == "") {
|
|
this.titleEl.setText(`Add a query`);
|
|
} else {
|
|
this.titleEl.setText(`Manage query ${this.query.name}`);
|
|
}
|
|
this.createForm();
|
|
}
|
|
onClose() {
|
|
Object.assign(this.query, this.initialQuery);
|
|
if (!this.new) {
|
|
this.parentSetting.setTextContentWithname();
|
|
} else if (this.saved) {
|
|
new QuerySetting(this.parentSettingContainer, this.query, this.app, this.plugin);
|
|
}
|
|
}
|
|
createNameInputContainer(parentNode) {
|
|
const queryNameContainerLabel = parentNode.createDiv();
|
|
queryNameContainerLabel.setText(`Query Name:`);
|
|
const input = new import_obsidian2.TextComponent(parentNode);
|
|
const name = this.query.name;
|
|
input.setValue(name);
|
|
input.setPlaceholder("Name of the query");
|
|
input.onChange((value) => {
|
|
this.query.name = value;
|
|
this.titleEl.setText(`Manage ${this.query.name}`);
|
|
QuerySettingsModal.removeValidationError(input);
|
|
});
|
|
return input;
|
|
}
|
|
createDescriptionInputContainer(parentNode) {
|
|
const queryDescriptionContainerLabel = parentNode.createDiv();
|
|
queryDescriptionContainerLabel.setText(`Query Description:`);
|
|
const input = new import_obsidian2.TextComponent(parentNode);
|
|
const description = this.query.description;
|
|
input.setValue(description);
|
|
input.setPlaceholder("Description of the query");
|
|
input.onChange((value) => {
|
|
this.query.description = value;
|
|
QuerySettingsModal.removeValidationError(input);
|
|
});
|
|
return input;
|
|
}
|
|
createDataviewJSInputContainer(parentNode) {
|
|
const queryDataviewJSQueryContainerLabel = parentNode.createDiv();
|
|
queryDataviewJSQueryContainerLabel.setText(`DataviewJS query:`);
|
|
const input = new import_obsidian2.TextAreaComponent(parentNode);
|
|
const dataviewJSQuery = this.query.dataviewJSQuery;
|
|
input.inputEl.cols = 100;
|
|
input.inputEl.rows = 15;
|
|
input.setPlaceholder(`Dataviewjs syntax to query pages
|
|
Example:
|
|
dv.pages("#SomeTag").where(p => p.field === "some value").sort(p => condition, 'asc')`);
|
|
input.setValue(dataviewJSQuery != null ? dataviewJSQuery : "");
|
|
input.onChange((value) => {
|
|
this.query.dataviewJSQuery = value;
|
|
QuerySettingsModal.removeValidationError(input);
|
|
});
|
|
return input;
|
|
}
|
|
createForm() {
|
|
const div = this.contentEl.createDiv({
|
|
cls: "frontmatter-prompt-div"
|
|
});
|
|
const mainDiv = div.createDiv({
|
|
cls: "frontmatter-prompt-form"
|
|
});
|
|
const nameContainer = mainDiv.createDiv();
|
|
const descriptionContainer = mainDiv.createDiv();
|
|
const dataviewJSQueryContainer = mainDiv.createDiv();
|
|
this.namePromptComponent = this.createNameInputContainer(nameContainer);
|
|
this.descriptionPromptComponent = this.createDescriptionInputContainer(descriptionContainer);
|
|
this.queryPromptComponent = this.createDataviewJSInputContainer(dataviewJSQueryContainer);
|
|
mainDiv.createDiv().createEl("hr");
|
|
const footerEl = this.contentEl.createDiv();
|
|
const footerButtons = new import_obsidian2.Setting(footerEl);
|
|
footerButtons.addButton((b) => this.createSaveButton(b));
|
|
footerButtons.addExtraButton((b) => this.createCancelButton(b));
|
|
}
|
|
createSaveButton(b) {
|
|
b.setTooltip("Save").setIcon("checkmark").onClick(() => __async(this, null, function* () {
|
|
let error = false;
|
|
if (/^[#>-]/.test(this.query.name)) {
|
|
QuerySettingsModal.setValidationError(this.namePromptComponent, this.namePromptComponent.inputEl, "Query name cannot start with #, >, -");
|
|
error = true;
|
|
}
|
|
if (this.query.name == "") {
|
|
QuerySettingsModal.setValidationError(this.namePromptComponent, this.namePromptComponent.inputEl, "Property name can not be Empty");
|
|
error = true;
|
|
}
|
|
if (error) {
|
|
new import_obsidian2.Notice("Fix errors before saving.");
|
|
return;
|
|
}
|
|
this.saved = true;
|
|
const currentExistingQuery = this.plugin.initialQueries.filter((q) => q.id == this.query.id)[0];
|
|
if (currentExistingQuery) {
|
|
this.plugin.initialQueries.remove(currentExistingQuery);
|
|
this.app.commands.removeCommand(`${this.plugin.manifest.id}:multiSelect-${currentExistingQuery.name}`);
|
|
}
|
|
this.plugin.initialQueries.push(this.query);
|
|
this.plugin.addMultiSelectQueryCommand(this.query);
|
|
this.initialQuery = this.query;
|
|
this.plugin.saveSettings();
|
|
this.close();
|
|
}));
|
|
return b;
|
|
}
|
|
createCancelButton(b) {
|
|
b.setIcon("cross").setTooltip("Cancel").onClick(() => {
|
|
this.saved = false;
|
|
if (this.initialQuery.name != "") {
|
|
Object.assign(this.query, this.initialQuery);
|
|
}
|
|
this.close();
|
|
});
|
|
return b;
|
|
}
|
|
static setValidationError(textInput, insertAfter, message) {
|
|
textInput.inputEl.addClass("is-invalid");
|
|
if (message) {
|
|
let mDiv = textInput.inputEl.parentElement.querySelector(".invalid-feedback");
|
|
if (!mDiv) {
|
|
mDiv = createDiv({ cls: "invalid-feedback" });
|
|
}
|
|
mDiv.innerText = message;
|
|
mDiv.insertAfter(insertAfter);
|
|
}
|
|
}
|
|
static removeValidationError(textInput) {
|
|
if (textInput.inputEl.hasClass("is-invalid")) {
|
|
textInput.inputEl.removeClass("is-invalid");
|
|
textInput.inputEl.parentElement.removeChild(textInput.inputEl.parentElement.lastElementChild);
|
|
}
|
|
}
|
|
};
|
|
|
|
// src/settings/QuerySetting.ts
|
|
var QuerySetting = class extends import_obsidian3.Setting {
|
|
constructor(containerEl, query, app, plugin) {
|
|
super(containerEl);
|
|
this.containerEl = containerEl;
|
|
this.query = query;
|
|
this.app = app;
|
|
this.plugin = plugin;
|
|
this.setTextContentWithname();
|
|
this.addEditButton();
|
|
this.addDeleteButton();
|
|
}
|
|
setTextContentWithname() {
|
|
this.setName(this.query.name);
|
|
this.setDesc(this.query.description);
|
|
}
|
|
addEditButton() {
|
|
this.addButton((b) => {
|
|
b.setIcon("pencil").setTooltip("Edit").onClick(() => {
|
|
let modal = new QuerySettingsModal(this.app, this.plugin, this.containerEl, this, this.query);
|
|
modal.open();
|
|
});
|
|
});
|
|
}
|
|
addDeleteButton() {
|
|
this.addButton((b) => {
|
|
b.setIcon("trash").setTooltip("Delete").onClick(() => {
|
|
const currentExistingQuery = this.plugin.initialQueries.filter((p) => p.id == this.query.id)[0];
|
|
if (currentExistingQuery) {
|
|
this.plugin.initialQueries.remove(currentExistingQuery);
|
|
this.app.commands.removeCommand(`${this.plugin.manifest.id}:multiSelect-${currentExistingQuery.name}`);
|
|
}
|
|
this.settingEl.parentElement.removeChild(this.settingEl);
|
|
this.plugin.saveSettings();
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
// src/settings/settingTab.ts
|
|
var MultiSelectSettingTab = class extends import_obsidian4.PluginSettingTab {
|
|
constructor(app, plugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
display() {
|
|
const { containerEl } = this;
|
|
containerEl.empty();
|
|
containerEl.createEl("h2", { text: "Settings for Multi Select." });
|
|
new import_obsidian4.Setting(containerEl).setName("Add New Query").setDesc("Add a new query to select files from result.").addButton((button) => {
|
|
let b = button.setTooltip("Add New Query").setButtonText("+").onClick(() => __async(this, null, function* () {
|
|
let modal = new QuerySettingsModal(this.app, this.plugin, containerEl);
|
|
modal.open();
|
|
}));
|
|
return b;
|
|
});
|
|
this.plugin.initialQueries.forEach((savedQuery) => {
|
|
const query = new Query_default();
|
|
Object.assign(query, savedQuery);
|
|
new QuerySetting(containerEl, query, this.app, this.plugin);
|
|
});
|
|
}
|
|
};
|
|
|
|
// main.ts
|
|
var MultiSelect = class extends import_obsidian5.Plugin {
|
|
constructor() {
|
|
super(...arguments);
|
|
this.initialQueries = [];
|
|
}
|
|
addMultiSelectQueryCommand(query) {
|
|
this.addCommand({
|
|
id: `multiSelect-${query.name}`,
|
|
name: `Multi Select from ${query.name}`,
|
|
callback: () => {
|
|
const leaf = this.app.workspace.activeLeaf;
|
|
if (leaf.view instanceof import_obsidian5.MarkdownView && leaf.view.editor) {
|
|
const queryResultModal = new QueryResultModal(this.app, this, query, leaf.view.editor.getCursor(), leaf.view.file);
|
|
queryResultModal.open();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
onload() {
|
|
return __async(this, null, function* () {
|
|
yield this.loadSettings();
|
|
this.settings.queries.forEach((savedQuery) => {
|
|
const query = new Query_default();
|
|
Object.assign(query, savedQuery);
|
|
this.initialQueries.push(query);
|
|
});
|
|
this.addSettingTab(new MultiSelectSettingTab(this.app, this));
|
|
this.settings.queries.forEach((query) => {
|
|
this.addMultiSelectQueryCommand(query);
|
|
});
|
|
});
|
|
}
|
|
onunload() {
|
|
}
|
|
loadSettings() {
|
|
return __async(this, null, function* () {
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
|
|
});
|
|
}
|
|
saveSettings() {
|
|
return __async(this, null, function* () {
|
|
this.settings.queries = this.initialQueries;
|
|
yield this.saveData(this.settings);
|
|
});
|
|
}
|
|
};
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyIsICJzcmMvc2V0dGluZ3Mvc2V0dGluZ3MudHMiLCAic3JjL3F1ZXJpZXMvUXVlcnkudHMiLCAic3JjL3F1ZXJpZXMvcXVlcnlSZXN1bHRzTW9kYWwudHMiLCAic3JjL3NldHRpbmdzL3NldHRpbmdUYWIudHMiLCAic3JjL3NldHRpbmdzL1F1ZXJ5U2V0dGluZy50cyIsICJzcmMvc2V0dGluZ3MvUXVlcnlTZXR0aW5nTW9kYWwudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7IE1hcmtkb3duVmlldywgUGx1Z2luIH0gZnJvbSAnb2JzaWRpYW4nO1xyXG5pbXBvcnQgeyBNdWx0aVNlbGVjdFNldHRpbmdzLCBERUZBVUxUX1NFVFRJTkdTIH0gZnJvbSBcInNyYy9zZXR0aW5ncy9zZXR0aW5nc1wiXHJcbmltcG9ydCBRdWVyeSBmcm9tIFwic3JjL3F1ZXJpZXMvUXVlcnlcIlxyXG5pbXBvcnQgUXVlcnlSZXN1bHRNb2RhbCBmcm9tIFwic3JjL3F1ZXJpZXMvcXVlcnlSZXN1bHRzTW9kYWxcIlxyXG5pbXBvcnQgc2V0dGluZ1RhYiBmcm9tIFwic3JjL3NldHRpbmdzL3NldHRpbmdUYWJcIlxyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTXVsdGlTZWxlY3QgZXh0ZW5kcyBQbHVnaW4ge1xyXG5cdHNldHRpbmdzOiBNdWx0aVNlbGVjdFNldHRpbmdzO1xyXG5cdGluaXRpYWxRdWVyaWVzOiBBcnJheTxRdWVyeT4gPSBbXVxyXG5cclxuXHRhZGRNdWx0aVNlbGVjdFF1ZXJ5Q29tbWFuZChxdWVyeTogUXVlcnkpIHtcclxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XHJcblx0XHRcdGlkOiBgbXVsdGlTZWxlY3QtJHtxdWVyeS5uYW1lfWAsXHJcblx0XHRcdG5hbWU6IGBNdWx0aSBTZWxlY3QgZnJvbSAke3F1ZXJ5Lm5hbWV9YCxcclxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcclxuXHRcdFx0XHRjb25zdCBsZWFmID0gdGhpcy5hcHAud29ya3NwYWNlLmFjdGl2ZUxlYWZcclxuXHRcdFx0XHRpZiAobGVhZi52aWV3IGluc3RhbmNlb2YgTWFya2Rvd25WaWV3ICYmIGxlYWYudmlldy5lZGl0b3IpIHtcclxuXHRcdFx0XHRcdGNvbnN0IHF1ZXJ5UmVzdWx0TW9kYWwgPSBuZXcgUXVlcnlSZXN1bHRNb2RhbCh0aGlzLmFwcCwgdGhpcywgcXVlcnksIGxlYWYudmlldy5lZGl0b3IuZ2V0Q3Vyc29yKCksIGxlYWYudmlldy5maWxlKVxyXG5cdFx0XHRcdFx0cXVlcnlSZXN1bHRNb2RhbC5vcGVuKClcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sXHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdGFzeW5jIG9ubG9hZCgpIHtcclxuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XHJcblx0XHR0aGlzLnNldHRpbmdzLnF1ZXJpZXMuZm9yRWFjaChzYXZlZFF1ZXJ5ID0+IHtcclxuXHRcdFx0Y29uc3QgcXVlcnkgPSBuZXcgUXVlcnkoKVxyXG5cdFx0XHRPYmplY3QuYXNzaWduKHF1ZXJ5LCBzYXZlZFF1ZXJ5KVxyXG5cdFx0XHR0aGlzLmluaXRpYWxRdWVyaWVzLnB1c2gocXVlcnkpXHJcblx0XHR9KVxyXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBzZXR0aW5nVGFiKHRoaXMuYXBwLCB0aGlzKSk7XHJcblx0XHR0aGlzLnNldHRpbmdzLnF1ZXJpZXMuZm9yRWFjaChxdWVyeSA9PiB7XHJcblx0XHRcdHRoaXMuYWRkTXVsdGlTZWxlY3RRdWVyeUNvbW1hbmQocXVlcnkpXHJcblx0XHR9KVxyXG5cclxuXHR9XHJcblxyXG5cdG9udW5sb2FkKCkge1xyXG5cclxuXHR9XHJcblxyXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpIHtcclxuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xyXG5cdH1cclxuXHJcblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xyXG5cdFx0dGhpcy5zZXR0aW5ncy5xdWVyaWVzID0gdGhpcy5pbml0aWFsUXVlcmllc1xyXG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcclxuXHR9XHJcbn1cclxuXHJcblxyXG4iLCAiaW1wb3J0IFF1ZXJ5IGZyb20gXCJzcmMvcXVlcmllcy9RdWVyeVwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgTXVsdGlTZWxlY3RTZXR0aW5ncyB7XG4gICAgcXVlcmllczogQXJyYXk8UXVlcnk+XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFVFRJTkdTOiBNdWx0aVNlbGVjdFNldHRpbmdzID0ge1xuICAgIHF1ZXJpZXM6IFtdXG59IiwgImludGVyZmFjZSBRdWVyeSB7XG4gICAgaWQ6IHN0cmluZ1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmdcbiAgICBkYXRhdmlld0pTUXVlcnk/OiBzdHJpbmdcbn1cblxuY2xhc3MgUXVlcnkge1xuXG4gICAgY29uc3RydWN0b3IobmFtZTogc3RyaW5nID0gXCJcIixcbiAgICAgICAgZGVzY3JpcHRpb246IHN0cmluZyA9IFwiXCIsXG4gICAgICAgIGlkOiBzdHJpbmcgPSBcIlwiLFxuICAgICAgICBkYXRhdmlld0pTUXVlcnk6IHN0cmluZyA9IG51bGwpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZVxuICAgICAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb25cbiAgICAgICAgdGhpcy5pZCA9IGlkXG4gICAgICAgIHRoaXMuZGF0YXZpZXdKU1F1ZXJ5ID0gZGF0YXZpZXdKU1F1ZXJ5XG4gICAgfVxuXG4gICAgc3RhdGljIGNvcHlRdWVyeSh0YXJnZXQ6IFF1ZXJ5LCBzb3VyY2U6IFF1ZXJ5KSB7XG4gICAgICAgIHRhcmdldC5pZCA9IHNvdXJjZS5pZFxuICAgICAgICB0YXJnZXQubmFtZSA9IHNvdXJjZS5uYW1lXG4gICAgICAgIHRhcmdldC5kZXNjcmlwdGlvbiA9IHNvdXJjZS5kZXNjcmlwdGlvblxuICAgICAgICB0YXJnZXQuZGF0YXZpZXdKU1F1ZXJ5ID0gc291cmNlLmRhdGF2aWV3SlNRdWVyeVxuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUXVlcnkiLCAiaW1wb3J0IHtcbiAgICBBcHAsXG4gICAgTW9kYWwsXG4gICAgVEZpbGUsXG4gICAgTWFya2Rvd25WaWV3LFxuICAgIEVkaXRvclBvc2l0aW9uLFxuICAgIEJ1dHRvbkNvbXBvbmVudCxcbiAgICBFeHRyYUJ1dHRvbkNvbXBvbmVudCxcbiAgICBzZXRJY29uLFxuICAgIFRvZ2dsZUNvbXBvbmVudCxcbiAgICBwYXJzZUZyb250TWF0dGVyQWxpYXNlcyxcbiAgICBUZXh0Q29tcG9uZW50LFxuICAgIFRleHRBcmVhQ29tcG9uZW50XG59IGZyb20gXCJvYnNpZGlhblwiXG5pbXBvcnQgTXVsdGlTZWxlY3QgZnJvbSBcIm1haW5cIlxuaW1wb3J0IFF1ZXJ5IGZyb20gXCJzcmMvcXVlcmllcy9RdWVyeVwiXG5cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUXVlcnlSZXN1bHRNb2RhbCBleHRlbmRzIE1vZGFsIHtcbiAgICBxdWVyeTogUXVlcnlcbiAgICBwbHVnaW46IE11bHRpU2VsZWN0XG4gICAgY3Vyc29yUG9zaXRpb246IEVkaXRvclBvc2l0aW9uXG4gICAgcmVzdWx0czogQXJyYXk8c3RyaW5nPlxuICAgIHNlbGVjdGVkUmVzdWx0czogc3RyaW5nW11cbiAgICBzZWxlY3RlZEFsaWFzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+XG4gICAgZmlsZTogVEZpbGVcbiAgICBwcmVwZW5kOiBzdHJpbmdcbiAgICBhcHBlbmQ6IHN0cmluZ1xuXG4gICAgY29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogTXVsdGlTZWxlY3QsIHF1ZXJ5OiBRdWVyeSwgY3Vyc29yUG9zaXRpb246IEVkaXRvclBvc2l0aW9uLCBmaWxlOiBURmlsZSkge1xuICAgICAgICBzdXBlcihhcHApXG4gICAgICAgIHRoaXMucGx1Z2luID0gcGx1Z2luXG4gICAgICAgIHRoaXMucXVlcnkgPSBxdWVyeVxuICAgICAgICB0aGlzLmN1cnNvclBvc2l0aW9uID0gY3Vyc29yUG9zaXRpb25cbiAgICAgICAgdGhpcy5yZXN1bHRzID0gW11cbiAgICAgICAgdGhpcy5zZWxlY3RlZFJlc3VsdHMgPSBbXVxuICAgICAgICB0aGlzLnNlbGVjdGVkQWxpYXMgPSB7fVxuICAgICAgICB0aGlzLmZpbGUgPSBmaWxlXG4gICAgICAgIHRoaXMucHJlcGVuZCA9IFwiXCJcbiAgICAgICAgdGhpcy5hcHBlbmQgPSBcIiwgXCJcbiAgICB9XG5cbiAgICBvbk9wZW4oKSB7XG4gICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICBjb25zdCBnZXRSZXN1bHRzID0gKGFwaTogRGF0YXZpZXdQbHVnaW5bXCJhcGlcIl0pID0+IHtcbiAgICAgICAgICAgIHJldHVybiAobmV3IEZ1bmN0aW9uKFwiZHZcIiwgYHJldHVybiAke3RoaXMucXVlcnkuZGF0YXZpZXdKU1F1ZXJ5fWApKShhcGkpXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHZhbHVlR3JpZCA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IFwibW9kYWwtcmVzdWx0cy1ncmlkXCJcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKHRoaXMuYXBwLnBsdWdpbnMuZW5hYmxlZFBsdWdpbnMuaGFzKFwiZGF0YXZpZXdcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IGFwaSA9IHRoaXMuYXBwLnBsdWdpbnMucGx1Z2lucy5kYXRhdmlldz8uYXBpO1xuICAgICAgICAgICAgaWYgKGFwaSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzdWx0cyA9IGdldFJlc3VsdHMoYXBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5yZWdpc3RlckV2ZW50KFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLm9uKFwiZGF0YXZpZXc6YXBpLXJlYWR5XCIsIChhcGkpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VsdHMgPSBnZXRSZXN1bHRzKGFwaSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wb3B1bGF0ZVZhbHVlc0dyaWQodmFsdWVHcmlkLCB0aGlzLnJlc3VsdHMubWFwKChwOiBhbnkpID0+IHAuZmlsZS5wYXRoKSlcbiAgICB9XG5cbiAgICBidWlsZEFsaWFzZXNMaXN0KGRlc3RGaWxlOiBURmlsZSk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgZnJvbnRtYXR0ZXIgPSB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLmdldEZpbGVDYWNoZShkZXN0RmlsZSkuZnJvbnRtYXR0ZXJcbiAgICAgICAgcmV0dXJuIHBhcnNlRnJvbnRNYXR0ZXJBbGlhc2VzKGZyb250bWF0dGVyKVxuICAgIH1cblxuICAgIGJ1aWxkVmFsdWVUb2dnbGVyKHZhbHVlR3JpZDogSFRNTERpdkVsZW1lbnQsIGRlc3RGaWxlOiBURmlsZSwgYWxpYXNlcz86IHN0cmluZ1tdKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlU2VsZWN0b3JDb250YWluZXIgPSB2YWx1ZUdyaWQuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogXCJ2YWx1ZS1zZWxlY3Rvci1jb250YWluZXJcIlxuICAgICAgICB9KVxuICAgICAgICBjb25zdCB2YWx1ZVRvZ2dsZXJMaW5lID0gdmFsdWVTZWxlY3RvckNvbnRhaW5lci5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiBcInZhbHVlLXRvZ2dsZXItbGluZVwiXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IHZhbHVlVG9nZ2xlckNvbnRhaW5lciA9IHZhbHVlVG9nZ2xlckxpbmUuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogXCJ2YWx1ZS1zZWxlY3Rvci10b2dnbGVyXCJcbiAgICAgICAgfSlcbiAgICAgICAgY29uc3QgdmFsdWVUb2dnbGVyID0gbmV3IFRvZ2dsZUNvbXBvbmVudCh2YWx1ZVRvZ2dsZXJDb250YWluZXIpXG4gICAgICAgIHZhbHVlVG9nZ2xlci5vbkNoYW5nZSh2YWx1ZSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgJiYgIXRoaXMuc2VsZWN0ZWRSZXN1bHRzLmluY2x1ZGVzKGRlc3RGaWxlLnBhdGgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJlc3VsdHMucHVzaChkZXN0RmlsZS5wYXRoKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSZXN1bHRzLnJlbW92ZShkZXN0RmlsZS5wYXRoKVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNlbGVjdGVkQWxpYXNbZGVzdEZpbGUuYmFzZW5hbWVdXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IHZhbHVlTGFiZWwgPSB2YWx1ZVRvZ2dsZXJMaW5lLmNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IFwidmFsdWUtc2VsZWN0b3ItbGFiZWxcIlxuICAgICAgICB9KVxuICAgICAgICB2YWx1ZUxhYmVsLnNldFRleHQoZGVzdEZpbGUuYmFzZW5hbWUpXG4gICAgICAgIHZhbHVlTGFiZWwub25DbGlja0V2ZW50KGUgPT4gdmFsdWVUb2dnbGVyLnNldFZhbHVlKCF2YWx1ZVRvZ2dsZXIuZ2V0VmFsdWUoKSkpXG4gICAgICAgIGlmIChhbGlhc2VzKSB7XG4gICAgICAgICAgICBjb25zdCBhbGlhc2VzU2VsZWN0b3JDb250YWluZXIgPSB2YWx1ZVRvZ2dsZXJMaW5lLmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgY2xzOiBcInZhbHVlLXNlbGVjdG9yLWFsaWFzZXNcIlxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHNldEljb24oYWxpYXNlc1NlbGVjdG9yQ29udGFpbmVyLCBcInRocmVlLWhvcml6b250YWwtYmFyc1wiKVxuICAgICAgICAgICAgY29uc3QgYWxpYXNlc0xpc3RDb250YWluZXIgPSB2YWx1ZVNlbGVjdG9yQ29udGFpbmVyLmNyZWF0ZURpdih7XG4gICAgICAgICAgICAgICAgY2xzOiBcImFsaWFzZXMtbGlzdC1jb250YWluZXJcIlxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIGFsaWFzZXNMaXN0Q29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgICAgICAgICAgYWxpYXNlc1NlbGVjdG9yQ29udGFpbmVyLm9uQ2xpY2tFdmVudChlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYWxpYXNlc0xpc3RDb250YWluZXIuc3R5bGUuZGlzcGxheSA9PT0gXCJub25lXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsZEFsaWFzU2VsZWN0b3IoYWxpYXNlc0xpc3RDb250YWluZXIsIHZhbHVlTGFiZWwsIGFsaWFzZXMsIGRlc3RGaWxlLmJhc2VuYW1lKVxuICAgICAgICAgICAgICAgICAgICBhbGlhc2VzTGlzdENvbnRhaW5lci5zdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIlxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFsaWFzZXNMaXN0Q29udGFpbmVyLmlubmVySFRNTCA9ICcnXG4gICAgICAgICAgICAgICAgICAgIGFsaWFzZXNMaXN0Q29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBidWlsZEFsaWFzU2VsZWN0b3IoYWxpYXNlc0xpc3RDb250YWluZXI6IEhUTUxEaXZFbGVtZW50LCB2YWx1ZUxhYmVsOiBIVE1MRGl2RWxlbWVudCwgYWxpYXNlczogc3RyaW5nW10sIGJhc2VuYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgYWxpYXNlcy5mb3JFYWNoKGFsaWFzID0+IHtcbiAgICAgICAgICAgIGlmICghT2JqZWN0LmtleXModGhpcy5zZWxlY3RlZEFsaWFzKS5pbmNsdWRlcyhiYXNlbmFtZSkgfHwgdGhpcy5zZWxlY3RlZEFsaWFzW2Jhc2VuYW1lXSAhPT0gYWxpYXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbGlhc0NvbnRhaW5lciA9IGFsaWFzZXNMaXN0Q29udGFpbmVyLmNyZWF0ZURpdigpXG4gICAgICAgICAgICAgICAgYWxpYXNDb250YWluZXIuaW5uZXJIVE1MID0gYDxzcGFuPlx1MjAyMiAke2FsaWFzfTwvc3Bhbj5gXG4gICAgICAgICAgICAgICAgYWxpYXNDb250YWluZXIub25DbGlja0V2ZW50KGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZUxhYmVsLnNldFRleHQoYWxpYXMpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRBbGlhc1tiYXNlbmFtZV0gPSBhbGlhc1xuICAgICAgICAgICAgICAgICAgICBhbGlhc2VzTGlzdENvbnRhaW5lci5pbm5lckhUTUwgPSBcIlwiXG4gICAgICAgICAgICAgICAgICAgIGFsaWFzZXNMaXN0Q29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIlxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLnNlbGVjdGVkQWxpYXMpLmluY2x1ZGVzKGJhc2VuYW1lKSAmJiB0aGlzLnNlbGVjdGVkQWxpYXNbYmFzZW5hbWVdICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBhbGlhc0NvbnRhaW5lciA9IGFsaWFzZXNMaXN0Q29udGFpbmVyLmNyZWF0ZURpdigpXG4gICAgICAgICAgICBhbGlhc0NvbnRhaW5lci5pbm5lckhUTUwgPSBgPHNwYW4+XHUyMDIyICR7YmFzZW5hbWV9PC9zcGFuPmBcbiAgICAgICAgICAgIGFsaWFzQ29udGFpbmVyLm9uQ2xpY2tFdmVudChlID0+IHtcbiAgICAgICAgICAgICAgICB2YWx1ZUxhYmVsLnNldFRleHQoYmFzZW5hbWUpXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEFsaWFzW2Jhc2VuYW1lXSA9IG51bGxcbiAgICAgICAgICAgICAgICBhbGlhc2VzTGlzdENvbnRhaW5lci5pbm5lckhUTUwgPSBcIlwiXG4gICAgICAgICAgICAgICAgYWxpYXNlc0xpc3RDb250YWluZXIuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYnVpbGRNYXJrRG93bkxpbmsocGF0aDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGRlc3RGaWxlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaXJzdExpbmtwYXRoRGVzdChwYXRoLCB0aGlzLmZpbGUucGF0aClcbiAgICAgICAgY29uc3QgbGluayA9IHRoaXMuYXBwLmZpbGVNYW5hZ2VyLmdlbmVyYXRlTWFya2Rvd25MaW5rKFxuICAgICAgICAgICAgZGVzdEZpbGUsXG4gICAgICAgICAgICB0aGlzLmZpbGUucGF0aCxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkQWxpYXNbZGVzdEZpbGUuYmFzZW5hbWVdXG4gICAgICAgIClcbiAgICAgICAgcmV0dXJuIGxpbmtcbiAgICB9XG5cbiAgICBidWlsZE5ld0xpbmUoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGxlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuYWN0aXZlTGVhZlxuXG4gICAgICAgIGlmIChsZWFmLnZpZXcgaW5zdGFuY2VvZiBNYXJrZG93blZpZXcgJiYgbGVhZi52aWV3LmVkaXRvcikge1xuICAgICAgICAgICAgY29uc3QgZWRpdG9yID0gbGVhZi52aWV3LmVkaXRvclxuICAgICAgICAgICAgY29uc3QgbGluZUF0Q3Vyc29yID0gZWRpdG9yLmdldExpbmUodGhpcy5jdXJzb3JQb3NpdGlvbi5saW5lKVxuICAgICAgICAgICAgY29uc3Qgc3RhcnRMaW5lID0gbGluZUF0Q3Vyc29yLnN1YnN0cigwLCB0aGlzLmN1cnNvclBvc2l0aW9uLmNoKVxuICAgICAgICAgICAgY29uc3QgY29udGVudCA9IHRoaXMuc2VsZWN0ZWRSZXN1bHRzLm1hcChyID0+IHRoaXMuYnVpbGRNYXJrRG93bkxpbmsocikpLm1hcChsID0+IHRoaXMucHJlcGVuZCArIGwpLmpvaW4odGhpcy5hcHBlbmQpXG4gICAgICAgICAgICBjb25zdCBlbmRMaW5lID0gbGluZUF0Q3Vyc29yLnN1YnN0cih0aGlzLmN1cnNvclBvc2l0aW9uLmNoLCBsaW5lQXRDdXJzb3IubGVuZ3RoIC0gdGhpcy5jdXJzb3JQb3NpdGlvbi5jaClcbiAgICAgICAgICAgIGVkaXRvci5zZXRMaW5lKHRoaXMuY3Vyc29yUG9zaXRpb24ubGluZSwgc3RhcnRMaW5lICsgY29udGVudCArIGVuZExpbmUpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwb3B1bGF0ZVZhbHVlc0dyaWQodmFsdWVHcmlkOiBIVE1MRGl2RWxlbWVudCwgZmlsZVBhdGhzOiBzdHJpbmdbXSkge1xuICAgICAgICBmaWxlUGF0aHMuZm9yRWFjaChmaWxlUGF0aCA9PiB7XG4gICAgICAgICAgICBjb25zdCBkZXN0RmlsZSA9IHRoaXMuYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Rmlyc3RMaW5rcGF0aERlc3QoZmlsZVBhdGgsIHRoaXMuZmlsZS5wYXRoKVxuICAgICAgICAgICAgdGhpcy5idWlsZFZhbHVlVG9nZ2xlcih2YWx1ZUdyaWQsIGRlc3RGaWxlLCB0aGlzLmJ1aWxkQWxpYXNlc0xpc3QoZGVzdEZpbGUpKVxuICAgICAgICB9KVxuICAgICAgICBjb25zdCBkaXZpZGVyID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRGl2KClcbiAgICAgICAgZGl2aWRlci5pbm5lckhUTUwgPSBcIjxocj5cIlxuXG4gICAgICAgIGNvbnN0IGhlbHBlciA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IFwic2VwYXJhdG9yLWhlbHBlci1sYWJlbFwiXG4gICAgICAgIH0pXG4gICAgICAgIGhlbHBlci5zZXRUZXh0KFwicHJlcGVuZC9hcHBlbmQgc3RyaW5ncyB0byB0aGUgbGlua3NcIilcbiAgICAgICAgY29uc3QgZm9vdGVyID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogXCJ2YWx1ZS1ncmlkLWZvb3RlclwiXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IHNlcGFyYXRvckNvbnRhaW5lciA9IGZvb3Rlci5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiAnc2VwYXJhdG9yLWNvbnRhaW5lcidcbiAgICAgICAgfSlcbiAgICAgICAgY29uc3QgcHJlcGVuZCA9IG5ldyBUZXh0Q29tcG9uZW50KHNlcGFyYXRvckNvbnRhaW5lcilcbiAgICAgICAgcHJlcGVuZC5pbnB1dEVsLnNpemUgPSAxMFxuICAgICAgICBwcmVwZW5kLnNldFZhbHVlKHRoaXMucHJlcGVuZClcbiAgICAgICAgY29uc3QgbGlua0xhYmVsID0gc2VwYXJhdG9yQ29udGFpbmVyLmNyZWF0ZURpdih7XG4gICAgICAgICAgICBjbHM6IFwic2VwYXJhdG9yLWxpbmstbGFiZWxcIlxuICAgICAgICB9KVxuICAgICAgICBsaW5rTGFiZWwuc2V0VGV4dChcIiBbW0xpbmtdXSBcIilcbiAgICAgICAgcHJlcGVuZC5vbkNoYW5nZSh2YWx1ZSA9PiB0aGlzLnByZXBlbmQgPSB2YWx1ZSlcbiAgICAgICAgY29uc3QgYXBwZW5kID0gbmV3IFRleHRBcmVhQ29tcG9uZW50KHNlcGFyYXRvckNvbnRhaW5lcilcbiAgICAgICAgYXBwZW5kLmlucHV0RWwuY29scyA9IDNcbiAgICAgICAgYXBwZW5kLmlucHV0RWwucm93cyA9IDJcbiAgICAgICAgYXBwZW5kLnNldFZhbHVlKHRoaXMuYXBwZW5kKVxuICAgICAgICBhcHBlbmQub25DaGFuZ2UodmFsdWUgPT4gdGhpcy5hcHBlbmQgPSB2YWx1ZSlcbiAgICAgICAgY29uc3QgYnV0dG9uc0NvbnRhaW5lciA9IGZvb3Rlci5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiAnYnV0dG9ucy1jb250YWluZXInXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IHNhdmVCdXR0b24gPSBuZXcgQnV0dG9uQ29tcG9uZW50KGJ1dHRvbnNDb250YWluZXIpXG4gICAgICAgIHNhdmVCdXR0b24uc2V0SWNvbihcImNoZWNrbWFya1wiKVxuICAgICAgICBzYXZlQnV0dG9uLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5zZWxlY3RlZFJlc3VsdHMsIHRoaXMuc2VsZWN0ZWRBbGlhcylcbiAgICAgICAgICAgIHRoaXMuYnVpbGROZXdMaW5lKClcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKVxuICAgICAgICB9KVxuICAgICAgICBjb25zdCBjYW5jZWxCdXR0b24gPSBuZXcgRXh0cmFCdXR0b25Db21wb25lbnQoYnV0dG9uc0NvbnRhaW5lcilcbiAgICAgICAgY2FuY2VsQnV0dG9uLnNldEljb24oXCJjcm9zc1wiKVxuICAgICAgICBjYW5jZWxCdXR0b24ub25DbGljaygoKSA9PiB0aGlzLmNsb3NlKCkpXG4gICAgfVxufSIsICJpbXBvcnQgeyBQbHVnaW5TZXR0aW5nVGFiLCBBcHAsIFNldHRpbmcsIEJ1dHRvbkNvbXBvbmVudCB9IGZyb20gXCJvYnNpZGlhblwiXG5pbXBvcnQgTXVsdGlTZWxlY3QgZnJvbSBcIm1haW5cIlxuaW1wb3J0IFF1ZXJ5IGZyb20gXCJzcmMvcXVlcmllcy9RdWVyeVwiXG5pbXBvcnQgUXVlcnlTZXR0aW5nIGZyb20gJ3NyYy9zZXR0aW5ncy9RdWVyeVNldHRpbmcnXG5pbXBvcnQgUXVlcnlTZXR0aW5nTW9kYWwgZnJvbSAnc3JjL3NldHRpbmdzL1F1ZXJ5U2V0dGluZ01vZGFsJ1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNdWx0aVNlbGVjdFNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcbiAgICBwbHVnaW46IE11bHRpU2VsZWN0XG5cbiAgICBjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBNdWx0aVNlbGVjdCkge1xuICAgICAgICBzdXBlcihhcHAsIHBsdWdpbik7XG4gICAgICAgIHRoaXMucGx1Z2luID0gcGx1Z2luO1xuICAgIH1cblxuICAgIGRpc3BsYXkoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG5cbiAgICAgICAgY29udGFpbmVyRWwuZW1wdHkoKTtcblxuICAgICAgICBjb250YWluZXJFbC5jcmVhdGVFbCgnaDInLCB7IHRleHQ6ICdTZXR0aW5ncyBmb3IgTXVsdGkgU2VsZWN0LicgfSk7XG5cbiAgICAgICAgLyogQWRkIG5ldyBxdWVyeSovXG4gICAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAgICAgLnNldE5hbWUoXCJBZGQgTmV3IFF1ZXJ5XCIpXG4gICAgICAgICAgICAuc2V0RGVzYyhcIkFkZCBhIG5ldyBxdWVyeSB0byBzZWxlY3QgZmlsZXMgZnJvbSByZXN1bHQuXCIpXG4gICAgICAgICAgICAuYWRkQnV0dG9uKChidXR0b246IEJ1dHRvbkNvbXBvbmVudCk6IEJ1dHRvbkNvbXBvbmVudCA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IGIgPSBidXR0b25cbiAgICAgICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJBZGQgTmV3IFF1ZXJ5XCIpXG4gICAgICAgICAgICAgICAgICAgIC5zZXRCdXR0b25UZXh0KFwiK1wiKVxuICAgICAgICAgICAgICAgICAgICAub25DbGljayhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbW9kYWwgPSBuZXcgUXVlcnlTZXR0aW5nTW9kYWwodGhpcy5hcHAsIHRoaXMucGx1Z2luLCBjb250YWluZXJFbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb2RhbC5vcGVuKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGI7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAvKiBNYW5hZ2VkIHByb3BlcnRpZXMgdGhhdCBjdXJyZW50bHkgaGF2ZSBwcmVzZXQgdmFsdWVzICovXG4gICAgICAgIHRoaXMucGx1Z2luLmluaXRpYWxRdWVyaWVzLmZvckVhY2goc2F2ZWRRdWVyeSA9PiB7XG4gICAgICAgICAgICBjb25zdCBxdWVyeSA9IG5ldyBRdWVyeSgpXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHF1ZXJ5LCBzYXZlZFF1ZXJ5KVxuICAgICAgICAgICAgbmV3IFF1ZXJ5U2V0dGluZyhjb250YWluZXJFbCwgcXVlcnksIHRoaXMuYXBwLCB0aGlzLnBsdWdpbilcbiAgICAgICAgfSlcbiAgICB9XG59IiwgImltcG9ydCB7IEFwcCwgU2V0dGluZyB9IGZyb20gXCJvYnNpZGlhblwiXG5pbXBvcnQgTXVsdGlTZWxlY3QgZnJvbSBcIm1haW5cIlxuaW1wb3J0IFF1ZXJ5IGZyb20gXCJzcmMvcXVlcmllcy9RdWVyeVwiXG5pbXBvcnQgUXVlcnlTZXR0aW5nTW9kYWwgZnJvbSBcInNyYy9zZXR0aW5ncy9RdWVyeVNldHRpbmdNb2RhbFwiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFF1ZXJ5U2V0dGluZyBleHRlbmRzIFNldHRpbmcge1xuICAgIHF1ZXJ5OiBRdWVyeVxuICAgIGFwcDogQXBwXG4gICAgcGx1Z2luOiBNdWx0aVNlbGVjdFxuICAgIGNvbnRhaW5lckVsOiBIVE1MRWxlbWVudFxuICAgIGNvbnN0cnVjdG9yKGNvbnRhaW5lckVsOiBIVE1MRWxlbWVudCwgcXVlcnk6IFF1ZXJ5LCBhcHA6IEFwcCwgcGx1Z2luOiBNdWx0aVNlbGVjdCkge1xuICAgICAgICBzdXBlcihjb250YWluZXJFbClcbiAgICAgICAgdGhpcy5jb250YWluZXJFbCA9IGNvbnRhaW5lckVsXG4gICAgICAgIHRoaXMucXVlcnkgPSBxdWVyeVxuICAgICAgICB0aGlzLmFwcCA9IGFwcFxuICAgICAgICB0aGlzLnBsdWdpbiA9IHBsdWdpblxuICAgICAgICB0aGlzLnNldFRleHRDb250ZW50V2l0aG5hbWUoKVxuICAgICAgICB0aGlzLmFkZEVkaXRCdXR0b24oKVxuICAgICAgICB0aGlzLmFkZERlbGV0ZUJ1dHRvbigpXG4gICAgfVxuXG4gICAgc2V0VGV4dENvbnRlbnRXaXRobmFtZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXROYW1lKHRoaXMucXVlcnkubmFtZSlcbiAgICAgICAgdGhpcy5zZXREZXNjKHRoaXMucXVlcnkuZGVzY3JpcHRpb24pXG4gICAgfVxuXG5cbiAgICBhZGRFZGl0QnV0dG9uKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmFkZEJ1dHRvbigoYikgPT4ge1xuICAgICAgICAgICAgYi5zZXRJY29uKFwicGVuY2lsXCIpXG4gICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJFZGl0XCIpXG4gICAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbW9kYWwgPSBuZXcgUXVlcnlTZXR0aW5nTW9kYWwodGhpcy5hcHAsIHRoaXMucGx1Z2luLCB0aGlzLmNvbnRhaW5lckVsLCB0aGlzLCB0aGlzLnF1ZXJ5KTtcbiAgICAgICAgICAgICAgICAgICAgbW9kYWwub3BlbigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgIH1cblxuICAgIGFkZERlbGV0ZUJ1dHRvbigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hZGRCdXR0b24oKGIpID0+IHtcbiAgICAgICAgICAgIGIuc2V0SWNvbihcInRyYXNoXCIpXG4gICAgICAgICAgICAgICAgLnNldFRvb2x0aXAoXCJEZWxldGVcIilcbiAgICAgICAgICAgICAgICAub25DbGljaygoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vcmVtb3ZlIHRoZSBjb21tYW5kXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRFeGlzdGluZ1F1ZXJ5ID0gdGhpcy5wbHVnaW4uaW5pdGlhbFF1ZXJpZXMuZmlsdGVyKHAgPT4gcC5pZCA9PSB0aGlzLnF1ZXJ5LmlkKVswXVxuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudEV4aXN0aW5nUXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLmluaXRpYWxRdWVyaWVzLnJlbW92ZShjdXJyZW50RXhpc3RpbmdRdWVyeSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHAuY29tbWFuZHMucmVtb3ZlQ29tbWFuZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBgJHt0aGlzLnBsdWdpbi5tYW5pZmVzdC5pZH06bXVsdGlTZWxlY3QtJHtjdXJyZW50RXhpc3RpbmdRdWVyeS5uYW1lfWBcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXR0aW5nRWwucGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZCh0aGlzLnNldHRpbmdFbClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKClcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxufSIsICJpbXBvcnQgeyBBcHAsIE1vZGFsLCBTZXR0aW5nLCBUZXh0Q29tcG9uZW50LCBOb3RpY2UsIEJ1dHRvbkNvbXBvbmVudCwgRXh0cmFCdXR0b25Db21wb25lbnQsIFRleHRBcmVhQ29tcG9uZW50IH0gZnJvbSBcIm9ic2lkaWFuXCJcbmltcG9ydCBNdWx0aVNlbGVjdCBmcm9tIFwibWFpblwiXG5pbXBvcnQgUXVlcnkgZnJvbSBcInNyYy9xdWVyaWVzL1F1ZXJ5XCJcbmltcG9ydCBRdWVyeVNldHRpbmcgZnJvbSBcInNyYy9zZXR0aW5ncy9RdWVyeVNldHRpbmdcIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBRdWVyeVNldHRpbmdzTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG4gICAgbmFtZVByb21wdENvbXBvbmVudDogVGV4dENvbXBvbmVudFxuICAgIGRlc2NyaXB0aW9uUHJvbXB0Q29tcG9uZW50OiBUZXh0Q29tcG9uZW50XG4gICAgcXVlcnlQcm9tcHRDb21wb25lbnQ6IFRleHRBcmVhQ29tcG9uZW50XG4gICAgc2F2ZWQ6IGJvb2xlYW4gPSBmYWxzZVxuICAgIHF1ZXJ5OiBRdWVyeVxuICAgIHBsdWdpbjogTXVsdGlTZWxlY3RcbiAgICBpbml0aWFsUXVlcnk6IFF1ZXJ5XG4gICAgcGFyZW50U2V0dGluZzogUXVlcnlTZXR0aW5nXG4gICAgbmV3OiBib29sZWFuID0gdHJ1ZVxuICAgIHBhcmVudFNldHRpbmdDb250YWluZXI6IEhUTUxFbGVtZW50XG5cblxuICAgIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IE11bHRpU2VsZWN0LCBwYXJlbnRTZXR0aW5nQ29udGFpbmVyOiBIVE1MRWxlbWVudCwgcGFyZW50U2V0dGluZz86IFF1ZXJ5U2V0dGluZywgcXVlcnk/OiBRdWVyeSkge1xuICAgICAgICBzdXBlcihhcHApXG4gICAgICAgIHRoaXMucGx1Z2luID0gcGx1Z2luXG4gICAgICAgIHRoaXMucGFyZW50U2V0dGluZyA9IHBhcmVudFNldHRpbmdcbiAgICAgICAgdGhpcy5pbml0aWFsUXVlcnkgPSBuZXcgUXVlcnkoKVxuICAgICAgICB0aGlzLnBhcmVudFNldHRpbmdDb250YWluZXIgPSBwYXJlbnRTZXR0aW5nQ29udGFpbmVyXG4gICAgICAgIGlmIChxdWVyeSkge1xuICAgICAgICAgICAgdGhpcy5uZXcgPSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5xdWVyeSA9IHF1ZXJ5XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxRdWVyeS5uYW1lID0gcXVlcnkubmFtZVxuICAgICAgICAgICAgdGhpcy5pbml0aWFsUXVlcnkuaWQgPSBxdWVyeS5pZFxuICAgICAgICAgICAgdGhpcy5pbml0aWFsUXVlcnkuZGVzY3JpcHRpb24gPSBxdWVyeS5kZXNjcmlwdGlvblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG5ld0lkID0gMVxuICAgICAgICAgICAgdGhpcy5wbHVnaW4uaW5pdGlhbFF1ZXJpZXMuZm9yRWFjaChxdWVyeSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlSW50KHF1ZXJ5LmlkKSAmJiBwYXJzZUludChxdWVyeS5pZCkgPj0gbmV3SWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbmV3SWQgPSBwYXJzZUludChxdWVyeS5pZCkgKyAxXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHRoaXMucXVlcnkgPSBuZXcgUXVlcnkoKVxuICAgICAgICAgICAgdGhpcy5xdWVyeS5pZCA9IG5ld0lkLnRvU3RyaW5nKClcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbFF1ZXJ5LmlkID0gbmV3SWQudG9TdHJpbmcoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25PcGVuKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5xdWVyeS5uYW1lID09IFwiXCIpIHtcbiAgICAgICAgICAgIHRoaXMudGl0bGVFbC5zZXRUZXh0KGBBZGQgYSBxdWVyeWApXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRpdGxlRWwuc2V0VGV4dChgTWFuYWdlIHF1ZXJ5ICR7dGhpcy5xdWVyeS5uYW1lfWApXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jcmVhdGVGb3JtKClcbiAgICB9XG5cbiAgICBvbkNsb3NlKCk6IHZvaWQge1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMucXVlcnksIHRoaXMuaW5pdGlhbFF1ZXJ5KVxuICAgICAgICBpZiAoIXRoaXMubmV3KSB7XG4gICAgICAgICAgICB0aGlzLnBhcmVudFNldHRpbmcuc2V0VGV4dENvbnRlbnRXaXRobmFtZSgpXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zYXZlZCkge1xuICAgICAgICAgICAgbmV3IFF1ZXJ5U2V0dGluZyh0aGlzLnBhcmVudFNldHRpbmdDb250YWluZXIsIHRoaXMucXVlcnksIHRoaXMuYXBwLCB0aGlzLnBsdWdpbilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNyZWF0ZU5hbWVJbnB1dENvbnRhaW5lcihwYXJlbnROb2RlOiBIVE1MRGl2RWxlbWVudCk6IFRleHRDb21wb25lbnQge1xuICAgICAgICBjb25zdCBxdWVyeU5hbWVDb250YWluZXJMYWJlbCA9IHBhcmVudE5vZGUuY3JlYXRlRGl2KClcbiAgICAgICAgcXVlcnlOYW1lQ29udGFpbmVyTGFiZWwuc2V0VGV4dChgUXVlcnkgTmFtZTpgKVxuICAgICAgICBjb25zdCBpbnB1dCA9IG5ldyBUZXh0Q29tcG9uZW50KHBhcmVudE5vZGUpXG4gICAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLnF1ZXJ5Lm5hbWVcbiAgICAgICAgaW5wdXQuc2V0VmFsdWUobmFtZSlcbiAgICAgICAgaW5wdXQuc2V0UGxhY2Vob2xkZXIoXCJOYW1lIG9mIHRoZSBxdWVyeVwiKVxuICAgICAgICBpbnB1dC5vbkNoYW5nZSh2YWx1ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLnF1ZXJ5Lm5hbWUgPSB2YWx1ZVxuICAgICAgICAgICAgdGhpcy50aXRsZUVsLnNldFRleHQoYE1hbmFnZSAke3RoaXMucXVlcnkubmFtZX1gKVxuICAgICAgICAgICAgUXVlcnlTZXR0aW5nc01vZGFsLnJlbW92ZVZhbGlkYXRpb25FcnJvcihpbnB1dClcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIGlucHV0XG4gICAgfVxuXG4gICAgY3JlYXRlRGVzY3JpcHRpb25JbnB1dENvbnRhaW5lcihwYXJlbnROb2RlOiBIVE1MRGl2RWxlbWVudCk6IFRleHRDb21wb25lbnQge1xuICAgICAgICBjb25zdCBxdWVyeURlc2NyaXB0aW9uQ29udGFpbmVyTGFiZWwgPSBwYXJlbnROb2RlLmNyZWF0ZURpdigpXG4gICAgICAgIHF1ZXJ5RGVzY3JpcHRpb25Db250YWluZXJMYWJlbC5zZXRUZXh0KGBRdWVyeSBEZXNjcmlwdGlvbjpgKVxuICAgICAgICBjb25zdCBpbnB1dCA9IG5ldyBUZXh0Q29tcG9uZW50KHBhcmVudE5vZGUpXG4gICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5xdWVyeS5kZXNjcmlwdGlvblxuICAgICAgICBpbnB1dC5zZXRWYWx1ZShkZXNjcmlwdGlvbilcbiAgICAgICAgaW5wdXQuc2V0UGxhY2Vob2xkZXIoXCJEZXNjcmlwdGlvbiBvZiB0aGUgcXVlcnlcIilcbiAgICAgICAgaW5wdXQub25DaGFuZ2UodmFsdWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5xdWVyeS5kZXNjcmlwdGlvbiA9IHZhbHVlXG4gICAgICAgICAgICBRdWVyeVNldHRpbmdzTW9kYWwucmVtb3ZlVmFsaWRhdGlvbkVycm9yKGlucHV0KVxuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gaW5wdXRcbiAgICB9XG5cbiAgICBjcmVhdGVEYXRhdmlld0pTSW5wdXRDb250YWluZXIocGFyZW50Tm9kZTogSFRNTERpdkVsZW1lbnQpOiBUZXh0QXJlYUNvbXBvbmVudCB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5RGF0YXZpZXdKU1F1ZXJ5Q29udGFpbmVyTGFiZWwgPSBwYXJlbnROb2RlLmNyZWF0ZURpdigpXG4gICAgICAgIHF1ZXJ5RGF0YXZpZXdKU1F1ZXJ5Q29udGFpbmVyTGFiZWwuc2V0VGV4dChgRGF0YXZpZXdKUyBxdWVyeTpgKVxuICAgICAgICBjb25zdCBpbnB1dCA9IG5ldyBUZXh0QXJlYUNvbXBvbmVudChwYXJlbnROb2RlKVxuICAgICAgICBjb25zdCBkYXRhdmlld0pTUXVlcnkgPSB0aGlzLnF1ZXJ5LmRhdGF2aWV3SlNRdWVyeVxuICAgICAgICBpbnB1dC5pbnB1dEVsLmNvbHMgPSAxMDBcbiAgICAgICAgaW5wdXQuaW5wdXRFbC5yb3dzID0gMTVcbiAgICAgICAgaW5wdXQuc2V0UGxhY2Vob2xkZXIoXCJEYXRhdmlld2pzIHN5bnRheCB0byBxdWVyeSBwYWdlc1xcbkV4YW1wbGU6XFxuZHYucGFnZXMoXFxcIiNTb21lVGFnXFxcIikud2hlcmUocCA9PiBwLmZpZWxkID09PSBcXFwic29tZSB2YWx1ZVxcXCIpLnNvcnQocCA9PiBjb25kaXRpb24sICdhc2MnKVwiKVxuICAgICAgICBpbnB1dC5zZXRWYWx1ZShkYXRhdmlld0pTUXVlcnkgPz8gXCJcIilcbiAgICAgICAgaW5wdXQub25DaGFuZ2UodmFsdWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5xdWVyeS5kYXRhdmlld0pTUXVlcnkgPSB2YWx1ZVxuICAgICAgICAgICAgUXVlcnlTZXR0aW5nc01vZGFsLnJlbW92ZVZhbGlkYXRpb25FcnJvcihpbnB1dClcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIGlucHV0XG4gICAgfVxuXG4gICAgY3JlYXRlRm9ybSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZGl2ID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRGl2KHtcbiAgICAgICAgICAgIGNsczogXCJmcm9udG1hdHRlci1wcm9tcHQtZGl2XCJcbiAgICAgICAgfSlcbiAgICAgICAgY29uc3QgbWFpbkRpdiA9IGRpdi5jcmVhdGVEaXYoe1xuICAgICAgICAgICAgY2xzOiBcImZyb250bWF0dGVyLXByb21wdC1mb3JtXCJcbiAgICAgICAgfSlcbiAgICAgICAgLyogUHJvcGVydHkgTmFtZSBTZWN0aW9uICovXG4gICAgICAgIGNvbnN0IG5hbWVDb250YWluZXIgPSBtYWluRGl2LmNyZWF0ZURpdigpXG4gICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uQ29udGFpbmVyID0gbWFpbkRpdi5jcmVhdGVEaXYoKVxuICAgICAgICBjb25zdCBkYXRhdmlld0pTUXVlcnlDb250YWluZXIgPSBtYWluRGl2LmNyZWF0ZURpdigpXG4gICAgICAgIHRoaXMubmFtZVByb21wdENvbXBvbmVudCA9IHRoaXMuY3JlYXRlTmFtZUlucHV0Q29udGFpbmVyKG5hbWVDb250YWluZXIpXG4gICAgICAgIHRoaXMuZGVzY3JpcHRpb25Qcm9tcHRDb21wb25lbnQgPSB0aGlzLmNyZWF0ZURlc2NyaXB0aW9uSW5wdXRDb250YWluZXIoZGVzY3JpcHRpb25Db250YWluZXIpXG4gICAgICAgIHRoaXMucXVlcnlQcm9tcHRDb21wb25lbnQgPSB0aGlzLmNyZWF0ZURhdGF2aWV3SlNJbnB1dENvbnRhaW5lcihkYXRhdmlld0pTUXVlcnlDb250YWluZXIpXG5cbiAgICAgICAgbWFpbkRpdi5jcmVhdGVEaXYoKS5jcmVhdGVFbChcImhyXCIpXG5cbiAgICAgICAgLyogZm9vdGVyIGJ1dHRvbnMqL1xuICAgICAgICBjb25zdCBmb290ZXJFbCA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdigpXG4gICAgICAgIGNvbnN0IGZvb3RlckJ1dHRvbnMgPSBuZXcgU2V0dGluZyhmb290ZXJFbClcbiAgICAgICAgZm9vdGVyQnV0dG9ucy5hZGRCdXR0b24oKGIpID0+IHRoaXMuY3JlYXRlU2F2ZUJ1dHRvbihiKSlcbiAgICAgICAgZm9vdGVyQnV0dG9ucy5hZGRFeHRyYUJ1dHRvbigoYikgPT4gdGhpcy5jcmVhdGVDYW5jZWxCdXR0b24oYikpO1xuICAgIH1cblxuICAgIGNyZWF0ZVNhdmVCdXR0b24oYjogQnV0dG9uQ29tcG9uZW50KTogQnV0dG9uQ29tcG9uZW50IHtcbiAgICAgICAgYi5zZXRUb29sdGlwKFwiU2F2ZVwiKVxuICAgICAgICAgICAgLnNldEljb24oXCJjaGVja21hcmtcIilcbiAgICAgICAgICAgIC5vbkNsaWNrKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZXJyb3IgPSBmYWxzZVxuICAgICAgICAgICAgICAgIGlmICgvXlsjPi1dLy50ZXN0KHRoaXMucXVlcnkubmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgUXVlcnlTZXR0aW5nc01vZGFsLnNldFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmFtZVByb21wdENvbXBvbmVudCwgdGhpcy5uYW1lUHJvbXB0Q29tcG9uZW50LmlucHV0RWwsXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlF1ZXJ5IG5hbWUgY2Fubm90IHN0YXJ0IHdpdGggIywgPiwgLVwiXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucXVlcnkubmFtZSA9PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIFF1ZXJ5U2V0dGluZ3NNb2RhbC5zZXRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5hbWVQcm9tcHRDb21wb25lbnQsIHRoaXMubmFtZVByb21wdENvbXBvbmVudC5pbnB1dEVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJQcm9wZXJ0eSBuYW1lIGNhbiBub3QgYmUgRW1wdHlcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHRydWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoXCJGaXggZXJyb3JzIGJlZm9yZSBzYXZpbmcuXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRFeGlzdGluZ1F1ZXJ5ID0gdGhpcy5wbHVnaW4uaW5pdGlhbFF1ZXJpZXMuZmlsdGVyKHEgPT4gcS5pZCA9PSB0aGlzLnF1ZXJ5LmlkKVswXVxuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50RXhpc3RpbmdRdWVyeSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5pbml0aWFsUXVlcmllcy5yZW1vdmUoY3VycmVudEV4aXN0aW5nUXVlcnkpXG4gICAgICAgICAgICAgICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcC5jb21tYW5kcy5yZW1vdmVDb21tYW5kKFxuICAgICAgICAgICAgICAgICAgICAgICAgYCR7dGhpcy5wbHVnaW4ubWFuaWZlc3QuaWR9Om11bHRpU2VsZWN0LSR7Y3VycmVudEV4aXN0aW5nUXVlcnkubmFtZX1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLmluaXRpYWxRdWVyaWVzLnB1c2godGhpcy5xdWVyeSlcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5hZGRNdWx0aVNlbGVjdFF1ZXJ5Q29tbWFuZCh0aGlzLnF1ZXJ5KVxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdGlhbFF1ZXJ5ID0gdGhpcy5xdWVyeVxuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIGJcbiAgICB9XG5cbiAgICBjcmVhdGVDYW5jZWxCdXR0b24oYjogRXh0cmFCdXR0b25Db21wb25lbnQpOiBFeHRyYUJ1dHRvbkNvbXBvbmVudCB7XG4gICAgICAgIGIuc2V0SWNvbihcImNyb3NzXCIpXG4gICAgICAgICAgICAuc2V0VG9vbHRpcChcIkNhbmNlbFwiKVxuICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAvKiByZXNldCB2YWx1ZXMgZnJvbSBzZXR0aW5ncyAqL1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmluaXRpYWxRdWVyeS5uYW1lICE9IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLnF1ZXJ5LCB0aGlzLmluaXRpYWxRdWVyeSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBiO1xuICAgIH1cblxuICAgIC8qIHV0aWxzIGZ1bmN0aW9ucyAqL1xuXG4gICAgc3RhdGljIHNldFZhbGlkYXRpb25FcnJvcih0ZXh0SW5wdXQ6IFRleHRDb21wb25lbnQgfCBUZXh0QXJlYUNvbXBvbmVudCwgaW5zZXJ0QWZ0ZXI6IEVsZW1lbnQsIG1lc3NhZ2U/OiBzdHJpbmcpIHtcbiAgICAgICAgdGV4dElucHV0LmlucHV0RWwuYWRkQ2xhc3MoXCJpcy1pbnZhbGlkXCIpO1xuICAgICAgICBpZiAobWVzc2FnZSkge1xuXG4gICAgICAgICAgICBsZXQgbURpdiA9IHRleHRJbnB1dC5pbnB1dEVsLnBhcmVudEVsZW1lbnQucXVlcnlTZWxlY3RvcihcbiAgICAgICAgICAgICAgICBcIi5pbnZhbGlkLWZlZWRiYWNrXCJcbiAgICAgICAgICAgICkgYXMgSFRNTERpdkVsZW1lbnQ7XG5cbiAgICAgICAgICAgIGlmICghbURpdikge1xuICAgICAgICAgICAgICAgIG1EaXYgPSBjcmVhdGVEaXYoeyBjbHM6IFwiaW52YWxpZC1mZWVkYmFja1wiIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbURpdi5pbm5lclRleHQgPSBtZXNzYWdlO1xuICAgICAgICAgICAgbURpdi5pbnNlcnRBZnRlcihpbnNlcnRBZnRlcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIHJlbW92ZVZhbGlkYXRpb25FcnJvcih0ZXh0SW5wdXQ6IFRleHRDb21wb25lbnQgfCBUZXh0QXJlYUNvbXBvbmVudCkge1xuICAgICAgICBpZiAodGV4dElucHV0LmlucHV0RWwuaGFzQ2xhc3MoXCJpcy1pbnZhbGlkXCIpKSB7XG4gICAgICAgICAgICB0ZXh0SW5wdXQuaW5wdXRFbC5yZW1vdmVDbGFzcyhcImlzLWludmFsaWRcIilcbiAgICAgICAgICAgIHRleHRJbnB1dC5pbnB1dEVsLnBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoXG4gICAgICAgICAgICAgICAgdGV4dElucHV0LmlucHV0RWwucGFyZW50RWxlbWVudC5sYXN0RWxlbWVudENoaWxkXG4gICAgICAgICAgICApXG4gICAgICAgIH1cbiAgICB9XG59Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQSx1QkFBcUM7OztBQ005QixJQUFNLG1CQUF3QztBQUFBLEVBQ2pELFNBQVM7QUFBQTs7O0FDQWIsa0JBQVk7QUFBQSxFQUVSLFlBQVksT0FBZSxJQUN2QixjQUFzQixJQUN0QixLQUFhLElBQ2Isa0JBQTBCLE1BQU07QUFDaEMsU0FBSyxPQUFPO0FBQ1osU0FBSyxjQUFjO0FBQ25CLFNBQUssS0FBSztBQUNWLFNBQUssa0JBQWtCO0FBQUE7QUFBQSxTQUdwQixVQUFVLFFBQWUsUUFBZTtBQUMzQyxXQUFPLEtBQUssT0FBTztBQUNuQixXQUFPLE9BQU8sT0FBTztBQUNyQixXQUFPLGNBQWMsT0FBTztBQUM1QixXQUFPLGtCQUFrQixPQUFPO0FBQUE7QUFBQTtBQUl4QyxJQUFPLGdCQUFROzs7QUMzQmYsc0JBYU87QUFLUCxxQ0FBOEMsc0JBQU07QUFBQSxFQVdoRCxZQUFZLEtBQVUsUUFBcUIsT0FBYyxnQkFBZ0MsTUFBYTtBQUNsRyxVQUFNO0FBQ04sU0FBSyxTQUFTO0FBQ2QsU0FBSyxRQUFRO0FBQ2IsU0FBSyxpQkFBaUI7QUFDdEIsU0FBSyxVQUFVO0FBQ2YsU0FBSyxrQkFBa0I7QUFDdkIsU0FBSyxnQkFBZ0I7QUFDckIsU0FBSyxPQUFPO0FBQ1osU0FBSyxVQUFVO0FBQ2YsU0FBSyxTQUFTO0FBQUE7QUFBQSxFQUdsQixTQUFTO0FBMUNiO0FBNENRLFVBQU0sYUFBYSxDQUFDLFFBQStCO0FBQy9DLGFBQVEsSUFBSSxTQUFTLE1BQU0sVUFBVSxLQUFLLE1BQU0sbUJBQW9CO0FBQUE7QUFFeEUsVUFBTSxZQUFZLEtBQUssVUFBVSxV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
|