@jsprismarine/logger
Version:
JSPrismarine logger and utilities
210 lines (202 loc) • 21.1 kB
JavaScript
;
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const colorParser = require('@jsprismarine/color-parser');
const winston = require('winston');
const transport = require('./transport.cjs.cjs');
const _interopDefault = e => e && e.__esModule ? e : { default: e };
function _interopNamespace(e) {
if (e && e.__esModule) return e;
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
if (e) {
for (const k in e) {
if (k !== 'default') {
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: () => e[k]
});
}
}
}
n.default = e;
return Object.freeze(n);
}
const colorParser__default = /*#__PURE__*/_interopDefault(colorParser);
const winston__namespace = /*#__PURE__*/_interopNamespace(winston);
class Logger {
/**
* 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__namespace.createLogger({
level,
format: winston.format.combine(
winston.format.timestamp({ format: "HH:mm:ss" }),
winston.format((info) => {
info.level = info.level.toUpperCase();
return info;
})(),
winston.format.colorize(),
winston.format.simple()
),
transports: [
new transport.PrismarineTransport({
format: winston.format.printf(({ level: level2, message, timestamp, namespace: ns }) => {
const prefix = `${timestamp} ${level2}${ns ? ` ${ns}` : ""}`;
return colorParser__default.default(`[${prefix}§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 = 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()}
` : ""}${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()
});
};
}
exports.Logger = Logger;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmNqcy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNvbG9yUGFyc2VyIGZyb20gJ0Bqc3ByaXNtYXJpbmUvY29sb3ItcGFyc2VyJztcblxuaW1wb3J0IHR5cGUgeyBMb2dnZXIgYXMgV2luc3RvbiB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0ICogYXMgd2luc3RvbiBmcm9tICd3aW5zdG9uJztcbmltcG9ydCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuXG5pbXBvcnQgdHlwZSBUcmFuc3BvcnRTdHJlYW0gZnJvbSAnd2luc3Rvbi10cmFuc3BvcnQnO1xuaW1wb3J0IHR5cGUgeyBDb25zb2xlTGlrZSB9IGZyb20gJy4vdHJhbnNwb3J0JztcbmltcG9ydCB7IFByaXNtYXJpbmVUcmFuc3BvcnQgfSBmcm9tICcuL3RyYW5zcG9ydCc7XG5cbi8qKlxuICogQSBsb2cgbGV2ZWwuXG4gKiBAdHlwZSB7TG9nTGV2ZWx9XG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gJ2Vycm9yJyB8ICd3YXJuJyB8ICdpbmZvJyB8ICd2ZXJib3NlJyB8ICdkZWJ1ZycgfCAnc2lsbHknO1xuXG4vKipcbiAqIEhlbHBlciBjbGFzcyBmb3IgZ2VuZXJhbCBsb2dnaW5nLlxuICogQGRvY3VtZW50IGRvY3MvbG9nLWxldmVscy5tZFxuICogQGNsYXNzXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2dnZXIge1xuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlcm5hbCBsb2dnZXIgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge1dpbnN0b259XG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwcml2YXRlIGxvZ2dlcjogV2luc3RvbiB8IG51bGwgPSBudWxsO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgbmV3IGxvZ2dlciBpbnN0YW5jZVxuICAgICAqIEBwYXJhbSB7TG9nTGV2ZWx9IGxldmVsIC0gVGhlIGxvZyBsZXZlbCB0byB1c2UuXG4gICAgICogQHBhcmFtIHtUcmFuc3BvcnRTdHJlYW1bXX0gdHJhbnNwb3J0cyAtIFRoZSB0cmFuc3BvcnRzIHRvIHVzZS5cbiAgICAgKiBAcmV0dXJucyB7TG9nZ2VyfSBUaGUgbG9nZ2VyIGluc3RhbmNlLlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihsZXZlbDogTG9nTGV2ZWwgPSAnaW5mbycsIHRyYW5zcG9ydHM6IFRyYW5zcG9ydFN0cmVhbVtdID0gW10pIHtcbiAgICAgICAgdGhpcy5jcmVhdGVMb2dnZXIobGV2ZWwsIHRyYW5zcG9ydHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBsb2dnZXIgaW5zdGFuY2VcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjcmVhdGVMb2dnZXIobGV2ZWw6IExvZ0xldmVsID0gJ2luZm8nLCB0cmFuc3BvcnRzOiBUcmFuc3BvcnRTdHJlYW1bXSA9IFtdKTogdm9pZCB7XG4gICAgICAgIC8vIElmIHRoZSBsb2dnZXIgaXMgYWxyZWFkeSBjcmVhdGVkIGFuZCBub3QgY2xvc2VkLCByZXR1cm4uXG4gICAgICAgIGlmICgodGhpcy5sb2dnZXIhIGFzIGFueSkgJiYgIXRoaXMubG9nZ2VyIS5jbG9zZWQpIHJldHVybjtcblxuICAgICAgICB0aGlzLmxvZ2dlciEgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcih7XG4gICAgICAgICAgICBsZXZlbCxcbiAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoXG4gICAgICAgICAgICAgICAgZm9ybWF0LnRpbWVzdGFtcCh7IGZvcm1hdDogJ0hIOm1tOnNzJyB9KSxcbiAgICAgICAgICAgICAgICBmb3JtYXQoKGluZm8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaW5mby5sZXZlbCA9IGluZm8ubGV2ZWwudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZm87XG4gICAgICAgICAgICAgICAgfSkoKSxcbiAgICAgICAgICAgICAgICBmb3JtYXQuY29sb3JpemUoKSxcbiAgICAgICAgICAgICAgICBmb3JtYXQuc2ltcGxlKClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0cmFuc3BvcnRzOiBbXG4gICAgICAgICAgICAgICAgbmV3IFByaXNtYXJpbmVUcmFuc3BvcnQoe1xuICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IGZvcm1hdC5wcmludGYoKHsgbGV2ZWwsIG1lc3NhZ2UsIHRpbWVzdGFtcCwgbmFtZXNwYWNlOiBucyB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSBgJHt0aW1lc3RhbXB9ICR7bGV2ZWx9JHtucyA/IGAgJHtuc31gIDogJyd9YDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbG9yUGFyc2VyKGBbJHtwcmVmaXh9wqdyXTogJHttZXNzYWdlfcKncmApO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIC4uLnRyYW5zcG9ydHNcbiAgICAgICAgICAgIF1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZW5hYmxlIGhvb2suXG4gICAgICogQGdyb3VwIExpZmVjeWNsZVxuICAgICAqL1xuICAgIHB1YmxpYyBhc3luYyBlbmFibGUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuY3JlYXRlTG9nZ2VyKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT24gZGlzYWJsZSBob29rLlxuICAgICAqIEBncm91cCBMaWZlY3ljbGVcbiAgICAgKi9cbiAgICBwdWJsaWMgYXN5bmMgZGlzYWJsZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmNsb3NlKCk7XG4gICAgICAgIHRoaXMubG9nZ2VyID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMaXN0ZW4gZm9yIGxvZyBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0geyhsZXZlbDogTG9nTGV2ZWwsIG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZH0gbGlzdGVuZXIgLSBUaGUgbGlzdGVuZXIgdG8gY2FsbCB3aGVuIGEgbG9nIG1lc3NhZ2UgaXMgcmVjZWl2ZWQuXG4gICAgICogQGV2ZW50XG4gICAgICovXG4gICAgcHVibGljIG9uTGluZShsaXN0ZW5lcjogKGxpbmU6IHN0cmluZykgPT4gdm9pZCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxvZ2dlciEub24oJ2RhdGEnLCAoZGF0YSkgPT4gbGlzdGVuZXIoZGF0YS5tZXNzYWdlLnRvU3RyaW5nKCkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNvbnNvbGUgaW5zdGFuY2UgdG8gdXNlLlxuICAgICAqIEBwYXJhbSB7Q29uc29sZUxpa2V9IGNvbnNvbGUgLSBUaGUgY29uc29sZSBpbnN0YW5jZSB0byB1c2UuXG4gICAgICovXG4gICAgcHVibGljIHNldENvbnNvbGUoY29uc29sZT86IENvbnNvbGVMaWtlKTogdm9pZCB7XG4gICAgICAgIGlmICghY29uc29sZSkgcmV0dXJuO1xuICAgICAgICAodGhpcy5sb2dnZXIhLnRyYW5zcG9ydHNbMF0gYXMgUHJpc21hcmluZVRyYW5zcG9ydCkuY29uc29sZSA9IGNvbnNvbGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGNhbGxlZSdzIG5hbWVzcGFjZSBmcm9tIHRoZSBzdGFjayB0cmFjZS5cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0TmFtZXNwYWNlID0gKCkgPT4ge1xuICAgICAgICBjb25zdCBzdGFjayA9IChuZXcgRXJyb3IoKS5zdGFjayBhcyBzdHJpbmcpLnJlcGxhY2VBbGwoJ1xcXFwnLCAnLycpO1xuICAgICAgICBpZiAoIXN0YWNrKSByZXR1cm4gJyc7XG5cbiAgICAgICAgY29uc3QgY2FsbGVyID0gKHN0YWNrLnNwbGl0KCdcXG4nKVszXSB8fCAnJykudHJpbSgpO1xuICAgICAgICBpZiAoIWNhbGxlcikgcmV0dXJuICcnO1xuXG4gICAgICAgIC8vIEdldCBwYXRoIGluc2lkZSBvZiB0aGUgcGFyZW50aGVzZXMgaW4gdGhlIGNhbGxlciBzdHJpbmcsIGV4Y2x1ZGluZyB0aGUgbGluZTpjb2wuXG4gICAgICAgIGNvbnN0IGZpbGUgPSBjYWxsZXIubWF0Y2goL1xcKChbXildKylcXCkvKT8uWzFdPy5zcGxpdCgnc3JjLycpWzFdIHx8ICcnO1xuICAgICAgICBpZiAoIWZpbGUpIHJldHVybiAnJztcblxuICAgICAgICAvLyBHZXQgcGF0aCBhbmQgbGluZTpjb2wgZnJvbSB0aGUgZmlsZSBzdHJpbmcsIHRoZW4gcmVtb3ZlIHRoZSBmaWxlIGV4dGVuc2lvbi5cbiAgICAgICAgY29uc3QgcGF0aCA9IGZpbGUuc3BsaXQoJzonKS5zbGljZSgwLCAtMikuam9pbignOicpLnNsaWNlKDAsIC0zKTtcbiAgICAgICAgaWYgKCFwYXRoKSByZXR1cm4gJyc7XG5cbiAgICAgICAgY29uc3QgbGluZUNvbCA9IGZpbGUuc3BsaXQoJzonKS5zbGljZSgtMikuam9pbignOicpO1xuICAgICAgICBpZiAoIWxpbmVDb2wpIHJldHVybiAnJztcblxuICAgICAgICBpZiAodGhpcy5sb2dnZXIhLmxldmVsID09PSAnc2lsbHknIHx8IHRoaXMubG9nZ2VyIS5sZXZlbCA9PT0gJ2RlYnVnJyB8fCB0aGlzLmxvZ2dlciEubGV2ZWwgPT09ICd2ZXJib3NlJykge1xuICAgICAgICAgICAgcmV0dXJuIGAke3BhdGh9LnRzOiR7bGluZUNvbH1gO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhdGguc3BsaXQoJy8nKS5hdCgtMSkgfHwgJyc7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgcHJpdmF0ZSBwYXJzZU1lc3NhZ2UgPSAoaW5wdXQ6IHN0cmluZ1tdKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGlucHV0LmpvaW4oJ8KnciAnKTtcblxuICAgICAgICAvLyBNYWtlIHN1cmUgbG9nIG1lc3NhZ2VzIGVuZCB3aXRoIGEgcGVyaW9kLlxuICAgICAgICBpZiAoWycuJywgJyEnLCAnPyddLmluY2x1ZGVzKG91dHB1dC5jaGFyQXQoLTEpKSkge1xuICAgICAgICAgICAgcmV0dXJuIGAke291dHB1dH0uYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBpbmZvcm1hdGlvbiBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgaW5mbyA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdpbmZvJywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIHdhcm5pbmcgbWVzc2FnZXMuXG4gICAgICogQHBhcmFtIHsuLi5zdHJpbmd9IG1lc3NhZ2UgLSBUaGUgbWVzc2FnZSB0byBsb2cuXG4gICAgICovXG4gICAgcHVibGljIHdhcm4gPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnd2FybicsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBlcnJvciBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZyB8IEVycm9yIHwgYW55fSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyBlcnJvciA9IChtZXNzYWdlOiBzdHJpbmcgfCBFcnJvciB8IGFueSk6IHZvaWQgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdlcnJvcicsIG1lc3NhZ2UsIHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lc3NhZ2Uuc3RhY2spIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyIS5lcnJvcihcbiAgICAgICAgICAgICAgICBgJHttZXNzYWdlLnN0YWNrLnNwbGl0KCdcXG4nKVswXSAhPT0gbWVzc2FnZS50b1N0cmluZygpID8gYCR7bWVzc2FnZS50b1N0cmluZygpfVxcbmAgOiAnJ30ke21lc3NhZ2Uuc3RhY2t9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubG9nZ2VyIS5lcnJvcihtZXNzYWdlLnRvU3RyaW5nKCkpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMb2cgdmVyYm9zZSBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgdmVyYm9zZSA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCd2ZXJib3NlJywgdGhpcy5wYXJzZU1lc3NhZ2UobWVzc2FnZSksIHtcbiAgICAgICAgICAgIG5hbWVzcGFjZTogdGhpcy5nZXROYW1lc3BhY2UoKVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogTG9nIGRlYnVnIG1lc3NhZ2VzLlxuICAgICAqIEBwYXJhbSB7Li4uc3RyaW5nfSBtZXNzYWdlIC0gVGhlIG1lc3NhZ2UgdG8gbG9nLlxuICAgICAqL1xuICAgIHB1YmxpYyBkZWJ1ZyA9ICguLi5tZXNzYWdlOiBzdHJpbmdbXSk6IHZvaWQgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlciEubG9nKCdkZWJ1ZycsIHRoaXMucGFyc2VNZXNzYWdlKG1lc3NhZ2UpLCB7XG4gICAgICAgICAgICBuYW1lc3BhY2U6IHRoaXMuZ2V0TmFtZXNwYWNlKClcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvZyBzaWxseSBtZXNzYWdlcy5cbiAgICAgKiBAcGFyYW0gey4uLnN0cmluZ30gbWVzc2FnZSAtIFRoZSBtZXNzYWdlIHRvIGxvZy5cbiAgICAgKi9cbiAgICBwdWJsaWMgc2lsbHkgPSAoLi4ubWVzc2FnZTogc3RyaW5nW10pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIhLmxvZygnc2lsbHknLCB0aGlzLnBhcnNlTWVzc2FnZShtZXNzYWdlKSwge1xuICAgICAgICAgICAgbmFtZXNwYWNlOiB0aGlzLmdldE5hbWVzcGFjZSgpXG4gICAgICAgIH0pO1xuICAgIH07XG59XG4iXSwibmFtZXMiOlsid2luc3RvbiIsImZvcm1hdCIsIlByaXNtYXJpbmVUcmFuc3BvcnQiLCJsZXZlbCIsImNvbG9yUGFyc2VyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBdUJPLE1BQU0sTUFBTyxDQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPUixNQUF5QixHQUFBLElBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVExQixXQUFZLENBQUEsS0FBQSxHQUFrQixNQUFRLEVBQUEsVUFBQSxH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