D /sublimated/undefined +0 -700
D /sublimated/undefined +0 -700
1var __defProp = Object.defineProperty;2var __getOwnPropDesc = Object.getOwnPropertyDescriptor;3var __getOwnPropNames = Object.getOwnPropertyNames;4var __hasOwnProp = Object.prototype.hasOwnProperty;5var __export = (target, all) => {6 for (var name in all)7 __defProp(target, name, { get: all[name], enumerable: true });8};9var __copyProps = (to, from, except, desc) => {10 if (from && typeof from === "object" || typeof from === "function") {11 for (let key of __getOwnPropNames(from))12 if (!__hasOwnProp.call(to, key) && key !== except)13 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });14 }15 return to;16};17var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);18
19// src/main.ts20var main_exports = {};21__export(main_exports, {22 default: () => SublimatedPlugin23});24module.exports = __toCommonJS(main_exports);25var import_obsidian6 = require("obsidian");26
27// src/settings.ts28var import_obsidian2 = require("obsidian");29
30// src/api.ts31var import_obsidian = require("obsidian");32var API_BASE = "https://api.sublimated.com";33var AuthRequiredError = class extends Error {34 constructor(status) {35 super(`auth required (${status})`);36 this.status = status;37 this.name = "AuthRequiredError";38 }39};40var SublimatedApi = class {41 constructor(token) {42 this.token = token;43 }44 async request(path) {45 const headers = {46 Accept: "application/json"47 };48 if (this.token) {49 headers.Authorization = `Bearer ${this.token}`;50 }51 const response = await (0, import_obsidian.requestUrl)({52 url: `${API_BASE}${path}`,53 headers,54 throw: false55 });56 if (response.status === 401 || response.status === 403) {57 throw new AuthRequiredError(response.status);58 }59 if (response.status >= 400) {60 throw new Error(61 `API error ${response.status}: ${response.text}`62 );63 }64 const body = response.json;65 if (!body.ok || body.data === void 0) {66 const msg = body.error?.message || body.error?.type || "unknown error";67 throw new Error(`API error: ${msg}`);68 }69 return body.data;70 }71 async getVersions(spaceSlug, itemId) {72 const raw = await this.request(73 `/v1/spaces/${encodeURIComponent(spaceSlug)}/items/${encodeURIComponent(itemId)}/versions`74 );75 return raw.map(mapVersion).reverse();76 }77 async testConnection() {78 try {79 const data = await this.request(80 "/v1/me"81 );82 return { ok: true, username: data.username };83 } catch (e) {84 return {85 ok: false,86 error: e instanceof Error ? e.message : "Unknown error"87 };88 }89 }90};91function mapVersion(r) {92 const author = r.actors.find((a) => a.role === "author") ?? r.actors[0] ?? null;93 return {94 id: r.id,95 number: r.version,96 authorName: author?.name ?? author?.username ?? "unknown",97 authorType: author?.actor_type ?? "person",98 message: r.message,99 createdAt: r.created_at100 };101}102
103// src/settings.ts104var DEFAULT_SETTINGS = {105 apiToken: "",106 hasSeenWelcome: false107};108var SublimatedSettingTab = class extends import_obsidian2.PluginSettingTab {109 plugin;110 constructor(app, plugin) {111 super(app, plugin);112 this.plugin = plugin;113 }114 display() {115 const { containerEl } = this;116 containerEl.empty();117 const header = containerEl.createDiv({ cls: "sbl-settings-header" });118 header.createEl("h2", { text: "sublimated" });119 header.createEl("p", {120 text: "Sync status, version history, and deep links.",121 cls: "setting-item-description"122 });123 const workspaceInfo = this.plugin.detectWorkspace();124 if (workspaceInfo) {125 new import_obsidian2.Setting(containerEl).setName("Detected workspace").setDesc(126 `Space: ${workspaceInfo.space || "unknown"}`127 );128 } else {129 new import_obsidian2.Setting(containerEl).setName("No sublimated file open").setDesc(130 "Open any synced file from a sublimated folder to see workspace info."131 );132 }133 new import_obsidian2.Setting(containerEl).setName("API token").setDesc(134 "Required for version history. Generate at sublimated.com/settings/tokens"135 ).addText(136 (text) => text.setPlaceholder("sk_...").setValue(this.plugin.settings.apiToken).onChange(async (value) => {137 this.plugin.settings.apiToken = value;138 await this.plugin.saveSettings();139 })140 );141 new import_obsidian2.Setting(containerEl).setName("Test connection").setDesc("Verify your API token works").addButton(142 (btn) => btn.setButtonText("Test").onClick(async () => {143 if (!this.plugin.settings.apiToken) {144 new import_obsidian2.Notice("No API token configured");145 return;146 }147 btn.setButtonText("Testing...");148 btn.setDisabled(true);149 const api = new SublimatedApi(150 this.plugin.settings.apiToken151 );152 const result = await api.testConnection();153 if (result.ok) {154 new import_obsidian2.Notice(155 `Connected as ${result.username}`156 );157 } else {158 new import_obsidian2.Notice(159 `Connection failed: ${result.error}`160 );161 }162 btn.setButtonText("Test");163 btn.setDisabled(false);164 })165 );166 containerEl.createEl("div", { cls: "sbl-settings-links" }, (el) => {167 el.createEl("a", {168 text: "sublimated.com",169 href: "https://sublimated.com"170 });171 el.createEl("span", { text: " \xB7 " });172 el.createEl("a", {173 text: "Documentation",174 href: "https://sublimated.com/docs/obsidian"175 });176 el.createEl("span", { text: " \xB7 " });177 el.createEl("a", {178 text: "Source code",179 href: "https://sublimated.com/sublimated/code/obsidian"180 });181 });182 }183};184
185// src/xattr.ts186var import_child_process = require("child_process");187var import_obsidian3 = require("obsidian");188var XATTR_PREFIX = "com.sublimated.";189var XATTR_SUFFIX = "#PS";190var ATTRS = [191 "version",192 "commit",193 "url",194 "contentHash",195 "id",196 "createdBy",197 "modifiedBy",198 "modifiedByType",199 "syncStatus",200 "space",201 "branch",202 "modifiedAt",203 "visibility"204];205function attrToXattrName(attr) {206 const kebab = attr.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());207 return `${XATTR_PREFIX}${kebab}${XATTR_SUFFIX}`;208}209function readXattr(path, xattrName) {210 return new Promise((resolve) => {211 (0, import_child_process.exec)(212 `xattr -p ${JSON.stringify(xattrName)} ${JSON.stringify(path)}`,213 { timeout: 2e3 },214 (err, stdout) => {215 if (err) {216 resolve(null);217 return;218 }219 resolve(stdout.trim() || null);220 }221 );222 });223}224async function readFileMetadata(path) {225 if (!import_obsidian3.Platform.isMacOS) return null;226 const results = await Promise.all(227 ATTRS.map((attr) => readXattr(path, attrToXattrName(attr)))228 );229 if (results.every((r) => r === null)) return null;230 const meta = {231 version: null,232 commit: null,233 url: null,234 contentHash: null,235 id: null,236 createdBy: null,237 modifiedBy: null,238 modifiedByType: null,239 syncStatus: null,240 space: null,241 branch: null,242 modifiedAt: null,243 visibility: null244 };245 ATTRS.forEach((attr, i) => {246 meta[attr] = results[i];247 });248 return meta;249}250function isMacOS() {251 return import_obsidian3.Platform.isMacOS;252}253
254// src/version-view.ts255var import_obsidian4 = require("obsidian");256var VERSION_VIEW_TYPE = "sublimated-versions";257var VersionView = class extends import_obsidian4.ItemView {258 plugin;259 constructor(leaf, plugin) {260 super(leaf);261 this.plugin = plugin;262 }263 getViewType() {264 return VERSION_VIEW_TYPE;265 }266 getDisplayText() {267 return "sublimated versions";268 }269 getIcon() {270 return "history";271 }272 async onOpen() {273 await this.refresh();274 this.registerEvent(275 this.app.workspace.on("active-leaf-change", () => {276 this.refresh();277 })278 );279 }280 async refresh() {281 const { contentEl } = this;282 contentEl.empty();283 contentEl.addClass("sbl-version-view");284 const activeFile = this.app.workspace.getActiveFile();285 if (!activeFile) {286 contentEl.createEl("p", {287 text: "No file open.",288 cls: "sbl-version-empty"289 });290 return;291 }292 const meta = this.plugin.lastMetadata;293 if (!meta?.space || !meta?.id) {294 contentEl.createEl("p", {295 text: "Not a sublimated file.",296 cls: "sbl-version-empty"297 });298 return;299 }300 contentEl.createEl("h4", {301 text: activeFile.name,302 cls: "sbl-version-filename"303 });304 const loading = contentEl.createEl("p", {305 text: "Loading versions...",306 cls: "sbl-version-loading"307 });308 try {309 const api = new SublimatedApi(this.plugin.settings.apiToken);310 const versions = await api.getVersions(meta.space, meta.id);311 loading.remove();312 if (versions.length === 0) {313 contentEl.createEl("p", {314 text: "No versions found.",315 cls: "sbl-version-empty"316 });317 return;318 }319 const list = contentEl.createEl("div", {320 cls: "sbl-version-list"321 });322 const groups = groupByDay(versions);323 for (const group of groups) {324 list.createEl("div", {325 text: group.label,326 cls: "sbl-version-day"327 });328 for (const v of group.versions) {329 this.renderVersion(list, v, meta.url);330 }331 }332 } catch (e) {333 loading.remove();334 if (e instanceof AuthRequiredError) {335 contentEl.createEl("p", {336 text: "This file is private \u2014 add an API token to view version history.",337 cls: "sbl-version-empty"338 });339 contentEl.createEl("p", {340 text: "Configure in Settings \u2192 sublimated",341 cls: "sbl-version-hint"342 });343 return;344 }345 contentEl.createEl("p", {346 text: `Error: ${e instanceof Error ? e.message : "Unknown"}`,347 cls: "sbl-version-error"348 });349 }350 }351 renderVersion(container, v, fileUrl) {352 const item = container.createDiv({ cls: "sbl-version-item" });353 const header = item.createDiv({ cls: "sbl-version-header" });354 header.createEl("span", {355 text: `v${v.number}`,356 cls: "sbl-version-number"357 });358 header.createEl("span", {359 text: v.authorName,360 cls: "sbl-version-author"361 });362 const time = item.createDiv({ cls: "sbl-version-time" });363 time.createEl("span", {364 text: formatRelativeTime(v.createdAt),365 attr: { title: new Date(v.createdAt).toLocaleString() }366 });367 if (v.message) {368 item.createDiv({369 text: v.message,370 cls: "sbl-version-message"371 });372 }373 if (fileUrl) {374 const webUrl = `https://${fileUrl}/~versions/v${v.number}`;375 const link = item.createEl("a", {376 text: "view on web",377 cls: "sbl-version-web-link",378 href: webUrl379 });380 link.addEventListener("click", (e) => {381 e.preventDefault();382 window.open(webUrl);383 });384 }385 }386 async onClose() {387 }388};389function groupByDay(versions) {390 const groups = /* @__PURE__ */ new Map();391 const order = [];392 for (const v of versions) {393 const label = formatDayLabel(v.createdAt);394 if (!groups.has(label)) {395 groups.set(label, []);396 order.push(label);397 }398 groups.get(label).push(v);399 }400 return order.map((label) => ({401 label,402 versions: groups.get(label)403 }));404}405function formatDayLabel(iso) {406 const now = /* @__PURE__ */ new Date();407 const date = new Date(iso);408 const nowDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());409 const thenDay = new Date(410 date.getFullYear(),411 date.getMonth(),412 date.getDate()413 );414 const days = Math.round(415 (nowDay.getTime() - thenDay.getTime()) / (1e3 * 60 * 60 * 24)416 );417 if (days === 0) return "Today";418 if (days === 1) return "Yesterday";419 if (days < 7) return `${days} days ago`;420 return date.toLocaleDateString("en-US", {421 month: "short",422 day: "numeric"423 });424}425function formatRelativeTime(iso) {426 const now = Date.now();427 const then = new Date(iso).getTime();428 const diff = now - then;429 const seconds = Math.floor(diff / 1e3);430 const minutes = Math.floor(seconds / 60);431 const hours = Math.floor(minutes / 60);432 const days = Math.floor(hours / 24);433 if (days > 30) return new Date(iso).toLocaleDateString();434 if (days > 0) return `${days}d ago`;435 if (hours > 0) return `${hours}h ago`;436 if (minutes > 0) return `${minutes}m ago`;437 return "just now";438}439
440// src/welcome-modal.ts441var import_obsidian5 = require("obsidian");442var WelcomeModal = class extends import_obsidian5.Modal {443 constructor(app) {444 super(app);445 }446 onOpen() {447 const { contentEl } = this;448 contentEl.addClass("sbl-welcome-modal");449 contentEl.createEl("h2", { text: "Welcome to sublimated" });450 contentEl.createEl("p", {451 text: "sublimated syncs your files with version history, collaboration, and a web viewer \u2014 all powered by git under the hood."452 });453 const steps = contentEl.createEl("div", { cls: "sbl-welcome-steps" });454 const step1 = steps.createDiv({ cls: "sbl-welcome-step" });455 step1.createEl("strong", { text: "1. Open a sublimated folder as a vault" });456 step1.createEl("p", {457 text: "In Finder, open any sublimated folder (or subfolder) under CloudStorage as an Obsidian vault. The plugin activates automatically on synced files."458 });459 const step2 = steps.createDiv({ cls: "sbl-welcome-step" });460 step2.createEl("strong", { text: "2. Status bar shows sync info" });461 step2.createEl("p", {462 text: "The bottom bar shows version number, sync status, and author for the current file \u2014 all read from local file metadata, no account needed."463 });464 const step3 = steps.createDiv({ cls: "sbl-welcome-step" });465 step3.createEl("strong", { text: "3. Add an API token for version history" });466 step3.createEl("p", {467 text: "To browse past versions, add your API token in Settings \u2192 sublimated. Generate one at sublimated.com/settings/tokens."468 });469 const links = contentEl.createDiv({ cls: "sbl-welcome-links" });470 links.createEl("a", {471 text: "Documentation",472 href: "https://sublimated.com/docs/obsidian"473 });474 links.createEl("br");475 links.createEl("a", {476 text: "Source code",477 href: "https://sublimated.com/sublimated/code/obsidian"478 });479 const footer = contentEl.createDiv({ cls: "sbl-welcome-footer" });480 footer.createEl("button", {481 text: "Get started",482 cls: "mod-cta"483 }).addEventListener("click", () => this.close());484 }485 onClose() {486 this.contentEl.empty();487 }488};489
490// src/main.ts491var SublimatedPlugin = class extends import_obsidian6.Plugin {492 settings = DEFAULT_SETTINGS;493 lastMetadata = null;494 statusBarEl = null;495 async onload() {496 await this.loadSettings();497 this.statusBarEl = this.addStatusBarItem();498 this.statusBarEl.addClass("sbl-status-bar");499 this.statusBarEl.addEventListener(500 "click",501 () => this.openCurrentFileOnWeb()502 );503 this.updateStatusBar(null);504 this.registerView(505 VERSION_VIEW_TYPE,506 (leaf) => new VersionView(leaf, this)507 );508 this.addCommand({509 id: "open-on-web",510 name: "Open on sublimated.com",511 callback: () => this.openCurrentFileOnWeb()512 });513 this.addCommand({514 id: "show-versions",515 name: "Show versions",516 callback: () => this.activateVersionView()517 });518 this.addCommand({519 id: "copy-web-link",520 name: "Copy web link",521 callback: () => this.copyWebLink()522 });523 this.addRibbonIcon("history", "sublimated versions", () => {524 this.activateVersionView();525 });526 this.registerObsidianProtocolHandler(527 "sublimated",528 (params) => this.handleUri(params)529 );530 this.addSettingTab(new SublimatedSettingTab(this.app, this));531 this.registerEvent(532 this.app.workspace.on("active-leaf-change", () => {533 this.refreshMetadata();534 })535 );536 this.refreshMetadata();537 if (!this.settings.hasSeenWelcome) {538 new WelcomeModal(this.app).open();539 this.settings.hasSeenWelcome = true;540 await this.saveSettings();541 }542 }543 onunload() {544 this.app.workspace.detachLeavesOfType(VERSION_VIEW_TYPE);545 }546 async loadSettings() {547 this.settings = Object.assign(548 {},549 DEFAULT_SETTINGS,550 await this.loadData()551 );552 }553 async saveSettings() {554 await this.saveData(this.settings);555 }556 // detect workspace from xattrs on the currently active file.557 // every synced file carries com.sublimated.space#PS, so any file558 // with sublimated metadata identifies the workspace.559 detectWorkspace() {560 if (!this.lastMetadata) return null;561 if (!this.lastMetadata.space && !this.lastMetadata.id) return null;562 return {563 space: this.lastMetadata.space ?? null564 };565 }566 async refreshMetadata() {567 const file = this.app.workspace.getActiveFile();568 if (!file) {569 this.lastMetadata = null;570 this.updateStatusBar(null);571 return;572 }573 if (!isMacOS()) {574 this.lastMetadata = null;575 this.updateStatusBar(null);576 return;577 }578 const adapter = this.app.vault.adapter;579 const basePath = adapter.getBasePath?.();580 if (!basePath) {581 this.lastMetadata = null;582 this.updateStatusBar(null);583 return;584 }585 const absPath = `${basePath}/${file.path}`;586 this.lastMetadata = await readFileMetadata(absPath);587 this.updateStatusBar(this.lastMetadata);588 }589 updateStatusBar(meta) {590 if (!this.statusBarEl) return;591 if (!meta || !meta.space && !meta.id) {592 this.statusBarEl.setText("");593 return;594 }595 const parts = [];596 if (meta.syncStatus) {597 const icon = syncStatusIcon(meta.syncStatus);598 parts.push(icon ? `${icon} ${meta.syncStatus}` : meta.syncStatus);599 }600 if (meta.version) {601 parts.push(`v${meta.version}`);602 }603 if (meta.modifiedBy) {604 const prefix = meta.modifiedByType === "ai_agent" ? "by AI:" : "by";605 parts.push(`${prefix} ${meta.modifiedBy}`);606 }607 if (meta.branch && meta.branch !== "main") {608 parts.push(meta.branch);609 }610 if (meta.visibility) {611 parts.push(visibilityIcon(meta.visibility));612 }613 this.statusBarEl.setText(parts.join(" "));614 if (meta.url) {615 this.statusBarEl.addClass("sbl-clickable");616 } else {617 this.statusBarEl.removeClass("sbl-clickable");618 }619 }620 openCurrentFileOnWeb() {621 const url = this.lastMetadata?.url;622 if (!url) {623 new import_obsidian6.Notice("No sublimated URL for this file");624 return;625 }626 window.open(`https://${url}`);627 }628 async copyWebLink() {629 const url = this.lastMetadata?.url;630 if (!url) {631 new import_obsidian6.Notice("No sublimated URL for this file");632 return;633 }634 await navigator.clipboard.writeText(`https://${url}`);635 new import_obsidian6.Notice("Link copied to clipboard");636 }637 async activateVersionView() {638 const existing = this.app.workspace.getLeavesOfType(VERSION_VIEW_TYPE);639 if (existing.length > 0) {640 this.app.workspace.revealLeaf(existing[0]);641 return;642 }643 const leaf = this.app.workspace.getRightLeaf(false);644 if (!leaf) return;645 await leaf.setViewState({646 type: VERSION_VIEW_TYPE,647 active: true648 });649 this.app.workspace.revealLeaf(leaf);650 }651 handleUri(params) {652 const { action, file } = params;653 if (action === "open" && file) {654 const normalized = (0, import_obsidian6.normalizePath)(file);655 const existing = this.app.vault.getAbstractFileByPath(normalized);656 if (existing) {657 this.app.workspace.openLinkText(normalized, "", false);658 } else {659 new import_obsidian6.Notice(`File not found: ${file}`);660 }661 return;662 }663 if (action === "auth" && params.token) {664 this.settings.apiToken = params.token;665 this.saveSettings();666 new import_obsidian6.Notice("sublimated: signed in successfully");667 return;668 }669 new import_obsidian6.Notice(`Unknown sublimated action: ${action}`);670 }671};672function syncStatusIcon(status) {673 switch (status) {674 case "synced":675 return "\u2713";676 case "uploading":677 return "\u2191";678 case "downloading":679 return "\u2193";680 case "error":681 return "!";682 case "conflict":683 return "\u26A0";684 default:685 return "";686 }687}688function visibilityIcon(visibility) {689 switch (visibility) {690 case "public":691 return "\u{1F310}";692 case "shared":693 return "\u{1F465}";694 case "private":695 return "\u{1F512}";696 default:697 return "";698 }699}700//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL3NldHRpbmdzLnRzIiwgInNyYy9hcGkudHMiLCAic3JjL3hhdHRyLnRzIiwgInNyYy92ZXJzaW9uLXZpZXcudHMiLCAic3JjL3dlbGNvbWUtbW9kYWwudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7XG5cdE5vdGljZSxcblx0UGx1Z2luLFxuXHRXb3Jrc3BhY2VMZWFmLFxuXHRub3JtYWxpemVQYXRoLFxufSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7XG5cdHR5cGUgU3VibGltYXRlZFNldHRpbmdzLFxuXHRERUZBVUxUX1NFVFRJTkdTLFxuXHRTdWJsaW1hdGVkU2V0dGluZ1RhYixcbn0gZnJvbSBcIi4vc2V0dGluZ3NcIjtcbmltcG9ydCB7IHR5cGUgRmlsZU1ldGFkYXRhLCByZWFkRmlsZU1ldGFkYXRhLCBpc01hY09TIH0gZnJvbSBcIi4veGF0dHJcIjtcbmltcG9ydCB7IFZlcnNpb25WaWV3LCBWRVJTSU9OX1ZJRVdfVFlQRSB9IGZyb20gXCIuL3ZlcnNpb24tdmlld1wiO1xuaW1wb3J0IHsgV2VsY29tZU1vZGFsIH0gZnJvbSBcIi4vd2VsY29tZS1tb2RhbFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdWJsaW1hdGVkUGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IFN1YmxpbWF0ZWRTZXR0aW5ncyA9IERFRkFVTFRfU0VUVElOR1M7XG5cdGxhc3RNZXRhZGF0YTogRmlsZU1ldGFkYXRhIHwgbnVsbCA9IG51bGw7XG5cblx0cHJpdmF0ZSBzdGF0dXNCYXJFbDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuXHRhc3luYyBvbmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblxuXHRcdC8vIHN0YXR1cyBiYXJcblx0XHR0aGlzLnN0YXR1c0JhckVsID0gdGhpcy5hZGRTdGF0dXNCYXJJdGVtKCk7XG5cdFx0dGhpcy5zdGF0dXNCYXJFbC5hZGRDbGFzcyhcInNibC1zdGF0dXMtYmFyXCIpO1xuXHRcdHRoaXMuc3RhdHVzQmFyRWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+XG5cdFx0XHR0aGlzLm9wZW5DdXJyZW50RmlsZU9uV2ViKClcblx0XHQpO1xuXHRcdHRoaXMudXBkYXRlU3RhdHVzQmFyKG51bGwpO1xuXG5cdFx0Ly8gcmVnaXN0ZXIgdmVyc2lvbiBoaXN0b3J5IHZpZXdcblx0XHR0aGlzLnJlZ2lzdGVyVmlldyhcblx0XHRcdFZFUlNJT05fVklFV19UWVBFLFxuXHRcdFx0KGxlYWYpID0+IG5ldyBWZXJzaW9uVmlldyhsZWFmLCB0aGlzKVxuXHRcdCk7XG5cblx0XHQvLyBjb21tYW5kc1xuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJvcGVuLW9uLXdlYlwiLFxuXHRcdFx0bmFtZTogXCJPcGVuIG9uIHN1YmxpbWF0ZWQuY29tXCIsXG5cdFx0XHRjYWxsYmFjazogKCkgPT4gdGhpcy5vcGVuQ3VycmVudEZpbGVPbldlYigpLFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiBcInNob3ctdmVyc2lvbnNcIixcblx0XHRcdG5hbWU6IFwiU2hvdyB2ZXJzaW9uc1wiLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHRoaXMuYWN0aXZhdGVWZXJzaW9uVmlldygpLFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiBcImNvcHktd2ViLWxpbmtcIixcblx0XHRcdG5hbWU6IFwiQ29weSB3ZWIgbGlua1wiLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHRoaXMuY29weVdlYkxpbmsoKSxcblx0XHR9KTtcblxuXHRcdC8vIHJpYmJvbiBpY29uIGZvciB2ZXJzaW9uIHNpZGViYXJcblx0XHR0aGlzLmFkZFJpYmJvbkljb24oXCJoaXN0b3J5XCIsIFwic3VibGltYXRlZCB2ZXJzaW9uc1wiLCAoKSA9PiB7XG5cdFx0XHR0aGlzLmFjdGl2YXRlVmVyc2lvblZpZXcoKTtcblx0XHR9KTtcblxuXHRcdC8vIFVSSSBoYW5kbGVyOiBvYnNpZGlhbjovL3N1YmxpbWF0ZWQ/YWN0aW9uPW9wZW4mZmlsZT1wYXRoL3RvL25vdGUubWRcblx0XHR0aGlzLnJlZ2lzdGVyT2JzaWRpYW5Qcm90b2NvbEhhbmRsZXIoXG5cdFx0XHRcInN1YmxpbWF0ZWRcIixcblx0XHRcdChwYXJhbXMpID0+IHRoaXMuaGFuZGxlVXJpKHBhcmFtcylcblx0XHQpO1xuXG5cdFx0Ly8gc2V0dGluZ3MgdGFiXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBTdWJsaW1hdGVkU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG5cdFx0Ly8gdXBkYXRlIHN0YXR1cyBiYXIgd2hlbiBhY3RpdmUgZmlsZSBjaGFuZ2VzXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKFwiYWN0aXZlLWxlYWYtY2hhbmdlXCIsICgpID0+IHtcblx0XHRcdFx0dGhpcy5yZWZyZXNoTWV0YWRhdGEoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdC8vIGluaXRpYWwgbWV0YWRhdGEgcmVhZFxuXHRcdHRoaXMucmVmcmVzaE1ldGFkYXRhKCk7XG5cblx0XHQvLyB3ZWxjb21lIG1vZGFsIG9uIGZpcnN0IGluc3RhbGxcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuaGFzU2VlbldlbGNvbWUpIHtcblx0XHRcdG5ldyBXZWxjb21lTW9kYWwodGhpcy5hcHApLm9wZW4oKTtcblx0XHRcdHRoaXMuc2V0dGluZ3MuaGFzU2VlbldlbGNvbWUgPSB0cnVlO1xuXHRcdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHR9XG5cdH1cblxuXHRvbnVubG9hZCgpOiB2b2lkIHtcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UuZGV0YWNoTGVhdmVzT2ZUeXBlKFZFUlNJT05fVklFV19UWVBFKTtcblx0fVxuXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbihcblx0XHRcdHt9LFxuXHRcdFx0REVGQVVMVF9TRVRUSU5HUyxcblx0XHRcdGF3YWl0IHRoaXMubG9hZERhdGEoKVxuXHRcdCk7XG5cdH1cblxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxuXG5cdC8vIGRldGVjdCB3b3Jrc3BhY2UgZnJvbSB4YXR0cnMgb24gdGhlIGN1cnJlbnRseSBhY3RpdmUgZmlsZS5cblx0Ly8gZXZlcnkgc3luY2VkIGZpbGUgY2FycmllcyBjb20uc3VibGltYXRlZC5zcGFjZSNQUywgc28gYW55IGZpbGVcblx0Ly8gd2l0aCBzdWJsaW1hdGVkIG1ldGFkYXRhIGlkZW50aWZpZXMgdGhlIHdvcmtzcGFjZS5cblx0ZGV0ZWN0V29ya3NwYWNlKCk6IHsgc3BhY2U6IHN0cmluZyB8IG51bGwgfSB8IG51bGwge1xuXHRcdGlmICghdGhpcy5sYXN0TWV0YWRhdGEpIHJldHVybiBudWxsO1xuXHRcdGlmICghdGhpcy5sYXN0TWV0YWRhdGEuc3BhY2UgJiYgIXRoaXMubGFzdE1ldGFkYXRhLmlkKSByZXR1cm4gbnVsbDtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c3BhY2U6IHRoaXMubGFzdE1ldGFkYXRhLnNwYWNlID8/IG51bGwsXG5cdFx0fTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgcmVmcmVzaE1ldGFkYXRhKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xuXHRcdGlmICghZmlsZSkge1xuXHRcdFx0dGhpcy5sYXN0TWV0YWRhdGEgPSBudWxsO1xuXHRcdFx0dGhpcy51cGRhdGVTdGF0dXNCYXIobnVsbCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCFpc01hY09TKCkpIHtcblx0XHRcdHRoaXMubGFzdE1ldGFkYXRhID0gbnVsbDtcblx0XHRcdHRoaXMudXBkYXRlU3RhdHVzQmFyKG51bGwpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGdldCBhYnNvbHV0ZSBwYXRoIHZpYSB2YXVsdCBhZGFwdGVyXG5cdFx0Y29uc3QgYWRhcHRlciA9IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXI7XG5cdFx0Y29uc3QgYmFzZVBhdGggPSAoYWRhcHRlciBhcyB7IGdldEJhc2VQYXRoPzogKCkgPT4gc3RyaW5nIH0pXG5cdFx0XHQuZ2V0QmFzZVBhdGg/LigpO1xuXHRcdGlmICghYmFzZVBhdGgpIHtcblx0XHRcdHRoaXMubGFzdE1ldGFkYXRhID0gbnVsbDtcblx0XHRcdHRoaXMudXBkYXRlU3RhdHVzQmFyKG51bGwpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGFic1BhdGggPSBgJHtiYXNlUGF0aH0vJHtmaWxlLnBhdGh9YDtcblx0XHR0aGlzLmxhc3RNZXRhZGF0YSA9IGF3YWl0IHJlYWRGaWxlTWV0YWRhdGEoYWJzUGF0aCk7XG5cdFx0dGhpcy51cGRhdGVTdGF0dXNCYXIodGhpcy5sYXN0TWV0YWRhdGEpO1xuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVTdGF0dXNCYXIobWV0YTogRmlsZU1ldGFkYXRhIHwgbnVsbCk6IHZvaWQge1xuXHRcdGlmICghdGhpcy5zdGF0dXNCYXJFbCkgcmV0dXJuO1xuXG5cdFx0Ly8gbm8gc3VibGltYXRlZCB4YXR0cnMgXHUyMTkyIGZpbGUgaXNuJ3QgdHJhY2tlZCBieSBzdWJsaW1hdGVkLCBoaWRlIHN0YXR1cyBiYXJcblx0XHRpZiAoIW1ldGEgfHwgKCFtZXRhLnNwYWNlICYmICFtZXRhLmlkKSkge1xuXHRcdFx0dGhpcy5zdGF0dXNCYXJFbC5zZXRUZXh0KFwiXCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGNvbXBhY3QgZm9ybWF0OiBcIlx1MjcxMyBzeW5jZWQgdjIxIGJ5IGFudG9uXCIgKHN5bmMgKyB2ZXJzaW9uICsgYXV0aG9yICsgb3B0aW9uYWwgYnJhbmNoL3Zpc2liaWxpdHkpXG5cdFx0Y29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XG5cblx0XHRpZiAobWV0YS5zeW5jU3RhdHVzKSB7XG5cdFx0XHRjb25zdCBpY29uID0gc3luY1N0YXR1c0ljb24obWV0YS5zeW5jU3RhdHVzKTtcblx0XHRcdHBhcnRzLnB1c2goaWNvbiA/IGAke2ljb259ICR7bWV0YS5zeW5jU3RhdHVzfWAgOiBtZXRhLnN5bmNTdGF0dXMpO1xuXHRcdH1cblxuXHRcdGlmIChtZXRhLnZlcnNpb24pIHtcblx0XHRcdHBhcnRzLnB1c2goYHYke21ldGEudmVyc2lvbn1gKTtcblx0XHR9XG5cblx0XHRpZiAobWV0YS5tb2RpZmllZEJ5KSB7XG5cdFx0XHRjb25zdCBwcmVmaXggPVxuXHRcdFx0XHRtZXRhLm1vZGlmaWVkQnlUeXBlID09PSBcImFpX2FnZW50XCIgPyBcImJ5IEFJOlwiIDogXCJieVwiO1xuXHRcdFx0cGFydHMucHVzaChgJHtwcmVmaXh9ICR7bWV0YS5tb2RpZmllZEJ5fWApO1xuXHRcdH1cblxuXHRcdGlmIChtZXRhLmJyYW5jaCAmJiBtZXRhLmJyYW5jaCAhPT0gXCJtYWluXCIpIHtcblx0XHRcdHBhcnRzLnB1c2gobWV0YS5icmFuY2gpO1xuXHRcdH1cblxuXHRcdGlmIChtZXRhLnZpc2liaWxpdHkpIHtcblx0XHRcdHBhcnRzLnB1c2godmlzaWJpbGl0eUljb24obWV0YS52aXNpYmlsaXR5KSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5zdGF0dXNCYXJFbC5zZXRUZXh0KHBhcnRzLmpvaW4oXCIgXCIpKTtcblxuXHRcdC8vIHNob3cgcG9pbnRlciBjdXJzb3Igd2hlbiBVUkwgYXZhaWxhYmxlXG5cdFx0aWYgKG1ldGEudXJsKSB7XG5cdFx0XHR0aGlzLnN0YXR1c0JhckVsLmFkZENsYXNzKFwic2JsLWNsaWNrYWJsZVwiKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5zdGF0dXNCYXJFbC5yZW1vdmVDbGFzcyhcInNibC1jbGlja2FibGVcIik7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBvcGVuQ3VycmVudEZpbGVPbldlYigpOiB2b2lkIHtcblx0XHRjb25zdCB1cmwgPSB0aGlzLmxhc3RNZXRhZGF0YT8udXJsO1xuXHRcdGlmICghdXJsKSB7XG5cdFx0XHRuZXcgTm90aWNlKFwiTm8gc3VibGltYXRlZCBVUkwgZm9yIHRoaXMgZmlsZVwiKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0d2luZG93Lm9wZW4oYGh0dHBzOi8vJHt1cmx9YCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGNvcHlXZWJMaW5rKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHVybCA9IHRoaXMubGFzdE1ldGFkYXRhPy51cmw7XG5cdFx0aWYgKCF1cmwpIHtcblx0XHRcdG5ldyBOb3RpY2UoXCJObyBzdWJsaW1hdGVkIFVSTCBmb3IgdGhpcyBmaWxlXCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRhd2FpdCBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dChgaHR0cHM6Ly8ke3VybH1gKTtcblx0XHRuZXcgTm90aWNlKFwiTGluayBjb3BpZWQgdG8gY2xpcGJvYXJkXCIpO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBhY3RpdmF0ZVZlcnNpb25WaWV3KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGV4aXN0aW5nID1cblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoVkVSU0lPTl9WSUVXX1RZUEUpO1xuXHRcdGlmIChleGlzdGluZy5sZW5ndGggPiAwKSB7XG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2UucmV2ZWFsTGVhZihleGlzdGluZ1swXSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgbGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRSaWdodExlYWYoZmFsc2UpO1xuXHRcdGlmICghbGVhZikgcmV0dXJuO1xuXHRcdGF3YWl0IGxlYWYuc2V0Vmlld1N0YXRlKHtcblx0XHRcdHR5cGU6IFZFUlNJT05fVklFV19UWVBFLFxuXHRcdFx0YWN0aXZlOiB0cnVlLFxuXHRcdH0pO1xuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5yZXZlYWxMZWFmKGxlYWYpO1xuXHR9XG5cblx0cHJpdmF0ZSBoYW5kbGVVcmkocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogdm9pZCB7XG5cdFx0Y29uc3QgeyBhY3Rpb24sIGZpbGUgfSA9IHBhcmFtcztcblxuXHRcdGlmIChhY3Rpb24gPT09IFwib3BlblwiICYmIGZpbGUpIHtcblx0XHRcdGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVQYXRoKGZpbGUpO1xuXHRcdFx0Y29uc3QgZXhpc3RpbmcgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobm9ybWFsaXplZCk7XG5cdFx0XHRpZiAoZXhpc3RpbmcpIHtcblx0XHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9wZW5MaW5rVGV4dChub3JtYWxpemVkLCBcIlwiLCBmYWxzZSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRuZXcgTm90aWNlKGBGaWxlIG5vdCBmb3VuZDogJHtmaWxlfWApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChhY3Rpb24gPT09IFwiYXV0aFwiICYmIHBhcmFtcy50b2tlbikge1xuXHRcdFx0Ly8gZnV0dXJlOiBPQXV0aCBmbG93IHN0b3JlcyB0b2tlbiBmcm9tIHJlZGlyZWN0XG5cdFx0XHR0aGlzLnNldHRpbmdzLmFwaVRva2VuID0gcGFyYW1zLnRva2VuO1xuXHRcdFx0dGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdG5ldyBOb3RpY2UoXCJzdWJsaW1hdGVkOiBzaWduZWQgaW4gc3VjY2Vzc2Z1bGx5XCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdG5ldyBOb3RpY2UoYFVua25vd24gc3VibGltYXRlZCBhY3Rpb246ICR7YWN0aW9ufWApO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHN5bmNTdGF0dXNJY29uKHN0YXR1czogc3RyaW5nKTogc3RyaW5nIHtcblx0c3dpdGNoIChzdGF0dXMpIHtcblx0XHRjYXNlIFwic3luY2VkXCI6XG5cdFx0XHRyZXR1cm4gXCJcdTI3MTNcIjtcblx0XHRjYXNlIFwidXBsb2FkaW5nXCI6XG5cdFx0XHRyZXR1cm4gXCJcdTIxOTFcIjtcblx0XHRjYXNlIFwiZG93bmxvYWRpbmdcIjpcblx0XHRcdHJldHVybiBcIlx1MjE5M1wiO1xuXHRcdGNhc2UgXCJlcnJvclwiOlxuXHRcdFx0cmV0dXJuIFwiIVwiO1xuXHRcdGNhc2UgXCJjb25mbGljdFwiOlxuXHRcdFx0cmV0dXJuIFwiXHUyNkEwXCI7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHJldHVybiBcIlwiO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHZpc2liaWxpdHlJY29uKHZpc2liaWxpdHk6IHN0cmluZyk6IHN0cmluZyB7XG5cdHN3aXRjaCAodmlzaWJpbGl0eSkge1xuXHRcdGNhc2UgXCJwdWJsaWNcIjpcblx0XHRcdHJldHVybiBcIlx1RDgzQ1x1REYxMFwiO1xuXHRcdGNhc2UgXCJzaGFyZWRcIjpcblx0XHRcdHJldHVybiBcIlx1RDgzRFx1REM2NVwiO1xuXHRcdGNhc2UgXCJwcml2YXRlXCI6XG5cdFx0XHRyZXR1cm4gXCJcdUQ4M0RcdUREMTJcIjtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIFwiXCI7XG5cdH1cbn1cbiIsICJpbXBvcnQgeyBBcHAsIE5vdGljZSwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUgU3VibGltYXRlZFBsdWdpbiBmcm9tIFwiLi9tYWluXCI7XG5pbXBvcnQgeyBTdWJsaW1hdGVkQXBpIH0gZnJvbSBcIi4vYXBpXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VibGltYXRlZFNldHRpbmdzIHtcblx0YXBpVG9rZW46IHN0cmluZztcblx0aGFzU2VlbldlbGNvbWU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFVFRJTkdTOiBTdWJsaW1hdGVkU2V0dGluZ3MgPSB7XG5cdGFwaVRva2VuOiBcIlwiLFxuXHRoYXNTZWVuV2VsY29tZTogZmFsc2UsXG59O1xuXG5leHBvcnQgY2xhc3MgU3VibGltYXRlZFNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBTdWJsaW1hdGVkUGx1Z2luO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IFN1YmxpbWF0ZWRQbHVnaW4pIHtcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRkaXNwbGF5KCk6IHZvaWQge1xuXHRcdGNvbnN0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG5cdFx0Y29udGFpbmVyRWwuZW1wdHkoKTtcblxuXHRcdC8vIGJyYW5kaW5nXG5cdFx0Y29uc3QgaGVhZGVyID0gY29udGFpbmVyRWwuY3JlYXRlRGl2KHsgY2xzOiBcInNibC1zZXR0aW5ncy1oZWFkZXJcIiB9KTtcblx0XHRoZWFkZXIuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwic3VibGltYXRlZFwiIH0pO1xuXHRcdGhlYWRlci5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0dGV4dDogXCJTeW5jIHN0YXR1cywgdmVyc2lvbiBoaXN0b3J5LCBhbmQgZGVlcCBsaW5rcy5cIixcblx0XHRcdGNsczogXCJzZXR0aW5nLWl0ZW0tZGVzY3JpcHRpb25cIixcblx0XHR9KTtcblxuXHRcdC8vIHdvcmtzcGFjZSBkZXRlY3Rpb24gKGJhc2VkIG9uIHhhdHRycyBvZiB0aGUgbGFzdCBvcGVuZWQgZmlsZSlcblx0XHRjb25zdCB3b3Jrc3BhY2VJbmZvID0gdGhpcy5wbHVnaW4uZGV0ZWN0V29ya3NwYWNlKCk7XG5cdFx0aWYgKHdvcmtzcGFjZUluZm8pIHtcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHQuc2V0TmFtZShcIkRldGVjdGVkIHdvcmtzcGFjZVwiKVxuXHRcdFx0XHQuc2V0RGVzYyhcblx0XHRcdFx0XHRgU3BhY2U6ICR7d29ya3NwYWNlSW5mby5zcGFjZSB8fCBcInVua25vd25cIn1gXG5cdFx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHQuc2V0TmFtZShcIk5vIHN1YmxpbWF0ZWQgZmlsZSBvcGVuXCIpXG5cdFx0XHRcdC5zZXREZXNjKFxuXHRcdFx0XHRcdFwiT3BlbiBhbnkgc3luY2VkIGZpbGUgZnJvbSBhIHN1YmxpbWF0ZWQgZm9sZGVyIHRvIHNlZSB3b3Jrc3BhY2UgaW5mby5cIlxuXHRcdFx0XHQpO1xuXHRcdH1cblxuXHRcdC8vIEFQSSB0b2tlblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJBUEkgdG9rZW5cIilcblx0XHRcdC5zZXREZXNjKFxuXHRcdFx0XHRcIlJlcXVpcmVkIGZvciB2ZXJzaW9uIGhpc3RvcnkuIEdlbmVyYXRlIGF0IHN1YmxpbWF0ZWQuY29tL3NldHRpbmdzL3Rva2Vuc1wiXG5cdFx0XHQpXG5cdFx0XHQuYWRkVGV4dCgodGV4dCkgPT5cblx0XHRcdFx0dGV4dFxuXHRcdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihcInNrXy4uLlwiKVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbilcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbiA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyB0ZXN0IGNvbm5lY3Rpb25cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiVGVzdCBjb25uZWN0aW9uXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlZlcmlmeSB5b3VyIEFQSSB0b2tlbiB3b3Jrc1wiKVxuXHRcdFx0LmFkZEJ1dHRvbigoYnRuKSA9PlxuXHRcdFx0XHRidG4uc2V0QnV0dG9uVGV4dChcIlRlc3RcIikub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbikge1xuXHRcdFx0XHRcdFx0bmV3IE5vdGljZShcIk5vIEFQSSB0b2tlbiBjb25maWd1cmVkXCIpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRidG4uc2V0QnV0dG9uVGV4dChcIlRlc3RpbmcuLi5cIik7XG5cdFx0XHRcdFx0YnRuLnNldERpc2FibGVkKHRydWUpO1xuXHRcdFx0XHRcdGNvbnN0IGFwaSA9IG5ldyBTdWJsaW1hdGVkQXBpKFxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYXBpVG9rZW5cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFwaS50ZXN0Q29ubmVjdGlvbigpO1xuXHRcdFx0XHRcdGlmIChyZXN1bHQub2spIHtcblx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXG5cdFx0XHRcdFx0XHRcdGBDb25uZWN0ZWQgYXMgJHtyZXN1bHQudXNlcm5hbWV9YFxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0bmV3IE5vdGljZShcblx0XHRcdFx0XHRcdFx0YENvbm5lY3Rpb24gZmFpbGVkOiAke3Jlc3VsdC5lcnJvcn1gXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRidG4uc2V0QnV0dG9uVGV4dChcIlRlc3RcIik7XG5cdFx0XHRcdFx0YnRuLnNldERpc2FibGVkKGZhbHNlKTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyBsaW5rc1xuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiZGl2XCIsIHsgY2xzOiBcInNibC1zZXR0aW5ncy1saW5rc1wiIH0sIChlbCkgPT4ge1xuXHRcdFx0ZWwuY3JlYXRlRWwoXCJhXCIsIHtcblx0XHRcdFx0dGV4dDogXCJzdWJsaW1hdGVkLmNvbVwiLFxuXHRcdFx0XHRocmVmOiBcImh0dHBzOi8vc3VibGltYXRlZC5jb21cIixcblx0XHRcdH0pO1xuXHRcdFx0ZWwuY3JlYXRlRWwoXCJzcGFuXCIsIHsgdGV4dDogXCIgXHUwMEI3IFwiIH0pO1xuXHRcdFx0ZWwuY3JlYXRlRWwoXCJhXCIsIHtcblx0XHRcdFx0dGV4dDogXCJEb2N1bWVudGF0aW9uXCIsXG5cdFx0XHRcdGhyZWY6IFwiaHR0cHM6Ly9zdWJsaW1hdGVkLmNvbS9kb2NzL29ic2lkaWFuXCIsXG5cdFx0XHR9KTtcblx0XHRcdGVsLmNyZWF0ZUVsKFwic3BhblwiLCB7IHRleHQ6IFwiIFx1MDBCNyBcIiB9KTtcblx0XHRcdGVsLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHRcdHRleHQ6IFwiU291cmNlIGNvZGVcIixcblx0XHRcdFx0aHJlZjogXCJodHRwczovL3N1YmxpbWF0ZWQuY29tL3N1YmxpbWF0ZWQvY29kZS9vYnNpZGlhblwiLFxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cbn1cbiIsICJpbXBvcnQgeyByZXF1ZXN0VXJsIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmNvbnN0IEFQSV9CQVNFID0gXCJodHRwczovL2FwaS5zdWJsaW1hdGVkLmNvbVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZlcnNpb24ge1xuXHRpZDogc3RyaW5nO1xuXHRudW1iZXI6IG51bWJlcjtcblx0YXV0aG9yTmFtZTogc3RyaW5nO1xuXHRhdXRob3JUeXBlOiBzdHJpbmc7XG5cdG1lc3NhZ2U6IHN0cmluZyB8IG51bGw7XG5cdGNyZWF0ZWRBdDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgQXV0aFJlcXVpcmVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdGNvbnN0cnVjdG9yKHB1YmxpYyBzdGF0dXM6IG51bWJlcikge1xuXHRcdHN1cGVyKGBhdXRoIHJlcXVpcmVkICgke3N0YXR1c30pYCk7XG5cdFx0dGhpcy5uYW1lID0gXCJBdXRoUmVxdWlyZWRFcnJvclwiO1xuXHR9XG59XG5cbi8vIFJhdyB3aXJlIGZvcm1hdCBmcm9tIGFwaS5zdWJsaW1hdGVkLmNvbVxuaW50ZXJmYWNlIFJhd0FjdG9yIHtcblx0dXNlcm5hbWU6IHN0cmluZyB8IG51bGw7XG5cdG5hbWU6IHN0cmluZyB8IG51bGw7XG5cdHJvbGU6IHN0cmluZztcblx0YWN0b3JfdHlwZTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUmF3VmVyc2lvbiB7XG5cdGlkOiBzdHJpbmc7XG5cdGl0ZW1faWQ6IHN0cmluZztcblx0dmVyc2lvbjogbnVtYmVyO1xuXHRjb250ZW50X2hhc2g6IHN0cmluZztcblx0YmxvYl9zaGExOiBzdHJpbmcgfCBudWxsO1xuXHRzaXplX2J5dGVzOiBudW1iZXI7XG5cdG1lc3NhZ2U6IHN0cmluZyB8IG51bGw7XG5cdG5hbWU6IHN0cmluZyB8IG51bGw7XG5cdGNyZWF0ZWRfYXQ6IHN0cmluZztcblx0YWN0b3JzOiBSYXdBY3RvcltdO1xufVxuXG5pbnRlcmZhY2UgQXBpRW52ZWxvcGU8VD4ge1xuXHRvazogYm9vbGVhbjtcblx0ZGF0YT86IFQ7XG5cdGVycm9yPzogeyB0eXBlOiBzdHJpbmc7IG1lc3NhZ2U/OiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0Q29ubmVjdGlvblJlc3VsdCB7XG5cdG9rOiBib29sZWFuO1xuXHR1c2VybmFtZT86IHN0cmluZztcblx0ZXJyb3I/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBTdWJsaW1hdGVkQXBpIHtcblx0Y29uc3RydWN0b3IocHJpdmF0ZSB0b2tlbjogc3RyaW5nKSB7fVxuXG5cdHByaXZhdGUgYXN5bmMgcmVxdWVzdDxUPihwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFQ+IHtcblx0XHRjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuXHRcdFx0QWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcblx0XHR9O1xuXHRcdGlmICh0aGlzLnRva2VuKSB7XG5cdFx0XHRoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7dGhpcy50b2tlbn1gO1xuXHRcdH1cblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmwoe1xuXHRcdFx0dXJsOiBgJHtBUElfQkFTRX0ke3BhdGh9YCxcblx0XHRcdGhlYWRlcnMsXG5cdFx0XHR0aHJvdzogZmFsc2UsXG5cdFx0fSk7XG5cblx0XHRpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDEgfHwgcmVzcG9uc2Uuc3RhdHVzID09PSA0MDMpIHtcblx0XHRcdHRocm93IG5ldyBBdXRoUmVxdWlyZWRFcnJvcihyZXNwb25zZS5zdGF0dXMpO1xuXHRcdH1cblx0XHRpZiAocmVzcG9uc2Uuc3RhdHVzID49IDQwMCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRgQVBJIGVycm9yICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS50ZXh0fWBcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgYm9keSA9IHJlc3BvbnNlLmpzb24gYXMgQXBpRW52ZWxvcGU8VD47XG5cdFx0aWYgKCFib2R5Lm9rIHx8IGJvZHkuZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRjb25zdCBtc2cgPSBib2R5LmVycm9yPy5tZXNzYWdlIHx8IGJvZHkuZXJyb3I/LnR5cGUgfHwgXCJ1bmtub3duIGVycm9yXCI7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYEFQSSBlcnJvcjogJHttc2d9YCk7XG5cdFx0fVxuXHRcdHJldHVybiBib2R5LmRhdGE7XG5cdH1cblxuXHRhc3luYyBnZXRWZXJzaW9ucyhcblx0XHRzcGFjZVNsdWc6IHN0cmluZyxcblx0XHRpdGVtSWQ6IHN0cmluZ1xuXHQpOiBQcm9taXNlPFZlcnNpb25bXT4ge1xuXHRcdGNvbnN0IHJhdyA9IGF3YWl0IHRoaXMucmVxdWVzdDxSYXdWZXJzaW9uW10+KFxuXHRcdFx0YC92MS9zcGFjZXMvJHtlbmNvZGVVUklDb21wb25lbnQoc3BhY2VTbHVnKX0vaXRlbXMvJHtlbmNvZGVVUklDb21wb25lbnQoaXRlbUlkKX0vdmVyc2lvbnNgXG5cdFx0KTtcblx0XHRyZXR1cm4gcmF3Lm1hcChtYXBWZXJzaW9uKS5yZXZlcnNlKCk7XG5cdH1cblxuXHRhc3luYyB0ZXN0Q29ubmVjdGlvbigpOiBQcm9taXNlPFRlc3RDb25uZWN0aW9uUmVzdWx0PiB7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnJlcXVlc3Q8eyB1c2VybmFtZTogc3RyaW5nIH0+KFxuXHRcdFx0XHRcIi92MS9tZVwiXG5cdFx0XHQpO1xuXHRcdFx0cmV0dXJuIHsgb2s6IHRydWUsIHVzZXJuYW1lOiBkYXRhLnVzZXJuYW1lIH07XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0b2s6IGZhbHNlLFxuXHRcdFx0XHRlcnJvcjogZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogXCJVbmtub3duIGVycm9yXCIsXG5cdFx0XHR9O1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBtYXBWZXJzaW9uKHI6IFJhd1ZlcnNpb24pOiBWZXJzaW9uIHtcblx0Ly8gcGljayB0aGUgYXV0aG9yIGFjdG9yOyBmYWxsIGJhY2sgdG8gdGhlIGZpcnN0IGFjdG9yIG9yIGEgcGxhY2Vob2xkZXJcblx0Y29uc3QgYXV0aG9yID1cblx0XHRyLmFjdG9ycy5maW5kKChhKSA9PiBhLnJvbGUgPT09IFwiYXV0aG9yXCIpID8/IHIuYWN0b3JzWzBdID8/IG51bGw7XG5cdHJldHVybiB7XG5cdFx0aWQ6IHIuaWQsXG5cdFx0bnVtYmVyOiByLnZlcnNpb24sXG5cdFx0YXV0aG9yTmFtZTogYXV0aG9yPy5uYW1lID8/IGF1dGhvcj8udXNlcm5hbWUgPz8gXCJ1bmtub3duXCIsXG5cdFx0YXV0aG9yVHlwZTogYXV0aG9yPy5hY3Rvcl90eXBlID8/IFwicGVyc29uXCIsXG5cdFx0bWVzc2FnZTogci5tZXNzYWdlLFxuXHRcdGNyZWF0ZWRBdDogci5jcmVhdGVkX2F0LFxuXHR9O1xufVxuIiwgImltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuY29uc3QgWEFUVFJfUFJFRklYID0gXCJjb20uc3VibGltYXRlZC5cIjtcbmNvbnN0IFhBVFRSX1NVRkZJWCA9IFwiI1BTXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZU1ldGFkYXRhIHtcblx0dmVyc2lvbjogc3RyaW5nIHwgbnVsbDtcblx0Y29tbWl0OiBzdHJpbmcgfCBudWxsO1xuXHR1cmw6IHN0cmluZyB8IG51bGw7XG5cdGNvbnRlbnRIYXNoOiBzdHJpbmcgfCBudWxsO1xuXHRpZDogc3RyaW5nIHwgbnVsbDtcblx0Y3JlYXRlZEJ5OiBzdHJpbmcgfCBudWxsO1xuXHRtb2RpZmllZEJ5OiBzdHJpbmcgfCBudWxsO1xuXHRtb2RpZmllZEJ5VHlwZTogc3RyaW5nIHwgbnVsbDtcblx0c3luY1N0YXR1czogc3RyaW5nIHwgbnVsbDtcblx0c3BhY2U6IHN0cmluZyB8IG51bGw7XG5cdGJyYW5jaDogc3RyaW5nIHwgbnVsbDtcblx0bW9kaWZpZWRBdDogc3RyaW5nIHwgbnVsbDtcblx0dmlzaWJpbGl0eTogc3RyaW5nIHwgbnVsbDtcbn1cblxuY29uc3QgQVRUUlM6IChrZXlvZiBGaWxlTWV0YWRhdGEpW10gPSBbXG5cdFwidmVyc2lvblwiLFxuXHRcImNvbW1pdFwiLFxuXHRcInVybFwiLFxuXHRcImNvbnRlbnRIYXNoXCIsXG5cdFwiaWRcIixcblx0XCJjcmVhdGVkQnlcIixcblx0XCJtb2RpZmllZEJ5XCIsXG5cdFwibW9kaWZpZWRCeVR5cGVcIixcblx0XCJzeW5jU3RhdHVzXCIsXG5cdFwic3BhY2VcIixcblx0XCJicmFuY2hcIixcblx0XCJtb2RpZmllZEF0XCIsXG5cdFwidmlzaWJpbGl0eVwiLFxuXTtcblxuZnVuY3Rpb24gYXR0clRvWGF0dHJOYW1lKGF0dHI6IHN0cmluZyk6IHN0cmluZyB7XG5cdC8vIGNhbWVsQ2FzZSBcdTIxOTIga2ViYWItY2FzZTogY29udGVudEhhc2ggXHUyMTkyIGNvbnRlbnQtaGFzaFxuXHRjb25zdCBrZWJhYiA9IGF0dHIucmVwbGFjZSgvW0EtWl0vZywgKGMpID0+IFwiLVwiICsgYy50b0xvd2VyQ2FzZSgpKTtcblx0cmV0dXJuIGAke1hBVFRSX1BSRUZJWH0ke2tlYmFifSR7WEFUVFJfU1VGRklYfWA7XG59XG5cbmZ1bmN0aW9uIHJlYWRYYXR0cihwYXRoOiBzdHJpbmcsIHhhdHRyTmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG5cdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuXHRcdGV4ZWMoXG5cdFx0XHRgeGF0dHIgLXAgJHtKU09OLnN0cmluZ2lmeSh4YXR0ck5hbWUpfSAke0pTT04uc3RyaW5naWZ5KHBhdGgpfWAsXG5cdFx0XHR7IHRpbWVvdXQ6IDIwMDAgfSxcblx0XHRcdChlcnIsIHN0ZG91dCkgPT4ge1xuXHRcdFx0XHRpZiAoZXJyKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZShudWxsKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzb2x2ZShzdGRvdXQudHJpbSgpIHx8IG51bGwpO1xuXHRcdFx0fVxuXHRcdCk7XG5cdH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZEZpbGVNZXRhZGF0YShcblx0cGF0aDogc3RyaW5nXG4pOiBQcm9taXNlPEZpbGVNZXRhZGF0YSB8IG51bGw+IHtcblx0aWYgKCFQbGF0Zm9ybS5pc01hY09TKSByZXR1cm4gbnVsbDtcblxuXHRjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG5cdFx0QVRUUlMubWFwKChhdHRyKSA9PiByZWFkWGF0dHIocGF0aCwgYXR0clRvWGF0dHJOYW1lKGF0dHIpKSlcblx0KTtcblxuXHQvLyBJZiBubyB4YXR0cnMgZm91bmQgYXQgYWxsLCB0aGlzIGlzbid0IGEgc3VibGltYXRlZCBmaWxlXG5cdGlmIChyZXN1bHRzLmV2ZXJ5KChyKSA9PiByID09PSBudWxsKSkgcmV0dXJuIG51bGw7XG5cblx0Y29uc3QgbWV0YTogRmlsZU1ldGFkYXRhID0ge1xuXHRcdHZlcnNpb246IG51bGwsIGNvbW1pdDogbnVsbCwgdXJsOiBudWxsLCBjb250ZW50SGFzaDogbnVsbCxcblx0XHRpZDogbnVsbCwgY3JlYXRlZEJ5OiBudWxsLCBtb2RpZmllZEJ5OiBudWxsLCBtb2RpZmllZEJ5VHlwZTogbnVsbCxcblx0XHRzeW5jU3RhdHVzOiBudWxsLCBzcGFjZTogbnVsbCwgYnJhbmNoOiBudWxsLCBtb2RpZmllZEF0OiBudWxsLCB2aXNpYmlsaXR5OiBudWxsLFxuXHR9O1xuXHRBVFRSUy5mb3JFYWNoKChhdHRyLCBpKSA9PiB7XG5cdFx0bWV0YVthdHRyXSA9IHJlc3VsdHNbaV07XG5cdH0pO1xuXHRyZXR1cm4gbWV0YTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFjT1MoKTogYm9vbGVhbiB7XG5cdHJldHVybiBQbGF0Zm9ybS5pc01hY09TO1xufVxuIiwgImltcG9ydCB7IEl0ZW1WaWV3LCBOb3RpY2UsIFdvcmtzcGFjZUxlYWYgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB0eXBlIFN1YmxpbWF0ZWRQbHVnaW4gZnJvbSBcIi4vbWFpblwiO1xuaW1wb3J0IHsgU3VibGltYXRlZEFwaSwgQXV0aFJlcXVpcmVkRXJyb3IsIHR5cGUgVmVyc2lvbiB9IGZyb20gXCIuL2FwaVwiO1xuXG5leHBvcnQgY29uc3QgVkVSU0lPTl9WSUVXX1RZUEUgPSBcInN1YmxpbWF0ZWQtdmVyc2lvbnNcIjtcblxuZXhwb3J0IGNsYXNzIFZlcnNpb25WaWV3IGV4dGVuZHMgSXRlbVZpZXcge1xuXHRwbHVnaW46IFN1YmxpbWF0ZWRQbHVnaW47XG5cblx0Y29uc3RydWN0b3IobGVhZjogV29ya3NwYWNlTGVhZiwgcGx1Z2luOiBTdWJsaW1hdGVkUGx1Z2luKSB7XG5cdFx0c3VwZXIobGVhZik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRnZXRWaWV3VHlwZSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiBWRVJTSU9OX1ZJRVdfVFlQRTtcblx0fVxuXG5cdGdldERpc3BsYXlUZXh0KCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIFwic3VibGltYXRlZCB2ZXJzaW9uc1wiO1xuXHR9XG5cblx0Z2V0SWNvbigpOiBzdHJpbmcge1xuXHRcdHJldHVybiBcImhpc3RvcnlcIjtcblx0fVxuXG5cdGFzeW5jIG9uT3BlbigpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRhd2FpdCB0aGlzLnJlZnJlc2goKTtcblx0XHQvLyByZWZyZXNoIHdoZW4gYWN0aXZlIGZpbGUgY2hhbmdlc1xuXHRcdHRoaXMucmVnaXN0ZXJFdmVudChcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbihcImFjdGl2ZS1sZWFmLWNoYW5nZVwiLCAoKSA9PiB7XG5cdFx0XHRcdHRoaXMucmVmcmVzaCgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXHR9XG5cblx0YXN5bmMgcmVmcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcblx0XHRjb250ZW50RWwuYWRkQ2xhc3MoXCJzYmwtdmVyc2lvbi12aWV3XCIpO1xuXG5cdFx0Y29uc3QgYWN0aXZlRmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XG5cdFx0aWYgKCFhY3RpdmVGaWxlKSB7XG5cdFx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdFx0dGV4dDogXCJObyBmaWxlIG9wZW4uXCIsXG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1lbXB0eVwiLFxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gcmVhZCB4YXR0cnMgdG8gZ2V0IHNwYWNlICsgaXRlbSBJRFxuXHRcdGNvbnN0IG1ldGEgPSB0aGlzLnBsdWdpbi5sYXN0TWV0YWRhdGE7XG5cdFx0aWYgKCFtZXRhPy5zcGFjZSB8fCAhbWV0YT8uaWQpIHtcblx0XHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0XHR0ZXh0OiBcIk5vdCBhIHN1YmxpbWF0ZWQgZmlsZS5cIixcblx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWVtcHR5XCIsXG5cdFx0XHR9KTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJoNFwiLCB7XG5cdFx0XHR0ZXh0OiBhY3RpdmVGaWxlLm5hbWUsXG5cdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tZmlsZW5hbWVcIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IGxvYWRpbmcgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdHRleHQ6IFwiTG9hZGluZyB2ZXJzaW9ucy4uLlwiLFxuXHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWxvYWRpbmdcIixcblx0XHR9KTtcblxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBhcGkgPSBuZXcgU3VibGltYXRlZEFwaSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbik7XG5cdFx0XHRjb25zdCB2ZXJzaW9ucyA9IGF3YWl0IGFwaS5nZXRWZXJzaW9ucyhtZXRhLnNwYWNlLCBtZXRhLmlkKTtcblx0XHRcdGxvYWRpbmcucmVtb3ZlKCk7XG5cblx0XHRcdGlmICh2ZXJzaW9ucy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG5cdFx0XHRcdFx0dGV4dDogXCJObyB2ZXJzaW9ucyBmb3VuZC5cIixcblx0XHRcdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tZW1wdHlcIixcblx0XHRcdFx0fSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgbGlzdCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiLCB7XG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1saXN0XCIsXG5cdFx0XHR9KTtcblx0XHRcdGNvbnN0IGdyb3VwcyA9IGdyb3VwQnlEYXkodmVyc2lvbnMpO1xuXHRcdFx0Zm9yIChjb25zdCBncm91cCBvZiBncm91cHMpIHtcblx0XHRcdFx0bGlzdC5jcmVhdGVFbChcImRpdlwiLCB7XG5cdFx0XHRcdFx0dGV4dDogZ3JvdXAubGFiZWwsXG5cdFx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWRheVwiLFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0Zm9yIChjb25zdCB2IG9mIGdyb3VwLnZlcnNpb25zKSB7XG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJWZXJzaW9uKGxpc3QsIHYsIG1ldGEudXJsKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdGxvYWRpbmcucmVtb3ZlKCk7XG5cdFx0XHRpZiAoZSBpbnN0YW5jZW9mIEF1dGhSZXF1aXJlZEVycm9yKSB7XG5cdFx0XHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0XHRcdHRleHQ6IFwiVGhpcyBmaWxlIGlzIHByaXZhdGUgXHUyMDE0IGFkZCBhbiBBUEkgdG9rZW4gdG8gdmlldyB2ZXJzaW9uIGhpc3RvcnkuXCIsXG5cdFx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWVtcHR5XCIsXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdFx0XHR0ZXh0OiBcIkNvbmZpZ3VyZSBpbiBTZXR0aW5ncyBcdTIxOTIgc3VibGltYXRlZFwiLFxuXHRcdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1oaW50XCIsXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdFx0dGV4dDogYEVycm9yOiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93blwifWAsXG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1lcnJvclwiLFxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXJWZXJzaW9uKFxuXHRcdGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsXG5cdFx0djogVmVyc2lvbixcblx0XHRmaWxlVXJsOiBzdHJpbmcgfCBudWxsXG5cdCk6IHZvaWQge1xuXHRcdGNvbnN0IGl0ZW0gPSBjb250YWluZXIuY3JlYXRlRGl2KHsgY2xzOiBcInNibC12ZXJzaW9uLWl0ZW1cIiB9KTtcblxuXHRcdGNvbnN0IGhlYWRlciA9IGl0ZW0uY3JlYXRlRGl2KHsgY2xzOiBcInNibC12ZXJzaW9uLWhlYWRlclwiIH0pO1xuXHRcdGhlYWRlci5jcmVhdGVFbChcInNwYW5cIiwge1xuXHRcdFx0dGV4dDogYHYke3YubnVtYmVyfWAsXG5cdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tbnVtYmVyXCIsXG5cdFx0fSk7XG5cdFx0aGVhZGVyLmNyZWF0ZUVsKFwic3BhblwiLCB7XG5cdFx0XHR0ZXh0OiB2LmF1dGhvck5hbWUsXG5cdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tYXV0aG9yXCIsXG5cdFx0fSk7XG5cblx0XHRjb25zdCB0aW1lID0gaXRlbS5jcmVhdGVEaXYoeyBjbHM6IFwic2JsLXZlcnNpb24tdGltZVwiIH0pO1xuXHRcdHRpbWUuY3JlYXRlRWwoXCJzcGFuXCIsIHtcblx0XHRcdHRleHQ6IGZvcm1hdFJlbGF0aXZlVGltZSh2LmNyZWF0ZWRBdCksXG5cdFx0XHRhdHRyOiB7IHRpdGxlOiBuZXcgRGF0ZSh2LmNyZWF0ZWRBdCkudG9Mb2NhbGVTdHJpbmcoKSB9LFxuXHRcdH0pO1xuXG5cdFx0aWYgKHYubWVzc2FnZSkge1xuXHRcdFx0aXRlbS5jcmVhdGVEaXYoe1xuXHRcdFx0XHR0ZXh0OiB2Lm1lc3NhZ2UsXG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1tZXNzYWdlXCIsXG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAoZmlsZVVybCkge1xuXHRcdFx0Y29uc3Qgd2ViVXJsID0gYGh0dHBzOi8vJHtmaWxlVXJsfS9+dmVyc2lvbnMvdiR7di5udW1iZXJ9YDtcblx0XHRcdGNvbnN0IGxpbmsgPSBpdGVtLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHRcdHRleHQ6IFwidmlldyBvbiB3ZWJcIixcblx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLXdlYi1saW5rXCIsXG5cdFx0XHRcdGhyZWY6IHdlYlVybCxcblx0XHRcdH0pO1xuXHRcdFx0bGluay5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR3aW5kb3cub3Blbih3ZWJVcmwpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgb25DbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBjbGVhbnVwIGhhbmRsZWQgYnkgb2JzaWRpYW5cblx0fVxufVxuXG5pbnRlcmZhY2UgRGF5R3JvdXAge1xuXHRsYWJlbDogc3RyaW5nO1xuXHR2ZXJzaW9uczogVmVyc2lvbltdO1xufVxuXG5mdW5jdGlvbiBncm91cEJ5RGF5KHZlcnNpb25zOiBWZXJzaW9uW10pOiBEYXlHcm91cFtdIHtcblx0Y29uc3QgZ3JvdXBzID0gbmV3IE1hcDxzdHJpbmcsIFZlcnNpb25bXT4oKTtcblx0Y29uc3Qgb3JkZXI6IHN0cmluZ1tdID0gW107XG5cblx0Zm9yIChjb25zdCB2IG9mIHZlcnNpb25zKSB7XG5cdFx0Y29uc3QgbGFiZWwgPSBmb3JtYXREYXlMYWJlbCh2LmNyZWF0ZWRBdCk7XG5cdFx0aWYgKCFncm91cHMuaGFzKGxhYmVsKSkge1xuXHRcdFx0Z3JvdXBzLnNldChsYWJlbCwgW10pO1xuXHRcdFx0b3JkZXIucHVzaChsYWJlbCk7XG5cdFx0fVxuXHRcdGdyb3Vwcy5nZXQobGFiZWwpIS5wdXNoKHYpO1xuXHR9XG5cblx0cmV0dXJuIG9yZGVyLm1hcCgobGFiZWwpID0+ICh7XG5cdFx0bGFiZWwsXG5cdFx0dmVyc2lvbnM6IGdyb3Vwcy5nZXQobGFiZWwpISxcblx0fSkpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXREYXlMYWJlbChpc286IHN0cmluZyk6IHN0cmluZyB7XG5cdGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cdGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShpc28pO1xuXG5cdGNvbnN0IG5vd0RheSA9IG5ldyBEYXRlKG5vdy5nZXRGdWxsWWVhcigpLCBub3cuZ2V0TW9udGgoKSwgbm93LmdldERhdGUoKSk7XG5cdGNvbnN0IHRoZW5EYXkgPSBuZXcgRGF0ZShcblx0XHRkYXRlLmdldEZ1bGxZZWFyKCksXG5cdFx0ZGF0ZS5nZXRNb250aCgpLFxuXHRcdGRhdGUuZ2V0RGF0ZSgpXG5cdCk7XG5cdGNvbnN0IGRheXMgPSBNYXRoLnJvdW5kKFxuXHRcdChub3dEYXkuZ2V0VGltZSgpIC0gdGhlbkRheS5nZXRUaW1lKCkpIC8gKDEwMDAgKiA2MCAqIDYwICogMjQpXG5cdCk7XG5cblx0aWYgKGRheXMgPT09IDApIHJldHVybiBcIlRvZGF5XCI7XG5cdGlmIChkYXlzID09PSAxKSByZXR1cm4gXCJZZXN0ZXJkYXlcIjtcblx0aWYgKGRheXMgPCA3KSByZXR1cm4gYCR7ZGF5c30gZGF5cyBhZ29gO1xuXHRyZXR1cm4gZGF0ZS50b0xvY2FsZURhdGVTdHJpbmcoXCJlbi1VU1wiLCB7XG5cdFx0bW9udGg6IFwic2hvcnRcIixcblx0XHRkYXk6IFwibnVtZXJpY1wiLFxuXHR9KTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UmVsYXRpdmVUaW1lKGlzbzogc3RyaW5nKTogc3RyaW5nIHtcblx0Y29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblx0Y29uc3QgdGhlbiA9IG5ldyBEYXRlKGlzbykuZ2V0VGltZSgpO1xuXHRjb25zdCBkaWZmID0gbm93IC0gdGhlbjtcblx0Y29uc3Qgc2Vjb25kcyA9IE1hdGguZmxvb3IoZGlmZiAvIDEwMDApO1xuXHRjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcihzZWNvbmRzIC8gNjApO1xuXHRjb25zdCBob3VycyA9IE1hdGguZmxvb3IobWludXRlcyAvIDYwKTtcblx0Y29uc3QgZGF5cyA9IE1hdGguZmxvb3IoaG91cnMgLyAyNCk7XG5cblx0aWYgKGRheXMgPiAzMCkgcmV0dXJuIG5ldyBEYXRlKGlzbykudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG5cdGlmIChkYXlzID4gMCkgcmV0dXJuIGAke2RheXN9ZCBhZ29gO1xuXHRpZiAoaG91cnMgPiAwKSByZXR1cm4gYCR7aG91cnN9aCBhZ29gO1xuXHRpZiAobWludXRlcyA+IDApIHJldHVybiBgJHttaW51dGVzfW0gYWdvYDtcblx0cmV0dXJuIFwianVzdCBub3dcIjtcbn1cbiIsICJpbXBvcnQgeyBBcHAsIE1vZGFsIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmV4cG9ydCBjbGFzcyBXZWxjb21lTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwKSB7XG5cdFx0c3VwZXIoYXBwKTtcblx0fVxuXG5cdG9uT3BlbigpOiB2b2lkIHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblx0XHRjb250ZW50RWwuYWRkQ2xhc3MoXCJzYmwtd2VsY29tZS1tb2RhbFwiKTtcblxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJXZWxjb21lIHRvIHN1YmxpbWF0ZWRcIiB9KTtcblxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0dGV4dDogXCJzdWJsaW1hdGVkIHN5bmNzIHlvdXIgZmlsZXMgd2l0aCB2ZXJzaW9uIGhpc3RvcnksIGNvbGxhYm9yYXRpb24sIGFuZCBhIHdlYiB2aWV3ZXIgXHUyMDE0IGFsbCBwb3dlcmVkIGJ5IGdpdCB1bmRlciB0aGUgaG9vZC5cIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IHN0ZXBzID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHsgY2xzOiBcInNibC13ZWxjb21lLXN0ZXBzXCIgfSk7XG5cblx0XHRjb25zdCBzdGVwMSA9IHN0ZXBzLmNyZWF0ZURpdih7IGNsczogXCJzYmwtd2VsY29tZS1zdGVwXCIgfSk7XG5cdFx0c3RlcDEuY3JlYXRlRWwoXCJzdHJvbmdcIiwgeyB0ZXh0OiBcIjEuIE9wZW4gYSBzdWJsaW1hdGVkIGZvbGRlciBhcyBhIHZhdWx0XCIgfSk7XG5cdFx0c3RlcDEuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdHRleHQ6IFwiSW4gRmluZGVyLCBvcGVuIGFueSBzdWJsaW1hdGVkIGZvbGRlciAob3Igc3ViZm9sZGVyKSB1bmRlciBDbG91ZFN0b3JhZ2UgYXMgYW4gT2JzaWRpYW4gdmF1bHQuIFRoZSBwbHVnaW4gYWN0aXZhdGVzIGF1dG9tYXRpY2FsbHkgb24gc3luY2VkIGZpbGVzLlwiLFxuXHRcdH0pO1xuXG5cdFx0Y29uc3Qgc3RlcDIgPSBzdGVwcy5jcmVhdGVEaXYoeyBjbHM6IFwic2JsLXdlbGNvbWUtc3RlcFwiIH0pO1xuXHRcdHN0ZXAyLmNyZWF0ZUVsKFwic3Ryb25nXCIsIHsgdGV4dDogXCIyLiBTdGF0dXMgYmFyIHNob3dzIHN5bmMgaW5mb1wiIH0pO1xuXHRcdHN0ZXAyLmNyZWF0ZUVsKFwicFwiLCB7XG5cdFx0XHR0ZXh0OiBcIlRoZSBib3R0b20gYmFyIHNob3dzIHZlcnNpb24gbnVtYmVyLCBzeW5jIHN0YXR1cywgYW5kIGF1dGhvciBmb3IgdGhlIGN1cnJlbnQgZmlsZSBcdTIwMTQgYWxsIHJlYWQgZnJvbSBsb2NhbCBmaWxlIG1ldGFkYXRhLCBubyBhY2NvdW50IG5lZWRlZC5cIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IHN0ZXAzID0gc3RlcHMuY3JlYXRlRGl2KHsgY2xzOiBcInNibC13ZWxjb21lLXN0ZXBcIiB9KTtcblx0XHRzdGVwMy5jcmVhdGVFbChcInN0cm9uZ1wiLCB7IHRleHQ6IFwiMy4gQWRkIGFuIEFQSSB0b2tlbiBmb3IgdmVyc2lvbiBoaXN0b3J5XCIgfSk7XG5cdFx0c3RlcDMuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdHRleHQ6IFwiVG8gYnJvd3NlIHBhc3QgdmVyc2lvbnMsIGFkZCB5b3VyIEFQSSB0b2tlbiBpbiBTZXR0aW5ncyBcdTIxOTIgc3VibGltYXRlZC4gR2VuZXJhdGUgb25lIGF0IHN1YmxpbWF0ZWQuY29tL3NldHRpbmdzL3Rva2Vucy5cIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IGxpbmtzID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogXCJzYmwtd2VsY29tZS1saW5rc1wiIH0pO1xuXHRcdGxpbmtzLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHR0ZXh0OiBcIkRvY3VtZW50YXRpb25cIixcblx0XHRcdGhyZWY6IFwiaHR0cHM6Ly9zdWJsaW1hdGVkLmNvbS9kb2NzL29ic2lkaWFuXCIsXG5cdFx0fSk7XG5cdFx0bGlua3MuY3JlYXRlRWwoXCJiclwiKTtcblx0XHRsaW5rcy5jcmVhdGVFbChcImFcIiwge1xuXHRcdFx0dGV4dDogXCJTb3VyY2UgY29kZVwiLFxuXHRcdFx0aHJlZjogXCJodHRwczovL3N1YmxpbWF0ZWQuY29tL3N1YmxpbWF0ZWQvY29kZS9vYnNpZGlhblwiLFxuXHRcdH0pO1xuXG5cdFx0Y29uc3QgZm9vdGVyID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogXCJzYmwtd2VsY29tZS1mb290ZXJcIiB9KTtcblx0XHRmb290ZXIuY3JlYXRlRWwoXCJidXR0b25cIiwge1xuXHRcdFx0dGV4dDogXCJHZXQgc3RhcnRlZFwiLFxuXHRcdFx0Y2xzOiBcIm1vZC1jdGFcIixcblx0XHR9KS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4gdGhpcy5jbG9zZSgpKTtcblx0fVxuXG5cdG9uQ2xvc2UoKTogdm9pZCB7XG5cdFx0dGhpcy5jb250ZW50RWwuZW1wdHkoKTtcblx0fVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7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LFVBQVUsV0FBVyxTQUFTLENBQUMsQ0FBQztBQUN6QztBQUFBLElBQ0Q7QUFFQSxVQUFNLE9BQU8sS0FBSyxJQUFJLFVBQVUsYUFBYSxLQUFLO0FBQ2xELFFBQUksQ0FBQyxLQUFNO0FBQ1gsVUFBTSxLQUFLLGFBQWE7QUFBQSxNQUN2QixNQUFNO0FBQUEsTUFDTixRQUFRO0FBQUEsSUFDVCxDQUFDO0FBQ0QsU0FBSyxJQUFJLFVBQVUsV0FBVyxJQUFJO0FBQUEsRUFDbkM7QUFBQSxFQUVRLFVBQVUsUUFBc0M7QUFDdkQsVUFBTSxFQUFFLFFBQVEsS0FBSyxJQUFJO0FBRXpCLFFBQUksV0FBVyxVQUFVLE1BQU07QUFDOUIsWUFBTSxpQkFBYSxnQ0FBYyxJQUFJO0FBQ3JDLFlBQU0sV0FBVyxLQUFLLElBQUksTUFBTSxzQkFBc0IsVUFBVTtBQUNoRSxVQUFJLFVBQVU7QUFDYixhQUFLLElBQUksVUFBVSxhQUFhLFlBQVksSUFBSSxLQUFLO0FBQUEsTUFDdEQsT0FBTztBQUNOLFlBQUksd0JBQU8sbUJBQW1CLElBQUksRUFBRTtBQUFBLE1BQ3JDO0FBQ0E7QUFBQSxJQUNEO0FBRUEsUUFBSSxXQUFXLFVBQVUsT0FBTyxPQUFPO0FBRXRDLFdBQUssU0FBUyxXQUFXLE9BQU87QUFDaEMsV0FBSyxhQUFhO0FBQ2xCLFVBQUksd0JBQU8sb0NBQW9DO0FBQy9DO0FBQUEsSUFDRDtBQUVBLFFBQUksd0JBQU8sOEJBQThCLE1BQU0sRUFBRTtBQUFBLEVBQ2xEO0FBQ0Q7QUFFQSxTQUFTLGVBQWUsUUFBd0I7QUFDL0MsVUFBUSxRQUFRO0FBQUEsSUFDZixLQUFLO0FBQ0osYUFBTztBQUFBLElBQ1IsS0FBSztBQUNKLGFBQU87QUFBQSxJQUNSLEtBQUs7QUFDSixhQUFPO0FBQUEsSUFDUixLQUFLO0FBQ0osYUFBTztBQUFBLElBQ1IsS0FBSztBQUNKLGFBQU87QUFBQSxJQUNSO0FBQ0MsYUFBTztBQUFBLEVBQ1Q7QUFDRDtBQUVBLFNBQVMsZUFBZSxZQUE0QjtBQUNuRCxVQUFRLFlBQVk7QUFBQSxJQUNuQixLQUFLO0FBQ0osYUFBTztBQUFBLElBQ1IsS0FBSztBQUNKLGFBQU87QUFBQSxJQUNSLEtBQUs7QUFDSixhQUFPO0FBQUEsSUFDUjtBQUNDLGFBQU87QUFBQSxFQUNUO0FBQ0Q7IiwKICAibmFtZXMiOiBbImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIiwgImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iXQp9Cg==A /sublimated/undefined +700 -0
1var __defProp = Object.defineProperty;2var __getOwnPropDesc = Object.getOwnPropertyDescriptor;3var __getOwnPropNames = Object.getOwnPropertyNames;4var __hasOwnProp = Object.prototype.hasOwnProperty;5var __export = (target, all) => {6 for (var name in all)7 __defProp(target, name, { get: all[name], enumerable: true });8};9var __copyProps = (to, from, except, desc) => {10 if (from && typeof from === "object" || typeof from === "function") {11 for (let key of __getOwnPropNames(from))12 if (!__hasOwnProp.call(to, key) && key !== except)13 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });14 }15 return to;16};17var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);18
19// src/main.ts20var main_exports = {};21__export(main_exports, {22 default: () => SublimatedPlugin23});24module.exports = __toCommonJS(main_exports);25var import_obsidian6 = require("obsidian");26
27// src/settings.ts28var import_obsidian2 = require("obsidian");29
30// src/api.ts31var import_obsidian = require("obsidian");32var API_BASE = "https://api.sublimated.com";33var AuthRequiredError = class extends Error {34 constructor(status) {35 super(`auth required (${status})`);36 this.status = status;37 this.name = "AuthRequiredError";38 }39};40var SublimatedApi = class {41 constructor(token) {42 this.token = token;43 }44 async request(path) {45 const headers = {46 Accept: "application/json"47 };48 if (this.token) {49 headers.Authorization = `Bearer ${this.token}`;50 }51 const response = await (0, import_obsidian.requestUrl)({52 url: `${API_BASE}${path}`,53 headers,54 throw: false55 });56 if (response.status === 401 || response.status === 403) {57 throw new AuthRequiredError(response.status);58 }59 if (response.status >= 400) {60 throw new Error(61 `API error ${response.status}: ${response.text}`62 );63 }64 const body = response.json;65 if (!body.ok || body.data === void 0) {66 const msg = body.error?.message || body.error?.type || "unknown error";67 throw new Error(`API error: ${msg}`);68 }69 return body.data;70 }71 async getVersions(spaceSlug, itemId) {72 const raw = await this.request(73 `/v1/spaces/${encodeURIComponent(spaceSlug)}/items/${encodeURIComponent(itemId)}/versions`74 );75 return raw.map(mapVersion).reverse();76 }77 async testConnection() {78 try {79 const data = await this.request(80 "/v1/me"81 );82 return { ok: true, username: data.username };83 } catch (e) {84 return {85 ok: false,86 error: e instanceof Error ? e.message : "Unknown error"87 };88 }89 }90};91function mapVersion(r) {92 const author = r.actors.find((a) => a.role === "author") ?? r.actors[0] ?? null;93 return {94 id: r.id,95 number: r.version,96 authorName: author?.name ?? author?.username ?? "unknown",97 authorType: author?.actor_type ?? "person",98 message: r.message,99 createdAt: r.created_at100 };101}102
103// src/settings.ts104var DEFAULT_SETTINGS = {105 apiToken: "",106 hasSeenWelcome: false107};108var SublimatedSettingTab = class extends import_obsidian2.PluginSettingTab {109 plugin;110 constructor(app, plugin) {111 super(app, plugin);112 this.plugin = plugin;113 }114 display() {115 const { containerEl } = this;116 containerEl.empty();117 const header = containerEl.createDiv({ cls: "sbl-settings-header" });118 header.createEl("h2", { text: "sublimated" });119 header.createEl("p", {120 text: "Sync status, version history, and deep links.",121 cls: "setting-item-description"122 });123 const workspaceInfo = this.plugin.detectWorkspace();124 if (workspaceInfo) {125 new import_obsidian2.Setting(containerEl).setName("Detected workspace").setDesc(126 `Space: ${workspaceInfo.space || "unknown"}`127 );128 } else {129 new import_obsidian2.Setting(containerEl).setName("No sublimated file open").setDesc(130 "Open any synced file from a sublimated folder to see workspace info."131 );132 }133 new import_obsidian2.Setting(containerEl).setName("API token").setDesc(134 "Required for version history. Generate at sublimated.com/settings/tokens"135 ).addText(136 (text) => text.setPlaceholder("sk_...").setValue(this.plugin.settings.apiToken).onChange(async (value) => {137 this.plugin.settings.apiToken = value;138 await this.plugin.saveSettings();139 })140 );141 new import_obsidian2.Setting(containerEl).setName("Test connection").setDesc("Verify your API token works").addButton(142 (btn) => btn.setButtonText("Test").onClick(async () => {143 if (!this.plugin.settings.apiToken) {144 new import_obsidian2.Notice("No API token configured");145 return;146 }147 btn.setButtonText("Testing...");148 btn.setDisabled(true);149 const api = new SublimatedApi(150 this.plugin.settings.apiToken151 );152 const result = await api.testConnection();153 if (result.ok) {154 new import_obsidian2.Notice(155 `Connected as ${result.username}`156 );157 } else {158 new import_obsidian2.Notice(159 `Connection failed: ${result.error}`160 );161 }162 btn.setButtonText("Test");163 btn.setDisabled(false);164 })165 );166 containerEl.createEl("div", { cls: "sbl-settings-links" }, (el) => {167 el.createEl("a", {168 text: "sublimated.com",169 href: "https://sublimated.com"170 });171 el.createEl("span", { text: " \xB7 " });172 el.createEl("a", {173 text: "Documentation",174 href: "https://sublimated.com/docs/obsidian"175 });176 el.createEl("span", { text: " \xB7 " });177 el.createEl("a", {178 text: "Source code",179 href: "https://sublimated.com/sublimated/code/obsidian"180 });181 });182 }183};184
185// src/xattr.ts186var import_child_process = require("child_process");187var import_obsidian3 = require("obsidian");188var XATTR_PREFIX = "com.sublimated.";189var XATTR_SUFFIX = "#PS";190var ATTRS = [191 "version",192 "commit",193 "url",194 "contentHash",195 "id",196 "createdBy",197 "modifiedBy",198 "modifiedByType",199 "syncStatus",200 "space",201 "branch",202 "modifiedAt",203 "visibility"204];205function attrToXattrName(attr) {206 const kebab = attr.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());207 return `${XATTR_PREFIX}${kebab}${XATTR_SUFFIX}`;208}209function readXattr(path, xattrName) {210 return new Promise((resolve) => {211 (0, import_child_process.exec)(212 `xattr -p ${JSON.stringify(xattrName)} ${JSON.stringify(path)}`,213 { timeout: 2e3 },214 (err, stdout) => {215 if (err) {216 resolve(null);217 return;218 }219 resolve(stdout.trim() || null);220 }221 );222 });223}224async function readFileMetadata(path) {225 if (!import_obsidian3.Platform.isMacOS) return null;226 const results = await Promise.all(227 ATTRS.map((attr) => readXattr(path, attrToXattrName(attr)))228 );229 if (results.every((r) => r === null)) return null;230 const meta = {231 version: null,232 commit: null,233 url: null,234 contentHash: null,235 id: null,236 createdBy: null,237 modifiedBy: null,238 modifiedByType: null,239 syncStatus: null,240 space: null,241 branch: null,242 modifiedAt: null,243 visibility: null244 };245 ATTRS.forEach((attr, i) => {246 meta[attr] = results[i];247 });248 return meta;249}250function isMacOS() {251 return import_obsidian3.Platform.isMacOS;252}253
254// src/version-view.ts255var import_obsidian4 = require("obsidian");256var VERSION_VIEW_TYPE = "sublimated-versions";257var VersionView = class extends import_obsidian4.ItemView {258 plugin;259 constructor(leaf, plugin) {260 super(leaf);261 this.plugin = plugin;262 }263 getViewType() {264 return VERSION_VIEW_TYPE;265 }266 getDisplayText() {267 return "sublimated versions";268 }269 getIcon() {270 return "history";271 }272 async onOpen() {273 await this.refresh();274 this.registerEvent(275 this.app.workspace.on("active-leaf-change", () => {276 this.refresh();277 })278 );279 }280 async refresh() {281 const { contentEl } = this;282 contentEl.empty();283 contentEl.addClass("sbl-version-view");284 const activeFile = this.app.workspace.getActiveFile();285 if (!activeFile) {286 contentEl.createEl("p", {287 text: "No file open.",288 cls: "sbl-version-empty"289 });290 return;291 }292 const meta = this.plugin.lastMetadata;293 if (!meta?.space || !meta?.id) {294 contentEl.createEl("p", {295 text: "Not a sublimated file.",296 cls: "sbl-version-empty"297 });298 return;299 }300 contentEl.createEl("h4", {301 text: activeFile.name,302 cls: "sbl-version-filename"303 });304 const loading = contentEl.createEl("p", {305 text: "Loading versions...",306 cls: "sbl-version-loading"307 });308 try {309 const api = new SublimatedApi(this.plugin.settings.apiToken);310 const versions = await api.getVersions(meta.space, meta.id);311 loading.remove();312 if (versions.length === 0) {313 contentEl.createEl("p", {314 text: "No versions found.",315 cls: "sbl-version-empty"316 });317 return;318 }319 const list = contentEl.createEl("div", {320 cls: "sbl-version-list"321 });322 const groups = groupByDay(versions);323 for (const group of groups) {324 list.createEl("div", {325 text: group.label,326 cls: "sbl-version-day"327 });328 for (const v of group.versions) {329 this.renderVersion(list, v, meta.url);330 }331 }332 } catch (e) {333 loading.remove();334 if (e instanceof AuthRequiredError) {335 contentEl.createEl("p", {336 text: "This file is private \u2014 add an API token to view version history.",337 cls: "sbl-version-empty"338 });339 contentEl.createEl("p", {340 text: "Configure in Settings \u2192 sublimated",341 cls: "sbl-version-hint"342 });343 return;344 }345 contentEl.createEl("p", {346 text: `Error: ${e instanceof Error ? e.message : "Unknown"}`,347 cls: "sbl-version-error"348 });349 }350 }351 renderVersion(container, v, fileUrl) {352 const item = container.createDiv({ cls: "sbl-version-item" });353 const header = item.createDiv({ cls: "sbl-version-header" });354 header.createEl("span", {355 text: `v${v.number}`,356 cls: "sbl-version-number"357 });358 header.createEl("span", {359 text: v.authorName,360 cls: "sbl-version-author"361 });362 const time = item.createDiv({ cls: "sbl-version-time" });363 time.createEl("span", {364 text: formatRelativeTime(v.createdAt),365 attr: { title: new Date(v.createdAt).toLocaleString() }366 });367 if (v.message) {368 item.createDiv({369 text: v.message,370 cls: "sbl-version-message"371 });372 }373 if (fileUrl) {374 const webUrl = `https://${fileUrl}/~versions/v${v.number}`;375 const link = item.createEl("a", {376 text: "view on web",377 cls: "sbl-version-web-link",378 href: webUrl379 });380 link.addEventListener("click", (e) => {381 e.preventDefault();382 window.open(webUrl);383 });384 }385 }386 async onClose() {387 }388};389function groupByDay(versions) {390 const groups = /* @__PURE__ */ new Map();391 const order = [];392 for (const v of versions) {393 const label = formatDayLabel(v.createdAt);394 if (!groups.has(label)) {395 groups.set(label, []);396 order.push(label);397 }398 groups.get(label).push(v);399 }400 return order.map((label) => ({401 label,402 versions: groups.get(label)403 }));404}405function formatDayLabel(iso) {406 const now = /* @__PURE__ */ new Date();407 const date = new Date(iso);408 const nowDay = new Date(now.getFullYear(), now.getMonth(), now.getDate());409 const thenDay = new Date(410 date.getFullYear(),411 date.getMonth(),412 date.getDate()413 );414 const days = Math.round(415 (nowDay.getTime() - thenDay.getTime()) / (1e3 * 60 * 60 * 24)416 );417 if (days === 0) return "Today";418 if (days === 1) return "Yesterday";419 if (days < 7) return `${days} days ago`;420 return date.toLocaleDateString("en-US", {421 month: "short",422 day: "numeric"423 });424}425function formatRelativeTime(iso) {426 const now = Date.now();427 const then = new Date(iso).getTime();428 const diff = now - then;429 const seconds = Math.floor(diff / 1e3);430 const minutes = Math.floor(seconds / 60);431 const hours = Math.floor(minutes / 60);432 const days = Math.floor(hours / 24);433 if (days > 30) return new Date(iso).toLocaleDateString();434 if (days > 0) return `${days}d ago`;435 if (hours > 0) return `${hours}h ago`;436 if (minutes > 0) return `${minutes}m ago`;437 return "just now";438}439
440// src/welcome-modal.ts441var import_obsidian5 = require("obsidian");442var WelcomeModal = class extends import_obsidian5.Modal {443 constructor(app) {444 super(app);445 }446 onOpen() {447 const { contentEl } = this;448 contentEl.addClass("sbl-welcome-modal");449 contentEl.createEl("h2", { text: "Welcome to sublimated" });450 contentEl.createEl("p", {451 text: "sublimated syncs your files with version history, collaboration, and a web viewer \u2014 all powered by git under the hood."452 });453 const steps = contentEl.createEl("div", { cls: "sbl-welcome-steps" });454 const step1 = steps.createDiv({ cls: "sbl-welcome-step" });455 step1.createEl("strong", { text: "1. Open a sublimated folder as a vault" });456 step1.createEl("p", {457 text: "In Finder, open any sublimated folder (or subfolder) under CloudStorage as an Obsidian vault. The plugin activates automatically on synced files."458 });459 const step2 = steps.createDiv({ cls: "sbl-welcome-step" });460 step2.createEl("strong", { text: "2. Status bar shows sync info" });461 step2.createEl("p", {462 text: "The bottom bar shows version number, sync status, and author for the current file \u2014 all read from local file metadata, no account needed."463 });464 const step3 = steps.createDiv({ cls: "sbl-welcome-step" });465 step3.createEl("strong", { text: "3. Add an API token for version history" });466 step3.createEl("p", {467 text: "To browse past versions, add your API token in Settings \u2192 sublimated. Generate one at sublimated.com/settings/tokens."468 });469 const links = contentEl.createDiv({ cls: "sbl-welcome-links" });470 links.createEl("a", {471 text: "Documentation",472 href: "https://sublimated.com/docs/obsidian"473 });474 links.createEl("br");475 links.createEl("a", {476 text: "Source code",477 href: "https://sublimated.com/sublimated/code/obsidian"478 });479 const footer = contentEl.createDiv({ cls: "sbl-welcome-footer" });480 footer.createEl("button", {481 text: "Get started",482 cls: "mod-cta"483 }).addEventListener("click", () => this.close());484 }485 onClose() {486 this.contentEl.empty();487 }488};489
490// src/main.ts491var SublimatedPlugin = class extends import_obsidian6.Plugin {492 settings = DEFAULT_SETTINGS;493 lastMetadata = null;494 statusBarEl = null;495 async onload() {496 await this.loadSettings();497 this.statusBarEl = this.addStatusBarItem();498 this.statusBarEl.addClass("sbl-status-bar");499 this.statusBarEl.addEventListener(500 "click",501 () => this.openCurrentFileOnWeb()502 );503 this.updateStatusBar(null);504 this.registerView(505 VERSION_VIEW_TYPE,506 (leaf) => new VersionView(leaf, this)507 );508 this.addCommand({509 id: "open-on-web",510 name: "Open on sublimated.com",511 callback: () => this.openCurrentFileOnWeb()512 });513 this.addCommand({514 id: "show-versions",515 name: "Show versions",516 callback: () => this.activateVersionView()517 });518 this.addCommand({519 id: "copy-web-link",520 name: "Copy web link",521 callback: () => this.copyWebLink()522 });523 this.addRibbonIcon("history", "sublimated versions", () => {524 this.activateVersionView();525 });526 this.registerObsidianProtocolHandler(527 "sublimated",528 (params) => this.handleUri(params)529 );530 this.addSettingTab(new SublimatedSettingTab(this.app, this));531 this.registerEvent(532 this.app.workspace.on("active-leaf-change", () => {533 this.refreshMetadata();534 })535 );536 this.refreshMetadata();537 if (!this.settings.hasSeenWelcome) {538 new WelcomeModal(this.app).open();539 this.settings.hasSeenWelcome = true;540 await this.saveSettings();541 }542 }543 onunload() {544 this.app.workspace.detachLeavesOfType(VERSION_VIEW_TYPE);545 }546 async loadSettings() {547 this.settings = Object.assign(548 {},549 DEFAULT_SETTINGS,550 await this.loadData()551 );552 }553 async saveSettings() {554 await this.saveData(this.settings);555 }556 // detect workspace from xattrs on the currently active file.557 // every synced file carries com.sublimated.space#PS, so any file558 // with sublimated metadata identifies the workspace.559 detectWorkspace() {560 if (!this.lastMetadata) return null;561 if (!this.lastMetadata.space && !this.lastMetadata.id) return null;562 return {563 space: this.lastMetadata.space ?? null564 };565 }566 async refreshMetadata() {567 const file = this.app.workspace.getActiveFile();568 if (!file) {569 this.lastMetadata = null;570 this.updateStatusBar(null);571 return;572 }573 if (!isMacOS()) {574 this.lastMetadata = null;575 this.updateStatusBar(null);576 return;577 }578 const adapter = this.app.vault.adapter;579 const basePath = adapter.getBasePath?.();580 if (!basePath) {581 this.lastMetadata = null;582 this.updateStatusBar(null);583 return;584 }585 const absPath = `${basePath}/${file.path}`;586 this.lastMetadata = await readFileMetadata(absPath);587 this.updateStatusBar(this.lastMetadata);588 }589 updateStatusBar(meta) {590 if (!this.statusBarEl) return;591 if (!meta || !meta.space && !meta.id) {592 this.statusBarEl.setText("");593 return;594 }595 const parts = [];596 if (meta.syncStatus) {597 const icon = syncStatusIcon(meta.syncStatus);598 parts.push(icon ? `${icon} ${meta.syncStatus}` : meta.syncStatus);599 }600 if (meta.version) {601 parts.push(`v${meta.version}`);602 }603 if (meta.modifiedBy) {604 const prefix = meta.modifiedByType === "ai_agent" ? "by AI:" : "by";605 parts.push(`${prefix} ${meta.modifiedBy}`);606 }607 if (meta.branch && meta.branch !== "main") {608 parts.push(meta.branch);609 }610 if (meta.visibility) {611 parts.push(visibilityIcon(meta.visibility));612 }613 this.statusBarEl.setText(parts.join(" "));614 if (meta.url) {615 this.statusBarEl.addClass("sbl-clickable");616 } else {617 this.statusBarEl.removeClass("sbl-clickable");618 }619 }620 openCurrentFileOnWeb() {621 const url = this.lastMetadata?.url;622 if (!url) {623 new import_obsidian6.Notice("No sublimated URL for this file");624 return;625 }626 window.open(`https://${url}`);627 }628 async copyWebLink() {629 const url = this.lastMetadata?.url;630 if (!url) {631 new import_obsidian6.Notice("No sublimated URL for this file");632 return;633 }634 await navigator.clipboard.writeText(`https://${url}`);635 new import_obsidian6.Notice("Link copied to clipboard");636 }637 async activateVersionView() {638 const existing = this.app.workspace.getLeavesOfType(VERSION_VIEW_TYPE);639 if (existing.length > 0) {640 this.app.workspace.revealLeaf(existing[0]);641 return;642 }643 const leaf = this.app.workspace.getRightLeaf(false);644 if (!leaf) return;645 await leaf.setViewState({646 type: VERSION_VIEW_TYPE,647 active: true648 });649 this.app.workspace.revealLeaf(leaf);650 }651 handleUri(params) {652 const { action, file } = params;653 if (action === "open" && file) {654 const normalized = (0, import_obsidian6.normalizePath)(file);655 const existing = this.app.vault.getAbstractFileByPath(normalized);656 if (existing) {657 this.app.workspace.openLinkText(normalized, "", false);658 } else {659 new import_obsidian6.Notice(`File not found: ${file}`);660 }661 return;662 }663 if (action === "auth" && params.token) {664 this.settings.apiToken = params.token;665 this.saveSettings();666 new import_obsidian6.Notice("sublimated: signed in successfully");667 return;668 }669 new import_obsidian6.Notice(`Unknown sublimated action: ${action}`);670 }671};672function syncStatusIcon(status) {673 switch (status) {674 case "synced":675 return "\u2713";676 case "uploading":677 return "\u2191";678 case "downloading":679 return "\u2193";680 case "error":681 return "!";682 case "conflict":683 return "\u26A0";684 default:685 return "";686 }687}688function visibilityIcon(visibility) {689 switch (visibility) {690 case "public":691 return "\u{1F310}";692 case "shared":693 return "\u{1F465}";694 case "private":695 return "\u{1F512}";696 default:697 return "";698 }699}700//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL3NldHRpbmdzLnRzIiwgInNyYy9hcGkudHMiLCAic3JjL3hhdHRyLnRzIiwgInNyYy92ZXJzaW9uLXZpZXcudHMiLCAic3JjL3dlbGNvbWUtbW9kYWwudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7XG5cdE5vdGljZSxcblx0UGx1Z2luLFxuXHRXb3Jrc3BhY2VMZWFmLFxuXHRub3JtYWxpemVQYXRoLFxufSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7XG5cdHR5cGUgU3VibGltYXRlZFNldHRpbmdzLFxuXHRERUZBVUxUX1NFVFRJTkdTLFxuXHRTdWJsaW1hdGVkU2V0dGluZ1RhYixcbn0gZnJvbSBcIi4vc2V0dGluZ3NcIjtcbmltcG9ydCB7IHR5cGUgRmlsZU1ldGFkYXRhLCByZWFkRmlsZU1ldGFkYXRhLCBpc01hY09TIH0gZnJvbSBcIi4veGF0dHJcIjtcbmltcG9ydCB7IFZlcnNpb25WaWV3LCBWRVJTSU9OX1ZJRVdfVFlQRSB9IGZyb20gXCIuL3ZlcnNpb24tdmlld1wiO1xuaW1wb3J0IHsgV2VsY29tZU1vZGFsIH0gZnJvbSBcIi4vd2VsY29tZS1tb2RhbFwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTdWJsaW1hdGVkUGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IFN1YmxpbWF0ZWRTZXR0aW5ncyA9IERFRkFVTFRfU0VUVElOR1M7XG5cdGxhc3RNZXRhZGF0YTogRmlsZU1ldGFkYXRhIHwgbnVsbCA9IG51bGw7XG5cblx0cHJpdmF0ZSBzdGF0dXNCYXJFbDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuXHRhc3luYyBvbmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0YXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcblxuXHRcdC8vIHN0YXR1cyBiYXJcblx0XHR0aGlzLnN0YXR1c0JhckVsID0gdGhpcy5hZGRTdGF0dXNCYXJJdGVtKCk7XG5cdFx0dGhpcy5zdGF0dXNCYXJFbC5hZGRDbGFzcyhcInNibC1zdGF0dXMtYmFyXCIpO1xuXHRcdHRoaXMuc3RhdHVzQmFyRWwuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsICgpID0+XG5cdFx0XHR0aGlzLm9wZW5DdXJyZW50RmlsZU9uV2ViKClcblx0XHQpO1xuXHRcdHRoaXMudXBkYXRlU3RhdHVzQmFyKG51bGwpO1xuXG5cdFx0Ly8gcmVnaXN0ZXIgdmVyc2lvbiBoaXN0b3J5IHZpZXdcblx0XHR0aGlzLnJlZ2lzdGVyVmlldyhcblx0XHRcdFZFUlNJT05fVklFV19UWVBFLFxuXHRcdFx0KGxlYWYpID0+IG5ldyBWZXJzaW9uVmlldyhsZWFmLCB0aGlzKVxuXHRcdCk7XG5cblx0XHQvLyBjb21tYW5kc1xuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogXCJvcGVuLW9uLXdlYlwiLFxuXHRcdFx0bmFtZTogXCJPcGVuIG9uIHN1YmxpbWF0ZWQuY29tXCIsXG5cdFx0XHRjYWxsYmFjazogKCkgPT4gdGhpcy5vcGVuQ3VycmVudEZpbGVPbldlYigpLFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiBcInNob3ctdmVyc2lvbnNcIixcblx0XHRcdG5hbWU6IFwiU2hvdyB2ZXJzaW9uc1wiLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHRoaXMuYWN0aXZhdGVWZXJzaW9uVmlldygpLFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiBcImNvcHktd2ViLWxpbmtcIixcblx0XHRcdG5hbWU6IFwiQ29weSB3ZWIgbGlua1wiLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHRoaXMuY29weVdlYkxpbmsoKSxcblx0XHR9KTtcblxuXHRcdC8vIHJpYmJvbiBpY29uIGZvciB2ZXJzaW9uIHNpZGViYXJcblx0XHR0aGlzLmFkZFJpYmJvbkljb24oXCJoaXN0b3J5XCIsIFwic3VibGltYXRlZCB2ZXJzaW9uc1wiLCAoKSA9PiB7XG5cdFx0XHR0aGlzLmFjdGl2YXRlVmVyc2lvblZpZXcoKTtcblx0XHR9KTtcblxuXHRcdC8vIFVSSSBoYW5kbGVyOiBvYnNpZGlhbjovL3N1YmxpbWF0ZWQ/YWN0aW9uPW9wZW4mZmlsZT1wYXRoL3RvL25vdGUubWRcblx0XHR0aGlzLnJlZ2lzdGVyT2JzaWRpYW5Qcm90b2NvbEhhbmRsZXIoXG5cdFx0XHRcInN1YmxpbWF0ZWRcIixcblx0XHRcdChwYXJhbXMpID0+IHRoaXMuaGFuZGxlVXJpKHBhcmFtcylcblx0XHQpO1xuXG5cdFx0Ly8gc2V0dGluZ3MgdGFiXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBTdWJsaW1hdGVkU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG5cdFx0Ly8gdXBkYXRlIHN0YXR1cyBiYXIgd2hlbiBhY3RpdmUgZmlsZSBjaGFuZ2VzXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKFwiYWN0aXZlLWxlYWYtY2hhbmdlXCIsICgpID0+IHtcblx0XHRcdFx0dGhpcy5yZWZyZXNoTWV0YWRhdGEoKTtcblx0XHRcdH0pXG5cdFx0KTtcblxuXHRcdC8vIGluaXRpYWwgbWV0YWRhdGEgcmVhZFxuXHRcdHRoaXMucmVmcmVzaE1ldGFkYXRhKCk7XG5cblx0XHQvLyB3ZWxjb21lIG1vZGFsIG9uIGZpcnN0IGluc3RhbGxcblx0XHRpZiAoIXRoaXMuc2V0dGluZ3MuaGFzU2VlbldlbGNvbWUpIHtcblx0XHRcdG5ldyBXZWxjb21lTW9kYWwodGhpcy5hcHApLm9wZW4oKTtcblx0XHRcdHRoaXMuc2V0dGluZ3MuaGFzU2VlbldlbGNvbWUgPSB0cnVlO1xuXHRcdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHR9XG5cdH1cblxuXHRvbnVubG9hZCgpOiB2b2lkIHtcblx0XHR0aGlzLmFwcC53b3Jrc3BhY2UuZGV0YWNoTGVhdmVzT2ZUeXBlKFZFUlNJT05fVklFV19UWVBFKTtcblx0fVxuXG5cdGFzeW5jIGxvYWRTZXR0aW5ncygpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHR0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbihcblx0XHRcdHt9LFxuXHRcdFx0REVGQVVMVF9TRVRUSU5HUyxcblx0XHRcdGF3YWl0IHRoaXMubG9hZERhdGEoKVxuXHRcdCk7XG5cdH1cblxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxuXG5cdC8vIGRldGVjdCB3b3Jrc3BhY2UgZnJvbSB4YXR0cnMgb24gdGhlIGN1cnJlbnRseSBhY3RpdmUgZmlsZS5cblx0Ly8gZXZlcnkgc3luY2VkIGZpbGUgY2FycmllcyBjb20uc3VibGltYXRlZC5zcGFjZSNQUywgc28gYW55IGZpbGVcblx0Ly8gd2l0aCBzdWJsaW1hdGVkIG1ldGFkYXRhIGlkZW50aWZpZXMgdGhlIHdvcmtzcGFjZS5cblx0ZGV0ZWN0V29ya3NwYWNlKCk6IHsgc3BhY2U6IHN0cmluZyB8IG51bGwgfSB8IG51bGwge1xuXHRcdGlmICghdGhpcy5sYXN0TWV0YWRhdGEpIHJldHVybiBudWxsO1xuXHRcdGlmICghdGhpcy5sYXN0TWV0YWRhdGEuc3BhY2UgJiYgIXRoaXMubGFzdE1ldGFkYXRhLmlkKSByZXR1cm4gbnVsbDtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c3BhY2U6IHRoaXMubGFzdE1ldGFkYXRhLnNwYWNlID8/IG51bGwsXG5cdFx0fTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgcmVmcmVzaE1ldGFkYXRhKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xuXHRcdGlmICghZmlsZSkge1xuXHRcdFx0dGhpcy5sYXN0TWV0YWRhdGEgPSBudWxsO1xuXHRcdFx0dGhpcy51cGRhdGVTdGF0dXNCYXIobnVsbCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCFpc01hY09TKCkpIHtcblx0XHRcdHRoaXMubGFzdE1ldGFkYXRhID0gbnVsbDtcblx0XHRcdHRoaXMudXBkYXRlU3RhdHVzQmFyKG51bGwpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGdldCBhYnNvbHV0ZSBwYXRoIHZpYSB2YXVsdCBhZGFwdGVyXG5cdFx0Y29uc3QgYWRhcHRlciA9IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXI7XG5cdFx0Y29uc3QgYmFzZVBhdGggPSAoYWRhcHRlciBhcyB7IGdldEJhc2VQYXRoPzogKCkgPT4gc3RyaW5nIH0pXG5cdFx0XHQuZ2V0QmFzZVBhdGg/LigpO1xuXHRcdGlmICghYmFzZVBhdGgpIHtcblx0XHRcdHRoaXMubGFzdE1ldGFkYXRhID0gbnVsbDtcblx0XHRcdHRoaXMudXBkYXRlU3RhdHVzQmFyKG51bGwpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IGFic1BhdGggPSBgJHtiYXNlUGF0aH0vJHtmaWxlLnBhdGh9YDtcblx0XHR0aGlzLmxhc3RNZXRhZGF0YSA9IGF3YWl0IHJlYWRGaWxlTWV0YWRhdGEoYWJzUGF0aCk7XG5cdFx0dGhpcy51cGRhdGVTdGF0dXNCYXIodGhpcy5sYXN0TWV0YWRhdGEpO1xuXHR9XG5cblx0cHJpdmF0ZSB1cGRhdGVTdGF0dXNCYXIobWV0YTogRmlsZU1ldGFkYXRhIHwgbnVsbCk6IHZvaWQge1xuXHRcdGlmICghdGhpcy5zdGF0dXNCYXJFbCkgcmV0dXJuO1xuXG5cdFx0Ly8gbm8gc3VibGltYXRlZCB4YXR0cnMgXHUyMTkyIGZpbGUgaXNuJ3QgdHJhY2tlZCBieSBzdWJsaW1hdGVkLCBoaWRlIHN0YXR1cyBiYXJcblx0XHRpZiAoIW1ldGEgfHwgKCFtZXRhLnNwYWNlICYmICFtZXRhLmlkKSkge1xuXHRcdFx0dGhpcy5zdGF0dXNCYXJFbC5zZXRUZXh0KFwiXCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGNvbXBhY3QgZm9ybWF0OiBcIlx1MjcxMyBzeW5jZWQgdjIxIGJ5IGFudG9uXCIgKHN5bmMgKyB2ZXJzaW9uICsgYXV0aG9yICsgb3B0aW9uYWwgYnJhbmNoL3Zpc2liaWxpdHkpXG5cdFx0Y29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XG5cblx0XHRpZiAobWV0YS5zeW5jU3RhdHVzKSB7XG5cdFx0XHRjb25zdCBpY29uID0gc3luY1N0YXR1c0ljb24obWV0YS5zeW5jU3RhdHVzKTtcblx0XHRcdHBhcnRzLnB1c2goaWNvbiA/IGAke2ljb259ICR7bWV0YS5zeW5jU3RhdHVzfWAgOiBtZXRhLnN5bmNTdGF0dXMpO1xuXHRcdH1cblxuXHRcdGlmIChtZXRhLnZlcnNpb24pIHtcblx0XHRcdHBhcnRzLnB1c2goYHYke21ldGEudmVyc2lvbn1gKTtcblx0XHR9XG5cblx0XHRpZiAobWV0YS5tb2RpZmllZEJ5KSB7XG5cdFx0XHRjb25zdCBwcmVmaXggPVxuXHRcdFx0XHRtZXRhLm1vZGlmaWVkQnlUeXBlID09PSBcImFpX2FnZW50XCIgPyBcImJ5IEFJOlwiIDogXCJieVwiO1xuXHRcdFx0cGFydHMucHVzaChgJHtwcmVmaXh9ICR7bWV0YS5tb2RpZmllZEJ5fWApO1xuXHRcdH1cblxuXHRcdGlmIChtZXRhLmJyYW5jaCAmJiBtZXRhLmJyYW5jaCAhPT0gXCJtYWluXCIpIHtcblx0XHRcdHBhcnRzLnB1c2gobWV0YS5icmFuY2gpO1xuXHRcdH1cblxuXHRcdGlmIChtZXRhLnZpc2liaWxpdHkpIHtcblx0XHRcdHBhcnRzLnB1c2godmlzaWJpbGl0eUljb24obWV0YS52aXNpYmlsaXR5KSk7XG5cdFx0fVxuXG5cdFx0dGhpcy5zdGF0dXNCYXJFbC5zZXRUZXh0KHBhcnRzLmpvaW4oXCIgXCIpKTtcblxuXHRcdC8vIHNob3cgcG9pbnRlciBjdXJzb3Igd2hlbiBVUkwgYXZhaWxhYmxlXG5cdFx0aWYgKG1ldGEudXJsKSB7XG5cdFx0XHR0aGlzLnN0YXR1c0JhckVsLmFkZENsYXNzKFwic2JsLWNsaWNrYWJsZVwiKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5zdGF0dXNCYXJFbC5yZW1vdmVDbGFzcyhcInNibC1jbGlja2FibGVcIik7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBvcGVuQ3VycmVudEZpbGVPbldlYigpOiB2b2lkIHtcblx0XHRjb25zdCB1cmwgPSB0aGlzLmxhc3RNZXRhZGF0YT8udXJsO1xuXHRcdGlmICghdXJsKSB7XG5cdFx0XHRuZXcgTm90aWNlKFwiTm8gc3VibGltYXRlZCBVUkwgZm9yIHRoaXMgZmlsZVwiKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0d2luZG93Lm9wZW4oYGh0dHBzOi8vJHt1cmx9YCk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGNvcHlXZWJMaW5rKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHVybCA9IHRoaXMubGFzdE1ldGFkYXRhPy51cmw7XG5cdFx0aWYgKCF1cmwpIHtcblx0XHRcdG5ldyBOb3RpY2UoXCJObyBzdWJsaW1hdGVkIFVSTCBmb3IgdGhpcyBmaWxlXCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRhd2FpdCBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dChgaHR0cHM6Ly8ke3VybH1gKTtcblx0XHRuZXcgTm90aWNlKFwiTGluayBjb3BpZWQgdG8gY2xpcGJvYXJkXCIpO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBhY3RpdmF0ZVZlcnNpb25WaWV3KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGV4aXN0aW5nID1cblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5nZXRMZWF2ZXNPZlR5cGUoVkVSU0lPTl9WSUVXX1RZUEUpO1xuXHRcdGlmIChleGlzdGluZy5sZW5ndGggPiAwKSB7XG5cdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2UucmV2ZWFsTGVhZihleGlzdGluZ1swXSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgbGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRSaWdodExlYWYoZmFsc2UpO1xuXHRcdGlmICghbGVhZikgcmV0dXJuO1xuXHRcdGF3YWl0IGxlYWYuc2V0Vmlld1N0YXRlKHtcblx0XHRcdHR5cGU6IFZFUlNJT05fVklFV19UWVBFLFxuXHRcdFx0YWN0aXZlOiB0cnVlLFxuXHRcdH0pO1xuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5yZXZlYWxMZWFmKGxlYWYpO1xuXHR9XG5cblx0cHJpdmF0ZSBoYW5kbGVVcmkocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogdm9pZCB7XG5cdFx0Y29uc3QgeyBhY3Rpb24sIGZpbGUgfSA9IHBhcmFtcztcblxuXHRcdGlmIChhY3Rpb24gPT09IFwib3BlblwiICYmIGZpbGUpIHtcblx0XHRcdGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVQYXRoKGZpbGUpO1xuXHRcdFx0Y29uc3QgZXhpc3RpbmcgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgobm9ybWFsaXplZCk7XG5cdFx0XHRpZiAoZXhpc3RpbmcpIHtcblx0XHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9wZW5MaW5rVGV4dChub3JtYWxpemVkLCBcIlwiLCBmYWxzZSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRuZXcgTm90aWNlKGBGaWxlIG5vdCBmb3VuZDogJHtmaWxlfWApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmIChhY3Rpb24gPT09IFwiYXV0aFwiICYmIHBhcmFtcy50b2tlbikge1xuXHRcdFx0Ly8gZnV0dXJlOiBPQXV0aCBmbG93IHN0b3JlcyB0b2tlbiBmcm9tIHJlZGlyZWN0XG5cdFx0XHR0aGlzLnNldHRpbmdzLmFwaVRva2VuID0gcGFyYW1zLnRva2VuO1xuXHRcdFx0dGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdG5ldyBOb3RpY2UoXCJzdWJsaW1hdGVkOiBzaWduZWQgaW4gc3VjY2Vzc2Z1bGx5XCIpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdG5ldyBOb3RpY2UoYFVua25vd24gc3VibGltYXRlZCBhY3Rpb246ICR7YWN0aW9ufWApO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHN5bmNTdGF0dXNJY29uKHN0YXR1czogc3RyaW5nKTogc3RyaW5nIHtcblx0c3dpdGNoIChzdGF0dXMpIHtcblx0XHRjYXNlIFwic3luY2VkXCI6XG5cdFx0XHRyZXR1cm4gXCJcdTI3MTNcIjtcblx0XHRjYXNlIFwidXBsb2FkaW5nXCI6XG5cdFx0XHRyZXR1cm4gXCJcdTIxOTFcIjtcblx0XHRjYXNlIFwiZG93bmxvYWRpbmdcIjpcblx0XHRcdHJldHVybiBcIlx1MjE5M1wiO1xuXHRcdGNhc2UgXCJlcnJvclwiOlxuXHRcdFx0cmV0dXJuIFwiIVwiO1xuXHRcdGNhc2UgXCJjb25mbGljdFwiOlxuXHRcdFx0cmV0dXJuIFwiXHUyNkEwXCI7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHJldHVybiBcIlwiO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHZpc2liaWxpdHlJY29uKHZpc2liaWxpdHk6IHN0cmluZyk6IHN0cmluZyB7XG5cdHN3aXRjaCAodmlzaWJpbGl0eSkge1xuXHRcdGNhc2UgXCJwdWJsaWNcIjpcblx0XHRcdHJldHVybiBcIlx1RDgzQ1x1REYxMFwiO1xuXHRcdGNhc2UgXCJzaGFyZWRcIjpcblx0XHRcdHJldHVybiBcIlx1RDgzRFx1REM2NVwiO1xuXHRcdGNhc2UgXCJwcml2YXRlXCI6XG5cdFx0XHRyZXR1cm4gXCJcdUQ4M0RcdUREMTJcIjtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIFwiXCI7XG5cdH1cbn1cbiIsICJpbXBvcnQgeyBBcHAsIE5vdGljZSwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUgU3VibGltYXRlZFBsdWdpbiBmcm9tIFwiLi9tYWluXCI7XG5pbXBvcnQgeyBTdWJsaW1hdGVkQXBpIH0gZnJvbSBcIi4vYXBpXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VibGltYXRlZFNldHRpbmdzIHtcblx0YXBpVG9rZW46IHN0cmluZztcblx0aGFzU2VlbldlbGNvbWU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFVFRJTkdTOiBTdWJsaW1hdGVkU2V0dGluZ3MgPSB7XG5cdGFwaVRva2VuOiBcIlwiLFxuXHRoYXNTZWVuV2VsY29tZTogZmFsc2UsXG59O1xuXG5leHBvcnQgY2xhc3MgU3VibGltYXRlZFNldHRpbmdUYWIgZXh0ZW5kcyBQbHVnaW5TZXR0aW5nVGFiIHtcblx0cGx1Z2luOiBTdWJsaW1hdGVkUGx1Z2luO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IFN1YmxpbWF0ZWRQbHVnaW4pIHtcblx0XHRzdXBlcihhcHAsIHBsdWdpbik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRkaXNwbGF5KCk6IHZvaWQge1xuXHRcdGNvbnN0IHsgY29udGFpbmVyRWwgfSA9IHRoaXM7XG5cdFx0Y29udGFpbmVyRWwuZW1wdHkoKTtcblxuXHRcdC8vIGJyYW5kaW5nXG5cdFx0Y29uc3QgaGVhZGVyID0gY29udGFpbmVyRWwuY3JlYXRlRGl2KHsgY2xzOiBcInNibC1zZXR0aW5ncy1oZWFkZXJcIiB9KTtcblx0XHRoZWFkZXIuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwic3VibGltYXRlZFwiIH0pO1xuXHRcdGhlYWRlci5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0dGV4dDogXCJTeW5jIHN0YXR1cywgdmVyc2lvbiBoaXN0b3J5LCBhbmQgZGVlcCBsaW5rcy5cIixcblx0XHRcdGNsczogXCJzZXR0aW5nLWl0ZW0tZGVzY3JpcHRpb25cIixcblx0XHR9KTtcblxuXHRcdC8vIHdvcmtzcGFjZSBkZXRlY3Rpb24gKGJhc2VkIG9uIHhhdHRycyBvZiB0aGUgbGFzdCBvcGVuZWQgZmlsZSlcblx0XHRjb25zdCB3b3Jrc3BhY2VJbmZvID0gdGhpcy5wbHVnaW4uZGV0ZWN0V29ya3NwYWNlKCk7XG5cdFx0aWYgKHdvcmtzcGFjZUluZm8pIHtcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHQuc2V0TmFtZShcIkRldGVjdGVkIHdvcmtzcGFjZVwiKVxuXHRcdFx0XHQuc2V0RGVzYyhcblx0XHRcdFx0XHRgU3BhY2U6ICR7d29ya3NwYWNlSW5mby5zcGFjZSB8fCBcInVua25vd25cIn1gXG5cdFx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0XHQuc2V0TmFtZShcIk5vIHN1YmxpbWF0ZWQgZmlsZSBvcGVuXCIpXG5cdFx0XHRcdC5zZXREZXNjKFxuXHRcdFx0XHRcdFwiT3BlbiBhbnkgc3luY2VkIGZpbGUgZnJvbSBhIHN1YmxpbWF0ZWQgZm9sZGVyIHRvIHNlZSB3b3Jrc3BhY2UgaW5mby5cIlxuXHRcdFx0XHQpO1xuXHRcdH1cblxuXHRcdC8vIEFQSSB0b2tlblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoXCJBUEkgdG9rZW5cIilcblx0XHRcdC5zZXREZXNjKFxuXHRcdFx0XHRcIlJlcXVpcmVkIGZvciB2ZXJzaW9uIGhpc3RvcnkuIEdlbmVyYXRlIGF0IHN1YmxpbWF0ZWQuY29tL3NldHRpbmdzL3Rva2Vuc1wiXG5cdFx0XHQpXG5cdFx0XHQuYWRkVGV4dCgodGV4dCkgPT5cblx0XHRcdFx0dGV4dFxuXHRcdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihcInNrXy4uLlwiKVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbilcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbiA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyB0ZXN0IGNvbm5lY3Rpb25cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKFwiVGVzdCBjb25uZWN0aW9uXCIpXG5cdFx0XHQuc2V0RGVzYyhcIlZlcmlmeSB5b3VyIEFQSSB0b2tlbiB3b3Jrc1wiKVxuXHRcdFx0LmFkZEJ1dHRvbigoYnRuKSA9PlxuXHRcdFx0XHRidG4uc2V0QnV0dG9uVGV4dChcIlRlc3RcIikub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0aWYgKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbikge1xuXHRcdFx0XHRcdFx0bmV3IE5vdGljZShcIk5vIEFQSSB0b2tlbiBjb25maWd1cmVkXCIpO1xuXHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRidG4uc2V0QnV0dG9uVGV4dChcIlRlc3RpbmcuLi5cIik7XG5cdFx0XHRcdFx0YnRuLnNldERpc2FibGVkKHRydWUpO1xuXHRcdFx0XHRcdGNvbnN0IGFwaSA9IG5ldyBTdWJsaW1hdGVkQXBpKFxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYXBpVG9rZW5cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFwaS50ZXN0Q29ubmVjdGlvbigpO1xuXHRcdFx0XHRcdGlmIChyZXN1bHQub2spIHtcblx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXG5cdFx0XHRcdFx0XHRcdGBDb25uZWN0ZWQgYXMgJHtyZXN1bHQudXNlcm5hbWV9YFxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0bmV3IE5vdGljZShcblx0XHRcdFx0XHRcdFx0YENvbm5lY3Rpb24gZmFpbGVkOiAke3Jlc3VsdC5lcnJvcn1gXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRidG4uc2V0QnV0dG9uVGV4dChcIlRlc3RcIik7XG5cdFx0XHRcdFx0YnRuLnNldERpc2FibGVkKGZhbHNlKTtcblx0XHRcdFx0fSlcblx0XHRcdCk7XG5cblx0XHQvLyBsaW5rc1xuXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiZGl2XCIsIHsgY2xzOiBcInNibC1zZXR0aW5ncy1saW5rc1wiIH0sIChlbCkgPT4ge1xuXHRcdFx0ZWwuY3JlYXRlRWwoXCJhXCIsIHtcblx0XHRcdFx0dGV4dDogXCJzdWJsaW1hdGVkLmNvbVwiLFxuXHRcdFx0XHRocmVmOiBcImh0dHBzOi8vc3VibGltYXRlZC5jb21cIixcblx0XHRcdH0pO1xuXHRcdFx0ZWwuY3JlYXRlRWwoXCJzcGFuXCIsIHsgdGV4dDogXCIgXHUwMEI3IFwiIH0pO1xuXHRcdFx0ZWwuY3JlYXRlRWwoXCJhXCIsIHtcblx0XHRcdFx0dGV4dDogXCJEb2N1bWVudGF0aW9uXCIsXG5cdFx0XHRcdGhyZWY6IFwiaHR0cHM6Ly9zdWJsaW1hdGVkLmNvbS9kb2NzL29ic2lkaWFuXCIsXG5cdFx0XHR9KTtcblx0XHRcdGVsLmNyZWF0ZUVsKFwic3BhblwiLCB7IHRleHQ6IFwiIFx1MDBCNyBcIiB9KTtcblx0XHRcdGVsLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHRcdHRleHQ6IFwiU291cmNlIGNvZGVcIixcblx0XHRcdFx0aHJlZjogXCJodHRwczovL3N1YmxpbWF0ZWQuY29tL3N1YmxpbWF0ZWQvY29kZS9vYnNpZGlhblwiLFxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cbn1cbiIsICJpbXBvcnQgeyByZXF1ZXN0VXJsIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmNvbnN0IEFQSV9CQVNFID0gXCJodHRwczovL2FwaS5zdWJsaW1hdGVkLmNvbVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZlcnNpb24ge1xuXHRpZDogc3RyaW5nO1xuXHRudW1iZXI6IG51bWJlcjtcblx0YXV0aG9yTmFtZTogc3RyaW5nO1xuXHRhdXRob3JUeXBlOiBzdHJpbmc7XG5cdG1lc3NhZ2U6IHN0cmluZyB8IG51bGw7XG5cdGNyZWF0ZWRBdDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgQXV0aFJlcXVpcmVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG5cdGNvbnN0cnVjdG9yKHB1YmxpYyBzdGF0dXM6IG51bWJlcikge1xuXHRcdHN1cGVyKGBhdXRoIHJlcXVpcmVkICgke3N0YXR1c30pYCk7XG5cdFx0dGhpcy5uYW1lID0gXCJBdXRoUmVxdWlyZWRFcnJvclwiO1xuXHR9XG59XG5cbi8vIFJhdyB3aXJlIGZvcm1hdCBmcm9tIGFwaS5zdWJsaW1hdGVkLmNvbVxuaW50ZXJmYWNlIFJhd0FjdG9yIHtcblx0dXNlcm5hbWU6IHN0cmluZyB8IG51bGw7XG5cdG5hbWU6IHN0cmluZyB8IG51bGw7XG5cdHJvbGU6IHN0cmluZztcblx0YWN0b3JfdHlwZTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUmF3VmVyc2lvbiB7XG5cdGlkOiBzdHJpbmc7XG5cdGl0ZW1faWQ6IHN0cmluZztcblx0dmVyc2lvbjogbnVtYmVyO1xuXHRjb250ZW50X2hhc2g6IHN0cmluZztcblx0YmxvYl9zaGExOiBzdHJpbmcgfCBudWxsO1xuXHRzaXplX2J5dGVzOiBudW1iZXI7XG5cdG1lc3NhZ2U6IHN0cmluZyB8IG51bGw7XG5cdG5hbWU6IHN0cmluZyB8IG51bGw7XG5cdGNyZWF0ZWRfYXQ6IHN0cmluZztcblx0YWN0b3JzOiBSYXdBY3RvcltdO1xufVxuXG5pbnRlcmZhY2UgQXBpRW52ZWxvcGU8VD4ge1xuXHRvazogYm9vbGVhbjtcblx0ZGF0YT86IFQ7XG5cdGVycm9yPzogeyB0eXBlOiBzdHJpbmc7IG1lc3NhZ2U/OiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0Q29ubmVjdGlvblJlc3VsdCB7XG5cdG9rOiBib29sZWFuO1xuXHR1c2VybmFtZT86IHN0cmluZztcblx0ZXJyb3I/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBTdWJsaW1hdGVkQXBpIHtcblx0Y29uc3RydWN0b3IocHJpdmF0ZSB0b2tlbjogc3RyaW5nKSB7fVxuXG5cdHByaXZhdGUgYXN5bmMgcmVxdWVzdDxUPihwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFQ+IHtcblx0XHRjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuXHRcdFx0QWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcblx0XHR9O1xuXHRcdGlmICh0aGlzLnRva2VuKSB7XG5cdFx0XHRoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7dGhpcy50b2tlbn1gO1xuXHRcdH1cblx0XHRjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmwoe1xuXHRcdFx0dXJsOiBgJHtBUElfQkFTRX0ke3BhdGh9YCxcblx0XHRcdGhlYWRlcnMsXG5cdFx0XHR0aHJvdzogZmFsc2UsXG5cdFx0fSk7XG5cblx0XHRpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDEgfHwgcmVzcG9uc2Uuc3RhdHVzID09PSA0MDMpIHtcblx0XHRcdHRocm93IG5ldyBBdXRoUmVxdWlyZWRFcnJvcihyZXNwb25zZS5zdGF0dXMpO1xuXHRcdH1cblx0XHRpZiAocmVzcG9uc2Uuc3RhdHVzID49IDQwMCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRgQVBJIGVycm9yICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS50ZXh0fWBcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgYm9keSA9IHJlc3BvbnNlLmpzb24gYXMgQXBpRW52ZWxvcGU8VD47XG5cdFx0aWYgKCFib2R5Lm9rIHx8IGJvZHkuZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRjb25zdCBtc2cgPSBib2R5LmVycm9yPy5tZXNzYWdlIHx8IGJvZHkuZXJyb3I/LnR5cGUgfHwgXCJ1bmtub3duIGVycm9yXCI7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYEFQSSBlcnJvcjogJHttc2d9YCk7XG5cdFx0fVxuXHRcdHJldHVybiBib2R5LmRhdGE7XG5cdH1cblxuXHRhc3luYyBnZXRWZXJzaW9ucyhcblx0XHRzcGFjZVNsdWc6IHN0cmluZyxcblx0XHRpdGVtSWQ6IHN0cmluZ1xuXHQpOiBQcm9taXNlPFZlcnNpb25bXT4ge1xuXHRcdGNvbnN0IHJhdyA9IGF3YWl0IHRoaXMucmVxdWVzdDxSYXdWZXJzaW9uW10+KFxuXHRcdFx0YC92MS9zcGFjZXMvJHtlbmNvZGVVUklDb21wb25lbnQoc3BhY2VTbHVnKX0vaXRlbXMvJHtlbmNvZGVVUklDb21wb25lbnQoaXRlbUlkKX0vdmVyc2lvbnNgXG5cdFx0KTtcblx0XHRyZXR1cm4gcmF3Lm1hcChtYXBWZXJzaW9uKS5yZXZlcnNlKCk7XG5cdH1cblxuXHRhc3luYyB0ZXN0Q29ubmVjdGlvbigpOiBQcm9taXNlPFRlc3RDb25uZWN0aW9uUmVzdWx0PiB7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnJlcXVlc3Q8eyB1c2VybmFtZTogc3RyaW5nIH0+KFxuXHRcdFx0XHRcIi92MS9tZVwiXG5cdFx0XHQpO1xuXHRcdFx0cmV0dXJuIHsgb2s6IHRydWUsIHVzZXJuYW1lOiBkYXRhLnVzZXJuYW1lIH07XG5cdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0b2s6IGZhbHNlLFxuXHRcdFx0XHRlcnJvcjogZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogXCJVbmtub3duIGVycm9yXCIsXG5cdFx0XHR9O1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBtYXBWZXJzaW9uKHI6IFJhd1ZlcnNpb24pOiBWZXJzaW9uIHtcblx0Ly8gcGljayB0aGUgYXV0aG9yIGFjdG9yOyBmYWxsIGJhY2sgdG8gdGhlIGZpcnN0IGFjdG9yIG9yIGEgcGxhY2Vob2xkZXJcblx0Y29uc3QgYXV0aG9yID1cblx0XHRyLmFjdG9ycy5maW5kKChhKSA9PiBhLnJvbGUgPT09IFwiYXV0aG9yXCIpID8/IHIuYWN0b3JzWzBdID8/IG51bGw7XG5cdHJldHVybiB7XG5cdFx0aWQ6IHIuaWQsXG5cdFx0bnVtYmVyOiByLnZlcnNpb24sXG5cdFx0YXV0aG9yTmFtZTogYXV0aG9yPy5uYW1lID8/IGF1dGhvcj8udXNlcm5hbWUgPz8gXCJ1bmtub3duXCIsXG5cdFx0YXV0aG9yVHlwZTogYXV0aG9yPy5hY3Rvcl90eXBlID8/IFwicGVyc29uXCIsXG5cdFx0bWVzc2FnZTogci5tZXNzYWdlLFxuXHRcdGNyZWF0ZWRBdDogci5jcmVhdGVkX2F0LFxuXHR9O1xufVxuIiwgImltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tIFwib2JzaWRpYW5cIjtcblxuY29uc3QgWEFUVFJfUFJFRklYID0gXCJjb20uc3VibGltYXRlZC5cIjtcbmNvbnN0IFhBVFRSX1NVRkZJWCA9IFwiI1BTXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZU1ldGFkYXRhIHtcblx0dmVyc2lvbjogc3RyaW5nIHwgbnVsbDtcblx0Y29tbWl0OiBzdHJpbmcgfCBudWxsO1xuXHR1cmw6IHN0cmluZyB8IG51bGw7XG5cdGNvbnRlbnRIYXNoOiBzdHJpbmcgfCBudWxsO1xuXHRpZDogc3RyaW5nIHwgbnVsbDtcblx0Y3JlYXRlZEJ5OiBzdHJpbmcgfCBudWxsO1xuXHRtb2RpZmllZEJ5OiBzdHJpbmcgfCBudWxsO1xuXHRtb2RpZmllZEJ5VHlwZTogc3RyaW5nIHwgbnVsbDtcblx0c3luY1N0YXR1czogc3RyaW5nIHwgbnVsbDtcblx0c3BhY2U6IHN0cmluZyB8IG51bGw7XG5cdGJyYW5jaDogc3RyaW5nIHwgbnVsbDtcblx0bW9kaWZpZWRBdDogc3RyaW5nIHwgbnVsbDtcblx0dmlzaWJpbGl0eTogc3RyaW5nIHwgbnVsbDtcbn1cblxuY29uc3QgQVRUUlM6IChrZXlvZiBGaWxlTWV0YWRhdGEpW10gPSBbXG5cdFwidmVyc2lvblwiLFxuXHRcImNvbW1pdFwiLFxuXHRcInVybFwiLFxuXHRcImNvbnRlbnRIYXNoXCIsXG5cdFwiaWRcIixcblx0XCJjcmVhdGVkQnlcIixcblx0XCJtb2RpZmllZEJ5XCIsXG5cdFwibW9kaWZpZWRCeVR5cGVcIixcblx0XCJzeW5jU3RhdHVzXCIsXG5cdFwic3BhY2VcIixcblx0XCJicmFuY2hcIixcblx0XCJtb2RpZmllZEF0XCIsXG5cdFwidmlzaWJpbGl0eVwiLFxuXTtcblxuZnVuY3Rpb24gYXR0clRvWGF0dHJOYW1lKGF0dHI6IHN0cmluZyk6IHN0cmluZyB7XG5cdC8vIGNhbWVsQ2FzZSBcdTIxOTIga2ViYWItY2FzZTogY29udGVudEhhc2ggXHUyMTkyIGNvbnRlbnQtaGFzaFxuXHRjb25zdCBrZWJhYiA9IGF0dHIucmVwbGFjZSgvW0EtWl0vZywgKGMpID0+IFwiLVwiICsgYy50b0xvd2VyQ2FzZSgpKTtcblx0cmV0dXJuIGAke1hBVFRSX1BSRUZJWH0ke2tlYmFifSR7WEFUVFJfU1VGRklYfWA7XG59XG5cbmZ1bmN0aW9uIHJlYWRYYXR0cihwYXRoOiBzdHJpbmcsIHhhdHRyTmFtZTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG5cdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuXHRcdGV4ZWMoXG5cdFx0XHRgeGF0dHIgLXAgJHtKU09OLnN0cmluZ2lmeSh4YXR0ck5hbWUpfSAke0pTT04uc3RyaW5naWZ5KHBhdGgpfWAsXG5cdFx0XHR7IHRpbWVvdXQ6IDIwMDAgfSxcblx0XHRcdChlcnIsIHN0ZG91dCkgPT4ge1xuXHRcdFx0XHRpZiAoZXJyKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZShudWxsKTtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0cmVzb2x2ZShzdGRvdXQudHJpbSgpIHx8IG51bGwpO1xuXHRcdFx0fVxuXHRcdCk7XG5cdH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZEZpbGVNZXRhZGF0YShcblx0cGF0aDogc3RyaW5nXG4pOiBQcm9taXNlPEZpbGVNZXRhZGF0YSB8IG51bGw+IHtcblx0aWYgKCFQbGF0Zm9ybS5pc01hY09TKSByZXR1cm4gbnVsbDtcblxuXHRjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG5cdFx0QVRUUlMubWFwKChhdHRyKSA9PiByZWFkWGF0dHIocGF0aCwgYXR0clRvWGF0dHJOYW1lKGF0dHIpKSlcblx0KTtcblxuXHQvLyBJZiBubyB4YXR0cnMgZm91bmQgYXQgYWxsLCB0aGlzIGlzbid0IGEgc3VibGltYXRlZCBmaWxlXG5cdGlmIChyZXN1bHRzLmV2ZXJ5KChyKSA9PiByID09PSBudWxsKSkgcmV0dXJuIG51bGw7XG5cblx0Y29uc3QgbWV0YTogRmlsZU1ldGFkYXRhID0ge1xuXHRcdHZlcnNpb246IG51bGwsIGNvbW1pdDogbnVsbCwgdXJsOiBudWxsLCBjb250ZW50SGFzaDogbnVsbCxcblx0XHRpZDogbnVsbCwgY3JlYXRlZEJ5OiBudWxsLCBtb2RpZmllZEJ5OiBudWxsLCBtb2RpZmllZEJ5VHlwZTogbnVsbCxcblx0XHRzeW5jU3RhdHVzOiBudWxsLCBzcGFjZTogbnVsbCwgYnJhbmNoOiBudWxsLCBtb2RpZmllZEF0OiBudWxsLCB2aXNpYmlsaXR5OiBudWxsLFxuXHR9O1xuXHRBVFRSUy5mb3JFYWNoKChhdHRyLCBpKSA9PiB7XG5cdFx0bWV0YVthdHRyXSA9IHJlc3VsdHNbaV07XG5cdH0pO1xuXHRyZXR1cm4gbWV0YTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWFjT1MoKTogYm9vbGVhbiB7XG5cdHJldHVybiBQbGF0Zm9ybS5pc01hY09TO1xufVxuIiwgImltcG9ydCB7IEl0ZW1WaWV3LCBOb3RpY2UsIFdvcmtzcGFjZUxlYWYgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB0eXBlIFN1YmxpbWF0ZWRQbHVnaW4gZnJvbSBcIi4vbWFpblwiO1xuaW1wb3J0IHsgU3VibGltYXRlZEFwaSwgQXV0aFJlcXVpcmVkRXJyb3IsIHR5cGUgVmVyc2lvbiB9IGZyb20gXCIuL2FwaVwiO1xuXG5leHBvcnQgY29uc3QgVkVSU0lPTl9WSUVXX1RZUEUgPSBcInN1YmxpbWF0ZWQtdmVyc2lvbnNcIjtcblxuZXhwb3J0IGNsYXNzIFZlcnNpb25WaWV3IGV4dGVuZHMgSXRlbVZpZXcge1xuXHRwbHVnaW46IFN1YmxpbWF0ZWRQbHVnaW47XG5cblx0Y29uc3RydWN0b3IobGVhZjogV29ya3NwYWNlTGVhZiwgcGx1Z2luOiBTdWJsaW1hdGVkUGx1Z2luKSB7XG5cdFx0c3VwZXIobGVhZik7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRnZXRWaWV3VHlwZSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiBWRVJTSU9OX1ZJRVdfVFlQRTtcblx0fVxuXG5cdGdldERpc3BsYXlUZXh0KCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIFwic3VibGltYXRlZCB2ZXJzaW9uc1wiO1xuXHR9XG5cblx0Z2V0SWNvbigpOiBzdHJpbmcge1xuXHRcdHJldHVybiBcImhpc3RvcnlcIjtcblx0fVxuXG5cdGFzeW5jIG9uT3BlbigpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRhd2FpdCB0aGlzLnJlZnJlc2goKTtcblx0XHQvLyByZWZyZXNoIHdoZW4gYWN0aXZlIGZpbGUgY2hhbmdlc1xuXHRcdHRoaXMucmVnaXN0ZXJFdmVudChcblx0XHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbihcImFjdGl2ZS1sZWFmLWNoYW5nZVwiLCAoKSA9PiB7XG5cdFx0XHRcdHRoaXMucmVmcmVzaCgpO1xuXHRcdFx0fSlcblx0XHQpO1xuXHR9XG5cblx0YXN5bmMgcmVmcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcblx0XHRjb250ZW50RWwuYWRkQ2xhc3MoXCJzYmwtdmVyc2lvbi12aWV3XCIpO1xuXG5cdFx0Y29uc3QgYWN0aXZlRmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XG5cdFx0aWYgKCFhY3RpdmVGaWxlKSB7XG5cdFx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdFx0dGV4dDogXCJObyBmaWxlIG9wZW4uXCIsXG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1lbXB0eVwiLFxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gcmVhZCB4YXR0cnMgdG8gZ2V0IHNwYWNlICsgaXRlbSBJRFxuXHRcdGNvbnN0IG1ldGEgPSB0aGlzLnBsdWdpbi5sYXN0TWV0YWRhdGE7XG5cdFx0aWYgKCFtZXRhPy5zcGFjZSB8fCAhbWV0YT8uaWQpIHtcblx0XHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0XHR0ZXh0OiBcIk5vdCBhIHN1YmxpbWF0ZWQgZmlsZS5cIixcblx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWVtcHR5XCIsXG5cdFx0XHR9KTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJoNFwiLCB7XG5cdFx0XHR0ZXh0OiBhY3RpdmVGaWxlLm5hbWUsXG5cdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tZmlsZW5hbWVcIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IGxvYWRpbmcgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdHRleHQ6IFwiTG9hZGluZyB2ZXJzaW9ucy4uLlwiLFxuXHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWxvYWRpbmdcIixcblx0XHR9KTtcblxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBhcGkgPSBuZXcgU3VibGltYXRlZEFwaSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hcGlUb2tlbik7XG5cdFx0XHRjb25zdCB2ZXJzaW9ucyA9IGF3YWl0IGFwaS5nZXRWZXJzaW9ucyhtZXRhLnNwYWNlLCBtZXRhLmlkKTtcblx0XHRcdGxvYWRpbmcucmVtb3ZlKCk7XG5cblx0XHRcdGlmICh2ZXJzaW9ucy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG5cdFx0XHRcdFx0dGV4dDogXCJObyB2ZXJzaW9ucyBmb3VuZC5cIixcblx0XHRcdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tZW1wdHlcIixcblx0XHRcdFx0fSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgbGlzdCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiLCB7XG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1saXN0XCIsXG5cdFx0XHR9KTtcblx0XHRcdGNvbnN0IGdyb3VwcyA9IGdyb3VwQnlEYXkodmVyc2lvbnMpO1xuXHRcdFx0Zm9yIChjb25zdCBncm91cCBvZiBncm91cHMpIHtcblx0XHRcdFx0bGlzdC5jcmVhdGVFbChcImRpdlwiLCB7XG5cdFx0XHRcdFx0dGV4dDogZ3JvdXAubGFiZWwsXG5cdFx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWRheVwiLFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0Zm9yIChjb25zdCB2IG9mIGdyb3VwLnZlcnNpb25zKSB7XG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJWZXJzaW9uKGxpc3QsIHYsIG1ldGEudXJsKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdGxvYWRpbmcucmVtb3ZlKCk7XG5cdFx0XHRpZiAoZSBpbnN0YW5jZW9mIEF1dGhSZXF1aXJlZEVycm9yKSB7XG5cdFx0XHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0XHRcdHRleHQ6IFwiVGhpcyBmaWxlIGlzIHByaXZhdGUgXHUyMDE0IGFkZCBhbiBBUEkgdG9rZW4gdG8gdmlldyB2ZXJzaW9uIGhpc3RvcnkuXCIsXG5cdFx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLWVtcHR5XCIsXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdFx0XHR0ZXh0OiBcIkNvbmZpZ3VyZSBpbiBTZXR0aW5ncyBcdTIxOTIgc3VibGltYXRlZFwiLFxuXHRcdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1oaW50XCIsXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdFx0dGV4dDogYEVycm9yOiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93blwifWAsXG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1lcnJvclwiLFxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSByZW5kZXJWZXJzaW9uKFxuXHRcdGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsXG5cdFx0djogVmVyc2lvbixcblx0XHRmaWxlVXJsOiBzdHJpbmcgfCBudWxsXG5cdCk6IHZvaWQge1xuXHRcdGNvbnN0IGl0ZW0gPSBjb250YWluZXIuY3JlYXRlRGl2KHsgY2xzOiBcInNibC12ZXJzaW9uLWl0ZW1cIiB9KTtcblxuXHRcdGNvbnN0IGhlYWRlciA9IGl0ZW0uY3JlYXRlRGl2KHsgY2xzOiBcInNibC12ZXJzaW9uLWhlYWRlclwiIH0pO1xuXHRcdGhlYWRlci5jcmVhdGVFbChcInNwYW5cIiwge1xuXHRcdFx0dGV4dDogYHYke3YubnVtYmVyfWAsXG5cdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tbnVtYmVyXCIsXG5cdFx0fSk7XG5cdFx0aGVhZGVyLmNyZWF0ZUVsKFwic3BhblwiLCB7XG5cdFx0XHR0ZXh0OiB2LmF1dGhvck5hbWUsXG5cdFx0XHRjbHM6IFwic2JsLXZlcnNpb24tYXV0aG9yXCIsXG5cdFx0fSk7XG5cblx0XHRjb25zdCB0aW1lID0gaXRlbS5jcmVhdGVEaXYoeyBjbHM6IFwic2JsLXZlcnNpb24tdGltZVwiIH0pO1xuXHRcdHRpbWUuY3JlYXRlRWwoXCJzcGFuXCIsIHtcblx0XHRcdHRleHQ6IGZvcm1hdFJlbGF0aXZlVGltZSh2LmNyZWF0ZWRBdCksXG5cdFx0XHRhdHRyOiB7IHRpdGxlOiBuZXcgRGF0ZSh2LmNyZWF0ZWRBdCkudG9Mb2NhbGVTdHJpbmcoKSB9LFxuXHRcdH0pO1xuXG5cdFx0aWYgKHYubWVzc2FnZSkge1xuXHRcdFx0aXRlbS5jcmVhdGVEaXYoe1xuXHRcdFx0XHR0ZXh0OiB2Lm1lc3NhZ2UsXG5cdFx0XHRcdGNsczogXCJzYmwtdmVyc2lvbi1tZXNzYWdlXCIsXG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRpZiAoZmlsZVVybCkge1xuXHRcdFx0Y29uc3Qgd2ViVXJsID0gYGh0dHBzOi8vJHtmaWxlVXJsfS9+dmVyc2lvbnMvdiR7di5udW1iZXJ9YDtcblx0XHRcdGNvbnN0IGxpbmsgPSBpdGVtLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHRcdHRleHQ6IFwidmlldyBvbiB3ZWJcIixcblx0XHRcdFx0Y2xzOiBcInNibC12ZXJzaW9uLXdlYi1saW5rXCIsXG5cdFx0XHRcdGhyZWY6IHdlYlVybCxcblx0XHRcdH0pO1xuXHRcdFx0bGluay5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKGUpID0+IHtcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR3aW5kb3cub3Blbih3ZWJVcmwpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgb25DbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBjbGVhbnVwIGhhbmRsZWQgYnkgb2JzaWRpYW5cblx0fVxufVxuXG5pbnRlcmZhY2UgRGF5R3JvdXAge1xuXHRsYWJlbDogc3RyaW5nO1xuXHR2ZXJzaW9uczogVmVyc2lvbltdO1xufVxuXG5mdW5jdGlvbiBncm91cEJ5RGF5KHZlcnNpb25zOiBWZXJzaW9uW10pOiBEYXlHcm91cFtdIHtcblx0Y29uc3QgZ3JvdXBzID0gbmV3IE1hcDxzdHJpbmcsIFZlcnNpb25bXT4oKTtcblx0Y29uc3Qgb3JkZXI6IHN0cmluZ1tdID0gW107XG5cblx0Zm9yIChjb25zdCB2IG9mIHZlcnNpb25zKSB7XG5cdFx0Y29uc3QgbGFiZWwgPSBmb3JtYXREYXlMYWJlbCh2LmNyZWF0ZWRBdCk7XG5cdFx0aWYgKCFncm91cHMuaGFzKGxhYmVsKSkge1xuXHRcdFx0Z3JvdXBzLnNldChsYWJlbCwgW10pO1xuXHRcdFx0b3JkZXIucHVzaChsYWJlbCk7XG5cdFx0fVxuXHRcdGdyb3Vwcy5nZXQobGFiZWwpIS5wdXNoKHYpO1xuXHR9XG5cblx0cmV0dXJuIG9yZGVyLm1hcCgobGFiZWwpID0+ICh7XG5cdFx0bGFiZWwsXG5cdFx0dmVyc2lvbnM6IGdyb3Vwcy5nZXQobGFiZWwpISxcblx0fSkpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXREYXlMYWJlbChpc286IHN0cmluZyk6IHN0cmluZyB7XG5cdGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cdGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShpc28pO1xuXG5cdGNvbnN0IG5vd0RheSA9IG5ldyBEYXRlKG5vdy5nZXRGdWxsWWVhcigpLCBub3cuZ2V0TW9udGgoKSwgbm93LmdldERhdGUoKSk7XG5cdGNvbnN0IHRoZW5EYXkgPSBuZXcgRGF0ZShcblx0XHRkYXRlLmdldEZ1bGxZZWFyKCksXG5cdFx0ZGF0ZS5nZXRNb250aCgpLFxuXHRcdGRhdGUuZ2V0RGF0ZSgpXG5cdCk7XG5cdGNvbnN0IGRheXMgPSBNYXRoLnJvdW5kKFxuXHRcdChub3dEYXkuZ2V0VGltZSgpIC0gdGhlbkRheS5nZXRUaW1lKCkpIC8gKDEwMDAgKiA2MCAqIDYwICogMjQpXG5cdCk7XG5cblx0aWYgKGRheXMgPT09IDApIHJldHVybiBcIlRvZGF5XCI7XG5cdGlmIChkYXlzID09PSAxKSByZXR1cm4gXCJZZXN0ZXJkYXlcIjtcblx0aWYgKGRheXMgPCA3KSByZXR1cm4gYCR7ZGF5c30gZGF5cyBhZ29gO1xuXHRyZXR1cm4gZGF0ZS50b0xvY2FsZURhdGVTdHJpbmcoXCJlbi1VU1wiLCB7XG5cdFx0bW9udGg6IFwic2hvcnRcIixcblx0XHRkYXk6IFwibnVtZXJpY1wiLFxuXHR9KTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UmVsYXRpdmVUaW1lKGlzbzogc3RyaW5nKTogc3RyaW5nIHtcblx0Y29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcblx0Y29uc3QgdGhlbiA9IG5ldyBEYXRlKGlzbykuZ2V0VGltZSgpO1xuXHRjb25zdCBkaWZmID0gbm93IC0gdGhlbjtcblx0Y29uc3Qgc2Vjb25kcyA9IE1hdGguZmxvb3IoZGlmZiAvIDEwMDApO1xuXHRjb25zdCBtaW51dGVzID0gTWF0aC5mbG9vcihzZWNvbmRzIC8gNjApO1xuXHRjb25zdCBob3VycyA9IE1hdGguZmxvb3IobWludXRlcyAvIDYwKTtcblx0Y29uc3QgZGF5cyA9IE1hdGguZmxvb3IoaG91cnMgLyAyNCk7XG5cblx0aWYgKGRheXMgPiAzMCkgcmV0dXJuIG5ldyBEYXRlKGlzbykudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG5cdGlmIChkYXlzID4gMCkgcmV0dXJuIGAke2RheXN9ZCBhZ29gO1xuXHRpZiAoaG91cnMgPiAwKSByZXR1cm4gYCR7aG91cnN9aCBhZ29gO1xuXHRpZiAobWludXRlcyA+IDApIHJldHVybiBgJHttaW51dGVzfW0gYWdvYDtcblx0cmV0dXJuIFwianVzdCBub3dcIjtcbn1cbiIsICJpbXBvcnQgeyBBcHAsIE1vZGFsIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5cbmV4cG9ydCBjbGFzcyBXZWxjb21lTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwKSB7XG5cdFx0c3VwZXIoYXBwKTtcblx0fVxuXG5cdG9uT3BlbigpOiB2b2lkIHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblx0XHRjb250ZW50RWwuYWRkQ2xhc3MoXCJzYmwtd2VsY29tZS1tb2RhbFwiKTtcblxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJXZWxjb21lIHRvIHN1YmxpbWF0ZWRcIiB9KTtcblxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0dGV4dDogXCJzdWJsaW1hdGVkIHN5bmNzIHlvdXIgZmlsZXMgd2l0aCB2ZXJzaW9uIGhpc3RvcnksIGNvbGxhYm9yYXRpb24sIGFuZCBhIHdlYiB2aWV3ZXIgXHUyMDE0IGFsbCBwb3dlcmVkIGJ5IGdpdCB1bmRlciB0aGUgaG9vZC5cIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IHN0ZXBzID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHsgY2xzOiBcInNibC13ZWxjb21lLXN0ZXBzXCIgfSk7XG5cblx0XHRjb25zdCBzdGVwMSA9IHN0ZXBzLmNyZWF0ZURpdih7IGNsczogXCJzYmwtd2VsY29tZS1zdGVwXCIgfSk7XG5cdFx0c3RlcDEuY3JlYXRlRWwoXCJzdHJvbmdcIiwgeyB0ZXh0OiBcIjEuIE9wZW4gYSBzdWJsaW1hdGVkIGZvbGRlciBhcyBhIHZhdWx0XCIgfSk7XG5cdFx0c3RlcDEuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdHRleHQ6IFwiSW4gRmluZGVyLCBvcGVuIGFueSBzdWJsaW1hdGVkIGZvbGRlciAob3Igc3ViZm9sZGVyKSB1bmRlciBDbG91ZFN0b3JhZ2UgYXMgYW4gT2JzaWRpYW4gdmF1bHQuIFRoZSBwbHVnaW4gYWN0aXZhdGVzIGF1dG9tYXRpY2FsbHkgb24gc3luY2VkIGZpbGVzLlwiLFxuXHRcdH0pO1xuXG5cdFx0Y29uc3Qgc3RlcDIgPSBzdGVwcy5jcmVhdGVEaXYoeyBjbHM6IFwic2JsLXdlbGNvbWUtc3RlcFwiIH0pO1xuXHRcdHN0ZXAyLmNyZWF0ZUVsKFwic3Ryb25nXCIsIHsgdGV4dDogXCIyLiBTdGF0dXMgYmFyIHNob3dzIHN5bmMgaW5mb1wiIH0pO1xuXHRcdHN0ZXAyLmNyZWF0ZUVsKFwicFwiLCB7XG5cdFx0XHR0ZXh0OiBcIlRoZSBib3R0b20gYmFyIHNob3dzIHZlcnNpb24gbnVtYmVyLCBzeW5jIHN0YXR1cywgYW5kIGF1dGhvciBmb3IgdGhlIGN1cnJlbnQgZmlsZSBcdTIwMTQgYWxsIHJlYWQgZnJvbSBsb2NhbCBmaWxlIG1ldGFkYXRhLCBubyBhY2NvdW50IG5lZWRlZC5cIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IHN0ZXAzID0gc3RlcHMuY3JlYXRlRGl2KHsgY2xzOiBcInNibC13ZWxjb21lLXN0ZXBcIiB9KTtcblx0XHRzdGVwMy5jcmVhdGVFbChcInN0cm9uZ1wiLCB7IHRleHQ6IFwiMy4gQWRkIGFuIEFQSSB0b2tlbiBmb3IgdmVyc2lvbiBoaXN0b3J5XCIgfSk7XG5cdFx0c3RlcDMuY3JlYXRlRWwoXCJwXCIsIHtcblx0XHRcdHRleHQ6IFwiVG8gYnJvd3NlIHBhc3QgdmVyc2lvbnMsIGFkZCB5b3VyIEFQSSB0b2tlbiBpbiBTZXR0aW5ncyBcdTIxOTIgc3VibGltYXRlZC4gR2VuZXJhdGUgb25lIGF0IHN1YmxpbWF0ZWQuY29tL3NldHRpbmdzL3Rva2Vucy5cIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IGxpbmtzID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogXCJzYmwtd2VsY29tZS1saW5rc1wiIH0pO1xuXHRcdGxpbmtzLmNyZWF0ZUVsKFwiYVwiLCB7XG5cdFx0XHR0ZXh0OiBcIkRvY3VtZW50YXRpb25cIixcblx0XHRcdGhyZWY6IFwiaHR0cHM6Ly9zdWJsaW1hdGVkLmNvbS9kb2NzL29ic2lkaWFuXCIsXG5cdFx0fSk7XG5cdFx0bGlua3MuY3JlYXRlRWwoXCJiclwiKTtcblx0XHRsaW5rcy5jcmVhdGVFbChcImFcIiwge1xuXHRcdFx0dGV4dDogXCJTb3VyY2UgY29kZVwiLFxuXHRcdFx0aHJlZjogXCJodHRwczovL3N1YmxpbWF0ZWQuY29tL3N1YmxpbWF0ZWQvY29kZS9vYnNpZGlhblwiLFxuXHRcdH0pO1xuXG5cdFx0Y29uc3QgZm9vdGVyID0gY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogXCJzYmwtd2VsY29tZS1mb290ZXJcIiB9KTtcblx0XHRmb290ZXIuY3JlYXRlRWwoXCJidXR0b25cIiwge1xuXHRcdFx0dGV4dDogXCJHZXQgc3RhcnRlZFwiLFxuXHRcdFx0Y2xzOiBcIm1vZC1jdGFcIixcblx0XHR9KS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgKCkgPT4gdGhpcy5jbG9zZSgpKTtcblx0fVxuXG5cdG9uQ2xvc2UoKTogdm9pZCB7XG5cdFx0dGhpcy5jb250ZW50RWwuZW1wdHkoKTtcblx0fVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7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LFVBQVUsV0FBVyxTQUFTLENBQUMsQ0FBQztBQUN6QztBQUFBLElBQ0Q7QUFFQSxVQUFNLE9BQU8sS0FBSyxJQUFJLFVBQVUsYUFBYSxLQUFLO0FBQ2xELFFBQUksQ0FBQyxLQUFNO0FBQ1gsVUFBTSxLQUFLLGFBQWE7QUFBQSxNQUN2QixNQUFNO0FBQUEsTUFDTixRQUFRO0FBQUEsSUFDVCxDQUFDO0FBQ0QsU0FBSyxJQUFJLFVBQVUsV0FBVyxJQUFJO0FBQUEsRUFDbkM7QUFBQSxFQUVRLFVBQVUsUUFBc0M7QUFDdkQsVUFBTSxFQUFFLFFBQVEsS0FBSyxJQUFJO0FBRXpCLFFBQUksV0FBVyxVQUFVLE1BQU07QUFDOUIsWUFBTSxpQkFBYSxnQ0FBYyxJQUFJO0FBQ3JDLFlBQU0sV0FBVyxLQUFLLElBQUksTUFBTSxzQkFBc0IsVUFBVTtBQUNoRSxVQUFJLFVBQVU7QUFDYixhQUFLLElBQUksVUFBVSxhQUFhLFlBQVksSUFBSSxLQUFLO0FBQUEsTUFDdEQsT0FBTztBQUNOLFlBQUksd0JBQU8sbUJBQW1CLElBQUksRUFBRTtBQUFBLE1BQ3JDO0FBQ0E7QUFBQSxJQUNEO0FBRUEsUUFBSSxXQUFXLFVBQVUsT0FBTyxPQUFPO0FBRXRDLFdBQUssU0FBUyxXQUFXLE9BQU87QUFDaEMsV0FBSyxhQUFhO0FBQ2xCLFVBQUksd0JBQU8sb0NBQW9DO0FBQy9DO0FBQUEsSUFDRDtBQUVBLFFBQUksd0JBQU8sOEJBQThCLE1BQU0sRUFBRTtBQUFBLEVBQ2xEO0FBQ0Q7QUFFQSxTQUFTLGVBQWUsUUFBd0I7QUFDL0MsVUFBUSxRQUFRO0FBQUEsSUFDZixLQUFLO0FBQ0osYUFBTztBQUFBLElBQ1IsS0FBSztBQUNKLGFBQU87QUFBQSxJQUNSLEtBQUs7QUFDSixhQUFPO0FBQUEsSUFDUixLQUFLO0FBQ0osYUFBTztBQUFBLElBQ1IsS0FBSztBQUNKLGFBQU87QUFBQSxJQUNSO0FBQ0MsYUFBTztBQUFBLEVBQ1Q7QUFDRDtBQUVBLFNBQVMsZUFBZSxZQUE0QjtBQUNuRCxVQUFRLFlBQVk7QUFBQSxJQUNuQixLQUFLO0FBQ0osYUFBTztBQUFBLElBQ1IsS0FBSztBQUNKLGFBQU87QUFBQSxJQUNSLEtBQUs7QUFDSixhQUFPO0FBQUEsSUFDUjtBQUNDLGFBQU87QUFBQSxFQUNUO0FBQ0Q7IiwKICAibmFtZXMiOiBbImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iLCAiaW1wb3J0X29ic2lkaWFuIiwgImltcG9ydF9vYnNpZGlhbiIsICJpbXBvcnRfb2JzaWRpYW4iXQp9Cg==