@sunbird-cb/access-settings 0.0.1-cbrelease-4.8.26

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.
Files changed (64) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/_common/access-control/access-control.component.mjs +561 -0
  3. package/esm2022/lib/_common/access-control/access-control.module.mjs +125 -0
  4. package/esm2022/lib/_common/dialogs/access-control-guide/access-control-guide.component.mjs +27 -0
  5. package/esm2022/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.mjs +27 -0
  6. package/esm2022/lib/_common/dialogs/entity-selections/entity-selections.component.mjs +371 -0
  7. package/esm2022/lib/_common/dialogs/invite-users/invite-users.component.mjs +116 -0
  8. package/esm2022/lib/_common/pagination/pagination.component.mjs +168 -0
  9. package/esm2022/lib/_constants/app.constants.mjs +6 -0
  10. package/esm2022/lib/_directives/drag-drop.directive.mjs +53 -0
  11. package/esm2022/lib/_models/access-control.model.mjs +31 -0
  12. package/esm2022/lib/_models/pagination.model.mjs +2 -0
  13. package/esm2022/lib/_services/access-control.service.mjs +195 -0
  14. package/esm2022/lib/_services/cadre-mapping.service.mjs +164 -0
  15. package/esm2022/lib/access-settings.component.mjs +13 -0
  16. package/esm2022/lib/access-settings.module.mjs +21 -0
  17. package/esm2022/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.mjs +391 -0
  18. package/esm2022/lib/components/list-table/list-table.component.mjs +148 -0
  19. package/esm2022/lib/components/snackbar/snackbar.component.mjs +19 -0
  20. package/esm2022/public-api.mjs +10 -0
  21. package/esm2022/sunbird-cb-access-settings.mjs +5 -0
  22. package/fesm2022/sunbird-cb-access-settings.mjs +2331 -0
  23. package/fesm2022/sunbird-cb-access-settings.mjs.map +1 -0
  24. package/index.d.ts +6 -0
  25. package/lib/_common/access-control/access-control.component.d.ts +71 -0
  26. package/lib/_common/access-control/access-control.component.d.ts.map +1 -0
  27. package/lib/_common/access-control/access-control.module.d.ts +36 -0
  28. package/lib/_common/access-control/access-control.module.d.ts.map +1 -0
  29. package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts +16 -0
  30. package/lib/_common/dialogs/access-control-guide/access-control-guide.component.d.ts.map +1 -0
  31. package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts +15 -0
  32. package/lib/_common/dialogs/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
  33. package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts +65 -0
  34. package/lib/_common/dialogs/entity-selections/entity-selections.component.d.ts.map +1 -0
  35. package/lib/_common/dialogs/invite-users/invite-users.component.d.ts +40 -0
  36. package/lib/_common/dialogs/invite-users/invite-users.component.d.ts.map +1 -0
  37. package/lib/_common/pagination/pagination.component.d.ts +31 -0
  38. package/lib/_common/pagination/pagination.component.d.ts.map +1 -0
  39. package/lib/_constants/app.constants.d.ts +6 -0
  40. package/lib/_constants/app.constants.d.ts.map +1 -0
  41. package/lib/_directives/drag-drop.directive.d.ts +12 -0
  42. package/lib/_directives/drag-drop.directive.d.ts.map +1 -0
  43. package/lib/_models/access-control.model.d.ts +106 -0
  44. package/lib/_models/access-control.model.d.ts.map +1 -0
  45. package/lib/_models/pagination.model.d.ts +6 -0
  46. package/lib/_models/pagination.model.d.ts.map +1 -0
  47. package/lib/_services/access-control.service.d.ts +72 -0
  48. package/lib/_services/access-control.service.d.ts.map +1 -0
  49. package/lib/_services/cadre-mapping.service.d.ts +71 -0
  50. package/lib/_services/cadre-mapping.service.d.ts.map +1 -0
  51. package/lib/access-settings.component.d.ts +9 -0
  52. package/lib/access-settings.component.d.ts.map +1 -0
  53. package/lib/access-settings.module.d.ts +12 -0
  54. package/lib/access-settings.module.d.ts.map +1 -0
  55. package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts +31 -0
  56. package/lib/components/bulk-upload-karmayogi/bulk-upload-karmayogi.component.d.ts.map +1 -0
  57. package/lib/components/list-table/list-table.component.d.ts +40 -0
  58. package/lib/components/list-table/list-table.component.d.ts.map +1 -0
  59. package/lib/components/snackbar/snackbar.component.d.ts +13 -0
  60. package/lib/components/snackbar/snackbar.component.d.ts.map +1 -0
  61. package/package.json +28 -0
  62. package/public-api.d.ts +7 -0
  63. package/public-api.d.ts.map +1 -0
  64. package/sunbird-cb-access-settings.d.ts.map +1 -0
