UNPKG

@hpe/angular-toolkit

Version:

Hewlett-Packard Enterprise : Angular toolkit for rapid project development

922 lines (910 loc) 80.1 kB
import { EventEmitter, Injectable, NgModule } from '@angular/core'; import { AppEvent } from '@hpe/angular-toolkit/model'; import { __extends } from 'tslib'; import { HttpClient } from '@angular/common/http'; import { DomSanitizer } from '@angular/platform-browser'; import { throwError } from 'rxjs'; import { catchError, map, finalize } from 'rxjs/operators'; import { MessageService } from 'primeng/components/common/messageservice'; import { CommonModule } from '@angular/common'; import { MessageService as MessageService$1 } from 'primeng/api'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ //============================================================================= //=== //=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP. //=== //=== Use of this source code is governed by an MIT-style license that can be //=== found in the LICENSE file //============================================================================= var AbstractSubscriber = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function AbstractSubscriber(eventBusService) { this.eventBusService = eventBusService; this.subscriptions = []; } /** * @return {?} */ AbstractSubscriber.prototype.ngOnDestroy = /** * @return {?} */ function () { this.subscriptions.forEach(function (s) { return s.unsubscribe(); }); }; //------------------------------------------------------------------------- //--- //--- API methods //--- //------------------------------------------------------------------------- /** * @param {?} eventCode * @param {?} handler * @return {?} */ AbstractSubscriber.prototype.subscribeToApp = /** * @param {?} eventCode * @param {?} handler * @return {?} */ function (eventCode, handler) { var /** @type {?} */ s = this.eventBusService.subscribeToApp(eventCode, handler); this.subscriptions.push(s); return s; }; //------------------------------------------------------------------------- /** * @param {?} event * @return {?} */ AbstractSubscriber.prototype.emitToApp = /** * @param {?} event * @return {?} */ function (event) { this.eventBusService.emitToApp(event); }; //------------------------------------------------------------------------- /** * @param {?} handler * @return {?} */ AbstractSubscriber.prototype.subscribeToError = /** * @param {?} handler * @return {?} */ function (handler) { var /** @type {?} */ s = this.eventBusService.subscribeToError(handler); this.subscriptions.push(s); return s; }; //------------------------------------------------------------------------- /** * @param {?} event * @return {?} */ AbstractSubscriber.prototype.emitToError = /** * @param {?} event * @return {?} */ function (event) { this.eventBusService.emitToError(event); }; return AbstractSubscriber; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var EventBusService = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function EventBusService() { this.eventEmitterMap = new Map(); this.errorEvents = new EventEmitter(); } /** * @param {?} eventCode * @param {?} handler * @return {?} */ EventBusService.prototype.subscribeToApp = /** * @param {?} eventCode * @param {?} handler * @return {?} */ function (eventCode, handler) { var /** @type {?} */ emitter = this.eventEmitterMap.get(eventCode); if (emitter == null) { emitter = new EventEmitter(); this.eventEmitterMap.set(eventCode, emitter); } return emitter.subscribe(handler, null, null); }; /** * @param {?} event * @return {?} */ EventBusService.prototype.emitToApp = /** * @param {?} event * @return {?} */ function (event) { var /** @type {?} */ emitter = this.eventEmitterMap.get(event.code); if (emitter != null) { console.log("Emitting event : " + JSON.stringify(event)); emitter.emit(event); } else { console.log("WARNING : Emitting an event without any handler : " + JSON.stringify(event)); } //--- Emitting to global handlers emitter = this.eventEmitterMap.get(AppEvent.ANY); if (emitter != null) { emitter.emit(event); } }; /** * @param {?} handler * @return {?} */ EventBusService.prototype.subscribeToError = /** * @param {?} handler * @return {?} */ function (handler) { return this.errorEvents.subscribe(handler, null, null); }; /** * @param {?} event * @return {?} */ EventBusService.prototype.emitToError = /** * @param {?} event * @return {?} */ function (event) { console.log("Emitting error event : " + JSON.stringify(event)); this.errorEvents.emit(event); }; EventBusService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ EventBusService.ctorParameters = function () { return []; }; return EventBusService; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** @enum {number} */ var Status = { LOGIN: 0, LOADING: 1, READY: 2, }; Status[Status.LOGIN] = "LOGIN"; Status[Status.LOADING] = "LOADING"; Status[Status.READY] = "READY"; var ApplicationService = /** @class */ (function (_super) { __extends(ApplicationService, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function ApplicationService(eventBusService) { var _this = _super.call(this, eventBusService) || this; _this.status = Status.LOGIN; _super.prototype.subscribeToApp.call(_this, AppEvent.LOGIN_SUCCESS, function (event) { return _this.onLoginSuccess(event); }); _super.prototype.subscribeToApp.call(_this, AppEvent.LOGIN_FAILED, function (event) { return _this.onLoginFailed(event); }); _super.prototype.subscribeToApp.call(_this, AppEvent.LOGOUT_SUCCESS, function (event) { return _this.onLogoutSuccess(event); }); _super.prototype.subscribeToApp.call(_this, AppEvent.LOGOUT_FAILED, function (event) { return _this.onLogoutFailed(event); }); _super.prototype.subscribeToApp.call(_this, AppEvent.INVALID_TOKEN, function (event) { return _this.onInvalidToken(event); }); _super.prototype.subscribeToApp.call(_this, AppEvent.APPLICATION_READY, function (event) { return _this.onApplicationReady(event); }); return _this; } /** * @return {?} */ ApplicationService.prototype.isStatusLogin = /** * @return {?} */ function () { return this.status == Status.LOGIN; }; /** * @return {?} */ ApplicationService.prototype.isStatusLoading = /** * @return {?} */ function () { return this.status == Status.LOADING; }; /** * @return {?} */ ApplicationService.prototype.isStatusReady = /** * @return {?} */ function () { return this.status == Status.READY; }; /** * @param {?} event * @return {?} */ ApplicationService.prototype.onLoginSuccess = /** * @param {?} event * @return {?} */ function (event) { this.status = Status.LOADING; }; /** * @param {?} event * @return {?} */ ApplicationService.prototype.onLoginFailed = /** * @param {?} event * @return {?} */ function (event) { this.status = Status.LOGIN; }; /** * @param {?} event * @return {?} */ ApplicationService.prototype.onLogoutSuccess = /** * @param {?} event * @return {?} */ function (event) { this.status = Status.LOGIN; }; /** * @param {?} event * @return {?} */ ApplicationService.prototype.onLogoutFailed = /** * @param {?} event * @return {?} */ function (event) { this.status = Status.LOGIN; }; /** * @param {?} event * @return {?} */ ApplicationService.prototype.onInvalidToken = /** * @param {?} event * @return {?} */ function (event) { this.status = Status.LOGIN; }; /** * @param {?} event * @return {?} */ ApplicationService.prototype.onApplicationReady = /** * @param {?} event * @return {?} */ function (event) { this.status = Status.READY; }; ApplicationService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ApplicationService.ctorParameters = function () { return [ { type: EventBusService, }, ]; }; return ApplicationService; }(AbstractSubscriber)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var HttpService = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function HttpService(httpClient, eventBusService, domSanitizer) { this.httpClient = httpClient; this.eventBusService = eventBusService; this.domSanitizer = domSanitizer; this.openRequests = 0; } Object.defineProperty(HttpService.prototype, "loading", { get: /** * @return {?} */ function () { return (this.openRequests > 0); }, enumerable: true, configurable: true }); /** * @param {?} url * @param {?=} options * @return {?} */ HttpService.prototype.getObject = /** * @param {?} url * @param {?=} options * @return {?} */ function (url, options) { var _this = this; this.showLoader(); //--- "Pragma": "no-cache" for IE 11 var /** @type {?} */ header = { "Pragma": "no-cache", "Cache-Control": "no-cache", "Expires": "0" }; return this.httpClient.get(url, { params: options, headers: header }).pipe(catchError(function (error) { return _this.handleError(error); }), finalize(function () { return _this.hideLoader(); })); }; /** * @param {?} url * @param {?=} options * @return {?} */ HttpService.prototype.getBlob = /** * @param {?} url * @param {?=} options * @return {?} */ function (url, options) { var _this = this; this.showLoader(); //--- Add timestamp to change static url to dynamic for IE 11 if (options != null) { options.ts = Date.now(); } return this.httpClient.get(url, { params: options, responseType: 'blob' }).pipe(map(function (e) { return _this.getSanitizedUrl(URL.createObjectURL(e)); }), catchError(function (error) { return _this.handleError(error); }), finalize(function () { return _this.hideLoader(); })); }; /** * @param {?} url * @param {?} object * @param {?=} options * @return {?} */ HttpService.prototype.postObject = /** * @param {?} url * @param {?} object * @param {?=} options * @return {?} */ function (url, object, options) { var _this = this; this.showLoader(); return this.httpClient.post(url, object, options).pipe(catchError(function (error) { return _this.handleError(error); }), finalize(function () { return _this.hideLoader(); })); }; /** * @param {?} url * @return {?} */ HttpService.prototype.getSanitizedUrl = /** * @param {?} url * @return {?} */ function (url) { return this.domSanitizer.bypassSecurityTrustResourceUrl(url); }; /** * @param {?} response * @return {?} */ HttpService.prototype.handleError = /** * @param {?} response * @return {?} */ function (response) { console.log("Got the following HTTP error : " + JSON.stringify(response)); var /** @type {?} */ error; if (response.status == 422) { //--- Unprocessable entity error = response.error; } else { error = { code: response.status.toString(), error: response.error.toString() }; } this.eventBusService.emitToError(error); return throwError(error); }; /** * @return {?} */ HttpService.prototype.showLoader = /** * @return {?} */ function () { if (++this.openRequests == 1) { this.eventBusService.emitToApp(new AppEvent(AppEvent.SUBMIT_START)); } }; /** * @return {?} */ HttpService.prototype.hideLoader = /** * @return {?} */ function () { if (--this.openRequests == 0) { this.eventBusService.emitToApp(new AppEvent(AppEvent.SUBMIT_END)); } }; HttpService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ HttpService.ctorParameters = function () { return [ { type: HttpClient, }, { type: EventBusService, }, { type: DomSanitizer, }, ]; }; return HttpService; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var LabelService = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function LabelService(httpService) { var _this = this; this.httpService = httpService; this.languages = ["en", "it"]; this.labelSet = new Map(); this.language = "en"; //--- Load language files this.languages.forEach(function (language) { _this.initLanguage(language); }); } /** * @param {?} language * @return {?} */ LabelService.prototype.setLanguage = /** * @param {?} language * @return {?} */ function (language) { this.language = language; }; /** * @param {?} entity * @param {?} code * @return {?} */ LabelService.prototype.getLabel = /** * @param {?} entity * @param {?} code * @return {?} */ function (entity, code) { if (code == null) { return null; } var /** @type {?} */ entitySet = this.getMapping(entity); if (entitySet == null) { return "?" + entity + "?"; } var /** @type {?} */ label = entitySet[code]; if (label == null) { return entity + ".?" + code + "?"; } return label; }; /** * @param {?} entity * @return {?} */ LabelService.prototype.getMapping = /** * @param {?} entity * @return {?} */ function (entity) { var /** @type {?} */ labels = this.labelSet.get(this.language); if (labels != null) { return labels.get(entity); } //--- Probably, we are still loading data return null; }; /** * @param {?} language * @return {?} */ LabelService.prototype.initLanguage = /** * @param {?} language * @return {?} */ function (language) { this.loadLanguageFile(language, LabelService.TOOLKIT_FILE); this.loadLanguageFile(language, LabelService.APPLICATION_FILE); }; /** * @param {?} language * @param {?} name * @return {?} */ LabelService.prototype.loadLanguageFile = /** * @param {?} language * @param {?} name * @return {?} */ function (language, name) { var _this = this; var /** @type {?} */ file = name + "-" + language + ".json"; this.httpService.getObject("asset/lang/" + file) .subscribe(function (result) { return _this.processFile(language, file, result); }, function (error) { return console.log("Cannot load labels file : " + file); }); }; /** * @param {?} language * @param {?} file * @param {?} data * @return {?} */ LabelService.prototype.processFile = /** * @param {?} language * @param {?} file * @param {?} data * @return {?} */ function (language, file, data) { console.log("Loaded labels file : " + file); var /** @type {?} */ labels = this.labelSet.get(language); if (labels == null) { labels = new Map(); this.labelSet.set(language, labels); } for (var /** @type {?} */ key in data) { labels.set(key, data[key]); } }; LabelService.TOOLKIT_FILE = "toolkit"; LabelService.APPLICATION_FILE = "application"; LabelService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ LabelService.ctorParameters = function () { return [ { type: HttpService, }, ]; }; return LabelService; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var NotificationService = /** @class */ (function () { //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function NotificationService(messageService) { this.messageService = messageService; } /** * @param {?} title * @param {?} message * @return {?} */ NotificationService.prototype.showSuccess = /** * @param {?} title * @param {?} message * @return {?} */ function (title, message) { this.show('success', title, message); }; /** * @param {?} title * @param {?} message * @return {?} */ NotificationService.prototype.showInfo = /** * @param {?} title * @param {?} message * @return {?} */ function (title, message) { this.show('info', title, message); }; /** * @param {?} title * @param {?} message * @return {?} */ NotificationService.prototype.showWarn = /** * @param {?} title * @param {?} message * @return {?} */ function (title, message) { this.show('warn', title, message); }; /** * @param {?} title * @param {?} message * @return {?} */ NotificationService.prototype.showError = /** * @param {?} title * @param {?} message * @return {?} */ function (title, message) { this.show('error', title, message); }; /** * @param {?} severity * @param {?} title * @param {?} message * @return {?} */ NotificationService.prototype.show = /** * @param {?} severity * @param {?} title * @param {?} message * @return {?} */ function (severity, title, message) { this.messageService.add({ severity: severity, summary: title, detail: message }); }; NotificationService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ NotificationService.ctorParameters = function () { return [ { type: MessageService, }, ]; }; return NotificationService; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var SessionService = /** @class */ (function (_super) { __extends(SessionService, _super); //------------------------------------------------------------------------- //--- //--- Constructor //--- //------------------------------------------------------------------------- function SessionService(eventBusService, httpService) { var _this = _super.call(this, eventBusService) || this; _this.httpService = httpService; _this.clearSession(); _super.prototype.subscribeToApp.call(_this, AppEvent.INVALID_TOKEN, function (event) { return _this.onInvalidToken(event); }); return _this; } /** * @param {?} cred * @return {?} */ SessionService.prototype.login = /** * @param {?} cred * @return {?} */ function (cred) { var _this = this; console.log("SessionService.login : Logging in user='" + cred.username + "'"); //--- Loads user profile from server this.httpService.postObject("/api/session/login", cred) .subscribe(function (result) { return _this.loginSuccess(result); }, function (error) { return _this.loginError(error); }); }; /** * @return {?} */ SessionService.prototype.logout = /** * @return {?} */ function () { var _this = this; console.log("SessionService.logout : Logging out user='" + (this.user || "???") + "'"); this.httpService.postObject("/api/session/logout", { token: this.token }) .subscribe(function (result) { return _this.logoutSuccess(); }, function (error) { return _this.logoutError(error); }); }; /** * @return {?} */ SessionService.prototype.clearSession = /** * @return {?} */ function () { console.log("SessionService.clearSession: Resetting session..."); this.session = null; this.token = null; this.user = null; this.profile = null; this.permissions = new Map(); }; Object.defineProperty(SessionService.prototype, "homePage", { get: /** * @return {?} */ function () { return (this.profile) ? this.profile.homePage : null; }, enumerable: true, configurable: true }); /** * @param {?} name * @return {?} */ SessionService.prototype.hasPermission = /** * @param {?} name * @return {?} */ function (name) { return (this.permissions.get(name)); }; /** * @param {?} session * @return {?} */ SessionService.prototype.loginSuccess = /** * @param {?} session * @return {?} */ function (session) { this.session = session; this.token = session.token; this.user = session.user; this.profile = session.profile; this.permissions = this.setupPermissionMap(this.profile.permissions); _super.prototype.emitToApp.call(this, new AppEvent(AppEvent.LOGIN_SUCCESS, session)); console.log("Login successful for user=" + this.user.username); }; /** * @param {?} response * @return {?} */ SessionService.prototype.loginError = /** * @param {?} response * @return {?} */ function (response) { _super.prototype.emitToApp.call(this, new AppEvent(AppEvent.LOGIN_FAILED, response)); }; /** * @return {?} */ SessionService.prototype.logoutSuccess = /** * @return {?} */ function () { var /** @type {?} */ username = this.user.username; this.clearSession(); _super.prototype.emitToApp.call(this, new AppEvent(AppEvent.LOGOUT_SUCCESS, username)); console.log("Logout successful for user=" + username); }; /** * @param {?} response * @return {?} */ SessionService.prototype.logoutError = /** * @param {?} response * @return {?} */ function (response) { this.clearSession(); _super.prototype.emitToApp.call(this, new AppEvent(AppEvent.LOGOUT_FAILED)); }; /** * @param {?} permissions * @return {?} */ SessionService.prototype.setupPermissionMap = /** * @param {?} permissions * @return {?} */ function (permissions) { var /** @type {?} */ map$$1 = new Map(); permissions.forEach(function (p) { return map$$1.set(p, true); }); return map$$1; }; /** * @param {?} event * @return {?} */ SessionService.prototype.onInvalidToken = /** * @param {?} event * @return {?} */ function (event) { this.clearSession(); }; SessionService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ SessionService.ctorParameters = function () { return [ { type: EventBusService, }, { type: HttpService, }, ]; }; return SessionService; }(AbstractSubscriber)); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ var HpeServiceModule = /** @class */ (function () { function HpeServiceModule() { } HpeServiceModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule ], declarations: [], exports: [], providers: [ ApplicationService, EventBusService, HttpService, LabelService, NotificationService, SessionService, MessageService$1 ], },] }, ]; return HpeServiceModule; }()); //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ export { HpeServiceModule, AbstractSubscriber, ApplicationService, EventBusService, HttpService, LabelService, NotificationService, SessionService }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHBlLWFuZ3VsYXItdG9vbGtpdC1zZXJ2aWNlLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL2Fic3RyYWN0LXN1YnNjcmliZXIudHMiLCJuZzovL0BocGUvYW5ndWxhci10b29sa2l0L3NlcnZpY2UvZXZlbnRidXMtc2VydmljZS50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZS9hcHBsaWNhdGlvbi1zZXJ2aWNlLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL2h0dHAtc2VydmljZS50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZS9sYWJlbC1zZXJ2aWNlLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL25vdGlmaWNhdGlvbi1zZXJ2aWNlLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL3Nlc3Npb24tc2VydmljZS50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZS9tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbXBvcnQge09uRGVzdHJveX0gICAgZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge0V2ZW50SGFuZGxlciwgRXJyb3JIYW5kbGVyLCBBcHBFdmVudCwgRXJyb3JFdmVudH0gZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbmltcG9ydCB7RXZlbnRCdXNTZXJ2aWNlfSBmcm9tIFwiLi9ldmVudGJ1cy1zZXJ2aWNlXCI7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGNsYXNzIEFic3RyYWN0U3Vic2NyaWJlciBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIENvbnN0cnVjdG9yXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgZXZlbnRCdXNTZXJ2aWNlIDogRXZlbnRCdXNTZXJ2aWNlKSB7fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBMaWZlY3ljbGUgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG5cdFx0dGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goIChzIDogU3Vic2NyaXB0aW9uKSA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEFQSSBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByb3RlY3RlZCBzdWJzY3JpYmVUb0FwcChldmVudENvZGUgOiBzdHJpbmcsIGhhbmRsZXIgOiBFdmVudEhhbmRsZXIpIDogU3Vic2NyaXB0aW9uIHtcblxuXHRcdGxldCBzIDogU3Vic2NyaXB0aW9uID0gdGhpcy5ldmVudEJ1c1NlcnZpY2Uuc3Vic2NyaWJlVG9BcHAoZXZlbnRDb2RlLCBoYW5kbGVyKTtcblx0XHR0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChzKTtcblxuXHRcdHJldHVybiBzO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJvdGVjdGVkIGVtaXRUb0FwcChldmVudCA6IEFwcEV2ZW50KSA6IHZvaWQge1xuXHRcdHRoaXMuZXZlbnRCdXNTZXJ2aWNlLmVtaXRUb0FwcChldmVudCk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcm90ZWN0ZWQgc3Vic2NyaWJlVG9FcnJvcihoYW5kbGVyIDogRXJyb3JIYW5kbGVyKSA6IFN1YnNjcmlwdGlvbiB7XG5cblx0XHRsZXQgcyA6IFN1YnNjcmlwdGlvbiA9IHRoaXMuZXZlbnRCdXNTZXJ2aWNlLnN1YnNjcmliZVRvRXJyb3IoaGFuZGxlcik7XG5cdFx0dGhpcy5zdWJzY3JpcHRpb25zLnB1c2gocyk7XG5cblx0XHRyZXR1cm4gcztcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByb3RlY3RlZCBlbWl0VG9FcnJvcihldmVudCA6IEVycm9yRXZlbnQpIDogdm9pZCB7XG5cdFx0dGhpcy5ldmVudEJ1c1NlcnZpY2UuZW1pdFRvRXJyb3IoZXZlbnQpO1xuXHR9XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtFdmVudEVtaXR0ZXIsIEluamVjdGFibGV9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge0FwcEV2ZW50LCBFcnJvckV2ZW50LCBFcnJvckhhbmRsZXIsIEV2ZW50SGFuZGxlcn0gZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEV2ZW50QnVzU2VydmljZSB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGV2ZW50RW1pdHRlck1hcCA6IE1hcDxzdHJpbmcsIEV2ZW50RW1pdHRlcjxBcHBFdmVudD4+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIGVycm9yRXZlbnRzICAgICA6IEV2ZW50RW1pdHRlcjxFcnJvckV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQVBJIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHN1YnNjcmliZVRvQXBwKGV2ZW50Q29kZSA6IHN0cmluZywgaGFuZGxlciA6IEV2ZW50SGFuZGxlcikgOiBTdWJzY3JpcHRpb24ge1xuXG5cdFx0bGV0IGVtaXR0ZXIgOiBFdmVudEVtaXR0ZXI8QXBwRXZlbnQ+ID0gdGhpcy5ldmVudEVtaXR0ZXJNYXAuZ2V0KGV2ZW50Q29kZSk7XG5cblx0XHRpZiAoZW1pdHRlciA9PSBudWxsKSB7XG5cdFx0XHRlbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHRcdFx0dGhpcy5ldmVudEVtaXR0ZXJNYXAuc2V0KGV2ZW50Q29kZSwgZW1pdHRlcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGVtaXR0ZXIuc3Vic2NyaWJlKGhhbmRsZXIsIG51bGwsIG51bGwpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIGVtaXRUb0FwcChldmVudCA6IEFwcEV2ZW50KSA6IHZvaWQge1xuXG5cdFx0bGV0IGVtaXR0ZXIgPSB0aGlzLmV2ZW50RW1pdHRlck1hcC5nZXQoZXZlbnQuY29kZSk7XG5cblx0XHRpZiAoZW1pdHRlciAhPSBudWxsKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkVtaXR0aW5nIGV2ZW50IDogXCIrIEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cdFx0XHRlbWl0dGVyLmVtaXQoZXZlbnQpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiV0FSTklORyA6IEVtaXR0aW5nIGFuIGV2ZW50IHdpdGhvdXQgYW55IGhhbmRsZXIgOiBcIisgSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblx0XHR9XG5cblx0XHQvLy0tLSBFbWl0dGluZyB0byBnbG9iYWwgaGFuZGxlcnNcblxuXHRcdGVtaXR0ZXIgPSB0aGlzLmV2ZW50RW1pdHRlck1hcC5nZXQoQXBwRXZlbnQuQU5ZKTtcblxuXHRcdGlmIChlbWl0dGVyICE9IG51bGwpIHtcblx0XHRcdGVtaXR0ZXIuZW1pdChldmVudCk7XG5cdFx0fVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHN1YnNjcmliZVRvRXJyb3IoaGFuZGxlciA6IEVycm9ySGFuZGxlcikgOiBTdWJzY3JpcHRpb24ge1xuXHRcdHJldHVybiB0aGlzLmVycm9yRXZlbnRzLnN1YnNjcmliZShoYW5kbGVyLCBudWxsLCBudWxsKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBlbWl0VG9FcnJvcihldmVudCA6IEVycm9yRXZlbnQpIDogdm9pZCB7XG5cdFx0Y29uc29sZS5sb2coXCJFbWl0dGluZyBlcnJvciBldmVudCA6IFwiKyBKU09OLnN0cmluZ2lmeShldmVudCkpO1xuXHRcdHRoaXMuZXJyb3JFdmVudHMuZW1pdChldmVudCk7XG5cdH1cbn1cblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiwiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbXBvcnQge0luamVjdGFibGV9ICAgICAgICAgZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FwcEV2ZW50fSAgICAgICAgICAgZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbmltcG9ydCB7QWJzdHJhY3RTdWJzY3JpYmVyfSBmcm9tIFwiLi9hYnN0cmFjdC1zdWJzY3JpYmVyXCI7XG5pbXBvcnQge0V2ZW50QnVzU2VydmljZX0gICAgZnJvbSBcIi4vZXZlbnRidXMtc2VydmljZVwiO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmVudW0gU3RhdHVzIHtcblx0TE9HSU4sXG5cdExPQURJTkcsXG5cdFJFQURZXG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uU2VydmljZSBleHRlbmRzIEFic3RyYWN0U3Vic2NyaWJlciB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIHN0YXR1cyA6IFN0YXR1cyA9IFN0YXR1cy5MT0dJTjtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IoZXZlbnRCdXNTZXJ2aWNlOiBFdmVudEJ1c1NlcnZpY2UpIHtcblxuXHRcdHN1cGVyKGV2ZW50QnVzU2VydmljZSk7XG5cblx0XHRzdXBlci5zdWJzY3JpYmVUb0FwcChBcHBFdmVudC5MT0dJTl9TVUNDRVNTLCAgICAgKGV2ZW50IDogQXBwRXZlbnQpID0+IHRoaXMub25Mb2dpblN1Y2Nlc3MgICAgKGV2ZW50KSk7XG5cdFx0c3VwZXIuc3Vic2NyaWJlVG9BcHAoQXBwRXZlbnQuTE9HSU5fRkFJTEVELCAgICAgIChldmVudCA6IEFwcEV2ZW50KSA9PiB0aGlzLm9uTG9naW5GYWlsZWQgICAgIChldmVudCkpO1xuXHRcdHN1cGVyLnN1YnNjcmliZVRvQXBwKEFwcEV2ZW50LkxPR09VVF9TVUNDRVNTLCAgICAoZXZlbnQgOiBBcHBFdmVudCkgPT4gdGhpcy5vbkxvZ291dFN1Y2Nlc3MgICAoZXZlbnQpKTtcblx0XHRzdXBlci5zdWJzY3JpYmVUb0FwcChBcHBFdmVudC5MT0dPVVRfRkFJTEVELCAgICAgKGV2ZW50IDogQXBwRXZlbnQpID0+IHRoaXMub25Mb2dvdXRGYWlsZWQgICAgKGV2ZW50KSk7XG5cdFx0c3VwZXIuc3Vic2NyaWJlVG9BcHAoQXBwRXZlbnQuSU5WQUxJRF9UT0tFTiwgICAgIChldmVudCA6IEFwcEV2ZW50KSA9PiB0aGlzLm9uSW52YWxpZFRva2VuICAgIChldmVudCkpO1xuXHRcdHN1cGVyLnN1YnNjcmliZVRvQXBwKEFwcEV2ZW50LkFQUExJQ0FUSU9OX1JFQURZLCAoZXZlbnQgOiBBcHBFdmVudCkgPT4gdGhpcy5vbkFwcGxpY2F0aW9uUmVhZHkoZXZlbnQpKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBBUEkgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgaXNTdGF0dXNMb2dpbigpIDogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuc3RhdHVzID09IFN0YXR1cy5MT0dJTjtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBpc1N0YXR1c0xvYWRpbmcoKSA6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLnN0YXR1cyA9PSBTdGF0dXMuTE9BRElORztcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBpc1N0YXR1c1JlYWR5KCkgOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5zdGF0dXMgPT0gU3RhdHVzLlJFQURZO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEV2ZW50c1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIG9uTG9naW5TdWNjZXNzKGV2ZW50IDogQXBwRXZlbnQpIHtcblx0XHR0aGlzLnN0YXR1cyA9IFN0YXR1cy5MT0FESU5HO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBvbkxvZ2luRmFpbGVkKGV2ZW50IDogQXBwRXZlbnQpIHtcblx0XHR0aGlzLnN0YXR1cyA9IFN0YXR1cy5MT0dJTjtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgb25Mb2dvdXRTdWNjZXNzKGV2ZW50IDogQXBwRXZlbnQpIHtcblx0XHR0aGlzLnN0YXR1cyA9IFN0YXR1cy5MT0dJTjtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgb25Mb2dvdXRGYWlsZWQoZXZlbnQgOiBBcHBFdmVudCkge1xuXHRcdHRoaXMuc3RhdHVzID0gU3RhdHVzLkxPR0lOO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBvbkludmFsaWRUb2tlbihldmVudCA6IEFwcEV2ZW50KSB7XG5cdFx0dGhpcy5zdGF0dXMgPSBTdGF0dXMuTE9HSU47XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIG9uQXBwbGljYXRpb25SZWFkeShldmVudCA6IEFwcEV2ZW50KSB7XG5cdFx0dGhpcy5zdGF0dXMgPSBTdGF0dXMuUkVBRFk7XG5cdH1cbn1cblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiwiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbXBvcnQge0luamVjdGFibGV9ICAgZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7SHR0cENsaWVudH0gICBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcbmltcG9ydCB7RG9tU2FuaXRpemVyfSBmcm9tIFwiQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3NlclwiO1xuaW1wb3J0IHtTYWZlVXJsfSAgICAgIGZyb20gXCJAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyL3NyYy9zZWN1cml0eS9kb21fc2FuaXRpemF0aW9uX3NlcnZpY2VcIjtcblxuaW1wb3J0IHtPYnNlcnZhYmxlLCB0aHJvd0Vycm9yfSAgICBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBtYXAsIGZpbmFsaXplfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcbmltcG9ydCB7QXBwRXZlbnQsIEVycm9yRXZlbnQgfSAgICAgZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbmltcG9ydCB7RXZlbnRCdXNTZXJ2aWNlfSAgICAgICAgICAgZnJvbSBcIi4vZXZlbnRidXMtc2VydmljZVwiXG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEh0dHBTZXJ2aWNlIHtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gVmFyaWFibGVzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgb3BlblJlcXVlc3RzIDogbnVtYmVyID0gMDtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSBodHRwQ2xpZW50ICAgICAgOiBIdHRwQ2xpZW50LFxuXHRcdFx0XHRwcml2YXRlIGV2ZW50QnVzU2VydmljZSA6IEV2ZW50QnVzU2VydmljZSxcblx0XHRcdFx0cHJpdmF0ZSBkb21TYW5pdGl6ZXIgICAgOiBEb21TYW5pdGl6ZXIgKSB7fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBBUEkgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0IGxvYWRpbmcoKSA6IGJvb2xlYW4ge1xuXHRcdHJldHVybiAodGhpcy5vcGVuUmVxdWVzdHMgPiAwKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBnZXRPYmplY3QodXJsIDogc3RyaW5nLCBvcHRpb25zPyA6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG5cblx0XHR0aGlzLnNob3dMb2FkZXIoKTtcblxuXHRcdC8vLS0tIFwiUHJhZ21hXCI6IFwibm8tY2FjaGVcIiBmb3IgSUUgMTFcblxuXHRcdGxldCBoZWFkZXIgPSB7XG5cdFx0XHRcIlByYWdtYVwiICAgICAgICA6IFwibm8tY2FjaGVcIixcblx0XHRcdFwiQ2FjaGUtQ29udHJvbFwiIDogXCJuby1jYWNoZVwiLFxuXHRcdFx0XCJFeHBpcmVzXCIgICAgICAgOiBcIjBcIlxuXHRcdH07XG5cblx0XHRyZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldCh1cmwsIHsgcGFyYW1zOiBvcHRpb25zLCBoZWFkZXJzIDogaGVhZGVyIH0pLnBpcGUoXG5cdFx0XHRjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnJvcikpLFxuXHRcdFx0ZmluYWxpemUgICgoKSAgICAgID0+IHRoaXMuaGlkZUxvYWRlcigpKVxuXHRcdCk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0QmxvYih1cmwgOiBzdHJpbmcsIG9wdGlvbnM/IDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcblxuXHRcdHRoaXMuc2hvd0xvYWRlcigpO1xuXG5cdFx0Ly8tLS0gQWRkIHRpbWVzdGFtcCB0byBjaGFuZ2Ugc3RhdGljIHVybCB0byBkeW5hbWljIGZvciBJRSAxMVxuXG5cdFx0aWYgKG9wdGlvbnMgIT0gbnVsbCkge1xuXHRcdFx0b3B0aW9ucy50cyA9IERhdGUubm93KCk7XG5cdFx0fVxuXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0KHVybCwgeyBwYXJhbXM6IG9wdGlvbnMsIHJlc3BvbnNlVHlwZSA6ICdibG9iJ30pLnBpcGUoXG5cdFx0XHRtYXAoZSA9PiB0aGlzLmdldFNhbml0aXplZFVybChVUkwuY3JlYXRlT2JqZWN0VVJMKGUpKSksXG5cdFx0XHRjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnJvcikpLFxuXHRcdFx0ZmluYWxpemUoKCkgPT4gdGhpcy5oaWRlTG9hZGVyKCkpXG5cdFx0KTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBwb3N0T2JqZWN0KHVybDogc3RyaW5nLCBvYmplY3Q6IGFueSwgb3B0aW9ucz86IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG5cbiAgICAgICAgdGhpcy5zaG93TG9hZGVyKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5wb3N0ICh1cmwsIG9iamVjdCwgb3B0aW9ucykucGlwZShcblx0XHRcdGNhdGNoRXJyb3IoKGVycm9yKSA9PiB0aGlzLmhhbmRsZUVycm9yKGVycm9yKSksXG5cdFx0XHRmaW5hbGl6ZSAgKCgpICAgICAgPT4gdGhpcy5oaWRlTG9hZGVyKCkpXG5cdFx0KTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBnZXRTYW5pdGl6ZWRVcmwodXJsIDogc3RyaW5nKTogU2FmZVVybCB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybCh1cmwpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFByaXZhdGUgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGhhbmRsZUVycm9yKHJlc3BvbnNlIDogYW55KSA6IE9ic2VydmFibGU8YW55PiB7XG5cblx0XHRjb25zb2xlLmxvZyhcIkdvdCB0aGUgZm9sbG93aW5nIEhUVFAgZXJyb3IgOiBcIiArIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XG5cblx0XHRsZXQgZXJyb3IgOiBFcnJvckV2ZW50O1xuXG5cdFx0aWYgKHJlc3BvbnNlLnN0YXR1cyA9PSA0MjIpIHtcblx0XHRcdC8vLS0tIFVucHJvY2Vzc2FibGUgZW50aXR5XG5cdFx0XHRlcnJvciA9IHJlc3BvbnNlLmVycm9yO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGVycm9yID0ge1xuXHRcdFx0XHRjb2RlIDogcmVzcG9uc2Uuc3RhdHVzLnRvU3RyaW5nKCksXG5cdFx0XHRcdGVycm9yOiByZXNwb25zZS5lcnJvci50b1N0cmluZygpXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdHRoaXMuZXZlbnRCdXNTZXJ2aWNlLmVtaXRUb0Vycm9yKGVycm9yKTtcblxuXHRcdHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgc2hvd0xvYWRlcigpOiB2b2lkIHtcblxuXHRcdGlmICgrK3RoaXMub3BlblJlcXVlc3RzID09IDEpIHtcblx0XHRcdHRoaXMuZXZlbnRCdXNTZXJ2aWNlLmVtaXRUb0FwcChuZXcgQXBwRXZlbnQoQXBwRXZlbnQuU1VCTUlUX1NUQVJUKSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBoaWRlTG9hZGVyKCk6IHZvaWQge1xuXG5cdFx0aWYgKC0tdGhpcy5vcGVuUmVxdWVzdHMgPT0gMCkge1xuXHRcdFx0dGhpcy5ldmVudEJ1c1NlcnZpY2UuZW1pdFRvQXBwKG5ldyBBcHBFdmVudChBcHBFdmVudC5TVUJNSVRfRU5EKSk7XG5cdFx0fVxuXHR9XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtJbmplY3RhYmxlfSAgZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7SHR0cFNlcnZpY2V9IGZyb20gXCIuL2h0dHAtc2VydmljZVwiO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBMYWJlbFNlcnZpY2Uge1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBWYXJpYWJsZXNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBzdGF0aWMgVE9PTEtJVF9GSUxFICAgICA6IHN0cmluZyA9IFwidG9vbGtpdFwiO1xuXHRwcml2YXRlIHN0YXRpYyBBUFBMSUNBVElPTl9GSUxFIDogc3RyaW5nID0gXCJhcHBsaWNhdGlvblwiO1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgbGFiZWxTZXQgOiBNYXA8U3RyaW5nLCBNYXA8c3RyaW5nLCBhbnk+Pjtcblx0cHJpdmF0ZSBsYW5ndWFnZSA6IHN0cmluZztcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGxhbmd1YWdlcyA6IHN0cmluZ1tdID0gWyBcImVuXCIsIFwiaXRcIiBdO1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBDb25zdHJ1Y3RvclxuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHBTZXJ2aWNlIDogSHR0cFNlcnZpY2UpIHtcblxuXHRcdHRoaXMubGFiZWxTZXQgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy5sYW5ndWFnZSA9IFwiZW5cIjtcblxuXHRcdC8vLS0tIExvYWQgbGFuZ3VhZ2UgZmlsZXNcblxuXHRcdHRoaXMubGFuZ3VhZ2VzLmZvckVhY2goIChsYW5ndWFnZSA6IHN0cmluZykgPT4ge1xuXHRcdFx0dGhpcy5pbml0TGFuZ3VhZ2UobGFuZ3VhZ2UpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEFQSSBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBzZXRMYW5ndWFnZShsYW5ndWFnZSA6IHN0cmluZykgOiB2b2lkIHtcblx0XHR0aGlzLmxhbmd1YWdlID0gbGFuZ3VhZ2U7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0TGFiZWwoZW50aXR5IDogc3RyaW5nLCBjb2RlIDogc3RyaW5nKSA6IGFueSB7XG5cblx0XHRpZ