@libs-ui/components-list 0.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/defines/list.define.d.ts +6 -0
- package/esm2022/defines/list.define.mjs +66 -0
- package/esm2022/highlight-key-search/highlight-key-search.directive.mjs +82 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/interfaces/config-item.interface.mjs +2 -0
- package/esm2022/interfaces/data-emit.interface.mjs +3 -0
- package/esm2022/interfaces/function-control-event.interface.mjs +2 -0
- package/esm2022/interfaces/index.mjs +6 -0
- package/esm2022/interfaces/tab.interface.mjs +2 -0
- package/esm2022/interfaces/templates-type.type.mjs +2 -0
- package/esm2022/libs-ui-components-list.mjs +5 -0
- package/esm2022/list.component.mjs +329 -0
- package/esm2022/pipes/call-function-in-template.pipe.mjs +28 -0
- package/esm2022/pipes/check-selected-by-key.pipe.mjs +21 -0
- package/esm2022/templates/templates.component.abstract.mjs +336 -0
- package/esm2022/templates/text/text.component.mjs +233 -0
- package/fesm2022/libs-ui-components-list.mjs +1077 -0
- package/fesm2022/libs-ui-components-list.mjs.map +1 -0
- package/highlight-key-search/highlight-key-search.directive.d.ts +13 -0
- package/index.d.ts +2 -0
- package/interfaces/config-item.interface.d.ts +225 -0
- package/interfaces/data-emit.interface.d.ts +10 -0
- package/interfaces/function-control-event.interface.d.ts +9 -0
- package/interfaces/index.d.ts +5 -0
- package/interfaces/tab.interface.d.ts +4 -0
- package/interfaces/templates-type.type.d.ts +1 -0
- package/list.component.d.ts +93 -0
- package/package.json +25 -0
- package/pipes/call-function-in-template.pipe.d.ts +8 -0
- package/pipes/check-selected-by-key.pipe.d.ts +7 -0
- package/templates/templates.component.abstract.d.ts +93 -0
- package/templates/text/text.component.d.ts +24 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { AsyncPipe, NgClass, NgTemplateOutlet } from '@angular/common';
|
|
3
|
+
import { ChangeDetectionStrategy, Component, signal, viewChild } from '@angular/core';
|
|
4
|
+
import { VirtualScrollerComponent, VirtualScrollerModule } from '@iharbeck/ngx-virtual-scroller';
|
|
5
|
+
import { LibsUiComponentsAvatarComponent } from '@libs-ui/components-avatar';
|
|
6
|
+
import { LibsUiComponentsButtonsButtonComponent } from '@libs-ui/components-buttons-button';
|
|
7
|
+
import { LibsUiComponentsButtonsSortArrowComponent } from '@libs-ui/components-buttons-sort';
|
|
8
|
+
import { LibsUiComponentsPopoverComponent } from '@libs-ui/components-popover';
|
|
9
|
+
import { LibsUiComponentsScrollOverlayDirective } from '@libs-ui/components-scroll-overlay';
|
|
10
|
+
import { LibsUiComponentsSpinnerComponent } from '@libs-ui/components-spinner';
|
|
11
|
+
import { LibsUiComponentsSwitchComponent } from '@libs-ui/components-switch';
|
|
12
|
+
import { cloneDeep, deleteUnicode, escapeHtml, isEmpty, isNil } from '@libs-ui/utils';
|
|
13
|
+
import { TranslateModule } from '@ngx-translate/core';
|
|
14
|
+
import { LibsUiComponentsListHighlightKeySearchDirective } from '../../highlight-key-search/highlight-key-search.directive';
|
|
15
|
+
import { MoLibsSharedPipesCallFunctionInTemplatePipe } from '../../pipes/call-function-in-template.pipe';
|
|
16
|
+
import { LibsUiCheckSelectedByKeyPipe } from '../../pipes/check-selected-by-key.pipe';
|
|
17
|
+
import { LibsUiComponentsListTemplatesComponentAbstract } from '../templates.component.abstract';
|
|
18
|
+
import * as i0 from "@angular/core";
|
|
19
|
+
import * as i1 from "@iharbeck/ngx-virtual-scroller";
|
|
20
|
+
import * as i2 from "@ngx-translate/core";
|
|
21
|
+
export class LibsUiComponentsListTextComponent extends LibsUiComponentsListTemplatesComponentAbstract {
|
|
22
|
+
configTemplateText = signal(undefined);
|
|
23
|
+
virtualScrollerComponent = viewChild(VirtualScrollerComponent);
|
|
24
|
+
ngOnInit() {
|
|
25
|
+
if (isEmpty(this.config()?.configTemplateText)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
super.ngOnInit();
|
|
29
|
+
this.configTemplateText.set(this.config()?.configTemplateText);
|
|
30
|
+
this.fieldKey.set(this.configTemplateText()?.fieldKey ?? this.fieldKeyDefault());
|
|
31
|
+
this.callApiByService();
|
|
32
|
+
}
|
|
33
|
+
handlerScrollBottom() {
|
|
34
|
+
if (this.loadedLastItem()) {
|
|
35
|
+
this.loading.set(false);
|
|
36
|
+
this.outLoading.emit(this.loading());
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (this.loading() || this.loadedLastItem()) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.loading.set(true);
|
|
43
|
+
this.outLoading.emit(this.loading());
|
|
44
|
+
this.callApiByService(false);
|
|
45
|
+
}
|
|
46
|
+
processSearch() {
|
|
47
|
+
if (!this.isSearchOnline()) {
|
|
48
|
+
return this.processData(true);
|
|
49
|
+
}
|
|
50
|
+
this.callApiByService(true);
|
|
51
|
+
}
|
|
52
|
+
handlerClickRelative(e, item) {
|
|
53
|
+
e.stopPropagation();
|
|
54
|
+
if (this.clickExactly()) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.handlerSelectItem(e, item);
|
|
58
|
+
}
|
|
59
|
+
processKeyChangeUnSelect(item) {
|
|
60
|
+
if (isNil(item[this.fieldKey()]) || item[this.fieldKey()] === '' || this.keySelected() !== item[this.fieldKey()]) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.keySelected.set('');
|
|
64
|
+
this.outSelectKey.emit(undefined);
|
|
65
|
+
}
|
|
66
|
+
handlerSelectItem(e, item, action, ignoreDisable = false) {
|
|
67
|
+
if (e instanceof Event) {
|
|
68
|
+
e.stopPropagation();
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
}
|
|
71
|
+
if (item.disable) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (this.disable() && !ignoreDisable) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (typeof e === 'string' && e !== 'click') {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (!item || (this.keysDisableItem() && this.keysDisableItem()?.some(key => key === item[this.fieldKey()]))) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (action) {
|
|
84
|
+
action(item.ref);
|
|
85
|
+
this.items().forEach(item => {
|
|
86
|
+
this.buildValueByConfig(item, this.configTemplateText());
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (this.configTemplateText()?.actionSort) {
|
|
91
|
+
const currentItemSort = this.configTemplateText()?.itemSort;
|
|
92
|
+
const mode = currentItemSort?.fieldSort !== item[this.fieldKey()] ? 'asc' : currentItemSort?.mode === 'desc' ? 'asc' : 'desc';
|
|
93
|
+
const newSort = {
|
|
94
|
+
fieldSort: item[this.fieldKey()],
|
|
95
|
+
mode,
|
|
96
|
+
modeNumber: mode === 'asc' ? 1 : 2,
|
|
97
|
+
reset: () => 0
|
|
98
|
+
};
|
|
99
|
+
this.configTemplateText.update(item => {
|
|
100
|
+
if (!item) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
return { ...item, itemSort: newSort };
|
|
104
|
+
});
|
|
105
|
+
this.outSortSingleSelect.emit(this.configTemplateText()?.itemSort || newSort);
|
|
106
|
+
}
|
|
107
|
+
this.keySelected.set(item[this.fieldKey()]);
|
|
108
|
+
this.outSelectKey.emit({ key: this.keySelected(), item, isClickManual: true });
|
|
109
|
+
}
|
|
110
|
+
handlerSort(itemSort) {
|
|
111
|
+
itemSort.reset = () => 0;
|
|
112
|
+
this.configTemplateText.update(item => {
|
|
113
|
+
if (!item) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
return { ...item, itemSort: itemSort };
|
|
117
|
+
});
|
|
118
|
+
this.outSortSingleSelect.emit(this.configTemplateText()?.itemSort || itemSort);
|
|
119
|
+
}
|
|
120
|
+
processData(replace) {
|
|
121
|
+
const itemByKeySearch = [];
|
|
122
|
+
const keysHidden = this.keysHiddenItem() || [];
|
|
123
|
+
if (replace) {
|
|
124
|
+
this.items.set([]);
|
|
125
|
+
}
|
|
126
|
+
this.store().forEach((item) => {
|
|
127
|
+
const dataStore = cloneDeep(item);
|
|
128
|
+
const key = keysHidden.find(key => dataStore()[this.fieldKey()] === key);
|
|
129
|
+
dataStore.ref = item;
|
|
130
|
+
if (key === undefined) {
|
|
131
|
+
const text = deleteUnicode(this.buildValueByConfig(dataStore, this.configTemplateText())).toLocaleLowerCase();
|
|
132
|
+
const textEscape = escapeHtml(text);
|
|
133
|
+
const keySearch = deleteUnicode(escapeHtml(this.keySearch().toLocaleLowerCase()));
|
|
134
|
+
if (((this.isSearchOnline() && this.config()?.httpRequestData?.serviceName && this.config()?.httpRequestData?.serviceName !== 'commonDataStaticService' && !this.config()?.httpRequestData?.serviceOther) ||
|
|
135
|
+
(text && (text.includes(keySearch) || textEscape.includes(keySearch)))) && (replace || (!replace && !this.items().find(dataItem => dataItem[this.fieldKey()] === dataStore[this.fieldKey()]))) && !itemByKeySearch.find(dataItem => dataItem[this.fieldKey()] === dataStore[this.fieldKey()])) {
|
|
136
|
+
dataStore.hrefButton = this.configTemplateText()?.getHrefButton?.(dataStore);
|
|
137
|
+
dataStore.classItem = item.classItem || this.configTemplateText()?.getClassItem?.(dataStore);
|
|
138
|
+
dataStore.classInclude = dataStore.classInclude || this.configTemplateText()?.getClassIncludePopover?.(dataStore);
|
|
139
|
+
dataStore.buttonLeftConfig = this.configTemplateText()?.getConfigButtonLeft?.(dataStore);
|
|
140
|
+
dataStore.classIconLeft = dataStore.classIconLeft || this.configTemplateText()?.getClassIconLeft?.(dataStore);
|
|
141
|
+
dataStore.hoverDanger = dataStore.hoverDanger || this.configTemplateText()?.getConfigHoverDanger?.(dataStore);
|
|
142
|
+
dataStore.avatarConfig = this.configTemplateText()?.getAvatarConfig?.(dataStore);
|
|
143
|
+
dataStore.itemAlignStart = dataStore.itemAlignStart || this.configTemplateText()?.getConfigAlignStart?.(dataStore);
|
|
144
|
+
itemByKeySearch.push(dataStore);
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const indexItemRemove = this.items().findIndex(item => item[this.fieldKey()] === key);
|
|
149
|
+
if (indexItemRemove > -1) {
|
|
150
|
+
this.items().splice(indexItemRemove, 1);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const checkLoadItem = (preStateHasScroll, currentHasScroll) => {
|
|
154
|
+
if (this.keysHiddenItem()?.length && preStateHasScroll && !currentHasScroll && (this.isSearchOnline())) {
|
|
155
|
+
this.callApiByService(false);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
if (replace) {
|
|
159
|
+
this.items.set(itemByKeySearch);
|
|
160
|
+
this.config()?.sort?.(this.items());
|
|
161
|
+
this.emitKeySelectedDefaultIfExistItem(this.items());
|
|
162
|
+
this.autoSelectFirstItem(this.items());
|
|
163
|
+
this.setHeightViewPort();
|
|
164
|
+
this.loading.set(false);
|
|
165
|
+
this.checkViewPortScroll(checkLoadItem);
|
|
166
|
+
this.scrollToItemSelected();
|
|
167
|
+
this.outLoading.emit(this.loading());
|
|
168
|
+
this.outLoadItemsComplete.emit({ items: this.items(), paging: this.pagingStore() });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
this.items.update(items => [...items, ...itemByKeySearch]);
|
|
172
|
+
this.config()?.sort?.(this.items());
|
|
173
|
+
this.setHeightViewPort();
|
|
174
|
+
this.loading.set(false);
|
|
175
|
+
this.checkViewPortScroll(checkLoadItem);
|
|
176
|
+
this.scrollToItemSelected();
|
|
177
|
+
this.outLoading.emit(this.loading());
|
|
178
|
+
this.outLoadItemsComplete.emit({ items: this.items(), paging: this.pagingStore() });
|
|
179
|
+
}
|
|
180
|
+
scrollToItemSelected() {
|
|
181
|
+
if (!this.configTemplateText()?.autoScrollToItemSelected) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
clearTimeout(this.timeAutoScrollItemSelected());
|
|
185
|
+
this.timeAutoScrollItemSelected.set(setTimeout(() => {
|
|
186
|
+
if (!this.keySelected()) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const index = this.items().findIndex(item => item[this.fieldKey()] === this.keySelected);
|
|
190
|
+
if (index !== -1) {
|
|
191
|
+
this.virtualScrollerComponent()?.scrollToIndex(index);
|
|
192
|
+
}
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
autoSelectFirstItem(items) {
|
|
196
|
+
if (this.keySelected() || !this.config()?.autoSelectFirstItem || !items || !items.length) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.handlerSelectItem('click', items[0], undefined, true);
|
|
200
|
+
}
|
|
201
|
+
emitKeySelectedDefaultIfExistItem(items) {
|
|
202
|
+
const item = items.find(store => store[this.fieldKey()] === this.keySelected);
|
|
203
|
+
if (item) {
|
|
204
|
+
this.handlerSelectItem('click', item, undefined, true);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
getLengthItem() {
|
|
208
|
+
return this.items().length;
|
|
209
|
+
}
|
|
210
|
+
handlerImageError(event, item) {
|
|
211
|
+
event.stopPropagation();
|
|
212
|
+
item.specific_loadImgError = true;
|
|
213
|
+
}
|
|
214
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsListTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
215
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsListTextComponent, isStandalone: true, selector: "libs_ui-components-list-templates_text", viewQueries: [{ propertyName: "virtualScrollerComponent", first: true, predicate: VirtualScrollerComponent, descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "@if (configTemplateText(); as configTemplateText) {\n <div class=\"relative h-full w-full\">\n @if (items() && items().length) {\n <div #elementScroll\n [style.height]=\"!configTemplateText.notUseVirtualScroll && heightViewPort() && (!config()?.ignoreShowDataWhenNotSearch || (config()?.ignoreShowDataWhenNotSearch && config()?.ignoreFixHeightShowDataWhenNotSearch)) ? heightViewPort()+'px':'100%'\"\n class=\"w-full\"\n LibsUiComponentsScrollOverlayDirective\n (outScrollBottom)=\"handlerScrollBottom()\">\n @if (!configTemplateText.notUseVirtualScroll) {\n <virtual-scroller #scroll\n [parentScroll]=\"elementScroll\"\n [items]=\"items()\"\n class=\"h-full\">\n <ng-container *ngTemplateOutlet='listRef;context:{itemsView:scroll.viewPortItems}' />\n </virtual-scroller>\n }\n @if (configTemplateText.notUseVirtualScroll) {\n <ng-container *ngTemplateOutlet='listRef;context:{itemsView:items()}' />\n }\n </div>\n }\n @if ((!items() || !items().length) && (!config()?.ignoreShowDataWhenNotSearch || keySearch())) {\n <div [class]=\"'libs-ui-font-h5r text-[#9ca2ad] '+ (config()?.textNoDataClassInclude ?? 'py-[6px] px-[16px]')\">\n @if (!keySearch() && !loading()) {\n {{ (config()?.textNoData ?? 'i18n_have_no_selection') | translate }}\n }\n @if (templateRefSearchNoData() && keySearch() && !loading()) {\n <ng-container *ngTemplateOutlet=\"templateRefSearchNoData() || null;context:{keySearch:keySearch()}\"></ng-container>\n }\n @if (!templateRefSearchNoData() && keySearch() && !loading()) {\n {{ (config()?.textSearchNoData ?? 'i18n_no_result') | translate }}\n }\n @if (loading()) {\n \n }\n </div>\n }\n @if (loading()) {\n <libs_ui-components-spinner [size]=\"loadingIconSize() || 'medium'\" />\n }\n </div>\n <ng-template #listRef\n let-itemsView='itemsView'>\n @for (item of itemsView; track item[fieldKey()]) {\n <div #itemRef\n [class]=\"item.classItemWrapper || ''\">\n <div LibsUiComponentsListHighlightKeySearchDirective\n [isHighlight]=\"config()?.highlightTextSearchInResult\"\n [keySearch]=\"keySearch()\"\n [class]=\"'libs-ui-list-template-text-item flex '+(item.classItem || '')\"\n [class.items-center]=\"!item.itemAlignStart\"\n [class.items-start]=\"item.itemAlignStart\"\n [class.libs-ui-bg-list-hover-danger]=\"!clickExactly() && item.hoverDanger\"\n [class.libs-ui-bg-list-hover]=\"!clickExactly() && !item.hoverDanger\"\n [class.libs-ui-bg-list-selected]=\"!clickExactly() && keySelected() === item[fieldKey()]\"\n [class.pl-[16px]]=\"paddingLeftItem()\"\n [class.bg-[#ffffff]]=\"clickExactly()\"\n [class.libs-ui-bg-list-hover-ffffff]=\"item.disable\"\n [class.cursor-default]=\"item.disable\"\n [class.py-[2px]]=\"clickExactly()\"\n [class.pr-[48px]]=\"keySelected() === item[fieldKey()] && (!configTemplateText?.ignoreIconSelected || configTemplateText?.actionSort)&& !configTemplateText?.stylePaddingRightItemOther\"\n [ngClass]=\"{'pointer-events-none libs-ui-disable':loading() || disable() || ((item[fieldKey()] | LibsUiCheckSelectedByKeyPipe:keysDisableItem():keysDisableItem()?.length) && !ignoreClassDisableDefaultWhenUseKeysDisableItem())}\"\n (click)=\"handlerClickRelative($event,item)\">\n @if (item.bullet) {\n <span class=\"libs-ui-list-template-text-item-bullet flex flex-shrink-0\"\n [style.background-color]=\"item.bullet.backgroundColor\"\n (click)=\"handlerSelectItem($event,item)\">\n </span>\n }\n\n @if (item.avatarConfig; as avatarConfig) {\n <libs_ui-components-avatar [typeShape]=\"avatarConfig.typeShape || 'circle'\"\n [classInclude]=\"avatarConfig.classInclude\"\n [classImageInclude]=\"avatarConfig.classImageInclude\"\n [size]='avatarConfig.size || 32'\n [linkAvatar]=\"avatarConfig.linkAvatar\"\n [linkAvatarError]=\"avatarConfig.linkAvatarError\"\n [idGenColor]=\"avatarConfig.idGenColor\"\n [textAvatar]=\"avatarConfig.textAvatar\"\n [classImageInclude]=\"avatarConfig.classImageInclude\" />\n }\n @if (configTemplateText.getImage || configTemplateText.fieldGetImage) {\n <img\n [src]=\"configTemplateText.getImage ? (('avatar' | MoLibsSharedPipesCallFunctionInTemplate:(item.specific_loadImgError && configTemplateText.getImageError ? configTemplateText.getImageError : configTemplateText.getImage):item) | async) : item[configTemplateText.fieldGetImage || '']\"\n [class]=\"'libs-ui-list-template-text-item-avatar ' + (configTemplateText.classIncludeImage ?? '')\"\n [class.w-[18px]]=\"configTemplateText.imgTypeIcon\"\n [class.h-[18px]]=\"configTemplateText.imgTypeIcon\"\n (error)=\"handlerImageError($event, item)\"\n (click)=\"handlerSelectItem($event,item)\" />\n }\n @if (item.buttonLeftConfig; as buttonLeft) {\n @if (item.hrefButton) {\n <a [class.w-full]=\"!buttonLeft.ignoreWidth100\"\n [href]=\"item.hrefButton\">\n <ng-container *ngTemplateOutlet=\"buttonLeftTemplate\"></ng-container>\n </a>\n }\n @if (!item.hrefButton) {\n <div [class.w-full]=\"!buttonLeft.ignoreWidth100\">\n <ng-container *ngTemplateOutlet=\"buttonLeftTemplate\"></ng-container>\n </div>\n }\n <ng-template #buttonLeftTemplate>\n <libs_ui-components-buttons-button class=\"w-full\"\n [type]=\"buttonLeft.type || 'button-link-primary'\"\n [label]=\"buttonLeft.label || ' '\"\n [zIndex]=\"buttonLeft.zIndex\"\n [disable]=\"buttonLeft.disable\"\n [classIconLeft]=\"buttonLeft.classIconLeft ? ((buttonLeft.classIconLeft || '')+' flex mr-[8px] text-[12px]') : ''\"\n [classInclude]=\"(buttonLeft.classInclude|| '')+' w-full'\"\n [classLabel]=\"(buttonLeft.classLabel ?? 'libs-ui-font-h4r')\"\n [ignoreStopPropagationEvent]=\"buttonLeft.ignoreStopPropagationEvent\"\n [styleIconLeft]=\"buttonLeft.styleIconLeft\"\n [styleButton]=\"buttonLeft.styleButton\"\n (moClick)=\"handlerSelectItem($event,item)\" />\n </ng-template>\n }\n @if (item.switchConfig) {\n <libs_ui-components-switch [active]=\"item.switchConfig.active\"\n (moSwitch)=\"handlerSelectItem('click',item)\" />\n }\n @if (item.classIconLeft) {\n <i [class]=\"item.classIconLeft + ' mr-[8px] text-[14px]'\"></i>\n }\n @if (!item.ignoreShowFieldLabel && !configTemplateText.rows) {\n <libs_ui-components-popover [type]=\"item.popoverLabel?.type || 'text'\"\n [elementRefCustom]=\"item.popoverLabel?.type === 'text'? undefined:itemRef\"\n [ignoreShowPopover]=\"item.popoverLabel?.ignoreShowPopover\"\n [config]=\"item.popoverLabel?.config || (configTemplateText.configLabelPopover || {})\"\n [innerHtml]=\"item.fieldLabel\"\n [classInclude]=\"item.classInclude\"\n (moEvent)=\"handlerSelectItem($event,item)\" />\n }\n @if (!item.ignoreShowFieldLabel && !configTemplateText.rows) {\n <libs_ui-components-popover [type]=\"item.popoverLabel?.type || 'text'\"\n [elementRefCustom]=\"item.popoverLabel?.type === 'text'? undefined:itemRef\"\n [ignoreShowPopover]=\"item.popoverLabel?.ignoreShowPopover\"\n [config]=\"item.popoverLabel?.config || ((configTemplateText.configLabelPopover || {}))\"\n [innerHtml]=\"item.fieldLabel\"\n [classInclude]=\"item.classInclude\"\n (moEvent)=\"handlerSelectItem($event,item)\" />\n }\n @if (item.fieldPopover; as popover) {\n <libs_ui-components-popover class=\"{{ popover.classInclude || '' }}\"\n [config]=\"popover?.config\">\n @if (!popover.dataView) {\n <i class=\"libs-ui-icon-tooltip-outline\"></i>\n }\n @if (popover.dataView) {\n <div [innerHtml]=\"popover.dataView | translate\"></div>\n }\n </libs_ui-components-popover>\n }\n <!-- <libs-uis-shared-components-list_view-templates-rows *ngIf=\"configTemplateText?.rows\"\n class=\"w-100 {{ configTemplateText.classRowsWrapper || configTemplateText.classRows || '' }}\"\n [item]=\"item\"\n [fieldKey]=\"fieldKey\"\n [keySelected]=\"keySelected\"\n [configTemplate]=\"configTemplateText\"\n [zIndex]=\"zIndex\"\n (moChangStageFlagMouseTooltip)=\"handlerChangStageFlagMouse($event)\"\n (moEvent)=\"handlerSelectItem($event.event,$event.item,$event.action)\">\n </libs-uis-shared-components-list_view-templates-rows> -->\n @if ((keySelected === item[fieldKey()] || (item[fieldKey()] | LibsUiCheckSelectedByKeyPipe:multiKeySelected():multiKeySelected()?.length) ? item[fieldKey()] : undefined) && !configTemplateText.ignoreIconSelected && !configTemplateText.actionSort) {\n <i [class]=\"'libs-ui-icon-check '+(configTemplateText.classIncludeIconSelected || 'right-[12px]')\">\n </i>\n }\n @if (keySelected() === item[fieldKey()] && configTemplateText.actionSort) {\n <div class=\"libs-ui-list-template-text-sort\">\n <libs_ui-components-buttons-sort-arrow [disable]=\"loading() || disable() || false\"\n [mode]=\"configTemplateText.itemSort?.mode || ''\"\n [fieldSort]=\"item[fieldKey()]\"\n (outChange)=\"handlerSort($event)\" />\n </div>\n }\n </div>\n </div>\n }\n </ng-template>\n}\n", styles: [".libs-ui-list-template-text-item{padding:6px 16px 6px 1px;font-size:12px;line-height:18px;position:relative;cursor:pointer}.libs-ui-list-template-text-item>.libs-ui-icon-check,.libs-ui-list-template-text-item .libs-ui-list-template-text-sort{position:absolute;right:16px}.libs-ui-list-template-text-item>.libs-ui-icon-check:before,.libs-ui-list-template-text-item .libs-ui-list-template-text-sort:before{font-size:16px;color:var(--libs-ui-color-default, #226FF5)}.libs-ui-list-template-text-item-bullet{width:10px;height:10px;border-radius:50%;margin-right:8px;cursor:pointer}.libs-ui-list-template-text-item-avatar{width:24px;height:24px;border-radius:50%;margin-right:8px;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: VirtualScrollerModule }, { kind: "component", type: i1.VirtualScrollerComponent, selector: "virtual-scroller,[virtualScroller]", inputs: ["executeRefreshOutsideAngularZone", "enableUnequalChildrenSizes", "RTL", "useMarginInsteadOfTranslate", "modifyOverflowStyleOfParentScroll", "stripedTable", "scrollbarWidth", "scrollbarHeight", "childWidth", "childHeight", "ssrChildWidth", "ssrChildHeight", "ssrViewportWidth", "ssrViewportHeight", "bufferAmount", "scrollAnimationTime", "resizeBypassRefreshThreshold", "scrollThrottlingTime", "scrollDebounceTime", "checkResizeInterval", "items", "compareItems", "horizontal", "parentScroll"], outputs: ["vsUpdate", "vsChange", "vsStart", "vsEnd"], exportAs: ["virtualScroller"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "component", type: LibsUiComponentsSpinnerComponent, selector: "libs_ui-components-spinner", inputs: ["type", "size"] }, { kind: "component", type: LibsUiComponentsAvatarComponent, selector: "libs_ui-components-avatar", inputs: ["typeShape", "classInclude", "size", "linkAvatar", "linkAvatarError", "idGenColor", "textAvatar", "classImageInclude"], outputs: ["outAvatarError"] }, { kind: "component", type: LibsUiComponentsButtonsButtonComponent, selector: "libs_ui-components-buttons-button", inputs: ["flagMouse", "type", "buttonCustom", "sizeButton", "label", "disable", "isPending", "imageLeft", "classInclude", "classIconLeft", "classIconRight", "classLabel", "iconOnlyType", "popover", "ignoreStopPropagationEvent", "zIndex", "widthLabelPopover", "styleIconLeft", "styleButton", "ignoreFocusWhenInputTab", "ignoreSetClickWhenShowPopover", "ignorePointerEvent", "isActive"], outputs: ["outClick", "outPopoverEvent", "outFunctionsControl"] }, { kind: "component", type: LibsUiComponentsPopoverComponent, selector: "libs_ui-components-popover,[LibsUiComponentsPopoverDirective]", inputs: ["flagMouse", "type", "mode", "config", "ignoreShowPopover", "elementRefCustom", "classInclude", "ignoreHiddenPopoverContentWhenMouseLeave", "ignoreStopPropagationEvent", "ignoreCursorPointerModeLikeClick", "isAddContentToParentDocument", "ignoreClickOutside"], outputs: ["outEvent", "outChangStageFlagMouse", "outEventPopoverContent", "outFunctionsControl"] }, { kind: "directive", type: LibsUiComponentsScrollOverlayDirective, selector: "[LibsUiComponentsScrollOverlayDirective]", inputs: ["classContainer", "options"], outputs: ["outScroll", "outScrollX", "outScrollY", "outScrollTop", "outScrollBottom"] }, { kind: "pipe", type: LibsUiCheckSelectedByKeyPipe, name: "LibsUiCheckSelectedByKeyPipe" }, { kind: "component", type: LibsUiComponentsSwitchComponent, selector: "libs_ui-components-switch", inputs: ["size", "disable", "active"], outputs: ["activeChange", "outSwitch"] }, { kind: "component", type: LibsUiComponentsButtonsSortArrowComponent, selector: "libs_ui-components-buttons-sort-arrow", inputs: ["size", "mode", "fieldSort", "disable", "ignorePopoverContent", "popoverContentAsc", "popoverContentDesc", "defaultMode", "zIndex"], outputs: ["modeChange", "outChange"] }, { kind: "pipe", type: MoLibsSharedPipesCallFunctionInTemplatePipe, name: "MoLibsSharedPipesCallFunctionInTemplate" }, { kind: "directive", type: LibsUiComponentsListHighlightKeySearchDirective, selector: "[LibsUiComponentsListHighlightKeySearchDirective]", inputs: ["isHighlight", "keySearch", "classHighlight"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
216
|
+
}
|
|
217
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsListTextComponent, decorators: [{
|
|
218
|
+
type: Component,
|
|
219
|
+
args: [{ selector: 'libs_ui-components-list-templates_text', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
220
|
+
VirtualScrollerModule, NgTemplateOutlet, TranslateModule, NgClass, AsyncPipe,
|
|
221
|
+
LibsUiComponentsSpinnerComponent,
|
|
222
|
+
LibsUiComponentsAvatarComponent,
|
|
223
|
+
LibsUiComponentsButtonsButtonComponent,
|
|
224
|
+
LibsUiComponentsPopoverComponent,
|
|
225
|
+
LibsUiComponentsScrollOverlayDirective,
|
|
226
|
+
LibsUiCheckSelectedByKeyPipe,
|
|
227
|
+
LibsUiComponentsSwitchComponent,
|
|
228
|
+
LibsUiComponentsButtonsSortArrowComponent,
|
|
229
|
+
MoLibsSharedPipesCallFunctionInTemplatePipe,
|
|
230
|
+
LibsUiComponentsListHighlightKeySearchDirective
|
|
231
|
+
], template: "@if (configTemplateText(); as configTemplateText) {\n <div class=\"relative h-full w-full\">\n @if (items() && items().length) {\n <div #elementScroll\n [style.height]=\"!configTemplateText.notUseVirtualScroll && heightViewPort() && (!config()?.ignoreShowDataWhenNotSearch || (config()?.ignoreShowDataWhenNotSearch && config()?.ignoreFixHeightShowDataWhenNotSearch)) ? heightViewPort()+'px':'100%'\"\n class=\"w-full\"\n LibsUiComponentsScrollOverlayDirective\n (outScrollBottom)=\"handlerScrollBottom()\">\n @if (!configTemplateText.notUseVirtualScroll) {\n <virtual-scroller #scroll\n [parentScroll]=\"elementScroll\"\n [items]=\"items()\"\n class=\"h-full\">\n <ng-container *ngTemplateOutlet='listRef;context:{itemsView:scroll.viewPortItems}' />\n </virtual-scroller>\n }\n @if (configTemplateText.notUseVirtualScroll) {\n <ng-container *ngTemplateOutlet='listRef;context:{itemsView:items()}' />\n }\n </div>\n }\n @if ((!items() || !items().length) && (!config()?.ignoreShowDataWhenNotSearch || keySearch())) {\n <div [class]=\"'libs-ui-font-h5r text-[#9ca2ad] '+ (config()?.textNoDataClassInclude ?? 'py-[6px] px-[16px]')\">\n @if (!keySearch() && !loading()) {\n {{ (config()?.textNoData ?? 'i18n_have_no_selection') | translate }}\n }\n @if (templateRefSearchNoData() && keySearch() && !loading()) {\n <ng-container *ngTemplateOutlet=\"templateRefSearchNoData() || null;context:{keySearch:keySearch()}\"></ng-container>\n }\n @if (!templateRefSearchNoData() && keySearch() && !loading()) {\n {{ (config()?.textSearchNoData ?? 'i18n_no_result') | translate }}\n }\n @if (loading()) {\n \n }\n </div>\n }\n @if (loading()) {\n <libs_ui-components-spinner [size]=\"loadingIconSize() || 'medium'\" />\n }\n </div>\n <ng-template #listRef\n let-itemsView='itemsView'>\n @for (item of itemsView; track item[fieldKey()]) {\n <div #itemRef\n [class]=\"item.classItemWrapper || ''\">\n <div LibsUiComponentsListHighlightKeySearchDirective\n [isHighlight]=\"config()?.highlightTextSearchInResult\"\n [keySearch]=\"keySearch()\"\n [class]=\"'libs-ui-list-template-text-item flex '+(item.classItem || '')\"\n [class.items-center]=\"!item.itemAlignStart\"\n [class.items-start]=\"item.itemAlignStart\"\n [class.libs-ui-bg-list-hover-danger]=\"!clickExactly() && item.hoverDanger\"\n [class.libs-ui-bg-list-hover]=\"!clickExactly() && !item.hoverDanger\"\n [class.libs-ui-bg-list-selected]=\"!clickExactly() && keySelected() === item[fieldKey()]\"\n [class.pl-[16px]]=\"paddingLeftItem()\"\n [class.bg-[#ffffff]]=\"clickExactly()\"\n [class.libs-ui-bg-list-hover-ffffff]=\"item.disable\"\n [class.cursor-default]=\"item.disable\"\n [class.py-[2px]]=\"clickExactly()\"\n [class.pr-[48px]]=\"keySelected() === item[fieldKey()] && (!configTemplateText?.ignoreIconSelected || configTemplateText?.actionSort)&& !configTemplateText?.stylePaddingRightItemOther\"\n [ngClass]=\"{'pointer-events-none libs-ui-disable':loading() || disable() || ((item[fieldKey()] | LibsUiCheckSelectedByKeyPipe:keysDisableItem():keysDisableItem()?.length) && !ignoreClassDisableDefaultWhenUseKeysDisableItem())}\"\n (click)=\"handlerClickRelative($event,item)\">\n @if (item.bullet) {\n <span class=\"libs-ui-list-template-text-item-bullet flex flex-shrink-0\"\n [style.background-color]=\"item.bullet.backgroundColor\"\n (click)=\"handlerSelectItem($event,item)\">\n </span>\n }\n\n @if (item.avatarConfig; as avatarConfig) {\n <libs_ui-components-avatar [typeShape]=\"avatarConfig.typeShape || 'circle'\"\n [classInclude]=\"avatarConfig.classInclude\"\n [classImageInclude]=\"avatarConfig.classImageInclude\"\n [size]='avatarConfig.size || 32'\n [linkAvatar]=\"avatarConfig.linkAvatar\"\n [linkAvatarError]=\"avatarConfig.linkAvatarError\"\n [idGenColor]=\"avatarConfig.idGenColor\"\n [textAvatar]=\"avatarConfig.textAvatar\"\n [classImageInclude]=\"avatarConfig.classImageInclude\" />\n }\n @if (configTemplateText.getImage || configTemplateText.fieldGetImage) {\n <img\n [src]=\"configTemplateText.getImage ? (('avatar' | MoLibsSharedPipesCallFunctionInTemplate:(item.specific_loadImgError && configTemplateText.getImageError ? configTemplateText.getImageError : configTemplateText.getImage):item) | async) : item[configTemplateText.fieldGetImage || '']\"\n [class]=\"'libs-ui-list-template-text-item-avatar ' + (configTemplateText.classIncludeImage ?? '')\"\n [class.w-[18px]]=\"configTemplateText.imgTypeIcon\"\n [class.h-[18px]]=\"configTemplateText.imgTypeIcon\"\n (error)=\"handlerImageError($event, item)\"\n (click)=\"handlerSelectItem($event,item)\" />\n }\n @if (item.buttonLeftConfig; as buttonLeft) {\n @if (item.hrefButton) {\n <a [class.w-full]=\"!buttonLeft.ignoreWidth100\"\n [href]=\"item.hrefButton\">\n <ng-container *ngTemplateOutlet=\"buttonLeftTemplate\"></ng-container>\n </a>\n }\n @if (!item.hrefButton) {\n <div [class.w-full]=\"!buttonLeft.ignoreWidth100\">\n <ng-container *ngTemplateOutlet=\"buttonLeftTemplate\"></ng-container>\n </div>\n }\n <ng-template #buttonLeftTemplate>\n <libs_ui-components-buttons-button class=\"w-full\"\n [type]=\"buttonLeft.type || 'button-link-primary'\"\n [label]=\"buttonLeft.label || ' '\"\n [zIndex]=\"buttonLeft.zIndex\"\n [disable]=\"buttonLeft.disable\"\n [classIconLeft]=\"buttonLeft.classIconLeft ? ((buttonLeft.classIconLeft || '')+' flex mr-[8px] text-[12px]') : ''\"\n [classInclude]=\"(buttonLeft.classInclude|| '')+' w-full'\"\n [classLabel]=\"(buttonLeft.classLabel ?? 'libs-ui-font-h4r')\"\n [ignoreStopPropagationEvent]=\"buttonLeft.ignoreStopPropagationEvent\"\n [styleIconLeft]=\"buttonLeft.styleIconLeft\"\n [styleButton]=\"buttonLeft.styleButton\"\n (moClick)=\"handlerSelectItem($event,item)\" />\n </ng-template>\n }\n @if (item.switchConfig) {\n <libs_ui-components-switch [active]=\"item.switchConfig.active\"\n (moSwitch)=\"handlerSelectItem('click',item)\" />\n }\n @if (item.classIconLeft) {\n <i [class]=\"item.classIconLeft + ' mr-[8px] text-[14px]'\"></i>\n }\n @if (!item.ignoreShowFieldLabel && !configTemplateText.rows) {\n <libs_ui-components-popover [type]=\"item.popoverLabel?.type || 'text'\"\n [elementRefCustom]=\"item.popoverLabel?.type === 'text'? undefined:itemRef\"\n [ignoreShowPopover]=\"item.popoverLabel?.ignoreShowPopover\"\n [config]=\"item.popoverLabel?.config || (configTemplateText.configLabelPopover || {})\"\n [innerHtml]=\"item.fieldLabel\"\n [classInclude]=\"item.classInclude\"\n (moEvent)=\"handlerSelectItem($event,item)\" />\n }\n @if (!item.ignoreShowFieldLabel && !configTemplateText.rows) {\n <libs_ui-components-popover [type]=\"item.popoverLabel?.type || 'text'\"\n [elementRefCustom]=\"item.popoverLabel?.type === 'text'? undefined:itemRef\"\n [ignoreShowPopover]=\"item.popoverLabel?.ignoreShowPopover\"\n [config]=\"item.popoverLabel?.config || ((configTemplateText.configLabelPopover || {}))\"\n [innerHtml]=\"item.fieldLabel\"\n [classInclude]=\"item.classInclude\"\n (moEvent)=\"handlerSelectItem($event,item)\" />\n }\n @if (item.fieldPopover; as popover) {\n <libs_ui-components-popover class=\"{{ popover.classInclude || '' }}\"\n [config]=\"popover?.config\">\n @if (!popover.dataView) {\n <i class=\"libs-ui-icon-tooltip-outline\"></i>\n }\n @if (popover.dataView) {\n <div [innerHtml]=\"popover.dataView | translate\"></div>\n }\n </libs_ui-components-popover>\n }\n <!-- <libs-uis-shared-components-list_view-templates-rows *ngIf=\"configTemplateText?.rows\"\n class=\"w-100 {{ configTemplateText.classRowsWrapper || configTemplateText.classRows || '' }}\"\n [item]=\"item\"\n [fieldKey]=\"fieldKey\"\n [keySelected]=\"keySelected\"\n [configTemplate]=\"configTemplateText\"\n [zIndex]=\"zIndex\"\n (moChangStageFlagMouseTooltip)=\"handlerChangStageFlagMouse($event)\"\n (moEvent)=\"handlerSelectItem($event.event,$event.item,$event.action)\">\n </libs-uis-shared-components-list_view-templates-rows> -->\n @if ((keySelected === item[fieldKey()] || (item[fieldKey()] | LibsUiCheckSelectedByKeyPipe:multiKeySelected():multiKeySelected()?.length) ? item[fieldKey()] : undefined) && !configTemplateText.ignoreIconSelected && !configTemplateText.actionSort) {\n <i [class]=\"'libs-ui-icon-check '+(configTemplateText.classIncludeIconSelected || 'right-[12px]')\">\n </i>\n }\n @if (keySelected() === item[fieldKey()] && configTemplateText.actionSort) {\n <div class=\"libs-ui-list-template-text-sort\">\n <libs_ui-components-buttons-sort-arrow [disable]=\"loading() || disable() || false\"\n [mode]=\"configTemplateText.itemSort?.mode || ''\"\n [fieldSort]=\"item[fieldKey()]\"\n (outChange)=\"handlerSort($event)\" />\n </div>\n }\n </div>\n </div>\n }\n </ng-template>\n}\n", styles: [".libs-ui-list-template-text-item{padding:6px 16px 6px 1px;font-size:12px;line-height:18px;position:relative;cursor:pointer}.libs-ui-list-template-text-item>.libs-ui-icon-check,.libs-ui-list-template-text-item .libs-ui-list-template-text-sort{position:absolute;right:16px}.libs-ui-list-template-text-item>.libs-ui-icon-check:before,.libs-ui-list-template-text-item .libs-ui-list-template-text-sort:before{font-size:16px;color:var(--libs-ui-color-default, #226FF5)}.libs-ui-list-template-text-item-bullet{width:10px;height:10px;border-radius:50%;margin-right:8px;cursor:pointer}.libs-ui-list-template-text-item-avatar{width:24px;height:24px;border-radius:50%;margin-right:8px;cursor:pointer}\n"] }]
|
|
232
|
+
}] });
|
|
233
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvbGlzdC9zcmMvdGVtcGxhdGVzL3RleHQvdGV4dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvbGlzdC9zcmMvdGVtcGxhdGVzL3RleHQvdGV4dC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFVLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakcsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0UsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDNUYsT0FBTyxFQUFTLHlDQUF5QyxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDcEcsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0UsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDNUYsT0FBTyxFQUFFLGdDQUFnQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0UsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJB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QUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUM7SUFDN0IsQ0FBQztJQUVTLGlCQUFpQixDQUFDLEtBQVksRUFBRSxJQUFTO1FBQ2pELEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO0lBQ3BDLENBQUM7d0dBL05VLGlDQUFpQzs0RkFBakMsaUNBQWlDLDRKQUVvQyx3QkFBd0IsdUZDMUMxRyxrb1VBb0xBLDR1QkR6SkkscUJBQXFCLHV0QkFBRSxnQkFBZ0IsbUpBQUUsZUFBZSw0RkFBRSxPQUFPLCtFQUFFLFNBQVMsOENBQzVFLGdDQUFnQyxpR0FDaEMsK0JBQStCLG9PQUMvQixzQ0FBc0MsaWhCQUN0QyxnQ0FBZ0MsMGRBQ2hDLHNDQUFzQyw4TUFDdEMsNEJBQTRCLHFFQUM1QiwrQkFBK0IscUpBQy9CLHlDQUF5QyxpUUFDekMsMkNBQTJDLGdGQUMzQywrQ0FBK0M7OzRGQUd0QyxpQ0FBaUM7a0JBckI3QyxTQUFTOytCQUVFLHdDQUF3QyxjQUd0QyxJQUFJLG1CQUNDLHVCQUF1QixDQUFDLE1BQU0sV0FDdEM7d0JBQ1AscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxTQUFTO3dCQUM1RSxnQ0FBZ0M7d0JBQ2hDLCtCQUErQjt3QkFDL0Isc0NBQXNDO3dCQUN0QyxnQ0FBZ0M7d0JBQ2hDLHNDQUFzQzt3QkFDdEMsNEJBQTRCO3dCQUM1QiwrQkFBK0I7d0JBQy9CLHlDQUF5Qzt3QkFDekMsMkNBQTJDO3dCQUMzQywrQ0FBK0M7cUJBQ2hEIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgQXN5bmNQaXBlLCBOZ0NsYXNzLCBOZ1RlbXBsYXRlT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIE9uSW5pdCwgc2lnbmFsLCB2aWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZpcnR1YWxTY3JvbGxlckNvbXBvbmVudCwgVmlydHVhbFNjcm9sbGVyTW9kdWxlIH0gZnJvbSAnQGloYXJiZWNrL25neC12aXJ0dWFsLXNjcm9sbGVyJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNBdmF0YXJDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLWF2YXRhcic7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudCB9IGZyb20gJ0BsaWJzLXVpL2NvbXBvbmVudHMtYnV0dG9ucy1idXR0b24nO1xuaW1wb3J0IHsgSVNvcnQsIExpYnNVaUNvbXBvbmVudHNCdXR0b25zU29ydEFycm93Q29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1idXR0b25zLXNvcnQnO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c1BvcG92ZXJDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLXBvcG92ZXInO1xuaW1wb3J0IHsgTGlic1VpQ29tcG9uZW50c1Njcm9sbE92ZXJsYXlEaXJlY3RpdmUgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLXNjcm9sbC1vdmVybGF5JztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNTcGlubmVyQ29tcG9uZW50IH0gZnJvbSAnQGxpYnMtdWkvY29tcG9uZW50cy1zcGlubmVyJztcbmltcG9ydCB7IExpYnNVaUNvbXBvbmVudHNTd2l0Y2hDb21wb25lbnQgfSBmcm9tICdAbGlicy11aS9jb21wb25lbnRzLXN3aXRjaCc7XG5pbXBvcnQgeyBjbG9uZURlZXAsIGRlbGV0ZVVuaWNvZGUsIGVzY2FwZUh0bWwsIGlzRW1wdHksIGlzTmlsIH0gZnJvbSAnQGxpYnMtdWkvdXRpbHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzTGlzdEhpZ2hsaWdodEtleVNlYXJjaERpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2hpZ2hsaWdodC1rZXktc2VhcmNoL2hpZ2hsaWdodC1rZXktc2VhcmNoLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBNb0xpYnNTaGFyZWRQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGVQaXBlIH0gZnJvbSAnLi4vLi4vcGlwZXMvY2FsbC1mdW5jdGlvbi1pbi10ZW1wbGF0ZS5waXBlJztcbmltcG9ydCB7IExpYnNVaUNoZWNrU2VsZWN0ZWRCeUtleVBpcGUgfSBmcm9tICcuLi8uLi9waXBlcy9jaGVjay1zZWxlY3RlZC1ieS1rZXkucGlwZSc7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzTGlzdFRlbXBsYXRlc0NvbXBvbmVudEFic3RyYWN0IH0gZnJvbSAnLi4vdGVtcGxhdGVzLmNvbXBvbmVudC5hYnN0cmFjdCc7XG5pbXBvcnQgeyBJTGlzdFZpZXdDb25maWdJdGVtVGV4dCB9IGZyb20gJy4vLi4vLi4vaW50ZXJmYWNlcy9jb25maWctaXRlbS5pbnRlcmZhY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdsaWJzX3VpLWNvbXBvbmVudHMtbGlzdC10ZW1wbGF0ZXNfdGV4dCcsXG4gIHRlbXBsYXRlVXJsOiAnLi90ZXh0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdGV4dC5jb21wb25lbnQuc2NzcyddLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW1xuICAgIFZpcnR1YWxTY3JvbGxlck1vZHVsZSwgTmdUZW1wbGF0ZU91dGxldCwgVHJhbnNsYXRlTW9kdWxlLCBOZ0NsYXNzLCBBc3luY1BpcGUsXG4gICAgTGlic1VpQ29tcG9uZW50c1NwaW5uZXJDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c0F2YXRhckNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzQnV0dG9uc0J1dHRvbkNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzUG9wb3ZlckNvbXBvbmVudCxcbiAgICBMaWJzVWlDb21wb25lbnRzU2Nyb2xsT3ZlcmxheURpcmVjdGl2ZSxcbiAgICBMaWJzVWlDaGVja1NlbGVjdGVkQnlLZXlQaXBlLFxuICAgIExpYnNVaUNvbXBvbmVudHNTd2l0Y2hDb21wb25lbnQsXG4gICAgTGlic1VpQ29tcG9uZW50c0J1dHRvbnNTb3J0QXJyb3dDb21wb25lbnQsXG4gICAgTW9MaWJzU2hhcmVkUGlwZXNDYWxsRnVuY3Rpb25JblRlbXBsYXRlUGlwZSxcbiAgICBMaWJzVWlDb21wb25lbnRzTGlzdEhpZ2hsaWdodEtleVNlYXJjaERpcmVjdGl2ZVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIExpYnNVaUNvbXBvbmVudHNMaXN0VGV4dENvbXBvbmVudCBleHRlbmRzIExpYnNVaUNvbXBvbmVudHNMaXN0VGVtcGxhdGVzQ29tcG9uZW50QWJzdHJhY3QgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcm90ZWN0ZWQgY29uZmlnVGVtcGxhdGVUZXh0ID0gc2lnbmFsPElMaXN0Vmlld0NvbmZpZ0l0ZW1UZXh0IHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIHJlYWRvbmx5IHZpcnR1YWxTY3JvbGxlckNvbXBvbmVudCA9IHZpZXdDaGlsZDxWaXJ0dWFsU2Nyb2xsZXJDb21wb25lbnQ+KFZpcnR1YWxTY3JvbGxlckNvbXBvbmVudCk7XG5cbiAgb3ZlcnJpZGUgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKGlzRW1wdHkodGhpcy5jb25maWcoKT8uY29uZmlnVGVtcGxhdGVUZXh0KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgdGhpcy5jb25maWdUZW1wbGF0ZVRleHQuc2V0KHRoaXMuY29uZmlnKCk/LmNvbmZpZ1RlbXBsYXRlVGV4dCk7XG4gICAgdGhpcy5maWVsZEtleS5zZXQodGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uZmllbGRLZXkgPz8gdGhpcy5maWVsZEtleURlZmF1bHQoKSk7XG4gICAgdGhpcy5jYWxsQXBpQnlTZXJ2aWNlKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclNjcm9sbEJvdHRvbSgpIHtcbiAgICBpZiAodGhpcy5sb2FkZWRMYXN0SXRlbSgpKSB7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMub3V0TG9hZGluZy5lbWl0KHRoaXMubG9hZGluZygpKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5sb2FkaW5nKCkgfHwgdGhpcy5sb2FkZWRMYXN0SXRlbSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgdGhpcy5vdXRMb2FkaW5nLmVtaXQodGhpcy5sb2FkaW5nKCkpO1xuICAgIHRoaXMuY2FsbEFwaUJ5U2VydmljZShmYWxzZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc1NlYXJjaCgpIHtcbiAgICBpZiAoIXRoaXMuaXNTZWFyY2hPbmxpbmUoKSkge1xuICAgICAgcmV0dXJuIHRoaXMucHJvY2Vzc0RhdGEodHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuY2FsbEFwaUJ5U2VydmljZSh0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyQ2xpY2tSZWxhdGl2ZShlOiBFdmVudCwgaXRlbTogYW55KSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAodGhpcy5jbGlja0V4YWN0bHkoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmhhbmRsZXJTZWxlY3RJdGVtKGUsIGl0ZW0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHByb2Nlc3NLZXlDaGFuZ2VVblNlbGVjdChpdGVtOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoaXNOaWwoaXRlbVt0aGlzLmZpZWxkS2V5KCldKSB8fCBpdGVtW3RoaXMuZmllbGRLZXkoKV0gPT09ICcnIHx8IHRoaXMua2V5U2VsZWN0ZWQoKSAhPT0gaXRlbVt0aGlzLmZpZWxkS2V5KCldKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMua2V5U2VsZWN0ZWQuc2V0KCcnKTtcbiAgICB0aGlzLm91dFNlbGVjdEtleS5lbWl0KHVuZGVmaW5lZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaGFuZGxlclNlbGVjdEl0ZW0oZTogRXZlbnQgfCBzdHJpbmcsIGl0ZW06IGFueSwgYWN0aW9uPzogKGl0ZW06IGFueSkgPT4gdm9pZCwgaWdub3JlRGlzYWJsZSA9IGZhbHNlKSB7XG4gICAgaWYgKGUgaW5zdGFuY2VvZiBFdmVudCkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgaWYgKGl0ZW0uZGlzYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5kaXNhYmxlKCkgJiYgIWlnbm9yZURpc2FibGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlID09PSAnc3RyaW5nJyAmJiBlICE9PSAnY2xpY2snKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghaXRlbSB8fCAodGhpcy5rZXlzRGlzYWJsZUl0ZW0oKSAmJiB0aGlzLmtleXNEaXNhYmxlSXRlbSgpPy5zb21lKGtleSA9PiBrZXkgPT09IGl0ZW1bdGhpcy5maWVsZEtleSgpXSkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChhY3Rpb24pIHtcbiAgICAgIGFjdGlvbihpdGVtLnJlZik7XG4gICAgICB0aGlzLml0ZW1zKCkuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgICAgdGhpcy5idWlsZFZhbHVlQnlDb25maWcoaXRlbSwgdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uYWN0aW9uU29ydCkge1xuICAgICAgY29uc3QgY3VycmVudEl0ZW1Tb3J0ID0gdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uaXRlbVNvcnQ7XG4gICAgICBjb25zdCBtb2RlID0gY3VycmVudEl0ZW1Tb3J0Py5maWVsZFNvcnQgIT09IGl0ZW1bdGhpcy5maWVsZEtleSgpXSA/ICdhc2MnIDogY3VycmVudEl0ZW1Tb3J0Py5tb2RlID09PSAnZGVzYycgPyAnYXNjJyA6ICdkZXNjJztcbiAgICAgIGNvbnN0IG5ld1NvcnQ6IElTb3J0ID0ge1xuICAgICAgICBmaWVsZFNvcnQ6IGl0ZW1bdGhpcy5maWVsZEtleSgpXSxcbiAgICAgICAgbW9kZSxcbiAgICAgICAgbW9kZU51bWJlcjogbW9kZSA9PT0gJ2FzYycgPyAxIDogMixcbiAgICAgICAgcmVzZXQ6ICgpID0+IDBcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuY29uZmlnVGVtcGxhdGVUZXh0LnVwZGF0ZShpdGVtID0+IHtcbiAgICAgICAgaWYgKCFpdGVtKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IC4uLml0ZW0sIGl0ZW1Tb3J0OiBuZXdTb3J0IH1cbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLm91dFNvcnRTaW5nbGVTZWxlY3QuZW1pdCh0aGlzLmNvbmZpZ1RlbXBsYXRlVGV4dCgpPy5pdGVtU29ydCB8fCBuZXdTb3J0KTtcbiAgICB9XG5cbiAgICB0aGlzLmtleVNlbGVjdGVkLnNldChpdGVtW3RoaXMuZmllbGRLZXkoKV0pO1xuICAgIHRoaXMub3V0U2VsZWN0S2V5LmVtaXQoeyBrZXk6IHRoaXMua2V5U2VsZWN0ZWQoKSwgaXRlbSwgaXNDbGlja01hbnVhbDogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyU29ydChpdGVtU29ydDogSVNvcnQpIHtcbiAgICBpdGVtU29ydC5yZXNldCA9ICgpID0+IDA7XG5cbiAgICB0aGlzLmNvbmZpZ1RlbXBsYXRlVGV4dC51cGRhdGUoaXRlbSA9PiB7XG4gICAgICBpZiAoIWl0ZW0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHsgLi4uaXRlbSwgaXRlbVNvcnQ6IGl0ZW1Tb3J0IH1cbiAgICB9KTtcbiAgICB0aGlzLm91dFNvcnRTaW5nbGVTZWxlY3QuZW1pdCh0aGlzLmNvbmZpZ1RlbXBsYXRlVGV4dCgpPy5pdGVtU29ydCB8fCBpdGVtU29ydCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcHJvY2Vzc0RhdGEocmVwbGFjZT86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBpdGVtQnlLZXlTZWFyY2g6IEFycmF5PGFueT4gPSBbXTtcbiAgICBjb25zdCBrZXlzSGlkZGVuID0gdGhpcy5rZXlzSGlkZGVuSXRlbSgpIHx8IFtdO1xuXG4gICAgaWYgKHJlcGxhY2UpIHtcbiAgICAgIHRoaXMuaXRlbXMuc2V0KFtdKVxuICAgIH1cbiAgICB0aGlzLnN0b3JlKCkuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgZGF0YVN0b3JlID0gY2xvbmVEZWVwKGl0ZW0pO1xuICAgICAgY29uc3Qga2V5ID0ga2V5c0hpZGRlbi5maW5kKGtleSA9PiBkYXRhU3RvcmUoKVt0aGlzLmZpZWxkS2V5KCldID09PSBrZXkpO1xuXG4gICAgICBkYXRhU3RvcmUucmVmID0gaXRlbTtcblxuICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSBkZWxldGVVbmljb2RlKHRoaXMuYnVpbGRWYWx1ZUJ5Q29uZmlnKGRhdGFTdG9yZSwgdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKSkpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gICAgICAgIGNvbnN0IHRleHRFc2NhcGUgPSBlc2NhcGVIdG1sKHRleHQpO1xuICAgICAgICBjb25zdCBrZXlTZWFyY2ggPSBkZWxldGVVbmljb2RlKGVzY2FwZUh0bWwodGhpcy5rZXlTZWFyY2goKS50b0xvY2FsZUxvd2VyQ2FzZSgpKSk7XG5cbiAgICAgICAgaWYgKCgodGhpcy5pc1NlYXJjaE9ubGluZSgpICYmIHRoaXMuY29uZmlnKCk/Lmh0dHBSZXF1ZXN0RGF0YT8uc2VydmljZU5hbWUgJiYgdGhpcy5jb25maWcoKT8uaHR0cFJlcXVlc3REYXRhPy5zZXJ2aWNlTmFtZSAhPT0gJ2NvbW1vbkRhdGFTdGF0aWNTZXJ2aWNlJyAmJiAhdGhpcy5jb25maWcoKT8uaHR0cFJlcXVlc3REYXRhPy5zZXJ2aWNlT3RoZXIpIHx8XG4gICAgICAgICAgKHRleHQgJiYgKHRleHQuaW5jbHVkZXMoa2V5U2VhcmNoKSB8fCB0ZXh0RXNjYXBlLmluY2x1ZGVzKGtleVNlYXJjaCkpKSkgJiYgKHJlcGxhY2UgfHwgKCFyZXBsYWNlICYmICF0aGlzLml0ZW1zKCkuZmluZChkYXRhSXRlbSA9PiBkYXRhSXRlbVt0aGlzLmZpZWxkS2V5KCldID09PSBkYXRhU3RvcmVbdGhpcy5maWVsZEtleSgpXSkpKSAmJiAhaXRlbUJ5S2V5U2VhcmNoLmZpbmQoZGF0YUl0ZW0gPT4gZGF0YUl0ZW1bdGhpcy5maWVsZEtleSgpXSA9PT0gZGF0YVN0b3JlW3RoaXMuZmllbGRLZXkoKV0pKSB7XG4gICAgICAgICAgZGF0YVN0b3JlLmhyZWZCdXR0b24gPSB0aGlzLmNvbmZpZ1RlbXBsYXRlVGV4dCgpPy5nZXRIcmVmQnV0dG9uPy4oZGF0YVN0b3JlKTtcbiAgICAgICAgICBkYXRhU3RvcmUuY2xhc3NJdGVtID0gaXRlbS5jbGFzc0l0ZW0gfHwgdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uZ2V0Q2xhc3NJdGVtPy4oZGF0YVN0b3JlKTtcbiAgICAgICAgICBkYXRhU3RvcmUuY2xhc3NJbmNsdWRlID0gZGF0YVN0b3JlLmNsYXNzSW5jbHVkZSB8fCB0aGlzLmNvbmZpZ1RlbXBsYXRlVGV4dCgpPy5nZXRDbGFzc0luY2x1ZGVQb3BvdmVyPy4oZGF0YVN0b3JlKTtcbiAgICAgICAgICBkYXRhU3RvcmUuYnV0dG9uTGVmdENvbmZpZyA9IHRoaXMuY29uZmlnVGVtcGxhdGVUZXh0KCk/LmdldENvbmZpZ0J1dHRvbkxlZnQ/LihkYXRhU3RvcmUpO1xuICAgICAgICAgIGRhdGFTdG9yZS5jbGFzc0ljb25MZWZ0ID0gZGF0YVN0b3JlLmNsYXNzSWNvbkxlZnQgfHwgdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uZ2V0Q2xhc3NJY29uTGVmdD8uKGRhdGFTdG9yZSk7XG4gICAgICAgICAgZGF0YVN0b3JlLmhvdmVyRGFuZ2VyID0gZGF0YVN0b3JlLmhvdmVyRGFuZ2VyIHx8IHRoaXMuY29uZmlnVGVtcGxhdGVUZXh0KCk/LmdldENvbmZpZ0hvdmVyRGFuZ2VyPy4oZGF0YVN0b3JlKTtcbiAgICAgICAgICBkYXRhU3RvcmUuYXZhdGFyQ29uZmlnID0gdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uZ2V0QXZhdGFyQ29uZmlnPy4oZGF0YVN0b3JlKTtcbiAgICAgICAgICBkYXRhU3RvcmUuaXRlbUFsaWduU3RhcnQgPSBkYXRhU3RvcmUuaXRlbUFsaWduU3RhcnQgfHwgdGhpcy5jb25maWdUZW1wbGF0ZVRleHQoKT8uZ2V0Q29uZmlnQWxpZ25TdGFydD8uKGRhdGFTdG9yZSk7XG4gICAgICAgICAgaXRlbUJ5S2V5U2VhcmNoLnB1c2goZGF0YVN0b3JlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluZGV4SXRlbVJlbW92ZSA9IHRoaXMuaXRlbXMoKS5maW5kSW5kZXgoaXRlbSA9PiBpdGVtW3RoaXMuZmllbGRLZXkoKV0gPT09IGtleSk7XG5cbiAgICAgIGlmIChpbmRleEl0ZW1SZW1vdmUgPiAtMSkge1xuICAgICAgICB0aGlzLml0ZW1zKCkuc3BsaWNlKGluZGV4SXRlbVJlbW92ZSwgMSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc3QgY2hlY2tMb2FkSXRlbSA9IChwcmVTdGF0ZUhhc1Njcm9sbDogYm9vbGVhbiwgY3VycmVudEhhc1Njcm9sbDogYm9vbGVhbikgPT4ge1xuICAgICAgaWYgKHRoaXMua2V5c0hpZGRlbkl0ZW0oKT8ubGVuZ3RoICYmIHByZVN0YXRlSGFzU2Nyb2xsICYmICFjdXJyZW50SGFzU2Nyb2xsICYmICh0aGlzLmlzU2VhcmNoT25saW5lKCkpKSB7XG4gICAgICAgIHRoaXMuY2FsbEFwaUJ5U2VydmljZShmYWxzZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmIChyZXBsYWNlKSB7XG4gICAgICB0aGlzLml0ZW1zLnNldChpdGVtQnlLZXlTZWFyY2gpO1xuICAgICAgdGhpcy5jb25maWcoKT8uc29ydD8uKHRoaXMuaXRlbXMoKSk7XG4gICAgICB0aGlzLmVtaXRLZXlTZWxlY3RlZERlZmF1bHRJZkV4aXN0SXRlbSh0aGlzLml0ZW1zKCkpO1xuICAgICAgdGhpcy5hdXRvU2VsZWN0Rmlyc3RJdGVtKHRoaXMuaXRlbXMoKSk7XG4gICAgICB0aGlzLnNldEhlaWdodFZpZXdQb3J0KCk7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMuY2hlY2tWaWV3UG9ydFNjcm9sbChjaGVja0xvYWRJdGVtKTtcbiAgICAgIHRoaXMuc2Nyb2xsVG9JdGVtU2VsZWN0ZWQoKTtcbiAgICAgIHRoaXMub3V0TG9hZGluZy5lbWl0KHRoaXMubG9hZGluZygpKTtcbiAgICAgIHRoaXMub3V0TG9hZEl0ZW1zQ29tcGxldGUuZW1pdCh7IGl0ZW1zOiB0aGlzLml0ZW1zKCksIHBhZ2luZzogdGhpcy5wYWdpbmdTdG9yZSgpIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaXRlbXMudXBkYXRlKGl0ZW1zID0+IFsuLi5pdGVtcywgLi4uaXRlbUJ5S2V5U2VhcmNoXSk7XG4gICAgdGhpcy5jb25maWcoKT8uc29ydD8uKHRoaXMuaXRlbXMoKSk7XG4gICAgdGhpcy5zZXRIZWlnaHRWaWV3UG9ydCgpO1xuICAgIHRoaXMubG9hZGluZy5zZXQoZmFsc2UpO1xuICAgIHRoaXMuY2hlY2tWaWV3UG9ydFNjcm9sbChjaGVja0xvYWRJdGVtKTtcbiAgICB0aGlzLnNjcm9sbFRvSXRlbVNlbGVjdGVkKCk7XG4gICAgdGhpcy5vdXRMb2FkaW5nLmVtaXQodGhpcy5sb2FkaW5nKCkpO1xuICAgIHRoaXMub3V0TG9hZEl0ZW1zQ29tcGxldGUuZW1pdCh7IGl0ZW1zOiB0aGlzLml0ZW1zKCksIHBhZ2luZzogdGhpcy5wYWdpbmdTdG9yZSgpIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzY3JvbGxUb0l0ZW1TZWxlY3RlZCgpIHtcbiAgICBpZiAoIXRoaXMuY29uZmlnVGVtcGxhdGVUZXh0KCk/LmF1dG9TY3JvbGxUb0l0ZW1TZWxlY3RlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVBdXRvU2Nyb2xsSXRlbVNlbGVjdGVkKCkpO1xuICAgIHRoaXMudGltZUF1dG9TY3JvbGxJdGVtU2VsZWN0ZWQuc2V0KChzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5rZXlTZWxlY3RlZCgpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pdGVtcygpLmZpbmRJbmRleChpdGVtID0+IGl0ZW1bdGhpcy5maWVsZEtleSgpXSA9PT0gdGhpcy5rZXlTZWxlY3RlZCk7XG5cbiAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgdGhpcy52aXJ0dWFsU2Nyb2xsZXJDb21wb25lbnQoKT8uc2Nyb2xsVG9JbmRleChpbmRleCk7XG4gICAgICB9XG4gICAgfSkgYXMgdW5rbm93bikgYXMgbnVtYmVyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhdXRvU2VsZWN0Rmlyc3RJdGVtKGl0ZW1zOiBBcnJheTxhbnk+KSB7XG4gICAgaWYgKHRoaXMua2V5U2VsZWN0ZWQoKSB8fCAhdGhpcy5jb25maWcoKT8uYXV0b1NlbGVjdEZpcnN0SXRlbSB8fCAhaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmhhbmRsZXJTZWxlY3RJdGVtKCdjbGljaycsIGl0ZW1zWzBdLCB1bmRlZmluZWQsIHRydWUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGVtaXRLZXlTZWxlY3RlZERlZmF1bHRJZkV4aXN0SXRlbShpdGVtczogQXJyYXk8YW55Pikge1xuICAgIGNvbnN0IGl0ZW0gPSBpdGVtcy5maW5kKHN0b3JlID0+IHN0b3JlW3RoaXMuZmllbGRLZXkoKV0gPT09IHRoaXMua2V5U2VsZWN0ZWQpO1xuXG4gICAgaWYgKGl0ZW0pIHtcbiAgICAgIHRoaXMuaGFuZGxlclNlbGVjdEl0ZW0oJ2NsaWNrJywgaXRlbSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0TGVuZ3RoSXRlbSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLml0ZW1zKCkubGVuZ3RoO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJJbWFnZUVycm9yKGV2ZW50OiBFdmVudCwgaXRlbTogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaXRlbS5zcGVjaWZpY19sb2FkSW1nRXJyb3IgPSB0cnVlO1xuICB9XG59XG4iLCJAaWYgKGNvbmZpZ1RlbXBsYXRlVGV4dCgpOyBhcyBjb25maWdUZW1wbGF0ZVRleHQpIHtcbiAgPGRpdiBjbGFzcz1cInJlbGF0aXZlIGgtZnVsbCB3LWZ1bGxcIj5cbiAgICBAaWYgKGl0ZW1zKCkgJiYgaXRlbXMoKS5sZW5ndGgpIHtcbiAgICAgIDxkaXYgI2VsZW1lbnRTY3JvbGxcbiAgICAgICAgW3N0eWxlLmhlaWdodF09XCIhY29uZmlnVGVtcGxhdGVUZXh0Lm5vdFVzZVZpcnR1YWxTY3JvbGwgJiYgaGVpZ2h0Vmlld1BvcnQoKSAmJiAoIWNvbmZpZygpPy5pZ25vcmVTaG93RGF0YVdoZW5Ob3RTZWFyY2ggfHwgKGNvbmZpZygpPy5pZ25vcmVTaG93RGF0YVdoZW5Ob3RTZWFyY2ggJiYgY29uZmlnKCk/Lmlnbm9yZUZpeEhlaWdodFNob3dEYXRhV2hlbk5vdFNlYXJjaCkpICA/IGhlaWdodFZpZXdQb3J0KCkrJ3B4JzonMTAwJSdcIlxuICAgICAgICBjbGFzcz1cInctZnVsbFwiXG4gICAgICAgIExpYnNVaUNvbXBvbmVudHNTY3JvbGxPdmVybGF5RGlyZWN0aXZlXG4gICAgICAgIChvdXRTY3JvbGxCb3R0b20pPVwiaGFuZGxlclNjcm9sbEJvdHRvbSgpXCI+XG4gICAgICAgIEBpZiAoIWNvbmZpZ1RlbXBsYXRlVGV4dC5ub3RVc2VWaXJ0dWFsU2Nyb2xsKSB7XG4gICAgICAgICAgPHZpcnR1YWwtc2Nyb2xsZXIgI3Njcm9sbFxuICAgICAgICAgICAgW3BhcmVudFNjcm9sbF09XCJlbGVtZW50U2Nyb2xsXCJcbiAgICAgICAgICAgIFtpdGVtc109XCJpdGVtcygpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiaC1mdWxsXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PSdsaXN0UmVmO2NvbnRleHQ6e2l0ZW1zVmlldzpzY3JvbGwudmlld1BvcnRJdGVtc30nIC8+XG4gICAgICAgICAgPC92aXJ0dWFsLXNjcm9sbGVyPlxuICAgICAgICB9XG4gICAgICAgIEBpZiAoY29uZmlnVGVtcGxhdGVUZXh0Lm5vdFVzZVZpcnR1YWxTY3JvbGwpIHtcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PSdsaXN0UmVmO2NvbnRleHQ6e2l0ZW1zVmlldzppdGVtcygpfScgLz5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfVxuICAgIEBpZiAoKCFpdGVtcygpIHx8ICFpdGVtcygpLmxlbmd0aCkgJiYgKCFjb25maWcoKT8uaWdub3JlU2hvd0RhdGFXaGVuTm90U2VhcmNoIHx8IGtleVNlYXJjaCgpKSkge1xuICAgICAgPGRpdiBbY2xhc3NdPVwiJ2xpYnMtdWktZm9udC1oNXIgdGV4dC1bIzljYTJhZF0gJysgKGNvbmZpZygpPy50ZXh0Tm9EYXRhQ2xhc3NJbmNsdWRlID8/ICdweS1bNnB4XSBweC1bMTZweF0nKVwiPlxuICAgICAgICBAaWYgKCFrZXlTZWFyY2goKSAmJiAhbG9hZGluZygpKSB7XG4gICAgICAgICAge3sgKGNvbmZpZygpPy50ZXh0Tm9EYXRhID8/ICdpMThuX2hhdmVfbm9fc2VsZWN0aW9uJykgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgfVxuICAgICAgICBAaWYgKHRlbXBsYXRlUmVmU2VhcmNoTm9EYXRhKCkgJiYga2V5U2VhcmNoKCkgJiYgIWxvYWRpbmcoKSkge1xuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0ZW1wbGF0ZVJlZlNlYXJjaE5vRGF0YSgpIHx8IG51bGw7Y29udGV4dDp7a2V5U2VhcmNoOmtleVNlYXJjaCgpfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICB9XG4gICAgICAgIEBpZiAoIXRlbXBsYXRlUmVmU2VhcmNoTm9EYXRhKCkgJiYga2V5U2VhcmNoKCkgJiYgIWxvYWRpbmcoKSkge1xuICAgICAgICAgIHt7IChjb25maWcoKT8udGV4dFNlYXJjaE5vRGF0YSA/PyAnaTE4bl9ub19yZXN1bHQnKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICB9XG4gICAgICAgIEBpZiAobG9hZGluZygpKSB7XG4gICAgICAgICAgJm5ic3A7XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgICBAaWYgKGxvYWRpbmcoKSkge1xuICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1zcGlubmVyIFtzaXplXT1cImxvYWRpbmdJY29uU2l6ZSgpIHx8ICdtZWRpdW0nXCIgLz5cbiAgICB9XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgI2xpc3RSZWZcbiAgICBsZXQtaXRlbXNWaWV3PSdpdGVtc1ZpZXcnPlxuICAgIEBmb3IgKGl0ZW0gb2YgaXRlbXNWaWV3OyB0cmFjayBpdGVtW2ZpZWxkS2V5KCldKSB7XG4gICAgICA8ZGl2ICNpdGVtUmVmXG4gICAgICAgIFtjbGFzc109XCJpdGVtLmNsYXNzSXRlbVdyYXBwZXIgfHwgJydcIj5cbiAgICAgICAgPGRpdiBMaWJzVWlDb21wb25lbnRzTGlzdEhpZ2hsaWdodEtleVNlYXJjaERpcmVjdGl2ZVxuICAgICAgICAgIFtpc0hpZ2hsaWdodF09XCJjb25maWcoKT8uaGlnaGxpZ2h0VGV4dFNlYXJjaEluUmVzdWx0XCJcbiAgICAgICAgICBba2V5U2VhcmNoXT1cImtleVNlYXJjaCgpXCJcbiAgICAgICAgICBbY2xhc3NdPVwiJ2xpYnMtdWktbGlzdC10ZW1wbGF0ZS10ZXh0LWl0ZW0gZmxleCAnKyhpdGVtLmNsYXNzSXRlbSB8fCAnJylcIlxuICAgICAgICAgIFtjbGFzcy5pdGVtcy1jZW50ZXJdPVwiIWl0ZW0uaXRlbUFsaWduU3RhcnRcIlxuICAgICAgICAgIFtjbGFzcy5pdGVtcy1zdGFydF09XCJpdGVtLml0ZW1BbGlnblN0YXJ0XCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1iZy1saXN0LWhvdmVyLWRhbmdlcl09XCIhY2xpY2tFeGFjdGx5KCkgJiYgaXRlbS5ob3ZlckRhbmdlclwiXG4gICAgICAgICAgW2NsYXNzLmxpYnMtdWktYmctbGlzdC1ob3Zlcl09XCIhY2xpY2tFeGFjdGx5KCkgICYmICFpdGVtLmhvdmVyRGFuZ2VyXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1iZy1saXN0LXNlbGVjdGVkXT1cIiFjbGlja0V4YWN0bHkoKSAmJiBrZXlTZWxlY3RlZCgpID09PSBpdGVtW2ZpZWxkS2V5KCldXCJcbiAgICAgICAgICBbY2xhc3MucGwtWzE2cHhdXT1cInBhZGRpbmdMZWZ0SXRlbSgpXCJcbiAgICAgICAgICBbY2xhc3MuYmctWyNmZmZmZmZdXT1cImNsaWNrRXhhY3RseSgpXCJcbiAgICAgICAgICBbY2xhc3MubGlicy11aS1iZy1saXN0LWhvdmVyLWZmZmZmZl09XCJpdGVtLmRpc2FibGVcIlxuICAgICAgICAgIFtjbGFzcy5jdXJzb3ItZGVmYXVsdF09XCJpdGVtLmRpc2FibGVcIlxuICAgICAgICAgIFtjbGFzcy5weS1bMnB4XV09XCJjbGlja0V4YWN0bHkoKVwiXG4gICAgICAgICAgW2NsYXNzLnByLVs0OHB4XV09XCJrZXlTZWxlY3RlZCgpID09PSBpdGVtW2ZpZWxkS2V5KCldICYmICghY29uZmlnVGVtcGxhdGVUZXh0Py5pZ25vcmVJY29uU2VsZWN0ZWQgfHwgY29uZmlnVGVtcGxhdGVUZXh0Py5hY3Rpb25Tb3J0KSYmICFjb25maWdUZW1wbGF0ZVRleHQ/LnN0eWxlUGFkZGluZ1JpZ2h0SXRlbU90aGVyXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7J3BvaW50ZXItZXZlbnRzLW5vbmUgbGlicy11aS1kaXNhYmxlJzpsb2FkaW5nKCkgfHwgZGlzYWJsZSgpIHx8ICgoaXRlbVtmaWVsZEtleSgpXSB8IExpYnNVaUNoZWNrU2VsZWN0ZWRCeUtleVBpcGU6a2V5c0Rpc2FibGVJdGVtKCk6a2V5c0Rpc2FibGVJdGVtKCk/Lmxlbmd0aCkgJiYgIWlnbm9yZUNsYXNzRGlzYWJsZURlZmF1bHRXaGVuVXNlS2V5c0Rpc2FibGVJdGVtKCkpfVwiXG4gICAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJDbGlja1JlbGF0aXZlKCRldmVudCxpdGVtKVwiPlxuICAgICAgICAgIEBpZiAoaXRlbS5idWxsZXQpIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGlicy11aS1saXN0LXRlbXBsYXRlLXRleHQtaXRlbS1idWxsZXQgZmxleCBmbGV4LXNocmluay0wXCJcbiAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtY29sb3JdPVwiaXRlbS5idWxsZXQuYmFja2dyb3VuZENvbG9yXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImhhbmRsZXJTZWxlY3RJdGVtKCRldmVudCxpdGVtKVwiPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH1cblxuICAgICAgICAgIEBpZiAoaXRlbS5hdmF0YXJDb25maWc7IGFzIGF2YXRhckNvbmZpZykge1xuICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1hdmF0YXIgW3R5cGVTaGFwZV09XCJhdmF0YXJDb25maWcudHlwZVNoYXBlIHx8ICdjaXJjbGUnXCJcbiAgICAgICAgICAgICAgW2NsYXNzSW5jbHVkZV09XCJhdmF0YXJDb25maWcuY2xhc3NJbmNsdWRlXCJcbiAgICAgICAgICAgICAgW2NsYXNzSW1hZ2VJbmNsdWRlXT1cImF2YXRhckNvbmZpZy5jbGFzc0ltYWdlSW5jbHVkZVwiXG4gICAgICAgICAgICAgIFtzaXplXT0nYXZhdGFyQ29uZmlnLnNpemUgfHwgMzInXG4gICAgICAgICAgICAgIFtsaW5rQXZhdGFyXT1cImF2YXRhckNvbmZpZy5saW5rQXZhdGFyXCJcbiAgICAgICAgICAgICAgW2xpbmtBdmF0YXJFcnJvcl09XCJhdmF0YXJDb25maWcubGlua0F2YXRhckVycm9yXCJcbiAgICAgICAgICAgICAgW2lkR2VuQ29sb3JdPVwiYXZhdGFyQ29uZmlnLmlkR2VuQ29sb3JcIlxuICAgICAgICAgICAgICBbdGV4dEF2YXRhcl09XCJhdmF0YXJDb25maWcudGV4dEF2YXRhclwiXG4gICAgICAgICAgICAgIFtjbGFzc0ltYWdlSW5jbHVkZV09XCJhdmF0YXJDb25maWcuY2xhc3NJbWFnZUluY2x1ZGVcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKGNvbmZpZ1RlbXBsYXRlVGV4dC5nZXRJbWFnZSB8fCBjb25maWdUZW1wbGF0ZVRleHQuZmllbGRHZXRJbWFnZSkge1xuICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICBbc3JjXT1cImNvbmZpZ1RlbXBsYXRlVGV4dC5nZXRJbWFnZSA/ICgoJ2F2YXRhcicgfCBNb0xpYnNTaGFyZWRQaXBlc0NhbGxGdW5jdGlvbkluVGVtcGxhdGU6KGl0ZW0uc3BlY2lmaWNfbG9hZEltZ0Vycm9yICYmIGNvbmZpZ1RlbXBsYXRlVGV4dC5nZXRJbWFnZUVycm9yID8gY29uZmlnVGVtcGxhdGVUZXh0LmdldEltYWdlRXJyb3IgOiBjb25maWdUZW1wbGF0ZVRleHQuZ2V0SW1hZ2UpOml0ZW0pIHwgYXN5bmMpIDogaXRlbVtjb25maWdUZW1wbGF0ZVRleHQuZmllbGRHZXRJbWFnZSB8fCAnJ11cIlxuICAgICAgICAgICAgICBbY2xhc3NdPVwiJ2xpYnMtdWktbGlzdC10ZW1wbGF0ZS10ZXh0LWl0ZW0tYXZhdGFyICcgKyAoY29uZmlnVGVtcGxhdGVUZXh0LmNsYXNzSW5jbHVkZUltYWdlID8/ICcnKVwiXG4gICAgICAgICAgICAgIFtjbGFzcy53LVsxOHB4XV09XCJjb25maWdUZW1wbGF0ZVRleHQuaW1nVHlwZUljb25cIlxuICAgICAgICAgICAgICBbY2xhc3MuaC1bMThweF1dPVwiY29uZmlnVGVtcGxhdGVUZXh0LmltZ1R5cGVJY29uXCJcbiAgICAgICAgICAgICAgKGVycm9yKT1cImhhbmRsZXJJbWFnZUVycm9yKCRldmVudCwgaXRlbSlcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiaGFuZGxlclNlbGVjdEl0ZW0oJGV2ZW50LGl0ZW0pXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmIChpdGVtLmJ1dHRvbkxlZnRDb25maWc7IGFzIGJ1dHRvbkxlZnQpIHtcbiAgICAgICAgICAgIEBpZiAoaXRlbS5ocmVmQnV0dG9uKSB7XG4gICAgICAgICAgICAgIDxhIFtjbGFzcy53LWZ1bGxdPVwiIWJ1dHRvbkxlZnQuaWdub3JlV2lkdGgxMDBcIlxuICAgICAgICAgICAgICAgIFtocmVmXT1cIml0ZW0uaHJlZkJ1dHRvblwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJidXR0b25MZWZ0VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmICghaXRlbS5ocmVmQnV0dG9uKSB7XG4gICAgICAgICAgICAgIDxkaXYgW2NsYXNzLnctZnVsbF09XCIhYnV0dG9uTGVmdC5pZ25vcmVXaWR0aDEwMFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJidXR0b25MZWZ0VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2J1dHRvbkxlZnRUZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPGxpYnNfdWktY29tcG9uZW50cy1idXR0b25zLWJ1dHRvbiBjbGFzcz1cInctZnVsbFwiXG4gICAgICAgICAgICAgICAgW3R5cGVdPVwiYnV0dG9uTGVmdC50eXBlIHx8ICdidXR0b24tbGluay1wcmltYXJ5J1wiXG4gICAgICAgICAgICAgICAgW2xhYmVsXT1cImJ1dHRvbkxlZnQubGFiZWwgfHwgJyAnXCJcbiAgICAgICAgICAgICAgICBbekluZGV4XT1cImJ1dHRvbkxlZnQuekluZGV4XCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZV09XCJidXR0b25MZWZ0LmRpc2FibGVcIlxuICAgICAgICAgICAgICAgIFtjbGFzc0ljb25MZWZ0XT1cImJ1dHRvbkxlZnQuY2xhc3NJY29uTGVmdCA/ICgoYnV0dG9uTGVmdC5jbGFzc0ljb25MZWZ0IHx8ICcnKSsnIGZsZXggbXItWzhweF0gdGV4dC1bMTJweF0nKSA6ICcnXCJcbiAgICAgICAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cIihidXR0b25MZWZ0LmNsYXNzSW5jbHVkZXx8ICcnKSsnIHctZnVsbCdcIlxuICAgICAgICAgICAgICAgIFtjbGFzc0xhYmVsXT1cIihidXR0b25MZWZ0LmNsYXNzTGFiZWwgPz8gJ2xpYnMtdWktZm9udC1oNHInKVwiXG4gICAgICAgICAgICAgICAgW2lnbm9yZVN0b3BQcm9wYWdhdGlvbkV2ZW50XT1cImJ1dHRvbkxlZnQuaWdub3JlU3RvcFByb3BhZ2F0aW9uRXZlbnRcIlxuICAgICAgICAgICAgICAgIFtzdHlsZUljb25MZWZ0XT1cImJ1dHRvbkxlZnQuc3R5bGVJY29uTGVmdFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlQnV0dG9uXT1cImJ1dHRvbkxlZnQuc3R5bGVCdXR0b25cIlxuICAgICAgICAgICAgICAgIChtb0NsaWNrKT1cImhhbmRsZXJTZWxlY3RJdGVtKCRldmVudCxpdGVtKVwiIC8+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKGl0ZW0uc3dpdGNoQ29uZmlnKSB7XG4gICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLXN3aXRjaCBbYWN0aXZlXT1cIml0ZW0uc3dpdGNoQ29uZmlnLmFjdGl2ZVwiXG4gICAgICAgICAgICAgIChtb1N3aXRjaCk9XCJoYW5kbGVyU2VsZWN0SXRlbSgnY2xpY2snLGl0ZW0pXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmIChpdGVtLmNsYXNzSWNvbkxlZnQpIHtcbiAgICAgICAgICAgIDxpIFtjbGFzc109XCJpdGVtLmNsYXNzSWNvbkxlZnQgKyAnIG1yLVs4cHhdIHRleHQtWzE0cHhdJ1wiPjwvaT5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmICghaXRlbS5pZ25vcmVTaG93RmllbGRMYWJlbCAmJiAhY29uZmlnVGVtcGxhdGVUZXh0LnJvd3MpIHtcbiAgICAgICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbdHlwZV09XCJpdGVtLnBvcG92ZXJMYWJlbD8udHlwZSB8fCAndGV4dCdcIlxuICAgICAgICAgICAgICBbZWxlbWVudFJlZkN1c3RvbV09XCJpdGVtLnBvcG92ZXJMYWJlbD8udHlwZSA9PT0gJ3RleHQnPyB1bmRlZmluZWQ6aXRlbVJlZlwiXG4gICAgICAgICAgICAgIFtpZ25vcmVTaG93UG9wb3Zlcl09XCJpdGVtLnBvcG92ZXJMYWJlbD8uaWdub3JlU2hvd1BvcG92ZXJcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cIml0ZW0ucG9wb3ZlckxhYmVsPy5jb25maWcgfHwgKGNvbmZpZ1RlbXBsYXRlVGV4dC5jb25maWdMYWJlbFBvcG92ZXIgfHwge30pXCJcbiAgICAgICAgICAgICAgW2lubmVySHRtbF09XCJpdGVtLmZpZWxkTGFiZWxcIlxuICAgICAgICAgICAgICBbY2xhc3NJbmNsdWRlXT1cIml0ZW0uY2xhc3NJbmNsdWRlXCJcbiAgICAgICAgICAgICAgKG1vRXZlbnQpPVwiaGFuZGxlclNlbGVjdEl0ZW0oJGV2ZW50LGl0ZW0pXCIgLz5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmICghaXRlbS5pZ25vcmVTaG93RmllbGRMYWJlbCAmJiAhY29uZmlnVGVtcGxhdGVUZXh0LnJvd3MpIHtcbiAgICAgICAgICAgIDxsaWJzX3VpLWNvbXBvbmVudHMtcG9wb3ZlciBbdHlwZV09XCJpdGVtLnBvcG92ZXJMYWJlbD8udHlwZSB8fCAndGV4dCdcIlxuICAgICAgICAgICAgICBbZWxlbWVudFJlZkN1c3RvbV09XCJpdGVtLnBvcG92ZXJMYWJlbD8udHlwZSA9PT0gJ3RleHQnPyB1bmRlZmluZWQ6aXRlbVJlZlwiXG4gICAgICAgICAgICAgIFtpZ25vcmVTaG93UG9wb3Zlcl09XCJpdGVtLnBvcG92ZXJMYWJlbD8uaWdub3JlU2hvd1BvcG92ZXJcIlxuICAgICAgICAgICAgICBbY29uZmlnXT1cIml0ZW0ucG9wb3ZlckxhYmVsPy5jb25maWcgfHwgKChjb25maWdUZW1wbGF0ZVRleHQuY29uZmlnTGFiZWxQb3BvdmVyIHx8IHt9KSlcIlxuICAgICAgICAgICAgICBbaW5uZXJIdG1sXT1cIml0ZW0uZmllbGRMYWJlbFwiXG4gICAgICAgICAgICAgIFtjbGFzc0luY2x1ZGVdPVwiaXRlbS5jbGFzc0luY2x1ZGVcIlxuICAgICAgICAgICAgICAobW9FdmVudCk9XCJoYW5kbGVyU2VsZWN0SXRlbSgkZXZlbnQsaXRlbSlcIiAvPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKGl0ZW0uZmllbGRQb3BvdmVyOyBhcyBwb3BvdmVyKSB7XG4gICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLXBvcG92ZXIgY2xhc3M9XCJ7eyBwb3BvdmVyLmNsYXNzSW5jbHVkZSB8fCAnJyB9fVwiXG4gICAgICAgICAgICAgIFtjb25maWddPVwicG9wb3Zlcj8uY29uZmlnXCI+XG4gICAgICAgICAgICAgIEBpZiAoIXBvcG92ZXIuZGF0YVZpZXcpIHtcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImxpYnMtdWktaWNvbi10b29sdGlwLW91dGxpbmVcIj48L2k+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGlmIChwb3BvdmVyLmRhdGFWaWV3KSB7XG4gICAgICAgICAgICAgICAgPGRpdiBbaW5uZXJIdG1sXT1cInBvcG92ZXIuZGF0YVZpZXcgfCB0cmFuc2xhdGVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9saWJzX3VpLWNvbXBvbmVudHMtcG9wb3Zlcj5cbiAgICAgICAgICB9XG4gICAgICAgICAgPCEtLSA8bGlicy11aXMtc2hhcmVkLWNvbXBvbmVudHMtbGlzdF92aWV3LXRlbXBsYXRlcy1yb3dzICpuZ0lmPVwiY29uZmlnVGVtcGxhdGVUZXh0Py5yb3dzXCJcbiAgICAgICAgICAgIGNsYXNzPVwidy0xMDAge3sgY29uZmlnVGVtcGxhdGVUZXh0LmNsYXNzUm93c1dyYXBwZXIgfHwgY29uZmlnVGVtcGxhdGVUZXh0LmNsYXNzUm93cyB8fCAnJyB9fVwiXG4gICAgICAgICAgICBbaXRlbV09XCJpdGVtXCJcbiAgICAgICAgICAgIFtmaWVsZEtleV09XCJmaWVsZEtleVwiXG4gICAgICAgICAgICBba2V5U2VsZWN0ZWRdPVwia2V5U2VsZWN0ZWRcIlxuICAgICAgICAgICAgW2NvbmZpZ1RlbXBsYXRlXT1cImNvbmZpZ1RlbXBsYXRlVGV4dFwiXG4gICAgICAgICAgICBbekluZGV4XT1cInpJbmRleFwiXG4gICAgICAgICAgICAobW9DaGFuZ1N0YWdlRmxhZ01vdXNlVG9vbHRpcCk9XCJoYW5kbGVyQ2hhbmdTdGFnZUZsYWdNb3VzZSgkZXZlbnQpXCJcbiAgICAgICAgICAgIChtb0V2ZW50KT1cImhhbmRsZXJTZWxlY3RJdGVtKCRldmVudC5ldmVudCwkZXZlbnQuaXRlbSwkZXZlbnQuYWN0aW9uKVwiPlxuICAgICAgICAgIDwvbGlicy11aXMtc2hhcmVkLWNvbXBvbmVudHMtbGlzdF92aWV3LXRlbXBsYXRlcy1yb3dzPiAtLT5cbiAgICAgICAgICBAaWYgKChrZXlTZWxlY3RlZCA9PT0gaXRlbVtmaWVsZEtleSgpXSB8fCAoaXRlbVtmaWVsZEtleSgpXSB8IExpYnNVaUNoZWNrU2VsZWN0ZWRCeUtleVBpcGU6bXVsdGlLZXlTZWxlY3RlZCgpOm11bHRpS2V5U2VsZWN0ZWQoKT8ubGVuZ3RoKSA/IGl0ZW1bZmllbGRLZXkoKV0gOiB1bmRlZmluZWQpICYmICFjb25maWdUZW1wbGF0ZVRleHQuaWdub3JlSWNvblNlbGVjdGVkICYmICFjb25maWdUZW1wbGF0ZVRleHQuYWN0aW9uU29ydCkge1xuICAgICAgICAgICAgPGkgW2NsYXNzXT1cIidsaWJzLXVpLWljb24tY2hlY2sgJysoY29uZmlnVGVtcGxhdGVUZXh0LmNsYXNzSW5jbHVkZUljb25TZWxlY3RlZCB8fCAncmlnaHQtWzEycHhdJylcIj5cbiAgICAgICAgICAgIDwvaT5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmIChrZXlTZWxlY3RlZCgpID09PSBpdGVtW2ZpZWxkS2V5KCldICYmIGNvbmZpZ1RlbXBsYXRlVGV4dC5hY3Rpb25Tb3J0KSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibGlicy11aS1saXN0LXRlbXBsYXRlLXRleHQtc29ydFwiPlxuICAgICAgICAgICAgICA8bGlic191aS1jb21wb25lbnRzLWJ1dHRvbnMtc29ydC1hcnJvdyBbZGlzYWJsZV09XCJsb2FkaW5nKCkgfHwgZGlzYWJsZSgpIHx8IGZhbHNlXCJcbiAgICAgICAgICAgICAgICBbbW9kZV09XCJjb25maWdUZW1wbGF0ZVRleHQuaXRlbVNvcnQ/Lm1vZGUgfHwgJydcIlxuICAgICAgICAgICAgICAgIFtmaWVsZFNvcnRdPVwiaXRlbVtmaWVsZEtleSgpXVwiXG4gICAgICAgICAgICAgICAgKG91dENoYW5nZSk9XCJoYW5kbGVyU29ydCgkZXZlbnQpXCIgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICB9XG4gIDwvbmctdGVtcGxhdGU+XG59XG4iXX0=
|