moh-common-lib
Version:
A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).
274 lines • 20.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AbstractHttpService } from './abstract-api-service';
import { throwError } from 'rxjs';
import * as moment_ from 'moment';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common/http";
/** @type {?} */
const moment = moment_;
/** @enum {string} */
const SeverityLevels = {
INFO: 'info',
ERROR: 'error',
};
/** @enum {string} */
const CommonLogEvents = {
navigation: 'navigation',
error: 'error',
submission: 'submission',
};
export { CommonLogEvents };
/**
* @record
*/
export function CommonLogMessage() { }
if (false) {
/**
* The type of event being logged.
* @type {?}
*/
CommonLogMessage.prototype.event;
/* Skipping unhandled member: [key: string]: any;*/
}
export class CommonLogger extends AbstractHttpService {
/**
* @param {?} http
*/
constructor(http) {
super(http);
this.http = http;
/**
* The HTTP Headers which go with each request. These MUST be set if you are
* using the logger. Fields include:
*
* - program (REQUIRED, the application wide code)
* - applicationId (REQUIRED, like sessionId)
* - request_method (REQUIRED, 'POST')
* - logsource: (REQUIRED, window.location.hostname)
* - http_x_forwarded_host (REQUIRED, window.location.hostname)
*
*/
this._headers = new HttpHeaders({
request_method: 'POST',
logsource: window.location.hostname,
http_x_forwarded_host: window.location.hostname
});
this.url = null;
}
/**
* @param {?} id
* @return {?}
*/
set applicationId(id) {
this._headers = this._headers.set('applicationId', id);
}
/**
* @return {?}
*/
get applicationId() {
return this._headers.get('applicationId');
}
/**
* @param {?} name
* @return {?}
*/
set programName(name) {
this._headers = this._headers.set('program', name);
}
/**
* @return {?}
*/
get programName() {
return this._headers.get('name');
}
/**
* @param {?} newURL
* @return {?}
*/
setURL(newURL) {
this.url = newURL;
}
/**
* @param {?} message
* @return {?}
*/
log(message) {
this._log((/** @type {?} */ (message)));
}
/**
* @param {?} errorMessage
* @return {?}
*/
logError(errorMessage) {
this._logError((/** @type {?} */ (errorMessage)));
}
/**
* Log a message to Splunk. This is the main way to send logs and
* automatically includes meta-data. You do **not** need to subscribe to the
* response, as the service already does that. The input object must have an
* 'event' property set, everything else is optional.
*
* Example:
* ```
* this.logService.log({
* event: 'submission',
* dateObj: new Date()
* });
* ```
* @protected
* @param {?} message A JavaScript object, nesting is fine, with `event` property
* set.
* @return {?}
*/
_log(message) {
this.setSeverity(SeverityLevels.INFO);
return this._sendLog(message);
}
/**
* @protected
* @param {?} errorMessage
* @return {?}
*/
_logError(errorMessage) {
this.setSeverity(SeverityLevels.ERROR);
return this._sendLog(errorMessage);
}
/**
* Log HTTP errors, e.g. when losing network connectivity or receiving an
* error response code.
* @param {?} error
* @return {?}
*/
logHttpError(error) {
return this._logError({
event: CommonLogEvents.error,
message: error.message,
errorName: error.name,
statusText: error.statusText
});
}
/**
* Internal method to send logs to Splunk, includes meta-data except that's
* consistent across all requests, but not specific values like severity
* level.
*
* @private
* @param {?} message A JavaScript object or anything that can be toString()'d,
* like Date
* @return {?}
*/
_sendLog(message) {
// Update headers
this.setTimestamp();
this.setTags(message.event);
if (this.url === null) {
/** @type {?} */
const msg = 'Unable to send logs as URL as not been set via setURL()';
console.error(msg);
return throwError(msg);
}
// Configure request
/** @type {?} */
const body = { message: message };
// We call .subscribe() here because we don't care about the response and
// we want to ensure that we never forget to call subscribe.
return this.post(this.url, body).subscribe();
}
/**
* @protected
* @param {?} error
* @return {?}
*/
handleError(error) {
if (error.error instanceof ErrorEvent) {
// Client-side / network error occured
console.error('An error occured: ', error.error.message);
}
else {
// The backend returned an unsuccessful response code
console.error(`Backend returned error code: ${error.status}. Error body: ${error.error}`);
}
return throwError(error);
}
/**
* Overwrite the inherited httpOptions so we can set responseType to text.
* This updates Angular's parsing, and it won't error out due to the server
* not responding with JSON.
* @protected
* @return {?}
*/
get httpOptions() {
return {
headers: this._headers,
responseType: 'text'
};
}
// TODO: Remove moment dependency
/**
* @private
* @return {?}
*/
setTimestamp() {
this._headers = this._headers.set('timestamp', moment().toISOString());
}
/**
* @private
* @param {?} severity
* @return {?}
*/
setSeverity(severity) {
this._headers = this._headers.set('severity', severity);
}
/**
* The headers are easier to search in splunk, and we aren't using tags, so
* repurpose it to event type.
* @private
* @param {?} message
* @return {?}
*/
setTags(message) {
this._headers = this._headers.set('tags', message);
}
}
CommonLogger.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
CommonLogger.ctorParameters = () => [
{ type: HttpClient }
];
/** @nocollapse */ CommonLogger.ngInjectableDef = i0.defineInjectable({ factory: function CommonLogger_Factory() { return new CommonLogger(i0.inject(i1.HttpClient)); }, token: CommonLogger, providedIn: "root" });
if (false) {
/**
* The HTTP Headers which go with each request. These MUST be set if you are
* using the logger. Fields include:
*
* - program (REQUIRED, the application wide code)
* - applicationId (REQUIRED, like sessionId)
* - request_method (REQUIRED, 'POST')
* - logsource: (REQUIRED, window.location.hostname)
* - http_x_forwarded_host (REQUIRED, window.location.hostname)
*
* @type {?}
* @protected
*/
CommonLogger.prototype._headers;
/**
* @type {?}
* @private
*/
CommonLogger.prototype.url;
/**
* @type {?}
* @protected
*/
CommonLogger.prototype.http;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9tb2gtY29tbW9uLWxpYi8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlcy9sb2dnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFxQixXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxPQUFPLE1BQU0sUUFBUSxDQUFDOzs7O01BQzVCLE1BQU0sR0FBRyxPQUFPOzs7SUFHcEIsTUFBTyxNQUFNO0lBQ2IsT0FBUSxPQUFPOzs7O0lBSWYsWUFBYSxZQUFZO0lBQ3pCLE9BQVEsT0FBTztJQUNmLFlBQWEsWUFBWTs7Ozs7O0FBRzNCLHNDQUtDOzs7Ozs7SUFIQyxpQ0FBYzs7O0FBUWhCLE1BQU0sT0FBTyxZQUFhLFNBQVEsbUJBQW1COzs7O0lBb0JuRCxZQUFzQixJQUFnQjtRQUNwQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFEUSxTQUFJLEdBQUosSUFBSSxDQUFZOzs7Ozs7Ozs7Ozs7UUFSNUIsYUFBUSxHQUFnQixJQUFJLFdBQVcsQ0FBQztZQUNoRCxjQUFjLEVBQUUsTUFBTTtZQUN0QixTQUFTLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRO1lBQ25DLHFCQUFxQixFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUTtTQUNoRCxDQUFDLENBQUM7UUFFSyxRQUFHLEdBQVcsSUFBSSxDQUFDO0lBSTNCLENBQUM7Ozs7O0lBRUQsSUFBSSxhQUFhLENBQUUsRUFBVTtRQUMzQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFF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SUFDM0IsQ0FBQzs7Ozs7Ozs7SUFPRCxJQUFjLFdBQVc7UUFDdkIsT0FBTztZQUNMLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN0QixZQUFZLEVBQUUsTUFBTTtTQUNyQixDQUFDO0lBQ0osQ0FBQzs7Ozs7O0lBR08sWUFBWTtRQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Ozs7OztJQUVPLFdBQVcsQ0FBQyxRQUF3QjtRQUMxQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxRCxDQUFDOzs7Ozs7OztJQU1PLE9BQU8sQ0FBQyxPQUFlO1FBQzdCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3JELENBQUM7OztZQWhLRixVQUFVLFNBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkI7Ozs7WUExQlEsVUFBVTs7Ozs7Ozs7Ozs7Ozs7Ozs7SUF1Q2pCLGdDQUlHOzs7OztJQUVILDJCQUEyQjs7Ozs7SUFFZiw0QkFBMEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEh0dHBDbGllbnQsIEh0dHBFcnJvclJlc3BvbnNlLCBIdHRwSGVhZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgQWJzdHJhY3RIdHRwU2VydmljZSB9IGZyb20gJy4vYWJzdHJhY3QtYXBpLXNlcnZpY2UnO1xyXG5pbXBvcnQgeyB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCAqIGFzIG1vbWVudF8gZnJvbSAnbW9tZW50JztcclxuY29uc3QgbW9tZW50ID0gbW9tZW50XztcclxuXHJcbmVudW0gU2V2ZXJpdHlMZXZlbHMge1xyXG4gIElORk8gPSAnaW5mbycsXHJcbiAgRVJST1IgPSAnZXJyb3InLFxyXG59XHJcblxyXG5leHBvcnQgZW51bSBDb21tb25Mb2dFdmVudHMge1xyXG4gIG5hdmlnYXRpb24gPSAnbmF2aWdhdGlvbicsXHJcbiAgZXJyb3IgPSAnZXJyb3InLFxyXG4gIHN1Ym1pc3Npb24gPSAnc3VibWlzc2lvbidcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb21tb25Mb2dNZXNzYWdlIHtcclxuICAvKiogVGhlIHR5cGUgb2YgZXZlbnQgYmVpbmcgbG9nZ2VkLiAqL1xyXG4gIGV2ZW50OiBzdHJpbmc7IC8vIFNob3VsZCBiZSBzdWJjbGFzc2VzIGludG8gbXVsdGlwbGUgc3RyaW5nIGxpdGVyYWxzXHJcbiAgLy8gV2UgYWxsb3cgYW55IG90aGVyIHByb3BlcnRpZXMvdmFsdWVzIGluIHRoZSBpbnRlcmZhY2VcclxuICBba2V5OiBzdHJpbmddOiBhbnk7XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIENvbW1vbkxvZ2dlciBleHRlbmRzIEFic3RyYWN0SHR0cFNlcnZpY2Uge1xyXG4gIC8qKlxyXG4gICAqIFRoZSBIVFRQIEhlYWRlcnMgd2hpY2ggZ28gd2l0aCBlYWNoIHJlcXVlc3QuICBUaGVzZSBNVVNUIGJlIHNldCBpZiB5b3UgYXJlXHJcbiAgICogdXNpbmcgdGhlIGxvZ2dlci4gIEZpZWxkcyBpbmNsdWRlOlxyXG4gICAqXHJcbiAgICogLSBwcm9ncmFtIChSRVFVSVJFRCwgdGhlIGFwcGxpY2F0aW9uIHdpZGUgY29kZSlcclxuICAgKiAtIGFwcGxpY2F0aW9uSWQgKFJFUVVJUkVELCBsaWtlIHNlc3Npb25JZClcclxuICAgKiAtIHJlcXVlc3RfbWV0aG9kIChSRVFVSVJFRCwgJ1BPU1QnKVxyXG4gICAqIC0gbG9nc291cmNlOiAoUkVRVUlSRUQsIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSlcclxuICAgKiAtIGh0dHBfeF9mb3J3YXJkZWRfaG9zdCAoUkVRVUlSRUQsIHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZSlcclxuICAgKlxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBfaGVhZGVyczogSHR0cEhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoe1xyXG4gICAgcmVxdWVzdF9tZXRob2Q6ICdQT1NUJyxcclxuICAgIGxvZ3NvdXJjZTogd2luZG93LmxvY2F0aW9uLmhvc3RuYW1lLFxyXG4gICAgaHR0cF94X2ZvcndhcmRlZF9ob3N0OiB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWVcclxuICB9KTtcclxuXHJcbiAgcHJpdmF0ZSB1cmw6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBodHRwOiBIdHRwQ2xpZW50KSB7XHJcbiAgICBzdXBlcihodHRwKTtcclxuICB9XHJcblxyXG4gIHNldCBhcHBsaWNhdGlvbklkKCBpZDogc3RyaW5nICkge1xyXG4gICAgdGhpcy5faGVhZGVycyA9IHRoaXMuX2hlYWRlcnMuc2V0KCAnYXBwbGljYXRpb25JZCcsIGlkICk7XHJcbiAgfVxyXG5cclxuICBnZXQgYXBwbGljYXRpb25JZCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9oZWFkZXJzLmdldCggJ2FwcGxpY2F0aW9uSWQnICk7XHJcbiAgfVxyXG5cclxuICBzZXQgcHJvZ3JhbU5hbWUoIG5hbWU6IHN0cmluZyApIHtcclxuICAgIHRoaXMuX2hlYWRlcnMgPSB0aGlzLl9oZWFkZXJzLnNldCggJ3Byb2dyYW0nLCBuYW1lICk7XHJcbiAgfVxyXG5cclxuICBnZXQgcHJvZ3JhbU5hbWUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5faGVhZGVycy5nZXQoICduYW1lJyApO1xyXG4gIH1cclxuXHJcbiAgc2V0VVJMKG5ld1VSTDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLnVybCA9IG5ld1VSTDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBsb2coIG1lc3NhZ2U6IGFueSApIHtcclxuICAgIHRoaXMuX2xvZyggbWVzc2FnZSBhcyBDb21tb25Mb2dNZXNzYWdlICk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbG9nRXJyb3IoIGVycm9yTWVzc2FnZTogYW55ICkge1xyXG4gICAgdGhpcy5fbG9nRXJyb3IoIGVycm9yTWVzc2FnZSBhcyBDb21tb25Mb2dNZXNzYWdlICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2cgYSBtZXNzYWdlIHRvIFNwbHVuay4gVGhpcyBpcyB0aGUgbWFpbiB3YXkgdG8gc2VuZCBsb2dzIGFuZFxyXG4gICAqIGF1dG9tYXRpY2FsbHkgaW5jbHVkZXMgbWV0YS1kYXRhLiBZb3UgZG8gKipub3QqKiBuZWVkIHRvIHN1YnNjcmliZSB0byB0aGVcclxuICAgKiByZXNwb25zZSwgYXMgdGhlIHNlcnZpY2UgYWxyZWFkeSBkb2VzIHRoYXQuIFRoZSBpbnB1dCBvYmplY3QgbXVzdCBoYXZlIGFuXHJcbiAgICogJ2V2ZW50JyBwcm9wZXJ0eSBzZXQsIGV2ZXJ5dGhpbmcgZWxzZSBpcyBvcHRpb25hbC5cclxuICAgKlxyXG4gICAqIEV4YW1wbGU6XHJcbiAgICogYGBgXHJcbiAgICB0aGlzLmxvZ1NlcnZpY2UubG9nKHtcclxuICAgICAgIGV2ZW50OiAnc3VibWlzc2lvbicsXHJcbiAgICAgICBkYXRlT2JqOiBuZXcgRGF0ZSgpXHJcbiAgICB9KTtcclxuICAgIGBgYFxyXG4gICAqIEBwYXJhbSBtZXNzYWdlIEEgSmF2YVNjcmlwdCBvYmplY3QsIG5lc3RpbmcgaXMgZmluZSwgd2l0aCBgZXZlbnRgIHByb3BlcnR5XHJcbiAgICogc2V0LlxyXG4gICAqL1xyXG4gIHByb3RlY3RlZCBfbG9nKG1lc3NhZ2U6IENvbW1vbkxvZ01lc3NhZ2UpIHtcclxuICAgIHRoaXMuc2V0U2V2ZXJpdHkoU2V2ZXJpdHlMZXZlbHMuSU5GTyk7XHJcbiAgICByZXR1cm4gdGhpcy5fc2VuZExvZyhtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBfbG9nRXJyb3IoZXJyb3JNZXNzYWdlOiBDb21tb25Mb2dNZXNzYWdlKSB7XHJcbiAgICB0aGlzLnNldFNldmVyaXR5KFNldmVyaXR5TGV2ZWxzLkVSUk9SKTtcclxuICAgIHJldHVybiB0aGlzLl9zZW5kTG9nKGVycm9yTWVzc2FnZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2cgSFRUUCBlcnJvcnMsIGUuZy4gd2hlbiBsb3NpbmcgbmV0d29yayBjb25uZWN0aXZpdHkgb3IgcmVjZWl2aW5nIGFuXHJcbiAgICogZXJyb3IgcmVzcG9uc2UgY29kZS5cclxuICAgKi9cclxuICBwdWJsaWMgbG9nSHR0cEVycm9yKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2xvZ0Vycm9yKHtcclxuICAgICAgZXZlbnQ6IENvbW1vbkxvZ0V2ZW50cy5lcnJvcixcclxuICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZSxcclxuICAgICAgZXJyb3JOYW1lOiBlcnJvci5uYW1lLFxyXG4gICAgICBzdGF0dXNUZXh0OiBlcnJvci5zdGF0dXNUZXh0XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEludGVybmFsIG1ldGhvZCB0byBzZW5kIGxvZ3MgdG8gU3BsdW5rLCBpbmNsdWRlcyBtZXRhLWRhdGEgZXhjZXB0IHRoYXQnc1xyXG4gICAqIGNvbnNpc3RlbnQgYWNyb3NzIGFsbCByZXF1ZXN0cywgYnV0IG5vdCBzcGVjaWZpYyB2YWx1ZXMgbGlrZSBzZXZlcml0eVxyXG4gICAqIGxldmVsLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIG1lc3NhZ2UgQSBKYXZhU2NyaXB0IG9iamVjdCBvciBhbnl0aGluZyB0aGF0IGNhbiBiZSB0b1N0cmluZygpJ2QsXHJcbiAgICogbGlrZSBEYXRlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBfc2VuZExvZyhtZXNzYWdlOiBDb21tb25Mb2dNZXNzYWdlKSB7XHJcbiAgICAvLyBVcGRhdGUgaGVhZGVyc1xyXG4gICAgdGhpcy5zZXRUaW1lc3RhbXAoKTtcclxuICAgIHRoaXMuc2V0VGFncyhtZXNzYWdlLmV2ZW50KTtcclxuXHJcbiAgICBpZiAodGhpcy51cmwgPT09IG51bGwpIHtcclxuICAgICAgICBjb25zdCBtc2cgPSAnVW5hYmxlIHRvIHNlbmQgbG9ncyBhcyBVUkwgYXMgbm90IGJlZW4gc2V0IHZpYSBzZXRVUkwoKSc7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihtc2cpO1xyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG1zZyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29uZmlndXJlIHJlcXVlc3RcclxuICAgIGNvbnN0IGJvZHkgPSB7IG1lc3NhZ2U6IG1lc3NhZ2UgfTtcclxuXHJcbiAgICAvLyBXZSBjYWxsIC5zdWJzY3JpYmUoKSBoZXJlIGJlY2F1c2Ugd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGUgcmVzcG9uc2UgYW5kXHJcbiAgICAvLyB3ZSB3YW50IHRvIGVuc3VyZSB0aGF0IHdlIG5ldmVyIGZvcmdldCB0byBjYWxsIHN1YnNjcmliZS5cclxuICAgIHJldHVybiB0aGlzLnBvc3QodGhpcy51cmwsIGJvZHkpLnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGhhbmRsZUVycm9yKGVycm9yOiBIdHRwRXJyb3JSZXNwb25zZSkge1xyXG4gICAgaWYgKGVycm9yLmVycm9yIGluc3RhbmNlb2YgRXJyb3JFdmVudCkge1xyXG4gICAgICAvLyBDbGllbnQtc2lkZSAvIG5ldHdvcmsgZXJyb3Igb2NjdXJlZFxyXG4gICAgICBjb25zb2xlLmVycm9yKCdBbiBlcnJvciBvY2N1cmVkOiAnLCBlcnJvci5lcnJvci5tZXNzYWdlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybmVkIGFuIHVuc3VjY2Vzc2Z1bCByZXNwb25zZSBjb2RlXHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoYEJhY2tlbmQgcmV0dXJuZWQgZXJyb3IgY29kZTogJHtlcnJvci5zdGF0dXN9LiAgRXJyb3IgYm9keTogJHtlcnJvci5lcnJvcn1gKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJvcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPdmVyd3JpdGUgdGhlIGluaGVyaXRlZCBodHRwT3B0aW9ucyBzbyB3ZSBjYW4gc2V0IHJlc3BvbnNlVHlwZSB0byB0ZXh0LlxyXG4gICAqIFRoaXMgdXBkYXRlcyBBbmd1bGFyJ3MgcGFyc2luZywgYW5kIGl0IHdvbid0IGVycm9yIG91dCBkdWUgdG8gdGhlIHNlcnZlclxyXG4gICAqIG5vdCByZXNwb25kaW5nIHdpdGggSlNPTi5cclxuICAgKi9cclxuICBwcm90ZWN0ZWQgZ2V0IGh0dHBPcHRpb25zKCk6IGFueSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBoZWFkZXJzOiB0aGlzLl9oZWFkZXJzLFxyXG4gICAgICByZXNwb25zZVR5cGU6ICd0ZXh0J1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIFRPRE86IFJlbW92ZSBtb21lbnQgZGVwZW5kZW5jeVxyXG4gIHByaXZhdGUgc2V0VGltZXN0YW1wKCkge1xyXG4gICAgdGhpcy5faGVhZGVycyA9IHRoaXMuX2hlYWRlcnMuc2V0KCd0aW1lc3RhbXAnLCBtb21lbnQoKS50b0lTT1N0cmluZygpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2V0U2V2ZXJpdHkoc2V2ZXJpdHk6IFNldmVyaXR5TGV2ZWxzKSB7XHJcbiAgICB0aGlzLl9oZWFkZXJzID0gdGhpcy5faGVhZGVycy5zZXQoJ3NldmVyaXR5Jywgc2V2ZXJpdHkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGhlYWRlcnMgYXJlIGVhc2llciB0byBzZWFyY2ggaW4gc3BsdW5rLCBhbmQgd2UgYXJlbid0IHVzaW5nIHRhZ3MsIHNvXHJcbiAgICogcmVwdXJwb3NlIGl0IHRvIGV2ZW50IHR5cGUuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXRUYWdzKG1lc3NhZ2U6IHN0cmluZyApIHtcclxuICAgIHRoaXMuX2hlYWRlcnMgPSB0aGlzLl9oZWFkZXJzLnNldCgndGFncycsIG1lc3NhZ2UpO1xyXG4gIH1cclxuXHJcbn1cclxuIl19