@huntsman-cancer-institute/cod 17.0.0 → 17.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  * @since 1.0.0
5
5
  */
6
6
  export { CodModule } from "./cod.module";
7
- export { AttributeConfigurationComponent } from "./components/attribute-configuration.component";
8
7
  export { AttributeService } from "./services/attribute.service";
9
8
  export { Attribute } from "./model/attribute.entity";
10
9
  export { AttributeChoice } from "./model/attribute-choice.entity";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huntsman-cancer-institute/cod",
3
- "version": "17.0.0",
3
+ "version": "17.0.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git@gitlab.com:huntsman-cancer-institute/risr/ng/hci-ng-lib.git"
@@ -15,23 +15,15 @@
15
15
  "@angular-material-components/datetime-picker": "^16.x",
16
16
  "ag-grid-angular": "^28.x",
17
17
  "ag-grid-community": "^28.x",
18
- "bootstrap": ">=4.3.1 <4.4.0",
19
18
  "date-fns": "^2.16.1"
20
19
  },
21
20
  "dependencies": {
22
- "@huntsman-cancer-institute/dictionary-service": "^17.x",
23
- "@huntsman-cancer-institute/input": "^17.x",
24
- "@huntsman-cancer-institute/misc": "^17.x",
21
+ "@huntsman-cancer-institute/dictionary-service": "17.0.2",
22
+ "@huntsman-cancer-institute/input": "17.0.2",
23
+ "@huntsman-cancer-institute/misc": "17.0.2",
25
24
  "tslib": "^2.3.0"
26
25
  },
