UNPKG

ionic-logging-service

Version:

Logging functionalities for apps built with Ionic framework

177 lines 19.7 kB
import * as log4javascript from "log4javascript"; import { LogLevelConverter } from "./log-level.converter"; import { LogLevel } from "./log-level.model"; /** * An appender which stores the log messages in the browser's local storage. * * The messages are saved JSON-serialized. * You have to configure which key is used for storing the messages. * * A typical configuration could be: * * ```json * { * "localStorageKey": "myLogs", * "maxMessages": 500, * "threshold": "INFO" * } * ``` */ export class LocalStorageAppender extends log4javascript.Appender { static { this.maxMessagesDefault = 250; } static { this.thresholdDefault = "WARN"; } /** * Creates a new instance of the appender. * * @param configuration configuration for the appender. */ constructor(configuration) { super(); if (!configuration) { throw new Error("configuration must be not empty"); } if (!configuration.localStorageKey || configuration.localStorageKey === "") { throw new Error("localStorageKey must be not empty"); } this.localStorageKey = configuration.localStorageKey; // read existing logMessages this.logMessages = LocalStorageAppender.loadLogMessages(this.localStorageKey); // process remaining configuration this.configure({ localStorageKey: configuration.localStorageKey, maxMessages: configuration.maxMessages || LocalStorageAppender.maxMessagesDefault, threshold: configuration.threshold || LocalStorageAppender.thresholdDefault, }); } /** * Load log messages from local storage which are stored there under the given key. * * @param localStorageKey local storage key * @return stored messages */ static loadLogMessages(localStorageKey) { let logMessages; if (!localStorageKey || localStorage.getItem(localStorageKey) === null) { logMessages = []; } else { logMessages = JSON.parse(localStorage.getItem(localStorageKey)); for (const logMessage of logMessages) { // timestamps are serialized as strings logMessage.timeStamp = new Date(logMessage.timeStamp); } } return logMessages; } /** * Remove log messages from local storage which are stored there under the given key. * * @param localStorageKey local storage key */ static removeLogMessages(localStorageKey) { localStorage.removeItem(localStorageKey); } /** * Configures the logging depending on the given configuration. * * Only the defined properties get overwritten. * The localStorageKey cannot be modified. * * @param configuration configuration data. */ configure(configuration) { if (configuration) { if (configuration.localStorageKey && configuration.localStorageKey !== this.localStorageKey) { throw new Error("localStorageKey must not be changed"); } if (configuration.maxMessages) { this.setMaxMessages(configuration.maxMessages); } if (configuration.threshold) { const convertedThreshold = LogLevelConverter.levelToLog4Javascript(LogLevelConverter.levelFromString(configuration.threshold)); this.setThreshold(convertedThreshold); } } } /** * Appender-specific method to append a log message. * * @param loggingEvent event to be appended. */ append(loggingEvent) { // if logMessages is already full, remove oldest element while (this.logMessages.length >= this.maxMessages) { this.logMessages.shift(); } // add event to logMessages const message = { level: LogLevel[LogLevelConverter.levelFromLog4Javascript(loggingEvent.level)], logger: typeof loggingEvent.logger !== "undefined" ? loggingEvent.logger.name : undefined, message: loggingEvent.messages.slice(1), methodName: loggingEvent.messages[0], timeStamp: loggingEvent.timeStamp, }; this.logMessages.push(message); // write values to localStorage localStorage.setItem(this.localStorageKey, JSON.stringify(this.logMessages)); } /** * Gets the appender's name. * Mainly for unit testing purposes. * * @return appender's name */ toString() { return "Ionic.Logging.LocalStorageAppender"; } /** * Get the key which is used to store the messages in the local storage. */ getLocalStorageKey() { return this.localStorageKey; } /** * Get the maximum number of messages which will be stored in local storage. */ getMaxMessages() { return this.maxMessages; } /** * Set the maximum number of messages which will be stored in local storage. * * If the appender stores currently more messages than the new value allows, the oldest messages get removed. * * @param value new maximum number */ setMaxMessages(value) { if (this.maxMessages !== value) { this.maxMessages = value; if (this.logMessages.length > this.maxMessages) { // there are too much logMessages for the new value, therefore remove oldest messages while (this.logMessages.length > this.maxMessages) { this.logMessages.shift(); } // write values to localStorage localStorage.setItem(this.localStorageKey, JSON.stringify(this.logMessages)); } } } /** * Gets all messages stored in local storage. * Mainly for unit testing purposes. * * @return stored messages */ getLogMessages() { return this.logMessages; } /** * Removes all messages from local storage. * Mainly for unit testing purposes. */ clearLog() { this.logMessages = []; localStorage.removeItem(this.localStorageKey); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtc3RvcmFnZS1hcHBlbmRlci5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2lvbmljLWxvZ2dpbmctc2VydmljZS9zcmMvbGliL2xvY2FsLXN0b3JhZ2UtYXBwZW5kZXIubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLGNBQWMsTUFBTSxnQkFBZ0IsQ0FBQztBQUdqRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHN0M7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGNBQWMsQ0FBQyxRQUFRO2FBRWpELHVCQUFrQixHQUFHLEdBQUcsQ0FBQzthQUN6QixxQkFBZ0IsR0FBRyxNQUFNLENBQUM7SUFPekM7Ozs7T0FJRztJQUNILFlBQVksYUFBZ0Q7UUFDM0QsS0FBSyxFQUFFLENBQUM7UUFFUixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsSUFBSSxhQUFhLENBQUMsZUFBZSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQzVFLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxhQUFhLENBQUMsZUFBZSxDQUFDO1FBRXJELDRCQUE0QjtRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFHLG9CQUFvQixDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFOUUsa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDZCxlQUFlLEVBQUUsYUFBYSxDQUFDLGVBQWU7WUFD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cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgbG9nNGphdmFzY3JpcHQgZnJvbSBcImxvZzRqYXZhc2NyaXB0XCI7XG5cbmltcG9ydCB7IExvY2FsU3RvcmFnZUFwcGVuZGVyQ29uZmlndXJhdGlvbiB9IGZyb20gXCIuL2xvY2FsLXN0b3JhZ2UtYXBwZW5kZXIuY29uZmlndXJhdGlvblwiO1xuaW1wb3J0IHsgTG9nTGV2ZWxDb252ZXJ0ZXIgfSBmcm9tIFwiLi9sb2ctbGV2ZWwuY29udmVydGVyXCI7XG5pbXBvcnQgeyBMb2dMZXZlbCB9IGZyb20gXCIuL2xvZy1sZXZlbC5tb2RlbFwiO1xuaW1wb3J0IHsgTG9nTWVzc2FnZSB9IGZyb20gXCIuL2xvZy1tZXNzYWdlLm1vZGVsXCI7XG5cbi8qKlxuICogQW4gYXBwZW5kZXIgd2hpY2ggc3RvcmVzIHRoZSBsb2cgbWVzc2FnZXMgaW4gdGhlIGJyb3dzZXIncyBsb2NhbCBzdG9yYWdlLlxuICpcbiAqIFRoZSBtZXNzYWdlcyBhcmUgc2F2ZWQgSlNPTi1zZXJpYWxpemVkLlxuICogWW91IGhhdmUgdG8gY29uZmlndXJlIHdoaWNoIGtleSBpcyB1c2VkIGZvciBzdG9yaW5nIHRoZSBtZXNzYWdlcy5cbiAqXG4gKiBBIHR5cGljYWwgY29uZmlndXJhdGlvbiBjb3VsZCBiZTpcbiAqXG4gKiBgYGBqc29uXG4gKiB7XG4gKiAgIFwibG9jYWxTdG9yYWdlS2V5XCI6IFwibXlMb2dzXCIsXG4gKiAgIFwibWF4TWVzc2FnZXNcIjogNTAwLFxuICogICBcInRocmVzaG9sZFwiOiBcIklORk9cIlxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NhbFN0b3JhZ2VBcHBlbmRlciBleHRlbmRzIGxvZzRqYXZhc2NyaXB0LkFwcGVuZGVyIHtcblxuXHRwcml2YXRlIHN0YXRpYyBtYXhNZXNzYWdlc0RlZmF1bHQgPSAyNTA7XG5cdHByaXZhdGUgc3RhdGljIHRocmVzaG9sZERlZmF1bHQgPSBcIldBUk5cIjtcblxuXHRwcml2YXRlIG1heE1lc3NhZ2VzOiBudW1iZXI7XG5cblx0cHJpdmF0ZSBsb2NhbFN0b3JhZ2VLZXk6IHN0cmluZztcblx0cHJpdmF0ZSBsb2dNZXNzYWdlczogTG9nTWVzc2FnZVtdO1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBhcHBlbmRlci5cblx0ICpcblx0ICogQHBhcmFtIGNvbmZpZ3VyYXRpb24gY29uZmlndXJhdGlvbiBmb3IgdGhlIGFwcGVuZGVyLlxuXHQgKi9cblx0Y29uc3RydWN0b3IoY29uZmlndXJhdGlvbjogTG9jYWxTdG9yYWdlQXBwZW5kZXJDb25maWd1cmF0aW9uKSB7XG5cdFx0c3VwZXIoKTtcblxuXHRcdGlmICghY29uZmlndXJhdGlvbikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiY29uZmlndXJhdGlvbiBtdXN0IGJlIG5vdCBlbXB0eVwiKTtcblx0XHR9XG5cdFx0aWYgKCFjb25maWd1cmF0aW9uLmxvY2FsU3RvcmFnZUtleSB8fCBjb25maWd1cmF0aW9uLmxvY2FsU3RvcmFnZUtleSA9PT0gXCJcIikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwibG9jYWxTdG9yYWdlS2V5IG11c3QgYmUgbm90IGVtcHR5XCIpO1xuXHRcdH1cblx0XHR0aGlzLmxvY2FsU3RvcmFnZUtleSA9IGNvbmZpZ3VyYXRpb24ubG9jYWxTdG9yYWdlS2V5O1xuXG5cdFx0Ly8gcmVhZCBleGlzdGluZyBsb2dNZXNzYWdlc1xuXHRcdHRoaXMubG9nTWVzc2FnZXMgPSBMb2NhbFN0b3JhZ2VBcHBlbmRlci5sb2FkTG9nTWVzc2FnZXModGhpcy5sb2NhbFN0b3JhZ2VLZXkpO1xuXG5cdFx0Ly8gcHJvY2VzcyByZW1haW5pbmcgY29uZmlndXJhdGlvblxuXHRcdHRoaXMuY29uZmlndXJlKHtcblx0XHRcdGxvY2FsU3RvcmFnZUtleTogY29uZmlndXJhdGlvbi5sb2NhbFN0b3JhZ2VLZXksXG5cdFx0XHRtYXhNZXNzYWdlczogY29uZmlndXJhdGlvbi5tYXhNZXNzYWdlcyB8fCBMb2NhbFN0b3JhZ2VBcHBlbmRlci5tYXhNZXNzYWdlc0RlZmF1bHQsXG5cdFx0XHR0aHJlc2hvbGQ6IGNvbmZpZ3VyYXRpb24udGhyZXNob2xkIHx8IExvY2FsU3RvcmFnZUFwcGVuZGVyLnRocmVzaG9sZERlZmF1bHQsXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogTG9hZCBsb2cgbWVzc2FnZXMgZnJvbSBsb2NhbCBzdG9yYWdlIHdoaWNoIGFyZSBzdG9yZWQgdGhlcmUgdW5kZXIgdGhlIGdpdmVuIGtleS5cblx0ICpcblx0ICogQHBhcmFtIGxvY2FsU3RvcmFnZUtleSBsb2NhbCBzdG9yYWdlIGtleVxuXHQgKiBAcmV0dXJuIHN0b3JlZCBtZXNzYWdlc1xuXHQgKi9cblx0cHVibGljIHN0YXRpYyBsb2FkTG9nTWVzc2FnZXMobG9jYWxTdG9yYWdlS2V5OiBzdHJpbmcpOiBMb2dNZXNzYWdlW10ge1xuXHRcdGxldCBsb2dNZXNzYWdlczogTG9nTWVzc2FnZVtdO1xuXG5cdFx0aWYgKCFsb2NhbFN0b3JhZ2VLZXkgfHwgbG9jYWxTdG9yYWdlLmdldEl0ZW0obG9jYWxTdG9yYWdlS2V5KSA9PT0gbnVsbCkge1xuXHRcdFx0bG9nTWVzc2FnZXMgPSBbXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bG9nTWVzc2FnZXMgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKGxvY2FsU3RvcmFnZUtleSkpO1xuXHRcdFx0Zm9yIChjb25zdCBsb2dNZXNzYWdlIG9mIGxvZ01lc3NhZ2VzKSB7XG5cdFx0XHRcdC8vIHRpbWVzdGFtcHMgYXJlIHNlcmlhbGl6ZWQgYXMgc3RyaW5nc1xuXHRcdFx0XHRsb2dNZXNzYWdlLnRpbWVTdGFtcCA9IG5ldyBEYXRlKGxvZ01lc3NhZ2UudGltZVN0YW1wKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbG9nTWVzc2FnZXM7XG5cdH1cblxuXHQvKipcblx0ICogUmVtb3ZlIGxvZyBtZXNzYWdlcyBmcm9tIGxvY2FsIHN0b3JhZ2Ugd2hpY2ggYXJlIHN0b3JlZCB0aGVyZSB1bmRlciB0aGUgZ2l2ZW4ga2V5LlxuXHQgKlxuXHQgKiBAcGFyYW0gbG9jYWxTdG9yYWdlS2V5IGxvY2FsIHN0b3JhZ2Uga2V5XG5cdCAqL1xuXHRwdWJsaWMgc3RhdGljIHJlbW92ZUxvZ01lc3NhZ2VzKGxvY2FsU3RvcmFnZUtleTogc3RyaW5nKTogdm9pZCB7XG5cdFx0bG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0obG9jYWxTdG9yYWdlS2V5KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb25maWd1cmVzIHRoZSBsb2dnaW5nIGRlcGVuZGluZyBvbiB0aGUgZ2l2ZW4gY29uZmlndXJhdGlvbi5cblx0ICpcblx0ICogT25seSB0aGUgZGVmaW5lZCBwcm9wZXJ0aWVzIGdldCBvdmVyd3JpdHRlbi5cblx0ICogVGhlIGxvY2FsU3RvcmFnZUtleSBjYW5ub3QgYmUgbW9kaWZpZWQuXG5cdCAqXG5cdCAqIEBwYXJhbSBjb25maWd1cmF0aW9uIGNvbmZpZ3VyYXRpb24gZGF0YS5cblx0ICovXG5cdHB1YmxpYyBjb25maWd1cmUoY29uZmlndXJhdGlvbjogTG9jYWxTdG9yYWdlQXBwZW5kZXJDb25maWd1cmF0aW9uKTogdm9pZCB7XG5cdFx0aWYgKGNvbmZpZ3VyYXRpb24pIHtcblx0XHRcdGlmIChjb25maWd1cmF0aW9uLmxvY2FsU3RvcmFnZUtleSAmJiBjb25maWd1cmF0aW9uLmxvY2FsU3RvcmFnZUtleSAhPT0gdGhpcy5sb2NhbFN0b3JhZ2VLZXkpIHtcblx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFwibG9jYWxTdG9yYWdlS2V5IG11c3Qgbm90IGJlIGNoYW5nZWRcIik7XG5cdFx0XHR9XG5cdFx0XHRpZiAoY29uZmlndXJhdGlvbi5tYXhNZXNzYWdlcykge1xuXHRcdFx0XHR0aGlzLnNldE1heE1lc3NhZ2VzKGNvbmZpZ3VyYXRpb24ubWF4TWVzc2FnZXMpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGNvbmZpZ3VyYXRpb24udGhyZXNob2xkKSB7XG5cdFx0XHRcdGNvbnN0IGNvbnZlcnRlZFRocmVzaG9sZCA9IExvZ0xldmVsQ29udmVydGVyLmxldmVsVG9Mb2c0SmF2YXNjcmlwdChcblx0XHRcdFx0XHRMb2dMZXZlbENvbnZlcnRlci5sZXZlbEZyb21TdHJpbmcoY29uZmlndXJhdGlvbi50aHJlc2hvbGQpKTtcblx0XHRcdFx0dGhpcy5zZXRUaHJlc2hvbGQoY29udmVydGVkVGhyZXNob2xkKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogQXBwZW5kZXItc3BlY2lmaWMgbWV0aG9kIHRvIGFwcGVuZCBhIGxvZyBtZXNzYWdlLlxuXHQgKlxuXHQgKiBAcGFyYW0gbG9nZ2luZ0V2ZW50IGV2ZW50IHRvIGJlIGFwcGVuZGVkLlxuXHQgKi9cblx0cHVibGljIGFwcGVuZChsb2dnaW5nRXZlbnQ6IGxvZzRqYXZhc2NyaXB0LkxvZ2dpbmdFdmVudCk6IHZvaWQge1xuXHRcdC8vIGlmIGxvZ01lc3NhZ2VzIGlzIGFscmVhZHkgZnVsbCwgcmVtb3ZlIG9sZGVzdCBlbGVtZW50XG5cdFx0d2hpbGUgKHRoaXMubG9nTWVzc2FnZXMubGVuZ3RoID49IHRoaXMubWF4TWVzc2FnZXMpIHtcblx0XHRcdHRoaXMubG9nTWVzc2FnZXMuc2hpZnQoKTtcblx0XHR9XG5cdFx0Ly8gYWRkIGV2ZW50IHRvIGxvZ01lc3NhZ2VzXG5cdFx0Y29uc3QgbWVzc2FnZTogTG9nTWVzc2FnZSA9IHtcblx0XHRcdGxldmVsOiBMb2dMZXZlbFtMb2dMZXZlbENvbnZlcnRlci5sZXZlbEZyb21Mb2c0SmF2YXNjcmlwdChsb2dnaW5nRXZlbnQubGV2ZWwpXSxcblx0XHRcdGxvZ2dlcjogdHlwZW9mIGxvZ2dpbmdFdmVudC5sb2dnZXIgIT09IFwidW5kZWZpbmVkXCIgPyBsb2dnaW5nRXZlbnQubG9nZ2VyLm5hbWUgOiB1bmRlZmluZWQsXG5cdFx0XHRtZXNzYWdlOiBsb2dnaW5nRXZlbnQubWVzc2FnZXMuc2xpY2UoMSksXG5cdFx0XHRtZXRob2ROYW1lOiBsb2dnaW5nRXZlbnQubWVzc2FnZXNbMF0sXG5cdFx0XHR0aW1lU3RhbXA6IGxvZ2dpbmdFdmVudC50aW1lU3RhbXAsXG5cdFx0fTtcblx0XHR0aGlzLmxvZ01lc3NhZ2VzLnB1c2gobWVzc2FnZSk7XG5cblx0XHQvLyB3cml0ZSB2YWx1ZXMgdG8gbG9jYWxTdG9yYWdlXG5cdFx0bG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5sb2NhbFN0b3JhZ2VLZXksIEpTT04uc3RyaW5naWZ5KHRoaXMubG9nTWVzc2FnZXMpKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXRzIHRoZSBhcHBlbmRlcidzIG5hbWUuXG5cdCAqIE1haW5seSBmb3IgdW5pdCB0ZXN0aW5nIHB1cnBvc2VzLlxuXHQgKlxuXHQgKiBAcmV0dXJuIGFwcGVuZGVyJ3MgbmFtZVxuXHQgKi9cblx0cHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIFwiSW9uaWMuTG9nZ2luZy5Mb2NhbFN0b3JhZ2VBcHBlbmRlclwiO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCB0aGUga2V5IHdoaWNoIGlzIHVzZWQgdG8gc3RvcmUgdGhlIG1lc3NhZ2VzIGluIHRoZSBsb2NhbCBzdG9yYWdlLlxuXHQgKi9cblx0cHVibGljIGdldExvY2FsU3RvcmFnZUtleSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLmxvY2FsU3RvcmFnZUtleTtcblx0fVxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIG1lc3NhZ2VzIHdoaWNoIHdpbGwgYmUgc3RvcmVkIGluIGxvY2FsIHN0b3JhZ2UuXG5cdCAqL1xuXHRwdWJsaWMgZ2V0TWF4TWVzc2FnZXMoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5tYXhNZXNzYWdlcztcblx0fVxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIG1lc3NhZ2VzIHdoaWNoIHdpbGwgYmUgc3RvcmVkIGluIGxvY2FsIHN0b3JhZ2UuXG5cdCAqXG5cdCAqIElmIHRoZSBhcHBlbmRlciBzdG9yZXMgY3VycmVudGx5IG1vcmUgbWVzc2FnZXMgdGhhbiB0aGUgbmV3IHZhbHVlIGFsbG93cywgdGhlIG9sZGVzdCBtZXNzYWdlcyBnZXQgcmVtb3ZlZC5cblx0ICpcblx0ICogQHBhcmFtIHZhbHVlIG5ldyBtYXhpbXVtIG51bWJlclxuXHQgKi9cblx0cHVibGljIHNldE1heE1lc3NhZ2VzKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcblx0XHRpZiAodGhpcy5tYXhNZXNzYWdlcyAhPT0gdmFsdWUpIHtcblx0XHRcdHRoaXMubWF4TWVzc2FnZXMgPSB2YWx1ZTtcblxuXHRcdFx0aWYgKHRoaXMubG9nTWVzc2FnZXMubGVuZ3RoID4gdGhpcy5tYXhNZXNzYWdlcykge1xuXHRcdFx0XHQvLyB0aGVyZSBhcmUgdG9vIG11Y2ggbG9nTWVzc2FnZXMgZm9yIHRoZSBuZXcgdmFsdWUsIHRoZXJlZm9yZSByZW1vdmUgb2xkZXN0IG1lc3NhZ2VzXG5cdFx0XHRcdHdoaWxlICh0aGlzLmxvZ01lc3NhZ2VzLmxlbmd0aCA+IHRoaXMubWF4TWVzc2FnZXMpIHtcblx0XHRcdFx0XHR0aGlzLmxvZ01lc3NhZ2VzLnNoaWZ0KCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyB3cml0ZSB2YWx1ZXMgdG8gbG9jYWxTdG9yYWdlXG5cdFx0XHRcdGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMubG9jYWxTdG9yYWdlS2V5LCBKU09OLnN0cmluZ2lmeSh0aGlzLmxvZ01lc3NhZ2VzKSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEdldHMgYWxsIG1lc3NhZ2VzIHN0b3JlZCBpbiBsb2NhbCBzdG9yYWdlLlxuXHQgKiBNYWlubHkgZm9yIHVuaXQgdGVzdGluZyBwdXJwb3Nlcy5cblx0ICpcblx0ICogQHJldHVybiBzdG9yZWQgbWVzc2FnZXNcblx0ICovXG5cdHB1YmxpYyBnZXRMb2dNZXNzYWdlcygpOiBMb2dNZXNzYWdlW10ge1xuXHRcdHJldHVybiB0aGlzLmxvZ01lc3NhZ2VzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbW92ZXMgYWxsIG1lc3NhZ2VzIGZyb20gbG9jYWwgc3RvcmFnZS5cblx0ICogTWFpbmx5IGZvciB1bml0IHRlc3RpbmcgcHVycG9zZXMuXG5cdCAqL1xuXHRwdWJsaWMgY2xlYXJMb2coKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dNZXNzYWdlcyA9IFtdO1xuXHRcdGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMubG9jYWxTdG9yYWdlS2V5KTtcblx0fVxufVxuIl19