obsidian-dev-utils
Version:
This is the collection of useful functions that you can use for your Obsidian plugin development
361 lines (347 loc) • 30.9 kB
JavaScript
/*
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 AbstractFileCommandBase_exports = {};
__export(AbstractFileCommandBase_exports, {
AbstractFileCommandBase: () => AbstractFileCommandBase,
AbstractFileCommandInvocationBase: () => AbstractFileCommandInvocationBase,
AbstractFilesCommandInvocationBase: () => AbstractFilesCommandInvocationBase,
ArrayDelegatingAbstractFileCommandInvocation: () => ArrayDelegatingAbstractFileCommandInvocation,
SequentialAbstractFilesCommandInvocationBase: () => SequentialAbstractFilesCommandInvocationBase
});
module.exports = __toCommonJS(AbstractFileCommandBase_exports);
var import_CommandBase = require('./CommandBase.cjs');
var import_NonEditorCommandBase = require('./NonEditorCommandBase.cjs');
class AbstractFileCommandBase extends import_NonEditorCommandBase.NonEditorCommandBase {
/**
* The item name to use in the file menu.
*/
fileMenuItemName;
/**
* The section to use in the file menu.
*/
fileMenuSection;
/**
* The item name to use in the files menu.
*/
filesMenuItemName;
/**
* The section to use in the files menu.
*/
filesMenuSection;
/**
* Checks if the command can execute or executes it.
*
* @param checking - Is checking mode only. If `true`, only the check if the command can execute is performed. If `false`, the command is executed.
* @returns Whether the command can execute.
*/
checkCallback(checking) {
if (!this.shouldAddToCommandPalette()) {
return false;
}
return super.checkCallback(checking);
}
/**
* Registers the command.
*/
register() {
super.register();
this.plugin.registerEvent(this.app.workspace.on("file-menu", this.handleAbstractFileMenu.bind(this)));
this.plugin.registerEvent(this.app.workspace.on("files-menu", this.handleAbstractFilesMenu.bind(this)));
}
/**
* Creates a new file command invocation.
*
* @param abstractFile - The abstract file to create the command invocation for.
* @returns The command invocation.
*/
createCommandInvocation(abstractFile) {
return this.createCommandInvocationForAbstractFile(abstractFile ?? this.app.workspace.getActiveFile());
}
/**
* Creates a new command invocation for abstract files.
*
* @param abstractFiles - The abstract files to create the command invocation for.
* @returns The command invocation.
*/
createCommandInvocationForAbstractFiles(abstractFiles) {
return new SequentialAbstractFilesCommandInvocationBase(this.plugin, abstractFiles, this.createCommandInvocationForAbstractFile.bind(this));
}
/**
* Checks if the command should be added to the abstract file menu.
*
* @param _abstractFile - The abstract file to check.
* @param _source - The source of the abstract file.
* @param _leaf - The leaf to check.
* @returns Whether the command should be added to the abstract file menu.
*/
shouldAddToAbstractFileMenu(_abstractFile, _source, _leaf) {
return false;
}
/**
* Checks if the command should be added to the abstract files menu.
*
* @param abstractFiles - The abstract files to check.
* @param source - The source of the abstract files.
* @param leaf - The leaf to check.
* @returns Whether the command should be added to the abstract files menu.
*/
shouldAddToAbstractFilesMenu(abstractFiles, source, leaf) {
for (const abstractFile of abstractFiles) {
if (!this.shouldAddToAbstractFileMenu(abstractFile, source, leaf)) {
return false;
}
}
return true;
}
/**
* Checks if the command should be added to the command palette.
*
* @returns Whether the command should be added to the command palette.
*/
shouldAddToCommandPalette() {
return true;
}
handleAbstractFileMenu(menu, abstractFile, source, leaf) {
if (!this.shouldAddToAbstractFileMenu(abstractFile, source, leaf)) {
return;
}
if (!this.createCommandInvocation(abstractFile).invoke(true)) {
return;
}
menu.addItem((item) => {
item.setTitle(this.fileMenuItemName ?? this.originalName).setIcon(this.icon).setSection(this.fileMenuSection ?? "").onClick(() => this.createCommandInvocation(abstractFile).invoke(false));
});
}
handleAbstractFilesMenu(menu, abstractFiles, source, leaf) {
if (!this.shouldAddToAbstractFilesMenu(abstractFiles, source, leaf)) {
return;
}
if (!this.createCommandInvocationForAbstractFiles(abstractFiles).invoke(true)) {
return;
}
menu.addItem((item) => {
item.setTitle(this.filesMenuItemName ?? this.fileMenuItemName ?? this.originalName).setIcon(this.icon).setSection(this.filesMenuSection ?? this.fileMenuSection ?? "").onClick(() => this.createCommandInvocationForAbstractFiles(abstractFiles).invoke(false));
});
}
}
class AbstractFileCommandInvocationBase extends import_CommandBase.CommandInvocationBase {
/** */
_abstractFile;
/**
* The abstract file to invoke the command for.
*
* @returns The abstract file to invoke the command for.
* @throws If the abstract file is not set.
*/
get abstractFile() {
if (!this._abstractFile) {
throw new Error("Abstract file not set");
}
return this._abstractFile;
}
/**
* Creates a new abstract file command invocation.
*
* @param plugin - The plugin that the command belongs to.
* @param abstractFile - The abstract file to invoke the command for.
*/
constructor(plugin, abstractFile) {
super(plugin);
this._abstractFile = abstractFile;
}
/**
* Checks if the command can execute.
*
* @returns Whether the command can execute.
*/
canExecute() {
return super.canExecute() && !!this._abstractFile;
}
}
class AbstractFilesCommandInvocationBase extends import_CommandBase.CommandInvocationBase {
/**
* Creates a new abstract files command invocation.
*
* @param plugin - The plugin that the command belongs to.
* @param abstractFiles - The abstract files to invoke the command for.
*/
constructor(plugin, abstractFiles) {
super(plugin);
this.abstractFiles = abstractFiles;
}
}
class ArrayDelegatingAbstractFileCommandInvocation extends AbstractFileCommandInvocationBase {
/**
* Creates a new array-delegating abstract file command invocation.
*
* @param plugin - The plugin that the command invocation belongs to.
* @param abstractFile - The abstract file to invoke the command for.
* @param createCommandInvocationForFiles - The function to create a command invocation for files.
*/
constructor(plugin, abstractFile, createCommandInvocationForFiles) {
super(plugin, abstractFile);
this.createCommandInvocationForFiles = createCommandInvocationForFiles;
}
/**
* Checks if the command can execute.
*
* @returns Whether the command can execute.
*/
canExecute() {
return super.canExecute() && this.createCommandInvocationForFiles([this.abstractFile]).invoke(true);
}
/**
* Executes the command.
*
* @returns A promise that resolves when the command has been executed.
*/
async execute() {
await this.createCommandInvocationForFiles([this.abstractFile]).invokeAsync(false);
}
}
class SequentialAbstractFilesCommandInvocationBase extends AbstractFilesCommandInvocationBase {
/**
* Creates a new sequential files command invocation.
*
* @param plugin - The plugin that the command invocation belongs to.
* @param abstractFiles - The files to invoke the command for.
* @param createCommandInvocationForFile - The function to create a command invocation for a file.
*/
constructor(plugin, abstractFiles, createCommandInvocationForFile) {
super(plugin, abstractFiles);
this.createCommandInvocationForFile = createCommandInvocationForFile;
}
/**
* Checks if the command can execute.
*
* @returns Whether the command can execute.
*/
canExecute() {
return super.canExecute() && this.abstractFiles.length > 0 && this.abstractFiles.every((file) => this.createCommandInvocationForFile(file).invoke(true));
}
/**
* Executes the command.
*
* @returns A promise that resolves when the command has been executed.
*/
async execute() {
for (const abstractFile of this.abstractFiles) {
await this.createCommandInvocationForFile(abstractFile).invokeAsync(false);
}
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
AbstractFileCommandBase,
AbstractFileCommandInvocationBase,
AbstractFilesCommandInvocationBase,
ArrayDelegatingAbstractFileCommandInvocation,
SequentialAbstractFilesCommandInvocationBase
});
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL0NvbW1hbmRzL0Fic3RyYWN0RmlsZUNvbW1hbmRCYXNlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICpcbiAqIEJhc2UgY2xhc3NlcyBmb3IgYWJzdHJhY3QgZmlsZSBjb21tYW5kcy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIE1lbnUsXG4gIFBsdWdpbixcbiAgVEFic3RyYWN0RmlsZSxcbiAgV29ya3NwYWNlTGVhZlxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7IENvbW1hbmRJbnZvY2F0aW9uQmFzZSB9IGZyb20gJy4vQ29tbWFuZEJhc2UudHMnO1xuaW1wb3J0IHsgTm9uRWRpdG9yQ29tbWFuZEJhc2UgfSBmcm9tICcuL05vbkVkaXRvckNvbW1hbmRCYXNlLnRzJztcblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhYnN0cmFjdCBmaWxlIGNvbW1hbmRzLlxuICpcbiAqIEB0eXBlUGFyYW0gVFBsdWdpbiAtIFRoZSB0eXBlIG9mIHRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBiZWxvbmdzIHRvLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RGaWxlQ29tbWFuZEJhc2U8VFBsdWdpbiBleHRlbmRzIFBsdWdpbiA9IFBsdWdpbj4gZXh0ZW5kcyBOb25FZGl0b3JDb21tYW5kQmFzZTxUUGx1Z2luPiB7XG4gIC8qKlxuICAgKiBUaGUgaXRlbSBuYW1lIHRvIHVzZSBpbiB0aGUgZmlsZSBtZW51LlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZpbGVNZW51SXRlbU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN0aW9uIHRvIHVzZSBpbiB0aGUgZmlsZSBtZW51LlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGZpbGVNZW51U2VjdGlvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGl0ZW0gbmFtZSB0byB1c2UgaW4gdGhlIGZpbGVzIG1lbnUuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZmlsZXNNZW51SXRlbU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBzZWN0aW9uIHRvIHVzZSBpbiB0aGUgZmlsZXMgbWVudS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBmaWxlc01lbnVTZWN0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGNvbW1hbmQgY2FuIGV4ZWN1dGUgb3IgZXhlY3V0ZXMgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBjaGVja2luZyAtIElzIGNoZWNraW5nIG1vZGUgb25seS4gSWYgYHRydWVgLCBvbmx5IHRoZSBjaGVjayBpZiB0aGUgY29tbWFuZCBjYW4gZXhlY3V0ZSBpcyBwZXJmb3JtZWQuIElmIGBmYWxzZWAsIHRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkLlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBjb21tYW5kIGNhbiBleGVjdXRlLlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIGNoZWNrQ2FsbGJhY2soY2hlY2tpbmc6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkQWRkVG9Db21tYW5kUGFsZXR0ZSgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBzdXBlci5jaGVja0NhbGxiYWNrKGNoZWNraW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhlIGNvbW1hbmQuXG4gICAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgcmVnaXN0ZXIoKTogdm9pZCB7XG4gICAgc3VwZXIucmVnaXN0ZXIoKTtcbiAgICB0aGlzLnBsdWdpbi5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLndvcmtzcGFjZS5vbignZmlsZS1tZW51JywgdGhpcy5oYW5kbGVBYnN0cmFjdEZpbGVNZW51LmJpbmQodGhpcykpKTtcbiAgICB0aGlzLnBsdWdpbi5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLndvcmtzcGFjZS5vbignZmlsZXMtbWVudScsIHRoaXMuaGFuZGxlQWJzdHJhY3RGaWxlc01lbnUuYmluZCh0aGlzKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgZmlsZSBjb21tYW5kIGludm9jYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBhYnN0cmFjdEZpbGUgLSBUaGUgYWJzdHJhY3QgZmlsZSB0byBjcmVhdGUgdGhlIGNvbW1hbmQgaW52b2NhdGlvbiBmb3IuXG4gICAqIEByZXR1cm5zIFRoZSBjb21tYW5kIGludm9jYXRpb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgY3JlYXRlQ29tbWFuZEludm9jYXRpb24oYWJzdHJhY3RGaWxlPzogVEFic3RyYWN0RmlsZSk6IEFic3RyYWN0RmlsZUNvbW1hbmRJbnZvY2F0aW9uQmFzZTxUUGx1Z2luPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlQ29tbWFuZEludm9jYXRpb25Gb3JBYnN0cmFjdEZpbGUoYWJzdHJhY3RGaWxlID8/IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgY29tbWFuZCBpbnZvY2F0aW9uIGZvciBhbiBhYnN0cmFjdCBmaWxlLlxuICAgKlxuICAgKiBAcGFyYW0gYWJzdHJhY3RGaWxlIC0gVGhlIGFic3RyYWN0IGZpbGUgdG8gY3JlYXRlIHRoZSBjb21tYW5kIGludm9jYXRpb24gZm9yLlxuICAgKiBAcmV0dXJucyBUaGUgY29tbWFuZCBpbnZvY2F0aW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uRm9yQWJzdHJhY3RGaWxlKGFic3RyYWN0RmlsZTogbnVsbCB8IFRBYnN0cmFjdEZpbGUpOiBBYnN0cmFjdEZpbGVDb21tYW5kSW52b2NhdGlvbkJhc2U8VFBsdWdpbj47XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgY29tbWFuZCBpbnZvY2F0aW9uIGZvciBhYnN0cmFjdCBmaWxlcy5cbiAgICpcbiAgICogQHBhcmFtIGFic3RyYWN0RmlsZXMgLSBUaGUgYWJzdHJhY3QgZmlsZXMgdG8gY3JlYXRlIHRoZSBjb21tYW5kIGludm9jYXRpb24gZm9yLlxuICAgKiBAcmV0dXJucyBUaGUgY29tbWFuZCBpbnZvY2F0aW9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uRm9yQWJzdHJhY3RGaWxlcyhhYnN0cmFjdEZpbGVzOiBUQWJzdHJhY3RGaWxlW10pOiBBYnN0cmFjdEZpbGVzQ29tbWFuZEludm9jYXRpb25CYXNlPFRQbHVnaW4+IHtcbiAgICByZXR1cm4gbmV3IFNlcXVlbnRpYWxBYnN0cmFjdEZpbGVzQ29tbWFuZEludm9jYXRpb25CYXNlKHRoaXMucGx1Z2luLCBhYnN0cmFjdEZpbGVzLCB0aGlzLmNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uRm9yQWJzdHJhY3RGaWxlLmJpbmQodGhpcykpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgY29tbWFuZCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGFic3RyYWN0IGZpbGUgbWVudS5cbiAgICpcbiAgICogQHBhcmFtIF9hYnN0cmFjdEZpbGUgLSBUaGUgYWJzdHJhY3QgZmlsZSB0byBjaGVjay5cbiAgICogQHBhcmFtIF9zb3VyY2UgLSBUaGUgc291cmNlIG9mIHRoZSBhYnN0cmFjdCBmaWxlLlxuICAgKiBAcGFyYW0gX2xlYWYgLSBUaGUgbGVhZiB0byBjaGVjay5cbiAgICogQHJldHVybnMgV2hldGhlciB0aGUgY29tbWFuZCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGFic3RyYWN0IGZpbGUgbWVudS5cbiAgICovXG4gIHByb3RlY3RlZCBzaG91bGRBZGRUb0Fic3RyYWN0RmlsZU1lbnUoX2Fic3RyYWN0RmlsZTogVEFic3RyYWN0RmlsZSwgX3NvdXJjZTogc3RyaW5nLCBfbGVhZj86IFdvcmtzcGFjZUxlYWYpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBjb21tYW5kIHNob3VsZCBiZSBhZGRlZCB0byB0aGUgYWJzdHJhY3QgZmlsZXMgbWVudS5cbiAgICpcbiAgICogQHBhcmFtIGFic3RyYWN0RmlsZXMgLSBUaGUgYWJzdHJhY3QgZmlsZXMgdG8gY2hlY2suXG4gICAqIEBwYXJhbSBzb3VyY2UgLSBUaGUgc291cmNlIG9mIHRoZSBhYnN0cmFjdCBmaWxlcy5cbiAgICogQHBhcmFtIGxlYWYgLSBUaGUgbGVhZiB0byBjaGVjay5cbiAgICogQHJldHVybnMgV2hldGhlciB0aGUgY29tbWFuZCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGFic3RyYWN0IGZpbGVzIG1lbnUuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2hvdWxkQWRkVG9BYnN0cmFjdEZpbGVzTWVudShhYnN0cmFjdEZpbGVzOiBUQWJzdHJhY3RGaWxlW10sIHNvdXJjZTogc3RyaW5nLCBsZWFmPzogV29ya3NwYWNlTGVhZik6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgYWJzdHJhY3RGaWxlIG9mIGFic3RyYWN0RmlsZXMpIHtcbiAgICAgIGlmICghdGhpcy5zaG91bGRBZGRUb0Fic3RyYWN0RmlsZU1lbnUoYWJzdHJhY3RGaWxlLCBzb3VyY2UsIGxlYWYpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGNvbW1hbmQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBjb21tYW5kIHBhbGV0dGUuXG4gICAqXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGNvbW1hbmQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBjb21tYW5kIHBhbGV0dGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2hvdWxkQWRkVG9Db21tYW5kUGFsZXR0ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQWJzdHJhY3RGaWxlTWVudShtZW51OiBNZW51LCBhYnN0cmFjdEZpbGU6IFRBYnN0cmFjdEZpbGUsIHNvdXJjZTogc3RyaW5nLCBsZWFmPzogV29ya3NwYWNlTGVhZik6IHZvaWQge1xuICAgIGlmICghdGhpcy5zaG91bGRBZGRUb0Fic3RyYWN0RmlsZU1lbnUoYWJzdHJhY3RGaWxlLCBzb3VyY2UsIGxlYWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uKGFic3RyYWN0RmlsZSkuaW52b2tlKHRydWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbWVudS5hZGRJdGVtKChpdGVtKSA9PiB7XG4gICAgICBpdGVtXG4gICAgICAgIC5zZXRUaXRsZSh0aGlzLmZpbGVNZW51SXRlbU5hbWUgPz8gdGhpcy5vcmlnaW5hbE5hbWUpXG4gICAgICAgIC5zZXRJY29uKHRoaXMuaWNvbilcbiAgICAgICAgLnNldFNlY3Rpb24odGhpcy5maWxlTWVudVNlY3Rpb24gPz8gJycpXG4gICAgICAgIC5vbkNsaWNrKCgpID0+IHRoaXMuY3JlYXRlQ29tbWFuZEludm9jYXRpb24oYWJzdHJhY3RGaWxlKS5pbnZva2UoZmFsc2UpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQWJzdHJhY3RGaWxlc01lbnUobWVudTogTWVudSwgYWJzdHJhY3RGaWxlczogVEFic3RyYWN0RmlsZVtdLCBzb3VyY2U6IHN0cmluZywgbGVhZj86IFdvcmtzcGFjZUxlYWYpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkQWRkVG9BYnN0cmFjdEZpbGVzTWVudShhYnN0cmFjdEZpbGVzLCBzb3VyY2UsIGxlYWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLmNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uRm9yQWJzdHJhY3RGaWxlcyhhYnN0cmFjdEZpbGVzKS5pbnZva2UodHJ1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBtZW51LmFkZEl0ZW0oKGl0ZW0pID0+IHtcbiAgICAgIGl0ZW1cbiAgICAgICAgLnNldFRpdGxlKHRoaXMuZmlsZXNNZW51SXRlbU5hbWUgPz8gdGhpcy5maWxlTWVudUl0ZW1OYW1lID8/IHRoaXMub3JpZ2luYWxOYW1lKVxuICAgICAgICAuc2V0SWNvbih0aGlzLmljb24pXG4gICAgICAgIC5zZXRTZWN0aW9uKHRoaXMuZmlsZXNNZW51U2VjdGlvbiA/PyB0aGlzLmZpbGVNZW51U2VjdGlvbiA/PyAnJylcbiAgICAgICAgLm9uQ2xpY2soKCkgPT4gdGhpcy5jcmVhdGVDb21tYW5kSW52b2NhdGlvbkZvckFic3RyYWN0RmlsZXMoYWJzdHJhY3RGaWxlcykuaW52b2tlKGZhbHNlKSk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhYnN0cmFjdCBmaWxlIGNvbW1hbmQgaW52b2NhdGlvbnMuXG4gKlxuICogQHR5cGVQYXJhbSBUUGx1Z2luIC0gVGhlIHR5cGUgb2YgdGhlIHBsdWdpbiB0aGF0IHRoZSBjb21tYW5kIGJlbG9uZ3MgdG8uXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBYnN0cmFjdEZpbGVDb21tYW5kSW52b2NhdGlvbkJhc2U8VFBsdWdpbiBleHRlbmRzIFBsdWdpbj4gZXh0ZW5kcyBDb21tYW5kSW52b2NhdGlvbkJhc2U8VFBsdWdpbj4ge1xuICAvKiogKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9hYnN0cmFjdEZpbGU6IG51bGwgfCBUQWJzdHJhY3RGaWxlO1xuXG4gIC8qKlxuICAgKiBUaGUgYWJzdHJhY3QgZmlsZSB0byBpbnZva2UgdGhlIGNvbW1hbmQgZm9yLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgYWJzdHJhY3QgZmlsZSB0byBpbnZva2UgdGhlIGNvbW1hbmQgZm9yLlxuICAgKiBAdGhyb3dzIElmIHRoZSBhYnN0cmFjdCBmaWxlIGlzIG5vdCBzZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IGFic3RyYWN0RmlsZSgpOiBUQWJzdHJhY3RGaWxlIHtcbiAgICBpZiAoIXRoaXMuX2Fic3RyYWN0RmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBYnN0cmFjdCBmaWxlIG5vdCBzZXQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Fic3RyYWN0RmlsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGFic3RyYWN0IGZpbGUgY29tbWFuZCBpbnZvY2F0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gcGx1Z2luIC0gVGhlIHBsdWdpbiB0aGF0IHRoZSBjb21tYW5kIGJlbG9uZ3MgdG8uXG4gICAqIEBwYXJhbSBhYnN0cmFjdEZpbGUgLSBUaGUgYWJzdHJhY3QgZmlsZSB0byBpbnZva2UgdGhlIGNvbW1hbmQgZm9yLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBsdWdpbjogVFBsdWdpbiwgYWJzdHJhY3RGaWxlOiBudWxsIHwgVEFic3RyYWN0RmlsZSkge1xuICAgIHN1cGVyKHBsdWdpbik7XG4gICAgdGhpcy5fYWJzdHJhY3RGaWxlID0gYWJzdHJhY3RGaWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgY29tbWFuZCBjYW4gZXhlY3V0ZS5cbiAgICpcbiAgICogQHJldHVybnMgV2hldGhlciB0aGUgY29tbWFuZCBjYW4gZXhlY3V0ZS5cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBjYW5FeGVjdXRlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzdXBlci5jYW5FeGVjdXRlKCkgJiYgISF0aGlzLl9hYnN0cmFjdEZpbGU7XG4gIH1cbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhYnN0cmFjdCBmaWxlcyBjb21tYW5kIGludm9jYXRpb25zLlxuICpcbiAqIEB0eXBlUGFyYW0gVFBsdWdpbiAtIFRoZSB0eXBlIG9mIHRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBiZWxvbmdzIHRvLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQWJzdHJhY3RGaWxlc0NvbW1hbmRJbnZvY2F0aW9uQmFzZTxUUGx1Z2luIGV4dGVuZHMgUGx1Z2luPiBleHRlbmRzIENvbW1hbmRJbnZvY2F0aW9uQmFzZTxUUGx1Z2luPiB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGFic3RyYWN0IGZpbGVzIGNvbW1hbmQgaW52b2NhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBiZWxvbmdzIHRvLlxuICAgKiBAcGFyYW0gYWJzdHJhY3RGaWxlcyAtIFRoZSBhYnN0cmFjdCBmaWxlcyB0byBpbnZva2UgdGhlIGNvbW1hbmQgZm9yLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBsdWdpbjogVFBsdWdpbiwgcHVibGljIHJlYWRvbmx5IGFic3RyYWN0RmlsZXM6IFRBYnN0cmFjdEZpbGVbXSkge1xuICAgIHN1cGVyKHBsdWdpbik7XG4gIH1cbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBhcnJheS1kZWxlZ2F0aW5nIGFic3RyYWN0IGZpbGUgY29tbWFuZCBpbnZvY2F0aW9ucy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRQbHVnaW4gLSBUaGUgdHlwZSBvZiB0aGUgcGx1Z2luIHRoYXQgdGhlIGNvbW1hbmQgYmVsb25ncyB0by5cbiAqL1xuZXhwb3J0IGNsYXNzIEFycmF5RGVsZWdhdGluZ0Fic3RyYWN0RmlsZUNvbW1hbmRJbnZvY2F0aW9uPFRQbHVnaW4gZXh0ZW5kcyBQbHVnaW4+IGV4dGVuZHMgQWJzdHJhY3RGaWxlQ29tbWFuZEludm9jYXRpb25CYXNlPFRQbHVnaW4+IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYXJyYXktZGVsZWdhdGluZyBhYnN0cmFjdCBmaWxlIGNvbW1hbmQgaW52b2NhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHBsdWdpbiAtIFRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBpbnZvY2F0aW9uIGJlbG9uZ3MgdG8uXG4gICAqIEBwYXJhbSBhYnN0cmFjdEZpbGUgLSBUaGUgYWJzdHJhY3QgZmlsZSB0byBpbnZva2UgdGhlIGNvbW1hbmQgZm9yLlxuICAgKiBAcGFyYW0gY3JlYXRlQ29tbWFuZEludm9jYXRpb25Gb3JGaWxlcyAtIFRoZSBmdW5jdGlvbiB0byBjcmVhdGUgYSBjb21tYW5kIGludm9jYXRpb24gZm9yIGZpbGVzLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIHBsdWdpbjogVFBsdWdpbixcbiAgICBhYnN0cmFjdEZpbGU6IG51bGwgfCBUQWJzdHJhY3RGaWxlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY3JlYXRlQ29tbWFuZEludm9jYXRpb25Gb3JGaWxlczogKGFic3RyYWN0RmlsZXM6IFRBYnN0cmFjdEZpbGVbXSkgPT4gQWJzdHJhY3RGaWxlc0NvbW1hbmRJbnZvY2F0aW9uQmFzZTxUUGx1Z2luPlxuICApIHtcbiAgICBzdXBlcihwbHVnaW4sIGFic3RyYWN0RmlsZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIHRoZSBjb21tYW5kIGNhbiBleGVjdXRlLlxuICAgKlxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBjb21tYW5kIGNhbiBleGVjdXRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGNhbkV4ZWN1dGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHN1cGVyLmNhbkV4ZWN1dGUoKSAmJiB0aGlzLmNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uRm9yRmlsZXMoW3RoaXMuYWJzdHJhY3RGaWxlXSkuaW52b2tlKHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIHRoZSBjb21tYW5kLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBjb21tYW5kIGhhcyBiZWVuIGV4ZWN1dGVkLlxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGV4ZWN1dGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jcmVhdGVDb21tYW5kSW52b2NhdGlvbkZvckZpbGVzKFt0aGlzLmFic3RyYWN0RmlsZV0pLmludm9rZUFzeW5jKGZhbHNlKTtcbiAgfVxufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHNlcXVlbnRpYWwgYWJzdHJhY3QgZmlsZXMgY29tbWFuZCBpbnZvY2F0aW9ucy5cbiAqXG4gKiBAdHlwZVBhcmFtIFRQbHVnaW4gLSBUaGUgdHlwZSBvZiB0aGUgcGx1Z2luIHRoYXQgdGhlIGNvbW1hbmQgYmVsb25ncyB0by5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlcXVlbnRpYWxBYnN0cmFjdEZpbGVzQ29tbWFuZEludm9jYXRpb25CYXNlPFRQbHVnaW4gZXh0ZW5kcyBQbHVnaW4+IGV4dGVuZHMgQWJzdHJhY3RGaWxlc0NvbW1hbmRJbnZvY2F0aW9uQmFzZTxUUGx1Z2luPiB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHNlcXVlbnRpYWwgZmlsZXMgY29tbWFuZCBpbnZvY2F0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gcGx1Z2luIC0gVGhlIHBsdWdpbiB0aGF0IHRoZSBjb21tYW5kIGludm9jYXRpb24gYmVsb25ncyB0by5cbiAgICogQHBhcmFtIGFic3RyYWN0RmlsZXMgLSBUaGUgZmlsZXMgdG8gaW52b2tlIHRoZSBjb21tYW5kIGZvci5cbiAgICogQHBhcmFtIGNyZWF0ZUNvbW1hbmRJbnZvY2F0aW9uRm9yRmlsZSAtIFRoZSBmdW5jdGlvbiB0byBjcmVhdGUgYSBjb21tYW5kIGludm9jYXRpb24gZm9yIGEgZmlsZS5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICBwbHVnaW46IFRQbHVnaW4sXG4gICAgYWJzdHJhY3RGaWxlczogVEFic3RyYWN0RmlsZVtdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY3JlYXRlQ29tbWFuZEludm9jYXRpb25Gb3JGaWxlOiAoYWJzdHJhY3RGaWxlOiBUQWJzdHJhY3RGaWxlKSA9PiBBYnN0cmFjdEZpbGVDb21tYW5kSW52b2NhdGlvbkJhc2U8VFBsdWdpbj5cbiAgKSB7XG4gICAgc3VwZXIocGx1Z2luLCBhYnN0cmFjdEZpbGVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGNvbW1hbmQgY2FuIGV4ZWN1dGUuXG4gICAqXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGNvbW1hbmQgY2FuIGV4ZWN1dGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgY2FuRXhlY3V0ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gc3VwZXIuY2FuRXhlY3V0ZSgpICYmIHRoaXMuYWJzdHJhY3RGaWxlcy5sZW5ndGggPiAwICYmIHRoaXMuYWJzdHJhY3RGaWxlcy5ldmVyeSgoZmlsZSkgPT4gdGhpcy5jcmVhdGVDb21tYW5kSW52b2NhdGlvbkZvckZpbGUoZmlsZSkuaW52b2tlKHRydWUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyB0aGUgY29tbWFuZC5cbiAgICpcbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29tbWFuZCBoYXMgYmVlbiBleGVjdXRlZC5cbiAgICovXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBleGVjdXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgYWJzdHJhY3RGaWxlIG9mIHRoaXMuYWJzdHJhY3RGaWxlcykge1xuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVDb21tYW5kSW52b2NhdGlvbkZvckZpbGUoYWJzdHJhY3RGaWxlKS5pbnZva2VBc3luYyhmYWxzZSk7XG4gICAgfVxuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFB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