@jsprismarine/logger
Version:
JSPrismarine logger and utilities
164 lines (163 loc) • 17.2 kB
JavaScript
import { PrismarineTransport } from "./transport.es.js";
import colorParser from "@jsprismarine/color-parser";
import * as winston from "winston";
import { format } from "winston";
//#region src/logger.ts
/**
* Helper class for general logging.
* @document ../../../docs/log-levels.md
* @class
* @public
*/
var Logger = class {
/**
* The internal logger instance.
* @type {Winston}
* @private
* @internal
*/
logger = null;
/**
* Create a new logger instance
* @param {LogLevel} level - The log level to use.
* @param {TransportStream[]} transports - The transports to use.
* @returns {Logger} The logger instance.
*/
constructor(level = "info", transports = []) {
this.createLogger(level, transports);
}
/**
* Create a new logger instance
*
* @returns {void}
*/
createLogger(level = "info", transports = []) {
if (this.logger && !this.logger.closed) return;
this.logger = winston.createLogger({
level,
format: format.combine(format.timestamp({ format: "HH:mm:ss" }), format((info) => {
info.level = info.level.toUpperCase();
return info;
})(), format.colorize(), format.simple()),
transports: [new PrismarineTransport({ format: format.printf(({ level, message, timestamp, namespace: ns }) => {
return colorParser(`[${`${timestamp} ${level}${ns ? ` ${ns}` : ""}`}§r]: ${message}§r`);
}) }), ...transports]
});
}
/**
* On enable hook.
* @group Lifecycle
*/
async enable() {
this.createLogger();
}
/**
* On disable hook.
* @group Lifecycle
*/
async disable() {
this.logger.close();
this.logger = null;
}
/**
* Listen for log messages.
* @param {(level: LogLevel, message: string) => void} listener - The listener to call when a log message is received.
* @event
*/
onLine(listener) {
this.logger.on("data", (data) => listener(data.message.toString()));
}
/**
* Set the console instance to use.
* @param {ConsoleLike} console - The console instance to use.
*/
setConsole(console) {
if (!console) return;
this.logger.transports[0].console = console;
}
/**
* Get callee's namespace from the stack trace.
* @private
* @internal
*/
getNamespace = () => {
const stack = (/* @__PURE__ */ new Error()).stack.replaceAll("\\", "/");
if (!stack) return "";
const caller = (stack.split("\n")[3] || "").trim();
if (!caller) return "";
const file = caller.match(/\(([^)]+)\)/)?.[1]?.split("src/")[1] || "";
if (!file) return "";
const path = file.split(":").slice(0, -2).join(":").slice(0, -3);
if (!path) return "";
const lineCol = file.split(":").slice(-2).join(":");
if (!lineCol) return "";
if (this.logger.level === "silly" || this.logger.level === "debug" || this.logger.level === "verbose") return `${path}.ts:${lineCol}`;
return path.split("/").at(-1) || "";
};
/**
* @private
* @internal
*/
parseMessage = (input) => {
const output = input.join("§r ");
if ([
".",
"!",
"?"
].includes(output.charAt(-1))) return `${output}.`;
return output;
};
/**
* Log information messages.
* @param {...string} message - The message to log.
*/
info = (...message) => {
this.logger.log("info", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log warning messages.
* @param {...string} message - The message to log.
*/
warn = (...message) => {
this.logger.log("warn", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log error messages.
* @param {string | Error | any} message - The message to log.
*/
error = (message) => {
if (typeof message === "string") {
this.logger.log("error", message, { namespace: this.getNamespace() });
return;
}
if (message.stack) {
this.logger.error(`${message.stack.split("\n")[0] !== message.toString() ? `${message.toString()}\n` : ""}${message.stack}`);
return;
}
this.logger.error(message.toString());
};
/**
* Log verbose messages.
* @param {...string} message - The message to log.
*/
verbose = (...message) => {
this.logger.log("verbose", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log debug messages.
* @param {...string} message - The message to log.
*/
debug = (...message) => {
this.logger.log("debug", this.parseMessage(message), { namespace: this.getNamespace() });
};
/**
* Log silly messages.
* @param {...string} message - The message to log.
*/
silly = (...message) => {
this.logger.log("silly", this.parseMessage(message), { namespace: this.getNamespace() });
};
};
//#endregion
export { Logger };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmVzLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNvbG9yUGFyc2VyIGZyb20gJ0Bqc3ByaXNtYXJpbmUvY29sb3ItcGFyc2VyJztcblxuaW1wb3J0IHR5cGUgeyBMb2dnZXIgYXMgV2luc3RvbiB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0ICogYXMgd2luc3RvbiBmcm9tICd3aW5zdG9uJztcbmltcG9ydCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuXG5pbXBvcnQgdHlwZSBUcmFuc3BvcnRTdHJlYW0gZnJvbSAnd2luc3Rvbi10cmFuc3BvcnQnO1xuaW1wb3J0IHR5cGUgeyBDb25zb2xlTGlrZSB9IGZyb20gJy4vdHJhbnNwb3J0JztcbmltcG9ydCB7IFByaXNtYXJpbmVUcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydCc7XG5cbi8qKlxuICogQSBsb2cgbGV2ZWwuXG4gKiBAdHlwZSB7TG9nTGV2ZWx9XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gJ2Vycm9yJyB8ICd3YXJuJyB8ICdpbmZvJyB8ICd2ZXJib3NlJyB8ICdkZWJ1ZycgfCAnc2lsbHknO1xuXG4vKipcbiAqIEhlbHBlciBjbGFzcyBmb3IgZ2VuZXJhbCBsb2dnaW5nLlxuICogQGRvY3VtZW50IC4uLy4uLy4uL2RvY3MvbG9nLWxldmVscy5tZFxuICogQGNsYXNzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnZXIge1xuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlcm5hbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge1dpbnN0b259XG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcml2YXRlIGxvZ2dlcjogV2luc3RvbiB8IG51bGwgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGxvZ2dlciBpbnN0YW5jZVxuICAgICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCB0byB1c2UuXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRTdHJlYW1bXX0gdHJhbnNwb3J0cyAtIFRoZSB0cmFuc3BvcnRzIHRvIHVzZS5cbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfSBUaGUgbG9nZ2VyIGluc3RhbmNlLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihsZXZlbDogTG9nTGV2ZWwgPSAnaW5mbycsIHRyYW5zcG9ydHM6IFRyYW5zcG9ydFN0cmVhbVtdID0gW10pIHtcbiAgICAgICAgdGhpcy5jcmVhdGVMb2dnZXIobGV2ZWwsIHRyYW5zcG9ydHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBsb2dnZXIgaW5zdGFuY2VcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjcmVhdGVMb2dnZXIobGV2ZWw6IExvZ0xldmVsID0gJ2luZm8nLCB0cmFuc3BvcnRzOiBUcmFuc3BvcnRTdHJlYW1bXSA9IFtdKTogdm9pZCB7XG4gICAgICAgIC8vIElmIHRoZSBsb2dnZXIgaXMgYWxyZWFkeSBjcmVhdGVkIGFuZCBub3QgY2xvc2VkLCByZXR1cm4uXG4gICAgICAgIGlmICgodGhpcy5sb2dnZXIhIGFzIGFueSkgJiYgIXRoaXMubG9nZ2VyIS5jbG9zZWQpIHJldHVybjtcblxuICAgICAgICB0aGlzLmxvZ2dlciEgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcih7XG4gICAgICAgICAgICBsZXZlbCxcbiAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoXG4gICAgICAgICAgICAgICAgZm9ybWF0LnRpbWVzdGFtcCh7IGZvcm1hdDogJ0hIOm1tOnNzJyB9KSxcbiAgICAgICAgICAgICAgICBmb3JtYXQoKGluZm8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaW5mby5sZXZlbCA9IGluZm8ubGV2ZWwudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZm87XG4gICAgICAgICAgICAgICAgfSkoKSxcbiAgICAgICAgICAgICAgICBmb3JtYXQuY29sb3JpemUoKSxcbiAgICAgICAgICAgICAgICBmb3JtYXQuc2ltcGxlKClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0cmFuc3BvcnRzOiBbXG4gICAgICAgICAgICAgICAgbmV3IFByaXNtYXJpbmVUcmFuc3BvcnQoe1xuICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IGZvcm1hdC5wcmludGYoKHsgbGV2ZWwsIG1lc3NhZ2UsIHRpbWVzdGFtcCwgbmFtZXNwYWNlOiBucyB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBgJHt0aW1lc3RhbXB9ICR7bGV2ZWx9JHtucyA/IGAgJHtuc31gIDogJyd9YDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbG9yUGFyc2VyKGBbJHtwcmVmaXh9wqdyXTogJHttZXNzYWdlfcKncmApO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIC4uLnRyYW5zcG9ydHNcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZW5hYmxlIGhvb2suXG4gICAgICogQGdyb3VwIExpZmVjeWNsZVxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBlbmFibGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuY3JlYXRlTG9nZ2VyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZGlzYWJsZSBob29rLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZGlzYWJsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmNsb3NlKCk7XG4gICAgICAgIHRoaXMubG9nZ2VyID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gZm9yIGxvZyBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0geyhsZXZlbDogTG9nTGV2ZWwsIG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZH0gbGlzdGVuZXIgLSBUaGUgbGlzdGVuZXIgdG8gY2FsbCB3aGVuIGEgbG9nIG1lc3NhZ2UgaXMgcmVjZWl2ZWQuXG4gICAgICogQGV2ZW50XG4gICAgICovXG4gICAgcHVibGljIG9uTGluZShsaXN0ZW5lcjogKGxpbmU6IHN0cmluZykgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxvZ2dlciEub24oJ2RhdGEnLCAoZGF0YSkgPT4gbGlzdGVuZXIoZGF0YS5tZXNzYWdlLnRvU3RyaW5nKCkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNvbnNvbGUgaW5zdGFuY2UgdG8gdXNlLlxuICAgICAqIEBwYXJhbSB7Q29uc29sZUxpa2V9IGNvbnNvbGUgLSBUaGUgY29uc29sZSBpbnN0YW5jZSB0byB1c2UuXG4gICAgICovXG4gICAgcHVibGljIHNldENvbnNvbGUoY29uc29sZT86IENvbnNvbGVMaWtlKTogdm9pZCB7XG4gICAgICAgIGlmICghY29uc29sZSkgcmV0dXJuO1xuICAgICAgICAodGhpcy5sb2dnZXIhLnRyYW5zcG9ydHNbMF0gYXMgUHJpc21hcmluZVRyYW5zcG9ydCkuY29uc29sZSA9IGNvbnNvbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGNhbGxlZSdzIG5hbWVzcGFjZSBmcm9tIHRoZSBzdGFjayB0cmFjZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0TmFtZXNwYWNlID0gKCkgPT4ge1xuICAgICAgICBjb25zdCBzdGFjayA9IChuZXcgRXJyb3IoKS5zdGFjayBhcyBzdHJpbmcpLnJlcGxhY2VBbGwoJ1xcXFwnLCAnLycpO1xuICAgICAgICBpZiAoIXN0YWNrKSByZXR1cm4gJyc7XG5cbiAgICAgICAgY29uc3QgY2FsbGVyID0gKHN0YWNrLnNwbGl0KCdcXG4nKVszXSB8fCAnJykudHJpbSgpO1xuICAgICAgICBpZiAoIWNhbGxlcikgcmV0dXJuICcnO1xuXG4gICAgICAgIC8vIEdldCBwYXRoIGluc2lkZSBvZiB0aGUgcGFyZW50aGVzZXMgaW4gdGhlIGNhbGxlciBzdHJpbmcsIGV4Y2x1ZGluZyB0aGUgbGluZTpjb2wuXG4gICAgICAgIGNvbnN0IGZpbGUgPSBjYWxsZXIubWF0Y2goL1xcKChbXildKylcXCkvKT8uWzFdPy5zcGxpdCgnc3JjLycpWzFdIHx8ICcnO1xuICAgICAgICBpZiAoIWZpbGUpIHJldHVybiAnJztcblxuICAgICAgICAvLyBHZXQgcGF0aCBhbmQgbGluZTpjb2wgZnJvbSB0aGUgZmlsZSBzdHJpbmcsIHRoZW4gcmVtb3ZlIHRoZSBmaWxlIGV4dGVuc2lvbi5cbiAgICAgICAgY29uc3QgcGF0aCA9IGZpbGUuc3BsaXQoJzonKS5zbGljZSgwLCAtMikuam9pbignOicpLnNsaWNlKDAsIC0zKTtcbiAgICAgICAgaWYgKCFwYXRoKSByZXR1cm4gJyc7XG5cbiAgICAgICAgY29uc3QgbGluZUNvbCA9IGZpbGUuc3BsaXQoJzonKS5zbGljZSgtMikuam9pbignOicpO1xuICAgICAgICBpZiAoIWxpbmVDb2wpIHJldHVybiAnJztcblxuICAgICAgICBpZiAodGhpcy5sb2dnZXIhLmxldmVsID09PSAnc2lsbHknIHx8IHRoaXMubG9nZ2VyIS5sZXZlbCA9PT0gJ2RlYnVnJyB8fCB0aGlzLmxvZ2dlciEubGV2ZWwgPT09ICd2ZXJib3NlJykge1xuICAgICAgICAgICAgcmV0dXJuIGAke3BhdGh9LnRzOiR7bGluZUNvbH1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhdGguc3BsaXQoJy8nKS5hdCgtMSkgfHwgJyc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJpdmF0ZSBwYXJzZU1lc3NhZ2UgPSAoaW5wdXQ6IHN0cmluZ1tdKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGlucHV0LmpvaW4oJ8KnciAnKTtcblxuICAgICAgICAvLyBNYWtlIHN1cmUgbG9nIG1lc3NhZ2VzIGVuZCB3aXRoIGEgcGVyaW9kLlxuICAgICAgICBpZiAoWycuJywgJyEnLCAnPyddLmluY2x1ZGVzKG91dHB1dC5jaGFyQXQoLTEpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGAke291dHB1dH0uYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBpbmZvcm1hdGlvbiBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgaW5mbyA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdpbmZvJywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIHdhcm5pbmcgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsuLi5zdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIHdhcm4gPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnd2FybicsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBlcnJvciBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZyB8IEVycm9yIHwgYW55fSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyBlcnJvciA9IChtZXNzYWdlOiBzdHJpbmcgfCBFcnJvciB8IGFueSk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdlcnJvcicsIG1lc3NhZ2UsIHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lc3NhZ2Uuc3RhY2spIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyIS5lcnJvcihcbiAgICAgICAgICAgICAgICBgJHttZXNzYWdlLnN0YWNrLnNwbGl0KCdcXG4nKVswXSAhPT0gbWVzc2FnZS50b1N0cmluZygpID8gYCR7bWVzc2FnZS50b1N0cmluZygpfVxcbmAgOiAnJ30ke21lc3NhZ2Uuc3RhY2t9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubG9nZ2VyIS5lcnJvcihtZXNzYWdlLnRvU3RyaW5nKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zZSBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgdmVyYm9zZSA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCd2ZXJib3NlJywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIGRlYnVnIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7Li4uc3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyBkZWJ1ZyA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdkZWJ1ZycsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBzaWxseSBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2lsbHkgPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnc2lsbHknLCB0aGlzLnBhcnNlTWVzc2FnZShtZXNzYWdlKSwge1xuICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgIH0pO1xuICAgIH07XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBdUJBLElBQWEsU0FBYixNQUFvQjs7Ozs7OztDQU9oQixTQUFpQzs7Ozs7OztDQVFqQyxZQUFtQixRQUFrQixRQUFRLGFBQWdDLENBQUMsR0FBRztFQUM3RSxLQUFLLGFBQWEsT0FBTyxVQUFVO0NBQ3ZDOzs7Ozs7Q0FPQSxhQUF1QixRQUFrQixRQUFRLGFBQWdDLENBQUMsR0FBUztFQUV2RixJQUFLLEtBQUssVUFBbUIsQ0FBQyxLQUFLLE9BQVEsUUFBUTtFQUVuRCxLQUFLLFNBQVUsUUFBUSxhQUFhO0dB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