ionic-logging-service
Version:
Logging functionalities for apps built with Ionic framework
177 lines • 19.7 kB
JavaScript
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