@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
133 lines • 18.7 kB
JavaScript
import { Injectable } from '@angular/core';
import { AlarmStatus } from '@c8y/client';
import { Permissions } from '@c8y/ngx-components';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components";
export class AlarmDetailsService {
constructor(permissions) {
this.permissions = permissions;
this.STATUS_ATTRIBUTE = 'status';
}
/**
* Retrieves the username of the user who acknowledged an alarm status.
*
* This method checks if the provided status is equal to the acknowledged
* status. If it is not, or if the
* audit log is empty or the first log item does not contain a user, the
* method returns a default value ('--').
*
* If the status is the acknowledged status and the audit log contains valid
* records, the method iterates over the audit records in reverse order
* (starting from the most recent). It finds the first record where the
* status attribute (defined by this.STATUS_ATTRIBUTE) has been changed to
* the acknowledged status. The method then returns the username of the user
* who made this change.
*
* If no such change is found in the audit records, it returns the username
* from the first record of the audit log.
*
* There can be multiple audit logs with ACKNOWLEDGED status.
*
* @param status - The current status of the alarm.
* @param auditLog - An array of audit records to process.
* @returns The username of the user who acknowledged the status
* or '--' if the status is not acknowledged or audit log is invalid.
*/
getAcknowledgedBy(status, auditLog) {
let acknowledgedBy = '--';
if (status !== AlarmStatus.ACKNOWLEDGED || !auditLog || !auditLog[0]?.user) {
return acknowledgedBy;
}
acknowledgedBy = auditLog[0].user;
return auditLog.reduceRight((acc, auditLogItem) => {
const changes = Array.from(auditLogItem.changes || []);
const acknowledgedStatusChange = changes.find((change) => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.ACKNOWLEDGED);
return (acknowledgedStatusChange && auditLogItem.user) || acc;
}, acknowledgedBy);
}
/**
* Calculates the acknowledge time from a list of audit records.
*
* This method iterates over the provided audit records in reverse order
* (starting from the most recent) and finds the first record where a
* specific status attribute (defined by this.STATUS_ATTRIBUTE) has been
* acknowledged. It then returns the creation time of that record.
*
* If no such record is found, the method returns the creation time of the
* first audit record. If the audit record list is empty, it returns null.
*
* There can be multiple audit logs with ACKNOWLEDGED status.
*
* @param auditLog - An array of audit records to process.
* @returns The creation time of the acknowledged record,
* the creation time of the first record if no acknowledged record is found,
* or null if the audit log is empty.
*/
getAcknowledgeTime(auditLog) {
const initialValue = auditLog.length ? auditLog[0].creationTime : null;
return auditLog.reduceRight((acc, auditLogItem) => {
const changes = Array.from(auditLogItem.changes || []);
const acknowledgedStatusChange = changes.find((change) => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.ACKNOWLEDGED);
return acknowledgedStatusChange ? auditLogItem.creationTime : acc;
}, initialValue);
}
/**
* Retrieves the end time of an event from an audit log.
*
* The method processes the provided audit log to find the first instance
* (starting from the most recent record) where the status was changed to 'CLEARED'.
* It iterates over the audit records and
* checks the changes in each record to find this status change.
*
* If a record with the CLEARED status is found, the method returns the creation time
* of that record. If the entire audit log is processed without finding a CLEARED status,
* the creation time of the first audit log record is returned.
*
* If the audit log is empty or null, the method returns null.
*
* There can be only one audit log with CLEARED status.
*
* @param auditLog - An array of audit records to process.
* @returns The creation time of the record with the CLEARED status,
* the creation time of the first record if no CLEARED status is found,
* or null if the audit log is empty or null.
*/
getEndTime(auditLog) {
if (!auditLog || auditLog.length === 0) {
return null;
}
let latestClearedAuditTime = null;
for (const auditLogItem of auditLog) {
const changes = Array.from(auditLogItem.changes || []);
const clearedStatusChange = changes.find(change => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.CLEARED);
if (clearedStatusChange) {
if (!latestClearedAuditTime || auditLogItem.creationTime > latestClearedAuditTime) {
latestClearedAuditTime = auditLogItem.creationTime;
}
}
}
return latestClearedAuditTime || auditLog[0].creationTime;
}
checkIfHasAnyRoleAllowingToCreateSmartRule() {
const ROLES_ALLOWING_SMART_RULE_CREATION = [
[
Permissions.ROLE_INVENTORY_ADMIN,
Permissions.ROLE_INVENTORY_CREATE,
Permissions.ROLE_MANAGED_OBJECT_ADMIN,
Permissions.ROLE_MANAGED_OBJECT_CREATE
],
[Permissions.ROLE_CEP_MANAGEMENT_ADMIN, Permissions.ROLE_SMARTRULE_ADMIN]
];
return (this.permissions.hasAnyRole(ROLES_ALLOWING_SMART_RULE_CREATION[0]) &&
this.permissions.hasAnyRole(ROLES_ALLOWING_SMART_RULE_CREATION[1]));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmDetailsService, deps: [{ token: i1.Permissions }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmDetailsService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmDetailsService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.Permissions }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxhcm0tZGV0YWlscy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWxhcm1zL2FsYXJtLWRldGFpbHMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxXQUFXLEVBQTBDLE1BQU0sYUFBYSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7O0FBS2xELE1BQU0sT0FBTyxtQkFBbUI7SUFHOUIsWUFBb0IsV0FBd0I7UUFBeEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFGM0IscUJBQWdCLEdBQUcsUUFBUSxDQUFDO0lBRUUsQ0FBQztJQUVoRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bd0JHO0lBQ0gsaUJBQWlCLENBQUMsTUFBdUIsRUFBRSxRQUF3QjtRQUNqRSxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFFMUIsSUFBSSxNQUFNLEtBQUssV0FBVyxDQUFDLFlBQVksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUMzRSxPQUFPLGNBQWMsQ0FBQztRQUN4QixDQUFDO1FBRUQsY0FBYyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFbEMsT0FBTyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsR0FBRyxFQUFFLFlBQVksRUFBRSxFQUFFO1lBQ2hELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQzNDLENBQUMsTUFBZSxFQUFFLEVBQUUsQ0FDbEIsTUFBTSxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxXQUFXLENBQUMsWUFBWSxDQUM3RixDQUFDO1lBQ0YsT0FBTyxDQUFDLHdCQUF3QixJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUM7UUFDaEUsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FpQkc7SUFDSCxrQkFBa0IsQ0FBQyxRQUF3QjtRQUN6QyxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFdkUsT0FBTyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsR0FBRyxFQUFFLFlBQVksRUFBRSxFQUFFO1lBQ2hELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQzNDLENBQUMsTUFBZSxFQUFFLEVBQUUsQ0FDbEIsTUFBTSxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxXQUFXLENBQUMsWUFBWSxDQUM3RixDQUFDO1lBQ0YsT0FBTyx3QkFBd0IsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3BFLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bb0JHO0lBQ0gsVUFBVSxDQUFDLFFBQXdCO1FBQ2pDLElBQUksQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxJQUFJLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUVsQyxLQUFLLE1BQU0sWUFBWSxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQ3RDLE1BQU0sQ0FBQyxFQUFFLENBQ1AsTUFBTSxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsZ0JBQWdCLElBQUksTUFBTSxDQUFDLFFBQVEsS0FBSyxXQUFXLENBQUMsT0FBTyxDQUN4RixDQUFDO1lBRUYsSUFBSSxtQkFBbUIsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsc0JBQXNCLElBQUksWUFBWSxDQUFDLFlBQVksR0FBRyxzQkFBc0IsRUFBRSxDQUFDO29CQUNsRixzQkFBc0IsR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDO2dCQUNyRCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLHNCQUFzQixJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUM7SUFDNUQsQ0FBQztJQUVELDBDQUEwQztRQUN4QyxNQUFNLGtDQUFrQyxHQUFHO1lBQ3pDO2dCQUNFLFdBQVcsQ0FBQyxvQkFBb0I7Z0JBQ2hDLFdBQVcsQ0FBQyxxQkFBcUI7Z0JBQ2pDLFdBQVcsQ0FBQyx5QkFBeUI7Z0JBQ3JDLFdBQVcsQ0FBQywwQkFBMEI7YUFDdkM7WUFDRCxDQUFDLFdBQVcsQ0FBQyx5QkFBeUIsRUFBRSxXQUFXLENBQUMsb0JBQW9CLENBQUM7U0FDMUUsQ0FBQztRQUVGLE9BQU8sQ0FDTCxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNuRSxDQUFDO0lBQ0osQ0FBQzsrR0E1SVUsbUJBQW1CO21IQUFuQixtQkFBbUIsY0FGbEIsTUFBTTs7NEZBRVAsbUJBQW1CO2tCQUgvQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFsYXJtU3RhdHVzLCBBbGFybVN0YXR1c1R5cGUsIElBdWRpdFJlY29yZCwgSUNoYW5nZSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IFBlcm1pc3Npb25zIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEFsYXJtRGV0YWlsc1NlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IFNUQVRVU19BVFRSSUJVVEUgPSAnc3RhdHVzJztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBlcm1pc3Npb25zOiBQZXJtaXNzaW9ucykge31cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB1c2VybmFtZSBvZiB0aGUgdXNlciB3aG8gYWNrbm93bGVkZ2VkIGFuIGFsYXJtIHN0YXR1cy5cbiAgICpcbiAgICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBwcm92aWRlZCBzdGF0dXMgaXMgZXF1YWwgdG8gdGhlIGFja25vd2xlZGdlZFxuICAgKiBzdGF0dXMuIElmIGl0IGlzIG5vdCwgb3IgaWYgdGhlXG4gICAqIGF1ZGl0IGxvZyBpcyBlbXB0eSBvciB0aGUgZmlyc3QgbG9nIGl0ZW0gZG9lcyBub3QgY29udGFpbiBhIHVzZXIsIHRoZVxuICAgKiBtZXRob2QgcmV0dXJucyBhIGRlZmF1bHQgdmFsdWUgKCctLScpLlxuICAgKlxuICAgKiBJZiB0aGUgc3RhdHVzIGlzIHRoZSBhY2tub3dsZWRnZWQgc3RhdHVzIGFuZCB0aGUgYXVkaXQgbG9nIGNvbnRhaW5zIHZhbGlkXG4gICAqIHJlY29yZHMsIHRoZSBtZXRob2QgaXRlcmF0ZXMgb3ZlciB0aGUgYXVkaXQgcmVjb3JkcyBpbiByZXZlcnNlIG9yZGVyXG4gICAqIChzdGFydGluZyBmcm9tIHRoZSBtb3N0IHJlY2VudCkuIEl0IGZpbmRzIHRoZSBmaXJzdCByZWNvcmQgd2hlcmUgdGhlXG4gICAqIHN0YXR1cyBhdHRyaWJ1dGUgKGRlZmluZWQgYnkgdGhpcy5TVEFUVVNfQVRUUklCVVRFKSBoYXMgYmVlbiBjaGFuZ2VkIHRvXG4gICAqIHRoZSBhY2tub3dsZWRnZWQgc3RhdHVzLiBUaGUgbWV0aG9kIHRoZW4gcmV0dXJucyB0aGUgdXNlcm5hbWUgb2YgdGhlIHVzZXJcbiAgICogd2hvIG1hZGUgdGhpcyBjaGFuZ2UuXG4gICAqXG4gICAqIElmIG5vIHN1Y2ggY2hhbmdlIGlzIGZvdW5kIGluIHRoZSBhdWRpdCByZWNvcmRzLCBpdCByZXR1cm5zIHRoZSB1c2VybmFtZVxuICAgKiBmcm9tIHRoZSBmaXJzdCByZWNvcmQgb2YgdGhlIGF1ZGl0IGxvZy5cbiAgICpcbiAgICogVGhlcmUgY2FuIGJlIG11bHRpcGxlIGF1ZGl0IGxvZ3Mgd2l0aCBBQ0tOT1dMRURHRUQgc3RhdHVzLlxuICAgKlxuICAgKiBAcGFyYW0gc3RhdHVzIC0gVGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBhbGFybS5cbiAgICogQHBhcmFtIGF1ZGl0TG9nIC0gQW4gYXJyYXkgb2YgYXVkaXQgcmVjb3JkcyB0byBwcm9jZXNzLlxuICAgKiBAcmV0dXJucyBUaGUgdXNlcm5hbWUgb2YgdGhlIHVzZXIgd2hvIGFja25vd2xlZGdlZCB0aGUgc3RhdHVzXG4gICAqICAgICAgICAgICBvciAnLS0nIGlmIHRoZSBzdGF0dXMgaXMgbm90IGFja25vd2xlZGdlZCBvciBhdWRpdCBsb2cgaXMgaW52YWxpZC5cbiAgICovXG4gIGdldEFja25vd2xlZGdlZEJ5KHN0YXR1czogQWxhcm1TdGF0dXNUeXBlLCBhdWRpdExvZzogSUF1ZGl0UmVjb3JkW10pOiBzdHJpbmcge1xuICAgIGxldCBhY2tub3dsZWRnZWRCeSA9ICctLSc7XG5cbiAgICBpZiAoc3RhdHVzICE9PSBBbGFybVN0YXR1cy5BQ0tOT1dMRURHRUQgfHwgIWF1ZGl0TG9nIHx8ICFhdWRpdExvZ1swXT8udXNlcikge1xuICAgICAgcmV0dXJuIGFja25vd2xlZGdlZEJ5O1xuICAgIH1cblxuICAgIGFja25vd2xlZGdlZEJ5ID0gYXVkaXRMb2dbMF0udXNlcjtcblxuICAgIHJldHVybiBhdWRpdExvZy5yZWR1Y2VSaWdodCgoYWNjLCBhdWRpdExvZ0l0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBBcnJheS5mcm9tKGF1ZGl0TG9nSXRlbS5jaGFuZ2VzIHx8IFtdKTtcbiAgICAgIGNvbnN0IGFja25vd2xlZGdlZFN0YXR1c0NoYW5nZSA9IGNoYW5nZXMuZmluZChcbiAgICAgICAgKGNoYW5nZTogSUNoYW5nZSkgPT5cbiAgICAgICAgICBjaGFuZ2UuYXR0cmlidXRlID09PSB0aGlzLlNUQVRVU19BVFRSSUJVVEUgJiYgY2hhbmdlLm5ld1ZhbHVlID09PSBBbGFybVN0YXR1cy5BQ0tOT1dMRURHRURcbiAgICAgICk7XG4gICAgICByZXR1cm4gKGFja25vd2xlZGdlZFN0YXR1c0NoYW5nZSAmJiBhdWRpdExvZ0l0ZW0udXNlcikgfHwgYWNjO1xuICAgIH0sIGFja25vd2xlZGdlZEJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBhY2tub3dsZWRnZSB0aW1lIGZyb20gYSBsaXN0IG9mIGF1ZGl0IHJlY29yZHMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGl0ZXJhdGVzIG92ZXIgdGhlIHByb3ZpZGVkIGF1ZGl0IHJlY29yZHMgaW4gcmV2ZXJzZSBvcmRlclxuICAgKiAoc3RhcnRpbmcgZnJvbSB0aGUgbW9zdCByZWNlbnQpIGFuZCBmaW5kcyB0aGUgZmlyc3QgcmVjb3JkIHdoZXJlIGFcbiAgICogc3BlY2lmaWMgc3RhdHVzIGF0dHJpYnV0ZSAoZGVmaW5lZCBieSB0aGlzLlNUQVRVU19BVFRSSUJVVEUpIGhhcyBiZWVuXG4gICAqIGFja25vd2xlZGdlZC4gSXQgdGhlbiByZXR1cm5zIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoYXQgcmVjb3JkLlxuICAgKlxuICAgKiBJZiBubyBzdWNoIHJlY29yZCBpcyBmb3VuZCwgdGhlIG1ldGhvZCByZXR1cm5zIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZVxuICAgKiBmaXJzdCBhdWRpdCByZWNvcmQuIElmIHRoZSBhdWRpdCByZWNvcmQgbGlzdCBpcyBlbXB0eSwgaXQgcmV0dXJucyBudWxsLlxuICAgKlxuICAgKiBUaGVyZSBjYW4gYmUgbXVsdGlwbGUgYXVkaXQgbG9ncyB3aXRoIEFDS05PV0xFREdFRCBzdGF0dXMuXG4gICAqXG4gICAqIEBwYXJhbSBhdWRpdExvZyAtIEFuIGFycmF5IG9mIGF1ZGl0IHJlY29yZHMgdG8gcHJvY2Vzcy5cbiAgICogQHJldHVybnMgVGhlIGNyZWF0aW9uIHRpbWUgb2YgdGhlIGFja25vd2xlZGdlZCByZWNvcmQsXG4gICAqICAgICAgICAgICB0aGUgY3JlYXRpb24gdGltZSBvZiB0aGUgZmlyc3QgcmVjb3JkIGlmIG5vIGFja25vd2xlZGdlZCByZWNvcmQgaXMgZm91bmQsXG4gICAqICAgICAgICAgICBvciBudWxsIGlmIHRoZSBhdWRpdCBsb2cgaXMgZW1wdHkuXG4gICAqL1xuICBnZXRBY2tub3dsZWRnZVRpbWUoYXVkaXRMb2c6IElBdWRpdFJlY29yZFtdKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgaW5pdGlhbFZhbHVlID0gYXVkaXRMb2cubGVuZ3RoID8gYXVkaXRMb2dbMF0uY3JlYXRpb25UaW1lIDogbnVsbDtcblxuICAgIHJldHVybiBhdWRpdExvZy5yZWR1Y2VSaWdodCgoYWNjLCBhdWRpdExvZ0l0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBBcnJheS5mcm9tKGF1ZGl0TG9nSXRlbS5jaGFuZ2VzIHx8IFtdKTtcbiAgICAgIGNvbnN0IGFja25vd2xlZGdlZFN0YXR1c0NoYW5nZSA9IGNoYW5nZXMuZmluZChcbiAgICAgICAgKGNoYW5nZTogSUNoYW5nZSkgPT5cbiAgICAgICAgICBjaGFuZ2UuYXR0cmlidXRlID09PSB0aGlzLlNUQVRVU19BVFRSSUJVVEUgJiYgY2hhbmdlLm5ld1ZhbHVlID09PSBBbGFybVN0YXR1cy5BQ0tOT1dMRURHRURcbiAgICAgICk7XG4gICAgICByZXR1cm4gYWNrbm93bGVkZ2VkU3RhdHVzQ2hhbmdlID8gYXVkaXRMb2dJdGVtLmNyZWF0aW9uVGltZSA6IGFjYztcbiAgICB9LCBpbml0aWFsVmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgZW5kIHRpbWUgb2YgYW4gZXZlbnQgZnJvbSBhbiBhdWRpdCBsb2cuXG4gICAqXG4gICAqIFRoZSBtZXRob2QgcHJvY2Vzc2VzIHRoZSBwcm92aWRlZCBhdWRpdCBsb2cgdG8gZmluZCB0aGUgZmlyc3QgaW5zdGFuY2VcbiAgICogKHN0YXJ0aW5nIGZyb20gdGhlIG1vc3QgcmVjZW50IHJlY29yZCkgd2hlcmUgdGhlIHN0YXR1cyB3YXMgY2hhbmdlZCB0byAnQ0xFQVJFRCcuXG4gICAqIEl0IGl0ZXJhdGVzIG92ZXIgdGhlIGF1ZGl0IHJlY29yZHMgYW5kXG4gICAqIGNoZWNrcyB0aGUgY2hhbmdlcyBpbiBlYWNoIHJlY29yZCB0byBmaW5kIHRoaXMgc3RhdHVzIGNoYW5nZS5cbiAgICpcbiAgICogSWYgYSByZWNvcmQgd2l0aCB0aGUgQ0xFQVJFRCBzdGF0dXMgaXMgZm91bmQsIHRoZSBtZXRob2QgcmV0dXJucyB0aGUgY3JlYXRpb24gdGltZVxuICAgKiBvZiB0aGF0IHJlY29yZC4gSWYgdGhlIGVudGlyZSBhdWRpdCBsb2cgaXMgcHJvY2Vzc2VkIHdpdGhvdXQgZmluZGluZyBhIENMRUFSRUQgc3RhdHVzLFxuICAgKiB0aGUgY3JlYXRpb24gdGltZSBvZiB0aGUgZmlyc3QgYXVkaXQgbG9nIHJlY29yZCBpcyByZXR1cm5lZC5cbiAgICpcbiAgICogSWYgdGhlIGF1ZGl0IGxvZyBpcyBlbXB0eSBvciBudWxsLCB0aGUgbWV0aG9kIHJldHVybnMgbnVsbC5cbiAgICpcbiAgICogVGhlcmUgY2FuIGJlIG9ubHkgb25lIGF1ZGl0IGxvZyB3aXRoIENMRUFSRUQgc3RhdHVzLlxuICAgKlxuICAgKiBAcGFyYW0gYXVkaXRMb2cgLSBBbiBhcnJheSBvZiBhdWRpdCByZWNvcmRzIHRvIHByb2Nlc3MuXG4gICAqIEByZXR1cm5zIFRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZSByZWNvcmQgd2l0aCB0aGUgQ0xFQVJFRCBzdGF0dXMsXG4gICAqICAgICAgICAgIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZSBmaXJzdCByZWNvcmQgaWYgbm8gQ0xFQVJFRCBzdGF0dXMgaXMgZm91bmQsXG4gICAqICAgICAgICAgIG9yIG51bGwgaWYgdGhlIGF1ZGl0IGxvZyBpcyBlbXB0eSBvciBudWxsLlxuICAgKi9cbiAgZ2V0RW5kVGltZShhdWRpdExvZzogSUF1ZGl0UmVjb3JkW10pOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoIWF1ZGl0TG9nIHx8IGF1ZGl0TG9nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IGxhdGVzdENsZWFyZWRBdWRpdFRpbWUgPSBudWxsO1xuXG4gICAgZm9yIChjb25zdCBhdWRpdExvZ0l0ZW0gb2YgYXVkaXRMb2cpIHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBBcnJheS5mcm9tKGF1ZGl0TG9nSXRlbS5jaGFuZ2VzIHx8IFtdKTtcbiAgICAgIGNvbnN0IGNsZWFyZWRTdGF0dXNDaGFuZ2UgPSBjaGFuZ2VzLmZpbmQoXG4gICAgICAgIGNoYW5nZSA9PlxuICAgICAgICAgIGNoYW5nZS5hdHRyaWJ1dGUgPT09IHRoaXMuU1RBVFVTX0FUVFJJQlVURSAmJiBjaGFuZ2UubmV3VmFsdWUgPT09IEFsYXJtU3RhdHVzLkNMRUFSRURcbiAgICAgICk7XG5cbiAgICAgIGlmIChjbGVhcmVkU3RhdHVzQ2hhbmdlKSB7XG4gICAgICAgIGlmICghbGF0ZXN0Q2xlYXJlZEF1ZGl0VGltZSB8fCBhdWRpdExvZ0l0ZW0uY3JlYXRpb25UaW1lID4gbGF0ZXN0Q2xlYXJlZEF1ZGl0VGltZSkge1xuICAgICAgICAgIGxhdGVzdENsZWFyZWRBdWRpdFRpbWUgPSBhdWRpdExvZ0l0ZW0uY3JlYXRpb25UaW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxhdGVzdENsZWFyZWRBdWRpdFRpbWUgfHwgYXVkaXRMb2dbMF0uY3JlYXRpb25UaW1lO1xuICB9XG5cbiAgY2hlY2tJZkhhc0FueVJvbGVBbGxvd2luZ1RvQ3JlYXRlU21hcnRSdWxlKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IFJPTEVTX0FMTE9XSU5HX1NNQVJUX1JVTEVfQ1JFQVRJT04gPSBbXG4gICAgICBbXG4gICAgICAgIFBlcm1pc3Npb25zLlJPTEVfSU5WRU5UT1JZX0FETUlOLFxuICAgICAgICBQZXJtaXNzaW9ucy5ST0xFX0lOVkVOVE9SWV9DUkVBVEUsXG4gICAgICAgIFBlcm1pc3Npb25zLlJPTEVfTUFOQUdFRF9PQkpFQ1RfQURNSU4sXG4gICAgICAgIFBlcm1pc3Npb25zLlJPTEVfTUFOQUdFRF9PQkpFQ1RfQ1JFQVRFXG4gICAgICBdLFxuICAgICAgW1Blcm1pc3Npb25zLlJPTEVfQ0VQX01BTkFHRU1FTlRfQURNSU4sIFBlcm1pc3Npb25zLlJPTEVfU01BUlRSVUxFX0FETUlOXVxuICAgIF07XG5cbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5wZXJtaXNzaW9ucy5oYXNBbnlSb2xlKFJPTEVTX0FMTE9XSU5HX1NNQVJUX1JVTEVfQ1JFQVRJT05bMF0pICYmXG4gICAgICB0aGlzLnBlcm1pc3Npb25zLmhhc0FueVJvbGUoUk9MRVNfQUxMT1dJTkdfU01BUlRfUlVMRV9DUkVBVElPTlsxXSlcbiAgICApO1xuICB9XG59XG4iXX0=