@huntsman-cancer-institute/cod 16.0.1 → 17.0.1

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 (56) hide show
  1. package/cod.module.d.ts +30 -31
  2. package/components/attribute-absolute.component.d.ts +28 -28
  3. package/components/attribute-base.d.ts +135 -135
  4. package/components/attribute-container.component.d.ts +50 -50
  5. package/components/attribute-default.component.d.ts +20 -20
  6. package/components/attribute-edit.component.d.ts +15 -15
  7. package/components/attribute-flex.component.d.ts +25 -25
  8. package/date/date-util.d.ts +9 -9
  9. package/esm2022/cod.module.mjs +114 -119
  10. package/esm2022/components/attribute-absolute.component.mjs +104 -104
  11. package/esm2022/components/attribute-base.mjs +564 -564
  12. package/esm2022/components/attribute-container.component.mjs +155 -155
  13. package/esm2022/components/attribute-default.component.mjs +63 -63
  14. package/esm2022/components/attribute-edit.component.mjs +33 -33
  15. package/esm2022/components/attribute-flex.component.mjs +58 -58
  16. package/esm2022/date/date-util.mjs +59 -59
  17. package/esm2022/huntsman-cancer-institute-cod.mjs +4 -4
  18. package/esm2022/index.mjs +20 -21
  19. package/esm2022/model/attribute-choice.entity.mjs +1 -1
  20. package/esm2022/model/attribute-configuration.dto.mjs +1 -1
  21. package/esm2022/model/attribute-configuration.entity.mjs +1 -1
  22. package/esm2022/model/attribute-container.entity.mjs +1 -1
  23. package/esm2022/model/attribute-dictionary.entity.mjs +1 -1
  24. package/esm2022/model/attribute-long-text.entity.mjs +1 -1
  25. package/esm2022/model/attribute-value-grid-row.entity.mjs +1 -1
  26. package/esm2022/model/attribute-value-set.entity.mjs +1 -1
  27. package/esm2022/model/attribute-value.entity.mjs +2 -2
  28. package/esm2022/model/attribute.entity.mjs +1 -1
  29. package/esm2022/model/dictionary-entries.dto.mjs +2 -2
  30. package/esm2022/model/extractable-field-status.entity.mjs +1 -1
  31. package/esm2022/model/graphical-attribute.entity.mjs +1 -1
  32. package/esm2022/model/pre-eval.dto.mjs +2 -2
  33. package/esm2022/pipes/is-group-attribute.pipe.mjs +32 -32
  34. package/esm2022/services/attribute.service.mjs +1211 -1211
  35. package/fesm2022/huntsman-cancer-institute-cod.mjs +2289 -2542
  36. package/fesm2022/huntsman-cancer-institute-cod.mjs.map +1 -1
  37. package/index.d.ts +26 -27
  38. package/model/attribute-choice.entity.d.ts +16 -16
  39. package/model/attribute-configuration.dto.d.ts +13 -13
  40. package/model/attribute-configuration.entity.d.ts +12 -12
  41. package/model/attribute-container.entity.d.ts +9 -9
  42. package/model/attribute-dictionary.entity.d.ts +12 -12
  43. package/model/attribute-long-text.entity.d.ts +4 -4
  44. package/model/attribute-value-grid-row.entity.d.ts +7 -7
  45. package/model/attribute-value-set.entity.d.ts +11 -11
  46. package/model/attribute-value.entity.d.ts +28 -28
  47. package/model/attribute.entity.d.ts +26 -26
  48. package/model/dictionary-entries.dto.d.ts +6 -6
  49. package/model/extractable-field-status.entity.d.ts +8 -8
  50. package/model/graphical-attribute.entity.d.ts +13 -13
  51. package/model/pre-eval.dto.d.ts +5 -5
  52. package/package.json +16 -8
  53. package/pipes/is-group-attribute.pipe.d.ts +13 -13
  54. package/services/attribute.service.d.ts +263 -263
  55. package/components/attribute-configuration.component.d.ts +0 -52
  56. package/esm2022/components/attribute-configuration.component.mjs +0 -263
