@alauda-fe/common
Version:
Alauda frontend team common codes.
282 lines • 40 kB
JavaScript
import { MessageService, MessageType as Type, NotificationService, } from '@alauda/ui';
import { Injectable } from '@angular/core';
import { get } from 'lodash-es';
import { Subject, of, map, switchMap, takeUntil, tap } from 'rxjs';
import { K8sApiService } from '../../../api/k8s-api.service';
import { WatchEvent } from '../../../api/types';
import { AuthorizationStateService } from '../../../authorization/state.service';
import { K8sUtilService } from '../../../core/public-api';
import { K8SResourceList } from '../../../k8s-resource-list/k8s-resource-list';
import { MESSAGE_CONFIG, MessageType, NOTIFY_INFO_TYPE, NOTIFY_NOT_FIXED, NOTIFY_PUSH_TYPE, dateValueOf, } from './utils';
import * as i0 from "@angular/core";
import * as i1 from "../../../api/k8s-api.service";
import * as i2 from "../../../authorization/state.service";
import * as i3 from "../../../core/public-api";
import * as i4 from "@alauda/ui";
const NOTIFY_TYPE_MAP = {
[MessageType.WarningMessage]: Type.Error,
[MessageType.SystemMessage]: Type.Info,
[MessageType.ProductMessage]: Type.Success,
[MessageType.PlatformAnnouncement]: '',
};
export class NotifyService {
constructor(k8sApi, auth, k8sUtil, notification, messages) {
this.k8sApi = k8sApi;
this.auth = auth;
this.k8sUtil = k8sUtil;
this.notification = notification;
this.messages = messages;
this.triggerNotify$ = new Subject();
this.pushEnabled = true;
this.auiNotificationList = [];
this.windowUnload = false;
this.onDestroy$ = new Subject();
this.userName$ = this.auth.getTokenPayload().pipe(takeUntil(this.onDestroy$), map(account => account.email || account.name), tap(name => {
this.userName = name;
this.settingDefaultPushStatus();
}));
// 这个版本没有自动发送的消息,用户手册没有办法描述这部分功能, 先注释
// 因占用并发数,后续如产品需要重新加入此功能,可以和产品讨论下是否可以阉割此功能
// watchConfigMap$ = this.k8sApi
// .watchGlobalResource({
// definition: {
// type: 'configmaps',
// },
// namespaced: true,
// name: 'message-config',
// })
// .pipe(
// takeUntil(this.onDestroy$),
// catchError(() => of(null)),
// map(() => {
// return this.pushEnabled;
// }),
// );
// watchMessageConfigMap$ = this.watchConfigMap$.pipe(
// switchMap(res =>
// this.userName$.pipe(
// map(() => {
// return res;
// }),
// ),
// ),
// );
this.list = new K8SResourceList({
fetchParams$: of({}), // 使用空参数否则路由参数变化会导致重新触发 get list
fetcher: this.fetcher.bind(this),
watcher: seed => this.k8sApi
.watchGlobalResourceChange(seed, {
definition: MESSAGE_CONFIG,
})
.pipe(tap(item => {
const cacheInfo = this.getCacheLocalValue(NOTIFY_INFO_TYPE);
const infoValue = cacheInfo?.split(',') || [];
this.removePush(item);
if ([WatchEvent.Added, WatchEvent.Modified].includes(item.type) &&
!infoValue.includes(this.k8sUtil.getName(item.object))) {
this.dispatchNotify(item.object);
const value = [...infoValue, this.k8sUtil.getName(item.object)];
this.cacheNotifyInfo(value.join(','));
}
})),
polling: 10_000,
});
}
watchNotify() {
this.triggerNotify$.pipe(takeUntil(this.onDestroy$)).subscribe(res => {
this.notifyMessage(res);
});
}
getNotifyList() {
return this.list.items$.pipe(takeUntil(this.onDestroy$), switchMap(res => this.userName$.pipe(map(() => res))), map(res => this.messageSort(res, 'desc')));
}
messageSort(data, type = 'asc') {
return data.sort((a, b) => {
const start = type === 'asc'
? a.metadata.creationTimestamp
: b.metadata.creationTimestamp;
const end = type === 'asc'
? b.metadata.creationTimestamp
: a.metadata.creationTimestamp;
return dateValueOf(start) - dateValueOf(end);
});
}
fetcher() {
return this.k8sApi
.getGlobalResourceList({
definition: MESSAGE_CONFIG,
})
.pipe(tap(res => {
this.handleNotify(res.items);
}));
}
handleNotify(data) {
const cacheInfo = this.getCacheLocalValue(NOTIFY_INFO_TYPE);
const infoValue = cacheInfo?.split(',') || [];
const messages = this.messageSort(data, 'desc').reduce((acc, item) => {
const { isResident } = item.spec;
if (isResident &&
!this.expired(item) &&
!infoValue.includes(this.k8sUtil.getName(item))) {
const pre = acc ? `${acc},` : '';
this.dispatchNotify(item); // 触发提示消息
return `${pre}${this.k8sUtil.getName(item)}`;
}
return acc;
}, '');
if (messages) {
this.cacheNotifyInfo(messages);
}
}
cacheNotifyInfo(values) {
this.addCacheLocalValue(NOTIFY_INFO_TYPE, values);
}
dispatchNotify(data) {
const notFixed = this.getCacheLocalValue(NOTIFY_NOT_FIXED);
const pass = !notFixed?.split(',')?.includes(this.k8sUtil.getName(data));
const push = this.getCacheLocalValue(NOTIFY_PUSH_TYPE);
if (((!data.spec.isResident && this.pushEnabled && push) ||
!this.expired(data)) &&
pass) {
this.triggerNotify$.next(data);
}
}
expired(item) {
const expiredTimestamp = item.spec.expiredTimestamp;
if (!expiredTimestamp) {
return true;
}
return new Date(expiredTimestamp).valueOf() < Date.now();
}
getCacheLocalValue(type) {
const value = window.localStorage.getItem(type);
return value && JSON.parse(value)[this.userName];
}
addCacheLocalValue(type, value) {
const preValue = window.localStorage.getItem(type);
window.localStorage.setItem(type, JSON.stringify({
...(preValue ? JSON.parse(preValue) : {}),
[this.userName]: value,
}));
}
notifyMessage(data) {
const { isResident, subject, content } = data.spec;
const name = this.k8sUtil.getName(data);
const type = this.getMessageType(data);
if (isResident) {
const notificationRef = this.notification.create({
type: type || Type.Info,
title: subject,
...(type ? {} : { customClass: 'platform-class' }),
content,
...(isResident ? { duration: 0 } : {}),
});
this.auiNotificationList.push(notificationRef);
Object.assign(notificationRef.instance, { data });
notificationRef.instance.afterClosed.subscribe(() => {
this.closedNotifyCallback(data, name, get(notificationRef.instance, 'windowUnload', false));
});
return;
}
this.messages.create({
type: type || Type.Info,
content: subject,
});
}
/**
* 关闭通知: 手动关闭存储 添加不再展示状态记录
* 关闭页面、删除消息 不记录
*/
closedNotifyCallback(data, name, windowUnload) {
this.removeNotificationList(name);
if (!this.windowUnload && !windowUnload) {
this.addNotFixed(data);
}
this.windowUnload = false;
}
/**
* 记录 不再展示状态 存储在 local storage
*/
addNotFixed(data) {
if (data.spec.isResident) {
const notFixedVal = this.getCacheLocalValue(NOTIFY_NOT_FIXED);
const value = [
...(notFixedVal?.split(',') || []),
this.k8sUtil.getName(data),
];
this.addCacheLocalValue(NOTIFY_NOT_FIXED, value.join(','));
}
this.windowUnload = false;
}
/**
* 触发删除消息
* - 删除 local storage NOT_FIXED 存储的消息
* - 手动触发关闭常驻通知弹框
*/
removePush(item) {
const name = this.k8sUtil.getName(item.object);
const notFixedVal = this.getCacheLocalValue(NOTIFY_NOT_FIXED)?.split(',') || [];
if (WatchEvent.Deleted === item.type) {
this.removeMessage(name);
this.manualCloseNotify(name);
}
if (WatchEvent.Deleted === item.type &&
item.object.spec.isResident &&
!notFixedVal.includes(name)) {
this.manualCloseNotify(name);
}
}
removeMessage(name) {
const cacheNotFixed = this.getCacheLocalValue(NOTIFY_NOT_FIXED)?.split(',') || [];
if (cacheNotFixed.length > 0) {
const index = cacheNotFixed.indexOf(name);
if (index !== -1) {
cacheNotFixed.splice(index, 1);
this.addCacheLocalValue(NOTIFY_NOT_FIXED, cacheNotFixed.join(','));
}
}
}
manualCloseNotify(name) {
const notifyInstance = this.auiNotificationList.find(item => this.k8sUtil.getName(get(item.instance, 'data')) === name);
if (notifyInstance) {
this.windowUnload = true;
notifyInstance.instance.close();
}
}
removeNotificationList(name) {
this.auiNotificationList = this.auiNotificationList.filter(item => this.k8sUtil.getName(get(item.instance, 'data')) !== name);
}
getMessageType(data) {
const type = this.k8sUtil.getLabel(data, 'type');
return NOTIFY_TYPE_MAP[type];
}
settingDefaultPushStatus() {
if (!window.localStorage.getItem(NOTIFY_PUSH_TYPE)) {
this.addCacheLocalValue(NOTIFY_PUSH_TYPE, true);
}
}
closeAllNotification() {
for (const notify of this.auiNotificationList) {
// 将 windowUnload 存储 instance 在 afterClosed 进行判断
// remove 异步 循环中 windowUnload 值已发生改变但还未触发 afterClosed 回调
Object.assign(notify.instance, { windowUnload: true });
notify.instance.close();
}
this.auiNotificationList = [];
}
destroy() {
// 重新加载 header 关闭所有通知,重新加载 header 重新弹出
this.closeAllNotification();
window.localStorage.removeItem(NOTIFY_INFO_TYPE);
this.onDestroy$.next();
}
static { this.ɵfac = function NotifyService_Factory(t) { return new (t || NotifyService)(i0.ɵɵinject(i1.K8sApiService), i0.ɵɵinject(i2.AuthorizationStateService), i0.ɵɵinject(i3.K8sUtilService), i0.ɵɵinject(i4.NotificationService), i0.ɵɵinject(i4.MessageService)); }; }
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: NotifyService, factory: NotifyService.ɵfac, providedIn: 'root' }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NotifyService, [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], () => [{ type: i1.K8sApiService }, { type: i2.AuthorizationStateService }, { type: i3.K8sUtilService }, { type: i4.NotificationService }, { type: i4.MessageService }], null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm90aWZ5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvcGFnZS1zY2FmZm9sZC9wYWdlLWhlYWRlci9oZWFkZXItbm90aWZ5L25vdGlmeS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxjQUFjLEVBQ2QsV0FBVyxJQUFJLElBQUksRUFFbkIsbUJBQW1CLEdBQ3BCLE1BQU0sWUFBWSxDQUFDO0FBQ3BCLE9BQU8sRUFBZ0IsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRW5FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM3RCxPQUFPLEVBQW9CLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWxFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOENBQThDLENBQUM7QUFFL0UsT0FBTyxFQUNMLGNBQWMsRUFFZCxXQUFXLEVBQ1gsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsV0FBVyxHQUNaLE1BQU0sU0FBUyxDQUFDOzs7Ozs7QUFFakIsTUFBTSxlQUFlLEdBQUc7SUFDdEIsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUs7SUFDeEMsQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUk7SUFDdEMsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU87SUFDMUMsQ0FBQyxXQUFXLENBQUMsb0JBQW9CLENBQUMsRUFBRSxFQUFFO0NBQ3ZDLENBQUM7QUFJRixNQUFNLE9BQU8sYUFBYTtJQW9FeEIsWUFDbUIsTUFBcUIsRUFDckIsSUFBK0IsRUFDL0IsT0FBdUIsRUFDdkIsWUFBaUMsRUFDakMsUUFBd0I7UUFKeEIsV0FBTSxHQUFOLE1BQU0sQ0FBZTtRQUNyQixTQUFJLEdBQUosSUFBSSxDQUEyQjtRQUMvQixZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN2QixpQkFBWSxHQUFaLFlBQVksQ0FBcUI7UUFDakMsYUFBUSxHQUFSLFFBQVEsQ0FBZ0I7UUF2RTNDLG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUN4QyxnQkFBVyxHQUFHLElBQUksQ0FBQztRQUNuQix3QkFBbUIsR0FBK0MsRUFBRSxDQUFDO1FBQ3JFLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGVBQVUsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBQ2pDLGNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBZSxDQUFDLElBQUksQ0FDdkQsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFDMUIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQzdDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNULElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ3JCLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixxQ0FBcUM7UUFDckMsMENBQTBDO1FBQzFDLGdDQUFnQztRQUNoQywyQkFBMkI7UUFDM0Isb0JBQW9CO1FBQ3BCLDRCQUE0QjtRQUM1QixTQUFTO1FBQ1Qsd0JBQXdCO1FBQ3hCLDhCQUE4QjtRQUM5QixPQUFPO1FBQ1AsV0FBVztRQUNYLGtDQUFrQztRQUNsQyxrQ0FBa0M7UUFDbEMsa0JBQWtCO1FBQ2xCLGlDQUFpQztRQUNqQyxVQUFVO1FBQ1YsT0FBTztRQUNQLHNEQUFzRDtRQUN0RCxxQkFBcUI7UUFDckIsMkJBQTJCO1FBQzNCLG9CQUFvQjtRQUNwQixzQkFBc0I7UUFDdEIsWUFBWTtRQUNaLFNBQVM7UUFDVCxPQUFPO1FBQ1AsS0FBSztRQUVMLFNBQUksR0FBRyxJQUFJLGVBQWUsQ0FBQztZQUN6QixZQUFZLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLGdDQUFnQztZQUN0RCxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2hDLE9BQU8sRUFBRSxJQUFJLENBQUMsRUFBRSxDQUNkLElBQUksQ0FBQyxNQUFNO2lCQUNSLHlCQUF5QixDQUFVLElBQUksRUFBRTtnQkFDeEMsVUFBVSxFQUFFLGNBQWM7YUFDM0IsQ0FBQztpQkFDRCxJQUFJLENBQ0gsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNULE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUM1RCxNQUFNLFNBQVMsR0FBYSxTQUFTLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdEIsSUFDRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO29CQUMzRCxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQ3RELENBQUM7b0JBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2pDLE1BQU0sS0FBSyxHQUFHLENBQUMsR0FBRyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7b0JBQ2hFLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUN4QyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQ0g7WUFDTCxPQUFPLEVBQUUsTUFBTTtTQUNoQixDQUFDLENBQUM7SUFRQSxDQUFDO0lBRUosV0FBVztRQUNULElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDbkUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxhQUFhO1FBQ1gsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQzFCLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQzFCLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQ3JELEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQzFDLENBQUM7SUFDSixDQUFDO0lBRUQsV0FBVyxDQUFDLElBQWUsRUFBRSxPQUF1QixLQUFLO1FBQ3ZELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN4QixNQUFNLEtBQUssR0FDVCxJQUFJLEtBQUssS0FBSztnQkFDWixDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUI7Z0JBQzlCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDO1lBQ25DLE1BQU0sR0FBRyxHQUNQLElBQUksS0FBSyxLQUFLO2dCQUNaLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGlCQUFpQjtnQkFDOUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUM7WUFDbkMsT0FBTyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLE9BQU87UUFDYixPQUFPLElBQUksQ0FBQyxNQUFNO2FBQ2YscUJBQXFCLENBQVU7WUFDOUIsVUFBVSxFQUFFLGNBQWM7U0FDM0IsQ0FBQzthQUNELElBQUksQ0FDSCxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDUixJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ04sQ0FBQztJQUVPLFlBQVksQ0FBQyxJQUFlO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzVELE1BQU0sU0FBUyxHQUFhLFNBQVMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNuRSxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNqQyxJQUNFLFVBQVU7Z0JBQ1YsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDbkIsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQy9DLENBQUM7Z0JBQ0QsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTO2dCQUNwQyxPQUFPLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDL0MsQ0FBQztZQUNELE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ1AsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFFTyxlQUFlLENBQUMsTUFBYztRQUNwQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVPLGNBQWMsQ0FBQyxJQUFhO1FBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzNELE1BQU0sSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN6RSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN2RCxJQUNFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDO1lBQ2xELENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixJQUFJLEVBQ0osQ0FBQztZQUNELElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLENBQUM7SUFDSCxDQUFDO0lBRU8sT0FBTyxDQUFDLElBQWE7UUFDM0IsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQ3BELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDM0QsQ0FBQztJQUVELGtCQUFrQixDQUFDLElBQVk7UUFDN0IsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsT0FBTyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVELGtCQUFrQixDQUFDLElBQVksRUFBRSxLQUF1QjtRQUN0RCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRCxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FDekIsSUFBSSxFQUNKLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDYixHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsS0FBSztTQUN2QixDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFTyxhQUFhLENBQUMsSUFBYTtRQUNqQyxNQUFNLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ25ELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFdkMsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO2dCQUMvQyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJO2dCQUN2QixLQUFLLEVBQUUsT0FBTztnQkFDZCxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLENBQUM7Z0JBQ2xELE9BQU87Z0JBQ1AsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUN2QyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQy9DLE1BQU0sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDbEQsZUFBZSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtnQkFDbEQsSUFBSSxDQUFDLG9CQUFvQixDQUN2QixJQUFJLEVBQ0osSUFBSSxFQUNKLEdBQUcsQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxLQUFLLENBQUMsQ0FDckQsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztZQUNuQixJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJO1lBQ3ZCLE9BQU8sRUFBRSxPQUFPO1NBQ2pCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSyxvQkFBb0IsQ0FDMUIsSUFBYSxFQUNiLElBQVksRUFDWixZQUFxQjtRQUVyQixJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSyxXQUFXLENBQUMsSUFBYTtRQUMvQixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDekIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDOUQsTUFBTSxLQUFLLEdBQUc7Z0JBQ1osR0FBRyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNsQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7YUFDM0IsQ0FBQztZQUNGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0QsQ0FBQztRQUNELElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQzVCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssVUFBVSxDQUFDLElBQStCO1FBQ2hELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxNQUFNLFdBQVcsR0FDZixJQUFJLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlELElBQUksVUFBVSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQ0UsVUFBVSxDQUFDLE9BQU8sS0FBSyxJQUFJLENBQUMsSUFBSTtZQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVO1lBQzNCLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFDM0IsQ0FBQztZQUNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVPLGFBQWEsQ0FBQyxJQUFZO1FBQ2hDLE1BQU0sYUFBYSxHQUNqQixJQUFJLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlELElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFDLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2pCLGFBQWEsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUMvQixJQUFJLENBQUMsa0JBQWtCLENBQUMsZ0JBQWdCLEVBQUUsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3JFLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGlCQUFpQixDQUFDLElBQVk7UUFDcEMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FDbEQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FDbEUsQ0FBQztRQUNGLElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsY0FBYyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLHNCQUFzQixDQUFDLElBQVk7UUFDekMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQ3hELElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQ2xFLENBQUM7SUFDSixDQUFDO0lBRU8sY0FBYyxDQUFDLElBQWE7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBZ0IsQ0FBQztRQUNoRSxPQUFPLGVBQWUsQ0FBQyxJQUFJLENBQVMsQ0FBQztJQUN2QyxDQUFDO0lBRU8sd0JBQXdCO1FBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7WUFDbkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xELENBQUM7SUFDSCxDQUFDO0lBRUQsb0JBQW9CO1FBQ2xCLEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsZ0RBQWdEO1lBQ2hELHdEQUF3RDtZQUN4RCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzFCLENBQUM7UUFDRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxPQUFPO1FBQ0wsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN6QixDQUFDOzhFQTNUVSxhQUFhO3VFQUFiLGFBQWEsV0FBYixhQUFhLG1CQUZaLE1BQU07O2lGQUVQLGFBQWE7Y0FIekIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgTWVzc2FnZVNlcnZpY2UsXG4gIE1lc3NhZ2VUeXBlIGFzIFR5cGUsXG4gIE5vdGlmaWNhdGlvbkNvbXBvbmVudCxcbiAgTm90aWZpY2F0aW9uU2VydmljZSxcbn0gZnJvbSAnQGFsYXVkYS91aSc7XG5pbXBvcnQgeyBDb21wb25lbnRSZWYsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBTdWJqZWN0LCBvZiwgbWFwLCBzd2l0Y2hNYXAsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEs4c0FwaVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9hcGkvazhzLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IFdhdGNoQVBJUmVzcG9uc2UsIFdhdGNoRXZlbnQgfSBmcm9tICcuLi8uLi8uLi9hcGkvdHlwZXMnO1xuaW1wb3J0IHsgQWNjb3VudEluZm8gfSBmcm9tICcuLi8uLi8uLi9hdXRob3JpemF0aW9uL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvblN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2F1dGhvcml6YXRpb24vc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBLOHNVdGlsU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvcHVibGljLWFwaSc7XG5pbXBvcnQgeyBLOFNSZXNvdXJjZUxpc3QgfSBmcm9tICcuLi8uLi8uLi9rOHMtcmVzb3VyY2UtbGlzdC9rOHMtcmVzb3VyY2UtbGlzdCc7XG5cbmltcG9ydCB7XG4gIE1FU1NBR0VfQ09ORklHLFxuICBNZXNzYWdlLFxuICBNZXNzYWdlVHlwZSxcbiAgTk9USUZZX0lORk9fVFlQRSxcbiAgTk9USUZZX05PVF9GSVhFRCxcbiAgTk9USUZZX1BVU0hfVFlQRSxcbiAgZGF0ZVZhbHVlT2YsXG59IGZyb20gJy4vdXRpbHMnO1xuXG5jb25zdCBOT1RJRllfVFlQRV9NQVAgPSB7XG4gIFtNZXNzYWdlVHlwZS5XYXJuaW5nTWVzc2FnZV06IFR5cGUuRXJyb3IsXG4gIFtNZXNzYWdlVHlwZS5TeXN0ZW1NZXNzYWdlXTogVHlwZS5JbmZvLFxuICBbTWVzc2FnZVR5cGUuUHJvZHVjdE1lc3NhZ2VdOiBUeXBlLlN1Y2Nlc3MsXG4gIFtNZXNzYWdlVHlwZS5QbGF0Zm9ybUFubm91bmNlbWVudF06ICcnLFxufTtcbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBOb3RpZnlTZXJ2aWNlIHtcbiAgcHJpdmF0ZSB1c2VyTmFtZTogc3RyaW5nO1xuICB0cmlnZ2VyTm90aWZ5JCA9IG5ldyBTdWJqZWN0PE1lc3NhZ2U+KCk7XG4gIHB1c2hFbmFibGVkID0gdHJ1ZTtcbiAgYXVpTm90aWZpY2F0aW9uTGlzdDogQXJyYXk8Q29tcG9uZW50UmVmPE5vdGlmaWNhdGlvbkNvbXBvbmVudD4+ID0gW107XG4gIHdpbmRvd1VubG9hZCA9IGZhbHNlO1xuICBvbkRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgdXNlck5hbWUkID0gdGhpcy5hdXRoLmdldFRva2VuUGF5bG9hZDxBY2NvdW50SW5mbz4oKS5waXBlKFxuICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpLFxuICAgIG1hcChhY2NvdW50ID0+IGFjY291bnQuZW1haWwgfHwgYWNjb3VudC5uYW1lKSxcbiAgICB0YXAobmFtZSA9PiB7XG4gICAgICB0aGlzLnVzZXJOYW1lID0gbmFtZTtcbiAgICAgIHRoaXMuc2V0dGluZ0RlZmF1bHRQdXNoU3RhdHVzKCk7XG4gICAgfSksXG4gICk7XG4gIC8vIOi/meS4queJiOacrOayoeacieiHquWKqOWPkemAgeeahOa2iOaBr++8jOeUqOaIt+aJi+WGjOayoeacieWKnuazleaPj+i/sOi/memDqOWIhuWKn+iDvSwg5YWI5rOo6YeKXG4gIC8vIOWboOWNoOeUqOW5tuWPkeaVsO+8jOWQjue7reWmguS6p+WTgemcgOimgemHjeaWsOWKoOWFpeatpOWKn+iDve+8jOWPr+S7peWSjOS6p+WTgeiuqOiuuuS4i+aYr+WQpuWPr+S7pemYieWJsuatpOWKn+iDvVxuICAvLyB3YXRjaENvbmZpZ01hcCQgPSB0aGlzLms4c0FwaVxuICAvLyAgIC53YXRjaEdsb2JhbFJlc291cmNlKHtcbiAgLy8gICAgIGRlZmluaXRpb246IHtcbiAgLy8gICAgICAgdHlwZTogJ2NvbmZpZ21hcHMnLFxuICAvLyAgICAgfSxcbiAgLy8gICAgIG5hbWVzcGFjZWQ6IHRydWUsXG4gIC8vICAgICBuYW1lOiAnbWVzc2FnZS1jb25maWcnLFxuICAvLyAgIH0pXG4gIC8vICAgLnBpcGUoXG4gIC8vICAgICB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kkKSxcbiAgLy8gICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YobnVsbCkpLFxuICAvLyAgICAgbWFwKCgpID0+IHtcbiAgLy8gICAgICAgcmV0dXJuIHRoaXMucHVzaEVuYWJsZWQ7XG4gIC8vICAgICB9KSxcbiAgLy8gICApO1xuICAvLyB3YXRjaE1lc3NhZ2VDb25maWdNYXAkID0gdGhpcy53YXRjaENvbmZpZ01hcCQucGlwZShcbiAgLy8gICBzd2l0Y2hNYXAocmVzID0+XG4gIC8vICAgICB0aGlzLnVzZXJOYW1lJC5waXBlKFxuICAvLyAgICAgICBtYXAoKCkgPT4ge1xuICAvLyAgICAgICAgIHJldHVybiByZXM7XG4gIC8vICAgICAgIH0pLFxuICAvLyAgICAgKSxcbiAgLy8gICApLFxuICAvLyApO1xuXG4gIGxpc3QgPSBuZXcgSzhTUmVzb3VyY2VMaXN0KHtcbiAgICBmZXRjaFBhcmFtcyQ6IG9mKHt9KSwgLy8g5L2/55So56m65Y+C5pWw5ZCm5YiZ6Lev55Sx5Y+C5pWw5Y+Y5YyW5Lya5a+86Ie06YeN5paw6Kem5Y+RIGdldCBsaXN0XG4gICAgZmV0Y2hlcjogdGhpcy5mZXRjaGVyLmJpbmQodGhpcyksXG4gICAgd2F0Y2hlcjogc2VlZCA9PlxuICAgICAgdGhpcy5rOHNBcGlcbiAgICAgICAgLndhdGNoR2xvYmFsUmVzb3VyY2VDaGFuZ2U8TWVzc2FnZT4oc2VlZCwge1xuICAgICAgICAgIGRlZmluaXRpb246IE1FU1NBR0VfQ09ORklHLFxuICAgICAgICB9KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0YXAoaXRlbSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjYWNoZUluZm8gPSB0aGlzLmdldENhY2hlTG9jYWxWYWx1ZShOT1RJRllfSU5GT19UWVBFKTtcbiAgICAgICAgICAgIGNvbnN0IGluZm9WYWx1ZTogc3RyaW5nW10gPSBjYWNoZUluZm8/LnNwbGl0KCcsJykgfHwgW107XG4gICAgICAgICAgICB0aGlzLnJlbW92ZVB1c2goaXRlbSk7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIFtXYXRjaEV2ZW50LkFkZGVkLCBXYXRjaEV2ZW50Lk1vZGlmaWVkXS5pbmNsdWRlcyhpdGVtLnR5cGUpICYmXG4gICAgICAgICAgICAgICFpbmZvVmFsdWUuaW5jbHVkZXModGhpcy5rOHNVdGlsLmdldE5hbWUoaXRlbS5vYmplY3QpKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2hOb3RpZnkoaXRlbS5vYmplY3QpO1xuICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IFsuLi5pbmZvVmFsdWUsIHRoaXMuazhzVXRpbC5nZXROYW1lKGl0ZW0ub2JqZWN0KV07XG4gICAgICAgICAgICAgIHRoaXMuY2FjaGVOb3RpZnlJbmZvKHZhbHVlLmpvaW4oJywnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgcG9sbGluZzogMTBfMDAwLFxuICB9KTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGs4c0FwaTogSzhzQXBpU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGF1dGg6IEF1dGhvcml6YXRpb25TdGF0ZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSByZWFkb25seSBrOHNVdGlsOiBLOHNVdGlsU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5vdGlmaWNhdGlvbjogTm90aWZpY2F0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1lc3NhZ2VzOiBNZXNzYWdlU2VydmljZSxcbiAgKSB7fVxuXG4gIHdhdGNoTm90aWZ5KCkge1xuICAgIHRoaXMudHJpZ2dlck5vdGlmeSQucGlwZSh0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kkKSkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICB0aGlzLm5vdGlmeU1lc3NhZ2UocmVzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldE5vdGlmeUxpc3QoKSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdC5pdGVtcyQucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpLFxuICAgICAgc3dpdGNoTWFwKHJlcyA9PiB0aGlzLnVzZXJOYW1lJC5waXBlKG1hcCgoKSA9PiByZXMpKSksXG4gICAgICBtYXAocmVzID0+IHRoaXMubWVzc2FnZVNvcnQocmVzLCAnZGVzYycpKSxcbiAgICApO1xuICB9XG5cbiAgbWVzc2FnZVNvcnQoZGF0YTogTWVzc2FnZVtdLCB0eXBlOiAnYXNjJyB8ICdkZXNjJyA9ICdhc2MnKSB7XG4gICAgcmV0dXJuIGRhdGEuc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3Qgc3RhcnQgPVxuICAgICAgICB0eXBlID09PSAnYXNjJ1xuICAgICAgICAgID8gYS5tZXRhZGF0YS5jcmVhdGlvblRpbWVzdGFtcFxuICAgICAgICAgIDogYi5tZXRhZGF0YS5jcmVhdGlvblRpbWVzdGFtcDtcbiAgICAgIGNvbnN0IGVuZCA9XG4gICAgICAgIHR5cGUgPT09ICdhc2MnXG4gICAgICAgICAgPyBiLm1ldGFkYXRhLmNyZWF0aW9uVGltZXN0YW1wXG4gICAgICAgICAgOiBhLm1ldGFkYXRhLmNyZWF0aW9uVGltZXN0YW1wO1xuICAgICAgcmV0dXJuIGRhdGVWYWx1ZU9mKHN0YXJ0KSAtIGRhdGVWYWx1ZU9mKGVuZCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGZldGNoZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuazhzQXBpXG4gICAgICAuZ2V0R2xvYmFsUmVzb3VyY2VMaXN0PE1lc3NhZ2U+KHtcbiAgICAgICAgZGVmaW5pdGlvbjogTUVTU0FHRV9DT05GSUcsXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcChyZXMgPT4ge1xuICAgICAgICAgIHRoaXMuaGFuZGxlTm90aWZ5KHJlcy5pdGVtcyk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlTm90aWZ5KGRhdGE6IE1lc3NhZ2VbXSkge1xuICAgIGNvbnN0IGNhY2hlSW5mbyA9IHRoaXMuZ2V0Q2FjaGVMb2NhbFZhbHVlKE5PVElGWV9JTkZPX1RZUEUpO1xuICAgIGNvbnN0IGluZm9WYWx1ZTogc3RyaW5nW10gPSBjYWNoZUluZm8/LnNwbGl0KCcsJykgfHwgW107XG4gICAgY29uc3QgbWVzc2FnZXMgPSB0aGlzLm1lc3NhZ2VTb3J0KGRhdGEsICdkZXNjJykucmVkdWNlKChhY2MsIGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHsgaXNSZXNpZGVudCB9ID0gaXRlbS5zcGVjO1xuICAgICAgaWYgKFxuICAgICAgICBpc1Jlc2lkZW50ICYmXG4gICAgICAgICF0aGlzLmV4cGlyZWQoaXRlbSkgJiZcbiAgICAgICAgIWluZm9WYWx1ZS5pbmNsdWRlcyh0aGlzLms4c1V0aWwuZ2V0TmFtZShpdGVtKSlcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwcmUgPSBhY2MgPyBgJHthY2N9LGAgOiAnJztcbiAgICAgICAgdGhpcy5kaXNwYXRjaE5vdGlmeShpdGVtKTsgLy8g6Kem5Y+R5o+Q56S65raI5oGvXG4gICAgICAgIHJldHVybiBgJHtwcmV9JHt0aGlzLms4c1V0aWwuZ2V0TmFtZShpdGVtKX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCAnJyk7XG4gICAgaWYgKG1lc3NhZ2VzKSB7XG4gICAgICB0aGlzLmNhY2hlTm90aWZ5SW5mbyhtZXNzYWdlcyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjYWNoZU5vdGlmeUluZm8odmFsdWVzOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFkZENhY2hlTG9jYWxWYWx1ZShOT1RJRllfSU5GT19UWVBFLCB2YWx1ZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBkaXNwYXRjaE5vdGlmeShkYXRhOiBNZXNzYWdlKSB7XG4gICAgY29uc3Qgbm90Rml4ZWQgPSB0aGlzLmdldENhY2hlTG9jYWxWYWx1ZShOT1RJRllfTk9UX0ZJWEVEKTtcbiAgICBjb25zdCBwYXNzID0gIW5vdEZpeGVkPy5zcGxpdCgnLCcpPy5pbmNsdWRlcyh0aGlzLms4c1V0aWwuZ2V0TmFtZShkYXRhKSk7XG4gICAgY29uc3QgcHVzaCA9IHRoaXMuZ2V0Q2FjaGVMb2NhbFZhbHVlKE5PVElGWV9QVVNIX1RZUEUpO1xuICAgIGlmIChcbiAgICAgICgoIWRhdGEuc3BlYy5pc1Jlc2lkZW50ICYmIHRoaXMucHVzaEVuYWJsZWQgJiYgcHVzaCkgfHxcbiAgICAgICAgIXRoaXMuZXhwaXJlZChkYXRhKSkgJiZcbiAgICAgIHBhc3NcbiAgICApIHtcbiAgICAgIHRoaXMudHJpZ2dlck5vdGlmeSQubmV4dChkYXRhKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGV4cGlyZWQoaXRlbTogTWVzc2FnZSkge1xuICAgIGNvbnN0IGV4cGlyZWRUaW1lc3RhbXAgPSBpdGVtLnNwZWMuZXhwaXJlZFRpbWVzdGFtcDtcbiAgICBpZiAoIWV4cGlyZWRUaW1lc3RhbXApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoZXhwaXJlZFRpbWVzdGFtcCkudmFsdWVPZigpIDwgRGF0ZS5ub3coKTtcbiAgfVxuXG4gIGdldENhY2hlTG9jYWxWYWx1ZSh0eXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHR5cGUpO1xuICAgIHJldHVybiB2YWx1ZSAmJiBKU09OLnBhcnNlKHZhbHVlKVt0aGlzLnVzZXJOYW1lXTtcbiAgfVxuXG4gIGFkZENhY2hlTG9jYWxWYWx1ZSh0eXBlOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBib29sZWFuKSB7XG4gICAgY29uc3QgcHJlVmFsdWUgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0odHlwZSk7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFxuICAgICAgdHlwZSxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgLi4uKHByZVZhbHVlID8gSlNPTi5wYXJzZShwcmVWYWx1ZSkgOiB7fSksXG4gICAgICAgIFt0aGlzLnVzZXJOYW1lXTogdmFsdWUsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBub3RpZnlNZXNzYWdlKGRhdGE6IE1lc3NhZ2UpIHtcbiAgICBjb25zdCB7IGlzUmVzaWRlbnQsIHN1YmplY3QsIGNvbnRlbnQgfSA9IGRhdGEuc3BlYztcbiAgICBjb25zdCBuYW1lID0gdGhpcy5rOHNVdGlsLmdldE5hbWUoZGF0YSk7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZ2V0TWVzc2FnZVR5cGUoZGF0YSk7XG5cbiAgICBpZiAoaXNSZXNpZGVudCkge1xuICAgICAgY29uc3Qgbm90aWZpY2F0aW9uUmVmID0gdGhpcy5ub3RpZmljYXRpb24uY3JlYXRlKHtcbiAgICAgICAgdHlwZTogdHlwZSB8fCBUeXBlLkluZm8sXG4gICAgICAgIHRpdGxlOiBzdWJqZWN0LFxuICAgICAgICAuLi4odHlwZSA/IHt9IDogeyBjdXN0b21DbGFzczogJ3BsYXRmb3JtLWNsYXNzJyB9KSxcbiAgICAgICAgY29udGVudCxcbiAgICAgICAgLi4uKGlzUmVzaWRlbnQgPyB7IGR1cmF0aW9uOiAwIH0gOiB7fSksXG4gICAgICB9KTtcbiAgICAgIHRoaXMuYXVpTm90aWZpY2F0aW9uTGlzdC5wdXNoKG5vdGlmaWNhdGlvblJlZik7XG4gICAgICBPYmplY3QuYXNzaWduKG5vdGlmaWNhdGlvblJlZi5pbnN0YW5jZSwgeyBkYXRhIH0pO1xuICAgICAgbm90aWZpY2F0aW9uUmVmLmluc3RhbmNlLmFmdGVyQ2xvc2VkLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuY2xvc2VkTm90aWZ5Q2FsbGJhY2soXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGdldChub3RpZmljYXRpb25SZWYuaW5zdGFuY2UsICd3aW5kb3dVbmxvYWQnLCBmYWxzZSksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5tZXNzYWdlcy5jcmVhdGUoe1xuICAgICAgdHlwZTogdHlwZSB8fCBUeXBlLkluZm8sXG4gICAgICBjb250ZW50OiBzdWJqZWN0LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIOWFs+mXremAmuefpTog5omL5Yqo5YWz6Zet5a2Y5YKoIOa3u+WKoOS4jeWGjeWxleekuueKtuaAgeiusOW9lVxuICAgKiDlhbPpl63pobXpnaLjgIHliKDpmaTmtojmga8g5LiN6K6w5b2VXG4gICAqL1xuICBwcml2YXRlIGNsb3NlZE5vdGlmeUNhbGxiYWNrKFxuICAgIGRhdGE6IE1lc3NhZ2UsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHdpbmRvd1VubG9hZDogYm9vbGVhbixcbiAgKSB7XG4gICAgdGhpcy5yZW1vdmVOb3RpZmljYXRpb25MaXN0KG5hbWUpO1xuICAgIGlmICghdGhpcy53aW5kb3dVbmxvYWQgJiYgIXdpbmRvd1VubG9hZCkge1xuICAgICAgdGhpcy5hZGROb3RGaXhlZChkYXRhKTtcbiAgICB9XG4gICAgdGhpcy53aW5kb3dVbmxvYWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDorrDlvZUg5LiN5YaN5bGV56S654q25oCBIOWtmOWCqOWcqCBsb2NhbCBzdG9yYWdlXG4gICAqL1xuICBwcml2YXRlIGFkZE5vdEZpeGVkKGRhdGE6IE1lc3NhZ2UpIHtcbiAgICBpZiAoZGF0YS5zcGVjLmlzUmVzaWRlbnQpIHtcbiAgICAgIGNvbnN0IG5vdEZpeGVkVmFsID0gdGhpcy5nZXRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCk7XG4gICAgICBjb25zdCB2YWx1ZSA9IFtcbiAgICAgICAgLi4uKG5vdEZpeGVkVmFsPy5zcGxpdCgnLCcpIHx8IFtdKSxcbiAgICAgICAgdGhpcy5rOHNVdGlsLmdldE5hbWUoZGF0YSksXG4gICAgICBdO1xuICAgICAgdGhpcy5hZGRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCwgdmFsdWUuam9pbignLCcpKTtcbiAgICB9XG4gICAgdGhpcy53aW5kb3dVbmxvYWQgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiDop6blj5HliKDpmaTmtojmga9cbiAgICogLSDliKDpmaQgbG9jYWwgc3RvcmFnZSBOT1RfRklYRUQg5a2Y5YKo55qE5raI5oGvXG4gICAqIC0g5omL5Yqo6Kem5Y+R5YWz6Zet5bi46am76YCa55+l5by55qGGXG4gICAqL1xuICBwcml2YXRlIHJlbW92ZVB1c2goaXRlbTogV2F0Y2hBUElSZXNwb25zZTxNZXNzYWdlPikge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLms4c1V0aWwuZ2V0TmFtZShpdGVtLm9iamVjdCk7XG4gICAgY29uc3Qgbm90Rml4ZWRWYWwgPVxuICAgICAgdGhpcy5nZXRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCk/LnNwbGl0KCcsJykgfHwgW107XG4gICAgaWYgKFdhdGNoRXZlbnQuRGVsZXRlZCA9PT0gaXRlbS50eXBlKSB7XG4gICAgICB0aGlzLnJlbW92ZU1lc3NhZ2UobmFtZSk7XG4gICAgICB0aGlzLm1hbnVhbENsb3NlTm90aWZ5KG5hbWUpO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBXYXRjaEV2ZW50LkRlbGV0ZWQgPT09IGl0ZW0udHlwZSAmJlxuICAgICAgaXRlbS5vYmplY3Quc3BlYy5pc1Jlc2lkZW50ICYmXG4gICAgICAhbm90Rml4ZWRWYWwuaW5jbHVkZXMobmFtZSlcbiAgICApIHtcbiAgICAgIHRoaXMubWFudWFsQ2xvc2VOb3RpZnkobmFtZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVNZXNzYWdlKG5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IGNhY2hlTm90Rml4ZWQgPVxuICAgICAgdGhpcy5nZXRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCk/LnNwbGl0KCcsJykgfHwgW107XG4gICAgaWYgKGNhY2hlTm90Rml4ZWQubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaW5kZXggPSBjYWNoZU5vdEZpeGVkLmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgIGNhY2hlTm90Rml4ZWQuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgdGhpcy5hZGRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX05PVF9GSVhFRCwgY2FjaGVOb3RGaXhlZC5qb2luKCcsJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgbWFudWFsQ2xvc2VOb3RpZnkobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgbm90aWZ5SW5zdGFuY2UgPSB0aGlzLmF1aU5vdGlmaWNhdGlvbkxpc3QuZmluZChcbiAgICAgIGl0ZW0gPT4gdGhpcy5rOHNVdGlsLmdldE5hbWUoZ2V0KGl0ZW0uaW5zdGFuY2UsICdkYXRhJykpID09PSBuYW1lLFxuICAgICk7XG4gICAgaWYgKG5vdGlmeUluc3RhbmNlKSB7XG4gICAgICB0aGlzLndpbmRvd1VubG9hZCA9IHRydWU7XG4gICAgICBub3RpZnlJbnN0YW5jZS5pbnN0YW5jZS5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTm90aWZpY2F0aW9uTGlzdChuYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLmF1aU5vdGlmaWNhdGlvbkxpc3QgPSB0aGlzLmF1aU5vdGlmaWNhdGlvbkxpc3QuZmlsdGVyKFxuICAgICAgaXRlbSA9PiB0aGlzLms4c1V0aWwuZ2V0TmFtZShnZXQoaXRlbS5pbnN0YW5jZSwgJ2RhdGEnKSkgIT09IG5hbWUsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TWVzc2FnZVR5cGUoZGF0YTogTWVzc2FnZSkge1xuICAgIGNvbnN0IHR5cGUgPSB0aGlzLms4c1V0aWwuZ2V0TGFiZWwoZGF0YSwgJ3R5cGUnKSBhcyBNZXNzYWdlVHlwZTtcbiAgICByZXR1cm4gTk9USUZZX1RZUEVfTUFQW3R5cGVdIGFzIFR5cGU7XG4gIH1cblxuICBwcml2YXRlIHNldHRpbmdEZWZhdWx0UHVzaFN0YXR1cygpIHtcbiAgICBpZiAoIXdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShOT1RJRllfUFVTSF9UWVBFKSkge1xuICAgICAgdGhpcy5hZGRDYWNoZUxvY2FsVmFsdWUoTk9USUZZX1BVU0hfVFlQRSwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgY2xvc2VBbGxOb3RpZmljYXRpb24oKSB7XG4gICAgZm9yIChjb25zdCBub3RpZnkgb2YgdGhpcy5hdWlOb3RpZmljYXRpb25MaXN0KSB7XG4gICAgICAvLyDlsIYgd2luZG93VW5sb2FkIOWtmOWCqCBpbnN0YW5jZSDlnKggYWZ0ZXJDbG9zZWQg6L+b6KGM5Yik5patXG4gICAgICAvLyByZW1vdmUg5byC5q2lIOW+queOr+S4rSB3aW5kb3dVbmxvYWQg5YC85bey5Y+R55Sf5pS55Y+Y5L2G6L+Y5pyq6Kem5Y+RIGFmdGVyQ2xvc2VkIOWbnuiwg1xuICAgICAgT2JqZWN0LmFzc2lnbihub3RpZnkuaW5zdGFuY2UsIHsgd2luZG93VW5sb2FkOiB0cnVlIH0pO1xuICAgICAgbm90aWZ5Lmluc3RhbmNlLmNsb3NlKCk7XG4gICAgfVxuICAgIHRoaXMuYXVpTm90aWZpY2F0aW9uTGlzdCA9IFtdO1xuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICAvLyDph43mlrDliqDovb0gaGVhZGVyIOWFs+mXreaJgOaciemAmuefpe+8jOmHjeaWsOWKoOi9vSBoZWFkZXIg6YeN5paw5by55Ye6XG4gICAgdGhpcy5jbG9zZUFsbE5vdGlmaWNhdGlvbigpO1xuICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShOT1RJRllfSU5GT19UWVBFKTtcbiAgICB0aGlzLm9uRGVzdHJveSQubmV4dCgpO1xuICB9XG59XG4iXX0=