diff --git a/.gitignore b/.gitignore
index 3c3629e..cabc9a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
node_modules
+main.js
+data.json
+package-lock.json
diff --git a/data.json b/data.json
deleted file mode 100644
index 9ba6454..0000000
--- a/data.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "micropubEndpoint": "https://blog.giersig.eu/micropub",
- "mediaEndpoint": "https://blog.giersig.eu/media",
- "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZSI6Imh0dHBzOi8vYmxvZy5naWVyc2lnLmV1Iiwic2NvcGUiOiJjcmVhdGUgdXBkYXRlIG1lZGlhIiwiaWF0IjoxNzczNTA1OTI2LCJleHAiOjE3ODEyODE5MjZ9.AaxtwgiQYbU7iWQt9GCResGK-DVfa0r7q2CHr_ibdFM",
- "defaultSyndicateTo": [],
- "autoDiscover": false,
- "siteUrl": "https://blog.giersig.eu",
- "authorizationEndpoint": "https://blog.giersig.eu/auth",
- "tokenEndpoint": "https://blog.giersig.eu/auth/token",
- "me": "https://blog.giersig.eu",
- "writeUrlToFrontmatter": true,
- "mapGardenTags": true,
- "defaultVisibility": "public"
-}
\ No newline at end of file
diff --git a/main.js b/main.js
deleted file mode 100644
index d66563d..0000000
--- a/main.js
+++ /dev/null
@@ -1,908 +0,0 @@
-/*
-THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
-if you want to view the source, please visit the github repository of this plugin
-*/
-
-"use strict";
-var __create = Object.create;
-var __defProp = Object.defineProperty;
-var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-var __getOwnPropNames = Object.getOwnPropertyNames;
-var __getProtoOf = Object.getPrototypeOf;
-var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __export = (target, all) => {
- for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
-};
-var __copyProps = (to, from, except, desc) => {
- if (from && typeof from === "object" || typeof from === "function") {
- for (let key of __getOwnPropNames(from))
- if (!__hasOwnProp.call(to, key) && key !== except)
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
- }
- return to;
-};
-var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
- // If the importer is in node compatibility mode or this is not an ESM
- // file that has been converted to a CommonJS file using a Babel-
- // compatible transform (i.e. "__esModule" has not been set), then set
- // "default" to the CommonJS "module.exports" for node compatibility.
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
- mod
-));
-var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
-
-// src/main.ts
-var main_exports = {};
-__export(main_exports, {
- default: () => MicropubPlugin
-});
-module.exports = __toCommonJS(main_exports);
-var import_obsidian5 = require("obsidian");
-
-// src/types.ts
-var DEFAULT_SETTINGS = {
- micropubEndpoint: "",
- mediaEndpoint: "",
- accessToken: "",
- defaultSyndicateTo: [],
- autoDiscover: false,
- siteUrl: "",
- authorizationEndpoint: "",
- tokenEndpoint: "",
- me: "",
- writeUrlToFrontmatter: true,
- mapGardenTags: true,
- defaultVisibility: "public"
-};
-
-// src/SettingsTab.ts
-var import_obsidian3 = require("obsidian");
-
-// src/MicropubClient.ts
-var import_obsidian = require("obsidian");
-var MicropubClient = class {
- constructor(getEndpoint, getMediaEndpoint, getToken) {
- this.getEndpoint = getEndpoint;
- this.getMediaEndpoint = getMediaEndpoint;
- this.getToken = getToken;
- }
- // ── Config discovery ─────────────────────────────────────────────────────
- /** Fetch Micropub server config (syndication targets, media endpoint, etc.) */
- async fetchConfig() {
- const url = `${this.getEndpoint()}?q=config`;
- const resp = await (0, import_obsidian.requestUrl)({
- url,
- method: "GET",
- headers: this.authHeaders()
- });
- return resp.json;
- }
- /**
- * Discover micropub + token endpoint URLs from a site's home page
- * by reading and tags.
- */
- async discoverEndpoints(siteUrl) {
- const resp = await (0, import_obsidian.requestUrl)({ url: siteUrl, method: "GET" });
- const html = resp.text;
- const micropub = this.extractLinkRel(html, "micropub");
- const tokenEndpoint = this.extractLinkRel(html, "token_endpoint");
- let mediaEndpoint;
- if (micropub) {
- try {
- const cfg = await this.fetchConfigFrom(micropub);
- mediaEndpoint = cfg["media-endpoint"];
- } catch (e) {
- }
- }
- return { micropubEndpoint: micropub, tokenEndpoint, mediaEndpoint };
- }
- // ── Post publishing ──────────────────────────────────────────────────────
- /**
- * Create a new post via Micropub.
- * Sends a JSON body with h-entry properties.
- * Returns the Location header URL on success.
- */
- async createPost(properties) {
- var _a, _b, _c;
- const body = {
- type: ["h-entry"],
- properties
- };
- try {
- const resp = await (0, import_obsidian.requestUrl)({
- url: this.getEndpoint(),
- method: "POST",
- headers: {
- ...this.authHeaders(),
- "Content-Type": "application/json"
- },
- body: JSON.stringify(body),
- throw: false
- });
- if (resp.status === 201 || resp.status === 202) {
- const location = ((_a = resp.headers) == null ? void 0 : _a["location"]) || ((_b = resp.headers) == null ? void 0 : _b["Location"]) || ((_c = resp.json) == null ? void 0 : _c.url);
- return { success: true, url: location };
- }
- const detail = this.extractError(resp.text);
- return { success: false, error: `HTTP ${resp.status}: ${detail}` };
- } catch (err) {
- return { success: false, error: String(err) };
- }
- }
- /**
- * Update an existing post.
- * @param postUrl The canonical URL of the post to update
- * @param replace Properties to replace (will overwrite existing values)
- */
- async updatePost(postUrl, replace) {
- const body = { action: "update", url: postUrl, replace };
- try {
- const resp = await (0, import_obsidian.requestUrl)({
- url: this.getEndpoint(),
- method: "POST",
- headers: {
- ...this.authHeaders(),
- "Content-Type": "application/json"
- },
- body: JSON.stringify(body),
- throw: false
- });
- if (resp.status >= 200 && resp.status < 300) {
- return { success: true, url: postUrl };
- }
- return {
- success: false,
- error: `HTTP ${resp.status}: ${this.extractError(resp.text)}`
- };
- } catch (err) {
- return { success: false, error: String(err) };
- }
- }
- // ── Media upload ─────────────────────────────────────────────────────────
- /**
- * Upload a binary file to the media endpoint.
- * @returns The URL of the uploaded media, or throws on failure.
- */
- async uploadMedia(fileBuffer, fileName, mimeType) {
- var _a, _b, _c;
- const endpoint = this.getMediaEndpoint() || `${this.getEndpoint()}/media`;
- const boundary = `----MicropubBoundary${Date.now()}`;
- const header = `--${boundary}\r
-Content-Disposition: form-data; name="file"; filename="${fileName}"\r
-Content-Type: ${mimeType}\r
-\r
-`;
- const footer = `\r
---${boundary}--\r
-`;
- const headerBuf = new TextEncoder().encode(header);
- const footerBuf = new TextEncoder().encode(footer);
- const fileBuf = new Uint8Array(fileBuffer);
- const combined = new Uint8Array(
- headerBuf.length + fileBuf.length + footerBuf.length
- );
- combined.set(headerBuf, 0);
- combined.set(fileBuf, headerBuf.length);
- combined.set(footerBuf, headerBuf.length + fileBuf.length);
- const resp = await (0, import_obsidian.requestUrl)({
- url: endpoint,
- method: "POST",
- headers: {
- ...this.authHeaders(),
- "Content-Type": `multipart/form-data; boundary=${boundary}`
- },
- body: combined.buffer,
- throw: false
- });
- if (resp.status === 201 || resp.status === 202) {
- const location = ((_a = resp.headers) == null ? void 0 : _a["location"]) || ((_b = resp.headers) == null ? void 0 : _b["Location"]) || ((_c = resp.json) == null ? void 0 : _c.url);
- if (location) return location;
- }
- throw new Error(
- `Media upload failed (HTTP ${resp.status}): ${this.extractError(resp.text)}`
- );
- }
- // ── Helpers ──────────────────────────────────────────────────────────────
- authHeaders() {
- return { Authorization: `Bearer ${this.getToken()}` };
- }
- extractLinkRel(html, rel) {
- var _a;
- const re = new RegExp(
- `]+rel=["']${rel}["'][^>]+href=["']([^"']+)["']|]+href=["']([^"']+)["'][^>]+rel=["']${rel}["']`,
- "i"
- );
- const m = html.match(re);
- return (_a = m == null ? void 0 : m[1]) != null ? _a : m == null ? void 0 : m[2];
- }
- async fetchConfigFrom(endpoint) {
- const resp = await (0, import_obsidian.requestUrl)({
- url: `${endpoint}?q=config`,
- method: "GET",
- headers: this.authHeaders()
- });
- return resp.json;
- }
- extractError(text) {
- var _a, _b;
- try {
- const obj = JSON.parse(text);
- return (_b = (_a = obj.error_description) != null ? _a : obj.error) != null ? _b : text.slice(0, 200);
- } catch (e) {
- return text.slice(0, 200);
- }
- }
-};
-
-// src/IndieAuth.ts
-var crypto = __toESM(require("crypto"));
-var import_obsidian2 = require("obsidian");
-var CLIENT_ID = "https://svemagie.github.io/obsidian-micropub/";
-var REDIRECT_URI = "https://svemagie.github.io/obsidian-micropub/callback";
-var SCOPE = "create update media";
-var AUTH_TIMEOUT_MS = 5 * 60 * 1e3;
-var pendingCallback = null;
-function handleProtocolCallback(params) {
- if (!pendingCallback) return;
- const { resolve, state: expectedState } = pendingCallback;
- pendingCallback = null;
- resolve(params);
-}
-var IndieAuth = class _IndieAuth {
- // ── Public API ────────────────────────────────────────────────────────────
- /**
- * Discover IndieAuth + Micropub endpoint URLs from the site's home page
- * by reading tags in the HTML
.
- */
- static async discoverEndpoints(siteUrl) {
- const resp = await (0, import_obsidian2.requestUrl)({ url: siteUrl, method: "GET" });
- const html = resp.text;
- const authorizationEndpoint = _IndieAuth.extractLinkRel(html, "authorization_endpoint");
- const tokenEndpoint = _IndieAuth.extractLinkRel(html, "token_endpoint");
- const micropubEndpoint = _IndieAuth.extractLinkRel(html, "micropub");
- if (!authorizationEndpoint) {
- throw new Error(
- `No found at ${siteUrl}. Make sure Indiekit is running and SITE_URL is set correctly.`
- );
- }
- if (!tokenEndpoint) {
- throw new Error(`No found at ${siteUrl}.`);
- }
- return { authorizationEndpoint, tokenEndpoint, micropubEndpoint };
- }
- /**
- * Run the full IndieAuth PKCE sign-in flow.
- *
- * Opens the browser at the user's IndieAuth login page. After login the
- * browser is redirected to the GitHub Pages callback, which triggers
- * the obsidian://micropub-auth protocol, which resolves the Promise here.
- *
- * Requires handleProtocolCallback() to be wired up in main.ts via
- * this.registerObsidianProtocolHandler("micropub-auth", handleProtocolCallback)
- */
- static async signIn(siteUrl) {
- var _a, _b, _c, _d, _e, _f;
- const { authorizationEndpoint, tokenEndpoint, micropubEndpoint } = await _IndieAuth.discoverEndpoints(siteUrl);
- const state = _IndieAuth.base64url(crypto.randomBytes(16));
- const codeVerifier = _IndieAuth.base64url(crypto.randomBytes(64));
- const codeChallenge = _IndieAuth.base64url(
- crypto.createHash("sha256").update(codeVerifier).digest()
- );
- const callbackPromise = new Promise(
- (resolve, reject) => {
- const timeout = setTimeout(() => {
- pendingCallback = null;
- reject(new Error("Sign-in timed out (5 min). Please try again."));
- }, AUTH_TIMEOUT_MS);
- pendingCallback = {
- state,
- resolve: (params) => {
- clearTimeout(timeout);
- resolve(params);
- }
- };
- }
- );
- const authUrl = new URL(authorizationEndpoint);
- authUrl.searchParams.set("response_type", "code");
- authUrl.searchParams.set("client_id", CLIENT_ID);
- authUrl.searchParams.set("redirect_uri", REDIRECT_URI);
- authUrl.searchParams.set("state", state);
- authUrl.searchParams.set("code_challenge", codeChallenge);
- authUrl.searchParams.set("code_challenge_method", "S256");
- authUrl.searchParams.set("scope", SCOPE);
- authUrl.searchParams.set("me", siteUrl);
- window.open(authUrl.toString());
- const callbackParams = await callbackPromise;
- if (callbackParams.state !== state) {
- throw new Error("State mismatch \u2014 possible CSRF attack. Please try again.");
- }
- const code = callbackParams.code;
- if (!code) {
- throw new Error(
- (_b = (_a = callbackParams.error_description) != null ? _a : callbackParams.error) != null ? _b : "No authorization code received."
- );
- }
- const tokenResp = await (0, import_obsidian2.requestUrl)({
- url: tokenEndpoint,
- method: "POST",
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- Accept: "application/json"
- },
- body: new URLSearchParams({
- grant_type: "authorization_code",
- code,
- client_id: CLIENT_ID,
- redirect_uri: REDIRECT_URI,
- code_verifier: codeVerifier
- }).toString(),
- throw: false
- });
- const data = tokenResp.json;
- if (!data.access_token) {
- throw new Error(
- (_d = (_c = data.error_description) != null ? _c : data.error) != null ? _d : `Token exchange failed (HTTP ${tokenResp.status})`
- );
- }
- return {
- accessToken: data.access_token,
- scope: (_e = data.scope) != null ? _e : SCOPE,
- me: (_f = data.me) != null ? _f : siteUrl,
- authorizationEndpoint,
- tokenEndpoint,
- micropubEndpoint
- };
- }
- // ── Helpers ───────────────────────────────────────────────────────────────
- static base64url(buf) {
- return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
- }
- static extractLinkRel(html, rel) {
- var _a;
- const re = new RegExp(
- `]+rel=["'][^"']*\\b${rel}\\b[^"']*["'][^>]+href=["']([^"']+)["']|]+href=["']([^"']+)["'][^>]+rel=["'][^"']*\\b${rel}\\b[^"']*["']`,
- "i"
- );
- const m = html.match(re);
- return (_a = m == null ? void 0 : m[1]) != null ? _a : m == null ? void 0 : m[2];
- }
-};
-
-// src/SettingsTab.ts
-var MicropubSettingsTab = class extends import_obsidian3.PluginSettingTab {
- constructor(app, plugin) {
- super(app, plugin);
- this.plugin = plugin;
- }
- display() {
- const { containerEl } = this;
- containerEl.empty();
- containerEl.createEl("h2", { text: "Micropub Publisher" });
- containerEl.createEl("h3", { text: "Account" });
- if (this.plugin.settings.me && this.plugin.settings.accessToken) {
- this.renderSignedIn(containerEl);
- } else {
- this.renderSignedOut(containerEl);
- }
- containerEl.createEl("h3", { text: "Endpoints" });
- containerEl.createEl("p", {
- text: "These are filled automatically when you sign in. Only edit them manually if your server uses non-standard paths.",
- cls: "setting-item-description"
- });
- new import_obsidian3.Setting(containerEl).setName("Micropub endpoint").setDesc("e.g. https://blog.giersig.eu/micropub").addText(
- (text) => text.setPlaceholder("https://example.com/micropub").setValue(this.plugin.settings.micropubEndpoint).onChange(async (value) => {
- this.plugin.settings.micropubEndpoint = value.trim();
- await this.plugin.saveSettings();
- })
- );
- new import_obsidian3.Setting(containerEl).setName("Media endpoint").setDesc("For image uploads. Auto-discovered if blank.").addText(
- (text) => text.setPlaceholder("https://example.com/micropub/media").setValue(this.plugin.settings.mediaEndpoint).onChange(async (value) => {
- this.plugin.settings.mediaEndpoint = value.trim();
- await this.plugin.saveSettings();
- })
- );
- containerEl.createEl("h3", { text: "Publish Behaviour" });
- new import_obsidian3.Setting(containerEl).setName("Default visibility").setDesc("Applies when the note has no explicit visibility property.").addDropdown(
- (drop) => drop.addOption("public", "Public").addOption("unlisted", "Unlisted").addOption("private", "Private").setValue(this.plugin.settings.defaultVisibility).onChange(async (value) => {
- this.plugin.settings.defaultVisibility = value;
- await this.plugin.saveSettings();
- })
- );
- new import_obsidian3.Setting(containerEl).setName("Write URL back to note").setDesc(
- "After publishing, store the post URL as `mp-url` in frontmatter. Subsequent publishes will update the existing post instead of creating a new one."
- ).addToggle(
- (toggle) => toggle.setValue(this.plugin.settings.writeUrlToFrontmatter).onChange(async (value) => {
- this.plugin.settings.writeUrlToFrontmatter = value;
- await this.plugin.saveSettings();
- })
- );
- containerEl.createEl("h3", { text: "Digital Garden" });
- new import_obsidian3.Setting(containerEl).setName("Map #garden/* tags to gardenStage").setDesc(
- "Obsidian tags like #garden/plant become a `garden-stage: plant` Micropub property. The blog renders these as growth stage badges at /garden/."
- ).addToggle(
- (toggle) => toggle.setValue(this.plugin.settings.mapGardenTags).onChange(async (value) => {
- this.plugin.settings.mapGardenTags = value;
- await this.plugin.saveSettings();
- })
- );
- containerEl.createEl("p", {
- text: "Stages: plant \u{1F331} \xB7 cultivate \u{1F33F} \xB7 question \u2753 \xB7 repot \u{1FAB4} \xB7 revitalize \u2728 \xB7 revisit \u{1F504}",
- cls: "setting-item-description"
- });
- }
- // ── Signed-out state ─────────────────────────────────────────────────────
- renderSignedOut(containerEl) {
- new import_obsidian3.Setting(containerEl).setName("Site URL").setDesc(
- "Your site's home page. Clicking Sign in opens your blog's login page in the browser \u2014 the same flow iA Writer uses."
- ).addText(
- (text) => text.setPlaceholder("https://blog.giersig.eu").setValue(this.plugin.settings.siteUrl).onChange(async (value) => {
- this.plugin.settings.siteUrl = value.trim();
- await this.plugin.saveSettings();
- })
- ).addButton((btn) => {
- btn.setButtonText("Sign in").setCta().onClick(async () => {
- const siteUrl = this.plugin.settings.siteUrl.trim();
- if (!siteUrl) {
- new import_obsidian3.Notice("Enter your site URL first.");
- return;
- }
- btn.setDisabled(true);
- btn.setButtonText("Opening browser\u2026");
- try {
- const result = await IndieAuth.signIn(siteUrl);
- this.plugin.settings.accessToken = result.accessToken;
- this.plugin.settings.me = result.me;
- this.plugin.settings.authorizationEndpoint = result.authorizationEndpoint;
- this.plugin.settings.tokenEndpoint = result.tokenEndpoint;
- if (result.micropubEndpoint) {
- this.plugin.settings.micropubEndpoint = result.micropubEndpoint;
- }
- if (result.mediaEndpoint) {
- this.plugin.settings.mediaEndpoint = result.mediaEndpoint;
- }
- await this.plugin.saveSettings();
- if (!this.plugin.settings.mediaEndpoint) {
- try {
- const client = new MicropubClient(
- () => this.plugin.settings.micropubEndpoint,
- () => this.plugin.settings.mediaEndpoint,
- () => this.plugin.settings.accessToken
- );
- const cfg = await client.fetchConfig();
- if (cfg["media-endpoint"]) {
- this.plugin.settings.mediaEndpoint = cfg["media-endpoint"];
- await this.plugin.saveSettings();
- }
- } catch (e) {
- }
- }
- new import_obsidian3.Notice(`\u2705 Signed in as ${result.me}`);
- this.display();
- } catch (err) {
- new import_obsidian3.Notice(`Sign-in failed: ${String(err)}`, 8e3);
- btn.setDisabled(false);
- btn.setButtonText("Sign in");
- }
- });
- });
- const details = containerEl.createEl("details");
- details.createEl("summary", {
- text: "Or paste a token manually",
- cls: "setting-item-description"
- });
- details.style.marginTop = "8px";
- details.style.marginBottom = "8px";
- new import_obsidian3.Setting(details).setName("Access token").setDesc("Bearer token from your Indiekit admin panel.").addText((text) => {
- text.setPlaceholder("your-bearer-token").setValue(this.plugin.settings.accessToken).onChange(async (value) => {
- this.plugin.settings.accessToken = value.trim();
- await this.plugin.saveSettings();
- });
- text.inputEl.type = "password";
- }).addButton(
- (btn) => btn.setButtonText("Verify").onClick(async () => {
- if (!this.plugin.settings.micropubEndpoint || !this.plugin.settings.accessToken) {
- new import_obsidian3.Notice("Set the Micropub endpoint and token first.");
- return;
- }
- btn.setDisabled(true);
- try {
- const client = new MicropubClient(
- () => this.plugin.settings.micropubEndpoint,
- () => this.plugin.settings.mediaEndpoint,
- () => this.plugin.settings.accessToken
- );
- await client.fetchConfig();
- new import_obsidian3.Notice("\u2705 Token is valid!");
- } catch (err) {
- new import_obsidian3.Notice(`Token check failed: ${String(err)}`);
- } finally {
- btn.setDisabled(false);
- }
- })
- );
- }
- // ── Signed-in state ──────────────────────────────────────────────────────
- renderSignedIn(containerEl) {
- const me = this.plugin.settings.me;
- const banner = containerEl.createDiv({
- cls: "micropub-auth-banner"
- });
- banner.style.cssText = "display:flex;align-items:center;gap:12px;padding:12px 16px;border:1px solid var(--background-modifier-border);border-radius:8px;margin-bottom:16px;background:var(--background-secondary);";
- const icon = banner.createDiv();
- icon.style.cssText = "width:40px;height:40px;border-radius:50%;background:var(--interactive-accent);display:flex;align-items:center;justify-content:center;font-size:1.2rem;flex-shrink:0;";
- icon.textContent = "\u{1F310}";
- const info = banner.createDiv();
- info.createEl("div", {
- text: "Signed in",
- attr: { style: "font-size:.75rem;color:var(--text-muted);margin-bottom:2px" }
- });
- info.createEl("div", {
- text: me,
- attr: { style: "font-weight:500;word-break:break-all" }
- });
- new import_obsidian3.Setting(containerEl).setName("Site URL").addText(
- (text) => text.setValue(this.plugin.settings.siteUrl).setDisabled(true)
- ).addButton(
- (btn) => btn.setButtonText("Sign out").setWarning().onClick(async () => {
- this.plugin.settings.accessToken = "";
- this.plugin.settings.me = "";
- this.plugin.settings.authorizationEndpoint = "";
- this.plugin.settings.tokenEndpoint = "";
- await this.plugin.saveSettings();
- this.display();
- })
- );
- }
-};
-
-// src/Publisher.ts
-var import_obsidian4 = require("obsidian");
-var GARDEN_TAG_PREFIX = "garden/";
-var Publisher = class {
- constructor(app, settings) {
- this.app = app;
- this.settings = settings;
- this.client = new MicropubClient(
- () => settings.micropubEndpoint,
- () => settings.mediaEndpoint,
- () => settings.accessToken
- );
- }
- /** Publish the given file. Returns PublishResult. */
- async publish(file) {
- var _a, _b;
- const raw = await this.app.vault.read(file);
- const { frontmatter, body } = this.parseFrontmatter(raw);
- const existingUrl = (_b = (_a = frontmatter["mp-url"]) != null ? _a : frontmatter["url"]) != null ? _b : void 0;
- const { content: processedBody, uploadedUrls } = await this.processImages(body);
- const properties = this.buildProperties(frontmatter, processedBody, uploadedUrls);
- let result;
- if (existingUrl) {
- const replace = {};
- for (const [k, v] of Object.entries(properties)) {
- replace[k] = Array.isArray(v) ? v : [v];
- }
- result = await this.client.updatePost(existingUrl, replace);
- } else {
- result = await this.client.createPost(properties);
- }
- if (result.success && result.url && this.settings.writeUrlToFrontmatter) {
- await this.writeUrlToNote(file, raw, result.url);
- }
- return result;
- }
- // ── Property builder ─────────────────────────────────────────────────────
- buildProperties(fm, body, uploadedUrls) {
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
- const props = {};
- const trimmedBody = body.trim();
- const bookmarkOf = (_a = fm["bookmarkOf"]) != null ? _a : fm["bookmark-of"];
- const likeOf = (_b = fm["likeOf"]) != null ? _b : fm["like-of"];
- const inReplyTo = (_c = fm["inReplyTo"]) != null ? _c : fm["in-reply-to"];
- const repostOf = (_d = fm["repostOf"]) != null ? _d : fm["repost-of"];
- if (bookmarkOf) props["bookmark-of"] = [String(bookmarkOf)];
- if (likeOf) props["like-of"] = [String(likeOf)];
- if (inReplyTo) props["in-reply-to"] = [String(inReplyTo)];
- if (repostOf) props["repost-of"] = [String(repostOf)];
- const isInteractionWithoutBody = (likeOf || repostOf) && !trimmedBody;
- if (!isInteractionWithoutBody) {
- props["content"] = trimmedBody ? [{ html: trimmedBody }] : [{ html: "" }];
- }
- if (fm["title"]) {
- props["name"] = [String(fm["title"])];
- }
- if ((_e = fm["summary"]) != null ? _e : fm["excerpt"]) {
- props["summary"] = [String((_f = fm["summary"]) != null ? _f : fm["excerpt"])];
- }
- const rawDate = (_g = fm["created"]) != null ? _g : fm["date"];
- if (rawDate) {
- props["published"] = [new Date(String(rawDate)).toISOString()];
- }
- const rawTags = this.resolveArray((_h = fm["tags"]) != null ? _h : fm["category"]);
- const gardenStage = this.extractGardenStage(rawTags);
- const normalTags = rawTags.filter(
- (t) => !t.startsWith(GARDEN_TAG_PREFIX) && t !== "garden"
- );
- if (normalTags.length > 0) {
- props["category"] = normalTags;
- }
- if (this.settings.mapGardenTags && gardenStage) {
- props["garden-stage"] = [gardenStage];
- }
- const syndicateTo = this.resolveArray(
- (_i = fm["mp-syndicate-to"]) != null ? _i : fm["mpSyndicateTo"]
- );
- const allSyndicateTo = [
- .../* @__PURE__ */ new Set([...this.settings.defaultSyndicateTo, ...syndicateTo])
- ];
- if (allSyndicateTo.length > 0) {
- props["mp-syndicate-to"] = allSyndicateTo;
- }
- const visibility = (_j = fm["visibility"]) != null ? _j : this.settings.defaultVisibility;
- if (visibility && visibility !== "public") {
- props["visibility"] = [visibility];
- }
- if (fm["ai"] && typeof fm["ai"] === "object") {
- props["ai"] = [fm["ai"]];
- }
- const fmPhotos = this.resolvePhotoArray(fm["photo"]);
- if (fmPhotos.length > 0) {
- props["photo"] = fmPhotos;
- } else if (uploadedUrls.length > 0) {
- props["photo"] = uploadedUrls.map((url) => ({ value: url }));
- }
- for (const [k, v] of Object.entries(fm)) {
- if (k.startsWith("mp-") && k !== "mp-url" && k !== "mp-syndicate-to") {
- props[k] = this.resolveArray(v);
- }
- }
- return props;
- }
- /**
- * Normalise the `photo` frontmatter field into Micropub photo objects.
- * Handles three formats:
- * - string URL: "https://..."
- * - array of strings: ["https://..."]
- * - array of objects: [{url: "https://...", alt: "..."}]
- */
- resolvePhotoArray(value) {
- if (!value) return [];
- const items = Array.isArray(value) ? value : [value];
- return items.map((item) => {
- var _a, _b;
- if (typeof item === "string") return { value: item };
- if (typeof item === "object" && item !== null) {
- const obj = item;
- const url = String((_b = (_a = obj["url"]) != null ? _a : obj["value"]) != null ? _b : "");
- if (!url) return null;
- return obj["alt"] ? { value: url, alt: String(obj["alt"]) } : { value: url };
- }
- return null;
- }).filter((x) => x !== null);
- }
- // ── Garden tag extraction ────────────────────────────────────────────────
- /**
- * Find the first #garden/ tag and return the stage name.
- * Supports both "garden/plant" (Obsidian array) and "#garden/plant" (inline).
- */
- extractGardenStage(tags) {
- for (const tag of tags) {
- const clean = tag.replace(/^#/, "");
- if (clean.startsWith(GARDEN_TAG_PREFIX)) {
- const stage = clean.slice(GARDEN_TAG_PREFIX.length);
- const valid = [
- "plant",
- "cultivate",
- "question",
- "repot",
- "revitalize",
- "revisit"
- ];
- if (valid.includes(stage)) return stage;
- }
- }
- return void 0;
- }
- // ── Image processing ─────────────────────────────────────────────────────
- /**
- * Find all `![[local-image.png]]` or `` in the body,
- * upload them to the media endpoint, and replace the references with remote URLs.
- */
- async processImages(body) {
- const uploadedUrls = [];
- const wikiPattern = /!\[\[([^\]]+\.(png|jpg|jpeg|gif|webp|svg))\]\]/gi;
- const mdPattern = /!\[([^\]]*)\]\(([^)]+\.(png|jpg|jpeg|gif|webp|svg))\)/gi;
- let content = body;
- const wikiMatches = [...body.matchAll(wikiPattern)];
- for (const match of wikiMatches) {
- const filename = match[1];
- try {
- const remoteUrl = await this.uploadLocalFile(filename);
- if (remoteUrl) {
- uploadedUrls.push(remoteUrl);
- content = content.replace(match[0], ``);
- }
- } catch (err) {
- console.warn(`[micropub] Failed to upload ${filename}:`, err);
- }
- }
- const mdMatches = [...content.matchAll(mdPattern)];
- for (const match of mdMatches) {
- const alt = match[1];
- const path = match[2];
- if (path.startsWith("http")) continue;
- try {
- const remoteUrl = await this.uploadLocalFile(path);
- if (remoteUrl) {
- uploadedUrls.push(remoteUrl);
- content = content.replace(match[0], ``);
- }
- } catch (err) {
- console.warn(`[micropub] Failed to upload ${path}:`, err);
- }
- }
- return { content, uploadedUrls };
- }
- async uploadLocalFile(path) {
- const file = this.app.vault.getFiles().find(
- (f) => f.name === path || f.path === path
- );
- if (!file) return void 0;
- const buffer = await this.app.vault.readBinary(file);
- const mimeType = this.guessMimeType(file.extension);
- return this.client.uploadMedia(buffer, file.name, mimeType);
- }
- // ── Frontmatter helpers ──────────────────────────────────────────────────
- parseFrontmatter(raw) {
- var _a;
- const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
- if (!fmMatch) return { frontmatter: {}, body: raw };
- let frontmatter = {};
- try {
- frontmatter = (_a = (0, import_obsidian4.parseYaml)(fmMatch[1])) != null ? _a : {};
- } catch (e) {
- }
- return { frontmatter, body: fmMatch[2] };
- }
- async writeUrlToNote(file, originalContent, url) {
- const fmMatch = originalContent.match(
- /^(---\r?\n[\s\S]*?\r?\n---\r?\n)([\s\S]*)$/
- );
- if (!fmMatch) {
- const newFm = `---
-mp-url: "${url}"
----
-`;
- await this.app.vault.modify(file, newFm + originalContent);
- return;
- }
- const fmBlock = fmMatch[1];
- const body = fmMatch[2];
- if (fmBlock.includes("mp-url:")) {
- const updated = fmBlock.replace(
- /mp-url:.*(\r?\n)/,
- `mp-url: "${url}"$1`
- );
- await this.app.vault.modify(file, updated + body);
- } else {
- const updated = fmBlock.replace(
- /(\r?\n---\r?\n)$/,
- `
-mp-url: "${url}"$1`
- );
- await this.app.vault.modify(file, updated + body);
- }
- }
- resolveArray(value) {
- if (!value) return [];
- if (Array.isArray(value)) return value.map(String);
- return [String(value)];
- }
- guessMimeType(ext) {
- var _a;
- const map = {
- png: "image/png",
- jpg: "image/jpeg",
- jpeg: "image/jpeg",
- gif: "image/gif",
- webp: "image/webp",
- svg: "image/svg+xml"
- };
- return (_a = map[ext.toLowerCase()]) != null ? _a : "application/octet-stream";
- }
-};
-
-// src/main.ts
-var MicropubPlugin = class extends import_obsidian5.Plugin {
- async onload() {
- await this.loadSettings();
- this.addCommand({
- id: "publish-to-micropub",
- name: "Publish to Micropub",
- checkCallback: (checking) => {
- const file = this.app.workspace.getActiveFile();
- if (!file || file.extension !== "md") return false;
- if (checking) return true;
- this.publishActiveNote(file);
- return true;
- }
- });
- this.addCommand({
- id: "publish-to-micropub-update",
- name: "Update existing Micropub post",
- checkCallback: (checking) => {
- const file = this.app.workspace.getActiveFile();
- if (!file || file.extension !== "md") return false;
- if (checking) return true;
- this.publishActiveNote(file);
- return true;
- }
- });
- this.registerObsidianProtocolHandler("micropub-auth", (params) => {
- handleProtocolCallback(params);
- });
- this.addSettingTab(new MicropubSettingsTab(this.app, this));
- this.addRibbonIcon("send", "Publish to Micropub", () => {
- const file = this.app.workspace.getActiveFile();
- if (!file || file.extension !== "md") {
- new import_obsidian5.Notice("Open a Markdown note to publish.");
- return;
- }
- this.publishActiveNote(file);
- });
- }
- onunload() {
- }
- // ── Publish flow ──────────────────────────────────────────────────────────
- async publishActiveNote(file) {
- if (!this.settings.micropubEndpoint) {
- new import_obsidian5.Notice(
- "\u26A0\uFE0F Micropub endpoint not configured. Open plugin settings to add it."
- );
- return;
- }
- if (!this.settings.accessToken) {
- new import_obsidian5.Notice(
- "\u26A0\uFE0F Access token not configured. Open plugin settings to add it."
- );
- return;
- }
- const notice = new import_obsidian5.Notice(
- "Publishing\u2026",
- 0
- /* persist until dismissed */
- );
- try {
- const publisher = new Publisher(this.app, this.settings);
- const result = await publisher.publish(file);
- notice.hide();
- if (result.success) {
- const urlDisplay = result.url ? `
-${result.url}` : "";
- new import_obsidian5.Notice(`\u2705 Published!${urlDisplay}`, 8e3);
- } else {
- new import_obsidian5.Notice(`\u274C Publish failed: ${result.error}`, 1e4);
- console.error("[micropub] Publish failed:", result.error);
- }
- } catch (err) {
- notice.hide();
- const msg = err instanceof Error ? err.message : String(err);
- new import_obsidian5.Notice(`\u274C Error: ${msg}`, 1e4);
- console.error("[micropub] Unexpected error:", err);
- }
- }
- // ── Settings persistence ──────────────────────────────────────────────────
- async loadSettings() {
- this.settings = Object.assign(
- {},
- DEFAULT_SETTINGS,
- await this.loadData()
- );
- }
- async saveSettings() {
- await this.saveData(this.settings);
- }
-};
-//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL3R5cGVzLnRzIiwgInNyYy9TZXR0aW5nc1RhYi50cyIsICJzcmMvTWljcm9wdWJDbGllbnQudHMiLCAic3JjL0luZGllQXV0aC50cyIsICJzcmMvUHVibGlzaGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIG1haW4udHMgXHUyMDE0IG9ic2lkaWFuLW1pY3JvcHViIHBsdWdpbiBlbnRyeSBwb2ludFxuICpcbiAqIFB1Ymxpc2hlcyB0aGUgYWN0aXZlIG5vdGUgdG8gYW55IE1pY3JvcHViLWNvbXBhdGlibGUgZW5kcG9pbnQuXG4gKiBEZXNpZ25lZCB0byB3b3JrIHdpdGggSW5kaWVraXQgKGh0dHBzOi8vZ2V0aW5kaWVraXQuY29tKSBidXQgY29tcGF0aWJsZVxuICogd2l0aCBhbnkgc2VydmVyIHRoYXQgaW1wbGVtZW50cyB0aGUgTWljcm9wdWIgc3BlYyAoVzNDKS5cbiAqXG4gKiBLZXkgZmVhdHVyZXMgdnMuIHRoZSBvcmlnaW5hbCBvYnNpZGlhbi1taWNyb2Jsb2c6XG4gKiAgIC0gQ29uZmlndXJhYmxlIGVuZHBvaW50IFVSTCAobm90IGhhcmRjb2RlZCB0byBNaWNyby5ibG9nKVxuICogICAtIEF1dG8tZGlzY292ZXJ5IG9mIG1pY3JvcHViL21lZGlhIGVuZHBvaW50cyBmcm9tIDxsaW5rIHJlbD4gaGVhZGVyc1xuICogICAtICNnYXJkZW4vKiB0YWcgXHUyMTkyIGdhcmRlblN0YWdlIHByb3BlcnR5IG1hcHBpbmcgZm9yIERpZ2l0YWwgR2FyZGVuXG4gKiAgIC0gV3JpdGVzIHJldHVybmVkIHBvc3QgVVJMIGJhY2sgdG8gbm90ZSBmcm9udG1hdHRlciBmb3IgZnV0dXJlIHVwZGF0ZXNcbiAqICAgLSBTdXBwb3J0cyBjcmVhdGUgKyB1cGRhdGUgZmxvd3NcbiAqXG4gKiBCYXNlZCBvbjogaHR0cHM6Ly9naXRodWIuY29tL3N2ZW1hZ2llL29ic2lkaWFuLW1pY3JvYmxvZyAoTUlUKVxuICovXG5cbmltcG9ydCB7IE5vdGljZSwgUGx1Z2luLCBURmlsZSB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgREVGQVVMVF9TRVRUSU5HUywgdHlwZSBNaWNyb3B1YlNldHRpbmdzIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IE1pY3JvcHViU2V0dGluZ3NUYWIgfSBmcm9tIFwiLi9TZXR0aW5nc1RhYlwiO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSBcIi4vUHVibGlzaGVyXCI7XG5pbXBvcnQgeyBoYW5kbGVQcm90b2NvbENhbGxiYWNrIH0gZnJvbSBcIi4vSW5kaWVBdXRoXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1pY3JvcHViUGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcbiAgc2V0dGluZ3MhOiBNaWNyb3B1YlNldHRpbmdzO1xuXG4gIGFzeW5jIG9ubG9hZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xuXG4gICAgLy8gXHUyNTAwXHUyNTAwIENvbW1hbmRzIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcInB1Ymxpc2gtdG8tbWljcm9wdWJcIixcbiAgICAgIG5hbWU6IFwiUHVibGlzaCB0byBNaWNyb3B1YlwiLFxuICAgICAgY2hlY2tDYWxsYmFjazogKGNoZWNraW5nOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xuICAgICAgICBpZiAoIWZpbGUgfHwgZmlsZS5leHRlbnNpb24gIT09IFwibWRcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoY2hlY2tpbmcpIHJldHVybiB0cnVlO1xuXG4gICAgICAgIHRoaXMucHVibGlzaEFjdGl2ZU5vdGUoZmlsZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogXCJwdWJsaXNoLXRvLW1pY3JvcHViLXVwZGF0ZVwiLFxuICAgICAgbmFtZTogXCJVcGRhdGUgZXhpc3RpbmcgTWljcm9wdWIgcG9zdFwiLFxuICAgICAgY2hlY2tDYWxsYmFjazogKGNoZWNraW5nOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xuICAgICAgICBpZiAoIWZpbGUgfHwgZmlsZS5leHRlbnNpb24gIT09IFwibWRcIikgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoY2hlY2tpbmcpIHJldHVybiB0cnVlO1xuXG4gICAgICAgIC8vIFVwZGF0ZSB1c2VzIHRoZSBzYW1lIHB1Ymxpc2ggZmxvdyBcdTIwMTQgUHVibGlzaGVyIGRldGVjdHMgbXAtdXJsIGFuZCByb3V0ZXMgdG8gdXBkYXRlXG4gICAgICAgIHRoaXMucHVibGlzaEFjdGl2ZU5vdGUoZmlsZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIFx1MjUwMFx1MjUwMCBJbmRpZUF1dGggcHJvdG9jb2wgaGFuZGxlciBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcbiAgICAvLyBSZWNlaXZlcyBvYnNpZGlhbjovL21pY3JvcHViLWF1dGg/Y29kZT0uLi4mc3RhdGU9Li4uIGFmdGVyIHRoZSB1c2VyXG4gICAgLy8gYXBwcm92ZXMgb24gdGhlaXIgSW5kaWVBdXRoIGxvZ2luIHBhZ2UuIFRoZSBHaXRIdWIgUGFnZXMgY2FsbGJhY2sgcGFnZVxuICAgIC8vIGF0IHN2ZW1hZ2llLmdpdGh1Yi5pby9vYnNpZGlhbi1taWNyb3B1Yi9jYWxsYmFjayByZWRpcmVjdHMgaGVyZS5cbiAgICB0aGlzLnJlZ2lzdGVyT2JzaWRpYW5Qcm90b2NvbEhhbmRsZXIoXCJtaWNyb3B1Yi1hdXRoXCIsIChwYXJhbXMpID0+IHtcbiAgICAgIGhhbmRsZVByb3RvY29sQ2FsbGJhY2socGFyYW1zIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pO1xuICAgIH0pO1xuXG4gICAgLy8gXHUyNTAwXHUyNTAwIFNldHRpbmdzIHRhYiBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcblxuICAgIHRoaXMuYWRkU2V0dGluZ1RhYihuZXcgTWljcm9wdWJTZXR0aW5nc1RhYih0aGlzLmFwcCwgdGhpcykpO1xuXG4gICAgLy8gXHUyNTAwXHUyNTAwIFJpYmJvbiBpY29uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gICAgdGhpcy5hZGRSaWJib25JY29uKFwic2VuZFwiLCBcIlB1Ymxpc2ggdG8gTWljcm9wdWJcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XG4gICAgICBpZiAoIWZpbGUgfHwgZmlsZS5leHRlbnNpb24gIT09IFwibWRcIikge1xuICAgICAgICBuZXcgTm90aWNlKFwiT3BlbiBhIE1hcmtkb3duIG5vdGUgdG8gcHVibGlzaC5cIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucHVibGlzaEFjdGl2ZU5vdGUoZmlsZSk7XG4gICAgfSk7XG4gIH1cblxuICBvbnVubG9hZCgpOiB2b2lkIHtcbiAgICAvLyBOb3RoaW5nIHRvIGNsZWFuIHVwXG4gIH1cblxuICAvLyBcdTI1MDBcdTI1MDAgUHVibGlzaCBmbG93IFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIHByaXZhdGUgYXN5bmMgcHVibGlzaEFjdGl2ZU5vdGUoZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuc2V0dGluZ3MubWljcm9wdWJFbmRwb2ludCkge1xuICAgICAgbmV3IE5vdGljZShcbiAgICAgICAgXCJcdTI2QTBcdUZFMEYgTWljcm9wdWIgZW5kcG9pbnQgbm90IGNvbmZpZ3VyZWQuIE9wZW4gcGx1Z2luIHNldHRpbmdzIHRvIGFkZCBpdC5cIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNldHRpbmdzLmFjY2Vzc1Rva2VuKSB7XG4gICAgICBuZXcgTm90aWNlKFxuICAgICAgICBcIlx1MjZBMFx1RkUwRiBBY2Nlc3MgdG9rZW4gbm90IGNvbmZpZ3VyZWQuIE9wZW4gcGx1Z2luIHNldHRpbmdzIHRvIGFkZCBpdC5cIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgbm90aWNlID0gbmV3IE5vdGljZShcIlB1Ymxpc2hpbmdcdTIwMjZcIiwgMCAvKiBwZXJzaXN0IHVudGlsIGRpc21pc3NlZCAqLyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcHVibGlzaGVyID0gbmV3IFB1Ymxpc2hlcih0aGlzLmFwcCwgdGhpcy5zZXR0aW5ncyk7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwdWJsaXNoZXIucHVibGlzaChmaWxlKTtcblxuICAgICAgbm90aWNlLmhpZGUoKTtcblxuICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgIGNvbnN0IHVybERpc3BsYXkgPSByZXN1bHQudXJsXG4gICAgICAgICAgPyBgXFxuJHtyZXN1bHQudXJsfWBcbiAgICAgICAgICA6IFwiXCI7XG4gICAgICAgIG5ldyBOb3RpY2UoYFx1MjcwNSBQdWJsaXNoZWQhJHt1cmxEaXNwbGF5fWAsIDgwMDApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3IE5vdGljZShgXHUyNzRDIFB1Ymxpc2ggZmFpbGVkOiAke3Jlc3VsdC5lcnJvcn1gLCAxMDAwMCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJbbWljcm9wdWJdIFB1Ymxpc2ggZmFpbGVkOlwiLCByZXN1bHQuZXJyb3IpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgbm90aWNlLmhpZGUoKTtcbiAgICAgIGNvbnN0IG1zZyA9IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKTtcbiAgICAgIG5ldyBOb3RpY2UoYFx1Mjc0QyBFcnJvcjogJHttc2d9YCwgMTAwMDApO1xuICAgICAgY29uc29sZS5lcnJvcihcIlttaWNyb3B1Yl0gVW5leHBlY3RlZCBlcnJvcjpcIiwgZXJyKTtcbiAgICB9XG4gIH1cblxuICAvLyBcdTI1MDBcdTI1MDAgU2V0dGluZ3MgcGVyc2lzdGVuY2UgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgYXN5bmMgbG9hZFNldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKFxuICAgICAge30sXG4gICAgICBERUZBVUxUX1NFVFRJTkdTLFxuICAgICAgYXdhaXQgdGhpcy5sb2FkRGF0YSgpLFxuICAgICkgYXMgTWljcm9wdWJTZXR0aW5ncztcbiAgfVxuXG4gIGFzeW5jIHNhdmVTZXR0aW5ncygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnNhdmVEYXRhKHRoaXMuc2V0dGluZ3MpO1xuICB9XG59XG4iLCAiLyoqXG4gKiB0eXBlcy50cyBcdTIwMTQgc2hhcmVkIGludGVyZmFjZXMgZm9yIG9ic2lkaWFuLW1pY3JvcHViXG4gKi9cblxuLyoqIFBsdWdpbiBzZXR0aW5ncyBzdG9yZWQgaW4gZGF0YS5qc29uICovXG5leHBvcnQgaW50ZXJmYWNlIE1pY3JvcHViU2V0dGluZ3Mge1xuICAvKiogRnVsbCBVUkwgb2YgdGhlIE1pY3JvcHViIGVuZHBvaW50LCBlLmcuIGh0dHBzOi8vZXhhbXBsZS5jb20vbWljcm9wdWIgKi9cbiAgbWljcm9wdWJFbmRwb2ludDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGdWxsIFVSTCBvZiB0aGUgbWVkaWEgZW5kcG9pbnQgZm9yIGltYWdlIHVwbG9hZHMuXG4gICAqIElmIGVtcHR5LCBkaXNjb3ZlcmVkIGF1dG9tYXRpY2FsbHkgZnJvbSB0aGUgTWljcm9wdWIgY29uZmlnIHF1ZXJ5LFxuICAgKiBvciBkZXJpdmVkIGZyb20gdGhlIG1pY3JvcHViRW5kcG9pbnQgKHNvbWUgc2VydmVycyB1c2UgL21pY3JvcHViL21lZGlhKS5cbiAgICovXG4gIG1lZGlhRW5kcG9pbnQ6IHN0cmluZztcblxuICAvKipcbiAgICogQmVhcmVyIHRva2VuIGZvciBBdXRob3JpemF0aW9uOiBCZWFyZXIgPHRva2VuPi5cbiAgICogT2J0YWluIGZyb20geW91ciBJbmRpZUF1dGggdG9rZW4gZW5kcG9pbnQgb3Igc2VydmVyIGFkbWluIHBhbmVsLlxuICAgKi9cbiAgYWNjZXNzVG9rZW46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHN5bmRpY2F0aW9uIHRhcmdldHMgdG8gcHJlLXRpY2sgaW4gdGhlIHB1Ymxpc2ggZGlhbG9nLlxuICAgKiBWYWx1ZXMgYXJlIHVpZCBzdHJpbmdzIHJldHVybmVkIGJ5IHRoZSBNaWNyb3B1YiBjb25maWcgP3E9Y29uZmlnLlxuICAgKi9cbiAgZGVmYXVsdFN5bmRpY2F0ZVRvOiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogV2hlbiB0cnVlLCBwZXJmb3JtIGEgZGlzY292ZXJ5IGZldGNoIGFnYWluc3QgdGhlIHNpdGUgVVJMIHRvIGF1dG8tZGV0ZWN0XG4gICAqIHRoZSBtaWNyb3B1YiBhbmQgdG9rZW4gZW5kcG9pbnRzIGZyb20gPGxpbmsgcmVsPVwibWljcm9wdWJcIj4gaGVhZGVycy5cbiAgICovXG4gIGF1dG9EaXNjb3ZlcjogYm9vbGVhbjtcblxuICAvKiogWW91ciBzaXRlJ3MgaG9tZXBhZ2UgVVJMIFx1MjAxNCB1c2VkIGZvciBlbmRwb2ludCBkaXNjb3ZlcnkgYW5kIEluZGllQXV0aC4gKi9cbiAgc2l0ZVVybDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYXV0aG9yaXphdGlvbl9lbmRwb2ludCBkaXNjb3ZlcmVkIGZyb20gdGhlIHNpdGUuXG4gICAqIFBvcHVsYXRlZCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSBJbmRpZUF1dGggc2lnbi1pbiBmbG93LlxuICAgKi9cbiAgYXV0aG9yaXphdGlvbkVuZHBvaW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB0b2tlbl9lbmRwb2ludCBkaXNjb3ZlcmVkIGZyb20gdGhlIHNpdGUuXG4gICAqIFBvcHVsYXRlZCBhdXRvbWF0aWNhbGx5IGJ5IHRoZSBJbmRpZUF1dGggc2lnbi1pbiBmbG93LlxuICAgKi9cbiAgdG9rZW5FbmRwb2ludDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgY2Fub25pY2FsIFwibWVcIiBVUkwgcmV0dXJuZWQgYnkgdGhlIHRva2VuIGVuZHBvaW50IGFmdGVyIHNpZ24taW4uXG4gICAqIFVzZWQgdG8gc2hvdyB3aG8gaXMgY3VycmVudGx5IGxvZ2dlZCBpbi5cbiAgICovXG4gIG1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFdoZW4gdHJ1ZSwgYWZ0ZXIgYSBzdWNjZXNzZnVsIHB1Ymxpc2ggdGhlIHBvc3QgVVJMIHJldHVybmVkIGJ5IHRoZSBzZXJ2ZXJcbiAgICogaXMgd3JpdHRlbiBiYWNrIHRvIHRoZSBub3RlJ3MgZnJvbnRtYXR0ZXIgYXMgYG1wLXVybGAuXG4gICAqL1xuICB3cml0ZVVybFRvRnJvbnRtYXR0ZXI6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE1hcCBPYnNpZGlhbiAjZ2FyZGVuLyogdGFncyB0byBhIGBnYXJkZW5TdGFnZWAgTWljcm9wdWIgcHJvcGVydHkuXG4gICAqIFdoZW4gZW5hYmxlZCwgYSB0YWcgbGlrZSAjZ2FyZGVuL3BsYW50IGJlY29tZXMgeyBcImdhcmRlbi1zdGFnZVwiOiBcInBsYW50XCIgfVxuICAgKiBpbiB0aGUgTWljcm9wdWIgcmVxdWVzdCAoYW5kIGdhcmRlblN0YWdlOiBwbGFudCBpbiB0aGUgc2VydmVyJ3MgZnJvbnQgbWF0dGVyKS5cbiAgICovXG4gIG1hcEdhcmRlblRhZ3M6IGJvb2xlYW47XG5cbiAgLyoqIFZpc2liaWxpdHkgZGVmYXVsdCBmb3IgbmV3IHBvc3RzOiBcInB1YmxpY1wiIHwgXCJ1bmxpc3RlZFwiIHwgXCJwcml2YXRlXCIgKi9cbiAgZGVmYXVsdFZpc2liaWxpdHk6IFwicHVibGljXCIgfCBcInVubGlzdGVkXCIgfCBcInByaXZhdGVcIjtcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfU0VUVElOR1M6IE1pY3JvcHViU2V0dGluZ3MgPSB7XG4gIG1pY3JvcHViRW5kcG9pbnQ6IFwiXCIsXG4gIG1lZGlhRW5kcG9pbnQ6IFwiXCIsXG4gIGFjY2Vzc1Rva2VuOiBcIlwiLFxuICBkZWZhdWx0U3luZGljYXRlVG86IFtdLFxuICBhdXRvRGlzY292ZXI6IGZhbHNlLFxuICBzaXRlVXJsOiBcIlwiLFxuICBhdXRob3JpemF0aW9uRW5kcG9pbnQ6IFwiXCIsXG4gIHRva2VuRW5kcG9pbnQ6IFwiXCIsXG4gIG1lOiBcIlwiLFxuICB3cml0ZVVybFRvRnJvbnRtYXR0ZXI6IHRydWUsXG4gIG1hcEdhcmRlblRhZ3M6IHRydWUsXG4gIGRlZmF1bHRWaXNpYmlsaXR5OiBcInB1YmxpY1wiLFxufTtcblxuLyoqIEEgc3luZGljYXRpb24gdGFyZ2V0IGFzIHJldHVybmVkIGJ5IE1pY3JvcHViIGNvbmZpZyBxdWVyeSAqL1xuZXhwb3J0IGludGVyZmFjZSBTeW5kaWNhdGlvblRhcmdldCB7XG4gIHVpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG59XG5cbi8qKiBNaWNyb3B1YiBjb25maWcgcmVzcG9uc2UgKD9xPWNvbmZpZykgKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWljcm9wdWJDb25maWcge1xuICBcIm1lZGlhLWVuZHBvaW50XCI/OiBzdHJpbmc7XG4gIFwic3luZGljYXRlLXRvXCI/OiBTeW5kaWNhdGlvblRhcmdldFtdO1xuICBcInBvc3QtdHlwZXNcIj86IEFycmF5PHsgdHlwZTogc3RyaW5nOyBuYW1lOiBzdHJpbmcgfT47XG59XG5cbi8qKlxuICogR2FyZGVuIHN0YWdlcyBcdTIwMTQgbWF0Y2hlcyBPYnNpZGlhbiAjZ2FyZGVuLyogdGFncyBhbmQgYmxvZyBnYXJkZW5TdGFnZSB2YWx1ZXMuXG4gKiBUaGUgTWljcm9wdWIgcHJvcGVydHkgbmFtZSBpcyBcImdhcmRlbi1zdGFnZVwiIChoeXBoZW5hdGVkLCBNaWNyb3B1YiBjb252ZW50aW9uKS5cbiAqL1xuZXhwb3J0IHR5cGUgR2FyZGVuU3RhZ2UgPVxuICB8IFwicGxhbnRcIlxuICB8IFwiY3VsdGl2YXRlXCJcbiAgfCBcInF1ZXN0aW9uXCJcbiAgfCBcInJlcG90XCJcbiAgfCBcInJldml0YWxpemVcIlxuICB8IFwicmV2aXNpdFwiO1xuXG5leHBvcnQgY29uc3QgR0FSREVOX1NUQUdFX0xBQkVMUzogUmVjb3JkPEdhcmRlblN0YWdlLCBzdHJpbmc+ID0ge1xuICBwbGFudDogICAgICBcIlx1RDgzQ1x1REYzMSBTZWVkbGluZ1wiLFxuICBjdWx0aXZhdGU6ICBcIlx1RDgzQ1x1REYzRiBHcm93aW5nXCIsXG4gIHF1ZXN0aW9uOiAgIFwiXHUyNzUzIE9wZW4gUXVlc3Rpb25cIixcbiAgcmVwb3Q6ICAgICAgXCJcdUQ4M0VcdURFQjQgUmVwb3R0aW5nXCIsXG4gIHJldml0YWxpemU6IFwiXHUyNzI4IFJldml0YWxpemluZ1wiLFxuICByZXZpc2l0OiAgICBcIlx1RDgzRFx1REQwNCBSZXZpc2l0XCIsXG59O1xuXG4vKiogUmVzdWx0IHJldHVybmVkIGJ5IFB1Ymxpc2hlci5wdWJsaXNoKCkgKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHVibGlzaFJlc3VsdCB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIC8qKiBVUkwgb2YgdGhlIHB1Ymxpc2hlZCBwb3N0IChmcm9tIExvY2F0aW9uIHJlc3BvbnNlIGhlYWRlcikgKi9cbiAgdXJsPzogc3RyaW5nO1xuICBlcnJvcj86IHN0cmluZztcbn1cbiIsICIvKipcbiAqIFNldHRpbmdzVGFiLnRzIFx1MjAxNCBPYnNpZGlhbiBzZXR0aW5ncyBVSSBmb3Igb2JzaWRpYW4tbWljcm9wdWJcbiAqXG4gKiBBdXRoZW50aWNhdGlvbiBzZWN0aW9uIHdvcmtzIGxpa2UgaUEgV3JpdGVyOlxuICogICAxLiBVc2VyIGVudGVycyB0aGVpciBzaXRlIFVSTFxuICogICAyLiBDbGlja3MgXCJTaWduIGluXCIgXHUyMDE0IGJyb3dzZXIgb3BlbnMgYXQgdGhlaXIgSW5kaWVBdXRoIGxvZ2luIHBhZ2VcbiAqICAgMy4gVGhleSBsb2cgaW4gd2l0aCB0aGVpciBibG9nIHBhc3N3b3JkXG4gKiAgIDQuIEJyb3dzZXIgcmVkaXJlY3RzIGJhY2s7IHBsdWdpbiByZWNlaXZlcyB0aGUgdG9rZW4gYXV0b21hdGljYWxseVxuICogICA1LiBTZXR0aW5ncyBzaG93IFwiU2lnbmVkIGluIGFzIDxtZT5cIiArIGEgU2lnbiBPdXQgYnV0dG9uXG4gKlxuICogQWR2YW5jZWQgdXNlcnMgY2FuIHN0aWxsIHBhc3RlIGEgdG9rZW4gbWFudWFsbHkgaWYgdGhleSBwcmVmZXIuXG4gKi9cblxuaW1wb3J0IHsgQXBwLCBOb3RpY2UsIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB0eXBlIE1pY3JvcHViUGx1Z2luIGZyb20gXCIuL21haW5cIjtcbmltcG9ydCB7IE1pY3JvcHViQ2xpZW50IH0gZnJvbSBcIi4vTWljcm9wdWJDbGllbnRcIjtcbmltcG9ydCB7IEluZGllQXV0aCB9IGZyb20gXCIuL0luZGllQXV0aFwiO1xuXG5leHBvcnQgY2xhc3MgTWljcm9wdWJTZXR0aW5nc1RhYiBleHRlbmRzIFBsdWdpblNldHRpbmdUYWIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBhcHA6IEFwcCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbjogTWljcm9wdWJQbHVnaW4sXG4gICkge1xuICAgIHN1cGVyKGFwcCwgcGx1Z2luKTtcbiAgfVxuXG4gIGRpc3BsYXkoKTogdm9pZCB7XG4gICAgY29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcbiAgICBjb250YWluZXJFbC5lbXB0eSgpO1xuXG4gICAgY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwiTWljcm9wdWIgUHVibGlzaGVyXCIgfSk7XG5cbiAgICAvLyBcdTI1MDBcdTI1MDAgU2l0ZSBVUkwgKyBTaWduIEluIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuICAgIGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDNcIiwgeyB0ZXh0OiBcIkFjY291bnRcIiB9KTtcblxuICAgIC8vIFNob3cgY3VycmVudCBzaWduLWluIHN0YXR1c1xuICAgIGlmICh0aGlzLnBsdWdpbi5zZXR0aW5ncy5tZSAmJiB0aGlzLnBsdWdpbi5zZXR0aW5ncy5hY2Nlc3NUb2tlbikge1xuICAgICAgdGhpcy5yZW5kZXJTaWduZWRJbihjb250YWluZXJFbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVuZGVyU2lnbmVkT3V0KGNvbnRhaW5lckVsKTtcbiAgICB9XG5cbiAgICAvLyBcdTI1MDBcdTI1MDAgRW5kcG9pbnRzIChjb2xsYXBzZWQgLyBhZHZhbmNlZCkgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG4gICAgY29udGFpbmVyRWwuY3JlYXRlRWwoXCJoM1wiLCB7IHRleHQ6IFwiRW5kcG9pbnRzXCIgfSk7XG5cbiAgICBjb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgdGV4dDogXCJUaGVzZSBhcmUgZmlsbGVkIGF1dG9tYXRpY2FsbHkgd2hlbiB5b3Ugc2lnbiBpbi4gT25seSBlZGl0IHRoZW0gbWFudWFsbHkgaWYgeW91ciBzZXJ2ZXIgdXNlcyBub24tc3RhbmRhcmQgcGF0aHMuXCIsXG4gICAgICBjbHM6IFwic2V0dGluZy1pdGVtLWRlc2NyaXB0aW9uXCIsXG4gICAgfSk7XG5cbiAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgIC5zZXROYW1lKFwiTWljcm9wdWIgZW5kcG9pbnRcIilcbiAgICAgIC5zZXREZXNjKFwiZS5nLiBodHRwczovL2Jsb2cuZ2llcnNpZy5ldS9taWNyb3B1YlwiKVxuICAgICAgLmFkZFRleHQoKHRleHQpID0+XG4gICAgICAgIHRleHRcbiAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoXCJodHRwczovL2V4YW1wbGUuY29tL21pY3JvcHViXCIpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm1pY3JvcHViRW5kcG9pbnQpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MubWljcm9wdWJFbmRwb2ludCA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUoXCJNZWRpYSBlbmRwb2ludFwiKVxuICAgICAgLnNldERlc2MoXCJGb3IgaW1hZ2UgdXBsb2Fkcy4gQXV0by1kaXNjb3ZlcmVkIGlmIGJsYW5rLlwiKVxuICAgICAgLmFkZFRleHQoKHRleHQpID0+XG4gICAgICAgIHRleHRcbiAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoXCJodHRwczovL2V4YW1wbGUuY29tL21pY3JvcHViL21lZGlhXCIpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLm1lZGlhRW5kcG9pbnQpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MubWVkaWFFbmRwb2ludCA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIC8vIFx1MjUwMFx1MjUwMCBQdWJsaXNoIGJlaGF2aW91ciBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcbiAgICBjb250YWluZXJFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJQdWJsaXNoIEJlaGF2aW91clwiIH0pO1xuXG4gICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAuc2V0TmFtZShcIkRlZmF1bHQgdmlzaWJpbGl0eVwiKVxuICAgICAgLnNldERlc2MoXCJBcHBsaWVzIHdoZW4gdGhlIG5vdGUgaGFzIG5vIGV4cGxpY2l0IHZpc2liaWxpdHkgcHJvcGVydHkuXCIpXG4gICAgICAuYWRkRHJvcGRvd24oKGRyb3ApID0+XG4gICAgICAgIGRyb3BcbiAgICAgICAgICAuYWRkT3B0aW9uKFwicHVibGljXCIsIFwiUHVibGljXCIpXG4gICAgICAgICAgLmFkZE9wdGlvbihcInVubGlzdGVkXCIsIFwiVW5saXN0ZWRcIilcbiAgICAgICAgICAuYWRkT3B0aW9uKFwicHJpdmF0ZVwiLCBcIlByaXZhdGVcIilcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdFZpc2liaWxpdHkpXG4gICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVmYXVsdFZpc2liaWxpdHkgPSB2YWx1ZSBhc1xuICAgICAgICAgICAgICB8IFwicHVibGljXCJcbiAgICAgICAgICAgICAgfCBcInVubGlzdGVkXCJcbiAgICAgICAgICAgICAgfCBcInByaXZhdGVcIjtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgLnNldE5hbWUoXCJXcml0ZSBVUkwgYmFjayB0byBub3RlXCIpXG4gICAgICAuc2V0RGVzYyhcbiAgICAgICAgXCJBZnRlciBwdWJsaXNoaW5nLCBzdG9yZSB0aGUgcG9zdCBVUkwgYXMgYG1wLXVybGAgaW4gZnJvbnRtYXR0ZXIuIFwiICtcbiAgICAgICAgXCJTdWJzZXF1ZW50IHB1Ymxpc2hlcyB3aWxsIHVwZGF0ZSB0aGUgZXhpc3RpbmcgcG9zdCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IG9uZS5cIixcbiAgICAgIClcbiAgICAgIC5hZGRUb2dnbGUoKHRvZ2dsZSkgPT5cbiAgICAgICAgdG9nZ2xlXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLndyaXRlVXJsVG9Gcm9udG1hdHRlcilcbiAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy53cml0ZVVybFRvRnJvbnRtYXR0ZXIgPSB2YWx1ZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIC8vIFx1MjUwMFx1MjUwMCBEaWdpdGFsIEdhcmRlbiBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcbiAgICBjb250YWluZXJFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJEaWdpdGFsIEdhcmRlblwiIH0pO1xuXG4gICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAuc2V0TmFtZShcIk1hcCAjZ2FyZGVuLyogdGFncyB0byBnYXJkZW5TdGFnZVwiKVxuICAgICAgLnNldERlc2MoXG4gICAgICAgIFwiT2JzaWRpYW4gdGFncyBsaWtlICNnYXJkZW4vcGxhbnQgYmVjb21lIGEgYGdhcmRlbi1zdGFnZTogcGxhbnRgIE1pY3JvcHViIFwiICtcbiAgICAgICAgXCJwcm9wZXJ0eS4gVGhlIGJsb2cgcmVuZGVycyB0aGVzZSBhcyBncm93dGggc3RhZ2UgYmFkZ2VzIGF0IC9nYXJkZW4vLlwiLFxuICAgICAgKVxuICAgICAgLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxuICAgICAgICB0b2dnbGVcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MubWFwR2FyZGVuVGFncylcbiAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tYXBHYXJkZW5UYWdzID0gdmFsdWU7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICBjb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgdGV4dDogXCJTdGFnZXM6IHBsYW50IFx1RDgzQ1x1REYzMSBcdTAwQjcgY3VsdGl2YXRlIFx1RDgzQ1x1REYzRiBcdTAwQjcgcXVlc3Rpb24gXHUyNzUzIFx1MDBCNyByZXBvdCBcdUQ4M0VcdURFQjQgXHUwMEI3IHJldml0YWxpemUgXHUyNzI4IFx1MDBCNyByZXZpc2l0IFx1RDgzRFx1REQwNFwiLFxuICAgICAgY2xzOiBcInNldHRpbmctaXRlbS1kZXNjcmlwdGlvblwiLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gXHUyNTAwXHUyNTAwIFNpZ25lZC1vdXQgc3RhdGUgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgcHJpdmF0ZSByZW5kZXJTaWduZWRPdXQoY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgLy8gU2l0ZSBVUkwgaW5wdXQgKyBTaWduIEluIGJ1dHRvbiBvbiB0aGUgc2FtZSByb3dcbiAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgIC5zZXROYW1lKFwiU2l0ZSBVUkxcIilcbiAgICAgIC5zZXREZXNjKFxuICAgICAgICBcIllvdXIgc2l0ZSdzIGhvbWUgcGFnZS4gQ2xpY2tpbmcgU2lnbiBpbiBvcGVucyB5b3VyIGJsb2cncyBsb2dpbiBwYWdlIFwiICtcbiAgICAgICAgXCJpbiB0aGUgYnJvd3NlciBcdTIwMTQgdGhlIHNhbWUgZmxvdyBpQSBXcml0ZXIgdXNlcy5cIixcbiAgICAgIClcbiAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PlxuICAgICAgICB0ZXh0XG4gICAgICAgICAgLnNldFBsYWNlaG9sZGVyKFwiaHR0cHM6Ly9ibG9nLmdpZXJzaWcuZXVcIilcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc2l0ZVVybClcbiAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaXRlVXJsID0gdmFsdWUudHJpbSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgfSksXG4gICAgICApXG4gICAgICAuYWRkQnV0dG9uKChidG4pID0+IHtcbiAgICAgICAgYnRuXG4gICAgICAgICAgLnNldEJ1dHRvblRleHQoXCJTaWduIGluXCIpXG4gICAgICAgICAgLnNldEN0YSgpXG4gICAgICAgICAgLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2l0ZVVybCA9IHRoaXMucGx1Z2luLnNldHRpbmdzLnNpdGVVcmwudHJpbSgpO1xuICAgICAgICAgICAgaWYgKCFzaXRlVXJsKSB7XG4gICAgICAgICAgICAgIG5ldyBOb3RpY2UoXCJFbnRlciB5b3VyIHNpdGUgVVJMIGZpcnN0LlwiKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBidG4uc2V0RGlzYWJsZWQodHJ1ZSk7XG4gICAgICAgICAgICBidG4uc2V0QnV0dG9uVGV4dChcIk9wZW5pbmcgYnJvd3Nlclx1MjAyNlwiKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgSW5kaWVBdXRoLnNpZ25JbihzaXRlVXJsKTtcblxuICAgICAgICAgICAgICAvLyBTYXZlIGV2ZXJ5dGhpbmcgcmV0dXJuZWQgYnkgdGhlIGF1dGggZmxvd1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5hY2Nlc3NUb2tlbiAgICAgID0gcmVzdWx0LmFjY2Vzc1Rva2VuO1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tZSAgICAgICAgICAgICAgID0gcmVzdWx0Lm1lO1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRob3JpemF0aW9uRW5kcG9pbnQgPSByZXN1bHQuYXV0aG9yaXphdGlvbkVuZHBvaW50O1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy50b2tlbkVuZHBvaW50ICAgID0gcmVzdWx0LnRva2VuRW5kcG9pbnQ7XG4gICAgICAgICAgICAgIGlmIChyZXN1bHQubWljcm9wdWJFbmRwb2ludCkge1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLm1pY3JvcHViRW5kcG9pbnQgPSByZXN1bHQubWljcm9wdWJFbmRwb2ludDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVzdWx0Lm1lZGlhRW5kcG9pbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tZWRpYUVuZHBvaW50ID0gcmVzdWx0Lm1lZGlhRW5kcG9pbnQ7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblxuICAgICAgICAgICAgICAvLyBUcnkgdG8gZmV0Y2ggdGhlIE1pY3JvcHViIGNvbmZpZyB0byBwaWNrIHVwIG1lZGlhIGVuZHBvaW50XG4gICAgICAgICAgICAgIGlmICghdGhpcy5wbHVnaW4uc2V0dGluZ3MubWVkaWFFbmRwb2ludCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBjbGllbnQgPSBuZXcgTWljcm9wdWJDbGllbnQoXG4gICAgICAgICAgICAgICAgICAgICgpID0+IHRoaXMucGx1Z2luLnNldHRpbmdzLm1pY3JvcHViRW5kcG9pbnQsXG4gICAgICAgICAgICAgICAgICAgICgpID0+IHRoaXMucGx1Z2luLnNldHRpbmdzLm1lZGlhRW5kcG9pbnQsXG4gICAgICAgICAgICAgICAgICAgICgpID0+IHRoaXMucGx1Z2luLnNldHRpbmdzLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNmZyA9IGF3YWl0IGNsaWVudC5mZXRjaENvbmZpZygpO1xuICAgICAgICAgICAgICAgICAgaWYgKGNmZ1tcIm1lZGlhLWVuZHBvaW50XCJdKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLm1lZGlhRW5kcG9pbnQgPSBjZmdbXCJtZWRpYS1lbmRwb2ludFwiXTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAvLyBOb24tZmF0YWxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBuZXcgTm90aWNlKGBcdTI3MDUgU2lnbmVkIGluIGFzICR7cmVzdWx0Lm1lfWApO1xuICAgICAgICAgICAgICB0aGlzLmRpc3BsYXkoKTsgLy8gUmVmcmVzaCB0byBzaG93IHNpZ25lZC1pbiBzdGF0ZVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICAgIG5ldyBOb3RpY2UoYFNpZ24taW4gZmFpbGVkOiAke1N0cmluZyhlcnIpfWAsIDgwMDApO1xuICAgICAgICAgICAgICBidG4uc2V0RGlzYWJsZWQoZmFsc2UpO1xuICAgICAgICAgICAgICBidG4uc2V0QnV0dG9uVGV4dChcIlNpZ24gaW5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgIC8vIERpdmlkZXIgKyBtYW51YWwgdG9rZW4gZmFsbGJhY2sgKGNvbGxhcHNlZCBieSBkZWZhdWx0KVxuICAgIGNvbnN0IGRldGFpbHMgPSBjb250YWluZXJFbC5jcmVhdGVFbChcImRldGFpbHNcIik7XG4gICAgZGV0YWlscy5jcmVhdGVFbChcInN1bW1hcnlcIiwge1xuICAgICAgdGV4dDogXCJPciBwYXN0ZSBhIHRva2VuIG1hbnVhbGx5XCIsXG4gICAgICBjbHM6IFwic2V0dGluZy1pdGVtLWRlc2NyaXB0aW9uXCIsXG4gICAgfSk7XG4gICAgZGV0YWlscy5zdHlsZS5tYXJnaW5Ub3AgPSBcIjhweFwiO1xuICAgIGRldGFpbHMuc3R5bGUubWFyZ2luQm90dG9tID0gXCI4cHhcIjtcblxuICAgIG5ldyBTZXR0aW5nKGRldGFpbHMpXG4gICAgICAuc2V0TmFtZShcIkFjY2VzcyB0b2tlblwiKVxuICAgICAgLnNldERlc2MoXCJCZWFyZXIgdG9rZW4gZnJvbSB5b3VyIEluZGlla2l0IGFkbWluIHBhbmVsLlwiKVxuICAgICAgLmFkZFRleHQoKHRleHQpID0+IHtcbiAgICAgICAgdGV4dFxuICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcihcInlvdXItYmVhcmVyLXRva2VuXCIpXG4gICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmFjY2Vzc1Rva2VuKVxuICAgICAgICAgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLmFjY2Vzc1Rva2VuID0gdmFsdWUudHJpbSgpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIHRleHQuaW5wdXRFbC50eXBlID0gXCJwYXNzd29yZFwiO1xuICAgICAgfSlcbiAgICAgIC5hZGRCdXR0b24oKGJ0bikgPT5cbiAgICAgICAgYnRuLnNldEJ1dHRvblRleHQoXCJWZXJpZnlcIikub25DbGljayhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXRoaXMucGx1Z2luLnNldHRpbmdzLm1pY3JvcHViRW5kcG9pbnQgfHxcbiAgICAgICAgICAgICF0aGlzLnBsdWdpbi5zZXR0aW5ncy5hY2Nlc3NUb2tlblxuICAgICAgICAgICkge1xuICAgICAgICAgICAgbmV3IE5vdGljZShcIlNldCB0aGUgTWljcm9wdWIgZW5kcG9pbnQgYW5kIHRva2VuIGZpcnN0LlwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnRuLnNldERpc2FibGVkKHRydWUpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjbGllbnQgPSBuZXcgTWljcm9wdWJDbGllbnQoXG4gICAgICAgICAgICAgICgpID0+IHRoaXMucGx1Z2luLnNldHRpbmdzLm1pY3JvcHViRW5kcG9pbnQsXG4gICAgICAgICAgICAgICgpID0+IHRoaXMucGx1Z2luLnNldHRpbmdzLm1lZGlhRW5kcG9pbnQsXG4gICAgICAgICAgICAgICgpID0+IHRoaXMucGx1Z2luLnNldHRpbmdzLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5mZXRjaENvbmZpZygpO1xuICAgICAgICAgICAgbmV3IE5vdGljZShcIlx1MjcwNSBUb2tlbiBpcyB2YWxpZCFcIik7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICBuZXcgTm90aWNlKGBUb2tlbiBjaGVjayBmYWlsZWQ6ICR7U3RyaW5nKGVycil9YCk7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIGJ0bi5zZXREaXNhYmxlZChmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBcdTI1MDBcdTI1MDAgU2lnbmVkLWluIHN0YXRlIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIHByaXZhdGUgcmVuZGVyU2lnbmVkSW4oY29udGFpbmVyRWw6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgY29uc3QgbWUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tZTtcblxuICAgIC8vIEF2YXRhciArIFwiU2lnbmVkIGluIGFzXCIgYmFubmVyXG4gICAgY29uc3QgYmFubmVyID0gY29udGFpbmVyRWwuY3JlYXRlRGl2KHtcbiAgICAgIGNsczogXCJtaWNyb3B1Yi1hdXRoLWJhbm5lclwiLFxuICAgIH0pO1xuICAgIGJhbm5lci5zdHlsZS5jc3NUZXh0ID1cbiAgICAgIFwiZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6MTJweDtwYWRkaW5nOjEycHggMTZweDtcIiArXG4gICAgICBcImJvcmRlcjoxcHggc29saWQgdmFyKC0tYmFja2dyb3VuZC1tb2RpZmllci1ib3JkZXIpO1wiICtcbiAgICAgIFwiYm9yZGVyLXJhZGl1czo4cHg7bWFyZ2luLWJvdHRvbToxNnB4O2JhY2tncm91bmQ6dmFyKC0tYmFja2dyb3VuZC1zZWNvbmRhcnkpO1wiO1xuXG4gICAgY29uc3QgaWNvbiA9IGJhbm5lci5jcmVhdGVEaXYoKTtcbiAgICBpY29uLnN0eWxlLmNzc1RleHQgPVxuICAgICAgXCJ3aWR0aDo0MHB4O2hlaWdodDo0MHB4O2JvcmRlci1yYWRpdXM6NTAlO2JhY2tncm91bmQ6dmFyKC0taW50ZXJhY3RpdmUtYWNjZW50KTtcIiArXG4gICAgICBcImRpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjtcIiArXG4gICAgICBcImZvbnQtc2l6ZToxLjJyZW07ZmxleC1zaHJpbms6MDtcIjtcbiAgICBpY29uLnRleHRDb250ZW50ID0gXCJcdUQ4M0NcdURGMTBcIjtcblxuICAgIGNvbnN0IGluZm8gPSBiYW5uZXIuY3JlYXRlRGl2KCk7XG4gICAgaW5mby5jcmVhdGVFbChcImRpdlwiLCB7XG4gICAgICB0ZXh0OiBcIlNpZ25lZCBpblwiLFxuICAgICAgYXR0cjogeyBzdHlsZTogXCJmb250LXNpemU6Ljc1cmVtO2NvbG9yOnZhcigtLXRleHQtbXV0ZWQpO21hcmdpbi1ib3R0b206MnB4XCIgfSxcbiAgICB9KTtcbiAgICBpbmZvLmNyZWF0ZUVsKFwiZGl2XCIsIHtcbiAgICAgIHRleHQ6IG1lLFxuICAgICAgYXR0cjogeyBzdHlsZTogXCJmb250LXdlaWdodDo1MDA7d29yZC1icmVhazpicmVhay1hbGxcIiB9LFxuICAgIH0pO1xuXG4gICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAuc2V0TmFtZShcIlNpdGUgVVJMXCIpXG4gICAgICAuYWRkVGV4dCgodGV4dCkgPT5cbiAgICAgICAgdGV4dFxuICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaXRlVXJsKVxuICAgICAgICAgIC5zZXREaXNhYmxlZCh0cnVlKSxcbiAgICAgIClcbiAgICAgIC5hZGRCdXR0b24oKGJ0bikgPT5cbiAgICAgICAgYnRuXG4gICAgICAgICAgLnNldEJ1dHRvblRleHQoXCJTaWduIG91dFwiKVxuICAgICAgICAgIC5zZXRXYXJuaW5nKClcbiAgICAgICAgICAub25DbGljayhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5hY2Nlc3NUb2tlbiA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5tZSA9IFwiXCI7XG4gICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRob3JpemF0aW9uRW5kcG9pbnQgPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudG9rZW5FbmRwb2ludCA9IFwiXCI7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcbiAgfVxufVxuIiwgIi8qKlxuICogTWljcm9wdWJDbGllbnQudHNcbiAqXG4gKiBMb3ctbGV2ZWwgSFRUUCBjbGllbnQgZm9yIE1pY3JvcHViIGFuZCBNZWRpYSBlbmRwb2ludCByZXF1ZXN0cy5cbiAqIFVzZXMgT2JzaWRpYW4ncyByZXF1ZXN0VXJsKCkgc28gcmVxdWVzdHMgYXJlIG1hZGUgZnJvbSB0aGUgZGVza3RvcCBhcHBcbiAqIChubyBDT1JTIGlzc3VlcykgcmF0aGVyIHRoYW4gYSBicm93c2VyIGZldGNoLlxuICovXG5cbmltcG9ydCB7IHJlcXVlc3RVcmwsIFJlcXVlc3RVcmxQYXJhbSB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUgeyBNaWNyb3B1YkNvbmZpZywgUHVibGlzaFJlc3VsdCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBNaWNyb3B1YkNsaWVudCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZ2V0RW5kcG9pbnQ6ICgpID0+IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdldE1lZGlhRW5kcG9pbnQ6ICgpID0+IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGdldFRva2VuOiAoKSA9PiBzdHJpbmcsXG4gICkge31cblxuICAvLyBcdTI1MDBcdTI1MDAgQ29uZmlnIGRpc2NvdmVyeSBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcblxuICAvKiogRmV0Y2ggTWljcm9wdWIgc2VydmVyIGNvbmZpZyAoc3luZGljYXRpb24gdGFyZ2V0cywgbWVkaWEgZW5kcG9pbnQsIGV0Yy4pICovXG4gIGFzeW5jIGZldGNoQ29uZmlnKCk6IFByb21pc2U8TWljcm9wdWJDb25maWc+IHtcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmdldEVuZHBvaW50KCl9P3E9Y29uZmlnYDtcbiAgICBjb25zdCByZXNwID0gYXdhaXQgcmVxdWVzdFVybCh7XG4gICAgICB1cmwsXG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICBoZWFkZXJzOiB0aGlzLmF1dGhIZWFkZXJzKCksXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3AuanNvbiBhcyBNaWNyb3B1YkNvbmZpZztcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb3ZlciBtaWNyb3B1YiArIHRva2VuIGVuZHBvaW50IFVSTHMgZnJvbSBhIHNpdGUncyBob21lIHBhZ2VcbiAgICogYnkgcmVhZGluZyA8bGluayByZWw9XCJtaWNyb3B1YlwiPiBhbmQgPGxpbmsgcmVsPVwidG9rZW5fZW5kcG9pbnRcIj4gdGFncy5cbiAgICovXG4gIGFzeW5jIGRpc2NvdmVyRW5kcG9pbnRzKHNpdGVVcmw6IHN0cmluZyk6IFByb21pc2U8e1xuICAgIG1pY3JvcHViRW5kcG9pbnQ/OiBzdHJpbmc7XG4gICAgdG9rZW5FbmRwb2ludD86IHN0cmluZztcbiAgICBtZWRpYUVuZHBvaW50Pzogc3RyaW5nO1xuICB9PiB7XG4gICAgY29uc3QgcmVzcCA9IGF3YWl0IHJlcXVlc3RVcmwoeyB1cmw6IHNpdGVVcmwsIG1ldGhvZDogXCJHRVRcIiB9KTtcbiAgICBjb25zdCBodG1sID0gcmVzcC50ZXh0O1xuXG4gICAgY29uc3QgbWljcm9wdWIgPSB0aGlzLmV4dHJhY3RMaW5rUmVsKGh0bWwsIFwibWljcm9wdWJcIik7XG4gICAgY29uc3QgdG9rZW5FbmRwb2ludCA9IHRoaXMuZXh0cmFjdExpbmtSZWwoaHRtbCwgXCJ0b2tlbl9lbmRwb2ludFwiKTtcblxuICAgIC8vIEFmdGVyIGRpc2NvdmVyaW5nIHRoZSBNaWNyb3B1YiBlbmRwb2ludCwgZmV0Y2ggaXRzIGNvbmZpZyBmb3IgdGhlIG1lZGlhIFVSTFxuICAgIGxldCBtZWRpYUVuZHBvaW50OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKG1pY3JvcHViKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjZmcgPSBhd2FpdCB0aGlzLmZldGNoQ29uZmlnRnJvbShtaWNyb3B1Yik7XG4gICAgICAgIG1lZGlhRW5kcG9pbnQgPSBjZmdbXCJtZWRpYS1lbmRwb2ludFwiXTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBOb24tZmF0YWwgXHUyMDE0IG1lZGlhIGVuZHBvaW50IHN0YXlzIHVuZGVmaW5lZFxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IG1pY3JvcHViRW5kcG9pbnQ6IG1pY3JvcHViLCB0b2tlbkVuZHBvaW50LCBtZWRpYUVuZHBvaW50IH07XG4gIH1cblxuICAvLyBcdTI1MDBcdTI1MDAgUG9zdCBwdWJsaXNoaW5nIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgcG9zdCB2aWEgTWljcm9wdWIuXG4gICAqIFNlbmRzIGEgSlNPTiBib2R5IHdpdGggaC1lbnRyeSBwcm9wZXJ0aWVzLlxuICAgKiBSZXR1cm5zIHRoZSBMb2NhdGlvbiBoZWFkZXIgVVJMIG9uIHN1Y2Nlc3MuXG4gICAqL1xuICBhc3luYyBjcmVhdGVQb3N0KHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgY29uc3QgYm9keSA9IHtcbiAgICAgIHR5cGU6IFtcImgtZW50cnlcIl0sXG4gICAgICBwcm9wZXJ0aWVzLFxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHJlcXVlc3RVcmwoe1xuICAgICAgICB1cmw6IHRoaXMuZ2V0RW5kcG9pbnQoKSxcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIC4uLnRoaXMuYXV0aEhlYWRlcnMoKSxcbiAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgfSxcbiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgICAgIHRocm93OiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAocmVzcC5zdGF0dXMgPT09IDIwMSB8fCByZXNwLnN0YXR1cyA9PT0gMjAyKSB7XG4gICAgICAgIGNvbnN0IGxvY2F0aW9uID1cbiAgICAgICAgICByZXNwLmhlYWRlcnM/LltcImxvY2F0aW9uXCJdIHx8XG4gICAgICAgICAgcmVzcC5oZWFkZXJzPy5bXCJMb2NhdGlvblwiXSB8fFxuICAgICAgICAgIChyZXNwLmpzb24gYXMgeyB1cmw/OiBzdHJpbmcgfSk/LnVybDtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgdXJsOiBsb2NhdGlvbiB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZXRhaWwgPSB0aGlzLmV4dHJhY3RFcnJvcihyZXNwLnRleHQpO1xuICAgICAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UsIGVycm9yOiBgSFRUUCAke3Jlc3Auc3RhdHVzfTogJHtkZXRhaWx9YCB9O1xuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UsIGVycm9yOiBTdHJpbmcoZXJyKSB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYW4gZXhpc3RpbmcgcG9zdC5cbiAgICogQHBhcmFtIHBvc3RVcmwgIFRoZSBjYW5vbmljYWwgVVJMIG9mIHRoZSBwb3N0IHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gcmVwbGFjZSAgUHJvcGVydGllcyB0byByZXBsYWNlICh3aWxsIG92ZXJ3cml0ZSBleGlzdGluZyB2YWx1ZXMpXG4gICAqL1xuICBhc3luYyB1cGRhdGVQb3N0KFxuICAgIHBvc3RVcmw6IHN0cmluZyxcbiAgICByZXBsYWNlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duW10+LFxuICApOiBQcm9taXNlPFB1Ymxpc2hSZXN1bHQ+IHtcbiAgICBjb25zdCBib2R5ID0geyBhY3Rpb246IFwidXBkYXRlXCIsIHVybDogcG9zdFVybCwgcmVwbGFjZSB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCByZXF1ZXN0VXJsKHtcbiAgICAgICAgdXJsOiB0aGlzLmdldEVuZHBvaW50KCksXG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAuLi50aGlzLmF1dGhIZWFkZXJzKCksXG4gICAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICAgICAgICB0aHJvdzogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlc3Auc3RhdHVzID49IDIwMCAmJiByZXNwLnN0YXR1cyA8IDMwMCkge1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB1cmw6IHBvc3RVcmwgfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgIGVycm9yOiBgSFRUUCAke3Jlc3Auc3RhdHVzfTogJHt0aGlzLmV4dHJhY3RFcnJvcihyZXNwLnRleHQpfWAsXG4gICAgICB9O1xuICAgIH0gY2F0Y2ggKGVycjogdW5rbm93bikge1xuICAgICAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UsIGVycm9yOiBTdHJpbmcoZXJyKSB9O1xuICAgIH1cbiAgfVxuXG4gIC8vIFx1MjUwMFx1MjUwMCBNZWRpYSB1cGxvYWQgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgLyoqXG4gICAqIFVwbG9hZCBhIGJpbmFyeSBmaWxlIHRvIHRoZSBtZWRpYSBlbmRwb2ludC5cbiAgICogQHJldHVybnMgVGhlIFVSTCBvZiB0aGUgdXBsb2FkZWQgbWVkaWEsIG9yIHRocm93cyBvbiBmYWlsdXJlLlxuICAgKi9cbiAgYXN5bmMgdXBsb2FkTWVkaWEoXG4gICAgZmlsZUJ1ZmZlcjogQXJyYXlCdWZmZXIsXG4gICAgZmlsZU5hbWU6IHN0cmluZyxcbiAgICBtaW1lVHlwZTogc3RyaW5nLFxuICApOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IGVuZHBvaW50ID0gdGhpcy5nZXRNZWRpYUVuZHBvaW50KCkgfHwgYCR7dGhpcy5nZXRFbmRwb2ludCgpfS9tZWRpYWA7XG5cbiAgICAvLyBCdWlsZCBtdWx0aXBhcnQvZm9ybS1kYXRhIG1hbnVhbGx5IFx1MjAxNCBPYnNpZGlhbidzIHJlcXVlc3RVcmwgZG9lc24ndFxuICAgIC8vIHN1cHBvcnQgRm9ybURhdGEgZGlyZWN0bHksIHNvIHdlIGVuY29kZSB0aGUgYm91bmRhcnkgb3Vyc2VsdmVzLlxuICAgIGNvbnN0IGJvdW5kYXJ5ID0gYC0tLS1NaWNyb3B1YkJvdW5kYXJ5JHtEYXRlLm5vdygpfWA7XG4gICAgY29uc3QgaGVhZGVyID1cbiAgICAgIGAtLSR7Ym91bmRhcnl9XFxyXFxuYCArXG4gICAgICBgQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPVwiZmlsZVwiOyBmaWxlbmFtZT1cIiR7ZmlsZU5hbWV9XCJcXHJcXG5gICtcbiAgICAgIGBDb250ZW50LVR5cGU6ICR7bWltZVR5cGV9XFxyXFxuXFxyXFxuYDtcbiAgICBjb25zdCBmb290ZXIgPSBgXFxyXFxuLS0ke2JvdW5kYXJ5fS0tXFxyXFxuYDtcblxuICAgIGNvbnN0IGhlYWRlckJ1ZiA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShoZWFkZXIpO1xuICAgIGNvbnN0IGZvb3RlckJ1ZiA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShmb290ZXIpO1xuICAgIGNvbnN0IGZpbGVCdWYgPSBuZXcgVWludDhBcnJheShmaWxlQnVmZmVyKTtcblxuICAgIGNvbnN0IGNvbWJpbmVkID0gbmV3IFVpbnQ4QXJyYXkoXG4gICAgICBoZWFkZXJCdWYubGVuZ3RoICsgZmlsZUJ1Zi5sZW5ndGggKyBmb290ZXJCdWYubGVuZ3RoLFxuICAgICk7XG4gICAgY29tYmluZWQuc2V0KGhlYWRlckJ1ZiwgMCk7XG4gICAgY29tYmluZWQuc2V0KGZpbGVCdWYsIGhlYWRlckJ1Zi5sZW5ndGgpO1xuICAgIGNvbWJpbmVkLnNldChmb290ZXJCdWYsIGhlYWRlckJ1Zi5sZW5ndGggKyBmaWxlQnVmLmxlbmd0aCk7XG5cbiAgICBjb25zdCByZXNwID0gYXdhaXQgcmVxdWVzdFVybCh7XG4gICAgICB1cmw6IGVuZHBvaW50LFxuICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgLi4udGhpcy5hdXRoSGVhZGVycygpLFxuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBgbXVsdGlwYXJ0L2Zvcm0tZGF0YTsgYm91bmRhcnk9JHtib3VuZGFyeX1gLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IGNvbWJpbmVkLmJ1ZmZlcixcbiAgICAgIHRocm93OiBmYWxzZSxcbiAgICB9KTtcblxuICAgIGlmIChyZXNwLnN0YXR1cyA9PT0gMjAxIHx8IHJlc3Auc3RhdHVzID09PSAyMDIpIHtcbiAgICAgIGNvbnN0IGxvY2F0aW9uID1cbiAgICAgICAgcmVzcC5oZWFkZXJzPy5bXCJsb2NhdGlvblwiXSB8fFxuICAgICAgICByZXNwLmhlYWRlcnM/LltcIkxvY2F0aW9uXCJdIHx8XG4gICAgICAgIChyZXNwLmpzb24gYXMgeyB1cmw/OiBzdHJpbmcgfSk/LnVybDtcbiAgICAgIGlmIChsb2NhdGlvbikgcmV0dXJuIGxvY2F0aW9uO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBNZWRpYSB1cGxvYWQgZmFpbGVkIChIVFRQICR7cmVzcC5zdGF0dXN9KTogJHt0aGlzLmV4dHJhY3RFcnJvcihyZXNwLnRleHQpfWAsXG4gICAgKTtcbiAgfVxuXG4gIC8vIFx1MjUwMFx1MjUwMCBIZWxwZXJzIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIHByaXZhdGUgYXV0aEhlYWRlcnMoKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgcmV0dXJuIHsgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke3RoaXMuZ2V0VG9rZW4oKX1gIH07XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RMaW5rUmVsKGh0bWw6IHN0cmluZywgcmVsOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIC8vIE1hdGNoIGJvdGggPGxpbms+IGFuZCBIVFRQIExpbmsgaGVhZGVycyBlbWJlZGRlZCBpbiBIVE1MXG4gICAgY29uc3QgcmUgPSBuZXcgUmVnRXhwKFxuICAgICAgYDxsaW5rW14+XStyZWw9W1wiJ10ke3JlbH1bXCInXVtePl0raHJlZj1bXCInXShbXlwiJ10rKVtcIiddfDxsaW5rW14+XStocmVmPVtcIiddKFteXCInXSspW1wiJ11bXj5dK3JlbD1bXCInXSR7cmVsfVtcIiddYCxcbiAgICAgIFwiaVwiLFxuICAgICk7XG4gICAgY29uc3QgbSA9IGh0bWwubWF0Y2gocmUpO1xuICAgIHJldHVybiBtPy5bMV0gPz8gbT8uWzJdO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmZXRjaENvbmZpZ0Zyb20oZW5kcG9pbnQ6IHN0cmluZyk6IFByb21pc2U8TWljcm9wdWJDb25maWc+IHtcbiAgICBjb25zdCByZXNwID0gYXdhaXQgcmVxdWVzdFVybCh7XG4gICAgICB1cmw6IGAke2VuZHBvaW50fT9xPWNvbmZpZ2AsXG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICBoZWFkZXJzOiB0aGlzLmF1dGhIZWFkZXJzKCksXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3AuanNvbiBhcyBNaWNyb3B1YkNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdEVycm9yKHRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG9iaiA9IEpTT04ucGFyc2UodGV4dCkgYXMgeyBlcnJvcl9kZXNjcmlwdGlvbj86IHN0cmluZzsgZXJyb3I/OiBzdHJpbmcgfTtcbiAgICAgIHJldHVybiBvYmouZXJyb3JfZGVzY3JpcHRpb24gPz8gb2JqLmVycm9yID8/IHRleHQuc2xpY2UoMCwgMjAwKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiB0ZXh0LnNsaWNlKDAsIDIwMCk7XG4gICAgfVxuICB9XG59XG4iLCAiLyoqXG4gKiBJbmRpZUF1dGgudHMgXHUyMDE0IEluZGllQXV0aCBQS0NFIHNpZ24taW4gZmxvdyBmb3Igb2JzaWRpYW4tbWljcm9wdWJcbiAqXG4gKiBXaHkgbm8gbG9jYWwgSFRUUCBzZXJ2ZXI6XG4gKiAgIEluZGllS2l0IChhbmQgbW9zdCBJbmRpZUF1dGggc2VydmVycykgZmV0Y2ggdGhlIGNsaWVudF9pZCBVUkwgc2VydmVyLXNpZGVcbiAqICAgdG8gcmV0cmlldmUgYXBwIG1ldGFkYXRhLiBBIGxvY2FsIDEyNy4wLjAuMSBhZGRyZXNzIGlzIHVucmVhY2hhYmxlIGZyb20gYVxuICogICByZW1vdGUgc2VydmVyLCBzbyB0aGF0IGFwcHJvYWNoIGFsd2F5cyBmYWlscyB3aXRoIFwiZmV0Y2ggZmFpbGVkXCIuXG4gKlxuICogVGhlIHNvbHV0aW9uIFx1MjAxNCBHaXRIdWIgUGFnZXMgcmVsYXk6XG4gKiAgIGNsaWVudF9pZCAgPSBodHRwczovL3N2ZW1hZ2llLmdpdGh1Yi5pby9vYnNpZGlhbi1taWNyb3B1Yi9cbiAqICAgcmVkaXJlY3RfdXJpID0gaHR0cHM6Ly9zdmVtYWdpZS5naXRodWIuaW8vb2JzaWRpYW4tbWljcm9wdWIvY2FsbGJhY2tcbiAqXG4gKiAgIEJvdGggYXJlIG9uIHRoZSBzYW1lIGhvc3QgXHUyMTkyIEluZGllS2l0J3MgaG9zdC1tYXRjaGluZyBjaGVjayBwYXNzZXMgXHUyNzEzXG4gKiAgIFRoZSBjYWxsYmFjayBwYWdlIGlzIGEgc3RhdGljIEhUTUwgZmlsZSB0aGF0IGltbWVkaWF0ZWx5IHJlZGlyZWN0cyB0b1xuICogICBvYnNpZGlhbjovL21pY3JvcHViLWF1dGg/Y29kZT1DT0RFJnN0YXRlPVNUQVRFXG4gKiAgIE9ic2lkaWFuJ3MgcHJvdG9jb2wgaGFuZGxlciAocmVnaXN0ZXJlZCBpbiBtYWluLnRzKSByZWNlaXZlcyB0aGUgY29kZS5cbiAqXG4gKiBGbG93OlxuICogICAxLiBEaXNjb3ZlciBhdXRob3JpemF0aW9uX2VuZHBvaW50ICsgdG9rZW5fZW5kcG9pbnQgZnJvbSBzaXRlIEhUTUxcbiAqICAgMi4gR2VuZXJhdGUgUEtDRSBjb2RlX3ZlcmlmaWVyICsgY29kZV9jaGFsbGVuZ2UgKFNIQS0yNTYpXG4gKiAgIDMuIE9wZW4gYnJvd3NlciBcdTIxOTIgdXNlcidzIEluZGllQXV0aCBsb2dpbiBwYWdlXG4gKiAgIDQuIFVzZXIgbG9ncyBpbiBcdTIxOTIgc2VydmVyIHJlZGlyZWN0cyB0byBHaXRIdWIgUGFnZXMgY2FsbGJhY2tcbiAqICAgNS4gQ2FsbGJhY2sgcGFnZSByZWRpcmVjdHMgdG8gb2JzaWRpYW46Ly9taWNyb3B1Yi1hdXRoP2NvZGU9Li4uXG4gKiAgIDYuIFBsdWdpbiBwcm90b2NvbCBoYW5kbGVyIHJlc29sdmVzIHRoZSBwZW5kaW5nIFByb21pc2VcbiAqICAgNy4gRXhjaGFuZ2UgY29kZSBmb3IgdG9rZW4gYXQgdG9rZW5fZW5kcG9pbnRcbiAqL1xuXG5pbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSBcImNyeXB0b1wiO1xuaW1wb3J0IHsgcmVxdWVzdFVybCB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5leHBvcnQgY29uc3QgQ0xJRU5UX0lEICAgPSBcImh0dHBzOi8vc3ZlbWFnaWUuZ2l0aHViLmlvL29ic2lkaWFuLW1pY3JvcHViL1wiO1xuZXhwb3J0IGNvbnN0IFJFRElSRUNUX1VSSSA9IFwiaHR0cHM6Ly9zdmVtYWdpZS5naXRodWIuaW8vb2JzaWRpYW4tbWljcm9wdWIvY2FsbGJhY2tcIjtcblxuY29uc3QgU0NPUEUgPSBcImNyZWF0ZSB1cGRhdGUgbWVkaWFcIjtcbmNvbnN0IEFVVEhfVElNRU9VVF9NUyA9IDUgKiA2MCAqIDEwMDA7IC8vIDUgbWludXRlc1xuXG5leHBvcnQgaW50ZXJmYWNlIEluZGllQXV0aFJlc3VsdCB7XG4gIGFjY2Vzc1Rva2VuOiBzdHJpbmc7XG4gIHNjb3BlOiBzdHJpbmc7XG4gIC8qKiBDYW5vbmljYWwgXCJtZVwiIFVSTCByZXR1cm5lZCBieSB0aGUgdG9rZW4gZW5kcG9pbnQgKi9cbiAgbWU6IHN0cmluZztcbiAgYXV0aG9yaXphdGlvbkVuZHBvaW50OiBzdHJpbmc7XG4gIHRva2VuRW5kcG9pbnQ6IHN0cmluZztcbiAgbWljcm9wdWJFbmRwb2ludD86IHN0cmluZztcbiAgbWVkaWFFbmRwb2ludD86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaXNjb3ZlcmVkRW5kcG9pbnRzIHtcbiAgYXV0aG9yaXphdGlvbkVuZHBvaW50OiBzdHJpbmc7XG4gIHRva2VuRW5kcG9pbnQ6IHN0cmluZztcbiAgbWljcm9wdWJFbmRwb2ludD86IHN0cmluZztcbn1cblxuLyoqIFBlbmRpbmcgY2FsbGJhY2sgc2V0IGJ5IG1haW4udHMgcHJvdG9jb2wgaGFuZGxlciAqL1xubGV0IHBlbmRpbmdDYWxsYmFjazpcbiAgfCB7IHJlc29sdmU6IChwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID0+IHZvaWQ7IHN0YXRlOiBzdHJpbmcgfVxuICB8IG51bGwgPSBudWxsO1xuXG4vKipcbiAqIENhbGxlZCBieSB0aGUgT2JzaWRpYW4gcHJvdG9jb2wgaGFuZGxlciBpbiBtYWluLnRzIHdoZW5cbiAqIG9ic2lkaWFuOi8vbWljcm9wdWItYXV0aCBpcyBvcGVuZWQgYnkgdGhlIGJyb3dzZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQcm90b2NvbENhbGxiYWNrKHBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IHZvaWQge1xuICBpZiAoIXBlbmRpbmdDYWxsYmFjaykgcmV0dXJuO1xuXG4gIGNvbnN0IHsgcmVzb2x2ZSwgc3RhdGU6IGV4cGVjdGVkU3RhdGUgfSA9IHBlbmRpbmdDYWxsYmFjaztcbiAgcGVuZGluZ0NhbGxiYWNrID0gbnVsbDtcbiAgcmVzb2x2ZShwYXJhbXMpOyAvLyBsZXQgc2lnbkluKCkgdmFsaWRhdGUgc3RhdGUgKyBleHRyYWN0IGNvZGVcbn1cblxuZXhwb3J0IGNsYXNzIEluZGllQXV0aCB7XG4gIC8vIFx1MjUwMFx1MjUwMCBQdWJsaWMgQVBJIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIC8qKlxuICAgKiBEaXNjb3ZlciBJbmRpZUF1dGggKyBNaWNyb3B1YiBlbmRwb2ludCBVUkxzIGZyb20gdGhlIHNpdGUncyBob21lIHBhZ2VcbiAgICogYnkgcmVhZGluZyA8bGluayByZWw9XCIuLi5cIj4gdGFncyBpbiB0aGUgSFRNTCA8aGVhZD4uXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgZGlzY292ZXJFbmRwb2ludHMoc2l0ZVVybDogc3RyaW5nKTogUHJvbWlzZTxEaXNjb3ZlcmVkRW5kcG9pbnRzPiB7XG4gICAgY29uc3QgcmVzcCA9IGF3YWl0IHJlcXVlc3RVcmwoeyB1cmw6IHNpdGVVcmwsIG1ldGhvZDogXCJHRVRcIiB9KTtcbiAgICBjb25zdCBodG1sID0gcmVzcC50ZXh0O1xuXG4gICAgY29uc3QgYXV0aG9yaXphdGlvbkVuZHBvaW50ID0gSW5kaWVBdXRoLmV4dHJhY3RMaW5rUmVsKGh0bWwsIFwiYXV0aG9yaXphdGlvbl9lbmRwb2ludFwiKTtcbiAgICBjb25zdCB0b2tlbkVuZHBvaW50ICAgICAgICAgPSBJbmRpZUF1dGguZXh0cmFjdExpbmtSZWwoaHRtbCwgXCJ0b2tlbl9lbmRwb2ludFwiKTtcbiAgICBjb25zdCBtaWNyb3B1YkVuZHBvaW50ICAgICAgPSBJbmRpZUF1dGguZXh0cmFjdExpbmtSZWwoaHRtbCwgXCJtaWNyb3B1YlwiKTtcblxuICAgIGlmICghYXV0aG9yaXphdGlvbkVuZHBvaW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyA8bGluayByZWw9XCJhdXRob3JpemF0aW9uX2VuZHBvaW50XCI+IGZvdW5kIGF0ICR7c2l0ZVVybH0uIGAgK1xuICAgICAgICBcIk1ha2Ugc3VyZSBJbmRpZWtpdCBpcyBydW5uaW5nIGFuZCBTSVRFX1VSTCBpcyBzZXQgY29ycmVjdGx5LlwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCF0b2tlbkVuZHBvaW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIDxsaW5rIHJlbD1cInRva2VuX2VuZHBvaW50XCI+IGZvdW5kIGF0ICR7c2l0ZVVybH0uYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgYXV0aG9yaXphdGlvbkVuZHBvaW50LCB0b2tlbkVuZHBvaW50LCBtaWNyb3B1YkVuZHBvaW50IH07XG4gIH1cblxuICAvKipcbiAgICogUnVuIHRoZSBmdWxsIEluZGllQXV0aCBQS0NFIHNpZ24taW4gZmxvdy5cbiAgICpcbiAgICogT3BlbnMgdGhlIGJyb3dzZXIgYXQgdGhlIHVzZXIncyBJbmRpZUF1dGggbG9naW4gcGFnZS4gQWZ0ZXIgbG9naW4gdGhlXG4gICAqIGJyb3dzZXIgaXMgcmVkaXJlY3RlZCB0byB0aGUgR2l0SHViIFBhZ2VzIGNhbGxiYWNrLCB3aGljaCB0cmlnZ2Vyc1xuICAgKiB0aGUgb2JzaWRpYW46Ly9taWNyb3B1Yi1hdXRoIHByb3RvY29sLCB3aGljaCByZXNvbHZlcyB0aGUgUHJvbWlzZSBoZXJlLlxuICAgKlxuICAgKiBSZXF1aXJlcyBoYW5kbGVQcm90b2NvbENhbGxiYWNrKCkgdG8gYmUgd2lyZWQgdXAgaW4gbWFpbi50cyB2aWFcbiAgICogdGhpcy5yZWdpc3Rlck9ic2lkaWFuUHJvdG9jb2xIYW5kbGVyKFwibWljcm9wdWItYXV0aFwiLCBoYW5kbGVQcm90b2NvbENhbGxiYWNrKVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHNpZ25JbihzaXRlVXJsOiBzdHJpbmcpOiBQcm9taXNlPEluZGllQXV0aFJlc3VsdD4ge1xuICAgIC8vIDEuIERpc2NvdmVyIGVuZHBvaW50c1xuICAgIGNvbnN0IHsgYXV0aG9yaXphdGlvbkVuZHBvaW50LCB0b2tlbkVuZHBvaW50LCBtaWNyb3B1YkVuZHBvaW50IH0gPVxuICAgICAgYXdhaXQgSW5kaWVBdXRoLmRpc2NvdmVyRW5kcG9pbnRzKHNpdGVVcmwpO1xuXG4gICAgLy8gMi4gR2VuZXJhdGUgUEtDRSArIHN0YXRlXG4gICAgY29uc3Qgc3RhdGUgICAgICAgID0gSW5kaWVBdXRoLmJhc2U2NHVybChjcnlwdG8ucmFuZG9tQnl0ZXMoMTYpKTtcbiAgICBjb25zdCBjb2RlVmVyaWZpZXIgPSBJbmRpZUF1dGguYmFzZTY0dXJsKGNyeXB0by5yYW5kb21CeXRlcyg2NCkpO1xuICAgIGNvbnN0IGNvZGVDaGFsbGVuZ2UgPSBJbmRpZUF1dGguYmFzZTY0dXJsKFxuICAgICAgY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvZGVWZXJpZmllcikuZGlnZXN0KCksXG4gICAgKTtcblxuICAgIC8vIDMuIFJlZ2lzdGVyIHBlbmRpbmcgY2FsbGJhY2sgXHUyMDE0IHJlc29sdmVkIGJ5IGhhbmRsZVByb3RvY29sQ2FsbGJhY2soKVxuICAgIGNvbnN0IGNhbGxiYWNrUHJvbWlzZSA9IG5ldyBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KFxuICAgICAgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgcGVuZGluZ0NhbGxiYWNrID0gbnVsbDtcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiU2lnbi1pbiB0aW1lZCBvdXQgKDUgbWluKS4gUGxlYXNlIHRyeSBhZ2Fpbi5cIikpO1xuICAgICAgICB9LCBBVVRIX1RJTUVPVVRfTVMpO1xuXG4gICAgICAgIHBlbmRpbmdDYWxsYmFjayA9IHtcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICByZXNvbHZlOiAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICByZXNvbHZlKHBhcmFtcyk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIDQuIEJ1aWxkIHRoZSBhdXRob3JpemF0aW9uIFVSTCBhbmQgb3BlbiB0aGUgYnJvd3NlclxuICAgIGNvbnN0IGF1dGhVcmwgPSBuZXcgVVJMKGF1dGhvcml6YXRpb25FbmRwb2ludCk7XG4gICAgYXV0aFVybC5zZWFyY2hQYXJhbXMuc2V0KFwicmVzcG9uc2VfdHlwZVwiLCAgICAgICAgXCJjb2RlXCIpO1xuICAgIGF1dGhVcmwuc2VhcmNoUGFyYW1zLnNldChcImNsaWVudF9pZFwiLCAgICAgICAgICAgIENMSUVOVF9JRCk7XG4gICAgYXV0aFVybC5zZWFyY2hQYXJhbXMuc2V0KFwicmVkaXJlY3RfdXJpXCIsICAgICAgICAgUkVESVJFQ1RfVVJJKTtcbiAgICBhdXRoVXJsLnNlYXJjaFBhcmFtcy5zZXQoXCJzdGF0ZVwiLCAgICAgICAgICAgICAgICBzdGF0ZSk7XG4gICAgYXV0aFVybC5zZWFyY2hQYXJhbXMuc2V0KFwiY29kZV9jaGFsbGVuZ2VcIiwgICAgICAgY29kZUNoYWxsZW5nZSk7XG4gICAgYXV0aFVybC5zZWFyY2hQYXJhbXMuc2V0KFwiY29kZV9jaGFsbGVuZ2VfbWV0aG9kXCIsXCJTMjU2XCIpO1xuICAgIGF1dGhVcmwuc2VhcmNoUGFyYW1zLnNldChcInNjb3BlXCIsICAgICAgICAgICAgICAgIFNDT1BFKTtcbiAgICBhdXRoVXJsLnNlYXJjaFBhcmFtcy5zZXQoXCJtZVwiLCAgICAgICAgICAgICAgICAgICBzaXRlVXJsKTtcblxuICAgIHdpbmRvdy5vcGVuKGF1dGhVcmwudG9TdHJpbmcoKSk7XG5cbiAgICAvLyA1LiBXYWl0IGZvciBvYnNpZGlhbjovL21pY3JvcHViLWF1dGggdG8gYmUgY2FsbGVkXG4gICAgY29uc3QgY2FsbGJhY2tQYXJhbXMgPSBhd2FpdCBjYWxsYmFja1Byb21pc2U7XG5cbiAgICAvLyA2LiBWYWxpZGF0ZSBzdGF0ZSAoQ1NSRiBwcm90ZWN0aW9uKVxuICAgIGlmIChjYWxsYmFja1BhcmFtcy5zdGF0ZSAhPT0gc3RhdGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN0YXRlIG1pc21hdGNoIFx1MjAxNCBwb3NzaWJsZSBDU1JGIGF0dGFjay4gUGxlYXNlIHRyeSBhZ2Fpbi5cIik7XG4gICAgfVxuXG4gICAgY29uc3QgY29kZSA9IGNhbGxiYWNrUGFyYW1zLmNvZGU7XG4gICAgaWYgKCFjb2RlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGNhbGxiYWNrUGFyYW1zLmVycm9yX2Rlc2NyaXB0aW9uID8/XG4gICAgICAgIGNhbGxiYWNrUGFyYW1zLmVycm9yID8/XG4gICAgICAgIFwiTm8gYXV0aG9yaXphdGlvbiBjb2RlIHJlY2VpdmVkLlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyA3LiBFeGNoYW5nZSBjb2RlIGZvciB0b2tlblxuICAgIGNvbnN0IHRva2VuUmVzcCA9IGF3YWl0IHJlcXVlc3RVcmwoe1xuICAgICAgdXJsOiB0b2tlbkVuZHBvaW50LFxuICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRcIixcbiAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIH0sXG4gICAgICBib2R5OiBuZXcgVVJMU2VhcmNoUGFyYW1zKHtcbiAgICAgICAgZ3JhbnRfdHlwZTogICAgXCJhdXRob3JpemF0aW9uX2NvZGVcIixcbiAgICAgICAgY29kZSxcbiAgICAgICAgY2xpZW50X2lkOiAgICAgQ0xJRU5UX0lELFxuICAgICAgICByZWRpcmVjdF91cmk6ICBSRURJUkVDVF9VUkksXG4gICAgICAgIGNvZGVfdmVyaWZpZXI6IGNvZGVWZXJpZmllcixcbiAgICAgIH0pLnRvU3RyaW5nKCksXG4gICAgICB0aHJvdzogZmFsc2UsXG4gICAgfSk7XG5cbiAgICBjb25zdCBkYXRhID0gdG9rZW5SZXNwLmpzb24gYXMge1xuICAgICAgYWNjZXNzX3Rva2VuPzogc3RyaW5nO1xuICAgICAgc2NvcGU/OiBzdHJpbmc7XG4gICAgICBtZT86IHN0cmluZztcbiAgICAgIGVycm9yPzogc3RyaW5nO1xuICAgICAgZXJyb3JfZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAgfTtcblxuICAgIGlmICghZGF0YS5hY2Nlc3NfdG9rZW4pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgZGF0YS5lcnJvcl9kZXNjcmlwdGlvbiA/P1xuICAgICAgICBkYXRhLmVycm9yID8/XG4gICAgICAgIGBUb2tlbiBleGNoYW5nZSBmYWlsZWQgKEhUVFAgJHt0b2tlblJlc3Auc3RhdHVzfSlgLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzVG9rZW46ICAgICAgICAgICBkYXRhLmFjY2Vzc190b2tlbixcbiAgICAgIHNjb3BlOiAgICAgICAgICAgICAgICAgZGF0YS5zY29wZSA/PyBTQ09QRSxcbiAgICAgIG1lOiAgICAgICAgICAgICAgICAgICAgZGF0YS5tZSA/PyBzaXRlVXJsLFxuICAgICAgYXV0aG9yaXphdGlvbkVuZHBvaW50LFxuICAgICAgdG9rZW5FbmRwb2ludCxcbiAgICAgIG1pY3JvcHViRW5kcG9pbnQsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFx1MjUwMFx1MjUwMCBIZWxwZXJzIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIHByaXZhdGUgc3RhdGljIGJhc2U2NHVybChidWY6IEJ1ZmZlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGJ1Zi50b1N0cmluZyhcImJhc2U2NFwiKVxuICAgICAgLnJlcGxhY2UoL1xcKy9nLCBcIi1cIilcbiAgICAgIC5yZXBsYWNlKC9cXC8vZywgXCJfXCIpXG4gICAgICAucmVwbGFjZSgvPS9nLCBcIlwiKTtcbiAgfVxuXG4gIHN0YXRpYyBleHRyYWN0TGlua1JlbChodG1sOiBzdHJpbmcsIHJlbDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCByZSA9IG5ldyBSZWdFeHAoXG4gICAgICBgPGxpbmtbXj5dK3JlbD1bXCInXVteXCInXSpcXFxcYiR7cmVsfVxcXFxiW15cIiddKltcIiddW14+XStocmVmPVtcIiddKFteXCInXSspW1wiJ11gICtcbiAgICAgIGB8PGxpbmtbXj5dK2hyZWY9W1wiJ10oW15cIiddKylbXCInXVtePl0rcmVsPVtcIiddW15cIiddKlxcXFxiJHtyZWx9XFxcXGJbXlwiJ10qW1wiJ11gLFxuICAgICAgXCJpXCIsXG4gICAgKTtcbiAgICBjb25zdCBtID0gaHRtbC5tYXRjaChyZSk7XG4gICAgcmV0dXJuIG0/LlsxXSA/PyBtPy5bMl07XG4gIH1cbn1cbiIsICIvKipcbiAqIFB1Ymxpc2hlci50c1xuICpcbiAqIE9yY2hlc3RyYXRlcyBhIGZ1bGwgcHVibGlzaCBmbG93OlxuICogICAxLiBQYXJzZSB0aGUgYWN0aXZlIG5vdGUncyBmcm9udG1hdHRlciArIGJvZHlcbiAqICAgMi4gVXBsb2FkIGFueSBsb2NhbCBpbWFnZXMgdG8gdGhlIG1lZGlhIGVuZHBvaW50XG4gKiAgIDMuIEJ1aWxkIHRoZSBNaWNyb3B1YiBwcm9wZXJ0aWVzIG9iamVjdFxuICogICA0LiBQT1NUIHRvIHRoZSBNaWNyb3B1YiBlbmRwb2ludFxuICogICA1LiBPcHRpb25hbGx5IHdyaXRlIHRoZSByZXR1cm5lZCBVUkwgYmFjayB0byBmcm9udG1hdHRlclxuICpcbiAqIEdhcmRlbiB0YWcgbWFwcGluZzpcbiAqICAgT2JzaWRpYW4gdGFncyAjZ2FyZGVuL3BsYW50IFx1MjE5MiBnYXJkZW5TdGFnZTogXCJwbGFudFwiIGluIHByb3BlcnRpZXNcbiAqICAgVGhlIGJsb2cgcmVhZHMgdGhpcyBhcyBgZ2FyZGVuU3RhZ2VgIGZyb250bWF0dGVyLCBzbyB0aGUgSW5kaWVraXRcbiAqICAgTWljcm9wdWIgc2VydmVyIG11c3QgYmUgY29uZmlndXJlZCB0byBwYXNzIHRocm91Z2ggdW5rbm93biBwcm9wZXJ0aWVzLlxuICovXG5cbmltcG9ydCB7IEFwcCwgVEZpbGUsIHBhcnNlRnJvbnRNYXR0ZXJBbGlhc2VzLCBwYXJzZVlhbWwsIHN0cmluZ2lmeVlhbWwgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB0eXBlIHsgTWljcm9wdWJTZXR0aW5ncywgR2FyZGVuU3RhZ2UsIFB1Ymxpc2hSZXN1bHQgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgTWljcm9wdWJDbGllbnQgfSBmcm9tIFwiLi9NaWNyb3B1YkNsaWVudFwiO1xuXG5jb25zdCBHQVJERU5fVEFHX1BSRUZJWCA9IFwiZ2FyZGVuL1wiO1xuXG5leHBvcnQgY2xhc3MgUHVibGlzaGVyIHtcbiAgcHJpdmF0ZSBjbGllbnQ6IE1pY3JvcHViQ2xpZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXBwOiBBcHAsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzZXR0aW5nczogTWljcm9wdWJTZXR0aW5ncyxcbiAgKSB7XG4gICAgdGhpcy5jbGllbnQgPSBuZXcgTWljcm9wdWJDbGllbnQoXG4gICAgICAoKSA9PiBzZXR0aW5ncy5taWNyb3B1YkVuZHBvaW50LFxuICAgICAgKCkgPT4gc2V0dGluZ3MubWVkaWFFbmRwb2ludCxcbiAgICAgICgpID0+IHNldHRpbmdzLmFjY2Vzc1Rva2VuLFxuICAgICk7XG4gIH1cblxuICAvKiogUHVibGlzaCB0aGUgZ2l2ZW4gZmlsZS4gUmV0dXJucyBQdWJsaXNoUmVzdWx0LiAqL1xuICBhc3luYyBwdWJsaXNoKGZpbGU6IFRGaWxlKTogUHJvbWlzZTxQdWJsaXNoUmVzdWx0PiB7XG4gICAgY29uc3QgcmF3ID0gYXdhaXQgdGhpcy5hcHAudmF1bHQucmVhZChmaWxlKTtcbiAgICBjb25zdCB7IGZyb250bWF0dGVyLCBib2R5IH0gPSB0aGlzLnBhcnNlRnJvbnRtYXR0ZXIocmF3KTtcblxuICAgIC8vIERldGVybWluZSBpZiB0aGlzIGlzIGFuIHVwZGF0ZSAocG9zdCBhbHJlYWR5IGhhcyBhIFVSTCkgb3IgbmV3IHBvc3RcbiAgICBjb25zdCBleGlzdGluZ1VybDogc3RyaW5nIHwgdW5kZWZpbmVkID1cbiAgICAgIGZyb250bWF0dGVyW1wibXAtdXJsXCJdID8/IGZyb250bWF0dGVyW1widXJsXCJdID8/IHVuZGVmaW5lZDtcblxuICAgIC8vIFVwbG9hZCBsb2NhbCBpbWFnZXMgYW5kIHJld3JpdGUgbWFya2Rvd24gcmVmZXJlbmNlc1xuICAgIGNvbnN0IHsgY29udGVudDogcHJvY2Vzc2VkQm9keSwgdXBsb2FkZWRVcmxzIH0gPVxuICAgICAgYXdhaXQgdGhpcy5wcm9jZXNzSW1hZ2VzKGJvZHkpO1xuXG4gICAgLy8gQnVpbGQgTWljcm9wdWIgcHJvcGVydGllc1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSB0aGlzLmJ1aWxkUHJvcGVydGllcyhmcm9udG1hdHRlciwgcHJvY2Vzc2VkQm9keSwgdXBsb2FkZWRVcmxzKTtcblxuICAgIGxldCByZXN1bHQ6IFB1Ymxpc2hSZXN1bHQ7XG5cbiAgICBpZiAoZXhpc3RpbmdVcmwpIHtcbiAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBwb3N0XG4gICAgICBjb25zdCByZXBsYWNlOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duW10+ID0ge307XG4gICAgICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhwcm9wZXJ0aWVzKSkge1xuICAgICAgICByZXBsYWNlW2tdID0gQXJyYXkuaXNBcnJheSh2KSA/IHYgOiBbdl07XG4gICAgICB9XG4gICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmNsaWVudC51cGRhdGVQb3N0KGV4aXN0aW5nVXJsLCByZXBsYWNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ3JlYXRlIG5ldyBwb3N0XG4gICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmNsaWVudC5jcmVhdGVQb3N0KHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIC8vIFdyaXRlIFVSTCBiYWNrIHRvIGZyb250bWF0dGVyXG4gICAgaWYgKHJlc3VsdC5zdWNjZXNzICYmIHJlc3VsdC51cmwgJiYgdGhpcy5zZXR0aW5ncy53cml0ZVVybFRvRnJvbnRtYXR0ZXIpIHtcbiAgICAgIGF3YWl0IHRoaXMud3JpdGVVcmxUb05vdGUoZmlsZSwgcmF3LCByZXN1bHQudXJsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gXHUyNTAwXHUyNTAwIFByb3BlcnR5IGJ1aWxkZXIgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgcHJpdmF0ZSBidWlsZFByb3BlcnRpZXMoXG4gICAgZm06IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIGJvZHk6IHN0cmluZyxcbiAgICB1cGxvYWRlZFVybHM6IHN0cmluZ1tdLFxuICApOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgY29uc3QgcHJvcHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgICAvLyBcdTI1MDBcdTI1MDAgUG9zdCB0eXBlIGRldGVjdGlvbiBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcdTI1MDBcbiAgICAvLyBJbnRlcmFjdGlvbiBwb3N0cyAoYm9va21hcmssIGxpa2UsIHJlcGx5LCByZXBvc3QpIGhhdmUgbm8gYm9keSBjb250ZW50LlxuICAgIC8vIEZvciB0aG9zZSwgb25seSBpbmNsdWRlIGNvbnRlbnQgaWYgdGhlIG5vdGUgYm9keSBpcyBub24tZW1wdHkgKGkuZS4gYSBjb21tZW50L3F1b3RlKS5cbiAgICBjb25zdCB0cmltbWVkQm9keSA9IGJvZHkudHJpbSgpO1xuXG4gICAgLy8gXHUyNTAwXHUyNTAwIEludGVyYWN0aW9uIFVSTCBwcm9wZXJ0aWVzIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuICAgIC8vIFN1cHBvcnQgYm90aCBjYW1lbENhc2UgKE9ic2lkaWFuLWZyaWVuZGx5KSBhbmQgaHlwaGVuYXRlZCAoTWljcm9wdWItc3BlYykuXG4gICAgY29uc3QgYm9va21hcmtPZiA9IGZtW1wiYm9va21hcmtPZlwiXSA/PyBmbVtcImJvb2ttYXJrLW9mXCJdO1xuICAgIGNvbnN0IGxpa2VPZiAgICAgPSBmbVtcImxpa2VPZlwiXSAgICAgPz8gZm1bXCJsaWtlLW9mXCJdO1xuICAgIGNvbnN0IGluUmVwbHlUbyAgPSBmbVtcImluUmVwbHlUb1wiXSAgPz8gZm1bXCJpbi1yZXBseS10b1wiXTtcbiAgICBjb25zdCByZXBvc3RPZiAgID0gZm1bXCJyZXBvc3RPZlwiXSAgID8/IGZtW1wicmVwb3N0LW9mXCJdO1xuXG4gICAgaWYgKGJvb2ttYXJrT2YpIHByb3BzW1wiYm9va21hcmstb2ZcIl0gPSBbU3RyaW5nKGJvb2ttYXJrT2YpXTtcbiAgICBpZiAobGlrZU9mKSAgICAgcHJvcHNbXCJsaWtlLW9mXCJdICAgICA9IFtTdHJpbmcobGlrZU9mKV07XG4gICAgaWYgKGluUmVwbHlUbykgIHByb3BzW1wiaW4tcmVwbHktdG9cIl0gPSBbU3RyaW5nKGluUmVwbHlUbyldO1xuICAgIGlmIChyZXBvc3RPZikgICBwcm9wc1tcInJlcG9zdC1vZlwiXSAgID0gW1N0cmluZyhyZXBvc3RPZildO1xuXG4gICAgLy8gQ29udGVudCBcdTIwMTQgb21pdCBmb3IgYmFyZSBsaWtlcy9yZXBvc3RzIHdpdGggbm8gYm9keSB0ZXh0XG4gICAgY29uc3QgaXNJbnRlcmFjdGlvbldpdGhvdXRCb2R5ID1cbiAgICAgIChsaWtlT2YgfHwgcmVwb3N0T2YpICYmICF0cmltbWVkQm9keTtcbiAgICBpZiAoIWlzSW50ZXJhY3Rpb25XaXRob3V0Qm9keSkge1xuICAgICAgcHJvcHNbXCJjb250ZW50XCJdID0gdHJpbW1lZEJvZHkgPyBbeyBodG1sOiB0cmltbWVkQm9keSB9XSA6IFt7IGh0bWw6IFwiXCIgfV07XG4gICAgfVxuXG4gICAgLy8gXHUyNTAwXHUyNTAwIFN0YW5kYXJkIHByb3BlcnRpZXMgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgICAvLyBUaXRsZSAoYXJ0aWNsZXMgaGF2ZSB0aXRsZXM7IG5vdGVzL21pY3JvLXBvc3RzIGRvbid0KVxuICAgIGlmIChmbVtcInRpdGxlXCJdKSB7XG4gICAgICBwcm9wc1tcIm5hbWVcIl0gPSBbU3RyaW5nKGZtW1widGl0bGVcIl0pXTtcbiAgICB9XG5cbiAgICAvLyBTdW1tYXJ5IC8gZXhjZXJwdFxuICAgIGlmIChmbVtcInN1bW1hcnlcIl0gPz8gZm1bXCJleGNlcnB0XCJdKSB7XG4gICAgICBwcm9wc1tcInN1bW1hcnlcIl0gPSBbU3RyaW5nKGZtW1wic3VtbWFyeVwiXSA/PyBmbVtcImV4Y2VycHRcIl0pXTtcbiAgICB9XG5cbiAgICAvLyBQdWJsaXNoZWQgZGF0ZSBcdTIwMTQgcHJlZmVyIGBjcmVhdGVkYCAoT2JzaWRpYW4gZGVmYXVsdCksIGZhbGwgYmFjayB0byBgZGF0ZWBcbiAgICBjb25zdCByYXdEYXRlID0gZm1bXCJjcmVhdGVkXCJdID8/IGZtW1wiZGF0ZVwiXTtcbiAgICBpZiAocmF3RGF0ZSkge1xuICAgICAgcHJvcHNbXCJwdWJsaXNoZWRcIl0gPSBbbmV3IERhdGUoU3RyaW5nKHJhd0RhdGUpKS50b0lTT1N0cmluZygpXTtcbiAgICB9XG5cbiAgICAvLyBDYXRlZ29yaWVzIGZyb20gZnJvbnRtYXR0ZXIgYGNhdGVnb3J5YCBvciBgdGFnc2AgKGV4Y2x1ZGluZyBnYXJkZW4vKiB0YWdzKVxuICAgIGNvbnN0IHJhd1RhZ3MgPSB0aGlzLnJlc29sdmVBcnJheShmbVtcInRhZ3NcIl0gPz8gZm1bXCJjYXRlZ29yeVwiXSk7XG4gICAgY29uc3QgZ2FyZGVuU3RhZ2UgPSB0aGlzLmV4dHJhY3RHYXJkZW5TdGFnZShyYXdUYWdzKTtcbiAgICBjb25zdCBub3JtYWxUYWdzID0gcmF3VGFncy5maWx0ZXIoXG4gICAgICAodCkgPT4gIXQuc3RhcnRzV2l0aChHQVJERU5fVEFHX1BSRUZJWCkgJiYgdCAhPT0gXCJnYXJkZW5cIixcbiAgICApO1xuICAgIGlmIChub3JtYWxUYWdzLmxlbmd0aCA+IDApIHtcbiAgICAgIHByb3BzW1wiY2F0ZWdvcnlcIl0gPSBub3JtYWxUYWdzO1xuICAgIH1cblxuICAgIC8vIEdhcmRlbiBzdGFnZSBcdTIxOTIgZGVkaWNhdGVkIHByb3BlcnR5XG4gICAgaWYgKHRoaXMuc2V0dGluZ3MubWFwR2FyZGVuVGFncyAmJiBnYXJkZW5TdGFnZSkge1xuICAgICAgcHJvcHNbXCJnYXJkZW4tc3RhZ2VcIl0gPSBbZ2FyZGVuU3RhZ2VdO1xuICAgIH1cblxuICAgIC8vIFN5bmRpY2F0aW9uIHRhcmdldHNcbiAgICAvLyBTdXBwb3J0IGJvdGggY2FtZWxDYXNlIChtcFN5bmRpY2F0ZVRvKSB1c2VkIGluIGV4aXN0aW5nIGJsb2cgcG9zdHMgYW5kIG1wLXN5bmRpY2F0ZS10b1xuICAgIGNvbnN0IHN5bmRpY2F0ZVRvID0gdGhpcy5yZXNvbHZlQXJyYXkoXG4gICAgICBmbVtcIm1wLXN5bmRpY2F0ZS10b1wiXSA/PyBmbVtcIm1wU3luZGljYXRlVG9cIl0sXG4gICAgKTtcbiAgICBjb25zdCBhbGxTeW5kaWNhdGVUbyA9IFtcbiAgICAgIC4uLm5ldyBTZXQoWy4uLnRoaXMuc2V0dGluZ3MuZGVmYXVsdFN5bmRpY2F0ZVRvLCAuLi5zeW5kaWNhdGVUb10pLFxuICAgIF07XG4gICAgaWYgKGFsbFN5bmRpY2F0ZVRvLmxlbmd0aCA+IDApIHtcbiAgICAgIHByb3BzW1wibXAtc3luZGljYXRlLXRvXCJdID0gYWxsU3luZGljYXRlVG87XG4gICAgfVxuXG4gICAgLy8gVmlzaWJpbGl0eVxuICAgIGNvbnN0IHZpc2liaWxpdHkgPVxuICAgICAgKGZtW1widmlzaWJpbGl0eVwiXSBhcyBzdHJpbmcpID8/IHRoaXMuc2V0dGluZ3MuZGVmYXVsdFZpc2liaWxpdHk7XG4gICAgaWYgKHZpc2liaWxpdHkgJiYgdmlzaWJpbGl0eSAhPT0gXCJwdWJsaWNcIikge1xuICAgICAgcHJvcHNbXCJ2aXNpYmlsaXR5XCJdID0gW3Zpc2liaWxpdHldO1xuICAgIH1cblxuICAgIC8vIEFJIGRpc2Nsb3N1cmUgKGN1c3RvbSBwcm9wZXJ0eSBwYXNzZWQgdGhyb3VnaCB0byBJbmRpZWtpdClcbiAgICBpZiAoZm1bXCJhaVwiXSAmJiB0eXBlb2YgZm1bXCJhaVwiXSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcHJvcHNbXCJhaVwiXSA9IFtmbVtcImFpXCJdXTtcbiAgICB9XG5cbiAgICAvLyBQaG90b3M6IHByZWZlciBzdHJ1Y3R1cmVkIHBob3RvIGFycmF5IGZyb20gZnJvbnRtYXR0ZXIgKHdpdGggYWx0IHRleHQpLFxuICAgIC8vIGZhbGwgYmFjayB0byB1cGxvYWRlZCBsb2NhbCBpbWFnZXMuXG4gICAgY29uc3QgZm1QaG90b3MgPSB0aGlzLnJlc29sdmVQaG90b0FycmF5KGZtW1wicGhvdG9cIl0pO1xuICAgIGlmIChmbVBob3Rvcy5sZW5ndGggPiAwKSB7XG4gICAgICBwcm9wc1tcInBob3RvXCJdID0gZm1QaG90b3M7XG4gICAgfSBlbHNlIGlmICh1cGxvYWRlZFVybHMubGVuZ3RoID4gMCkge1xuICAgICAgcHJvcHNbXCJwaG90b1wiXSA9IHVwbG9hZGVkVXJscy5tYXAoKHVybCkgPT4gKHsgdmFsdWU6IHVybCB9KSk7XG4gICAgfVxuXG4gICAgLy8gUGFzcyB0aHJvdWdoIGFueSBgbXAtKmAgcHJvcGVydGllcyBmcm9tIGZyb250bWF0dGVyIHZlcmJhdGltXG4gICAgZm9yIChjb25zdCBbaywgdl0gb2YgT2JqZWN0LmVudHJpZXMoZm0pKSB7XG4gICAgICBpZiAoay5zdGFydHNXaXRoKFwibXAtXCIpICYmIGsgIT09IFwibXAtdXJsXCIgJiYgayAhPT0gXCJtcC1zeW5kaWNhdGUtdG9cIikge1xuICAgICAgICBwcm9wc1trXSA9IHRoaXMucmVzb2x2ZUFycmF5KHYpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9wcztcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpc2UgdGhlIGBwaG90b2AgZnJvbnRtYXR0ZXIgZmllbGQgaW50byBNaWNyb3B1YiBwaG90byBvYmplY3RzLlxuICAgKiBIYW5kbGVzIHRocmVlIGZvcm1hdHM6XG4gICAqICAgLSBzdHJpbmcgVVJMOiBcImh0dHBzOi8vLi4uXCJcbiAgICogICAtIGFycmF5IG9mIHN0cmluZ3M6IFtcImh0dHBzOi8vLi4uXCJdXG4gICAqICAgLSBhcnJheSBvZiBvYmplY3RzOiBbe3VybDogXCJodHRwczovLy4uLlwiLCBhbHQ6IFwiLi4uXCJ9XVxuICAgKi9cbiAgcHJpdmF0ZSByZXNvbHZlUGhvdG9BcnJheShcbiAgICB2YWx1ZTogdW5rbm93bixcbiAgKTogQXJyYXk8eyB2YWx1ZTogc3RyaW5nOyBhbHQ/OiBzdHJpbmcgfT4ge1xuICAgIGlmICghdmFsdWUpIHJldHVybiBbXTtcbiAgICBjb25zdCBpdGVtcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdO1xuICAgIHJldHVybiBpdGVtc1xuICAgICAgLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIGl0ZW0gPT09IFwic3RyaW5nXCIpIHJldHVybiB7IHZhbHVlOiBpdGVtIH07XG4gICAgICAgIGlmICh0eXBlb2YgaXRlbSA9PT0gXCJvYmplY3RcIiAmJiBpdGVtICE9PSBudWxsKSB7XG4gICAgICAgICAgY29uc3Qgb2JqID0gaXRlbSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICBjb25zdCB1cmwgPSBTdHJpbmcob2JqW1widXJsXCJdID8/IG9ialtcInZhbHVlXCJdID8/IFwiXCIpO1xuICAgICAgICAgIGlmICghdXJsKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICByZXR1cm4gb2JqW1wiYWx0XCJdXG4gICAgICAgICAgICA/IHsgdmFsdWU6IHVybCwgYWx0OiBTdHJpbmcob2JqW1wiYWx0XCJdKSB9XG4gICAgICAgICAgICA6IHsgdmFsdWU6IHVybCB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKHgpOiB4IGlzIHsgdmFsdWU6IHN0cmluZzsgYWx0Pzogc3RyaW5nIH0gPT4geCAhPT0gbnVsbCk7XG4gIH1cblxuICAvLyBcdTI1MDBcdTI1MDAgR2FyZGVuIHRhZyBleHRyYWN0aW9uIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIC8qKlxuICAgKiBGaW5kIHRoZSBmaXJzdCAjZ2FyZGVuLzxzdGFnZT4gdGFnIGFuZCByZXR1cm4gdGhlIHN0YWdlIG5hbWUuXG4gICAqIFN1cHBvcnRzIGJvdGggXCJnYXJkZW4vcGxhbnRcIiAoT2JzaWRpYW4gYXJyYXkpIGFuZCBcIiNnYXJkZW4vcGxhbnRcIiAoaW5saW5lKS5cbiAgICovXG4gIHByaXZhdGUgZXh0cmFjdEdhcmRlblN0YWdlKHRhZ3M6IHN0cmluZ1tdKTogR2FyZGVuU3RhZ2UgfCB1bmRlZmluZWQge1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGNvbnN0IGNsZWFuID0gdGFnLnJlcGxhY2UoL14jLywgXCJcIik7XG4gICAgICBpZiAoY2xlYW4uc3RhcnRzV2l0aChHQVJERU5fVEFHX1BSRUZJWCkpIHtcbiAgICAgICAgY29uc3Qgc3RhZ2UgPSBjbGVhbi5zbGljZShHQVJERU5fVEFHX1BSRUZJWC5sZW5ndGgpIGFzIEdhcmRlblN0YWdlO1xuICAgICAgICBjb25zdCB2YWxpZDogR2FyZGVuU3RhZ2VbXSA9IFtcbiAgICAgICAgICBcInBsYW50XCIsIFwiY3VsdGl2YXRlXCIsIFwicXVlc3Rpb25cIiwgXCJyZXBvdFwiLCBcInJldml0YWxpemVcIiwgXCJyZXZpc2l0XCIsXG4gICAgICAgIF07XG4gICAgICAgIGlmICh2YWxpZC5pbmNsdWRlcyhzdGFnZSkpIHJldHVybiBzdGFnZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIFx1MjUwMFx1MjUwMCBJbWFnZSBwcm9jZXNzaW5nIFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFx1MjUwMFxuXG4gIC8qKlxuICAgKiBGaW5kIGFsbCBgIVtbbG9jYWwtaW1hZ2UucG5nXV1gIG9yIGAhW2FsdF0ocmVsYXRpdmUvcGF0aC5qcGcpYCBpbiB0aGUgYm9keSxcbiAgICogdXBsb2FkIHRoZW0gdG8gdGhlIG1lZGlhIGVuZHBvaW50LCBhbmQgcmVwbGFjZSB0aGUgcmVmZXJlbmNlcyB3aXRoIHJlbW90ZSBVUkxzLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzSW1hZ2VzKFxuICAgIGJvZHk6IHN0cmluZyxcbiAgKTogUHJvbWlzZTx7IGNvbnRlbnQ6IHN0cmluZzsgdXBsb2FkZWRVcmxzOiBzdHJpbmdbXSB9PiB7XG4gICAgY29uc3QgdXBsb2FkZWRVcmxzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gTWF0Y2ggd2lraS1zdHlsZSBlbWJlZHM6ICFbW2ZpbGVuYW1lLmV4dF1dXG4gICAgY29uc3Qgd2lraVBhdHRlcm4gPSAvIVxcW1xcWyhbXlxcXV0rXFwuKHBuZ3xqcGd8anBlZ3xnaWZ8d2VicHxzdmcpKVxcXVxcXS9naTtcbiAgICAvLyBNYXRjaCBtYXJrZG93biBpbWFnZXM6ICFbYWx0XShwYXRoKVxuICAgIGNvbnN0IG1kUGF0dGVybiA9IC8hXFxbKFteXFxdXSopXFxdXFwoKFteKV0rXFwuKHBuZ3xqcGd8anBlZ3xnaWZ8d2VicHxzdmcpKVxcKS9naTtcblxuICAgIGxldCBjb250ZW50ID0gYm9keTtcblxuICAgIC8vIFByb2Nlc3Mgd2lraS1zdHlsZSBlbWJlZHNcbiAgICBjb25zdCB3aWtpTWF0Y2hlcyA9IFsuLi5ib2R5Lm1hdGNoQWxsKHdpa2lQYXR0ZXJuKV07XG4gICAgZm9yIChjb25zdCBtYXRjaCBvZiB3aWtpTWF0Y2hlcykge1xuICAgICAgY29uc3QgZmlsZW5hbWUgPSBtYXRjaFsxXTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlbW90ZVVybCA9IGF3YWl0IHRoaXMudXBsb2FkTG9jYWxGaWxlKGZpbGVuYW1lKTtcbiAgICAgICAgaWYgKHJlbW90ZVVybCkge1xuICAgICAgICAgIHVwbG9hZGVkVXJscy5wdXNoKHJlbW90ZVVybCk7XG4gICAgICAgICAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZShtYXRjaFswXSwgYCFbJHtmaWxlbmFtZX1dKCR7cmVtb3RlVXJsfSlgKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW21pY3JvcHViXSBGYWlsZWQgdG8gdXBsb2FkICR7ZmlsZW5hbWV9OmAsIGVycik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUHJvY2VzcyBtYXJrZG93biBpbWFnZSByZWZlcmVuY2VzXG4gICAgY29uc3QgbWRNYXRjaGVzID0gWy4uLmNvbnRlbnQubWF0Y2hBbGwobWRQYXR0ZXJuKV07XG4gICAgZm9yIChjb25zdCBtYXRjaCBvZiBtZE1hdGNoZXMpIHtcbiAgICAgIGNvbnN0IGFsdCA9IG1hdGNoWzFdO1xuICAgICAgY29uc3QgcGF0aCA9IG1hdGNoWzJdO1xuICAgICAgaWYgKHBhdGguc3RhcnRzV2l0aChcImh0dHBcIikpIGNvbnRpbnVlOyAvLyBhbHJlYWR5IHJlbW90ZVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVtb3RlVXJsID0gYXdhaXQgdGhpcy51cGxvYWRMb2NhbEZpbGUocGF0aCk7XG4gICAgICAgIGlmIChyZW1vdGVVcmwpIHtcbiAgICAgICAgICB1cGxvYWRlZFVybHMucHVzaChyZW1vdGVVcmwpO1xuICAgICAgICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UobWF0Y2hbMF0sIGAhWyR7YWx0fV0oJHtyZW1vdGVVcmx9KWApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbbWljcm9wdWJdIEZhaWxlZCB0byB1cGxvYWQgJHtwYXRofTpgLCBlcnIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IGNvbnRlbnQsIHVwbG9hZGVkVXJscyB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB1cGxvYWRMb2NhbEZpbGUocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCBmaWxlID0gdGhpcy5hcHAudmF1bHQuZ2V0RmlsZXMoKS5maW5kKFxuICAgICAgKGYpID0+IGYubmFtZSA9PT0gcGF0aCB8fCBmLnBhdGggPT09IHBhdGgsXG4gICAgKTtcbiAgICBpZiAoIWZpbGUpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBidWZmZXIgPSBhd2FpdCB0aGlzLmFwcC52YXVsdC5yZWFkQmluYXJ5KGZpbGUpO1xuICAgIGNvbnN0IG1pbWVUeXBlID0gdGhpcy5ndWVzc01pbWVUeXBlKGZpbGUuZXh0ZW5zaW9uKTtcblxuICAgIHJldHVybiB0aGlzLmNsaWVudC51cGxvYWRNZWRpYShidWZmZXIsIGZpbGUubmFtZSwgbWltZVR5cGUpO1xuICB9XG5cbiAgLy8gXHUyNTAwXHUyNTAwIEZyb250bWF0dGVyIGhlbHBlcnMgXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXHUyNTAwXG5cbiAgcHJpdmF0ZSBwYXJzZUZyb250bWF0dGVyKHJhdzogc3RyaW5nKToge1xuICAgIGZyb250bWF0dGVyOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBib2R5OiBzdHJpbmc7XG4gIH0ge1xuICAgIGNvbnN0IGZtTWF0Y2ggPSByYXcubWF0Y2goL14tLS1cXHI/XFxuKFtcXHNcXFNdKj8pXFxyP1xcbi0tLVxccj9cXG4oW1xcc1xcU10qKSQvKTtcbiAgICBpZiAoIWZtTWF0Y2gpIHJldHVybiB7IGZyb250bWF0dGVyOiB7fSwgYm9keTogcmF3IH07XG5cbiAgICBsZXQgZnJvbnRtYXR0ZXI6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgdHJ5IHtcbiAgICAgIGZyb250bWF0dGVyID0gKHBhcnNlWWFtbChmbU1hdGNoWzFdKSA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBNYWxmb3JtZWQgZnJvbnRtYXR0ZXIgXHUyMDE0IHRyZWF0IGFzIGVtcHR5XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZnJvbnRtYXR0ZXIsIGJvZHk6IGZtTWF0Y2hbMl0gfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd3JpdGVVcmxUb05vdGUoXG4gICAgZmlsZTogVEZpbGUsXG4gICAgb3JpZ2luYWxDb250ZW50OiBzdHJpbmcsXG4gICAgdXJsOiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGZtTWF0Y2ggPSBvcmlnaW5hbENvbnRlbnQubWF0Y2goXG4gICAgICAvXigtLS1cXHI/XFxuW1xcc1xcU10qP1xccj9cXG4tLS1cXHI/XFxuKShbXFxzXFxTXSopJC8sXG4gICAgKTtcblxuICAgIGlmICghZm1NYXRjaCkge1xuICAgICAgLy8gTm8gZXhpc3RpbmcgZnJvbnRtYXR0ZXIgXHUyMDE0IHByZXBlbmQgaXRcbiAgICAgIGNvbnN0IG5ld0ZtID0gYC0tLVxcbm1wLXVybDogXCIke3VybH1cIlxcbi0tLVxcbmA7XG4gICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoZmlsZSwgbmV3Rm0gKyBvcmlnaW5hbENvbnRlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEluamVjdCBtcC11cmwgaW50byBleGlzdGluZyBmcm9udG1hdHRlciBibG9ja1xuICAgIGNvbnN0IGZtQmxvY2sgPSBmbU1hdGNoWzFdO1xuICAgIGNvbnN0IGJvZHkgPSBmbU1hdGNoWzJdO1xuXG4gICAgaWYgKGZtQmxvY2suaW5jbHVkZXMoXCJtcC11cmw6XCIpKSB7XG4gICAgICAvLyBSZXBsYWNlIGV4aXN0aW5nIG1wLXVybCBsaW5lXG4gICAgICBjb25zdCB1cGRhdGVkID0gZm1CbG9jay5yZXBsYWNlKFxuICAgICAgICAvbXAtdXJsOi4qKFxccj9cXG4pLyxcbiAgICAgICAgYG1wLXVybDogXCIke3VybH1cIiQxYCxcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoZmlsZSwgdXBkYXRlZCArIGJvZHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJbnNlcnQgbXAtdXJsIGJlZm9yZSBjbG9zaW5nIC0tLVxuICAgICAgY29uc3QgdXBkYXRlZCA9IGZtQmxvY2sucmVwbGFjZShcbiAgICAgICAgLyhcXHI/XFxuLS0tXFxyP1xcbikkLyxcbiAgICAgICAgYFxcbm1wLXVybDogXCIke3VybH1cIiQxYCxcbiAgICAgICk7XG4gICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoZmlsZSwgdXBkYXRlZCArIGJvZHkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVzb2x2ZUFycmF5KHZhbHVlOiB1bmtub3duKTogc3RyaW5nW10ge1xuICAgIGlmICghdmFsdWUpIHJldHVybiBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiB2YWx1ZS5tYXAoU3RyaW5nKTtcbiAgICByZXR1cm4gW1N0cmluZyh2YWx1ZSldO1xuICB9XG5cbiAgcHJpdmF0ZSBndWVzc01pbWVUeXBlKGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICBwbmc6IFwiaW1hZ2UvcG5nXCIsXG4gICAgICBqcGc6IFwiaW1hZ2UvanBlZ1wiLFxuICAgICAganBlZzogXCJpbWFnZS9qcGVnXCIsXG4gICAgICBnaWY6IFwiaW1hZ2UvZ2lmXCIsXG4gICAgICB3ZWJwOiBcImltYWdlL3dlYnBcIixcbiAgICAgIHN2ZzogXCJpbWFnZS9zdmcreG1sXCIsXG4gICAgfTtcbiAgICByZXR1cm4gbWFwW2V4dC50b0xvd2VyQ2FzZSgpXSA/PyBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFpQkEsSUFBQUEsbUJBQXNDOzs7QUN1RC9CLElBQU0sbUJBQXFDO0FBQUEsRUFDaEQsa0JBQWtCO0FBQUEsRUFDbEIsZUFBZTtBQUFBLEVBQ2YsYUFBYTtBQUFBLEVBQ2Isb0JBQW9CLENBQUM7QUFBQSxFQUNyQixjQUFjO0FBQUEsRUFDZCxTQUFTO0FBQUEsRUFDVCx1QkFBdUI7QUFBQSxFQUN2QixlQUFlO0FBQUEsRUFDZixJQUFJO0FBQUEsRUFDSix1QkFBdUI7QUFBQSxFQUN2QixlQUFlO0FBQUEsRUFDZixtQkFBbUI7QUFDckI7OztBQ3hFQSxJQUFBQyxtQkFBdUQ7OztBQ0x2RCxzQkFBNEM7QUFHckMsSUFBTSxpQkFBTixNQUFxQjtBQUFBLEVBQzFCLFlBQ21CLGFBQ0Esa0JBQ0EsVUFDakI7QUFIaUI7QUFDQTtBQUNBO0FBQUEsRUFDaEI7QUFBQTtBQUFBO0FBQUEsRUFLSCxNQUFNLGNBQXVDO0FBQzNDLFVBQU0sTUFBTSxHQUFHLEtBQUssWUFBWSxDQUFDO0FBQ2pDLFVBQU0sT0FBTyxVQUFNLDRCQUFXO0FBQUEsTUFDNUI7QUFBQSxNQUNBLFFBQVE7QUFBQSxNQUNSLFNBQVMsS0FBSyxZQUFZO0FBQUEsSUFDNUIsQ0FBQztBQUNELFdBQU8sS0FBSztBQUFBLEVBQ2Q7QUFBQTtBQUFBO0FB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
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index c6f17b8..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,676 +0,0 @@
-{
- "name": "obsidian-micropub",
- "version": "0.1.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "obsidian-micropub",
- "version": "0.1.0",
- "license": "MIT",
- "devDependencies": {
- "@types/node": "^20.0.0",
- "@types/qrcode": "^1.5.5",
- "builtin-modules": "^4.0.0",
- "esbuild": "^0.25.0",
- "obsidian": "latest",
- "tslib": "^2.6.0",
- "typescript": "^5.0.0"
- }
- },
- "node_modules/@codemirror/state": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.0.tgz",
- "integrity": "sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@marijn/find-cluster-break": "^1.0.0"
- }
- },
- "node_modules/@codemirror/view": {
- "version": "6.38.6",
- "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.6.tgz",
- "integrity": "sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@codemirror/state": "^6.5.0",
- "crelt": "^1.0.6",
- "style-mod": "^4.1.0",
- "w3c-keyname": "^2.2.4"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
- "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
- "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
- "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
- "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
- "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
- "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
- "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
- "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
- "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
- "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
- "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
- "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
- "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
- "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
- "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
- "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
- "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
- "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
- "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
- "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
- "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
- "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
- "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
- "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
- "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
- "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@marijn/find-cluster-break": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
- "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/@types/codemirror": {
- "version": "5.60.8",
- "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.8.tgz",
- "integrity": "sha512-VjFgDF/eB+Aklcy15TtOTLQeMjTo07k7KAjql8OK5Dirr7a6sJY4T1uVBDuTVG9VEmn1uUsohOpYnVfgC6/jyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/tern": "*"
- }
- },
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "20.19.37",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz",
- "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~6.21.0"
- }
- },
- "node_modules/@types/qrcode": {
- "version": "1.5.6",
- "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.6.tgz",
- "integrity": "sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/node": "*"
- }
- },
- "node_modules/@types/tern": {
- "version": "0.23.9",
- "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz",
- "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "*"
- }
- },
- "node_modules/builtin-modules": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-4.0.0.tgz",
- "integrity": "sha512-p1n8zyCkt1BVrKNFymOHjcDSAl7oq/gUvfgULv2EblgpPVQlQr9yHnWjg9IJ2MhfwPqiYqMMrr01OY7yQoK2yA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/crelt": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
- "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/esbuild": {
- "version": "0.25.12",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
- "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.25.12",
- "@esbuild/android-arm": "0.25.12",
- "@esbuild/android-arm64": "0.25.12",
- "@esbuild/android-x64": "0.25.12",
- "@esbuild/darwin-arm64": "0.25.12",
- "@esbuild/darwin-x64": "0.25.12",
- "@esbuild/freebsd-arm64": "0.25.12",
- "@esbuild/freebsd-x64": "0.25.12",
- "@esbuild/linux-arm": "0.25.12",
- "@esbuild/linux-arm64": "0.25.12",
- "@esbuild/linux-ia32": "0.25.12",
- "@esbuild/linux-loong64": "0.25.12",
- "@esbuild/linux-mips64el": "0.25.12",
- "@esbuild/linux-ppc64": "0.25.12",
- "@esbuild/linux-riscv64": "0.25.12",
- "@esbuild/linux-s390x": "0.25.12",
- "@esbuild/linux-x64": "0.25.12",
- "@esbuild/netbsd-arm64": "0.25.12",
- "@esbuild/netbsd-x64": "0.25.12",
- "@esbuild/openbsd-arm64": "0.25.12",
- "@esbuild/openbsd-x64": "0.25.12",
- "@esbuild/openharmony-arm64": "0.25.12",
- "@esbuild/sunos-x64": "0.25.12",
- "@esbuild/win32-arm64": "0.25.12",
- "@esbuild/win32-ia32": "0.25.12",
- "@esbuild/win32-x64": "0.25.12"
- }
- },
- "node_modules/moment": {
- "version": "2.29.4",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
- "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/obsidian": {
- "version": "1.12.3",
- "resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.12.3.tgz",
- "integrity": "sha512-HxWqe763dOqzXjnNiHmAJTRERN8KILBSqxDSEqbeSr7W8R8Jxezzbca+nz1LiiqXnMpM8lV2jzAezw3CZ4xNUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/codemirror": "5.60.8",
- "moment": "2.29.4"
- },
- "peerDependencies": {
- "@codemirror/state": "6.5.0",
- "@codemirror/view": "6.38.6"
- }
- },
- "node_modules/style-mod": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz",
- "integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "dev": true,
- "license": "0BSD"
- },
- "node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/undici-types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/w3c-keyname": {
- "version": "2.2.8",
- "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
- "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
- "dev": true,
- "license": "MIT",
- "peer": true
- }
- }
-}