27
26
  "overrides": {
28
- "@ng-bootstrap/ng-bootstrap": {
29
- ".": "^15.0.0",
30
- "@angular/common": ">=16.0.0",
31
- "@angular/core": ">=16.0.0",
32
- "@angular/forms": ">=16.0.0",
33
- "@angular/localize": ">=16.0.0"
34
- },
35
27
  "@angular-material-components/datetime-picker": {
36
28
  "@angular/platform-browser": ">=16.0.0",
37
29
  "@angular/common": ">=16.0.0",
@@ -1,52 +0,0 @@
1
- import { ChangeDetectorRef, ElementRef, TemplateRef, QueryList, Renderer2, SimpleChange, OnInit, OnDestroy } 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 { AttributeConfiguration } from "../model/attribute-configuration.entity";
7
- import { AttributeValueSet } from "../model/attribute-value-set.entity";
8
- import { AttributeContainer } from "../model/attribute-container.entity";
9
- import * as i0 from "@angular/core";
10
- /**
11
- * This component should be added on to any screen that displays an entity with an idAttributeValueSet. This configuration
12
- * represents the parent of separate containers, which in turn contain attributes which display those values in the
13
- * attributeValueSet.
14
- */
15
- export declare class AttributeConfigurationComponent implements OnInit, OnDestroy {
16
- private attributeService;
17
- private elementRef;
18
- private renderer;
19
- private changeDetectorRef;
20
- private modalService;
21
- classList: string;
22
- idAttributeValueSet: number;
23
- idParentObject: number;
24
- accordionNav: AccordionNavComponent;
25
- editInline: boolean;
26
- editPopup: boolean;
27
- editable: boolean;
28
- vPanels: QueryList<NgbPanel>;
29
- cPanels: QueryList<NgbPanel>;
30
- attributeConfiguration: AttributeConfiguration;
31
- attributeValueSet: AttributeValueSet;
32
- loadingSubject: Subject<boolean>;
33
- editContainer: AttributeContainer;
34
- windowDimension: any;
35
- subscriptions: Subscription;
36
- constructor(attributeService: AttributeService, elementRef: ElementRef, renderer: Renderer2, changeDetectorRef: ChangeDetectorRef, modalService: NgbModal);
37
- /**
38
- * Upon init, subscribe to the configuration and value set.
39
- */
40
- ngOnInit(): void;
41
- set boundData(value: any);
42
- ngOnDestroy(): void;
43
- set accordion(accordion: NgbAccordion);
44
- ngOnChanges(changes: {
45
- [propName: string]: SimpleChange;
46
- }): void;
47
- getAttributeService(): AttributeService;
48
- edit(modal: TemplateRef<any>, editContainer: AttributeContainer): void;
49
- post(): void;
50
- static ɵfac: i0.ɵɵFactoryDeclaration<AttributeConfigurationComponent, never>;
51
- static ɵcmp: i0.ɵɵComponentDeclaration<AttributeConfigurationComponent, "hci-attribute-configuration", never, { "idAttributeValueSet": { "alias": "idAttributeValueSet"; "required": false; }; "idParentObject": { "alias": "idParentObject"; "required": false; }; "accordionNav": { "alias": "accordionNav"; "required": false; }; "editInline": { "alias": "editInline"; "required": false; }; "editPopup": { "alias": "editPopup"; "required": false; }; "editable": { "alias": "editable"; "required": false; }; "boundData": { "alias": "boundData"; "required": false; }; }, {}, ["cPanels"], ["*"], false, never>;
52
- }
@@ -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: "17.1.2", 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: "17.1.2", 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: "17.1.2", 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: () => [{ 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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QVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBK0RUO2lCQUNGOzZMQUV1QixTQUFTO3NCQUE5QixXQUFXO3VCQUFDLE9BQU87Z0JBRVgsbUJBQW1CO3NCQUEzQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsWUFBWTtzQkFBcEIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFFa0IsT0FBTztzQkFBOUIsWUFBWTt1QkFBQyxRQUFRO2dCQUNLLE9BQU87c0JBQWpDLGVBQWU7dUJBQUMsUUFBUTtnQkFpRFosU0FBUztzQkFBckIsS0FBSztnQkFTRixTQUFTO3NCQURaLFNBQVM7dUJBQUMsWUFBWSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgQ29udGVudENoaWxkcmVuLCBFbGVtZW50UmVmLCBJbnB1dCwgaXNEZXZNb2RlLCBUZW1wbGF0ZVJlZixcclxuICBRdWVyeUxpc3QsIFJlbmRlcmVyMiwgU2ltcGxlQ2hhbmdlLCBWaWV3Q2hpbGQsIFZpZXdDaGlsZHJlbiwgT25Jbml0LCBPbkRlc3Ryb3ksIEhvc3RCaW5kaW5nXHJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuXHJcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7TmdiQWNjb3JkaW9uLCBOZ2JNb2RhbCwgTmdiUGFuZWx9IGZyb20gXCJAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcFwiO1xyXG5cclxuaW1wb3J0IHtBY2NvcmRpb25OYXZDb21wb25lbnR9IGZyb20gXCJAaHVudHNtYW4tY2FuY2VyLWluc3RpdHV0ZS9taXNjXCI7XHJcblxyXG5pbXBvcnQge0F0dHJpYnV0ZVNlcnZpY2V9IGZyb20gXCIuLi9zZXJ2aWNlcy9hdHRyaWJ1dGUuc2VydmljZVwiO1xyXG5pbXBvcnQge0F0dHJpYnV0ZUNvbmZpZ3VyYXRpb259IGZyb20gXCIuLi9tb2RlbC9hdHRyaWJ1dGUtY29uZmlndXJhdGlvbi5lbnRpdHlcIjtcclxuaW1wb3J0IHtBdHRyaWJ1dGVWYWx1ZVNldH0gZnJvbSBcIi4uL21vZGVsL2F0dHJpYnV0ZS12YWx1ZS1zZXQuZW50aXR5XCI7XHJcbmltcG9ydCB7QXR0cmlidXRlQ29udGFpbmVyfSBmcm9tIFwiLi4vbW9kZWwvYXR0cmlidXRlLWNvbnRhaW5lci5lbnRpdHlcIjtcclxuXHJcbi8qKlxyXG4gKiBUaGlzIGNvbXBvbmVudCBzaG91bGQgYmUgYWRkZWQgb24gdG8gYW55IHNjcmVlbiB0aGF0IGRpc3BsYXlzIGFuIGVudGl0eSB3aXRoIGFuIGlkQXR0cmlidXRlVmFsdWVTZXQuICBUaGlzIGNvbmZpZ3VyYXRpb25cclxuICogcmVwcmVzZW50cyB0aGUgcGFyZW50IG9mIHNlcGFyYXRlIGNvbnRhaW5lcnMsIHdoaWNoIGluIHR1cm4gY29udGFpbiBhdHRyaWJ1dGVzIHdoaWNoIGRpc3BsYXkgdGhvc2UgdmFsdWVzIGluIHRoZVxyXG4gKiBhdHRyaWJ1dGVWYWx1ZVNldC5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcImhjaS1hdHRyaWJ1dGUtY29uZmlndXJhdGlvblwiLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8aGNpLWJ1c3kgW2J1c3lTdWJqZWN0c109XCJbbG9hZGluZ1N1YmplY3RdXCI+PC9oY2ktYnVzeT5cclxuXHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0cmlidXRlQ29uZmlndXJhdGlvbiAmJiBhdHRyaWJ1dGVWYWx1ZVNldFwiPlxyXG4gICAgICA8bmdiLWFjY29yZGlvbiAjYWNjb3JkaW9uPVwibmdiQWNjb3JkaW9uXCIgY2xhc3M9XCJ5LWF1dG9cIj5cclxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgYXR0cmlidXRlQ29udGFpbmVyIG9mIGF0dHJpYnV0ZUNvbmZpZ3VyYXRpb24uYXR0cmlidXRlQ29udGFpbmVyc1wiPlxyXG4gICAgICAgICAgPG5nYi1wYW5lbCBbaWRdPVwiJ2lkLWF0dHJpYnV0ZS1jb250YWluZXItJyArIGF0dHJpYnV0ZUNvbnRhaW5lci5pZEF0dHJpYnV0ZUNvbnRhaW5lclwiIFt0aXRsZV09XCJhdHRyaWJ1dGVDb250YWluZXIuY29udGFpbmVyTmFtZVwiPlxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgbmdiUGFuZWxUaXRsZT5cclxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZWRpdFBvcHVwXCIgW2lkXT1cIidpZC1hdHRyaWJ1dGUtY29udGFpbmVyLScgKyBhdHRyaWJ1dGVDb250YWluZXIuaWRBdHRyaWJ1dGVDb250YWluZXIgKyAnLWhlYWRlcidcIlxyXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkLWZsZXggZmxleC1ncm93LTEgYXR0cmlidXRlLWNvbnRhaW5lci1oZWFkZXIge3snc29ydC1vcmRlci0nICsgYXR0cmlidXRlQ29udGFpbmVyLnNvcnRPcmRlcn19XCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWwtYXV0byBtci0wXCIgKGNsaWNrKT1cImVkaXQoZWRpdE1vZGFsLCBhdHRyaWJ1dGVDb250YWluZXIpXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXBlbmNpbFwiPjwvaT5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgbmdiUGFuZWxDb250ZW50PlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdHRyaWJ1dGUtY29udGFpbmVyXCJcclxuICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtMTJdPVwiYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCAmJiBhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0ID09PSAnWSdcIlxyXG4gICAgICAgICAgICAgICAgICAgW2NsYXNzLmZsZXhdPVwiYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCAmJiBhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0ID09PSAnWSdcIlxyXG4gICAgICAgICAgICAgICAgICAgW2NsYXNzLmZsZXgtd3JhcF09XCJhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0ICYmIGF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgPT09ICdZJ1wiXHJcbiAgICAgICAgICAgICAgICAgICBbY2xhc3MuYWJzb2x1dGVdPVwiIWF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgfHwgYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCA9PT0gJ04nXCJcclxuICAgICAgICAgICAgICAgICAgIFtjbGFzcy54LWF1dG9dPVwiIWF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgfHwgYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCA9PT0gJ04nXCJcclxuICAgICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiKCFhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0IHx8IGF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgPT09ICdOJykgPyB3aW5kb3dEaW1lbnNpb24uaGVpZ2h0IDogJ2F1dG8nXCI+XHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBhdHRyaWJ1dGUgb2YgYXR0cmlidXRlQ29udGFpbmVyLmdyYXBoaWNhbEF0dHJpYnV0ZXMgfCBpc0dyb3VwQXR0cmlidXRlOiBmYWxzZVwiPlxyXG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCAmJiBhdHRyaWJ1dGVDb250YWluZXIuaXNBdXRvTGF5b3V0ID09PSAnWScgJiYgYXR0cmlidXRlLmNvZGVBdHRyaWJ1dGVEYXRhVHlwZSAhPT0gJ0xJTkUnXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGhjaS1hdHRyaWJ1dGUtZmxleCBbaWRdPVwiJ2lkLWF0dHJpYnV0ZS0nICsgYXR0cmlidXRlLmlkQXR0cmlidXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyaWJ1dGVdPVwiYXR0cmlidXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlZGl0SW5saW5lXT1cImVkaXRJbmxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmF0dHJpYnV0ZV09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtNF09XCJhdHRyaWJ1dGUuY29kZUF0dHJpYnV0ZURhdGFUeXBlICE9PSAnR0EnICYmIGF0dHJpYnV0ZS5jb2RlQXR0cmlidXRlRGF0YVR5cGUgIT09ICdMSU5FJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuY29sLTEyXT1cImF0dHJpYnV0ZS5jb2RlQXR0cmlidXRlRGF0YVR5cGUgPT09ICdHQScgfHwgYXR0cmlidXRlLmNvZGVBdHRyaWJ1dGVEYXRhVHlwZSA9PT0gJ0xJTkUnXCI+PC9oY2ktYXR0cmlidXRlLWZsZXg+XHJcbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWF0dHJpYnV0ZUNvbnRhaW5lci5pc0F1dG9MYXlvdXQgfHwgYXR0cmlidXRlQ29udGFpbmVyLmlzQXV0b0xheW91dCA9PT0gJ04nXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGhjaS1hdHRyaWJ1dGUtYWJzb2x1dGUgW2lkXT1cIidpZC1hdHRyaWJ1dGUtJyArIGF0dHJpYnV0ZS5pZEF0dHJpYnV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHJpYnV0ZV09XCJhdHRyaWJ1dGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlZGl0SW5saW5lXT1cImVkaXRJbmxpbmVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5hdHRyaWJ1dGVdPVwidHJ1ZVwiPjwvaGNpLWF0dHJpYnV0ZS1hYnNvbHV0ZT5cclxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cclxuICAgICAgICAgIDwvbmdiLXBhbmVsPlxyXG4gICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICA8L25nYi1hY2NvcmRpb24+XHJcbiAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICA8bmctdGVtcGxhdGUgI2VkaXRNb2RhbCBsZXQtY2xvc2U9XCJjbG9zZVwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XHJcbiAgICAgICAge3tlZGl0Q29udGFpbmVyLmNvbnRhaW5lck5hbWV9fVxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHkgZC1mbGV4IGZsZXgtY29sdW1uIGhjaS1jb2QtZWRpdFwiPlxyXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGF0dHJpYnV0ZSBvZiBlZGl0Q29udGFpbmVyLmdyYXBoaWNhbEF0dHJpYnV0ZXMgfCBpc0dyb3VwQXR0cmlidXRlOiBmYWxzZVwiPlxyXG4gICAgICAgICAgPGhjaS1hdHRyaWJ1dGUtZWRpdCBbaWRdPVwiJ2VkaXQtaWQtYXR0cmlidXRlLScgKyBhdHRyaWJ1dGUuaWRBdHRyaWJ1dGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0cmlidXRlXT1cImF0dHJpYnV0ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYXR0cmlidXRlXCI+PC9oY2ktYXR0cmlidXRlLWVkaXQ+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XHJcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIChjbGljayk9XCJjbG9zZSgnU2F2ZScpXCI+U2F2ZTwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiAoY2xpY2spPVwiY2xvc2UoJ0NhbmNlbCcpXCI+Q2FuY2VsPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuICBgXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBdHRyaWJ1dGVDb25maWd1cmF0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBIb3N0QmluZGluZyhcImNsYXNzXCIpIGNsYXNzTGlzdDogc3RyaW5nID0gXCJoY2ktYXR0cmlidXRlLWNvbmZpZ3VyYXRpb24gaGNpLWNvZCBkLWZsZXggZmxleC1jb2x1bW4gZmxleC1ncm93LTFcIjtcclxuXHJcbiAgQElucHV0KCkgaWRBdHRyaWJ1dGVWYWx1ZVNldDogbnVtYmVyO1xyXG4gIEBJbnB1dCgpIGlkUGFyZW50T2JqZWN0OiBudW1iZXI7XHJcbiAgXHJcbiAgQElucHV0KCkgYWNjb3JkaW9uTmF2OiBBY2NvcmRpb25OYXZDb21wb25lbnQ7XHJcbiAgXHJcbiAgQElucHV0KCkgZWRpdElubGluZTogYm9vbGVhbiA9IHRydWU7XHJcbiAgQElucHV0KCkgZWRpdFBvcHVwOiBib29sZWFuID0gIGZhbHNlO1xyXG4gIEBJbnB1dCgpIGVkaXRhYmxlOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgQFZpZXdDaGlsZHJlbihOZ2JQYW5lbCkgdlBhbmVsczogUXVlcnlMaXN0PE5nYlBhbmVsPjtcclxuICBAQ29udGVudENoaWxkcmVuKE5nYlBhbmVsKSBjUGFuZWxzOiBRdWVyeUxpc3Q8TmdiUGFuZWw+O1xyXG5cclxuICBhdHRyaWJ1dGVDb25maWd1cmF0aW9uOiBBdHRyaWJ1dGVDb25maWd1cmF0aW9uO1xyXG4gIGF0dHJpYnV0ZVZhbHVlU2V0OiBBdHRyaWJ1dGVWYWx1ZVNldDtcclxuXHJcbiAgbG9hZGluZ1N1YmplY3Q6IFN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xyXG5cclxuICBlZGl0Q29udGFpbmVyOiBBdHRyaWJ1dGVDb250YWluZXI7XHJcblxyXG4gIHdpbmRvd0RpbWVuc2lvbjogYW55ID0ge307XHJcblxyXG4gIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBhdHRyaWJ1dGVTZXJ2aWNlOiBBdHRyaWJ1dGVTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcclxuICAgICAgICAgICAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsKSB7fVxyXG5cclxuICAvKipcclxuICAgKiBVcG9uIGluaXQsIHN1YnNjcmliZSB0byB0aGUgY29uZmlndXJhdGlvbiBhbmQgdmFsdWUgc2V0LlxyXG4gICAqL1xyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgaWYgKCEgdGhpcy5lZGl0YWJsZSkge1xyXG4gICAgICB0aGlzLmVkaXRJbmxpbmUgPSBmYWxzZTtcclxuICAgICAgdGhpcy5lZGl0UG9wdXAgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5sb2FkaW5nU3ViamVjdCA9IHRoaXMuYXR0cmlidXRlU2VydmljZS5nZXRMb2FkaW5nU3ViamVjdCgpO1xyXG5cclxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLmdldEF0dHJpYnV0ZUNvbmZpZ3VyYXRpb25TdWJqZWN0KCkuc3Vic2NyaWJlKChhdHRyaWJ1dGVDb25maWd1cmF0aW9uOiBBdHRyaWJ1dGVDb25maWd1cmF0aW9uKSA9PiB7XHJcbiAgICAgIHRoaXMuYXR0cmlidXRlQ29uZmlndXJhdGlvbiA9IGF0dHJpYnV0ZUNvbmZpZ3VyYXRpb247XHJcbiAgICAgIFxyXG4gICAgICB0aGlzLmF0dHJpYnV0ZVNlcnZpY2Uuc2V0QXR0cmlidXRlVmFsdWVTZXQodGhpcy5pZEF0dHJpYnV0ZVZhbHVlU2V0LCB0aGlzLmlkUGFyZW50T2JqZWN0KTtcclxuICAgIH0pKTtcclxuXHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKHRoaXMuYXR0cmlidXRlU2VydmljZS5hdHRyaWJ1dGVDb25maWd1cmF0aW9uRGltZW5zaW9uU3ViamVjdC5zdWJzY3JpYmUoKHdpbmRvd0RpbWVuc2lvbjogYW55KSA9PiB7XHJcbiAgICAgIHRoaXMud2luZG93RGltZW5zaW9uID0gd2luZG93RGltZW5zaW9uO1xyXG4gICAgfSkpO1xyXG5cclxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5hZGQodGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLmdldEF0dHJpYnV0ZVZhbHVlU2V0KCkuc3Vic2NyaWJlKChhdHRyaWJ1dGVWYWx1ZVNldDogQXR0cmlidXRlVmFsdWVTZXQpID0+IHtcclxuICAgICAgdGhpcy5hdHRyaWJ1dGVWYWx1ZVNldCA9IGF0dHJpYnV0ZVZhbHVlU2V0O1xyXG4gICAgICBcclxuICAgICAgaWYgKHRoaXMuYXR0cmlidXRlVmFsdWVTZXQpIHtcclxuICAgICAgICB0aGlzLmF0dHJpYnV0ZVNlcnZpY2Uubm90aWZ5QXR0cmlidXRlcygpO1xyXG4gICAgICB9XHJcbiAgICB9KSk7XHJcbiAgfVxyXG4gIFxyXG4gIEBJbnB1dCgpIHNldCBib3VuZERhdGEodmFsdWU6IGFueSkge1xyXG4gICAgdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLnNldEJvdW5kRGF0YSh2YWx1ZSk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgQFZpZXdDaGlsZChOZ2JBY2NvcmRpb24sIHtzdGF0aWM6IGZhbHNlfSlcclxuICBzZXQgYWNjb3JkaW9uKGFjY29yZGlvbjogTmdiQWNjb3JkaW9uKSB7XHJcbiAgICBpZiAoYWNjb3JkaW9uKSB7XHJcbiAgICAgIGFjY29yZGlvbi5wYW5lbHMucmVzZXQoW3RoaXMuY1BhbmVscy50b0FycmF5KCksIHRoaXMudlBhbmVscy50b0FycmF5KCldKTtcclxuICAgICAgYWNjb3JkaW9uLm5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpO1xyXG5cclxuICAgICAgaWYgKHRoaXMuYWNjb3JkaW9uTmF2ICYmICF0aGlzLmFjY29yZGlvbk5hdi5hY2NvcmRpb24pIHtcclxuICAgICAgICB0aGlzLmFjY29yZGlvbk5hdi5zZXRBY2NvcmRpb24oYWNjb3JkaW9uKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiB7W3Byb3BOYW1lOiBzdHJpbmddOiBTaW1wbGVDaGFuZ2V9KSB7XHJcbiAgICBpZiAoISB0aGlzLmVkaXRhYmxlKSB7XHJcbiAgICAgIHRoaXMuZWRpdElubGluZSA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmVkaXRQb3B1cCA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBpZiAoY2hhbmdlc1tcImFjY29yZGlvbk5hdlwiXSAmJiB0aGlzLmFjY29yZGlvbk5hdiAmJiB0aGlzLmFjY29yZGlvbikge1xyXG4gICAgICB0aGlzLmFjY29yZGlvbk5hdi5hY2NvcmRpb24gPSB0aGlzLmFjY29yZGlvbjtcclxuICAgICAgdGhpcy5hY2NvcmRpb25OYXYucGFuZWxzID0gdGhpcy5hY2NvcmRpb24ucGFuZWxzO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0QXR0cmlidXRlU2VydmljZSgpOiBBdHRyaWJ1dGVTZXJ2aWNlIHtcclxuICAgIHJldHVybiB0aGlzLmF0dHJpYnV0ZVNlcnZpY2U7XHJcbiAgfVxyXG5cclxuICBlZGl0KG1vZGFsOiBUZW1wbGF0ZVJlZjxhbnk+LCBlZGl0Q29udGFpbmVyOiBBdHRyaWJ1dGVDb250YWluZXIpOiB2b2lkIHtcclxuICAgIHRoaXMuZWRpdENvbnRhaW5lciA9IGVkaXRDb250YWluZXI7XHJcblxyXG4gICAgdGhpcy5tb2RhbFNlcnZpY2Uub3Blbihtb2RhbCwge3dpbmRvd0NsYXNzOiBcIm1vZGFsLWxnXCJ9KS5yZXN1bHQudGhlbigocmVzdWx0KSA9PiB7XHJcbiAgICAgIGlmIChyZXN1bHQgPT09IFwiU2F2ZVwiKSB7XHJcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLnVwZGF0ZUF0dHJpYnV0ZVZhbHVlU2V0KCk7XHJcbiAgICAgIH0gZWxzZSBpZiAocmVzdWx0ID09PSBcIkNhbmNlbFwiKSB7XHJcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLmNsZWFyVXBkYXRlZEF0dHJpYnV0ZVZhbHVlcygpO1xyXG4gICAgICB9XHJcbiAgICB9LCAocmVhc29uKSA9PiB7fSk7XHJcbiAgfVxyXG5cclxuICBwb3N0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5hdHRyaWJ1dGVTZXJ2aWNlLnVwZGF0ZUF0dHJpYnV0ZVZhbHVlU2V0KCk7XHJcbiAgfVxyXG5cclxufVxyXG4iXX0=