obsidian-dev-utils
Version:
This is the collection of useful functions that you can use for your Obsidian plugin development
254 lines (240 loc) • 14.8 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 {};
}
})();
;
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 CommandBase_exports = {};
__export(CommandBase_exports, {
CommandBase: () => CommandBase,
CommandInvocationBase: () => CommandInvocationBase
});
module.exports = __toCommonJS(CommandBase_exports);
var import_Async = require('../../Async.cjs');
class CommandBase {
/**
* The icon of the command.
*/
icon;
/**
* The ID of the command.
*
* Obsidian changes the passed ID by prepending the plugin's ID to it.
*
* @see {@link originalId}.
*/
id;
/**
* The name of the command.
*
* Obsidian changes the passed name by prepending the plugin's name to it.
*
* @see {@link originalName}.
*/
name;
/**
* The app that the command belongs to.
*/
app;
/**
* The original ID of the command.
*/
originalId;
/**
* The original name of the command.
*/
originalName;
/**
* The plugin that the command belongs to.
*/
plugin;
/**
* Creates a new command.
*
* @param options - The options for the command.
*/
constructor(options) {
this.id = options.id;
this.name = options.name;
this.icon = options.icon;
this.plugin = options.plugin;
this.app = this.plugin.app;
this.originalId = this.id;
this.originalName = this.name;
}
/**
* Registers the command.
*/
register() {
this.plugin.addCommand(this);
}
}
class CommandInvocationBase {
/**
* Creates a new command invocation.
*
* @param plugin - The plugin that the command invocation belongs to.
*/
constructor(plugin) {
this.plugin = plugin;
this.app = plugin.app;
}
/**
* The app that the command invocation belongs to.
*/
app;
lastCanExecuteResult;
/**
* Invokes the command.
*
* @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 was executed.
*/
invoke(checking) {
this.lastCanExecuteResult = this.canExecute();
if (!checking && this.lastCanExecuteResult) {
(0, import_Async.invokeAsyncSafely)(() => this.execute());
}
return this.lastCanExecuteResult;
}
/**
* Invokes the command asynchronously.
*
* @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 A promise that resolves when the command has been executed.
*/
async invokeAsync(checking) {
this.lastCanExecuteResult = this.canExecute();
if (!checking && this.lastCanExecuteResult) {
await this.execute();
}
}
/**
* Checks if the command can execute.
*
* @returns Whether the command can execute.
*/
canExecute() {
return true;
}
/**
* Executes the command.
*/
async execute() {
if (this.lastCanExecuteResult === void 0) {
throw new Error("canExecute() must be called before execute()");
}
if (!this.lastCanExecuteResult) {
throw new Error("canExecute() must return true before execute()");
}
await Promise.resolve();
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CommandBase,
CommandInvocationBase
});
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL0NvbW1hbmRzL0NvbW1hbmRCYXNlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBwYWNrYWdlRG9jdW1lbnRhdGlvblxuICpcbiAqIEJhc2UgY2xhc3NlcyBmb3IgY29tbWFuZHMuXG4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBBcHAsXG4gIENvbW1hbmQsXG4gIEljb25OYW1lLFxuICBQbHVnaW5cbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgeyBpbnZva2VBc3luY1NhZmVseSB9IGZyb20gJy4uLy4uL0FzeW5jLnRzJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciBjcmVhdGluZyBhIGNvbW1hbmQuXG4gKlxuICogQHR5cGVQYXJhbSBUUGx1Z2luIC0gVGhlIHR5cGUgb2YgdGhlIHBsdWdpbiB0aGF0IHRoZSBjb21tYW5kIGJlbG9uZ3MgdG8uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbWFuZEJhc2VPcHRpb25zPFRQbHVnaW4gZXh0ZW5kcyBQbHVnaW4+IHtcbiAgLyoqXG4gICAqIFRoZSBpY29uIHRvIHVzZSBmb3IgdGhlIGNvbW1hbmQuXG4gICAqL1xuICBpY29uOiBJY29uTmFtZTtcblxuICAvKipcbiAgICogVGhlIElEIG9mIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgaWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGNvbW1hbmQuXG4gICAqL1xuICBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBiZWxvbmdzIHRvLlxuICAgKi9cbiAgcGx1Z2luOiBUUGx1Z2luO1xufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGNvbW1hbmRzLlxuICpcbiAqIEB0eXBlUGFyYW0gVFBsdWdpbiAtIFRoZSB0eXBlIG9mIHRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBiZWxvbmdzIHRvLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ29tbWFuZEJhc2U8VFBsdWdpbiBleHRlbmRzIFBsdWdpbj4gaW1wbGVtZW50cyBDb21tYW5kIHtcbiAgLyoqXG4gICAqIFRoZSBpY29uIG9mIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgcHVibGljIGljb246IEljb25OYW1lO1xuXG4gIC8qKlxuICAgKiBUaGUgSUQgb2YgdGhlIGNvbW1hbmQuXG4gICAqXG4gICAqIE9ic2lkaWFuIGNoYW5nZXMgdGhlIHBhc3NlZCBJRCBieSBwcmVwZW5kaW5nIHRoZSBwbHVnaW4ncyBJRCB0byBpdC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgb3JpZ2luYWxJZH0uXG4gICAqL1xuICBwdWJsaWMgaWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGNvbW1hbmQuXG4gICAqXG4gICAqIE9ic2lkaWFuIGNoYW5nZXMgdGhlIHBhc3NlZCBuYW1lIGJ5IHByZXBlbmRpbmcgdGhlIHBsdWdpbidzIG5hbWUgdG8gaXQuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIG9yaWdpbmFsTmFtZX0uXG4gICAqL1xuICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYXBwIHRoYXQgdGhlIGNvbW1hbmQgYmVsb25ncyB0by5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBhcHA6IEFwcDtcblxuICAvKipcbiAgICogVGhlIG9yaWdpbmFsIElEIG9mIHRoZSBjb21tYW5kLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG9yaWdpbmFsSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9yaWdpbmFsIG5hbWUgb2YgdGhlIGNvbW1hbmQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3JpZ2luYWxOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gdGhhdCB0aGUgY29tbWFuZCBiZWxvbmdzIHRvLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHBsdWdpbjogVFBsdWdpbjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBjb21tYW5kLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgY29tbWFuZC5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBDb21tYW5kQmFzZU9wdGlvbnM8VFBsdWdpbj4pIHtcbiAgICB0aGlzLmlkID0gb3B0aW9ucy5pZDtcbiAgICB0aGlzLm5hbWUgPSBvcHRpb25zLm5hbWU7XG4gICAgdGhpcy5pY29uID0gb3B0aW9ucy5pY29uO1xuICAgIHRoaXMucGx1Z2luID0gb3B0aW9ucy5wbHVnaW47XG4gICAgdGhpcy5hcHAgPSB0aGlzLnBsdWdpbi5hcHA7XG4gICAgdGhpcy5vcmlnaW5hbElkID0gdGhpcy5pZDtcbiAgICB0aGlzLm9yaWdpbmFsTmFtZSA9IHRoaXMubmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhlIGNvbW1hbmQuXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXIoKTogdm9pZCB7XG4gICAgdGhpcy5wbHVnaW4uYWRkQ29tbWFuZCh0aGlzKTtcbiAgfVxufVxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGNvbW1hbmQgaW52b2NhdGlvbnMuXG4gKlxuICogQHR5cGVQYXJhbSBUUGx1Z2luIC0gVGhlIHR5cGUgb2YgdGhlIHBsdWdpbiB0aGF0IHRoZSBjb21tYW5kIGJlbG9uZ3MgdG8uXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDb21tYW5kSW52b2NhdGlvbkJhc2U8VFBsdWdpbiBleHRlbmRzIFBsdWdpbiA9IFBsdWdpbj4ge1xuICAvKipcbiAgICogVGhlIGFwcCB0aGF0IHRoZSBjb21tYW5kIGludm9jYXRpb24gYmVsb25ncyB0by5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBhcHA6IEFwcDtcblxuICBwcml2YXRlIGxhc3RDYW5FeGVjdXRlUmVzdWx0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBjb21tYW5kIGludm9jYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBwbHVnaW4gLSBUaGUgcGx1Z2luIHRoYXQgdGhlIGNvbW1hbmQgaW52b2NhdGlvbiBiZWxvbmdzIHRvLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSBwbHVnaW46IFRQbHVnaW4pIHtcbiAgICB0aGlzLmFwcCA9IHBsdWdpbi5hcHA7XG4gIH1cblxuICAvKipcbiAgICogSW52b2tlcyB0aGUgY29tbWFuZC5cbiAgICpcbiAgICogQHBhcmFtIGNoZWNraW5nIC0gSXMgY2hlY2tpbmcgbW9kZSBvbmx5LiBJZiBgdHJ1ZWAsIG9ubHkgdGhlIGNoZWNrIGlmIHRoZSBjb21tYW5kIGNhbiBleGVjdXRlIGlzIHBlcmZvcm1lZC4gSWYgYGZhbHNlYCwgdGhlIGNvbW1hbmQgaXMgZXhlY3V0ZWQuXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGNvbW1hbmQgd2FzIGV4ZWN1dGVkLlxuICAgKi9cbiAgcHVibGljIGludm9rZShjaGVja2luZzogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIHRoaXMubGFzdENhbkV4ZWN1dGVSZXN1bHQgPSB0aGlzLmNhbkV4ZWN1dGUoKTtcbiAgICBpZiAoIWNoZWNraW5nICYmIHRoaXMubGFzdENhbkV4ZWN1dGVSZXN1bHQpIHtcbiAgICAgIGludm9rZUFzeW5jU2FmZWx5KCgpID0+IHRoaXMuZXhlY3V0ZSgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5sYXN0Q2FuRXhlY3V0ZVJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VzIHRoZSBjb21tYW5kIGFzeW5jaHJvbm91c2x5LlxuICAgKlxuICAgKiBAcGFyYW0gY2hlY2tpbmcgLSBJcyBjaGVja2luZyBtb2RlIG9ubHkuIElmIGB0cnVlYCwgb25seSB0aGUgY2hlY2sgaWYgdGhlIGNvbW1hbmQgY2FuIGV4ZWN1dGUgaXMgcGVyZm9ybWVkLiBJZiBgZmFsc2VgLCB0aGUgY29tbWFuZCBpcyBleGVjdXRlZC5cbiAgICogQHJldHVybnMgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY29tbWFuZCBoYXMgYmVlbiBleGVjdXRlZC5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBpbnZva2VBc3luYyhjaGVja2luZzogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubGFzdENhbkV4ZWN1dGVSZXN1bHQgPSB0aGlzLmNhbkV4ZWN1dGUoKTtcbiAgICBpZiAoIWNoZWNraW5nICYmIHRoaXMubGFzdENhbkV4ZWN1dGVSZXN1bHQpIHtcbiAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGNvbW1hbmQgY2FuIGV4ZWN1dGUuXG4gICAqXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdGhlIGNvbW1hbmQgY2FuIGV4ZWN1dGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2FuRXhlY3V0ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyB0aGUgY29tbWFuZC5cbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBleGVjdXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmxhc3RDYW5FeGVjdXRlUmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2FuRXhlY3V0ZSgpIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBleGVjdXRlKCknKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmxhc3RDYW5FeGVjdXRlUmVzdWx0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbkV4ZWN1dGUoKSBtdXN0IHJldHVybiB0cnVlIGJlZm9yZSBleGVjdXRlKCknKTtcbiAgICB9XG4gICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFhQSxtQkFBa0M7QUFrQzNCLE1BQWUsWUFBdUQ7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlwRTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFTQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS1k7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPWixZQUFZLFNBQXNDO0FBQ3ZELFNBQUssS0FBSyxRQUFRO0FBQ2xCLFNBQUssT0FBTyxRQUFRO0FBQ3BCLFNBQUssT0FBTyxRQUFRO0FBQ3BCLFNBQUssU0FBUyxRQUFRO0FBQ3RCLFNBQUssTUFBTSxLQUFLLE9BQU87QUFDdkIsU0FBSyxhQUFhLEtBQUs7QUFDdkIsU0FBSyxlQUFlLEtBQUs7QUFBQSxFQUMzQjtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS08sV0FBaUI7QUFDdEIsU0FBSyxPQUFPLFdBQVcsSUFBSTtBQUFBLEVBQzdCO0FBQ0Y7QUFPTyxNQUFlLHNCQUF1RDtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQWFwRSxZQUErQixRQUFpQjtBQUFqQjtBQUNwQyxTQUFLLE1BQU0sT0FBTztBQUFBLEVBQ3BCO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFYbUI7QUFBQSxFQUVYO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFpQkQsT0FBTyxVQUE0QjtBQUN4QyxTQUFLLHVCQUF1QixLQUFLLFdBQVc7QUFDNUMsUUFBSSxDQUFDLFlBQVksS0FBSyxzQkFBc0I7QUFDMUMsMENBQWtCLE1BQU0sS0FBSyxRQUFRLENBQUM7QUFBQSxJQUN4QztBQUVBLFdBQU8sS0FBSztBQUFBLEVBQ2Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVFBLE1BQWEsWUFBWSxVQUFrQztBQUN6RCxTQUFLLHVCQUF1QixLQUFLLFdBQVc7QUFDNUMsUUFBSSxDQUFDLFlBQVksS0FBSyxzQkFBc0I7QUFDMUMsWUFBTSxLQUFLLFFBQVE7QUFBQSxJQUNyQjtBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPVSxhQUFzQjtBQUM5QixXQUFPO0FBQUEsRUFDVDtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0EsTUFBZ0IsVUFBeUI7QUFDdkMsUUFBSSxLQUFLLHlCQUF5QixRQUFXO0FBQzNDLFlBQU0sSUFBSSxNQUFNLDhDQUE4QztBQUFBLElBQ2hFO0FBQ0EsUUFBSSxDQUFDLEtBQUssc0JBQXNCO0FBQzlCLFlBQU0sSUFBSSxNQUFNLGdEQUFnRDtBQUFBLElBQ2xFO0FBQ0EsVUFBTSxRQUFRLFFBQVE7QUFBQSxFQUN4QjtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=