UNPKG

obsidian-dev-utils

Version:

This is the collection of useful functions that you can use for your Obsidian plugin development

370 lines (356 loc) 38.2 kB
/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ (function initCjs() { const globalThisRecord = globalThis; globalThisRecord['__name'] ??= name; const originalRequire = require; if (originalRequire && !originalRequire.__isPatched) { // eslint-disable-next-line no-global-assign, no-implicit-globals -- We need to patch the `require()` function. require = Object.assign( (id) => requirePatched(id), originalRequire, { __isPatched: true } ); } const newFuncs = { __extractDefault() { return extractDefault; }, process() { const browserProcess = { browser: true, cwd() { return '/'; }, env: {}, platform: 'android' }; return browserProcess; } }; for (const key of Object.keys(newFuncs)) { globalThisRecord[key] ??= newFuncs[key]?.(); } function name(obj) { return obj; } function extractDefault(module) { return module && module.__esModule && 'default' in module ? module.default : module; } const OBSIDIAN_BUILT_IN_MODULE_NAMES = [ 'obsidian', '@codemirror/autocomplete', '@codemirror/collab', '@codemirror/commands', '@codemirror/language', '@codemirror/lint', '@codemirror/search', '@codemirror/state', '@codemirror/text', '@codemirror/view', '@lezer/common', '@lezer/lr', '@lezer/highlight']; const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = [ '@codemirror/closebrackets', '@codemirror/comment', '@codemirror/fold', '@codemirror/gutter', '@codemirror/highlight', '@codemirror/history', '@codemirror/matchbrackets', '@codemirror/panel', '@codemirror/rangeset', '@codemirror/rectangular-selection', '@codemirror/stream-parser', '@codemirror/tooltip']; function requirePatched(id) { if (OBSIDIAN_BUILT_IN_MODULE_NAMES.includes(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.includes(id)) { return originalRequire?.(id); } // eslint-disable-next-line @typescript-eslint/no-deprecated, @typescript-eslint/no-unnecessary-condition -- We need access to app here which might not be available yet. if (globalThis?.app?.isMobile) { if (id === 'process' || id === 'node:process') { console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`); return globalThis.process; } } else { const module = originalRequire?.(id); if (module) { return extractDefault(module); } } console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`); return {}; } })(); "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; 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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var MetadataCache_exports = {}; __export(MetadataCache_exports, { ensureMetadataCacheReady: () => ensureMetadataCacheReady, getAllLinks: () => getAllLinks, getBacklinksForFileOrPath: () => getBacklinksForFileOrPath, getBacklinksForFileSafe: () => getBacklinksForFileSafe, getCacheSafe: () => getCacheSafe, getFrontmatterSafe: () => getFrontmatterSafe, parseMetadata: () => parseMetadata, registerFileCacheForNonExistingFile: () => registerFileCacheForNonExistingFile, registerFiles: () => registerFiles, tempRegisterFilesAndRun: () => tempRegisterFilesAndRun, tempRegisterFilesAndRunAsync: () => tempRegisterFilesAndRunAsync, unregisterFileCacheForNonExistingFile: () => unregisterFileCacheForNonExistingFile, unregisterFiles: () => unregisterFiles }); module.exports = __toCommonJS(MetadataCache_exports); var import_implementations = require('obsidian-typings/implementations'); var import_ObjectUtils = require('../ObjectUtils.cjs'); var import_App = require('./App.cjs'); var import_AsyncWithNotice = require('./AsyncWithNotice.cjs'); var import_FileSystem = require('./FileSystem.cjs'); var import_Frontmatter = require('./Frontmatter.cjs'); var import_FrontmatterLinkCacheWithOffsets = require('./FrontmatterLinkCacheWithOffsets.cjs'); var import_i18n = require('./i18n/i18n.cjs'); var import_Reference = require('./Reference.cjs'); var import_Vault = require('./Vault.cjs'); async function ensureMetadataCacheReady(app) { await new Promise((resolve) => { app.metadataCache.onCleanCache(resolve); }); } function getAllLinks(cache) { let links = []; if (cache.links) { links.push(...cache.links); } if (cache.embeds) { links.push(...cache.embeds); } if (cache.frontmatterLinks) { links.push(...cache.frontmatterLinks); } (0, import_Reference.sortReferences)(links); links = links.filter((link, index) => { if (index === 0) { return true; } const previousLink = links[index - 1]; if (!previousLink) { return true; } if ((0, import_implementations.isReferenceCache)(link) && (0, import_implementations.isReferenceCache)(previousLink)) { return link.position.start.offset !== previousLink.position.start.offset; } if ((0, import_implementations.isFrontmatterLinkCache)(link) && (0, import_implementations.isFrontmatterLinkCache)(previousLink)) { const linkStartOffset = (0, import_FrontmatterLinkCacheWithOffsets.isFrontmatterLinkCacheWithOffsets)(link) ? link.startOffset : 0; const previousLinkStartOffset = (0, import_FrontmatterLinkCacheWithOffsets.isFrontmatterLinkCacheWithOffsets)(previousLink) ? previousLink.startOffset : 0; return link.key !== previousLink.key || (0, import_FrontmatterLinkCacheWithOffsets.isFrontmatterLinkCacheWithOffsets)(link) !== (0, import_FrontmatterLinkCacheWithOffsets.isFrontmatterLinkCacheWithOffsets)(previousLink) || linkStartOffset !== previousLinkStartOffset; } return true; }); return links; } function getBacklinksForFileOrPath(app, pathOrFile) { const file = (0, import_FileSystem.getFile)(app, pathOrFile, true); return tempRegisterFilesAndRun(app, [file], () => app.metadataCache.getBacklinksForFile(file)); } async function getBacklinksForFileSafe(app, pathOrFile, options = {}) { const safeOverload = app.metadataCache.getBacklinksForFile.safe; if (safeOverload) { return safeOverload(pathOrFile); } let backlinks = new import_implementations.CustomArrayDictImpl(); await (0, import_AsyncWithNotice.retryWithTimeoutNotice)({ async operationFn(abortSignal) { abortSignal.throwIfAborted(); const file = (0, import_FileSystem.getFile)(app, pathOrFile); await ensureMetadataCacheReady(app); abortSignal.throwIfAborted(); backlinks = getBacklinksForFileOrPath(app, file); for (const notePath of backlinks.keys()) { abortSignal.throwIfAborted(); const note = (0, import_FileSystem.getFileOrNull)(app, notePath); if (!note) { return false; } await (0, import_Vault.saveNote)(app, note); abortSignal.throwIfAborted(); const content = await (0, import_Vault.readSafe)(app, note); abortSignal.throwIfAborted(); if (!content) { return false; } const frontmatter = (0, import_Frontmatter.parseFrontmatter)(content); const links = backlinks.get(notePath); if (!links) { return false; } for (const link of links) { let actualLink; if ((0, import_implementations.isReferenceCache)(link)) { actualLink = content.slice(link.position.start.offset, link.position.end.offset); } else if ((0, import_implementations.isFrontmatterLinkCache)(link)) { const propertyValue = (0, import_ObjectUtils.getNestedPropertyValue)(frontmatter, link.key); if (typeof propertyValue !== "string") { return false; } const linkWithOffsets = (0, import_FrontmatterLinkCacheWithOffsets.toFrontmatterLinkCacheWithOffsets)(link); actualLink = propertyValue.slice(linkWithOffsets.startOffset, linkWithOffsets.endOffset); } else { return true; } if (actualLink !== link.original) { return false; } } } return true; }, operationName: (0, import_i18n.t)(($) => $.obsidianDevUtils.metadataCache.getBacklinksForFilePath, { filePath: (0, import_FileSystem.getPath)(app, pathOrFile) }), retryOptions: options, shouldShowTimeoutNotice: options.shouldShowTimeoutNotice ?? true }); return backlinks; } async function getCacheSafe(app, fileOrPath) { const file = (0, import_FileSystem.getFileOrNull)(app, fileOrPath); try { if (!file) { return null; } if (file.deleted) { return app.metadataCache.getFileCache(file); } await (0, import_Vault.saveNote)(app, file); const fileCacheEntry = app.metadataCache.fileCache[file.path]; const isUpToDate = fileCacheEntry?.mtime === file.stat.mtime && fileCacheEntry.size === file.stat.size && app.metadataCache.metadataCache[fileCacheEntry.hash]; if (!isUpToDate) { await app.metadataCache.computeFileMetadataAsync(file); await ensureMetadataCacheReady(app); } return app.metadataCache.getFileCache(file); } catch (error) { if (!file || file.deleted) { return null; } throw error; } } async function getFrontmatterSafe(app, pathOrFile) { const cache = await getCacheSafe(app, pathOrFile); return cache?.frontmatter ?? {}; } async function parseMetadata(app, str) { const encoder = new TextEncoder(); const buffer = encoder.encode(str).buffer; return await app.metadataCache.computeMetadataAsync(buffer) ?? {}; } function registerFileCacheForNonExistingFile(app, pathOrFile, cache) { const file = (0, import_FileSystem.getFile)(app, pathOrFile, true); if (!file.deleted) { throw new Error("File is existing"); } app.metadataCache.fileCache[file.path] = { hash: file.path, mtime: 0, size: 0 }; app.metadataCache.metadataCache[file.path] = cache; } function registerFiles(app, files) { const registeredFilesCounts = getRegisteredFilesCounts(app); for (let file of files) { while (file.deleted) { let count = registeredFilesCounts.get(file.path) ?? 0; count++; registeredFilesCounts.set(file.path, count); app.vault.fileMap[file.path] = file; if ((0, import_FileSystem.isFile)(file)) { app.metadataCache.uniqueFileLookup.add(file.name.toLowerCase(), file); } file = (0, import_FileSystem.getFolder)(app, (0, import_implementations.parentFolderPath)(file.path), true); } } } function tempRegisterFilesAndRun(app, files, fn) { try { registerFiles(app, files); return fn(); } finally { unregisterFiles(app, files); } } async function tempRegisterFilesAndRunAsync(app, files, fn) { try { registerFiles(app, files); return await fn(); } finally { unregisterFiles(app, files); } } function unregisterFileCacheForNonExistingFile(app, pathOrFile) { const file = (0, import_FileSystem.getFile)(app, pathOrFile, true); if (!file.deleted) { throw new Error("File is existing"); } delete app.metadataCache.fileCache[file.path]; delete app.metadataCache.metadataCache[file.path]; } function unregisterFiles(app, files) { const registeredFilesCounts = getRegisteredFilesCounts(app); for (let file of files) { while (file.deleted) { let count = registeredFilesCounts.get(file.path) ?? 1; count--; registeredFilesCounts.set(file.path, count); if (count === 0) { registeredFilesCounts.delete(file.path); delete app.vault.fileMap[file.path]; if ((0, import_FileSystem.isFile)(file)) { app.metadataCache.uniqueFileLookup.remove(file.name.toLowerCase(), file); } } file = (0, import_FileSystem.getFolder)(app, (0, import_implementations.parentFolderPath)(file.path), true); } } } function getRegisteredFilesCounts(app) { return (0, import_App.getObsidianDevUtilsState)(app, "registeredFilesCounts", /* @__PURE__ */ new Map()).value; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ensureMetadataCacheReady, getAllLinks, getBacklinksForFileOrPath, getBacklinksForFileSafe, getCacheSafe, getFrontmatterSafe, parseMetadata, registerFileCacheForNonExistingFile, registerFiles, tempRegisterFilesAndRun, tempRegisterFilesAndRunAsync, unregisterFileCacheForNonExistingFile, unregisterFiles }); //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL01ldGFkYXRhQ2FjaGUudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKlxuICogVGhpcyBtb2R1bGUgcHJvdmlkZXMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdvcmtpbmcgd2l0aCB0aGUgbWV0YWRhdGEgY2FjaGUgaW4gT2JzaWRpYW4uXG4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBBcHAsXG4gIENhY2hlZE1ldGFkYXRhLFxuICBSZWZlcmVuY2UsXG4gIFRBYnN0cmFjdEZpbGVcbn0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHR5cGUgeyBDdXN0b21BcnJheURpY3QgfSBmcm9tICdvYnNpZGlhbi10eXBpbmdzJztcblxuaW1wb3J0IHtcbiAgQ3VzdG9tQXJyYXlEaWN0SW1wbCxcbiAgaXNGcm9udG1hdHRlckxpbmtDYWNoZSxcbiAgaXNSZWZlcmVuY2VDYWNoZSxcbiAgcGFyZW50Rm9sZGVyUGF0aFxufSBmcm9tICdvYnNpZGlhbi10eXBpbmdzL2ltcGxlbWVudGF0aW9ucyc7XG5cbmltcG9ydCB0eXBlIHsgUmV0cnlPcHRpb25zIH0gZnJvbSAnLi4vQXN5bmMudHMnO1xuaW1wb3J0IHR5cGUgeyBQYXRoT3JGaWxlIH0gZnJvbSAnLi9GaWxlU3lzdGVtLnRzJztcbmltcG9ydCB0eXBlIHsgQ29tYmluZWRGcm9udG1hdHRlciB9IGZyb20gJy4vRnJvbnRtYXR0ZXIudHMnO1xuXG5pbXBvcnQgeyBnZXROZXN0ZWRQcm9wZXJ0eVZhbHVlIH0gZnJvbSAnLi4vT2JqZWN0VXRpbHMudHMnO1xuaW1wb3J0IHsgZ2V0T2JzaWRpYW5EZXZVdGlsc1N0YXRlIH0gZnJvbSAnLi9BcHAudHMnO1xuaW1wb3J0IHsgcmV0cnlXaXRoVGltZW91dE5vdGljZSB9IGZyb20gJy4vQXN5bmNXaXRoTm90aWNlLnRzJztcbmltcG9ydCB7XG4gIGdldEZpbGUsXG4gIGdldEZpbGVPck51bGwsXG4gIGdldEZvbGRlcixcbiAgZ2V0UGF0aCxcbiAgaXNGaWxlXG59IGZyb20gJy4vRmlsZVN5c3RlbS50cyc7XG5pbXBvcnQgeyBwYXJzZUZyb250bWF0dGVyIH0gZnJvbSAnLi9Gcm9udG1hdHRlci50cyc7XG5pbXBvcnQge1xuICBpc0Zyb250bWF0dGVyTGlua0NhY2hlV2l0aE9mZnNldHMsXG4gIHRvRnJvbnRtYXR0ZXJMaW5rQ2FjaGVXaXRoT2Zmc2V0c1xufSBmcm9tICcuL0Zyb250bWF0dGVyTGlua0NhY2hlV2l0aE9mZnNldHMudHMnO1xuaW1wb3J0IHsgdCB9IGZyb20gJy4vaTE4bi9pMThuLnRzJztcbmltcG9ydCB7IHNvcnRSZWZlcmVuY2VzIH0gZnJvbSAnLi9SZWZlcmVuY2UudHMnO1xuaW1wb3J0IHtcbiAgcmVhZFNhZmUsXG4gIHNhdmVOb3RlXG59IGZyb20gJy4vVmF1bHQudHMnO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBnZXRCYWNrbGlua3NGb3JGaWxlU2FmZX0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2V0QmFja2xpbmtzRm9yRmlsZVNhZmVPcHRpb25zIGV4dGVuZHMgUmV0cnlPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2hvdyBhIHRpbWVvdXQgbm90aWNlLiBEZWZhdWx0IGlzIGB0cnVlYC5cbiAgICovXG4gIHNob3VsZFNob3dUaW1lb3V0Tm90aWNlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXcmFwcGVyIGZvciB0aGUgZ2V0QmFja2xpbmtzRm9yRmlsZSBtZXRob2QgdGhhdCBwcm92aWRlcyBhIHNhZmUgb3ZlcmxvYWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2V0QmFja2xpbmtzRm9yRmlsZVNhZmVXcmFwcGVyIHtcbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgYmFja2xpbmtzIGZvciBhIGZpbGUgc2FmZWx5LlxuICAgKlxuICAgKiBAcGFyYW0gcGF0aE9yRmlsZSAtIFRoZSBwYXRoIG9yIGZpbGUgb2JqZWN0LlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IGRpY3Rpb25hcnkgb2YgYmFja2xpbmtzLlxuICAgKi9cbiAgc2FmZShwYXRoT3JGaWxlOiBQYXRoT3JGaWxlKTogUHJvbWlzZTxDdXN0b21BcnJheURpY3Q8UmVmZXJlbmNlPj47XG59XG5cbi8qKlxuICogRW5zdXJlcyB0aGF0IHRoZSBtZXRhZGF0YSBjYWNoZSBpcyByZWFkeSBmb3IgYWxsIGZpbGVzLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBtZXRhZGF0YSBjYWNoZSBpcyByZWFkeS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuc3VyZU1ldGFkYXRhQ2FjaGVSZWFkeShhcHA6IEFwcCk6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGFwcC5tZXRhZGF0YUNhY2hlLm9uQ2xlYW5DYWNoZShyZXNvbHZlKTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIGFsbCBsaW5rcyBmcm9tIHRoZSBwcm92aWRlZCBjYWNoZS5cbiAqXG4gKiBAcGFyYW0gY2FjaGUgLSBUaGUgY2FjaGVkIG1ldGFkYXRhLlxuICogQHJldHVybnMgQW4gYXJyYXkgb2YgcmVmZXJlbmNlIGNhY2hlcyByZXByZXNlbnRpbmcgdGhlIGxpbmtzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxsTGlua3MoY2FjaGU6IENhY2hlZE1ldGFkYXRhKTogUmVmZXJlbmNlW10ge1xuICBsZXQgbGlua3M6IFJlZmVyZW5jZVtdID0gW107XG5cbiAgaWYgKGNhY2hlLmxpbmtzKSB7XG4gICAgbGlua3MucHVzaCguLi5jYWNoZS5saW5rcyk7XG4gIH1cblxuICBpZiAoY2FjaGUuZW1iZWRzKSB7XG4gICAgbGlua3MucHVzaCguLi5jYWNoZS5lbWJlZHMpO1xuICB9XG5cbiAgaWYgKGNhY2hlLmZyb250bWF0dGVyTGlua3MpIHtcbiAgICBsaW5rcy5wdXNoKC4uLmNhY2hlLmZyb250bWF0dGVyTGlua3MpO1xuICB9XG5cbiAgc29ydFJlZmVyZW5jZXMobGlua3MpO1xuXG4gIC8vIEJVRzogaHR0cHM6Ly9mb3J1bS5vYnNpZGlhbi5tZC90L2J1Zy1kdXBsaWNhdGVkLWxpbmtzLWluLW1ldGFkYXRhY2FjaGUtaW5zaWRlLWZvb3Rub3Rlcy84NTU1MVxuICBsaW5rcyA9IGxpbmtzLmZpbHRlcigobGluaywgaW5kZXgpID0+IHtcbiAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHByZXZpb3VzTGluayA9IGxpbmtzW2luZGV4IC0gMV07XG4gICAgaWYgKCFwcmV2aW91c0xpbmspIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChpc1JlZmVyZW5jZUNhY2hlKGxpbmspICYmIGlzUmVmZXJlbmNlQ2FjaGUocHJldmlvdXNMaW5rKSkge1xuICAgICAgcmV0dXJuIGxpbmsucG9zaXRpb24uc3RhcnQub2Zmc2V0ICE9PSBwcmV2aW91c0xpbmsucG9zaXRpb24uc3RhcnQub2Zmc2V0O1xuICAgIH1cblxuICAgIGlmIChpc0Zyb250bWF0dGVyTGlua0NhY2hlKGxpbmspICYmIGlzRnJvbnRtYXR0ZXJMaW5rQ2FjaGUocHJldmlvdXNMaW5rKSkge1xuICAgICAgY29uc3QgbGlua1N0YXJ0T2Zmc2V0ID0gaXNGcm9udG1hdHRlckxpbmtDYWNoZVdpdGhPZmZzZXRzKGxpbmspID8gbGluay5zdGFydE9mZnNldCA6IDA7XG4gICAgICBjb25zdCBwcmV2aW91c0xpbmtTdGFydE9mZnNldCA9IGlzRnJvbnRtYXR0ZXJMaW5rQ2FjaGVXaXRoT2Zmc2V0cyhwcmV2aW91c0xpbmspID8gcHJldmlvdXNMaW5rLnN0YXJ0T2Zmc2V0IDogMDtcbiAgICAgIHJldHVybiBsaW5rLmtleSAhPT0gcHJldmlvdXNMaW5rLmtleSB8fCBpc0Zyb250bWF0dGVyTGlua0NhY2hlV2l0aE9mZnNldHMobGluaykgIT09IGlzRnJvbnRtYXR0ZXJMaW5rQ2FjaGVXaXRoT2Zmc2V0cyhwcmV2aW91c0xpbmspXG4gICAgICAgIHx8IGxpbmtTdGFydE9mZnNldCAhPT0gcHJldmlvdXNMaW5rU3RhcnRPZmZzZXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBsaW5rcztcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGJhY2tsaW5rcyBmb3IgYSBmaWxlIG9yIHBhdGguXG4gKiBOT1RFOiBUaGUgZmlsZSBtYXkgYmUgbm9uLWV4aXN0ZW50LlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwbGljYXRpb24gaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGF0aE9yRmlsZSAtIFRoZSBwYXRoIG9yIGZpbGUgb2JqZWN0LlxuICogQHJldHVybnMgVGhlIGJhY2tsaW5rcyBmb3IgdGhlIGZpbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYWNrbGlua3NGb3JGaWxlT3JQYXRoKGFwcDogQXBwLCBwYXRoT3JGaWxlOiBQYXRoT3JGaWxlKTogQ3VzdG9tQXJyYXlEaWN0PFJlZmVyZW5jZT4ge1xuICBjb25zdCBmaWxlID0gZ2V0RmlsZShhcHAsIHBhdGhPckZpbGUsIHRydWUpO1xuICByZXR1cm4gdGVtcFJlZ2lzdGVyRmlsZXNBbmRSdW4oYXBwLCBbZmlsZV0sICgpID0+IGFwcC5tZXRhZGF0YUNhY2hlLmdldEJhY2tsaW5rc0ZvckZpbGUoZmlsZSkpO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgYmFja2xpbmtzIGZvciBhIGZpbGUgc2FmZWx5LlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwbGljYXRpb24gaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGF0aE9yRmlsZSAtIFRoZSBwYXRoIG9yIGZpbGUgb2JqZWN0LlxuICogQHBhcmFtIG9wdGlvbnMgLSBPdGhlciBvcHRpb25zLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBkaWN0aW9uYXJ5IG9mIGJhY2tsaW5rcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEJhY2tsaW5rc0ZvckZpbGVTYWZlKFxuICBhcHA6IEFwcCxcbiAgcGF0aE9yRmlsZTogUGF0aE9yRmlsZSxcbiAgb3B0aW9uczogR2V0QmFja2xpbmtzRm9yRmlsZVNhZmVPcHRpb25zID0ge31cbik6IFByb21pc2U8Q3VzdG9tQXJyYXlEaWN0PFJlZmVyZW5jZT4+IHtcbiAgY29uc3Qgc2FmZU92ZXJsb2FkID0gKGFwcC5tZXRhZGF0YUNhY2hlLmdldEJhY2tsaW5rc0ZvckZpbGUgYXMgUGFydGlhbDxHZXRCYWNrbGlua3NGb3JGaWxlU2FmZVdyYXBwZXI+KS5zYWZlO1xuICBpZiAoc2FmZU92ZXJsb2FkKSB7XG4gICAgcmV0dXJuIHNhZmVPdmVybG9hZChwYXRoT3JGaWxlKTtcbiAgfVxuICBsZXQgYmFja2xpbmtzOiBDdXN0b21BcnJheURpY3Q8UmVmZXJlbmNlPiA9IG5ldyBDdXN0b21BcnJheURpY3RJbXBsPFJlZmVyZW5jZT4oKTtcbiAgYXdhaXQgcmV0cnlXaXRoVGltZW91dE5vdGljZSh7XG4gICAgYXN5bmMgb3BlcmF0aW9uRm4oYWJvcnRTaWduYWwpIHtcbiAgICAgIGFib3J0U2lnbmFsLnRocm93SWZBYm9ydGVkKCk7XG4gICAgICBjb25zdCBmaWxlID0gZ2V0RmlsZShhcHAsIHBhdGhPckZpbGUpO1xuICAgICAgYXdhaXQgZW5zdXJlTWV0YWRhdGFDYWNoZVJlYWR5KGFwcCk7XG4gICAgICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuICAgICAgYmFja2xpbmtzID0gZ2V0QmFja2xpbmtzRm9yRmlsZU9yUGF0aChhcHAsIGZpbGUpO1xuICAgICAgZm9yIChjb25zdCBub3RlUGF0aCBvZiBiYWNrbGlua3Mua2V5cygpKSB7XG4gICAgICAgIGFib3J0U2lnbmFsLnRocm93SWZBYm9ydGVkKCk7XG4gICAgICAgIGNvbnN0IG5vdGUgPSBnZXRGaWxlT3JOdWxsKGFwcCwgbm90ZVBhdGgpO1xuICAgICAgICBpZiAoIW5vdGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCBzYXZlTm90ZShhcHAsIG5vdGUpO1xuICAgICAgICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCByZWFkU2FmZShhcHAsIG5vdGUpO1xuICAgICAgICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuICAgICAgICBpZiAoIWNvbnRlbnQpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZnJvbnRtYXR0ZXIgPSBwYXJzZUZyb250bWF0dGVyKGNvbnRlbnQpO1xuICAgICAgICBjb25zdCBsaW5rcyA9IGJhY2tsaW5rcy5nZXQobm90ZVBhdGgpO1xuICAgICAgICBpZiAoIWxpbmtzKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBsaW5rIG9mIGxpbmtzKSB7XG4gICAgICAgICAgbGV0IGFjdHVhbExpbms6IHN0cmluZztcbiAgICAgICAgICBpZiAoaXNSZWZlcmVuY2VDYWNoZShsaW5rKSkge1xuICAgICAgICAgICAgYWN0dWFsTGluayA9IGNvbnRlbnQuc2xpY2UobGluay5wb3NpdGlvbi5zdGFydC5vZmZzZXQsIGxpbmsucG9zaXRpb24uZW5kLm9mZnNldCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChpc0Zyb250bWF0dGVyTGlua0NhY2hlKGxpbmspKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0eVZhbHVlID0gZ2V0TmVzdGVkUHJvcGVydHlWYWx1ZShmcm9udG1hdHRlciwgbGluay5rZXkpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGxpbmtXaXRoT2Zmc2V0cyA9IHRvRnJvbnRtYXR0ZXJMaW5rQ2FjaGVXaXRoT2Zmc2V0cyhsaW5rKTtcbiAgICAgICAgICAgIGFjdHVhbExpbmsgPSBwcm9wZXJ0eVZhbHVlLnNsaWNlKGxpbmtXaXRoT2Zmc2V0cy5zdGFydE9mZnNldCwgbGlua1dpdGhPZmZzZXRzLmVuZE9mZnNldCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYWN0dWFsTGluayAhPT0gbGluay5vcmlnaW5hbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuICAgIG9wZXJhdGlvbk5hbWU6IHQoKCQpID0+ICQub2JzaWRpYW5EZXZVdGlscy5tZXRhZGF0YUNhY2hlLmdldEJhY2tsaW5rc0ZvckZpbGVQYXRoLCB7IGZpbGVQYXRoOiBnZXRQYXRoKGFwcCwgcGF0aE9yRmlsZSkgfSksXG4gICAgcmV0cnlPcHRpb25zOiBvcHRpb25zLFxuICAgIHNob3VsZFNob3dUaW1lb3V0Tm90aWNlOiBvcHRpb25zLnNob3VsZFNob3dUaW1lb3V0Tm90aWNlID8/IHRydWVcbiAgfSk7XG5cbiAgcmV0dXJuIGJhY2tsaW5rcztcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGNhY2hlZCBtZXRhZGF0YSBmb3IgYSBnaXZlbiBmaWxlIG9yIHBhdGguXG4gKlxuICogQHBhcmFtIGFwcCAtIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gZmlsZU9yUGF0aCAtIFRoZSBmaWxlIG9yIHBhdGggdG8gcmV0cmlldmUgdGhlIG1ldGFkYXRhIGZvci5cbiAqIEByZXR1cm5zIFRoZSBjYWNoZWQgbWV0YWRhdGEgZm9yIHRoZSBmaWxlLCBvciBudWxsIGlmIGl0IGRvZXNuJ3QgZXhpc3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRDYWNoZVNhZmUoYXBwOiBBcHAsIGZpbGVPclBhdGg6IFBhdGhPckZpbGUpOiBQcm9taXNlPENhY2hlZE1ldGFkYXRhIHwgbnVsbD4ge1xuICBjb25zdCBmaWxlID0gZ2V0RmlsZU9yTnVsbChhcHAsIGZpbGVPclBhdGgpO1xuXG4gIHRyeSB7XG4gICAgaWYgKCFmaWxlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoZmlsZS5kZWxldGVkKSB7XG4gICAgICByZXR1cm4gYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0RmlsZUNhY2hlKGZpbGUpO1xuICAgIH1cblxuICAgIGF3YWl0IHNhdmVOb3RlKGFwcCwgZmlsZSk7XG5cbiAgICBjb25zdCBmaWxlQ2FjaGVFbnRyeSA9IGFwcC5tZXRhZGF0YUNhY2hlLmZpbGVDYWNoZVtmaWxlLnBhdGhdO1xuICAgIGNvbnN0IGlzVXBUb0RhdGUgPSBmaWxlQ2FjaGVFbnRyeT8ubXRpbWUgPT09IGZpbGUuc3RhdC5tdGltZVxuICAgICAgJiYgZmlsZUNhY2hlRW50cnkuc2l6ZSA9PT0gZmlsZS5zdGF0LnNpemVcbiAgICAgICYmIGFwcC5tZXRhZGF0YUNhY2hlLm1ldGFkYXRhQ2FjaGVbZmlsZUNhY2hlRW50cnkuaGFzaF07XG4gICAgaWYgKCFpc1VwVG9EYXRlKSB7XG4gICAgICBhd2FpdCBhcHAubWV0YWRhdGFDYWNoZS5jb21wdXRlRmlsZU1ldGFkYXRhQXN5bmMoZmlsZSk7XG4gICAgICBhd2FpdCBlbnN1cmVNZXRhZGF0YUNhY2hlUmVhZHkoYXBwKTtcbiAgICB9XG4gICAgcmV0dXJuIGFwcC5tZXRhZGF0YUNhY2hlLmdldEZpbGVDYWNoZShmaWxlKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoIWZpbGUgfHwgZmlsZS5kZWxldGVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgZnJvbnQgbWF0dGVyIGZyb20gdGhlIG1ldGFkYXRhIGNhY2hlIHNhZmVseS5cbiAqXG4gKiBAdHlwZVBhcmFtIEN1c3RvbUZyb250bWF0dGVyIC0gVGhlIHR5cGUgb2YgY3VzdG9tIGZyb250IG1hdHRlci5cbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBmaWxlIHRvIHJldHJpZXZlIHRoZSBmcm9udCBtYXR0ZXIgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSBjb21iaW5lZCBmcm9udCBtYXR0ZXIuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRGcm9udG1hdHRlclNhZmU8Q3VzdG9tRnJvbnRtYXR0ZXIgPSB1bmtub3duPihhcHA6IEFwcCwgcGF0aE9yRmlsZTogUGF0aE9yRmlsZSk6IFByb21pc2U8Q29tYmluZWRGcm9udG1hdHRlcjxDdXN0b21Gcm9udG1hdHRlcj4+IHtcbiAgY29uc3QgY2FjaGUgPSBhd2FpdCBnZXRDYWNoZVNhZmUoYXBwLCBwYXRoT3JGaWxlKTtcbiAgcmV0dXJuIChjYWNoZT8uZnJvbnRtYXR0ZXIgPz8ge30pIGFzIENvbWJpbmVkRnJvbnRtYXR0ZXI8Q3VzdG9tRnJvbnRtYXR0ZXI+O1xufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgbWV0YWRhdGEgZm9yIGEgZ2l2ZW4gc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gcGFyc2UgdGhlIG1ldGFkYXRhIGZvci5cbiAqIEByZXR1cm5zIFRoZSBwYXJzZWQgbWV0YWRhdGEuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwYXJzZU1ldGFkYXRhKGFwcDogQXBwLCBzdHI6IHN0cmluZyk6IFByb21pc2U8Q2FjaGVkTWV0YWRhdGE+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICBjb25zdCBidWZmZXIgPSBlbmNvZGVyLmVuY29kZShzdHIpLmJ1ZmZlcjtcbiAgcmV0dXJuIGF3YWl0IGFwcC5tZXRhZGF0YUNhY2hlLmNvbXB1dGVNZXRhZGF0YUFzeW5jKGJ1ZmZlcikgPz8ge307XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIHRoZSBmaWxlIGNhY2hlIGZvciBhIG5vbi1leGlzdGluZyBmaWxlLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBmaWxlIHRvIHJlZ2lzdGVyIHRoZSBmaWxlIGNhY2hlIGZvci5cbiAqIEBwYXJhbSBjYWNoZSAtIFRoZSBmaWxlIGNhY2hlIHRvIHJlZ2lzdGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJGaWxlQ2FjaGVGb3JOb25FeGlzdGluZ0ZpbGUoYXBwOiBBcHAsIHBhdGhPckZpbGU6IFBhdGhPckZpbGUsIGNhY2hlOiBDYWNoZWRNZXRhZGF0YSk6IHZvaWQge1xuICBjb25zdCBmaWxlID0gZ2V0RmlsZShhcHAsIHBhdGhPckZpbGUsIHRydWUpO1xuICBpZiAoIWZpbGUuZGVsZXRlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmlsZSBpcyBleGlzdGluZycpO1xuICB9XG5cbiAgYXBwLm1ldGFkYXRhQ2FjaGUuZmlsZUNhY2hlW2ZpbGUucGF0aF0gPSB7XG4gICAgaGFzaDogZmlsZS5wYXRoLFxuICAgIG10aW1lOiAwLFxuICAgIHNpemU6IDBcbiAgfTtcblxuICBhcHAubWV0YWRhdGFDYWNoZS5tZXRhZGF0YUNhY2hlW2ZpbGUucGF0aF0gPSBjYWNoZTtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgZmlsZXMgaW4gdGhlIE9ic2lkaWFuIGFwcC5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIGFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBmaWxlcyAtIFRoZSBmaWxlcyB0byByZWdpc3Rlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyRmlsZXMoYXBwOiBBcHAsIGZpbGVzOiBUQWJzdHJhY3RGaWxlW10pOiB2b2lkIHtcbiAgY29uc3QgcmVnaXN0ZXJlZEZpbGVzQ291bnRzID0gZ2V0UmVnaXN0ZXJlZEZpbGVzQ291bnRzKGFwcCk7XG5cbiAgZm9yIChsZXQgZmlsZSBvZiBmaWxlcykge1xuICAgIHdoaWxlIChmaWxlLmRlbGV0ZWQpIHtcbiAgICAgIGxldCBjb3VudCA9IHJlZ2lzdGVyZWRGaWxlc0NvdW50cy5nZXQoZmlsZS5wYXRoKSA/PyAwO1xuICAgICAgY291bnQrKztcbiAgICAgIHJlZ2lzdGVyZWRGaWxlc0NvdW50cy5zZXQoZmlsZS5wYXRoLCBjb3VudCk7XG5cbiAgICAgIGFwcC52YXVsdC5maWxlTWFwW2ZpbGUucGF0aF0gPSBmaWxlO1xuXG4gICAgICBpZiAoaXNGaWxlKGZpbGUpKSB7XG4gICAgICAgIGFwcC5tZXRhZGF0YUNhY2hlLnVuaXF1ZUZpbGVMb29rdXAuYWRkKGZpbGUubmFtZS50b0xvd2VyQ2FzZSgpLCBmaWxlKTtcbiAgICAgIH1cblxuICAgICAgZmlsZSA9IGdldEZvbGRlcihhcHAsIHBhcmVudEZvbGRlclBhdGgoZmlsZS5wYXRoKSwgdHJ1ZSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGVtcG9yYXJpbHkgcmVnaXN0ZXJzIGZpbGVzIGFuZCBydW5zIGEgZnVuY3Rpb24uXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIHJlc3VsdCBvZiB0aGUgZnVuY3Rpb24uXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIGFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBmaWxlcyAtIFRoZSBmaWxlcyB0byB0ZW1wb3JhcmlseSByZWdpc3Rlci5cbiAqIEBwYXJhbSBmbiAtIFRoZSBmdW5jdGlvbiB0byBydW4uXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0IG9mIHRoZSBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRlbXBSZWdpc3RlckZpbGVzQW5kUnVuPFQ+KGFwcDogQXBwLCBmaWxlczogVEFic3RyYWN0RmlsZVtdLCBmbjogKCkgPT4gVCk6IFQge1xuICB0cnkge1xuICAgIHJlZ2lzdGVyRmlsZXMoYXBwLCBmaWxlcyk7XG4gICAgcmV0dXJuIGZuKCk7XG4gIH0gZmluYWxseSB7XG4gICAgdW5yZWdpc3RlckZpbGVzKGFwcCwgZmlsZXMpO1xuICB9XG59XG5cbi8qKlxuICogVGVtcG9yYXJpbHkgcmVnaXN0ZXJzIGZpbGVzIGFuZCBydW5zIGFuIGFzeW5jIGZ1bmN0aW9uLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uLlxuICogQHBhcmFtIGFwcCAtIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gZmlsZXMgLSBUaGUgZmlsZXMgdG8gdGVtcG9yYXJpbHkgcmVnaXN0ZXIuXG4gKiBAcGFyYW0gZm4gLSBUaGUgZnVuY3Rpb24gdG8gcnVuLlxuICogQHJldHVybnMgVGhlIHJlc3VsdCBvZiB0aGUgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZW1wUmVnaXN0ZXJGaWxlc0FuZFJ1bkFzeW5jPFQ+KGFwcDogQXBwLCBmaWxlczogVEFic3RyYWN0RmlsZVtdLCBmbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICB0cnkge1xuICAgIHJlZ2lzdGVyRmlsZXMoYXBwLCBmaWxlcyk7XG4gICAgcmV0dXJuIGF3YWl0IGZuKCk7XG4gIH0gZmluYWxseSB7XG4gICAgdW5yZWdpc3RlckZpbGVzKGFwcCwgZmlsZXMpO1xuICB9XG59XG5cbi8qKlxuICogVW5yZWdpc3RlcnMgdGhlIGZpbGUgY2FjaGUgZm9yIGEgbm9uLWV4aXN0aW5nIGZpbGUuXG4gKlxuICogQHBhcmFtIGFwcCAtIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGF0aE9yRmlsZSAtIFRoZSBwYXRoIG9yIGZpbGUgdG8gdW5yZWdpc3RlciB0aGUgZmlsZSBjYWNoZSBmb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bnJlZ2lzdGVyRmlsZUNhY2hlRm9yTm9uRXhpc3RpbmdGaWxlKGFwcDogQXBwLCBwYXRoT3JGaWxlOiBQYXRoT3JGaWxlKTogdm9pZCB7XG4gIGNvbnN0IGZpbGUgPSBnZXRGaWxlKGFwcCwgcGF0aE9yRmlsZSwgdHJ1ZSk7XG4gIGlmICghZmlsZS5kZWxldGVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaWxlIGlzIGV4aXN0aW5nJyk7XG4gIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1keW5hbWljLWRlbGV0ZSAtLSBXZSBoYXZlIG5vIG90aGVyIHdheSB0byBkZWxldGUgdGhlIHByb3BlcnR5LlxuICBkZWxldGUgYXBwLm1ldGFkYXRhQ2FjaGUuZmlsZUNhY2hlW2ZpbGUucGF0aF07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGUgLS0gV2UgaGF2ZSBubyBvdGhlciB3YXkgdG8gZGVsZXRlIHRoZSBwcm9wZXJ0eS5cbiAgZGVsZXRlIGFwcC5tZXRhZGF0YUNhY2hlLm1ldGFkYXRhQ2FjaGVbZmlsZS5wYXRoXTtcbn1cblxuLyoqXG4gKiBVbnJlZ2lzdGVycyBmaWxlcyBmcm9tIHRoZSBPYnNpZGlhbiBhcHAuXG4gKlxuICogQHBhcmFtIGFwcCAtIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gZmlsZXMgLSBUaGUgZmlsZXMgdG8gdW5yZWdpc3Rlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVucmVnaXN0ZXJGaWxlcyhhcHA6IEFwcCwgZmlsZXM6IFRBYnN0cmFjdEZpbGVbXSk6IHZvaWQge1xuICBjb25zdCByZWdpc3RlcmVkRmlsZXNDb3VudHMgPSBnZXRSZWdpc3RlcmVkRmlsZXNDb3VudHMoYXBwKTtcblxuICBmb3IgKGxldCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgd2hpbGUgKGZpbGUuZGVsZXRlZCkge1xuICAgICAgbGV0IGNvdW50ID0gcmVnaXN0ZXJlZEZpbGVzQ291bnRzLmdldChmaWxlLnBhdGgpID8/IDE7XG4gICAgICBjb3VudC0tO1xuICAgICAgcmVnaXN0ZXJlZEZpbGVzQ291bnRzLnNldChmaWxlLnBhdGgsIGNvdW50KTtcbiAgICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgICByZWdpc3RlcmVkRmlsZXNDb3VudHMuZGVsZXRlKGZpbGUucGF0aCk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGUgLS0gV2UgaGF2ZSBubyBvdGhlciB3YXkgdG8gZGVsZXRlIHRoZSBwcm9wZXJ0eS5cbiAgICAgICAgZGVsZXRlIGFwcC52YXVsdC5maWxlTWFwW2ZpbGUucGF0aF07XG5cbiAgICAgICAgaWYgKGlzRmlsZShmaWxlKSkge1xuICAgICAgICAgIGFwcC5tZXRhZGF0YUNhY2hlLnVuaXF1ZUZpbGVMb29rdXAucmVtb3ZlKGZpbGUubmFtZS50b0xvd2VyQ2FzZSgpLCBmaWxlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmaWxlID0gZ2V0Rm9sZGVyKGFwcCwgcGFyZW50Rm9sZGVyUGF0aChmaWxlLnBhdGgpLCB0cnVlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0UmVnaXN0ZXJlZEZpbGVzQ291bnRzKGFwcDogQXBwKTogTWFwPHN0cmluZywgbnVtYmVyPiB7XG4gIHJldHVybiBnZXRPYnNpZGlhbkRldlV0aWxzU3RhdGUoYXBwLCAncmVnaXN0ZXJlZEZpbGVzQ291bnRzJywgbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKSku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