@@ -1,263 +0,0 @@
1
- import { ChangeDetectorRef, Component, ContentChildren, ElementRef, Input, QueryList, Renderer2, ViewChild, ViewChildren, HostBinding } from "@angular/core";
2
- import { Subject, Subscription } from "rxjs";
3
- import { NgbAccordion, NgbModal, NgbPanel } from "@ng-bootstrap/ng-bootstrap";
4
- import { AccordionNavComponent } from "@huntsman-cancer-institute/misc";
5
- import { AttributeService } from "../services/attribute.service";
6
- import * as i0 from "@angular/core";
7
- import * as i1 from "../services/attribute.service";
8
- import * as i2 from "@ng-bootstrap/ng-bootstrap";
9
- import * as i3 from "@angular/common";
10
- import * as i4 from "@huntsman-cancer-institute/misc";
11
- import * as i5 from "./attribute-absolute.component";
12
- import * as i6 from "./attribute-flex.component";
13
- import * as i7 from "./attribute-edit.component";
14
- import * as i8 from "../pipes/is-group-attribute.pipe";
15
- /**
16
- * This component should be added on to any screen that displays an entity with an idAttributeValueSet. This configuration
17
- * represents the parent of separate containers, which in turn contain attributes which display those values in the
18
- * attributeValueSet.
19
- */
20
- export class AttributeConfigurationComponent {
21
- constructor(attributeService, elementRef, renderer, changeDetectorRef, modalService) {
22
- this.attributeService = attributeService;
23
- this.elementRef = elementRef;
24
- this.renderer = renderer;
25
- this.changeDetectorRef = changeDetectorRef;
26
- this.modalService = modalService;
27
- this.classList = "hci-attribute-configuration hci-cod d-flex flex-column flex-grow-1";
28
- this.editInline = true;
29
- this.editPopup = false;
30
- this.editable = true;
31
- this.loadingSubject = new Subject();
32
- this.windowDimension = {};
33
- this.subscriptions = new Subscription();
34
- }
35
- /**
36
- * Upon init, subscribe to the configuration and value set.
37
- */
38
- ngOnInit() {
39
- if (!this.editable) {
40
- this.editInline = false;
41
- this.editPopup = false;
42
- }
43
- this.loadingSubject = this.attributeService.getLoadingSubject();
44
- this.subscriptions.add(this.attributeService.getAttributeConfigurationSubject().subscribe((attributeConfiguration) => {
45
- this.attributeConfiguration = attributeConfiguration;
46
- this.attributeService.setAttributeValueSet(this.idAttributeValueSet, this.idParentObject);
47
- }));
48
- this.subscriptions.add(this.attributeService.attributeConfigurationDimensionSubject.subscribe((windowDimension) => {
49
- this.windowDimension = windowDimension;
50
- }));
51
- this.subscriptions.add(this.attributeService.getAttributeValueSet().subscribe((attributeValueSet) => {
52
- this.attributeValueSet = attributeValueSet;
53
- if (this.attributeValueSet) {
54
- this.attributeService.notifyAttributes();
55
- }
56
- }));
57
- }
58
- set boundData(value) {
59
- this.attributeService.setBoundData(value);
60
- }
61
- ngOnDestroy() {
62
- this.subscriptions.unsubscribe();
63
- }
64
- set accordion(accordion) {
65
- if (accordion) {
66
- accordion.panels.reset([this.cPanels.toArray(), this.vPanels.toArray()]);
67
- accordion.ngAfterContentChecked();
68
- if (this.accordionNav && !this.accordionNav.accordion) {
69
- this.accordionNav.setAccordion(accordion);
70
- }
71
- this.changeDetectorRef.detectChanges();
72
- }
73
- }
74
- ngOnChanges(changes) {
75
- if (!this.editable) {
76
- this.editInline = false;
77
- this.editPopup = false;
78
- }
79
- if (changes["accordionNav"] && this.accordionNav && this.accordion) {
80
- this.accordionNav.accordion = this.accordion;
81
- this.accordionNav.panels = this.accordion.panels;
82
- }
83
- }
84
- getAttributeService() {
85
- return this.attributeService;
86
- }
87
- edit(modal, editContainer) {
88
- this.editContainer = editContainer;
89
- this.modalService.open(modal, { windowClass: "modal-lg" }).result.then((result) => {
90
- if (result === "Save") {
91
- this.attributeService.updateAttributeValueSet();
92
- }
93
- else if (result === "Cancel") {
94
- this.attributeService.clearUpdatedAttributeValues();
95
- }
96
- }, (reason) => { });
97
- }
98
- post() {
99
- this.attributeService.updateAttributeValueSet();
100
- }
101
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AttributeConfigurationComponent, deps: [{ token: i1.AttributeService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i2.NgbModal }], target: i0.ɵɵFactoryTarget.Component }); }
102
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: AttributeConfigurationComponent, selector: "hci-attribute-configuration", inputs: { idAttributeValueSet: "idAttributeValueSet", idParentObject: "idParentObject", accordionNav: "accordionNav", editInline: "editInline", editPopup: "editPopup", editable: "editable", boundData: "boundData" }, host: { properties: { "class": "this.classList" } }, queries: [{ propertyName: "cPanels", predicate: NgbPanel }], viewQueries: [{ propertyName: "accordion", first: true, predicate: NgbAccordion, descendants: true }, { propertyName: "vPanels", predicate: NgbPanel, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
103
- <hci-busy [busySubjects]="[loadingSubject]"></hci-busy>
104
-
105
- <ng-container *ngIf="attributeConfiguration && attributeValueSet">
106
- <ngb-accordion #accordion="ngbAccordion" class="y-auto">
107
- <ng-content></ng-content>
108
- <ng-container *ngFor="let attributeContainer of attributeConfiguration.attributeContainers">
109
- <ngb-panel [id]="'id-attribute-container-' + attributeContainer.idAttributeContainer" [title]="attributeContainer.containerName">
110
- <ng-template ngbPanelTitle>
111
- <div *ngIf="editPopup" [id]="'id-attribute-container-' + attributeContainer.idAttributeContainer + '-header'"
112
- class="d-flex flex-grow-1 attribute-container-header {{'sort-order-' + attributeContainer.sortOrder}}">
113
- <div class="ml-auto mr-0" (click)="edit(editModal, attributeContainer)">
114
- <i class="fas fa-pencil"></i>
115
- </div>
116
- </div>
117
- </ng-template>
118
- <ng-template ngbPanelContent>
119
- <div class="attribute-container"
120
- [class.col-md-12]="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y'"
121
- [class.flex]="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y'"
122
- [class.flex-wrap]="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y'"
123
- [class.absolute]="!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N'"
124
- [class.x-auto]="!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N'"
125
- [style.height.px]="(!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N') ? windowDimension.height : 'auto'">
126
- <ng-container *ngFor="let attribute of attributeContainer.graphicalAttributes | isGroupAttribute: false">
127
- <ng-container *ngIf="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y' && attribute.codeAttributeDataType !== 'LINE'">
128
- <hci-attribute-flex [id]="'id-attribute-' + attribute.idAttribute"
129
- [attribute]="attribute"
130
- [editInline]="editInline"
131
- [class.attribute]="true"
132
- [class.col-4]="attribute.codeAttributeDataType !== 'GA' && attribute.codeAttributeDataType !== 'LINE'"
133
- [class.col-12]="attribute.codeAttributeDataType === 'GA' || attribute.codeAttributeDataType === 'LINE'"></hci-attribute-flex>
134
- </ng-container>
135
- <ng-container *ngIf="!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N'">
136
- <hci-attribute-absolute [id]="'id-attribute-' + attribute.idAttribute"
137
- [attribute]="attribute"
138
- [editInline]="editInline"
139
- [class.attribute]="true"></hci-attribute-absolute>
140
- </ng-container>
141
- </ng-container>
142
- </div>
143
- </ng-template>
144
- </ngb-panel>
145
- </ng-container>
146
- </ngb-accordion>
147
- </ng-container>
148
-
149
- <ng-template #editModal let-close="close">
150
- <div class="modal-header">
151
- {{editContainer.containerName}}
152
- </div>
153
- <div class="modal-body d-flex flex-column hci-cod-edit">
154
- <ng-container *ngFor="let attribute of editContainer.graphicalAttributes | isGroupAttribute: false">
155
- <hci-attribute-edit [id]="'edit-id-attribute-' + attribute.idAttribute"
156
- [attribute]="attribute"
157
- class="attribute"></hci-attribute-edit>
158
- </ng-container>
159
- </div>
160
- <div class="modal-footer">
161
- <button class="btn btn-primary" (click)="close('Save')">Save</button>
162
- <button class="btn btn-primary" (click)="close('Cancel')">Cancel</button>
163
- </div>
164
- </ng-template>
165
- `, isInline: true, dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.NgbAccordion, selector: "ngb-accordion", inputs: ["animation", "activeIds", "closeOthers", "destroyOnHide", "type"], outputs: ["panelChange", "shown", "hidden"], exportAs: ["ngbAccordion"] }, { kind: "directive", type: i2.NgbPanel, selector: "ngb-panel", inputs: ["disabled", "id", "title", "type", "cardClass"], outputs: ["shown", "hidden"] }, { kind: "directive", type: i2.NgbPanelTitle, selector: "ng-template[ngbPanelTitle]" }, { kind: "directive", type: i2.NgbPanelContent, selector: "ng-template[ngbPanelContent]" }, { kind: "component", type: i4.BusyComponent, selector: "hci-busy", inputs: ["busy", "busySubjects", "getBusySubjects", "parentSelector", "rootClass", "icon", "iconSize", "showIcon", "mxAuto", "myAuto", "text", "template", "config"] }, { kind: "component", type: i5.AttributeAbsoluteComponent, selector: "hci-attribute-absolute" }, { kind: "component", type: i6.AttributeFlexComponent, selector: "hci-attribute-flex" }, { kind: "component", type: i7.AttributeEditComponent, selector: "hci-attribute-edit" }, { kind: "pipe", type: i8.IsGroupAttributePipe, name: "isGroupAttribute" }] }); }
166
- }
167
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AttributeConfigurationComponent, decorators: [{
168
- type: Component,
169
- args: [{
170
- selector: "hci-attribute-configuration",
171
- template: `
172
- <hci-busy [busySubjects]="[loadingSubject]"></hci-busy>
173
-
174
- <ng-container *ngIf="attributeConfiguration && attributeValueSet">
175
- <ngb-accordion #accordion="ngbAccordion" class="y-auto">
176
- <ng-content></ng-content>
177
- <ng-container *ngFor="let attributeContainer of attributeConfiguration.attributeContainers">
178
- <ngb-panel [id]="'id-attribute-container-' + attributeContainer.idAttributeContainer" [title]="attributeContainer.containerName">
179
- <ng-template ngbPanelTitle>
180
- <div *ngIf="editPopup" [id]="'id-attribute-container-' + attributeContainer.idAttributeContainer + '-header'"
181
- class="d-flex flex-grow-1 attribute-container-header {{'sort-order-' + attributeContainer.sortOrder}}">
182
- <div class="ml-auto mr-0" (click)="edit(editModal, attributeContainer)">
183
- <i class="fas fa-pencil"></i>
184
- </div>
185
- </div>
186
- </ng-template>
187
- <ng-template ngbPanelContent>
188
- <div class="attribute-container"
189
- [class.col-md-12]="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y'"
190
- [class.flex]="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y'"
191
- [class.flex-wrap]="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y'"
192
- [class.absolute]="!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N'"
193
- [class.x-auto]="!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N'"
194
- [style.height.px]="(!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N') ? windowDimension.height : 'auto'">
195
- <ng-container *ngFor="let attribute of attributeContainer.graphicalAttributes | isGroupAttribute: false">
196
- <ng-container *ngIf="attributeContainer.isAutoLayout && attributeContainer.isAutoLayout === 'Y' && attribute.codeAttributeDataType !== 'LINE'">
197
- <hci-attribute-flex [id]="'id-attribute-' + attribute.idAttribute"
198
- [attribute]="attribute"
199
- [editInline]="editInline"
200
- [class.attribute]="true"
201
- [class.col-4]="attribute.codeAttributeDataType !== 'GA' && attribute.codeAttributeDataType !== 'LINE'"
202
- [class.col-12]="attribute.codeAttributeDataType === 'GA' || attribute.codeAttributeDataType === 'LINE'"></hci-attribute-flex>
203
- </ng-container>
204
- <ng-container *ngIf="!attributeContainer.isAutoLayout || attributeContainer.isAutoLayout === 'N'">
205
- <hci-attribute-absolute [id]="'id-attribute-' + attribute.idAttribute"
206
- [attribute]="attribute"
207
- [editInline]="editInline"
208
- [class.attribute]="true"></hci-attribute-absolute>
209
- </ng-container>
210
- </ng-container>
211
- </div>
212
- </ng-template>
213
- </ngb-panel>
214
- </ng-container>
215
- </ngb-accordion>
216
- </ng-container>
217
-
218
- <ng-template #editModal let-close="close">
219
- <div class="modal-header">
220
- {{editContainer.containerName}}
221
- </div>
222
- <div class="modal-body d-flex flex-column hci-cod-edit">
223
- <ng-container *ngFor="let attribute of editContainer.graphicalAttributes | isGroupAttribute: false">
224
- <hci-attribute-edit [id]="'edit-id-attribute-' + attribute.idAttribute"
225
- [attribute]="attribute"
226
- class="attribute"></hci-attribute-edit>
227
- </ng-container>
228
- </div>
229
- <div class="modal-footer">
230
- <button class="btn btn-primary" (click)="close('Save')">Save</button>
231
- <button class="btn btn-primary" (click)="close('Cancel')">Cancel</button>
232
- </div>
233
- </ng-template>
234
- `
235
- }]
236
- }], ctorParameters: function () { return [{ type: i1.AttributeService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i2.NgbModal }]; }, propDecorators: { classList: [{
237
- type: HostBinding,
238
- args: ["class"]
239
- }], idAttributeValueSet: [{
240
- type: Input
241
- }], idParentObject: [{
242
- type: Input
243
- }], accordionNav: [{
244
- type: Input
245
- }], editInline: [{
246
- type: Input
247
- }], editPopup: [{
248
- type: Input
249
- }], editable: [{
250
- type: Input
251
- }], vPanels: [{
252
- type: ViewChildren,
253
- args: [NgbPanel]
254
- }], cPanels: [{
255
- type: ContentChildren,
256
- args: [NgbPanel]
257
- }], boundData: [{
258
- type: Input
259
- }], accordion: [{
260
- type: ViewChild,
261
- args: [NgbAccordion, { static: false }]
262
- }] } });
263
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0cmlidXRlLWNvbmZpZ3VyYXRpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvY29kL3NyYy9jb21wb25lbnRzL2F0dHJpYnV0ZS1jb25maWd1cmF0aW9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUNoRSxTQUFTLEVBQUUsU0FBUyxFQUFnQixTQUFTLEVBQUUsWUFBWSxFQUFxQixXQUFXLEVBQzVGLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBRTVFLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLGlDQUFpQyxDQUFDO0FBRXRFLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLCtCQUErQixDQUFDOzs7Ozs7Ozs7O0FBSy9EOzs7O0dBSUc7QUFvRUgsTUFBTSxPQUFPLCtCQUErQjtJQTBCMUMsWUFBb0IsZ0JBQWtDLEVBQ2xDLFVBQXNCLEVBQ3RCLFFBQW1CLEVBQ25CLGlCQUFvQyxFQUNwQyxZQUFzQjtRQUp0QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUNuQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1CO1FBQ3BDLGlCQUFZLEdBQVosWUFBWSxDQUFVO1FBN0JwQixjQUFTLEdBQVcsb0VBQW9FLENBQUM7UUFPdEcsZUFBVSxHQUFZLElBQUksQ0FBQztRQUMzQixjQUFTLEdBQWEsS0FBSyxDQUFDO1FBQzVCLGFBQVEsR0FBWSxJQUFJLENBQUM7UUFRbEMs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RjsrTUFFdUIsU0FBUztzQkFBOUIsV0FBVzt1QkFBQyxPQUFPO2dCQUVYLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUVHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRWtCLE9BQU87c0JBQTlCLFlBQVk7dUJBQUMsUUFBUTtnQkFDSyxPQUFPO3NCQUFqQyxlQUFlO3VCQUFDLFFBQVE7Z0JBaURaLFNBQVM7c0JBQXJCLEtBQUs7Z0JBU0YsU0FBUztzQkFEWixTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIENvbnRlbnRDaGlsZHJlbiwgRWxlbWVudFJlZiwgSW5wdXQsIGlzRGV2TW9kZSwgVGVtcGxhdGVSZWYsXHJcbiAgUXVlcnlMaXN0LCBSZW5kZXJlcjIsIFNpbXBsZUNoYW5nZSwgVmlld0NoaWxkLCBWaWV3Q2hpbGRyZW4sIE9uSW5pdCwgT25EZXN0cm95LCBIb3N0QmluZGluZ1xyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcblxyXG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQge05nYkFjY29yZGlvbiwgTmdiTW9kYWwsIE5nYlBhbmVsfSBmcm9tIFwiQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXBcIjtcclxuXHJcbmltcG9ydCB7QWNjb3JkaW9uTmF2Q29tcG9uZW50fSBmcm9tIFwiQGh1bnRzbWFuLWNhbmNlci1pbnN0aXR1dGUvbWlzY1wiO1xyXG5cclxuaW1wb3J0IHtBdHRyaWJ1dGVTZXJ2aWNlfSBmcm9tIFwiLi4vc2VydmljZXMvYXR0cmlidXRlLnNlcnZpY2VcIjtcclxuaW1wb3J0IHtBdHRyaWJ1dGVDb25maWd1cmF0aW9ufSBmcm9tIFwiLi4vbW9kZWwvYXR0cmlidXRlLWNvbmZpZ3VyYXRpb24uZW50aXR5XCI7XHJcbmltcG9ydCB7QXR0cmlidXRlVmFsdWVTZXR9IGZyb20gXCIuLi9tb2RlbC9hdHRyaWJ1dGUtdmFsdWUtc2V0LmVudGl0eVwiO1xyXG5pbXBvcnQge0F0dHJpYnV0ZUNvbnRhaW5lcn0gZnJvbSBcIi4uL21vZGVsL2F0dHJpYnV0ZS1jb250YWluZXIuZW50aXR5XCI7XHJcblxyXG4vKipcclxuICogVGhpcyBjb21wb25lbnQgc2hvdWxkIGJlIGFkZGVkIG9uIHRvIGFueSBzY3JlZW4gdGhhdCBkaXNwbGF5cyBhbiBlbnRpdHkgd2l0aCBhbiBpZEF0dHJpYnV0ZVZhbHVlU2V0LiAgVGhpcyBjb25maWd1cmF0aW9uXHJcbiAqIHJlcHJlc2VudHMgdGhlIHBhcmVudCBvZiBzZXBhcmF0ZSBjb250YWluZXJzLCB3aGljaCBpbiB0dXJuIGNvbnRhaW4gYXR0cmlidXRlcyB3aGljaCBkaXNwbGF5IHRob3NlIHZhbHVlcyBpbiB0aGVcclxuICogYXR0cmlidXRlVmFsdWVTZXQuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogXCJoY2ktYXR0cmlidXRlLWNvbmZpZ3VyYXRpb25cIixcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPGhjaS1idXN5IFtidXN5U3ViamVjdHNdPVwiW2xvYWRpbmdTdWJqZWN0XVwiPjwvaGNpLWJ1c3k+XHJcblxyXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImF0dHJpYnV0ZUNvbmZpZ3VyYXRpb24gJiYgYXR0cmlidXRlVmFsdWVTZXRcIj5cclxuICAgICAgPG5nYi1hY2NvcmRpb24gI2FjY29yZGlvbj1cIm5nYkFjY29yZGlvblwiIGNsYXNzPVwieS1hdXRvXCI+XHJcbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGF0dHJpYnV0ZUNvbnRhaW5lciBvZiBhdHRyaWJ1dGVDb25maWd1cmF0aW9uLmF0dHJpYnV0ZUNvbnRhaW5lcnNcIj5cclxuICAgICAgICAgIDxuZ2ItcGFuZWwgW2lkXT1cIidpZC1hdHRyaWJ1dGUtY29udGFpbmVyLScgKyBhdHRyaWJ1dGVDb250YWluZXIuaWRBdHRyaWJ1dGVDb250YWluZXJcIiBbdGl0bGVdPVwiYXR0cmlidXRlQ29udGFpbmVyLmNvbnRhaW5lck5hbWVcIj5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nYlBhbmVsVGl0bGU+XHJcbiAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImVkaXRQb3B1cFwiIFtpZF09XCInaWQtYXR0cmlidXRlLWNvbnRhaW5lci0nICsgYXR0cmlidXRlQ29udGFpbmVyLmlkQXR0cmlidXRlQ29udGFpbmVyICsgJy1oZWFkZXInXCJcclxuICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZC1mbGV4IGZsZXgtZ3Jvdy0xIGF0dHJpYnV0ZS1jb250YWluZXItaGVhZGVyIHt7J3NvcnQtb3JkZXItJyArIGF0dHJpYnV0ZUNvbnRhaW5lci5zb3J0T3JkZXJ9fVwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1sLWF1dG8gbXItMFwiIChjbGljayk9XCJlZGl0KGVkaXRNb2RhbCwgYXR0cmlidXRlQ29udGFpbmVyKVwiPlxyXG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1wZW5jaWxcIj48L2k+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlIG5nYlBhbmVsQ29udGVudD5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXR0cmlidXRlLWNvbnRhaW5lclwiXHJcbiAgICAgICAgICAgICAgICAgICBbY2xhc3MuY29sLW1kLTEyXT1cImF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgJiYgYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCA9PT0gJ1knXCJcclxuICAgICAgICAgICAgICAgICAgIFtjbGFzcy5mbGV4XT1cImF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgJiYgYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCA9PT0gJ1knXCJcclxuICAgICAgICAgICAgICAgICAgIFtjbGFzcy5mbGV4LXdyYXBdPVwiYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCAmJiBhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0ID09PSAnWSdcIlxyXG4gICAgICAgICAgICAgICAgICAgW2NsYXNzLmFic29sdXRlXT1cIiFhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0IHx8IGF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgPT09ICdOJ1wiXHJcbiAgICAgICAgICAgICAgICAgICBbY2xhc3MueC1hdXRvXT1cIiFhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0IHx8IGF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgPT09ICdOJ1wiXHJcbiAgICAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cIighYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCB8fCBhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0ID09PSAnTicpID8gd2luZG93RGltZW5zaW9uLmhlaWdodCA6ICdhdXRvJ1wiPlxyXG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYXR0cmlidXRlIG9mIGF0dHJpYnV0ZUNvbnRhaW5lci5ncmFwaGljYWxBdHRyaWJ1dGVzIHwgaXNHcm91cEF0dHJpYnV0ZTogZmFsc2VcIj5cclxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgJiYgYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCA9PT0gJ1knICYmIGF0dHJpYnV0ZS5jb2RlQXR0cmlidXRlRGF0YVR5cGUgIT09ICdMSU5FJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxoY2ktYXR0cmlidXRlLWZsZXggW2lkXT1cIidpZC1hdHRyaWJ1dGUtJyArIGF0dHJpYnV0ZS5pZEF0dHJpYnV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0cmlidXRlXT1cImF0dHJpYnV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZWRpdElubGluZV09XCJlZGl0SW5saW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hdHRyaWJ1dGVdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY29sLTRdPVwiYXR0cmlidXRlLmNvZGVBdHRyaWJ1dGVEYXRhVHlwZSAhPT0gJ0dBJyAmJiBhdHRyaWJ1dGUuY29kZUF0dHJpYnV0ZURhdGFUeXBlICE9PSAnTElORSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmNvbC0xMl09XCJhdHRyaWJ1dGUuY29kZUF0dHJpYnV0ZURhdGFUeXBlID09PSAnR0EnIHx8IGF0dHJpYnV0ZS5jb2RlQXR0cmlidXRlRGF0YVR5cGUgPT09ICdMSU5FJ1wiPjwvaGNpLWF0dHJpYnV0ZS1mbGV4PlxyXG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0IHx8IGF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgPT09ICdOJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxoY2ktYXR0cmlidXRlLWFic29sdXRlIFtpZF09XCInaWQtYXR0cmlidXRlLScgKyBhdHRyaWJ1dGUuaWRBdHRyaWJ1dGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyaWJ1dGVdPVwiYXR0cmlidXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZWRpdElubGluZV09XCJlZGl0SW5saW5lXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuYXR0cmlidXRlXT1cInRydWVcIj48L2hjaS1hdHRyaWJ1dGUtYWJzb2x1dGU+XHJcbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICA8L25nYi1wYW5lbD5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgPC9uZ2ItYWNjb3JkaW9uPlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgPG5nLXRlbXBsYXRlICNlZGl0TW9kYWwgbGV0LWNsb3NlPVwiY2xvc2VcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxyXG4gICAgICAgIHt7ZWRpdENvbnRhaW5lci5jb250YWluZXJOYW1lfX1cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IGQtZmxleCBmbGV4LWNvbHVtbiBoY2ktY29kLWVkaXRcIj5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBhdHRyaWJ1dGUgb2YgZWRpdENvbnRhaW5lci5ncmFwaGljYWxBdHRyaWJ1dGVzIHwgaXNHcm91cEF0dHJpYnV0ZTogZmFsc2VcIj5cclxuICAgICAgICAgIDxoY2ktYXR0cmlidXRlLWVkaXQgW2lkXT1cIidlZGl0LWlkLWF0dHJpYnV0ZS0nICsgYXR0cmlidXRlLmlkQXR0cmlidXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHJpYnV0ZV09XCJhdHRyaWJ1dGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImF0dHJpYnV0ZVwiPjwvaGNpLWF0dHJpYnV0ZS1lZGl0PlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiAoY2xpY2spPVwiY2xvc2UoJ1NhdmUnKVwiPlNhdmU8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgKGNsaWNrKT1cImNsb3NlKCdDYW5jZWwnKVwiPkNhbmNlbDwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgYFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQXR0cmlidXRlQ29uZmlndXJhdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICBASG9zdEJpbmRpbmcoXCJjbGFzc1wiKSBjbGFzc0xpc3Q6IHN0cmluZyA9IFwiaGNpLWF0dHJpYnV0ZS1jb25maWd1cmF0aW9uIGhjaS1jb2QgZC1mbGV4IGZsZXgtY29sdW1uIGZsZXgtZ3Jvdy0xXCI7XHJcblxyXG4gIEBJbnB1dCgpIGlkQXR0cmlidXRlVmFsdWVTZXQ6IG51bWJlcjtcclxuICBASW5wdXQoKSBpZFBhcmVudE9iamVjdDogbnVtYmVyO1xyXG4gIFxyXG4gIEBJbnB1dCgpIGFjY29yZGlvbk5hdjogQWNjb3JkaW9uTmF2Q29tcG9uZW50O1xyXG4gIFxyXG4gIEBJbnB1dCgpIGVkaXRJbmxpbmU6IGJvb2xlYW4gPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGVkaXRQb3B1cDogYm9vbGVhbiA9ICBmYWxzZTtcclxuICBASW5wdXQoKSBlZGl0YWJsZTogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIEBWaWV3Q2hpbGRyZW4oTmdiUGFuZWwpIHZQYW5lbHM6IFF1ZXJ5TGlzdDxOZ2JQYW5lbD47XHJcbiAgQENvbnRlbnRDaGlsZHJlbihOZ2JQYW5lbCkgY1BhbmVsczogUXVlcnlMaXN0PE5nYlBhbmVsPjtcclxuXHJcbiAgYXR0cmlidXRlQ29uZmlndXJhdGlvbjogQXR0cmlidXRlQ29uZmlndXJhdGlvbjtcclxuICBhdHRyaWJ1dGVWYWx1ZVNldDogQXR0cmlidXRlVmFsdWVTZXQ7XHJcblxyXG4gIGxvYWRpbmdTdWJqZWN0OiBTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcclxuXHJcbiAgZWRpdENvbnRhaW5lcjogQXR0cmlidXRlQ29udGFpbmVyO1xyXG5cclxuICB3aW5kb3dEaW1lbnNpb246IGFueSA9IHt9O1xyXG5cclxuICBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYXR0cmlidXRlU2VydmljZTogQXR0cmlidXRlU2VydmljZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgbW9kYWxTZXJ2aWNlOiBOZ2JNb2RhbCkge31cclxuXHJcbiAgLyoqXHJcbiAgICogVXBvbiBpbml0LCBzdWJzY3JpYmUgdG8gdGhlIGNvbmZpZ3VyYXRpb24gYW5kIHZhbHVlIHNldC5cclxuICAgKi9cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIGlmICghIHRoaXMuZWRpdGFibGUpIHtcclxuICAgICAgdGhpcy5lZGl0SW5saW5lID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuZWRpdFBvcHVwID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRoaXMubG9hZGluZ1N1YmplY3QgPSB0aGlzLmF0dHJpYnV0ZVNlcnZpY2UuZ2V0TG9hZGluZ1N1YmplY3QoKTtcclxuXHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuYXR0cmlidXRlU2VydmljZS5nZXRBdHRyaWJ1dGVDb25maWd1cmF0aW9uU3ViamVjdCgpLnN1YnNjcmliZSgoYXR0cmlidXRlQ29uZmlndXJhdGlvbjogQXR0cmlidXRlQ29uZmlndXJhdGlvbikgPT4ge1xyXG4gICAgICB0aGlzLmF0dHJpYnV0ZUNvbmZpZ3VyYXRpb24gPSBhdHRyaWJ1dGVDb25maWd1cmF0aW9uO1xyXG4gICAgICBcclxuICAgICAgdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLnNldEF0dHJpYnV0ZVZhbHVlU2V0KHRoaXMuaWRBdHRyaWJ1dGVWYWx1ZVNldCwgdGhpcy5pZFBhcmVudE9iamVjdCk7XHJcbiAgICB9KSk7XHJcblxyXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZCh0aGlzLmF0dHJpYnV0ZVNlcnZpY2UuYXR0cmlidXRlQ29uZmlndXJhdGlvbkRpbWVuc2lvblN1YmplY3Quc3Vic2NyaWJlKCh3aW5kb3dEaW1lbnNpb246IGFueSkgPT4ge1xyXG4gICAgICB0aGlzLndpbmRvd0RpbWVuc2lvbiA9IHdpbmRvd0RpbWVuc2lvbjtcclxuICAgIH0pKTtcclxuXHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuYXR0cmlidXRlU2VydmljZS5nZXRBdHRyaWJ1dGVWYWx1ZVNldCgpLnN1YnNjcmliZSgoYXR0cmlidXRlVmFsdWVTZXQ6IEF0dHJpYnV0ZVZhbHVlU2V0KSA9PiB7XHJcbiAgICAgIHRoaXMuYXR0cmlidXRlVmFsdWVTZXQgPSBhdHRyaWJ1dGVWYWx1ZVNldDtcclxuICAgICAgXHJcbiAgICAgIGlmICh0aGlzLmF0dHJpYnV0ZVZhbHVlU2V0KSB7XHJcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLm5vdGlmeUF0dHJpYnV0ZXMoKTtcclxuICAgICAgfVxyXG4gICAgfSkpO1xyXG4gIH1cclxuICBcclxuICBASW5wdXQoKSBzZXQgYm91bmREYXRhKHZhbHVlOiBhbnkpIHtcclxuICAgIHRoaXMuYXR0cmlidXRlU2VydmljZS5zZXRCb3VuZERhdGEodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMudW5zdWJzY3JpYmUoKTtcclxuICB9XHJcblxyXG4gIEBWaWV3Q2hpbGQoTmdiQWNjb3JkaW9uLCB7c3RhdGljOiBmYWxzZX0pXHJcbiAgc2V0IGFjY29yZGlvbihhY2NvcmRpb246IE5nYkFjY29yZGlvbikge1xyXG4gICAgaWYgKGFjY29yZGlvbikge1xyXG4gICAgICBhY2NvcmRpb24ucGFuZWxzLnJlc2V0KFt0aGlzLmNQYW5lbHMudG9BcnJheSgpLCB0aGlzLnZQYW5lbHMudG9BcnJheSgpXSk7XHJcbiAgICAgIGFjY29yZGlvbi5uZ0FmdGVyQ29udGVudENoZWNrZWQoKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmFjY29yZGlvbk5hdiAmJiAhdGhpcy5hY2NvcmRpb25OYXYuYWNjb3JkaW9uKSB7XHJcbiAgICAgICAgdGhpcy5hY2NvcmRpb25OYXYuc2V0QWNjb3JkaW9uKGFjY29yZGlvbik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczoge1twcm9wTmFtZTogc3RyaW5nXTogU2ltcGxlQ2hhbmdlfSkge1xyXG4gICAgaWYgKCEgdGhpcy5lZGl0YWJsZSkge1xyXG4gICAgICB0aGlzLmVkaXRJbmxpbmUgPSBmYWxzZTtcclxuICAgICAgdGhpcy5lZGl0UG9wdXAgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgaWYgKGNoYW5nZXNbXCJhY2NvcmRpb25OYXZcIl0gJiYgdGhpcy5hY2NvcmRpb25OYXYgJiYgdGhpcy5hY2NvcmRpb24pIHtcclxuICAgICAgdGhpcy5hY2NvcmRpb25OYXYuYWNjb3JkaW9uID0gdGhpcy5hY2NvcmRpb247XHJcbiAgICAgIHRoaXMuYWNjb3JkaW9uTmF2LnBhbmVscyA9IHRoaXMuYWNjb3JkaW9uLnBhbmVscztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldEF0dHJpYnV0ZVNlcnZpY2UoKTogQXR0cmlidXRlU2VydmljZSB7XHJcbiAgICByZXR1cm4gdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlO1xyXG4gIH1cclxuXHJcbiAgZWRpdChtb2RhbDogVGVtcGxhdGVSZWY8YW55PiwgZWRpdENvbnRhaW5lcjogQXR0cmlidXRlQ29udGFpbmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLmVkaXRDb250YWluZXIgPSBlZGl0Q29udGFpbmVyO1xyXG5cclxuICAgIHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4obW9kYWwsIHt3aW5kb3dDbGFzczogXCJtb2RhbC1sZ1wifSkucmVzdWx0LnRoZW4oKHJlc3VsdCkgPT4ge1xyXG4gICAgICBpZiAocmVzdWx0ID09PSBcIlNhdmVcIikge1xyXG4gICAgICAgIHRoaXMuYXR0cmlidXRlU2VydmljZS51cGRhdGVBdHRyaWJ1dGVWYWx1ZVNldCgpO1xyXG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gXCJDYW5jZWxcIikge1xyXG4gICAgICAgIHRoaXMuYXR0cmlidXRlU2VydmljZS5jbGVhclVwZGF0ZWRBdHRyaWJ1dGVWYWx1ZXMoKTtcclxuICAgICAgfVxyXG4gICAgfSwgKHJlYXNvbikgPT4ge30pO1xyXG4gIH1cclxuXHJcbiAgcG9zdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuYXR0cmlidXRlU2VydmljZS51cGRhdGVBdHRyaWJ1dGVWYWx1ZVNldCgpO1xyXG4gIH1cclxuXHJcbn1cclxuIl19