UNPKG

ionic-logging-service

Version:

Logging functionalities for apps built with Ionic framework

167 lines 22.3 kB
import { EventEmitter, Injectable } from "@angular/core"; import * as log4javascript from "log4javascript"; import { AjaxAppender } from "./ajax-appender.model"; import { LocalStorageAppender } from "./local-storage-appender.model"; import { LogLevelConverter } from "./log-level.converter"; import { Logger } from "./logger.model"; import { MemoryAppender } from "./memory-appender.model"; import * as i0 from "@angular/core"; /** * Service for logging functionality. * * By default, the following settings are used: * - logger: root with level WARN * - appender: BrowserConsoleAppender with threshold DEBUG and MemoryAppender with threshold ALL * * Via [configure](#configure), it is possible to amend these settings. */ export class LoggingService { /** * Creates a new instance of the service. */ constructor() { // prevent log4javascript to show alerts on case of errors log4javascript.logLog.setQuietMode(true); // create event emitter this.logMessagesChanged = new EventEmitter(); this.ajaxAppenderFailed = new EventEmitter(); // configure appender const logger = log4javascript.getRootLogger(); logger.setLevel(log4javascript.Level.WARN); // browser console appender for debugger this.browserConsoleAppender = new log4javascript.BrowserConsoleAppender(); this.browserConsoleAppender.setLayout(new log4javascript.PatternLayout("%d{HH:mm:ss,SSS} %c %m")); this.browserConsoleAppender.setThreshold(log4javascript.Level.ALL); logger.addAppender(this.browserConsoleAppender); // in-memory appender for display on log messages page this.memoryAppender = new MemoryAppender(); this.memoryAppender.setLayout(new log4javascript.PatternLayout("%d{HH:mm:ss,SSS} %c %m")); this.memoryAppender.setOnLogMessagesChangedCallback((message) => { this.logMessagesChanged.emit(); }); logger.addAppender(this.memoryAppender); this.configure(); } /** * Configures the logging depending on the given configuration. * * @param configuration configuration data. */ configure(configuration) { if (typeof configuration === "undefined") { configuration = {}; } // set log levels if (typeof configuration.logLevels !== "undefined") { for (const level of configuration.logLevels) { let logger; if (level.loggerName === "root") { logger = log4javascript.getRootLogger(); } else { logger = log4javascript.getLogger(level.loggerName); } try { logger.setLevel(LogLevelConverter.levelToLog4Javascript(LogLevelConverter.levelFromString(level.logLevel))); } catch (e) { throw new Error(`invalid log level ${level.logLevel}`); } } } // configure AjaxAppender if (typeof configuration.ajaxAppender !== "undefined") { const ajaxAppender = new AjaxAppender(configuration.ajaxAppender); ajaxAppender.appenderFailed.subscribe((message) => { this.ajaxAppenderFailed.emit(message); }); log4javascript.getRootLogger().addAppender(ajaxAppender); } // configure LocalStorageAppender if (typeof configuration.localStorageAppender !== "undefined") { const localStorageAppender = new LocalStorageAppender(configuration.localStorageAppender); log4javascript.getRootLogger().addAppender(localStorageAppender); // ensure that an eventual memoryAppender is behind the localStorageAppender const appenders = new Logger().getInternalLogger().getEffectiveAppenders(); const memoryAppender = appenders.find((a) => a.toString() === "Ionic.Logging.MemoryAppender"); if (memoryAppender) { log4javascript.getRootLogger().removeAppender(memoryAppender); log4javascript.getRootLogger().addAppender(memoryAppender); } } // configure MemoryAppender if (configuration.memoryAppender) { this.memoryAppender.configure(configuration.memoryAppender); } // configure BrowserConsoleAppender if (configuration.browserConsoleAppender) { if (configuration.browserConsoleAppender.threshold) { const convertedThreshold = LogLevelConverter.levelToLog4Javascript(LogLevelConverter.levelFromString(configuration.browserConsoleAppender.threshold)); this.browserConsoleAppender.setThreshold(convertedThreshold); } } } /** * Gets the root logger from which all other loggers derive. * * @return root logger */ getRootLogger() { return new Logger(); } /** * Gets a logger with the specified name, creating it if a logger with that name does not already exist. * * @param loggerName name of the logger * @return logger */ getLogger(loggerName) { return new Logger(loggerName); } /** * Gets the last log messages. * * The log messages are retrieved from the internal [MemoryAppender](../memoryappender.html). * That means you will get only the most current messages. The number of the messages is limited * by its maxMessages value. * * @return log messages */ getLogMessages() { return this.memoryAppender.getLogMessages(); } /** * Loads the log messages written by the LocalStorageAppender with the given key. * * @param localStorageKey key for the local storage * @returns log messages */ getLogMessagesFromLocalStorage(localStorageKey) { return LocalStorageAppender.loadLogMessages(localStorageKey); } /** * Remove all log messages. */ removeLogMessages() { this.memoryAppender.removeLogMessages(); this.logMessagesChanged.emit(); } /** * Removes the log messages written by the LocalStorageAppender with the given key. * * @param localStorageKey key for the local storage */ removeLogMessagesFromLocalStorage(localStorageKey) { LocalStorageAppender.removeLogMessages(localStorageKey); this.logMessagesChanged.emit(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: LoggingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: LoggingService, providedIn: "root" }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.2", ngImport: i0, type: LoggingService, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }], ctorParameters: () => [] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2luZy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvaW9uaWMtbG9nZ2luZy1zZXJ2aWNlL3NyYy9saWIvbG9nZ2luZy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBRW5FLE9BQU8sS0FBSyxjQUFjLE1BQU0sZ0JBQWdCLENBQUM7QUFFakQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7O0FBRXpEOzs7Ozs7OztHQVFHO0FBSUgsTUFBTSxPQUFPLGNBQWM7SUFxQjFCOztPQUVHO0lBQ0g7UUFFQywwREFBMEQ7UUFDMUQsY0FBYyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekMsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ25ELElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBRXJELHFCQUFxQjtRQUNyQixNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDOUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTNDLHdDQUF3QztRQUN4QyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxjQUFjLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUMxRSxJ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O09BUUc7SUFDSSxjQUFjO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSw4QkFBOEIsQ0FBQyxlQUF1QjtRQUM1RCxPQUFPLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxpQkFBaUI7UUFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLGlDQUFpQyxDQUFDLGVBQXVCO1FBQy9ELG9CQUFvQixDQUFDLGlCQUFpQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoQyxDQUFDOzhHQW5MVyxjQUFjO2tIQUFkLGNBQWMsY0FGZCxNQUFNOzsyRkFFTixjQUFjO2tCQUgxQixVQUFVO21CQUFDO29CQUNYLFVBQVUsRUFBRSxNQUFNO2lCQUNsQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciwgSW5qZWN0YWJsZSwgT3B0aW9uYWwgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuXG5pbXBvcnQgKiBhcyBsb2c0amF2YXNjcmlwdCBmcm9tIFwibG9nNGphdmFzY3JpcHRcIjtcblxuaW1wb3J0IHsgQWpheEFwcGVuZGVyIH0gZnJvbSBcIi4vYWpheC1hcHBlbmRlci5tb2RlbFwiO1xuaW1wb3J0IHsgTG9jYWxTdG9yYWdlQXBwZW5kZXIgfSBmcm9tIFwiLi9sb2NhbC1zdG9yYWdlLWFwcGVuZGVyLm1vZGVsXCI7XG5pbXBvcnQgeyBMb2dMZXZlbENvbnZlcnRlciB9IGZyb20gXCIuL2xvZy1sZXZlbC5jb252ZXJ0ZXJcIjtcbmltcG9ydCB7IExvZ01lc3NhZ2UgfSBmcm9tIFwiLi9sb2ctbWVzc2FnZS5tb2RlbFwiO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSBcIi4vbG9nZ2VyLm1vZGVsXCI7XG5pbXBvcnQgeyBMb2dnaW5nU2VydmljZUNvbmZpZ3VyYXRpb24gfSBmcm9tIFwiLi9sb2dnaW5nLXNlcnZpY2UuY29uZmlndXJhdGlvblwiO1xuaW1wb3J0IHsgTWVtb3J5QXBwZW5kZXIgfSBmcm9tIFwiLi9tZW1vcnktYXBwZW5kZXIubW9kZWxcIjtcblxuLyoqXG4gKiBTZXJ2aWNlIGZvciBsb2dnaW5nIGZ1bmN0aW9uYWxpdHkuXG4gKlxuICogQnkgZGVmYXVsdCwgdGhlIGZvbGxvd2luZyBzZXR0aW5ncyBhcmUgdXNlZDpcbiAqICAtIGxvZ2dlcjogcm9vdCB3aXRoIGxldmVsIFdBUk5cbiAqICAtIGFwcGVuZGVyOiBCcm93c2VyQ29uc29sZUFwcGVuZGVyIHdpdGggdGhyZXNob2xkIERFQlVHIGFuZCBNZW1vcnlBcHBlbmRlciB3aXRoIHRocmVzaG9sZCBBTExcbiAqXG4gKiBWaWEgW2NvbmZpZ3VyZV0oI2NvbmZpZ3VyZSksIGl0IGlzIHBvc3NpYmxlIHRvIGFtZW5kIHRoZXNlIHNldHRpbmdzLlxuICovXG5ASW5qZWN0YWJsZSh7XG5cdHByb3ZpZGVkSW46IFwicm9vdFwiXG59KVxuZXhwb3J0IGNsYXNzIExvZ2dpbmdTZXJ2aWNlIHtcblxuXHQvKipcblx0ICogRXZlbnQgdHJpZ2dlcmVkIHdoZW4gdGhlIGxvZyBtZXNzYWdlcyBnb3QgKHBvdGVudGlhbGx5KSBjaGFuZ2UuXG5cdCAqIFRoaXMgY2FuIGhhcHBlbiB3aGVuOlxuXHQgKiAtIG5ldyBtZXNzYWdlIHdhcyBhZGRlZFxuXHQgKiAtIGFsbCBtZXNzYWdlIHdoZXJlIHJlbW92ZWQgZnJvbSBtZW1vcnlcblx0ICogLSBhbGwgbWFzc2FnZXMgd2hlcmUgcmVtb3ZlZCBmb3Igb25lIHNwY2lmaWMgTG9jYWxTdG9yYWdlQXBwZW5kZXJcblx0ICovXG5cdHB1YmxpYyBsb2dNZXNzYWdlc0NoYW5nZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPjtcblxuXHQvKipcblx0ICogRXZlbnQgdHJpZ2dlcmVkIHdoZW4gYWpheCBhcHBlbmRlciBjb3VsZCBub3Qgc2VuZCBsb2cgbWVzc2FnZXMgdG8gdGhlIHNlcnZlci5cblx0ICpcblx0ICogQHBhcmFtIG1lc3NhZ2UgZXJyb3IgbWVzc2FnZVxuXHQgKi9cblx0cHVibGljIGFqYXhBcHBlbmRlckZhaWxlZDogRXZlbnRFbWl0dGVyPHN0cmluZz47XG5cblx0cHJpdmF0ZSBtZW1vcnlBcHBlbmRlcjogTWVtb3J5QXBwZW5kZXI7XG5cdHByaXZhdGUgYnJvd3NlckNvbnNvbGVBcHBlbmRlcjogbG9nNGphdmFzY3JpcHQuQnJvd3NlckNvbnNvbGVBcHBlbmRlcjtcblxuXHQvKipcblx0ICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgc2VydmljZS5cblx0ICovXG5cdGNvbnN0cnVjdG9yKCkge1xuXG5cdFx0Ly8gcHJldmVudCBsb2c0amF2YXNjcmlwdCB0byBzaG93IGFsZXJ0cyBvbiBjYXNlIG9mIGVycm9yc1xuXHRcdGxvZzRqYXZhc2NyaXB0LmxvZ0xvZy5zZXRRdWlldE1vZGUodHJ1ZSk7XG5cblx0XHQvLyBjcmVhdGUgZXZlbnQgZW1pdHRlclxuXHRcdHRoaXMubG9nTWVzc2FnZXNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXHRcdHRoaXMuYWpheEFwcGVuZGVyRmFpbGVkID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cblx0XHQvLyBjb25maWd1cmUgYXBwZW5kZXJcblx0XHRjb25zdCBsb2dnZXIgPSBsb2c0amF2YXNjcmlwdC5nZXRSb290TG9nZ2VyKCk7XG5cdFx0bG9nZ2VyLnNldExldmVsKGxvZzRqYXZhc2NyaXB0LkxldmVsLldBUk4pO1xuXG5cdFx0Ly8gYnJvd3NlciBjb25zb2xlIGFwcGVuZGVyIGZvciBkZWJ1Z2dlclxuXHRcdHRoaXMuYnJvd3NlckNvbnNvbGVBcHBlbmRlciA9IG5ldyBsb2c0amF2YXNjcmlwdC5Ccm93c2VyQ29uc29sZUFwcGVuZGVyKCk7XG5cdFx0dGhpcy5icm93c2VyQ29uc29sZUFwcGVuZGVyLnNldExheW91dChuZXcgbG9nNGphdmFzY3JpcHQuUGF0dGVybkxheW91dChcIiVke0hIOm1tOnNzLFNTU30gJWMgJW1cIikpO1xuXHRcdHRoaXMuYnJvd3NlckNvbnNvbGVBcHBlbmRlci5zZXRUaHJlc2hvbGQobG9nNGphdmFzY3JpcHQuTGV2ZWwuQUxMKTtcblx0XHRsb2dnZXIuYWRkQXBwZW5kZXIodGhpcy5icm93c2VyQ29uc29sZUFwcGVuZGVyKTtcblxuXHRcdC8vIGluLW1lbW9yeSBhcHBlbmRlciBmb3IgZGlzcGxheSBvbiBsb2cgbWVzc2FnZXMgcGFnZVxuXHRcdHRoaXMubWVtb3J5QXBwZW5kZXIgPSBuZXcgTWVtb3J5QXBwZW5kZXIoKTtcblx0XHR0aGlzLm1lbW9yeUFwcGVuZGVyLnNldExheW91dChuZXcgbG9nNGphdmFzY3JpcHQuUGF0dGVybkxheW91dChcIiVke0hIOm1tOnNzLFNTU30gJWMgJW1cIikpO1xuXHRcdHRoaXMubWVtb3J5QXBwZW5kZXIuc2V0T25Mb2dNZXNzYWdlc0NoYW5nZWRDYWxsYmFjaygobWVzc2FnZSkgPT4ge1xuXHRcdFx0dGhpcy5sb2dNZXNzYWdlc0NoYW5nZWQuZW1pdCgpO1xuXHRcdH0pO1xuXHRcdGxvZ2dlci5hZGRBcHBlbmRlcih0aGlzLm1lbW9yeUFwcGVuZGVyKTtcblxuXHRcdHRoaXMuY29uZmlndXJlKCk7XG5cdH1cblxuXHQvKipcblx0ICogQ29uZmlndXJlcyB0aGUgbG9nZ2luZyBkZXBlbmRpbmcgb24gdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb24uXG5cdCAqXG5cdCAqIEBwYXJhbSBjb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24gZGF0YS5cblx0ICovXG5cdHB1YmxpYyBjb25maWd1cmUoY29uZmlndXJhdGlvbj86IExvZ2dpbmdTZXJ2aWNlQ29uZmlndXJhdGlvbik6IHZvaWQge1xuXG5cdFx0aWYgKHR5cGVvZiBjb25maWd1cmF0aW9uID09PSBcInVuZGVmaW5lZFwiKSB7XG5cdFx0XHRjb25maWd1cmF0aW9uID0ge307XG5cdFx0fVxuXG5cdFx0Ly8gc2V0IGxvZyBsZXZlbHNcblx0XHRpZiAodHlwZW9mIGNvbmZpZ3VyYXRpb24ubG9nTGV2ZWxzICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdFx0XHRmb3IgKGNvbnN0IGxldmVsIG9mIGNvbmZpZ3VyYXRpb24ubG9nTGV2ZWxzKSB7XG5cdFx0XHRcdGxldCBsb2dnZXI6IGxvZzRqYXZhc2NyaXB0LkxvZ2dlcjtcblx0XHRcdFx0aWYgKGxldmVsLmxvZ2dlck5hbWUgPT09IFwicm9vdFwiKSB7XG5cdFx0XHRcdFx0bG9nZ2VyID0gbG9nNGphdmFzY3JpcHQuZ2V0Um9vdExvZ2dlcigpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGxvZ2dlciA9IGxvZzRqYXZhc2NyaXB0LmdldExvZ2dlcihsZXZlbC5sb2dnZXJOYW1lKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGxvZ2dlci5zZXRMZXZlbChMb2dMZXZlbENvbnZlcnRlci5sZXZlbFRvTG9nNEphdmFzY3JpcHQoTG9nTGV2ZWxDb252ZXJ0ZXIubGV2ZWxGcm9tU3RyaW5nKGxldmVsLmxvZ0xldmVsKSkpO1xuXHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGxvZyBsZXZlbCAke2xldmVsLmxvZ0xldmVsfWApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gY29uZmlndXJlIEFqYXhBcHBlbmRlclxuXHRcdGlmICh0eXBlb2YgY29uZmlndXJhdGlvbi5hamF4QXBwZW5kZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcblx0XHRcdGNvbnN0IGFqYXhBcHBlbmRlciA9IG5ldyBBamF4QXBwZW5kZXIoY29uZmlndXJhdGlvbi5hamF4QXBwZW5kZXIpO1xuXHRcdFx0YWpheEFwcGVuZGVyLmFwcGVuZGVyRmFpbGVkLnN1YnNjcmliZSgobWVzc2FnZTogc3RyaW5nKSA9PiB7XG5cdFx0XHRcdHRoaXMuYWpheEFwcGVuZGVyRmFpbGVkLmVtaXQobWVzc2FnZSk7XG5cdFx0XHR9KTtcblx0XHRcdGxvZzRqYXZhc2NyaXB0LmdldFJvb3RMb2dnZXIoKS5hZGRBcHBlbmRlcihhamF4QXBwZW5kZXIpO1xuXHRcdH1cblxuXHRcdC8vIGNvbmZpZ3VyZSBMb2NhbFN0b3JhZ2VBcHBlbmRlclxuXHRcdGlmICh0eXBlb2YgY29uZmlndXJhdGlvbi5sb2NhbFN0b3JhZ2VBcHBlbmRlciAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHRcdFx0Y29uc3QgbG9jYWxTdG9yYWdlQXBwZW5kZXIgPSBuZXcgTG9jYWxTdG9yYWdlQXBwZW5kZXIoY29uZmlndXJhdGlvbi5sb2NhbFN0b3JhZ2VBcHBlbmRlcik7XG5cdFx0XHRsb2c0amF2YXNjcmlwdC5nZXRSb290TG9nZ2VyKCkuYWRkQXBwZW5kZXIobG9jYWxTdG9yYWdlQXBwZW5kZXIpO1xuXG5cdFx0XHQvLyBlbnN1cmUgdGhhdCBhbiBldmVudHVhbCBtZW1vcnlBcHBlbmRlciBpcyBiZWhpbmQgdGhlIGxvY2FsU3RvcmFnZUFwcGVuZGVyXG5cdFx0XHRjb25zdCBhcHBlbmRlcnMgPSBuZXcgTG9nZ2VyKCkuZ2V0SW50ZXJuYWxMb2dnZXIoKS5nZXRFZmZlY3RpdmVBcHBlbmRlcnMoKTtcblx0XHRcdGNvbnN0IG1lbW9yeUFwcGVuZGVyID0gYXBwZW5kZXJzLmZpbmQoKGEpID0+IGEudG9TdHJpbmcoKSA9PT0gXCJJb25pYy5Mb2dnaW5nLk1lbW9yeUFwcGVuZGVyXCIpIGFzIE1lbW9yeUFwcGVuZGVyO1xuXHRcdFx0aWYgKG1lbW9yeUFwcGVuZGVyKSB7XG5cdFx0XHRcdGxvZzRqYXZhc2NyaXB0LmdldFJvb3RMb2dnZXIoKS5yZW1vdmVBcHBlbmRlcihtZW1vcnlBcHBlbmRlcik7XG5cdFx0XHRcdGxvZzRqYXZhc2NyaXB0LmdldFJvb3RMb2dnZXIoKS5hZGRBcHBlbmRlcihtZW1vcnlBcHBlbmRlcik7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gY29uZmlndXJlIE1lbW9yeUFwcGVuZGVyXG5cdFx0aWYgKGNvbmZpZ3VyYXRpb24ubWVtb3J5QXBwZW5kZXIpIHtcblx0XHRcdHRoaXMubWVtb3J5QXBwZW5kZXIuY29uZmlndXJlKGNvbmZpZ3VyYXRpb24ubWVtb3J5QXBwZW5kZXIpO1xuXHRcdH1cblxuXHRcdC8vIGNvbmZpZ3VyZSBCcm93c2VyQ29uc29sZUFwcGVuZGVyXG5cdFx0aWYgKGNvbmZpZ3VyYXRpb24uYnJvd3NlckNvbnNvbGVBcHBlbmRlcikge1xuXHRcdFx0aWYgKGNvbmZpZ3VyYXRpb24uYnJvd3NlckNvbnNvbGVBcHBlbmRlci50aHJlc2hvbGQpIHtcblx0XHRcdFx0Y29uc3QgY29udmVydGVkVGhyZXNob2xkID0gTG9nTGV2ZWxDb252ZXJ0ZXIubGV2ZWxUb0xvZzRKYXZhc2NyaXB0KFxuXHRcdFx0XHRcdExvZ0xldmVsQ29udmVydGVyLmxldmVsRnJvbVN0cmluZyhjb25maWd1cmF0aW9uLmJyb3dzZXJDb25zb2xlQXBwZW5kZXIudGhyZXNob2xkKSk7XG5cdFx0XHRcdHRoaXMuYnJvd3NlckNvbnNvbGVBcHBlbmRlci5zZXRUaHJlc2hvbGQoY29udmVydGVkVGhyZXNob2xkKTtcblx0XHRcdH1cblx0XHR9XG5cblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSByb290IGxvZ2dlciBmcm9tIHdoaWNoIGFsbCBvdGhlciBsb2dnZXJzIGRlcml2ZS5cblx0ICpcblx0ICogQHJldHVybiByb290IGxvZ2dlclxuXHQgKi9cblx0cHVibGljIGdldFJvb3RMb2dnZXIoKTogTG9nZ2VyIHtcblx0XHRyZXR1cm4gbmV3IExvZ2dlcigpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYSBsb2dnZXIgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUsIGNyZWF0aW5nIGl0IGlmIGEgbG9nZ2VyIHdpdGggdGhhdCBuYW1lIGRvZXMgbm90IGFscmVhZHkgZXhpc3QuXG5cdCAqXG5cdCAqIEBwYXJhbSBsb2dnZXJOYW1lIG5hbWUgb2YgdGhlIGxvZ2dlclxuXHQgKiBAcmV0dXJuIGxvZ2dlclxuXHQgKi9cblx0cHVibGljIGdldExvZ2dlcihsb2dnZXJOYW1lOiBzdHJpbmcpOiBMb2dnZXIge1xuXHRcdHJldHVybiBuZXcgTG9nZ2VyKGxvZ2dlck5hbWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgdGhlIGxhc3QgbG9nIG1lc3NhZ2VzLlxuXHQgKlxuXHQgKiBUaGUgbG9nIG1lc3NhZ2VzIGFyZSByZXRyaWV2ZWQgZnJvbSB0aGUgaW50ZXJuYWwgW01lbW9yeUFwcGVuZGVyXSguLi9tZW1vcnlhcHBlbmRlci5odG1sKS5cblx0ICogVGhhdCBtZWFucyB5b3Ugd2lsbCBnZXQgb25seSB0aGUgbW9zdCBjdXJyZW50IG1lc3NhZ2VzLiBUaGUgbnVtYmVyIG9mIHRoZSBtZXNzYWdlcyBpcyBsaW1pdGVkXG5cdCAqIGJ5IGl0cyBtYXhNZXNzYWdlcyB2YWx1ZS5cblx0ICpcblx0ICogQHJldHVybiBsb2cgbWVzc2FnZXNcblx0ICovXG5cdHB1YmxpYyBnZXRMb2dNZXNzYWdlcygpOiBMb2dNZXNzYWdlW10ge1xuXHRcdHJldHVybiB0aGlzLm1lbW9yeUFwcGVuZGVyLmdldExvZ01lc3NhZ2VzKCk7XG5cdH1cblxuXHQvKipcblx0ICogTG9hZHMgdGhlIGxvZyBtZXNzYWdlcyB3cml0dGVuIGJ5IHRoZSBMb2NhbFN0b3JhZ2VBcHBlbmRlciB3aXRoIHRoZSBnaXZlbiBrZXkuXG5cdCAqXG5cdCAqIEBwYXJhbSBsb2NhbFN0b3JhZ2VLZXkga2V5IGZvciB0aGUgbG9jYWwgc3RvcmFnZVxuXHQgKiBAcmV0dXJucyBsb2cgbWVzc2FnZXNcblx0ICovXG5cdHB1YmxpYyBnZXRMb2dNZXNzYWdlc0Zyb21Mb2NhbFN0b3JhZ2UobG9jYWxTdG9yYWdlS2V5OiBzdHJpbmcpOiBMb2dNZXNzYWdlW10ge1xuXHRcdHJldHVybiBMb2NhbFN0b3JhZ2VBcHBlbmRlci5sb2FkTG9nTWVzc2FnZXMobG9jYWxTdG9yYWdlS2V5KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYWxsIGxvZyBtZXNzYWdlcy5cblx0ICovXG5cdHB1YmxpYyByZW1vdmVMb2dNZXNzYWdlcygpOiB2b2lkIHtcblx0XHR0aGlzLm1lbW9yeUFwcGVuZGVyLnJlbW92ZUxvZ01lc3NhZ2VzKCk7XG5cdFx0dGhpcy5sb2dNZXNzYWdlc0NoYW5nZWQuZW1pdCgpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgdGhlIGxvZyBtZXNzYWdlcyB3cml0dGVuIGJ5IHRoZSBMb2NhbFN0b3JhZ2VBcHBlbmRlciB3aXRoIHRoZSBnaXZlbiBrZXkuXG5cdCAqXG5cdCAqIEBwYXJhbSBsb2NhbFN0b3JhZ2VLZXkga2V5IGZvciB0aGUgbG9jYWwgc3RvcmFnZVxuXHQgKi9cblx0cHVibGljIHJlbW92ZUxvZ01lc3NhZ2VzRnJvbUxvY2FsU3RvcmFnZShsb2NhbFN0b3JhZ2VLZXk6IHN0cmluZyk6IHZvaWQge1xuXHRcdExvY2FsU3RvcmFnZUFwcGVuZGVyLnJlbW92ZUxvZ01lc3NhZ2VzKGxvY2FsU3RvcmFnZUtleSk7XG5cdFx0dGhpcy5sb2dNZXNzYWdlc0NoYW5nZWQuZW1pdCgpO1xuXHR9XG59XG4iXX0=