@@ -0,0 +1,371 @@
1
+ import { Component, inject } from "@angular/core";
2
+ import { MAT_DIALOG_DATA } from "@angular/material/dialog";
3
+ import { FormControl } from "@angular/forms";
4
+ import { BATCH_RANGES } from "../../../_constants/app.constants";
5
+ import { NsAccessControlConfig } from "../../../_models/access-control.model";
6
+ import { Subject } from "rxjs";
7
+ import { takeUntil } from "rxjs/operators";
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@angular/material/dialog";
10
+ import * as i2 from "../../../_services/access-control.service";
11
+ import * as i3 from "@angular/common";
12
+ import * as i4 from "@angular/material/legacy-radio";
13
+ import * as i5 from "@angular/material/icon";
14
+ import * as i6 from "@angular/material/legacy-checkbox";
15
+ import * as i7 from "@angular/material/legacy-form-field";
16
+ import * as i8 from "@angular/material/legacy-input";
17
+ import * as i9 from "@angular/forms";
18
+ import * as i10 from "@angular/material/legacy-button";
19
+ import * as i11 from "@angular/material/legacy-progress-spinner";
20
+ export class EntitySelectionsComponent {
21
+ constructor(dialogRef, accessControlService) {
22
+ this.dialogRef = dialogRef;
23
+ this.accessControlService = accessControlService;
24
+ this.destroy$ = new Subject();
25
+ this.isLoading = false;
26
+ this.searchControl = new FormControl("");
27
+ this.filterValue = "all";
28
+ this.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ#".split("");
29
+ this.dataList = [];
30
+ this.selectedData = [];
31
+ this.groupedEntityData = {};
32
+ this.selectionType = "";
33
+ this.selectionTypeEnum = NsAccessControlConfig.SelectionType;
34
+ this.radioSelections = [];
35
+ this.data = inject(MAT_DIALOG_DATA);
36
+ }
37
+ ngOnInit() {
38
+ // If data was passed to the dialog, initialize selections
39
+ this.accessControlCriteriaSelection = this.accessControlService.accessControlConfig().accessControlCriteriaSelection;
40
+ if (this.data) {
41
+ this.selectionType = this.data?.condition?.entity;
42
+ }
43
+ if (this.data && this.data.selected) {
44
+ this.selectedData = this.data.selected;
45
+ }
46
+ // Subscribe to search control changes
47
+ this.searchControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((query) => {
48
+ if (this.selectionType) {
49
+ switch (this.selectionType) {
50
+ case this.selectionTypeEnum.Service:
51
+ this.getServicesList(query);
52
+ break;
53
+ case this.selectionTypeEnum.Cadre:
54
+ this.getCadreList(query);
55
+ break;
56
+ case this.selectionTypeEnum.Batch:
57
+ this.getBatchList(query);
58
+ break;
59
+ }
60
+ }
61
+ });
62
+ this.initializeDisplay();
63
+ }
64
+ initializeDisplay() {
65
+ switch (this.selectionType) {
66
+ case NsAccessControlConfig.SelectionType.Organizations:
67
+ this.radioSelections = this.accessControlCriteriaSelection.organizationRadioSelection;
68
+ break;
69
+ case NsAccessControlConfig.SelectionType.Designation:
70
+ const selectionIds = this.data?.rule?.conditions?.find((c) => c.entity === NsAccessControlConfig.SelectionType.Organizations)?.selections;
71
+ if (selectionIds?.length) {
72
+ this.getDesignationsList("");
73
+ }
74
+ this.radioSelections = this.accessControlCriteriaSelection.designationRadioSelection;
75
+ break;
76
+ case NsAccessControlConfig.SelectionType.Service:
77
+ this.radioSelections = this.accessControlCriteriaSelection.servicesRadioSelection;
78
+ this.getServicesList(this.searchControl.value);
79
+ break;
80
+ case NsAccessControlConfig.SelectionType.Cadre:
81
+ this.radioSelections = [{ value: "all", label: "All" }];
82
+ this.getCadreList(this.searchControl.value);
83
+ break;
84
+ case NsAccessControlConfig.SelectionType.Batch:
85
+ this.radioSelections = [{ value: "all", label: "All" }];
86
+ this.getBatchList(this.searchControl.value);
87
+ break;
88
+ case NsAccessControlConfig.SelectionType.Group:
89
+ this.getGroupList();
90
+ break;
91
+ case NsAccessControlConfig.SelectionType.VerificationStatus:
92
+ this.getVerificationStatus();
93
+ break;
94
+ }
95
+ }
96
+ onClose() {
97
+ this.dialogRef.close();
98
+ }
99
+ getSelectionValue(item) {
100
+ if (typeof item !== "object" || item === null) {
101
+ return item;
102
+ }
103
+ else if (this.selectionType === NsAccessControlConfig.SelectionType.Cadre ||
104
+ this.selectionType === NsAccessControlConfig.SelectionType.Service ||
105
+ this.selectionType === NsAccessControlConfig.SelectionType.Designation) {
106
+ return item?.name;
107
+ }
108
+ return item?.id || item?.identifier || item;
109
+ }
110
+ isSelected(item) {
111
+ const value = this.getSelectionValue(item);
112
+ return this.selectedData.includes(value);
113
+ }
114
+ toggleSelection(item) {
115
+ const value = this.getSelectionValue(item);
116
+ const index = this.selectedData.indexOf(value);
117
+ if (index > -1) {
118
+ this.selectedData.splice(index, 1);
119
+ }
120
+ else {
121
+ this.selectedData.push(value);
122
+ }
123
+ }
124
+ onFilterChange(event) {
125
+ this.filterValue = event.value;
126
+ this.getFilteredEntityGrouped();
127
+ }
128
+ search() {
129
+ switch (this.selectionType) {
130
+ case NsAccessControlConfig.SelectionType.Designation:
131
+ this.getDesignationsList(this.searchControl.value);
132
+ break;
133
+ case NsAccessControlConfig.SelectionType.Organizations:
134
+ this.getOrganisationsList(this.searchControl.value);
135
+ break;
136
+ case NsAccessControlConfig.SelectionType.Service:
137
+ this.getServicesList(this.searchControl.value);
138
+ break;
139
+ case NsAccessControlConfig.SelectionType.Cadre:
140
+ this.getCadreList(this.searchControl.value);
141
+ break;
142
+ case NsAccessControlConfig.SelectionType.Batch:
143
+ this.getCadreList(this.searchControl.value);
144
+ break;
145
+ }
146
+ }
147
+ getFilteredEntityGrouped() {
148
+ let filtered = this.dataList;
149
+ // Filter by radio selection only
150
+ if (this.filterValue === "selected") {
151
+ filtered = filtered.filter(org => this.isSelected(org));
152
+ }
153
+ else if (this.filterValue === "notSelected") {
154
+ filtered = filtered.filter(org => !this.isSelected(org));
155
+ }
156
+ // For batch, group by range and chunk each range
157
+ if (this.selectionType === this.selectionTypeEnum.Batch) {
158
+ const batchGrouped = this.groupBatchByRange(filtered);
159
+ const chunked = {};
160
+ for (const key in batchGrouped) {
161
+ chunked[key] = this.chunkArray(batchGrouped[key], 8);
162
+ }
163
+ this.groupedEntityData = chunked;
164
+ return;
165
+ }
166
+ // For all other types, group by letter and chunk each group
167
+ const grouped = {};
168
+ const temp = {};
169
+ for (const org of filtered) {
170
+ let entity = org?.channel || org?.name || org?.designation;
171
+ let letter = entity?.charAt(0)?.toUpperCase() || "#";
172
+ if (!/^[A-Z]$/.test(letter)) {
173
+ letter = "#";
174
+ }
175
+ if (!temp[letter])
176
+ temp[letter] = [];
177
+ temp[letter].push(org);
178
+ }
179
+ for (const letter in temp) {
180
+ grouped[letter] = this.chunkArray(temp[letter], 7);
181
+ }
182
+ this.groupedEntityData = grouped;
183
+ }
184
+ scrollToSection(letter) {
185
+ const section = document.getElementById(`section-${letter}`);
186
+ if (section) {
187
+ this.selectedCharacterRange = letter;
188
+ section.scrollIntoView({ behavior: "smooth", inline: "start" });
189
+ }
190
+ }
191
+ updateAlphabet() {
192
+ const chars = new Set();
193
+ for (const data of this.dataList) {
194
+ let letter = "#";
195
+ const value = data?.channel || data?.name || data?.designation;
196
+ letter = value.charAt(0)?.toUpperCase() || "#";
197
+ if (!/^[A-Z]$/.test(letter)) {
198
+ letter = "#";
199
+ }
200
+ chars.add(letter);
201
+ }
202
+ const sorted = Array.from(chars)
203
+ .filter(c => c !== "#")
204
+ .sort();
205
+ if (chars.has("#"))
206
+ sorted.push("#");
207
+ this.alphabet = sorted;
208
+ }
209
+ get checkIfData() {
210
+ return ((this.groupedEntityData && Object.keys(this.groupedEntityData).length > 0) ||
211
+ (this.selectionType === NsAccessControlConfig.SelectionType.Group && this.dataList.length > 0) ||
212
+ (this.selectionType === NsAccessControlConfig.SelectionType.VerificationStatus && this.dataList.length > 0));
213
+ }
214
+ getOrganisationsList(query) {
215
+ this.isLoading = true;
216
+ this.accessControlService.fetchOrgList(query).subscribe({
217
+ next: response => {
218
+ if (response?.result && response?.result?.response?.content) {
219
+ this.dataList = response.result.response.content;
220
+ this.updateAlphabet();
221
+ this.getFilteredEntityGrouped();
222
+ }
223
+ else {
224
+ this.dataList = [];
225
+ this.alphabet = [];
226
+ }
227
+ },
228
+ complete: () => {
229
+ this.isLoading = false;
230
+ }
231
+ });
232
+ }
233
+ getDesignationsList(query) {
234
+ this.isLoading = true;
235
+ const selectionIds = this.data?.rule?.conditions?.find((c) => c.entity === NsAccessControlConfig.SelectionType.Organizations)?.selections;
236
+ if (selectionIds?.length) {
237
+ const categories = selectionIds.map((ele) => `${ele}_odcs_designation`);
238
+ this.accessControlService
239
+ .fetchDesignationsWithOrg(categories, query)
240
+ .pipe(takeUntil(this.destroy$))
241
+ .subscribe({
242
+ next: response => {
243
+ if (response?.result && response?.result?.Term) {
244
+ this.dataList = response?.result?.Term;
245
+ this.updateAlphabet();
246
+ this.getFilteredEntityGrouped();
247
+ }
248
+ else {
249
+ this.dataList = [];
250
+ this.alphabet = [];
251
+ }
252
+ },
253
+ complete: () => {
254
+ this.isLoading = false;
255
+ }
256
+ });
257
+ }
258
+ else {
259
+ this.accessControlService
260
+ .fetchDesignation(query)
261
+ .pipe(takeUntil(this.destroy$))
262
+ .subscribe({
263
+ next: response => {
264
+ if (response?.result && response?.result?.result?.data) {
265
+ this.dataList = response?.result?.result?.data;
266
+ this.updateAlphabet();
267
+ this.getFilteredEntityGrouped();
268
+ }
269
+ else {
270
+ this.dataList = [];
271
+ this.alphabet = [];
272
+ }
273
+ },
274
+ complete: () => {
275
+ this.isLoading = false;
276
+ }
277
+ });
278
+ }
279
+ }
280
+ getServicesList(query) {
281
+ const baseList = this.accessControlService.holdServiceCadrebatch().service;
282
+ this.dataList = query ? baseList.filter(service => service.name?.toLowerCase().includes(query.toLowerCase())) : baseList;
283
+ this.updateAlphabet();
284
+ this.getFilteredEntityGrouped();
285
+ }
286
+ getCadreList(query) {
287
+ const baseList = this.accessControlService.holdServiceCadrebatch().cadre;
288
+ this.dataList = query ? baseList.filter(cadre => cadre.name?.toLowerCase().includes(query.toLowerCase())) : baseList;
289
+ this.updateAlphabet();
290
+ this.getFilteredEntityGrouped();
291
+ }
292
+ getBatchList(query) {
293
+ const baseList = this.accessControlService.holdServiceCadrebatch().batch;
294
+ this.dataList = query ? baseList.filter(batch => batch.toString().includes(query)) : baseList;
295
+ this.updateBatchRanges();
296
+ this.getFilteredEntityGrouped();
297
+ }
298
+ getGroupList() {
299
+ this.isLoading = true;
300
+ this.accessControlService
301
+ .fetchGroupsList()
302
+ .pipe(takeUntil(this.destroy$))
303
+ .subscribe({
304
+ next: (response) => {
305
+ if (response?.result && response?.result?.response) {
306
+ this.dataList = response.result.response;
307
+ }
308
+ },
309
+ complete: () => {
310
+ this.isLoading = false;
311
+ }
312
+ });
313
+ }
314
+ getVerificationStatus() {
315
+ this.dataList = this.accessControlCriteriaSelection.verificationStatus;
316
+ }
317
+ updateBatchRanges() {
318
+ this.batchRanges = BATCH_RANGES.map(range => range.label);
319
+ }
320
+ groupBatchByRange(batchList) {
321
+ const grouped = {};
322
+ for (const range of BATCH_RANGES) {
323
+ grouped[range.label] = batchList.filter(year => year >= range.start && year <= range.end);
324
+ }
325
+ return grouped;
326
+ }
327
+ getModalTitle() {
328
+ switch (this.selectionType) {
329
+ case NsAccessControlConfig.SelectionType.Designation:
330
+ return "Select Designation";
331
+ case NsAccessControlConfig.SelectionType.Organizations:
332
+ return "Select Organisation";
333
+ case NsAccessControlConfig.SelectionType.Service:
334
+ return "Select Services";
335
+ case NsAccessControlConfig.SelectionType.Cadre:
336
+ return "Select Cadre";
337
+ case NsAccessControlConfig.SelectionType.Batch:
338
+ return "Select Batch";
339
+ case NsAccessControlConfig.SelectionType.Group:
340
+ return "Select Group";
341
+ case NsAccessControlConfig.SelectionType.VerificationStatus:
342
+ return "Verification Status";
343
+ }
344
+ return "";
345
+ }
346
+ applySelections() {
347
+ this.dialogRef.close({
348
+ rule: this.data.rule,
349
+ condition: this.data.condition,
350
+ selected: this.selectedData
351
+ });
352
+ }
353
+ chunkArray(array, chunkSize) {
354
+ const results = [];
355
+ for (let i = 0; i < array.length; i += chunkSize) {
356
+ results.push(array.slice(i, i + chunkSize));
357
+ }
358
+ return results;
359
+ }
360
+ ngOnDestroy() {
361
+ this.destroy$.next();
362
+ this.destroy$.complete();
363
+ }
364
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EntitySelectionsComponent, deps: [{ token: i1.MatDialogRef }, { token: i2.AccessControlService }], target: i0.ɵɵFactoryTarget.Component }); }
365
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: EntitySelectionsComponent, selector: "sb-uic-entity-selections", ngImport: i0, template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">{{ getModalTitle() }}</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre ||\n selectionType === selectionTypeEnum.Batch ||\n selectionType === selectionTypeEnum.Organizations\n \">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Type here to search...\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button\n mat-flat-button\n [disabled]=\"!searchControl.value\"\n class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n\n <div class=\"p-4 mt-2\">\n <!-- Filter Options -->\n <ng-container *ngIf=\"dataList.length && this.selectionType !== selectionTypeEnum.Cadre && this.selectionType !== selectionTypeEnum.Batch\">\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <ng-container *ngFor=\"let item of radioSelections\">\n <mat-radio-button [value]=\"item?.value\">{{ item?.label }}</mat-radio-button>\n </ng-container>\n </mat-radio-group>\n </div>\n </ng-container>\n\n <div class=\"org-container\">\n <!-- A-Z Filter Bar -->\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isLoading\">\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType !== selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of alphabet; let i = index; let last = last\">\n <button\n mat-button\n class=\"letter-button\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType === selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of batchRanges; let i = index; let last = last\">\n <button\n mat-button\n class=\"range-button px-4\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"checkIfData; else noData\">\n <div class=\"flex overflow-x-auto\">\n <ng-container *ngFor=\"let group of groupedEntityData | keyvalue\">\n <div class=\"org-column p-2 mr-4\" [attr.id]=\"'section-' + group.key\">\n <div class=\"org-list\">\n <div class=\"batch-range-columns\">\n <ng-container *ngIf=\"group.value && group.value.length\">\n <ng-container *ngFor=\"let column of group.value\">\n <div class=\"batch-column\">\n <div *ngFor=\"let entity of column\" class=\"org-card py-2\">\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Organizations ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre\n \">\n <mat-checkbox\n [checked]=\"isSelected(entity)\"\n (change)=\"toggleSelection(entity)\"\n [title]=\"entity?.name || entity?.designation || entity?.channel\">\n {{ entity?.name || entity?.designation || entity?.channel }}\n </mat-checkbox>\n </ng-container>\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Batch\">\n <mat-checkbox [checked]=\"isSelected(entity)\" (change)=\"toggleSelection(entity)\" [title]=\"entity\">\n {{ entity }}\n </mat-checkbox>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Group\">\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.VerificationStatus\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"flex gap-4 items-center ml-auto mr-1 apply-button-container my-2\">\n <div class=\"text-xs\">{{ selectedData.length }} items selected</div>\n <button\n mat-flat-button\n [disabled]=\"selectedData.length === 0\"\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white mt-2\">\n Apply\n </button>\n </div>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 0 9px}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.org-container{display:flex;flex-direction:column}.alphabet-filter{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;padding:8px 0}.alphabet-filter .divider-apl{width:1px;height:14px;background-color:#00000029}.alphabet-filter .letter-button,.alphabet-filter .range-button{min-width:30px;padding:0;margin:2px;line-height:30px;font-family:Lato;font-weight:400;font-size:12px;color:#0009}.alphabet-filter .letter-button.active-range-btn,.alphabet-filter .active-range-btn.range-button{font-weight:700;font-size:14px;color:#000}.alphabet-filter .range-button{padding:0 16px!important}.organization-scroll{flex:1;overflow-x:auto;white-space:nowrap}.org-row{display:flex;flex-direction:row}.org-column .org-list{display:flex;flex-direction:column;gap:6px}.org-column .org-card .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;width:180px;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}.apply-button-container div:first-child{color:#0009}.apply-button-container button{padding:0 54px}.spinner-loader{height:200px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}.batch-range-title{font-weight:700;margin-bottom:8px}.batch-range-columns{display:flex;flex-direction:row;gap:24px}.batch-column{display:flex;flex-direction:column;min-width:180px}.options-checkbox .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.MatLegacyRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { kind: "component", type: i4.MatLegacyRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i1.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i6.MatLegacyCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i7.MatLegacyFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLegacyPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i8.MatLegacyInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", exportAs: ["matInput"] }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i10.MatLegacyButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i11.MatLegacyProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { kind: "pipe", type: i3.KeyValuePipe, name: "keyvalue" }] }); }
366
+ }
367
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EntitySelectionsComponent, decorators: [{
368
+ type: Component,
369
+ args: [{ selector: "sb-uic-entity-selections", template: "<div class=\"flex justify-between dialog-heading items-center\">\n <h2 mat-dialog-title class=\"mb-0\">{{ getModalTitle() }}</h2>\n <button mat-icon-button class=\"close-button\" (click)=\"onClose()\">\n <mat-icon>close</mat-icon>\n </button>\n</div>\n\n<div mat-dialog-content>\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre ||\n selectionType === selectionTypeEnum.Batch ||\n selectionType === selectionTypeEnum.Organizations\n \">\n <!-- Search Box -->\n <div class=\"search-container flex items-center gap-4\">\n <div class=\"mat-full-radius flex-grow\">\n <mat-form-field appearance=\"outline\" class=\"w-full\">\n <mat-icon matPrefix>search</mat-icon>\n <input matInput placeholder=\"Type here to search...\" [formControl]=\"searchControl\" (keyup.enter)=\"search()\" />\n </mat-form-field>\n </div>\n <button\n mat-flat-button\n [disabled]=\"!searchControl.value\"\n class=\"flex items-center rounded-full new-bg-color font-bold text-sm text-white search-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n\n <div class=\"p-4 mt-2\">\n <!-- Filter Options -->\n <ng-container *ngIf=\"dataList.length && this.selectionType !== selectionTypeEnum.Cadre && this.selectionType !== selectionTypeEnum.Batch\">\n <div class=\"filter-options\">\n <mat-radio-group [(ngModel)]=\"filterValue\" aria-label=\"Filter options\" (change)=\"onFilterChange($event)\">\n <ng-container *ngFor=\"let item of radioSelections\">\n <mat-radio-button [value]=\"item?.value\">{{ item?.label }}</mat-radio-button>\n </ng-container>\n </mat-radio-group>\n </div>\n </ng-container>\n\n <div class=\"org-container\">\n <!-- A-Z Filter Bar -->\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!isLoading\">\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType !== selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of alphabet; let i = index; let last = last\">\n <button\n mat-button\n class=\"letter-button\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n <div class=\"alphabet-filter\" *ngIf=\"this.selectionType === selectionTypeEnum.Batch\">\n <ng-container *ngFor=\"let letter of batchRanges; let i = index; let last = last\">\n <button\n mat-button\n class=\"range-button px-4\"\n (click)=\"scrollToSection(letter)\"\n [ngClass]=\"{\n 'active-range-btn': selectedCharacterRange === letter\n }\">\n {{ letter }}\n </button>\n <div class=\"divider-apl\" *ngIf=\"!last\"></div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"checkIfData; else noData\">\n <div class=\"flex overflow-x-auto\">\n <ng-container *ngFor=\"let group of groupedEntityData | keyvalue\">\n <div class=\"org-column p-2 mr-4\" [attr.id]=\"'section-' + group.key\">\n <div class=\"org-list\">\n <div class=\"batch-range-columns\">\n <ng-container *ngIf=\"group.value && group.value.length\">\n <ng-container *ngFor=\"let column of group.value\">\n <div class=\"batch-column\">\n <div *ngFor=\"let entity of column\" class=\"org-card py-2\">\n <ng-container\n *ngIf=\"\n selectionType === selectionTypeEnum.Designation ||\n selectionType === selectionTypeEnum.Organizations ||\n selectionType === selectionTypeEnum.Service ||\n selectionType === selectionTypeEnum.Cadre\n \">\n <mat-checkbox\n [checked]=\"isSelected(entity)\"\n (change)=\"toggleSelection(entity)\"\n [title]=\"entity?.name || entity?.designation || entity?.channel\">\n {{ entity?.name || entity?.designation || entity?.channel }}\n </mat-checkbox>\n </ng-container>\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Batch\">\n <mat-checkbox [checked]=\"isSelected(entity)\" (change)=\"toggleSelection(entity)\" [title]=\"entity\">\n {{ entity }}\n </mat-checkbox>\n </ng-container>\n </div>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-template #noData>\n <div class=\"no-data p-4 flex flex-column items-center justify-center\">\n <img src=\"/assets/icons/no-events.png\" alt=\"no-data\" />\n <span class=\"font-bold\">No information to display yet</span>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.Group\">\n <ng-container *ngIf=\"isLoading\">\n <div class=\"spinner-loader flex items-center justify-center\">\n <mat-spinner></mat-spinner>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"!isLoading\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"selectionType === selectionTypeEnum.VerificationStatus\">\n <div class=\"flex gap-16 items-center p-4 options-checkbox\">\n <ng-container *ngFor=\"let group of dataList\">\n <mat-checkbox [checked]=\"isSelected(group)\" (change)=\"toggleSelection(group)\" [title]=\"group\">\n {{ group }}\n </mat-checkbox>\n </ng-container>\n </div>\n </ng-container>\n</div>\n\n<mat-dialog-actions>\n <ng-container *ngIf=\"checkIfData\">\n <div class=\"flex gap-4 items-center ml-auto mr-1 apply-button-container my-2\">\n <div class=\"text-xs\">{{ selectedData.length }} items selected</div>\n <button\n mat-flat-button\n [disabled]=\"selectedData.length === 0\"\n (click)=\"applySelections()\"\n class=\"flex items-center justify-center rounded-full new-bg-color font-bold text-sm text-white mt-2\">\n Apply\n </button>\n </div>\n </ng-container>\n</mat-dialog-actions>\n", styles: [":host{display:block}.dialog-heading{border-bottom:2px solid rgba(0,0,0,.12);padding:0 16px}::ng-deep .mat-mdc-dialog-container .mdc-dialog__title{margin-bottom:8px!important;font-family:Montserrat;font-weight:600;font-size:16px;color:#000000de;padding:0 0 9px}.close-button{margin-right:-8px}::ng-deep .mat-form-field-wrapper{padding-bottom:0!important}.search-button{padding:4px 24px}.filter-options{margin-bottom:15px}.filter-options .mat-radio-button{margin-right:24px}.org-container{display:flex;flex-direction:column}.alphabet-filter{display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;padding:8px 0}.alphabet-filter .divider-apl{width:1px;height:14px;background-color:#00000029}.alphabet-filter .letter-button,.alphabet-filter .range-button{min-width:30px;padding:0;margin:2px;line-height:30px;font-family:Lato;font-weight:400;font-size:12px;color:#0009}.alphabet-filter .letter-button.active-range-btn,.alphabet-filter .active-range-btn.range-button{font-weight:700;font-size:14px;color:#000}.alphabet-filter .range-button{padding:0 16px!important}.organization-scroll{flex:1;overflow-x:auto;white-space:nowrap}.org-row{display:flex;flex-direction:row}.org-column .org-list{display:flex;flex-direction:column;gap:6px}.org-column .org-card .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;width:180px;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}:host ::ng-deep .mat-mdc-dialog-content{max-height:79vh!important}.apply-button-container div:first-child{color:#0009}.apply-button-container button{padding:0 54px}.spinner-loader{height:200px}.no-data span{font-family:Lato;font-size:8.98px;color:#000000de}.batch-range-title{font-weight:700;margin-bottom:8px}.batch-range-columns{display:flex;flex-direction:row;gap:24px}.batch-column{display:flex;flex-direction:column;min-width:180px}.options-checkbox .mat-checkbox ::ng-deep .mat-checkbox-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;font-family:Lato;font-weight:700;font-size:14px;line-height:14px;color:#000000de}\n"] }]
370
+ }], ctorParameters: function () { return [{ type: i1.MatDialogRef }, { type: i2.AccessControlService }]; } });
371
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXNlbGVjdGlvbnMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicmFyeS9zdW5iaXJkLWNiL2FjY2Vzcy1zZXR0aW5ncy9zcmMvbGliL19jb21tb24vZGlhbG9ncy9lbnRpdHktc2VsZWN0aW9ucy9lbnRpdHktc2VsZWN0aW9ucy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJyYXJ5L3N1bmJpcmQtY2IvYWNjZXNzLXNldHRpbmdzL3NyYy9saWIvX2NvbW1vbi9kaWFsb2dzL2VudGl0eS1zZWxlY3Rpb25zL2VudGl0eS1zZWxlY3Rpb25zLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUVyRSxPQUFPLEVBQUUsZUFBZSxFQUFnQixNQUFNLDBCQUEwQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDakUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDOUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7Ozs7QUFPM0MsTUFBTSxPQUFPLHlCQUF5QjtJQW1CcEMsWUFBbUIsU0FBa0QsRUFBVSxvQkFBMEM7UUFBdEcsY0FBUyxHQUFULFNBQVMsQ0FBeUM7UUFBVSx5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBbEJqSCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUN2QyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGtCQUFhLEdBQUcsSUFBSSxXQUFXLENB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QVEsRUFBRSxDQUFDO0lBQzNCLENBQUM7K0dBN1hVLHlCQUF5QjttR0FBekIseUJBQXlCLGdFQ2R0QywrelBBa0xBOzs0RkRwS2EseUJBQXlCO2tCQUxyQyxTQUFTOytCQUNFLDBCQUEwQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5qZWN0LCBPbkluaXQsIE9uRGVzdHJveSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBBY2Nlc3NDb250cm9sU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi9fc2VydmljZXMvYWNjZXNzLWNvbnRyb2wuc2VydmljZVwiO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBLCBNYXREaWFsb2dSZWYgfSBmcm9tIFwiQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nXCI7XG5pbXBvcnQgeyBGb3JtQ29udHJvbCB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgQkFUQ0hfUkFOR0VTIH0gZnJvbSBcIi4uLy4uLy4uL19jb25zdGFudHMvYXBwLmNvbnN0YW50c1wiO1xuaW1wb3J0IHsgTnNBY2Nlc3NDb250cm9sQ29uZmlnIH0gZnJvbSBcIi4uLy4uLy4uL19tb2RlbHMvYWNjZXNzLWNvbnRyb2wubW9kZWxcIjtcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJzYi11aWMtZW50aXR5LXNlbGVjdGlvbnNcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9lbnRpdHktc2VsZWN0aW9ucy5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vZW50aXR5LXNlbGVjdGlvbnMuY29tcG9uZW50LnNjc3NcIl1cbn0pXG5leHBvcnQgY2xhc3MgRW50aXR5U2VsZWN0aW9uc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIGlzTG9hZGluZyA9IGZhbHNlO1xuICBzZWFyY2hDb250cm9sID0gbmV3IEZvcm1Db250cm9sKFwiXCIpO1xuICBmaWx0ZXJWYWx1ZTogXCJhbGxcIiB8IFwic2VsZWN0ZWRcIiB8IFwibm90U2VsZWN0ZWRcIiA9IFwiYWxsXCI7XG4gIGFscGhhYmV0ID0gXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiNcIi5zcGxpdChcIlwiKTtcblxuICBkYXRhTGlzdDogYW55W10gPSBbXTtcblxuICBzZWxlY3RlZERhdGE6IG51bWJlcltdID0gW107XG4gIGdyb3VwZWRFbnRpdHlEYXRhOiB7IFtrZXk6IHN0cmluZ106IGFueVtdIH0gPSB7fTtcbiAgc2VsZWN0aW9uVHlwZSA9IFwiXCI7XG4gIHNlbGVjdGlvblR5cGVFbnVtID0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGU7XG4gIHJhZGlvU2VsZWN0aW9uczogeyB2YWx1ZTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xuICBiYXRjaFJhbmdlczogYW55O1xuICBzZWxlY3RlZENoYXJhY3RlclJhbmdlOiBzdHJpbmc7XG4gIGFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbiE6IE5zQWNjZXNzQ29udHJvbENvbmZpZy5JQWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uO1xuXG4gIHB1YmxpYyByZWFkb25seSBkYXRhID0gaW5qZWN0PHsgcnVsZTogYW55OyBjb25kaXRpb246IGFueTsgc2VsZWN0ZWQ6IGFueVtdIH0+KE1BVF9ESUFMT0dfREFUQSk7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxFbnRpdHlTZWxlY3Rpb25zQ29tcG9uZW50PiwgcHJpdmF0ZSBhY2Nlc3NDb250cm9sU2VydmljZTogQWNjZXNzQ29udHJvbFNlcnZpY2UpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gSWYgZGF0YSB3YXMgcGFzc2VkIHRvIHRoZSBkaWFsb2csIGluaXRpYWxpemUgc2VsZWN0aW9uc1xuICAgIHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uID0gdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5hY2Nlc3NDb250cm9sQ29uZmlnKCkuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uO1xuICAgIGlmICh0aGlzLmRhdGEpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uVHlwZSA9IHRoaXMuZGF0YT8uY29uZGl0aW9uPy5lbnRpdHk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRhdGEgJiYgdGhpcy5kYXRhLnNlbGVjdGVkKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YSA9IHRoaXMuZGF0YS5zZWxlY3RlZDtcbiAgICB9XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gc2VhcmNoIGNvbnRyb2wgY2hhbmdlc1xuICAgIHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgocXVlcnk6IHN0cmluZykgPT4ge1xuICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uVHlwZSkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuc2VsZWN0aW9uVHlwZSkge1xuICAgICAgICAgIGNhc2UgdGhpcy5zZWxlY3Rpb25UeXBlRW51bS5TZXJ2aWNlOlxuICAgICAgICAgICAgdGhpcy5nZXRTZXJ2aWNlc0xpc3QocXVlcnkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSB0aGlzLnNlbGVjdGlvblR5cGVFbnVtLkNhZHJlOlxuICAgICAgICAgICAgdGhpcy5nZXRDYWRyZUxpc3QocXVlcnkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSB0aGlzLnNlbGVjdGlvblR5cGVFbnVtLkJhdGNoOlxuICAgICAgICAgICAgdGhpcy5nZXRCYXRjaExpc3QocXVlcnkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuaW5pdGlhbGl6ZURpc3BsYXkoKTtcbiAgfVxuXG4gIGluaXRpYWxpemVEaXNwbGF5KCk6IHZvaWQge1xuICAgIHN3aXRjaCAodGhpcy5zZWxlY3Rpb25UeXBlKSB7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLk9yZ2FuaXphdGlvbnM6XG4gICAgICAgIHRoaXMucmFkaW9TZWxlY3Rpb25zID0gdGhpcy5hY2Nlc3NDb250cm9sQ3JpdGVyaWFTZWxlY3Rpb24ub3JnYW5pemF0aW9uUmFkaW9TZWxlY3Rpb247XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5EZXNpZ25hdGlvbjpcbiAgICAgICAgY29uc3Qgc2VsZWN0aW9uSWRzID0gdGhpcy5kYXRhPy5ydWxlPy5jb25kaXRpb25zPy5maW5kKFxuICAgICAgICAgIChjOiBhbnkpID0+IGMuZW50aXR5ID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Pcmdhbml6YXRpb25zXG4gICAgICAgICk/LnNlbGVjdGlvbnM7XG4gICAgICAgIGlmIChzZWxlY3Rpb25JZHM/Lmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuZ2V0RGVzaWduYXRpb25zTGlzdChcIlwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJhZGlvU2VsZWN0aW9ucyA9IHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uLmRlc2lnbmF0aW9uUmFkaW9TZWxlY3Rpb247XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5TZXJ2aWNlOlxuICAgICAgICB0aGlzLnJhZGlvU2VsZWN0aW9ucyA9IHRoaXMuYWNjZXNzQ29udHJvbENyaXRlcmlhU2VsZWN0aW9uLnNlcnZpY2VzUmFkaW9TZWxlY3Rpb247XG4gICAgICAgIHRoaXMuZ2V0U2VydmljZXNMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5DYWRyZTpcbiAgICAgICAgdGhpcy5yYWRpb1NlbGVjdGlvbnMgPSBbeyB2YWx1ZTogXCJhbGxcIiwgbGFiZWw6IFwiQWxsXCIgfV07XG4gICAgICAgIHRoaXMuZ2V0Q2FkcmVMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5CYXRjaDpcbiAgICAgICAgdGhpcy5yYWRpb1NlbGVjdGlvbnMgPSBbeyB2YWx1ZTogXCJhbGxcIiwgbGFiZWw6IFwiQWxsXCIgfV07XG4gICAgICAgIHRoaXMuZ2V0QmF0Y2hMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Hcm91cDpcbiAgICAgICAgdGhpcy5nZXRHcm91cExpc3QoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlZlcmlmaWNhdGlvblN0YXR1czpcbiAgICAgICAgdGhpcy5nZXRWZXJpZmljYXRpb25TdGF0dXMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgb25DbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTZWxlY3Rpb25WYWx1ZShpdGVtOiBhbnkpOiBhbnkge1xuICAgIGlmICh0eXBlb2YgaXRlbSAhPT0gXCJvYmplY3RcIiB8fCBpdGVtID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gaXRlbTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5zZWxlY3Rpb25UeXBlID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5DYWRyZSB8fFxuICAgICAgdGhpcy5zZWxlY3Rpb25UeXBlID09PSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5TZXJ2aWNlIHx8XG4gICAgICB0aGlzLnNlbGVjdGlvblR5cGUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkRlc2lnbmF0aW9uXG4gICAgKSB7XG4gICAgICByZXR1cm4gaXRlbT8ubmFtZTtcbiAgICB9XG5cbiAgICByZXR1cm4gaXRlbT8uaWQgfHwgaXRlbT8uaWRlbnRpZmllciB8fCBpdGVtO1xuICB9XG5cbiAgaXNTZWxlY3RlZChpdGVtOiBhbnkpOiBib29sZWFuIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0U2VsZWN0aW9uVmFsdWUoaXRlbSk7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWREYXRhLmluY2x1ZGVzKHZhbHVlKTtcbiAgfVxuXG4gIHRvZ2dsZVNlbGVjdGlvbihpdGVtOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0U2VsZWN0aW9uVmFsdWUoaXRlbSk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnNlbGVjdGVkRGF0YS5pbmRleE9mKHZhbHVlKTtcblxuICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkRGF0YS5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBvbkZpbHRlckNoYW5nZShldmVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXJWYWx1ZSA9IGV2ZW50LnZhbHVlO1xuICAgIHRoaXMuZ2V0RmlsdGVyZWRFbnRpdHlHcm91cGVkKCk7XG4gIH1cblxuICBzZWFyY2goKTogdm9pZCB7XG4gICAgc3dpdGNoICh0aGlzLnNlbGVjdGlvblR5cGUpIHtcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuRGVzaWduYXRpb246XG4gICAgICAgIHRoaXMuZ2V0RGVzaWduYXRpb25zTGlzdCh0aGlzLnNlYXJjaENvbnRyb2wudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuT3JnYW5pemF0aW9uczpcbiAgICAgICAgdGhpcy5nZXRPcmdhbmlzYXRpb25zTGlzdCh0aGlzLnNlYXJjaENvbnRyb2wudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuU2VydmljZTpcbiAgICAgICAgdGhpcy5nZXRTZXJ2aWNlc0xpc3QodGhpcy5zZWFyY2hDb250cm9sLnZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkNhZHJlOlxuICAgICAgICB0aGlzLmdldENhZHJlTGlzdCh0aGlzLnNlYXJjaENvbnRyb2wudmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuQmF0Y2g6XG4gICAgICAgIHRoaXMuZ2V0Q2FkcmVMaXN0KHRoaXMuc2VhcmNoQ29udHJvbC52YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpOiB2b2lkIHtcbiAgICBsZXQgZmlsdGVyZWQgPSB0aGlzLmRhdGFMaXN0O1xuXG4gICAgLy8gRmlsdGVyIGJ5IHJhZGlvIHNlbGVjdGlvbiBvbmx5XG4gICAgaWYgKHRoaXMuZmlsdGVyVmFsdWUgPT09IFwic2VsZWN0ZWRcIikge1xuICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIob3JnID0+IHRoaXMuaXNTZWxlY3RlZChvcmcpKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZmlsdGVyVmFsdWUgPT09IFwibm90U2VsZWN0ZWRcIikge1xuICAgICAgZmlsdGVyZWQgPSBmaWx0ZXJlZC5maWx0ZXIob3JnID0+ICF0aGlzLmlzU2VsZWN0ZWQob3JnKSk7XG4gICAgfVxuXG4gICAgLy8gRm9yIGJhdGNoLCBncm91cCBieSByYW5nZSBhbmQgY2h1bmsgZWFjaCByYW5nZVxuICAgIGlmICh0aGlzLnNlbGVjdGlvblR5cGUgPT09IHRoaXMuc2VsZWN0aW9uVHlwZUVudW0uQmF0Y2gpIHtcbiAgICAgIGNvbnN0IGJhdGNoR3JvdXBlZCA9IHRoaXMuZ3JvdXBCYXRjaEJ5UmFuZ2UoZmlsdGVyZWQpO1xuICAgICAgY29uc3QgY2h1bmtlZDogeyBba2V5OiBzdHJpbmddOiBhbnlbXVtdIH0gPSB7fTtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGJhdGNoR3JvdXBlZCkge1xuICAgICAgICBjaHVua2VkW2tleV0gPSB0aGlzLmNodW5rQXJyYXkoYmF0Y2hHcm91cGVkW2tleV0sIDgpO1xuICAgICAgfVxuICAgICAgdGhpcy5ncm91cGVkRW50aXR5RGF0YSA9IGNodW5rZWQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRm9yIGFsbCBvdGhlciB0eXBlcywgZ3JvdXAgYnkgbGV0dGVyIGFuZCBjaHVuayBlYWNoIGdyb3VwXG4gICAgY29uc3QgZ3JvdXBlZDogeyBba2V5OiBzdHJpbmddOiBhbnlbXVtdIH0gPSB7fTtcbiAgICBjb25zdCB0ZW1wOiB7IFtrZXk6IHN0cmluZ106IGFueVtdIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IG9yZyBvZiBmaWx0ZXJlZCkge1xuICAgICAgbGV0IGVudGl0eSA9IG9yZz8uY2hhbm5lbCB8fCBvcmc/Lm5hbWUgfHwgb3JnPy5kZXNpZ25hdGlvbjtcbiAgICAgIGxldCBsZXR0ZXIgPSBlbnRpdHk/LmNoYXJBdCgwKT8udG9VcHBlckNhc2UoKSB8fCBcIiNcIjtcbiAgICAgIGlmICghL15bQS1aXSQvLnRlc3QobGV0dGVyKSkge1xuICAgICAgICBsZXR0ZXIgPSBcIiNcIjtcbiAgICAgIH1cbiAgICAgIGlmICghdGVtcFtsZXR0ZXJdKSB0ZW1wW2xldHRlcl0gPSBbXTtcbiAgICAgIHRlbXBbbGV0dGVyXS5wdXNoKG9yZyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgbGV0dGVyIGluIHRlbXApIHtcbiAgICAgIGdyb3VwZWRbbGV0dGVyXSA9IHRoaXMuY2h1bmtBcnJheSh0ZW1wW2xldHRlcl0sIDcpO1xuICAgIH1cbiAgICB0aGlzLmdyb3VwZWRFbnRpdHlEYXRhID0gZ3JvdXBlZDtcbiAgfVxuXG4gIHNjcm9sbFRvU2VjdGlvbihsZXR0ZXI6IHN0cmluZykge1xuICAgIGNvbnN0IHNlY3Rpb24gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgc2VjdGlvbi0ke2xldHRlcn1gKTtcbiAgICBpZiAoc2VjdGlvbikge1xuICAgICAgdGhpcy5zZWxlY3RlZENoYXJhY3RlclJhbmdlID0gbGV0dGVyO1xuICAgICAgc2VjdGlvbi5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiBcInNtb290aFwiLCBpbmxpbmU6IFwic3RhcnRcIiB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUFscGhhYmV0KCk6IHZvaWQge1xuICAgIGNvbnN0IGNoYXJzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IGRhdGEgb2YgdGhpcy5kYXRhTGlzdCkge1xuICAgICAgbGV0IGxldHRlciA9IFwiI1wiO1xuXG4gICAgICBjb25zdCB2YWx1ZSA9IGRhdGE/LmNoYW5uZWwgfHwgZGF0YT8ubmFtZSB8fCBkYXRhPy5kZXNpZ25hdGlvbjtcbiAgICAgIGxldHRlciA9IHZhbHVlLmNoYXJBdCgwKT8udG9VcHBlckNhc2UoKSB8fCBcIiNcIjtcblxuICAgICAgaWYgKCEvXltBLVpdJC8udGVzdChsZXR0ZXIpKSB7XG4gICAgICAgIGxldHRlciA9IFwiI1wiO1xuICAgICAgfVxuXG4gICAgICBjaGFycy5hZGQobGV0dGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3J0ZWQgPSBBcnJheS5mcm9tKGNoYXJzKVxuICAgICAgLmZpbHRlcihjID0+IGMgIT09IFwiI1wiKVxuICAgICAgLnNvcnQoKTtcbiAgICBpZiAoY2hhcnMuaGFzKFwiI1wiKSkgc29ydGVkLnB1c2goXCIjXCIpO1xuXG4gICAgdGhpcy5hbHBoYWJldCA9IHNvcnRlZDtcbiAgfVxuXG4gIGdldCBjaGVja0lmRGF0YSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHRoaXMuZ3JvdXBlZEVudGl0eURhdGEgJiYgT2JqZWN0LmtleXModGhpcy5ncm91cGVkRW50aXR5RGF0YSkubGVuZ3RoID4gMCkgfHxcbiAgICAgICh0aGlzLnNlbGVjdGlvblR5cGUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkdyb3VwICYmIHRoaXMuZGF0YUxpc3QubGVuZ3RoID4gMCkgfHxcbiAgICAgICh0aGlzLnNlbGVjdGlvblR5cGUgPT09IE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlZlcmlmaWNhdGlvblN0YXR1cyAmJiB0aGlzLmRhdGFMaXN0Lmxlbmd0aCA+IDApXG4gICAgKTtcbiAgfVxuXG4gIGdldE9yZ2FuaXNhdGlvbnNMaXN0KHF1ZXJ5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XG4gICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5mZXRjaE9yZ0xpc3QocXVlcnkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiByZXNwb25zZSA9PiB7XG4gICAgICAgIGlmIChyZXNwb25zZT8ucmVzdWx0ICYmIHJlc3BvbnNlPy5yZXN1bHQ/LnJlc3BvbnNlPy5jb250ZW50KSB7XG4gICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IHJlc3BvbnNlLnJlc3VsdC5yZXNwb25zZS5jb250ZW50O1xuICAgICAgICAgIHRoaXMudXBkYXRlQWxwaGFiZXQoKTtcbiAgICAgICAgICB0aGlzLmdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuZGF0YUxpc3QgPSBbXTtcbiAgICAgICAgICB0aGlzLmFscGhhYmV0ID0gW107XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0RGVzaWduYXRpb25zTGlzdChxdWVyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IHNlbGVjdGlvbklkcyA9IHRoaXMuZGF0YT8ucnVsZT8uY29uZGl0aW9ucz8uZmluZCgoYzogYW55KSA9PiBjLmVudGl0eSA9PT0gTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuT3JnYW5pemF0aW9ucyk/LnNlbGVjdGlvbnM7XG4gICAgaWYgKHNlbGVjdGlvbklkcz8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCBjYXRlZ29yaWVzID0gc2VsZWN0aW9uSWRzLm1hcCgoZWxlOiBzdHJpbmcpID0+IGAke2VsZX1fb2Rjc19kZXNpZ25hdGlvbmApO1xuICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZVxuICAgICAgICAuZmV0Y2hEZXNpZ25hdGlvbnNXaXRoT3JnKGNhdGVnb3JpZXMsIHF1ZXJ5KVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICAgIG5leHQ6IHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZT8ucmVzdWx0ICYmIHJlc3BvbnNlPy5yZXN1bHQ/LlRlcm0pIHtcbiAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IHJlc3BvbnNlPy5yZXN1bHQ/LlRlcm07XG4gICAgICAgICAgICAgIHRoaXMudXBkYXRlQWxwaGFiZXQoKTtcbiAgICAgICAgICAgICAgdGhpcy5nZXRGaWx0ZXJlZEVudGl0eUdyb3VwZWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuZGF0YUxpc3QgPSBbXTtcbiAgICAgICAgICAgICAgdGhpcy5hbHBoYWJldCA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZVxuICAgICAgICAuZmV0Y2hEZXNpZ25hdGlvbihxdWVyeSlcbiAgICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgICBuZXh0OiByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2U/LnJlc3VsdCAmJiByZXNwb25zZT8ucmVzdWx0Py5yZXN1bHQ/LmRhdGEpIHtcbiAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IHJlc3BvbnNlPy5yZXN1bHQ/LnJlc3VsdD8uZGF0YTtcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVBbHBoYWJldCgpO1xuICAgICAgICAgICAgICB0aGlzLmdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5kYXRhTGlzdCA9IFtdO1xuICAgICAgICAgICAgICB0aGlzLmFscGhhYmV0ID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldFNlcnZpY2VzTGlzdChxdWVyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYmFzZUxpc3QgPSB0aGlzLmFjY2Vzc0NvbnRyb2xTZXJ2aWNlLmhvbGRTZXJ2aWNlQ2FkcmViYXRjaCgpLnNlcnZpY2U7XG4gICAgdGhpcy5kYXRhTGlzdCA9IHF1ZXJ5ID8gYmFzZUxpc3QuZmlsdGVyKHNlcnZpY2UgPT4gc2VydmljZS5uYW1lPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHF1ZXJ5LnRvTG93ZXJDYXNlKCkpKSA6IGJhc2VMaXN0O1xuICAgIHRoaXMudXBkYXRlQWxwaGFiZXQoKTtcbiAgICB0aGlzLmdldEZpbHRlcmVkRW50aXR5R3JvdXBlZCgpO1xuICB9XG5cbiAgZ2V0Q2FkcmVMaXN0KHF1ZXJ5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBiYXNlTGlzdCA9IHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2UuaG9sZFNlcnZpY2VDYWRyZWJhdGNoKCkuY2FkcmU7XG4gICAgdGhpcy5kYXRhTGlzdCA9IHF1ZXJ5ID8gYmFzZUxpc3QuZmlsdGVyKGNhZHJlID0+IGNhZHJlLm5hbWU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkudG9Mb3dlckNhc2UoKSkpIDogYmFzZUxpc3Q7XG4gICAgdGhpcy51cGRhdGVBbHBoYWJldCgpO1xuICAgIHRoaXMuZ2V0RmlsdGVyZWRFbnRpdHlHcm91cGVkKCk7XG4gIH1cblxuICBnZXRCYXRjaExpc3QocXVlcnk6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGJhc2VMaXN0ID0gdGhpcy5hY2Nlc3NDb250cm9sU2VydmljZS5ob2xkU2VydmljZUNhZHJlYmF0Y2goKS5iYXRjaDtcbiAgICB0aGlzLmRhdGFMaXN0ID0gcXVlcnkgPyBiYXNlTGlzdC5maWx0ZXIoYmF0Y2ggPT4gYmF0Y2gudG9TdHJpbmcoKS5pbmNsdWRlcyhxdWVyeSkpIDogYmFzZUxpc3Q7XG4gICAgdGhpcy51cGRhdGVCYXRjaFJhbmdlcygpO1xuICAgIHRoaXMuZ2V0RmlsdGVyZWRFbnRpdHlHcm91cGVkKCk7XG4gIH1cblxuICBnZXRHcm91cExpc3QoKTogdm9pZCB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuYWNjZXNzQ29udHJvbFNlcnZpY2VcbiAgICAgIC5mZXRjaEdyb3Vwc0xpc3QoKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3BvbnNlPy5yZXN1bHQgJiYgcmVzcG9uc2U/LnJlc3VsdD8ucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YUxpc3QgPSByZXNwb25zZS5yZXN1bHQucmVzcG9uc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0VmVyaWZpY2F0aW9uU3RhdHVzKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0YUxpc3QgPSB0aGlzLmFjY2Vzc0NvbnRyb2xDcml0ZXJpYVNlbGVjdGlvbi52ZXJpZmljYXRpb25TdGF0dXM7XG4gIH1cblxuICB1cGRhdGVCYXRjaFJhbmdlcygpOiB2b2lkIHtcbiAgICB0aGlzLmJhdGNoUmFuZ2VzID0gQkFUQ0hfUkFOR0VTLm1hcChyYW5nZSA9PiByYW5nZS5sYWJlbCk7XG4gIH1cblxuICBncm91cEJhdGNoQnlSYW5nZShiYXRjaExpc3Q6IG51bWJlcltdKSB7XG4gICAgY29uc3QgZ3JvdXBlZDogeyBba2V5OiBzdHJpbmddOiBudW1iZXJbXSB9ID0ge307XG4gICAgZm9yIChjb25zdCByYW5nZSBvZiBCQVRDSF9SQU5HRVMpIHtcbiAgICAgIGdyb3VwZWRbcmFuZ2UubGFiZWxdID0gYmF0Y2hMaXN0LmZpbHRlcih5ZWFyID0+IHllYXIgPj0gcmFuZ2Uuc3RhcnQgJiYgeWVhciA8PSByYW5nZS5lbmQpO1xuICAgIH1cbiAgICByZXR1cm4gZ3JvdXBlZDtcbiAgfVxuXG4gIGdldE1vZGFsVGl0bGUoKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKHRoaXMuc2VsZWN0aW9uVHlwZSkge1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5EZXNpZ25hdGlvbjpcbiAgICAgICAgcmV0dXJuIFwiU2VsZWN0IERlc2lnbmF0aW9uXCI7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLk9yZ2FuaXphdGlvbnM6XG4gICAgICAgIHJldHVybiBcIlNlbGVjdCBPcmdhbmlzYXRpb25cIjtcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuU2VydmljZTpcbiAgICAgICAgcmV0dXJuIFwiU2VsZWN0IFNlcnZpY2VzXCI7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLkNhZHJlOlxuICAgICAgICByZXR1cm4gXCJTZWxlY3QgQ2FkcmVcIjtcbiAgICAgIGNhc2UgTnNBY2Nlc3NDb250cm9sQ29uZmlnLlNlbGVjdGlvblR5cGUuQmF0Y2g6XG4gICAgICAgIHJldHVybiBcIlNlbGVjdCBCYXRjaFwiO1xuICAgICAgY2FzZSBOc0FjY2Vzc0NvbnRyb2xDb25maWcuU2VsZWN0aW9uVHlwZS5Hcm91cDpcbiAgICAgICAgcmV0dXJuIFwiU2VsZWN0IEdyb3VwXCI7XG4gICAgICBjYXNlIE5zQWNjZXNzQ29udHJvbENvbmZpZy5TZWxlY3Rpb25UeXBlLlZlcmlmaWNhdGlvblN0YXR1czpcbiAgICAgICAgcmV0dXJuIFwiVmVyaWZpY2F0aW9uIFN0YXR1c1wiO1xuICAgIH1cbiAgICByZXR1cm4gXCJcIjtcbiAgfVxuXG4gIGFwcGx5U2VsZWN0aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLmRpYWxvZ1JlZi5jbG9zZSh7XG4gICAgICBydWxlOiB0aGlzLmRhdGEucnVsZSxcbiAgICAgIGNvbmRpdGlvbjogdGhpcy5kYXRhLmNvbmRpdGlvbixcbiAgICAgIHNlbGVjdGVkOiB0aGlzLnNlbGVjdGVkRGF0YVxuICAgIH0pO1xuICB9XG5cbiAgY2h1bmtBcnJheTxUPihhcnJheTogVFtdLCBjaHVua1NpemU6IG51bWJlcik6IFRbXVtdIHtcbiAgICBjb25zdCByZXN1bHRzOiBUW11bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpICs9IGNodW5rU2l6ZSkge1xuICAgICAgcmVzdWx0cy5wdXNoKGFycmF5LnNsaWNlKGksIGkgKyBjaHVua1NpemUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJmbGV4IGp1c3RpZnktYmV0d2VlbiBkaWFsb2ctaGVhZGluZyBpdGVtcy1jZW50ZXJcIj5cbiAgPGgyIG1hdC1kaWFsb2ctdGl0bGUgY2xhc3M9XCJtYi0wXCI+e3sgZ2V0TW9kYWxUaXRsZSgpIH19PC9oMj5cbiAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gY2xhc3M9XCJjbG9zZS1idXR0b25cIiAoY2xpY2spPVwib25DbG9zZSgpXCI+XG4gICAgPG1hdC1pY29uPmNsb3NlPC9tYXQtaWNvbj5cbiAgPC9idXR0b24+XG48L2Rpdj5cblxuPGRpdiBtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gIDxuZy1jb250YWluZXJcbiAgICAqbmdJZj1cIlxuICAgICAgc2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uRGVzaWduYXRpb24gfHxcbiAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLlNlcnZpY2UgfHxcbiAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkNhZHJlIHx8XG4gICAgICBzZWxlY3Rpb25UeXBlID09PSBzZWxlY3Rpb25UeXBlRW51bS5CYXRjaCB8fFxuICAgICAgc2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uT3JnYW5pemF0aW9uc1xuICAgIFwiPlxuICAgIDwhLS0gU2VhcmNoIEJveCAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2VhcmNoLWNvbnRhaW5lciBmbGV4IGl0ZW1zLWNlbnRlciBnYXAtNFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1hdC1mdWxsLXJhZGl1cyBmbGV4LWdyb3dcIj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCIgY2xhc3M9XCJ3LWZ1bGxcIj5cbiAgICAgICAgICA8bWF0LWljb24gbWF0UHJlZml4PnNlYXJjaDwvbWF0LWljb24+XG4gICAgICAgICAgPGlucHV0IG1hdElucHV0IHBsYWNlaG9sZGVyPVwiVHlwZSBoZXJlIHRvIHNlYXJjaC4uLlwiIFtmb3JtQ29udHJvbF09XCJzZWFyY2hDb250cm9sXCIgKGtleXVwLmVudGVyKT1cInNlYXJjaCgpXCIgLz5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtZmxhdC1idXR0b25cbiAgICAgICAgW2Rpc2FibGVkXT1cIiFzZWFyY2hDb250cm9sLnZhbHVlXCJcbiAgICAgICAgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciByb3VuZGVkLWZ1bGwgbmV3LWJnLWNvbG9yIGZvbnQtYm9sZCB0ZXh0LXNtIHRleHQtd2hpdGUgc2VhcmNoLWJ1dHRvblwiXG4gICAgICAgIChjbGljayk9XCJzZWFyY2goKVwiPlxuICAgICAgICBTZWFyY2hcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cInAtNCBtdC0yXCI+XG4gICAgICA8IS0tIEZpbHRlciBPcHRpb25zIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRhdGFMaXN0Lmxlbmd0aCAmJiB0aGlzLnNlbGVjdGlvblR5cGUgIT09IHNlbGVjdGlvblR5cGVFbnVtLkNhZHJlICYmIHRoaXMuc2VsZWN0aW9uVHlwZSAhPT0gc2VsZWN0aW9uVHlwZUVudW0uQmF0Y2hcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlci1vcHRpb25zXCI+XG4gICAgICAgICAgPG1hdC1yYWRpby1ncm91cCBbKG5nTW9kZWwpXT1cImZpbHRlclZhbHVlXCIgYXJpYS1sYWJlbD1cIkZpbHRlciBvcHRpb25zXCIgKGNoYW5nZSk9XCJvbkZpbHRlckNoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJhZGlvU2VsZWN0aW9uc1wiPlxuICAgICAgICAgICAgICA8bWF0LXJhZGlvLWJ1dHRvbiBbdmFsdWVdPVwiaXRlbT8udmFsdWVcIj57eyBpdGVtPy5sYWJlbCB9fTwvbWF0LXJhZGlvLWJ1dHRvbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbWF0LXJhZGlvLWdyb3VwPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwib3JnLWNvbnRhaW5lclwiPlxuICAgICAgICA8IS0tIEEtWiBGaWx0ZXIgQmFyIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItbG9hZGVyIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICA8bWF0LXNwaW5uZXI+PC9tYXQtc3Bpbm5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkaW5nXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoZWNrSWZEYXRhXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxwaGFiZXQtZmlsdGVyXCIgKm5nSWY9XCJ0aGlzLnNlbGVjdGlvblR5cGUgIT09IHNlbGVjdGlvblR5cGVFbnVtLkJhdGNoXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGxldHRlciBvZiBhbHBoYWJldDsgbGV0IGkgPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJsZXR0ZXItYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzY3JvbGxUb1NlY3Rpb24obGV0dGVyKVwiXG4gICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgICAgICdhY3RpdmUtcmFuZ2UtYnRuJzogc2VsZWN0ZWRDaGFyYWN0ZXJSYW5nZSA9PT0gbGV0dGVyXG4gICAgICAgICAgICAgICAgICB9XCI+XG4gICAgICAgICAgICAgICAgICB7eyBsZXR0ZXIgfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGl2aWRlci1hcGxcIiAqbmdJZj1cIiFsYXN0XCI+PC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWxwaGFiZXQtZmlsdGVyXCIgKm5nSWY9XCJ0aGlzLnNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkJhdGNoXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGxldHRlciBvZiBiYXRjaFJhbmdlczsgbGV0IGkgPSBpbmRleDsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyYW5nZS1idXR0b24gcHgtNFwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2Nyb2xsVG9TZWN0aW9uKGxldHRlcilcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgICAgICAgICAnYWN0aXZlLXJhbmdlLWJ0bic6IHNlbGVjdGVkQ2hhcmFjdGVyUmFuZ2UgPT09IGxldHRlclxuICAgICAgICAgICAgICAgICAgfVwiPlxuICAgICAgICAgICAgICAgICAge3sgbGV0dGVyIH19XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRpdmlkZXItYXBsXCIgKm5nSWY9XCIhbGFzdFwiPjwvZGl2PlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoZWNrSWZEYXRhOyBlbHNlIG5vRGF0YVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggb3ZlcmZsb3cteC1hdXRvXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGdyb3VwZWRFbnRpdHlEYXRhIHwga2V5dmFsdWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwib3JnLWNvbHVtbiBwLTIgbXItNFwiIFthdHRyLmlkXT1cIidzZWN0aW9uLScgKyBncm91cC5rZXlcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJvcmctbGlzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmF0Y2gtcmFuZ2UtY29sdW1uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJncm91cC52YWx1ZSAmJiBncm91cC52YWx1ZS5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBncm91cC52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmF0Y2gtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZW50aXR5IG9mIGNvbHVtblwiIGNsYXNzPVwib3JnLWNhcmQgcHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkRlc2lnbmF0aW9uIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uT3JnYW5pemF0aW9ucyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLlNlcnZpY2UgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb25UeXBlID09PSBzZWxlY3Rpb25UeXBlRW51bS5DYWRyZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImlzU2VsZWN0ZWQoZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ0b2dnbGVTZWxlY3Rpb24oZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cImVudGl0eT8ubmFtZSB8fCBlbnRpdHk/LmRlc2lnbmF0aW9uIHx8IGVudGl0eT8uY2hhbm5lbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVudGl0eT8ubmFtZSB8fCBlbnRpdHk/LmRlc2lnbmF0aW9uIHx8IGVudGl0eT8uY2hhbm5lbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLkJhdGNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggW2NoZWNrZWRdPVwiaXNTZWxlY3RlZChlbnRpdHkpXCIgKGNoYW5nZSk9XCJ0b2dnbGVTZWxlY3Rpb24oZW50aXR5KVwiIFt0aXRsZV09XCJlbnRpdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBlbnRpdHkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbm9EYXRhPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vLWRhdGEgcC00IGZsZXggZmxleC1jb2x1bW4gaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxpbWcgc3JjPVwiL2Fzc2V0cy9pY29ucy9uby1ldmVudHMucG5nXCIgYWx0PVwibm8tZGF0YVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9udC1ib2xkXCI+Tm8gaW5mb3JtYXRpb24gdG8gZGlzcGxheSB5ZXQ8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VsZWN0aW9uVHlwZSA9PT0gc2VsZWN0aW9uVHlwZUVudW0uR3JvdXBcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNMb2FkaW5nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1sb2FkZXIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgPG1hdC1zcGlubmVyPjwvbWF0LXNwaW5uZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNMb2FkaW5nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZmxleCBnYXAtMTYgaXRlbXMtY2VudGVyIHAtNCBvcHRpb25zLWNoZWNrYm94XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGRhdGFMaXN0XCI+XG4gICAgICAgICAgPG1hdC1jaGVja2JveCBbY2hlY2tlZF09XCJpc1NlbGVjdGVkKGdyb3VwKVwiIChjaGFuZ2UpPVwidG9nZ2xlU2VsZWN0aW9uKGdyb3VwKVwiIFt0aXRsZV09XCJncm91cFwiPlxuICAgICAgICAgICAge3sgZ3JvdXAgfX1cbiAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGlvblR5cGUgPT09IHNlbGVjdGlvblR5cGVFbnVtLlZlcmlmaWNhdGlvblN0YXR1c1wiPlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGdhcC0xNiBpdGVtcy1jZW50ZXIgcC00IG9wdGlvbnMtY2hlY2tib3hcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGdyb3VwIG9mIGRhdGFMaXN0XCI+XG4gICAgICAgIDxtYXQtY2hlY2tib3ggW2NoZWNrZWRdPVwiaXNTZWxlY3RlZChncm91cClcIiAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdGlvbihncm91cClcIiBbdGl0bGVdPVwiZ3JvdXBcIj5cbiAgICAgICAgICB7eyBncm91cCB9fVxuICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuXG48bWF0LWRpYWxvZy1hY3Rpb25zPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2hlY2tJZkRhdGFcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleCBnYXAtNCBpdGVtcy1jZW50ZXIgbWwtYXV0byBtci0xIGFwcGx5LWJ1dHRvbi1jb250YWluZXIgbXktMlwiPlxuICAgICAgPGRpdiBjbGFzcz1cInRleHQteHNcIj57eyBzZWxlY3RlZERhdGEubGVuZ3RoIH19IGl0ZW1zIHNlbGVjdGVkPC9kaXY+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1mbGF0LWJ1dHRvblxuICAgICAgICBbZGlzYWJsZWRdPVwic2VsZWN0ZWREYXRhLmxlbmd0aCA9PT0gMFwiXG4gICAgICAgIChjbGljayk9XCJhcHBseVNlbGVjdGlvbnMoKVwiXG4gICAgICAgIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1mdWxsIG5ldy1iZy1jb2xvciBmb250LWJvbGQgdGV4dC1zbSB0ZXh0LXdoaXRlIG10LTJcIj5cbiAgICAgICAgQXBwbHlcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuIl19