@ifsworld/granite-components 15.0.2 → 16.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.
- package/date-picker/lib/date-picker-base.d.ts +3 -3
- package/date-picker/lib/date-picker.module.d.ts +2 -2
- package/fesm2022/ifsworld-granite-components-carousel.mjs +9 -9
- package/fesm2022/ifsworld-granite-components-carousel.mjs.map +1 -1
- package/fesm2022/ifsworld-granite-components-date-picker.mjs +34 -30
- package/fesm2022/ifsworld-granite-components-date-picker.mjs.map +1 -1
- package/fesm2022/ifsworld-granite-components-file-upload.mjs +13 -12
- package/fesm2022/ifsworld-granite-components-file-upload.mjs.map +1 -1
- package/fesm2022/ifsworld-granite-components-table.mjs +32 -29
- package/fesm2022/ifsworld-granite-components-table.mjs.map +1 -1
- package/fesm2022/ifsworld-granite-components-tooltip.mjs +16 -15
- package/fesm2022/ifsworld-granite-components-tooltip.mjs.map +1 -1
- package/fesm2022/ifsworld-granite-components.mjs +341 -322
- package/fesm2022/ifsworld-granite-components.mjs.map +1 -1
- package/lib/contacts/contacts-trigger/contacts-trigger-data.d.ts +1 -1
- package/lib/core/overlay-base.d.ts +1 -1
- package/lib/core/radio-checkbox-base.d.ts +1 -1
- package/lib/menu/menu-base.d.ts +1 -1
- package/lib/progress-bar/progress-bar-legend-base.d.ts +1 -1
- package/package.json +13 -25
- package/src/lib/core/style/_mixins.scss +10 -9
- package/src/lib/core/style/_range-functions.scss +6 -4
- package/src/lib/core/style/_z-index.scss +6 -4
- package/table/lib/cell/cell.d.ts +1 -1
- package/esm2022/carousel/ifsworld-granite-components-carousel.mjs +0 -5
- package/esm2022/carousel/index.mjs +0 -3
- package/esm2022/carousel/lib/carousel.component.mjs +0 -156
- package/esm2022/carousel/lib/carousel.module.mjs +0 -31
- package/esm2022/date-picker/ifsworld-granite-components-date-picker.mjs +0 -5
- package/esm2022/date-picker/index.mjs +0 -5
- package/esm2022/date-picker/lib/date-picker-base.mjs +0 -53
- package/esm2022/date-picker/lib/date-picker-trigger-for.directive.mjs +0 -228
- package/esm2022/date-picker/lib/date-picker.component.mjs +0 -30
- package/esm2022/date-picker/lib/date-picker.module.mjs +0 -58
- package/esm2022/date-picker/lib/date-range-picker.component.mjs +0 -46
- package/esm2022/file-upload/ifsworld-granite-components-file-upload.mjs +0 -5
- package/esm2022/file-upload/index.mjs +0 -3
- package/esm2022/file-upload/lib/directives/file-drag-and-drop.directive.mjs +0 -102
- package/esm2022/file-upload/lib/file-upload.component.mjs +0 -182
- package/esm2022/file-upload/lib/file-upload.constants.mjs +0 -45
- package/esm2022/file-upload/lib/file-upload.module.mjs +0 -32
- package/esm2022/file-upload/lib/file-upload.utils.mjs +0 -13
- package/esm2022/ifsworld-granite-components.mjs +0 -5
- package/esm2022/index.mjs +0 -90
- package/esm2022/lib/arrange-grid/arrange-grid-item.component.mjs +0 -44
- package/esm2022/lib/arrange-grid/arrange-grid.component.mjs +0 -125
- package/esm2022/lib/arrange-grid/arrange-grid.module.mjs +0 -19
- package/esm2022/lib/avatar/avatar-default-status/avatar-default-status.component.mjs +0 -36
- package/esm2022/lib/avatar/avatar.component.mjs +0 -68
- package/esm2022/lib/avatar/avatar.component.public-types.mjs +0 -7
- package/esm2022/lib/avatar/avatar.module.mjs +0 -37
- package/esm2022/lib/avatar/custom-avatar-status.directive.mjs +0 -18
- package/esm2022/lib/avatar/empty-avatar/empty-avatar.component.mjs +0 -37
- package/esm2022/lib/badge/badge.component.mjs +0 -39
- package/esm2022/lib/badge/badge.module.mjs +0 -18
- package/esm2022/lib/badge/testing/badge.harness.mjs +0 -25
- package/esm2022/lib/button/button.component.mjs +0 -87
- package/esm2022/lib/button/button.module.mjs +0 -16
- package/esm2022/lib/card-list/card/card-avatar.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-actions.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-body.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-content.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-footer.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-header-subtitle.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-header-title.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card-content/card-header.component.mjs +0 -11
- package/esm2022/lib/card-list/card/card.component.mjs +0 -11
- package/esm2022/lib/card-list/card-list.component.mjs +0 -24
- package/esm2022/lib/card-list/card-list.module.mjs +0 -68
- package/esm2022/lib/checkbox/checkbox-group.component.mjs +0 -17
- package/esm2022/lib/checkbox/checkbox.component.mjs +0 -99
- package/esm2022/lib/checkbox/checkbox.module.mjs +0 -17
- package/esm2022/lib/chips/chip-input.mjs +0 -195
- package/esm2022/lib/chips/chip-list.component.mjs +0 -567
- package/esm2022/lib/chips/chip.component.mjs +0 -288
- package/esm2022/lib/chips/chips.module.mjs +0 -31
- package/esm2022/lib/collapsible-group/collapsible-group-body.directive.mjs +0 -17
- package/esm2022/lib/collapsible-group/collapsible-group-header.directive.mjs +0 -17
- package/esm2022/lib/collapsible-group/collapsible-group.component.mjs +0 -46
- package/esm2022/lib/collapsible-group/collapsible-group.module.mjs +0 -33
- package/esm2022/lib/contacts/contact-item/contact-item.component.mjs +0 -27
- package/esm2022/lib/contacts/contact-item-default-status/contact-item-default-status.component.mjs +0 -20
- package/esm2022/lib/contacts/contact-item-title/contact-item-title.component.mjs +0 -15
- package/esm2022/lib/contacts/contacts-profile/contacts-profile.component.mjs +0 -18
- package/esm2022/lib/contacts/contacts-trigger/contacts-trigger-data.mjs +0 -24
- package/esm2022/lib/contacts/contacts-trigger/contacts-trigger-for.directive.mjs +0 -231
- package/esm2022/lib/contacts/contacts-types/contacts.component.private-types.mjs +0 -2
- package/esm2022/lib/contacts/contacts-types/contacts.component.public-types.mjs +0 -9
- package/esm2022/lib/contacts/contacts.component.mjs +0 -92
- package/esm2022/lib/contacts/contacts.module.mjs +0 -53
- package/esm2022/lib/contacts/custom-profile.directive.mjs +0 -16
- package/esm2022/lib/contacts/custom-status.directive.mjs +0 -18
- package/esm2022/lib/core/animation.mjs +0 -34
- package/esm2022/lib/core/client-environment.mjs +0 -20
- package/esm2022/lib/core/common-behaviors/disabled.mjs +0 -27
- package/esm2022/lib/core/core.module.mjs +0 -44
- package/esm2022/lib/core/devices/client-input-desktop.directive.mjs +0 -29
- package/esm2022/lib/core/devices/client-input-touch.directive.mjs +0 -29
- package/esm2022/lib/core/devices/client-output-desktop.directive.mjs +0 -29
- package/esm2022/lib/core/devices/client-output-touch.directive.mjs +0 -29
- package/esm2022/lib/core/hide-on-overflow.directive.mjs +0 -83
- package/esm2022/lib/core/overlay-base.mjs +0 -18
- package/esm2022/lib/core/overlay-position-config.mjs +0 -2
- package/esm2022/lib/core/overlay-trigger-for-base.directive.mjs +0 -121
- package/esm2022/lib/core/overlay.service.mjs +0 -90
- package/esm2022/lib/core/pipes/pure-pipes.module.mjs +0 -16
- package/esm2022/lib/core/pipes/title.pipe.mjs +0 -21
- package/esm2022/lib/core/radio-checkbox-base.mjs +0 -19
- package/esm2022/lib/core/services/names-utils-service.mjs +0 -51
- package/esm2022/lib/core/theme.library.mjs +0 -59
- package/esm2022/lib/core/types.mjs +0 -2
- package/esm2022/lib/grid/grid.component.mjs +0 -128
- package/esm2022/lib/grid/grid.module.mjs +0 -18
- package/esm2022/lib/icon/icon.component.mjs +0 -43
- package/esm2022/lib/icon/icon.module.mjs +0 -16
- package/esm2022/lib/input-field/input-field.component.mjs +0 -167
- package/esm2022/lib/input-field/input-field.module.mjs +0 -20
- package/esm2022/lib/label/label.component.mjs +0 -31
- package/esm2022/lib/label/label.module.mjs +0 -18
- package/esm2022/lib/menu/divider.directive.mjs +0 -23
- package/esm2022/lib/menu/menu-base.mjs +0 -364
- package/esm2022/lib/menu/menu-desktop-animations.mjs +0 -23
- package/esm2022/lib/menu/menu-errors.mjs +0 -37
- package/esm2022/lib/menu/menu-item.component.mjs +0 -89
- package/esm2022/lib/menu/menu-panel.mjs +0 -7
- package/esm2022/lib/menu/menu-positions.mjs +0 -9
- package/esm2022/lib/menu/menu-touch-animations.mjs +0 -137
- package/esm2022/lib/menu/menu-touch-close.component.mjs +0 -13
- package/esm2022/lib/menu/menu-touch-title.component.mjs +0 -59
- package/esm2022/lib/menu/menu-trigger-for.directive.mjs +0 -738
- package/esm2022/lib/menu/menu.component.mjs +0 -30
- package/esm2022/lib/menu/menu.module.mjs +0 -55
- package/esm2022/lib/menu/testing/menu.harness.mjs +0 -109
- package/esm2022/lib/menu/title.directive.mjs +0 -17
- package/esm2022/lib/progress-bar/progress-bar-legend/progress-bar-legend.component.mjs +0 -19
- package/esm2022/lib/progress-bar/progress-bar-legend-base.mjs +0 -17
- package/esm2022/lib/progress-bar/progress-bar-legend-trigger-for.directive.mjs +0 -54
- package/esm2022/lib/progress-bar/progress-bar.component.mjs +0 -92
- package/esm2022/lib/progress-bar/progress-bar.model.mjs +0 -2
- package/esm2022/lib/progress-bar/progress-bar.module.mjs +0 -44
- package/esm2022/lib/radio-button/radio-button.component.mjs +0 -119
- package/esm2022/lib/radio-button/radio-button.module.mjs +0 -17
- package/esm2022/lib/radio-button/radio-group.component.mjs +0 -17
- package/esm2022/lib/toggle-switch/toggle-switch.component.mjs +0 -100
- package/esm2022/lib/toggle-switch/toggle-switch.module.mjs +0 -16
- package/esm2022/table/ifsworld-granite-components-table.mjs +0 -5
- package/esm2022/table/index.mjs +0 -5
- package/esm2022/table/lib/cell/cell-align/cell-align-classes.directive.mjs +0 -26
- package/esm2022/table/lib/cell/cell.mjs +0 -15
- package/esm2022/table/lib/cell/table-data-cell.component.mjs +0 -25
- package/esm2022/table/lib/cell/table-header-cell.component.mjs +0 -14
- package/esm2022/table/lib/column/table-column.directive.mjs +0 -33
- package/esm2022/table/lib/column-size/column-size.directive.mjs +0 -34
- package/esm2022/table/lib/table-constants.library.mjs +0 -7
- package/esm2022/table/lib/table.component.mjs +0 -62
- package/esm2022/table/lib/table.model.mjs +0 -2
- package/esm2022/table/lib/table.module.mjs +0 -38
- package/esm2022/tooltip/ifsworld-granite-components-tooltip.mjs +0 -5
- package/esm2022/tooltip/index.mjs +0 -4
- package/esm2022/tooltip/lib/Services/granite-tooltip.service.mjs +0 -28
- package/esm2022/tooltip/lib/tooltip-constants.library.mjs +0 -4
- package/esm2022/tooltip/lib/tooltip-trigger-for.directive.mjs +0 -147
- package/esm2022/tooltip/lib/tooltip.component.mjs +0 -14
- package/esm2022/tooltip/lib/tooltip.module.mjs +0 -19
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
import { FocusKeyManager } from '@angular/cdk/a11y';
|
|
2
|
-
import { Directionality } from '@angular/cdk/bidi';
|
|
3
|
-
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
4
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
5
|
-
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, ElementRef, Input, Optional, QueryList, Self, EventEmitter, } from '@angular/core';
|
|
6
|
-
import { FormGroupDirective, NgControl, NgForm, } from '@angular/forms';
|
|
7
|
-
import { merge, Subject } from 'rxjs';
|
|
8
|
-
import { startWith, takeUntil } from 'rxjs/operators';
|
|
9
|
-
import { GraniteChipComponent, } from './chip.component';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "@angular/cdk/bidi";
|
|
12
|
-
import * as i2 from "@angular/forms";
|
|
13
|
-
class GraniteChipListBase {
|
|
14
|
-
constructor(_parentForm, _parentFormGroup, ngControl) {
|
|
15
|
-
this._parentForm = _parentForm;
|
|
16
|
-
this._parentFormGroup = _parentFormGroup;
|
|
17
|
-
this.ngControl = ngControl;
|
|
18
|
-
this.stateChanges = new EventEmitter();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// Increasing integer for generating unique ids for chip-list components.
|
|
22
|
-
let nextUniqueId = 0;
|
|
23
|
-
export class GraniteChipListComponent extends GraniteChipListBase {
|
|
24
|
-
/** The ARIA role applied to the chip list. */
|
|
25
|
-
get role() {
|
|
26
|
-
if (this._explicitRole) {
|
|
27
|
-
return this._explicitRole;
|
|
28
|
-
}
|
|
29
|
-
return this.empty ? null : 'listbox';
|
|
30
|
-
}
|
|
31
|
-
set role(role) {
|
|
32
|
-
this._explicitRole = role;
|
|
33
|
-
}
|
|
34
|
-
/** Whether the user should be allowed to select multiselect chips. */
|
|
35
|
-
get multiselect() {
|
|
36
|
-
return this._multiple;
|
|
37
|
-
}
|
|
38
|
-
set multiselect(value) {
|
|
39
|
-
this._multiple = coerceBooleanProperty(value);
|
|
40
|
-
this._syncChipsState();
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Whether the chip list is disabled.
|
|
44
|
-
*/
|
|
45
|
-
get disabled() {
|
|
46
|
-
return this.ngControl ? !!this.ngControl.disabled : this._disabled;
|
|
47
|
-
}
|
|
48
|
-
set disabled(value) {
|
|
49
|
-
this._disabled = coerceBooleanProperty(value);
|
|
50
|
-
this._syncChipsState();
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Whether or not this chip list is selectable. When a chip list is not selectable,
|
|
54
|
-
* the selected states for all the chips inside the chip list are always ignored.
|
|
55
|
-
*/
|
|
56
|
-
get selectable() {
|
|
57
|
-
return this._selectable;
|
|
58
|
-
}
|
|
59
|
-
set selectable(value) {
|
|
60
|
-
this._selectable = coerceBooleanProperty(value);
|
|
61
|
-
if (this.chips) {
|
|
62
|
-
this.chips.forEach((chip) => (chip._chipListSelectable = this._selectable));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
set tabindex(value) {
|
|
66
|
-
this._userTabIndex = value;
|
|
67
|
-
this._tabIndex = value;
|
|
68
|
-
}
|
|
69
|
-
/** Unique identifier for the chip list. */
|
|
70
|
-
get id() {
|
|
71
|
-
return this._chipInput ? this._chipInput.id : this._uid;
|
|
72
|
-
}
|
|
73
|
-
/** Whether any chips or the matChipInput inside of this chip-list has focus. */
|
|
74
|
-
get focused() {
|
|
75
|
-
return ((this._chipInput && this._chipInput.focused) || this._hasFocusedChip());
|
|
76
|
-
}
|
|
77
|
-
/** Whether the chip list is empty. */
|
|
78
|
-
get empty() {
|
|
79
|
-
return ((!this._chipInput || this._chipInput.empty) &&
|
|
80
|
-
(!this.chips || this.chips.length === 0));
|
|
81
|
-
}
|
|
82
|
-
/** The array of selected chips inside chip list. */
|
|
83
|
-
get selected() {
|
|
84
|
-
return this.multiselect
|
|
85
|
-
? this._selectionModel?.selected || []
|
|
86
|
-
: this._selectionModel?.selected[0];
|
|
87
|
-
}
|
|
88
|
-
/** Combined stream of all of the child chips' selection change events. */
|
|
89
|
-
get chipSelectionChanges() {
|
|
90
|
-
return merge(...this.chips.map((chip) => chip.selectionChange));
|
|
91
|
-
}
|
|
92
|
-
/** Combined stream of all of the child chips' focus change events. */
|
|
93
|
-
get chipFocusChanges() {
|
|
94
|
-
return merge(...this.chips.map((chip) => chip.chipFocus));
|
|
95
|
-
}
|
|
96
|
-
/** Combined stream of all of the child chips' blur change events. */
|
|
97
|
-
get chipBlurChanges() {
|
|
98
|
-
return merge(...this.chips.map((chip) => chip.chipBlur));
|
|
99
|
-
}
|
|
100
|
-
/** Combined stream of all of the child chips' remove change events. */
|
|
101
|
-
get chipRemoveChanges() {
|
|
102
|
-
return merge(...this.chips.map((chip) => chip.destroyed));
|
|
103
|
-
}
|
|
104
|
-
constructor(_elementRef, _changeDetectorRef, _dir, _parentForm, _parentFormGroup, ngControl) {
|
|
105
|
-
super(_parentForm, _parentFormGroup, ngControl);
|
|
106
|
-
this._elementRef = _elementRef;
|
|
107
|
-
this._changeDetectorRef = _changeDetectorRef;
|
|
108
|
-
this._dir = _dir;
|
|
109
|
-
this.ariaLabel = null;
|
|
110
|
-
this.ariaLabelledby = null;
|
|
111
|
-
this.ariaOrientation = 'horizontal';
|
|
112
|
-
this.controlType = 'granite-chip-list';
|
|
113
|
-
/** Uid of the chip list */
|
|
114
|
-
this._uid = `granite-chip-list-${nextUniqueId++}`;
|
|
115
|
-
/** Tab index for the chip list. */
|
|
116
|
-
this._tabIndex = 0;
|
|
117
|
-
/**
|
|
118
|
-
* User defined tab index.
|
|
119
|
-
* When it is not null, use user defined tab index. Otherwise use _tabIndex
|
|
120
|
-
*/
|
|
121
|
-
this._userTabIndex = null;
|
|
122
|
-
this._disabled = false;
|
|
123
|
-
this._selectable = true;
|
|
124
|
-
/**
|
|
125
|
-
* When a chip is destroyed, we store the index of the destroyed chip until the chips
|
|
126
|
-
* query list notifies about the update. This is necessary because we cannot determine an
|
|
127
|
-
* appropriate chip that should receive focus until the array of chips updated completely.
|
|
128
|
-
*/
|
|
129
|
-
this._lastDestroyedChipIndex = null;
|
|
130
|
-
/** Subject that emits when the component has been destroyed. */
|
|
131
|
-
this._destroyed = new Subject();
|
|
132
|
-
this._multiple = false;
|
|
133
|
-
/** Function when changed */
|
|
134
|
-
this._onChange = () => {
|
|
135
|
-
// Implemented as part of ControlValueAccessor
|
|
136
|
-
};
|
|
137
|
-
/** Function when changed */
|
|
138
|
-
this._onTouched = () => {
|
|
139
|
-
// Implemented as part of ControlValueAccessor
|
|
140
|
-
};
|
|
141
|
-
this._compareWith = (o1, o2) => o1 === o2;
|
|
142
|
-
if (this.ngControl) {
|
|
143
|
-
this.ngControl.valueAccessor = this;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
ngAfterContentInit() {
|
|
147
|
-
this._keyManager = new FocusKeyManager(this.chips)
|
|
148
|
-
.withWrap()
|
|
149
|
-
.withVerticalOrientation()
|
|
150
|
-
.withHomeAndEnd()
|
|
151
|
-
.withHorizontalOrientation(this._dir ? this._dir.value : 'ltr');
|
|
152
|
-
if (this._dir) {
|
|
153
|
-
this._dir.change
|
|
154
|
-
.pipe(takeUntil(this._destroyed))
|
|
155
|
-
.subscribe((dir) => this._keyManager.withHorizontalOrientation(dir));
|
|
156
|
-
}
|
|
157
|
-
this._keyManager.tabOut.pipe(takeUntil(this._destroyed)).subscribe(() => {
|
|
158
|
-
this._allowFocusEscape();
|
|
159
|
-
});
|
|
160
|
-
// When the list changes, re-subscribe
|
|
161
|
-
this.chips.changes
|
|
162
|
-
.pipe(startWith(null), takeUntil(this._destroyed))
|
|
163
|
-
.subscribe(() => {
|
|
164
|
-
if (this.disabled) {
|
|
165
|
-
// Since this happens after the content has been
|
|
166
|
-
// checked, we need to defer it to the next tick.
|
|
167
|
-
Promise.resolve().then(() => {
|
|
168
|
-
this._syncChipsState();
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
this._resetChips();
|
|
172
|
-
// Reset chips selected/deselected status
|
|
173
|
-
this._initializeSelection();
|
|
174
|
-
// Check to see if we need to update our tab index
|
|
175
|
-
this._updateTabIndex();
|
|
176
|
-
// Check to see if we have a destroyed chip and need to refocus
|
|
177
|
-
this._updateFocusForDestroyedChips();
|
|
178
|
-
this.stateChanges.next();
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
ngOnInit() {
|
|
182
|
-
this._selectionModel = new SelectionModel(this.multiselect, undefined, false);
|
|
183
|
-
this.stateChanges.next();
|
|
184
|
-
}
|
|
185
|
-
ngDoCheck() {
|
|
186
|
-
if (this.ngControl) {
|
|
187
|
-
// We need to re-evaluate this on every change detection cycle, because there are some
|
|
188
|
-
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
|
|
189
|
-
// that whatever logic is in here has to be super lean or we risk destroying the performance.
|
|
190
|
-
if (this.ngControl.disabled !== this._disabled) {
|
|
191
|
-
this.disabled = !!this.ngControl.disabled;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
ngOnDestroy() {
|
|
196
|
-
this._destroyed.next();
|
|
197
|
-
this._destroyed.complete();
|
|
198
|
-
this.stateChanges.complete();
|
|
199
|
-
this._dropSubscriptions();
|
|
200
|
-
}
|
|
201
|
-
/** Associates an HTML input element with this chip list. */
|
|
202
|
-
registerInput(inputElement) {
|
|
203
|
-
this._chipInput = inputElement;
|
|
204
|
-
// We use this attribute to match the chip list to its input in test harnesses.
|
|
205
|
-
// Set the attribute directly here to avoid "changed after checked" errors.
|
|
206
|
-
this._elementRef.nativeElement.setAttribute('data-granite-chip-input', inputElement.id);
|
|
207
|
-
}
|
|
208
|
-
// Implemented as part of ControlValueAccessor.
|
|
209
|
-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
210
|
-
writeValue(value) {
|
|
211
|
-
if (this.chips) {
|
|
212
|
-
this._setSelectionByValue(value, false);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
// Implemented as part of ControlValueAccessor.
|
|
216
|
-
registerOnChange(fn) {
|
|
217
|
-
this._onChange = fn;
|
|
218
|
-
}
|
|
219
|
-
// Implemented as part of ControlValueAccessor.
|
|
220
|
-
registerOnTouched(fn) {
|
|
221
|
-
this._onTouched = fn;
|
|
222
|
-
}
|
|
223
|
-
// Implemented as part of ControlValueAccessor.
|
|
224
|
-
setDisabledState(isDisabled) {
|
|
225
|
-
this.disabled = isDisabled;
|
|
226
|
-
this.stateChanges.next();
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Focus chip list when click on the container.
|
|
230
|
-
*/
|
|
231
|
-
onContainerClick(event) {
|
|
232
|
-
if (!this._originatesFromChip(event)) {
|
|
233
|
-
this.focus();
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Focuses the first non-disabled chip in this chip list, or the associated input when there
|
|
238
|
-
* are no eligible chips.
|
|
239
|
-
*/
|
|
240
|
-
focus(options) {
|
|
241
|
-
if (this.disabled) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
// Focus on first element if there's no chipInput inside chip-list
|
|
245
|
-
if (this._chipInput && this._chipInput.focused) {
|
|
246
|
-
// do nothing
|
|
247
|
-
}
|
|
248
|
-
else if (this.chips.length > 0) {
|
|
249
|
-
this._keyManager.setFirstItemActive();
|
|
250
|
-
this.stateChanges.next();
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
this._focusInput(options);
|
|
254
|
-
this.stateChanges.next();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
/** Attempt to focus an input if we have one. */
|
|
258
|
-
_focusInput(options) {
|
|
259
|
-
if (this._chipInput) {
|
|
260
|
-
this._chipInput.setFocus(options);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* Pass events to the keyboard manager. Available here for tests.
|
|
265
|
-
*/
|
|
266
|
-
_keydown(event) {
|
|
267
|
-
const target = event.target;
|
|
268
|
-
if (target && target.classList.contains('granite-chip')) {
|
|
269
|
-
this._keyManager.onKeydown(event);
|
|
270
|
-
this.stateChanges.next();
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
/** When blurred, mark the field as touched when focus moved outside the chip list. */
|
|
274
|
-
_blur() {
|
|
275
|
-
if (!this._hasFocusedChip()) {
|
|
276
|
-
this._keyManager.setActiveItem(-1);
|
|
277
|
-
}
|
|
278
|
-
if (!this.disabled) {
|
|
279
|
-
if (this._chipInput) {
|
|
280
|
-
// If there's a chip input, we should check whether the focus moved to chip input.
|
|
281
|
-
// If the focus is not moved to chip input, mark the field as touched. If the focus moved
|
|
282
|
-
// to chip input, do nothing.
|
|
283
|
-
// Timeout is needed to wait for the focus() event trigger on chip input.
|
|
284
|
-
setTimeout(() => {
|
|
285
|
-
if (!this.focused) {
|
|
286
|
-
this._markAsTouched();
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
// If there's no chip input, then mark the field as touched.
|
|
292
|
-
this._markAsTouched();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
/** Mark the field as touched */
|
|
297
|
-
_markAsTouched() {
|
|
298
|
-
this._onTouched();
|
|
299
|
-
this._changeDetectorRef.markForCheck();
|
|
300
|
-
this.stateChanges.next();
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Removes the `tabindex` from the chip list and resets it back afterwards, allowing the
|
|
304
|
-
* user to tab out of it. This prevents the list from capturing focus and redirecting
|
|
305
|
-
* it back to the first chip, creating a focus trap, if it user tries to tab away.
|
|
306
|
-
*/
|
|
307
|
-
_allowFocusEscape() {
|
|
308
|
-
if (this._tabIndex !== -1) {
|
|
309
|
-
this._tabIndex = -1;
|
|
310
|
-
setTimeout(() => {
|
|
311
|
-
this._tabIndex = this._userTabIndex || 0;
|
|
312
|
-
this._changeDetectorRef.markForCheck();
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Check the tab index as you should not be allowed to focus an empty list.
|
|
318
|
-
*/
|
|
319
|
-
_updateTabIndex() {
|
|
320
|
-
// If we have 0 chips, we should not allow keyboard focus
|
|
321
|
-
this._tabIndex = this._userTabIndex || (this.chips.length === 0 ? -1 : 0);
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* If the amount of chips changed, we need to update the
|
|
325
|
-
* key manager state and focus the next closest chip.
|
|
326
|
-
*/
|
|
327
|
-
_updateFocusForDestroyedChips() {
|
|
328
|
-
// Move focus to the closest chip. If no other chips remain, focus the chip-list itself.
|
|
329
|
-
if (this._lastDestroyedChipIndex != null) {
|
|
330
|
-
if (this.chips.length) {
|
|
331
|
-
const newChipIndex = Math.min(this._lastDestroyedChipIndex, this.chips.length - 1);
|
|
332
|
-
this._keyManager.setActiveItem(newChipIndex);
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
335
|
-
this.focus();
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
this._lastDestroyedChipIndex = null;
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Utility to ensure all indexes are valid.
|
|
342
|
-
*
|
|
343
|
-
* @param index The index to be checked.
|
|
344
|
-
* @returns True if the index is valid for our list of chips.
|
|
345
|
-
*/
|
|
346
|
-
_isValidIndex(index) {
|
|
347
|
-
return index >= 0 && index < this.chips.length;
|
|
348
|
-
}
|
|
349
|
-
_setSelectionByValue(value, isUserInput = true) {
|
|
350
|
-
this._clearSelection();
|
|
351
|
-
this.chips.forEach((chip) => chip.deselect());
|
|
352
|
-
if (Array.isArray(value)) {
|
|
353
|
-
value.forEach((currentValue) => this._selectValue(currentValue, isUserInput));
|
|
354
|
-
this._sortValues();
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
const correspondingChip = this._selectValue(value, isUserInput);
|
|
358
|
-
// Shift focus to the active item. Note that we shouldn't do this in multiselect
|
|
359
|
-
// mode, because we don't know what chip the user interacted with last.
|
|
360
|
-
if (correspondingChip) {
|
|
361
|
-
if (isUserInput) {
|
|
362
|
-
this._keyManager.setActiveItem(correspondingChip);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* Finds and selects the chip based on its value.
|
|
369
|
-
* @returns Chip that has the corresponding value.
|
|
370
|
-
*/
|
|
371
|
-
_selectValue(value, isUserInput = true) {
|
|
372
|
-
const correspondingChip = this.chips.find((chip) => {
|
|
373
|
-
return chip.value != null && this._compareWith(chip.value, value);
|
|
374
|
-
});
|
|
375
|
-
if (correspondingChip) {
|
|
376
|
-
correspondingChip.select(isUserInput);
|
|
377
|
-
this._selectionModel.select(correspondingChip);
|
|
378
|
-
}
|
|
379
|
-
return correspondingChip;
|
|
380
|
-
}
|
|
381
|
-
_initializeSelection() {
|
|
382
|
-
// Defer setting the value in order to avoid the "Expression
|
|
383
|
-
// has changed after it was checked" errors from Angular.
|
|
384
|
-
Promise.resolve().then(() => {
|
|
385
|
-
if (this.ngControl) {
|
|
386
|
-
this._setSelectionByValue(this.ngControl.value, false);
|
|
387
|
-
this.stateChanges.next();
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Deselects every chip in the list.
|
|
393
|
-
* @param skip Chip that should not be deselected.
|
|
394
|
-
*/
|
|
395
|
-
_clearSelection(skip) {
|
|
396
|
-
this._selectionModel.clear();
|
|
397
|
-
this.chips.forEach((chip) => {
|
|
398
|
-
if (chip !== skip) {
|
|
399
|
-
chip.deselect();
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
this.stateChanges.next();
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Sorts the model values, ensuring that they keep the same
|
|
406
|
-
* order that they have in the panel.
|
|
407
|
-
*/
|
|
408
|
-
_sortValues() {
|
|
409
|
-
if (this._multiple) {
|
|
410
|
-
this._selectionModel.clear();
|
|
411
|
-
this.chips.forEach((chip) => {
|
|
412
|
-
if (chip.selected) {
|
|
413
|
-
this._selectionModel.select(chip);
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
this.stateChanges.next();
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
_resetChips() {
|
|
420
|
-
this._dropSubscriptions();
|
|
421
|
-
this._listenToChipsFocus();
|
|
422
|
-
this._listenToChipsSelection();
|
|
423
|
-
this._listenToChipsRemoved();
|
|
424
|
-
}
|
|
425
|
-
_dropSubscriptions() {
|
|
426
|
-
if (this._chipFocusSubscription) {
|
|
427
|
-
this._chipFocusSubscription.unsubscribe();
|
|
428
|
-
this._chipFocusSubscription = null;
|
|
429
|
-
}
|
|
430
|
-
if (this._chipBlurSubscription) {
|
|
431
|
-
this._chipBlurSubscription.unsubscribe();
|
|
432
|
-
this._chipBlurSubscription = null;
|
|
433
|
-
}
|
|
434
|
-
if (this._chipSelectionSubscription) {
|
|
435
|
-
this._chipSelectionSubscription.unsubscribe();
|
|
436
|
-
this._chipSelectionSubscription = null;
|
|
437
|
-
}
|
|
438
|
-
if (this._chipRemoveSubscription) {
|
|
439
|
-
this._chipRemoveSubscription.unsubscribe();
|
|
440
|
-
this._chipRemoveSubscription = null;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
/** Listens to user-generated selection events on each chip. */
|
|
444
|
-
_listenToChipsSelection() {
|
|
445
|
-
this._chipSelectionSubscription = this.chipSelectionChanges.subscribe((event) => {
|
|
446
|
-
event.source.selected
|
|
447
|
-
? this._selectionModel.select(event.source)
|
|
448
|
-
: this._selectionModel.deselect(event.source);
|
|
449
|
-
// For single selection chip list, make sure the deselected value is unselected.
|
|
450
|
-
if (!this.multiselect) {
|
|
451
|
-
this.chips.forEach((chip) => {
|
|
452
|
-
if (!this._selectionModel.isSelected(chip) && chip.selected) {
|
|
453
|
-
chip.deselect();
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
/** Listens to user-generated selection events on each chip. */
|
|
460
|
-
_listenToChipsFocus() {
|
|
461
|
-
this._chipFocusSubscription = this.chipFocusChanges.subscribe((event) => {
|
|
462
|
-
const chipIndex = this.chips.toArray().indexOf(event.chip);
|
|
463
|
-
if (this._isValidIndex(chipIndex)) {
|
|
464
|
-
this._keyManager.updateActiveItem(chipIndex);
|
|
465
|
-
}
|
|
466
|
-
this.stateChanges.next();
|
|
467
|
-
});
|
|
468
|
-
this._chipBlurSubscription = this.chipBlurChanges.subscribe(() => {
|
|
469
|
-
this._blur();
|
|
470
|
-
this.stateChanges.next();
|
|
471
|
-
});
|
|
472
|
-
}
|
|
473
|
-
_listenToChipsRemoved() {
|
|
474
|
-
this._chipRemoveSubscription = this.chipRemoveChanges.subscribe((event) => {
|
|
475
|
-
const chip = event.chip;
|
|
476
|
-
const chipIndex = this.chips.toArray().indexOf(event.chip);
|
|
477
|
-
// In case the chip that will be removed is currently focused, we temporarily store
|
|
478
|
-
// the index in order to be able to determine an appropriate sibling chip that will
|
|
479
|
-
// receive focus.
|
|
480
|
-
if (this._isValidIndex(chipIndex) && chip._hasFocus) {
|
|
481
|
-
this._lastDestroyedChipIndex = chipIndex;
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
/** Checks whether an event comes from inside a chip element. */
|
|
486
|
-
_originatesFromChip(event) {
|
|
487
|
-
let currentElement = event.target;
|
|
488
|
-
while (currentElement &&
|
|
489
|
-
currentElement !== this._elementRef.nativeElement) {
|
|
490
|
-
if (currentElement.classList.contains('granite-chip')) {
|
|
491
|
-
return true;
|
|
492
|
-
}
|
|
493
|
-
currentElement = currentElement.parentElement;
|
|
494
|
-
}
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
497
|
-
/** Checks whether any of the chips is focused. */
|
|
498
|
-
_hasFocusedChip() {
|
|
499
|
-
return this.chips && this.chips.some((chip) => chip._hasFocus);
|
|
500
|
-
}
|
|
501
|
-
/** Syncs the list's state with the individual chips. */
|
|
502
|
-
_syncChipsState() {
|
|
503
|
-
if (this.chips) {
|
|
504
|
-
this.chips.forEach((chip) => {
|
|
505
|
-
chip._chipListDisabled = this._disabled;
|
|
506
|
-
chip._chipListMultiple = this.multiselect;
|
|
507
|
-
});
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GraniteChipListComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.Directionality, optional: true }, { token: i2.NgForm, optional: true }, { token: i2.FormGroupDirective, optional: true }, { token: i2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
511
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: GraniteChipListComponent, selector: "granite-chip-list", inputs: { ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"], ariaOrientation: ["aria-orientation", "ariaOrientation"], role: "role", multiselect: "multiselect", disabled: "disabled", selectable: "selectable", tabindex: "tabindex" }, host: { listeners: { "focus": "focus()", "blur": "_blur()", "keydown": "_keydown($event)" }, properties: { "class.granite-chip-list-disabled": "disabled", "attr.tabindex": "disabled ? null : _tabIndex", "attr.role": "role", "attr.aria-label": "ariaLabel", "attr.aria-labelledby": "ariaLabelledby", "attr.aria-disabled": "disabled.toString()", "attr.aria-multiselectable": "multiselect", "attr.aria-orientation": "ariaOrientation", "id": "_uid" }, classAttribute: "granite-chip-list" }, queries: [{ propertyName: "chips", predicate: GraniteChipComponent, descendants: true }], exportAs: ["graniteChipList"], usesInheritance: true, ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host.granite-chip-list{display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;place-content:center flex-start;align-items:center;font-weight:400;font-size:var(--granite-font-size-body-small);line-height:var(--granite-line-height-regular);overflow:auto;padding:0;margin:0}:host ::ng-deep input.granite-chip-input{outline:none;border:none;background-color:transparent;color:var(--granite-color-text);margin:var(--granite-spacing-4)}:host ::ng-deep granite-icon{color:var(--granite-color-text);background-color:transparent}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
512
|
-
}
|
|
513
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GraniteChipListComponent, decorators: [{
|
|
514
|
-
type: Component,
|
|
515
|
-
args: [{ selector: 'granite-chip-list', template: `<ng-content></ng-content>`, exportAs: 'graniteChipList', host: {
|
|
516
|
-
class: 'granite-chip-list',
|
|
517
|
-
'[class.granite-chip-list-disabled]': 'disabled',
|
|
518
|
-
'[attr.tabindex]': 'disabled ? null : _tabIndex',
|
|
519
|
-
'[attr.role]': 'role',
|
|
520
|
-
'[attr.aria-label]': 'ariaLabel',
|
|
521
|
-
'[attr.aria-labelledby]': 'ariaLabelledby',
|
|
522
|
-
'[attr.aria-disabled]': 'disabled.toString()',
|
|
523
|
-
'[attr.aria-multiselectable]': 'multiselect',
|
|
524
|
-
'[attr.aria-orientation]': 'ariaOrientation',
|
|
525
|
-
'[id]': '_uid',
|
|
526
|
-
'(focus)': 'focus()',
|
|
527
|
-
'(blur)': '_blur()',
|
|
528
|
-
'(keydown)': '_keydown($event)',
|
|
529
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host.granite-chip-list{display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;place-content:center flex-start;align-items:center;font-weight:400;font-size:var(--granite-font-size-body-small);line-height:var(--granite-line-height-regular);overflow:auto;padding:0;margin:0}:host ::ng-deep input.granite-chip-input{outline:none;border:none;background-color:transparent;color:var(--granite-color-text);margin:var(--granite-spacing-4)}:host ::ng-deep granite-icon{color:var(--granite-color-text);background-color:transparent}\n"] }]
|
|
530
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.Directionality, decorators: [{
|
|
531
|
-
type: Optional
|
|
532
|
-
}] }, { type: i2.NgForm, decorators: [{
|
|
533
|
-
type: Optional
|
|
534
|
-
}] }, { type: i2.FormGroupDirective, decorators: [{
|
|
535
|
-
type: Optional
|
|
536
|
-
}] }, { type: i2.NgControl, decorators: [{
|
|
537
|
-
type: Optional
|
|
538
|
-
}, {
|
|
539
|
-
type: Self
|
|
540
|
-
}] }], propDecorators: { ariaLabel: [{
|
|
541
|
-
type: Input,
|
|
542
|
-
args: ['aria-label']
|
|
543
|
-
}], ariaLabelledby: [{
|
|
544
|
-
type: Input,
|
|
545
|
-
args: ['aria-labelledby']
|
|
546
|
-
}], ariaOrientation: [{
|
|
547
|
-
type: Input,
|
|
548
|
-
args: ['aria-orientation']
|
|
549
|
-
}], chips: [{
|
|
550
|
-
type: ContentChildren,
|
|
551
|
-
args: [GraniteChipComponent, {
|
|
552
|
-
// We need to use `descendants: true`, because Ivy will no longer match
|
|
553
|
-
// indirect descendants if it's left as false.
|
|
554
|
-
descendants: true,
|
|
555
|
-
}]
|
|
556
|
-
}], role: [{
|
|
557
|
-
type: Input
|
|
558
|
-
}], multiselect: [{
|
|
559
|
-
type: Input
|
|
560
|
-
}], disabled: [{
|
|
561
|
-
type: Input
|
|
562
|
-
}], selectable: [{
|
|
563
|
-
type: Input
|
|
564
|
-
}], tabindex: [{
|
|
565
|
-
type: Input
|
|
566
|
-
}] } });
|
|
567
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hpcC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZ3Jhbml0ZS1jb21wb25lbnRzL3NyYy9saWIvY2hpcHMvY2hpcC1saXN0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxFQUVmLFVBQVUsRUFDVixLQUFLLEVBR0wsUUFBUSxFQUNSLFNBQVMsRUFDVCxJQUFJLEVBQ0osWUFBWSxHQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxrQkFBa0IsRUFDbEIsU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxLQUFLLEVBQWMsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUNoRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFDTCxvQkFBb0IsR0FHckIsTUFBTSxrQkFBa0IsQ0FBQzs7OztBQUcxQixNQUFlLG1CQUFtQjtJQUdoQyxZQUNTLFdBQW1CLEVBQ25CLGdCQUFvQyxFQUNwQyxTQUFvQjtRQUZwQixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtRQUNuQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQW9CO1FBQ3BDLGNBQVMsR0FBVCxTQUFTLENBQVc7UUFMcEIsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0lBTTlDLENBQUM7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QixFQUFFLDZCQUE2Qjt3QkFDaEQsYUFBYSxFQUFFLE1BQU07d0JBQ3JCLG1CQUFtQixFQUFFLFdBQVc7d0JBQ2hDLHdCQUF3QixFQUFFLGdCQUFnQjt3QkFDMUMsc0JBQXNCLEVBQUUscUJBQXFCO3dCQUM3Qyw2QkFBNkIsRUFBRSxhQUFhO3dCQUM1Qyx5QkFBeUIsRUFBRSxpQkFBaUI7d0JBQzVDLE1BQU0sRUFBRSxNQUFNO3dCQUNkLFNBQVMsRUFBRSxTQUFTO3dCQUNwQixRQUFRLEVBQUUsU0FBUzt3QkFDbkIsV0FBVyxFQUFFLGtCQUFrQjtxQkFDaEMsbUJBRWdCLHVCQUF1QixDQUFDLE1BQU07OzBCQXFMNUMsUUFBUTs7MEJBQ1IsUUFBUTs7MEJBQ1IsUUFBUTs7MEJBQ1IsUUFBUTs7MEJBQUksSUFBSTt5Q0FqTG5CLFNBQVM7c0JBRFIsS0FBSzt1QkFBQyxZQUFZO2dCQUluQixjQUFjO3NCQURiLEtBQUs7dUJBQUMsaUJBQWlCO2dCQUl4QixlQUFlO3NCQURkLEtBQUs7dUJBQUMsa0JBQWtCO2dCQVN6QixLQUFLO3NCQUxKLGVBQWU7dUJBQUMsb0JBQW9CLEVBQUU7d0JBQ3JDLHVFQUF1RTt3QkFDdkUsOENBQThDO3dCQUM5QyxXQUFXLEVBQUUsSUFBSTtxQkFDbEI7Z0JBb0RHLElBQUk7c0JBRFAsS0FBSztnQkFlRixXQUFXO3NCQURkLEtBQUs7Z0JBY0YsUUFBUTtzQkFEWCxLQUFLO2dCQWNGLFVBQVU7c0JBRGIsS0FBSztnQkFlRixRQUFRO3NCQURYLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb2N1c0tleU1hbmFnZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5pbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBEb0NoZWNrLFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBRdWVyeUxpc3QsXG4gIFNlbGYsXG4gIEV2ZW50RW1pdHRlcixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBDb250cm9sVmFsdWVBY2Nlc3NvcixcbiAgRm9ybUdyb3VwRGlyZWN0aXZlLFxuICBOZ0NvbnRyb2wsXG4gIE5nRm9ybSxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgbWVyZ2UsIE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3RhcnRXaXRoLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBHcmFuaXRlQ2hpcENvbXBvbmVudCxcbiAgR3Jhbml0ZUNoaXBFdmVudCxcbiAgR3Jhbml0ZUNoaXBTZWxlY3Rpb25DaGFuZ2VFdmVudCxcbn0gZnJvbSAnLi9jaGlwLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHcmFuaXRlQ2hpcFRleHRDb250cm9sIH0gZnJvbSAnLi9jaGlwLWlucHV0JztcblxuYWJzdHJhY3QgY2xhc3MgR3Jhbml0ZUNoaXBMaXN0QmFzZSB7XG4gIHJlYWRvbmx5IHN0YXRlQ2hhbmdlcyA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgX3BhcmVudEZvcm06IE5nRm9ybSxcbiAgICBwdWJsaWMgX3BhcmVudEZvcm1Hcm91cDogRm9ybUdyb3VwRGlyZWN0aXZlLFxuICAgIHB1YmxpYyBuZ0NvbnRyb2w6IE5nQ29udHJvbFxuICApIHt9XG59XG5cbi8vIEluY3JlYXNpbmcgaW50ZWdlciBmb3IgZ2VuZXJhdGluZyB1bmlxdWUgaWRzIGZvciBjaGlwLWxpc3QgY29tcG9uZW50cy5cbmxldCBuZXh0VW5pcXVlSWQgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdncmFuaXRlLWNoaXAtbGlzdCcsXG4gIHRlbXBsYXRlOiBgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PmAsXG4gIGV4cG9ydEFzOiAnZ3Jhbml0ZUNoaXBMaXN0JyxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnZ3Jhbml0ZS1jaGlwLWxpc3QnLFxuICAgICdbY2xhc3MuZ3Jhbml0ZS1jaGlwLWxpc3QtZGlzYWJsZWRdJzogJ2Rpc2FibGVkJyxcbiAgICAnW2F0dHIudGFiaW5kZXhdJzogJ2Rpc2FibGVkID8gbnVsbCA6IF90YWJJbmRleCcsXG4gICAgJ1thdHRyLnJvbGVdJzogJ3JvbGUnLFxuICAgICdbYXR0ci5hcmlhLWxhYmVsXSc6ICdhcmlhTGFiZWwnLFxuICAgICdbYXR0ci5hcmlhLWxhYmVsbGVkYnldJzogJ2FyaWFMYWJlbGxlZGJ5JyxcbiAgICAnW2F0dHIuYXJpYS1kaXNhYmxlZF0nOiAnZGlzYWJsZWQudG9TdHJpbmcoKScsXG4gICAgJ1thdHRyLmFyaWEtbXVsdGlzZWxlY3RhYmxlXSc6ICdtdWx0aXNlbGVjdCcsXG4gICAgJ1thdHRyLmFyaWEtb3JpZW50YXRpb25dJzogJ2FyaWFPcmllbnRhdGlvbicsXG4gICAgJ1tpZF0nOiAnX3VpZCcsXG4gICAgJyhmb2N1cyknOiAnZm9jdXMoKScsXG4gICAgJyhibHVyKSc6ICdfYmx1cigpJyxcbiAgICAnKGtleWRvd24pJzogJ19rZXlkb3duKCRldmVudCknLFxuICB9LFxuICBzdHlsZVVybHM6IFsnLi9jaGlwLWxpc3QuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIEdyYW5pdGVDaGlwTGlzdENvbXBvbmVudFxuICBleHRlbmRzIEdyYW5pdGVDaGlwTGlzdEJhc2VcbiAgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgQWZ0ZXJDb250ZW50SW5pdCwgRG9DaGVjaywgT25Jbml0LCBPbkRlc3Ryb3lcbntcbiAgQElucHV0KCdhcmlhLWxhYmVsJylcbiAgYXJpYUxhYmVsOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBASW5wdXQoJ2FyaWEtbGFiZWxsZWRieScpXG4gIGFyaWFMYWJlbGxlZGJ5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBASW5wdXQoJ2FyaWEtb3JpZW50YXRpb24nKVxuICBhcmlhT3JpZW50YXRpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCcgPSAnaG9yaXpvbnRhbCc7XG5cbiAgLyoqIFRoZSBjaGlwcyBjb250YWluZWQgd2l0aGluIHRoaXMgY2hpcCBsaXN0LiAqL1xuICBAQ29udGVudENoaWxkcmVuKEdyYW5pdGVDaGlwQ29tcG9uZW50LCB7XG4gICAgLy8gV2UgbmVlZCB0byB1c2UgYGRlc2NlbmRhbnRzOiB0cnVlYCwgYmVjYXVzZSBJdnkgd2lsbCBubyBsb25nZXIgbWF0Y2hcbiAgICAvLyBpbmRpcmVjdCBkZXNjZW5kYW50cyBpZiBpdCdzIGxlZnQgYXMgZmFsc2UuXG4gICAgZGVzY2VuZGFudHM6IHRydWUsXG4gIH0pXG4gIGNoaXBzOiBRdWVyeUxpc3Q8R3Jhbml0ZUNoaXBDb21wb25lbnQ+O1xuXG4gIHJlYWRvbmx5IGNvbnRyb2xUeXBlOiBzdHJpbmcgPSAnZ3Jhbml0ZS1jaGlwLWxpc3QnO1xuXG4gIC8qKiBVaWQgb2YgdGhlIGNoaXAgbGlzdCAqL1xuICBfdWlkOiBzdHJpbmcgPSBgZ3Jhbml0ZS1jaGlwLWxpc3QtJHtuZXh0VW5pcXVlSWQrK31gO1xuXG4gIC8qKiBUYWIgaW5kZXggZm9yIHRoZSBjaGlwIGxpc3QuICovXG4gIF90YWJJbmRleCA9IDA7XG5cbiAgLyoqXG4gICAqIFVzZXIgZGVmaW5lZCB0YWIgaW5kZXguXG4gICAqIFdoZW4gaXQgaXMgbm90IG51bGwsIHVzZSB1c2VyIGRlZmluZWQgdGFiIGluZGV4LiBPdGhlcndpc2UgdXNlIF90YWJJbmRleFxuICAgKi9cbiAgX3VzZXJUYWJJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFRoZSBGb2N1c0tleU1hbmFnZXIgd2hpY2ggaGFuZGxlcyBmb2N1cy4gKi9cbiAgX2tleU1hbmFnZXI6IEZvY3VzS2V5TWFuYWdlcjxHcmFuaXRlQ2hpcENvbXBvbmVudD47XG5cbiAgX3NlbGVjdGlvbk1vZGVsOiBTZWxlY3Rpb25Nb2RlbDxHcmFuaXRlQ2hpcENvbXBvbmVudD47XG5cbiAgLyoqIFRoZSBjaGlwIGlucHV0IHRvIGFkZCBtb3JlIGNoaXBzICovXG4gIHByb3RlY3RlZCBfY2hpcElucHV0OiBHcmFuaXRlQ2hpcFRleHRDb250cm9sO1xuXG4gIHByb3RlY3RlZCBfZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIF9zZWxlY3RhYmxlOiBib29sZWFuID0gdHJ1ZTtcblxuICAvKipcbiAgICogV2hlbiBhIGNoaXAgaXMgZGVzdHJveWVkLCB3ZSBzdG9yZSB0aGUgaW5kZXggb2YgdGhlIGRlc3Ryb3llZCBjaGlwIHVudGlsIHRoZSBjaGlwc1xuICAgKiBxdWVyeSBsaXN0IG5vdGlmaWVzIGFib3V0IHRoZSB1cGRhdGUuIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugd2UgY2Fubm90IGRldGVybWluZSBhblxuICAgKiBhcHByb3ByaWF0ZSBjaGlwIHRoYXQgc2hvdWxkIHJlY2VpdmUgZm9jdXMgdW50aWwgdGhlIGFycmF5IG9mIGNoaXBzIHVwZGF0ZWQgY29tcGxldGVseS5cbiAgICovXG4gIHByaXZhdGUgX2xhc3REZXN0cm95ZWRDaGlwSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBTdWJqZWN0IHRoYXQgZW1pdHMgd2hlbiB0aGUgY29tcG9uZW50IGhhcyBiZWVuIGRlc3Ryb3llZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfZGVzdHJveWVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKiogU3Vic2NyaXB0aW9uIHRvIGZvY3VzIGNoYW5nZXMgaW4gdGhlIGNoaXBzLiAqL1xuICBwcml2YXRlIF9jaGlwRm9jdXNTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGw7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byBibHVyIGNoYW5nZXMgaW4gdGhlIGNoaXBzLiAqL1xuICBwcml2YXRlIF9jaGlwQmx1clN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbDtcblxuICAvKiogU3Vic2NyaXB0aW9uIHRvIHNlbGVjdGlvbiBjaGFuZ2VzIGluIGNoaXBzLiAqL1xuICBwcml2YXRlIF9jaGlwU2VsZWN0aW9uU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsO1xuXG4gIC8qKiBTdWJzY3JpcHRpb24gdG8gcmVtb3ZlIGNoYW5nZXMgaW4gY2hpcHMuICovXG4gIHByaXZhdGUgX2NoaXBSZW1vdmVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGw7XG5cbiAgLyoqIFRoZSBBUklBIHJvbGUgYXBwbGllZCB0byB0aGUgY2hpcCBsaXN0LiAqL1xuICBASW5wdXQoKVxuICBnZXQgcm9sZSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAodGhpcy5fZXhwbGljaXRSb2xlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZXhwbGljaXRSb2xlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmVtcHR5ID8gbnVsbCA6ICdsaXN0Ym94JztcbiAgfVxuICBzZXQgcm9sZShyb2xlOiBzdHJpbmcgfCBudWxsKSB7XG4gICAgdGhpcy5fZXhwbGljaXRSb2xlID0gcm9sZTtcbiAgfVxuICBwcml2YXRlIF9leHBsaWNpdFJvbGU/OiBzdHJpbmcgfCBudWxsO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSB1c2VyIHNob3VsZCBiZSBhbGxvd2VkIHRvIHNlbGVjdCBtdWx0aXNlbGVjdCBjaGlwcy4gKi9cbiAgQElucHV0KClcbiAgZ2V0IG11bHRpc2VsZWN0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9tdWx0aXBsZTtcbiAgfVxuICBzZXQgbXVsdGlzZWxlY3QodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9tdWx0aXBsZSA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gICAgdGhpcy5fc3luY0NoaXBzU3RhdGUoKTtcbiAgfVxuICBwcml2YXRlIF9tdWx0aXBsZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBjaGlwIGxpc3QgaXMgZGlzYWJsZWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmdDb250cm9sID8gISF0aGlzLm5nQ29udHJvbC5kaXNhYmxlZCA6IHRoaXMuX2Rpc2FibGVkO1xuICB9XG4gIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgICB0aGlzLl9zeW5jQ2hpcHNTdGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgb3Igbm90IHRoaXMgY2hpcCBsaXN0IGlzIHNlbGVjdGFibGUuIFdoZW4gYSBjaGlwIGxpc3QgaXMgbm90IHNlbGVjdGFibGUsXG4gICAqIHRoZSBzZWxlY3RlZCBzdGF0ZXMgZm9yIGFsbCB0aGUgY2hpcHMgaW5zaWRlIHRoZSBjaGlwIGxpc3QgYXJlIGFsd2F5cyBpZ25vcmVkLlxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IHNlbGVjdGFibGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGFibGU7XG4gIH1cbiAgc2V0IHNlbGVjdGFibGUodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9zZWxlY3RhYmxlID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcblxuICAgIGlmICh0aGlzLmNoaXBzKSB7XG4gICAgICB0aGlzLmNoaXBzLmZvckVhY2goXG4gICAgICAgIChjaGlwKSA9PiAoY2hpcC5fY2hpcExpc3RTZWxlY3RhYmxlID0gdGhpcy5fc2VsZWN0YWJsZSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHRhYmluZGV4KHZhbHVlOiBudW1iZXIpIHtcbiAgICB0aGlzLl91c2VyVGFiSW5kZXggPSB2YWx1ZTtcbiAgICB0aGlzLl90YWJJbmRleCA9IHZhbHVlO1xuICB9XG5cbiAgLyoqIFVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgY2hpcCBsaXN0LiAqL1xuICBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY2hpcElucHV0ID8gdGhpcy5fY2hpcElucHV0LmlkIDogdGhpcy5fdWlkO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgYW55IGNoaXBzIG9yIHRoZSBtYXRDaGlwSW5wdXQgaW5zaWRlIG9mIHRoaXMgY2hpcC1saXN0IGhhcyBmb2N1cy4gKi9cbiAgZ2V0IGZvY3VzZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgICh0aGlzLl9jaGlwSW5wdXQgJiYgdGhpcy5fY2hpcElucHV0LmZvY3VzZWQpIHx8IHRoaXMuX2hhc0ZvY3VzZWRDaGlwKClcbiAgICApO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGNoaXAgbGlzdCBpcyBlbXB0eS4gKi9cbiAgZ2V0IGVtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAoIXRoaXMuX2NoaXBJbnB1dCB8fCB0aGlzLl9jaGlwSW5wdXQuZW1wdHkpICYmXG4gICAgICAoIXRoaXMuY2hpcHMgfHwgdGhpcy5jaGlwcy5sZW5ndGggPT09IDApXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBUaGUgYXJyYXkgb2Ygc2VsZWN0ZWQgY2hpcHMgaW5zaWRlIGNoaXAgbGlzdC4gKi9cbiAgZ2V0IHNlbGVjdGVkKCk6IEdyYW5pdGVDaGlwQ29tcG9uZW50W10gfCBHcmFuaXRlQ2hpcENvbXBvbmVudCB7XG4gICAgcmV0dXJuIHRoaXMubXVsdGlzZWxlY3RcbiAgICAgID8gdGhpcy5fc2VsZWN0aW9uTW9kZWw/LnNlbGVjdGVkIHx8IFtdXG4gICAgICA6IHRoaXMuX3NlbGVjdGlvbk1vZGVsPy5zZWxlY3RlZFswXTtcbiAgfVxuXG4gIC8qKiBDb21iaW5lZCBzdHJlYW0gb2YgYWxsIG9mIHRoZSBjaGlsZCBjaGlwcycgc2VsZWN0aW9uIGNoYW5nZSBldmVudHMuICovXG4gIGdldCBjaGlwU2VsZWN0aW9uQ2hhbmdlcygpOiBPYnNlcnZhYmxlPEdyYW5pdGVDaGlwU2VsZWN0aW9uQ2hhbmdlRXZlbnQ+IHtcbiAgICByZXR1cm4gbWVyZ2UoLi4udGhpcy5jaGlwcy5tYXAoKGNoaXApID0+IGNoaXAuc2VsZWN0aW9uQ2hhbmdlKSk7XG4gIH1cblxuICAvKiogQ29tYmluZWQgc3RyZWFtIG9mIGFsbCBvZiB0aGUgY2hpbGQgY2hpcHMnIGZvY3VzIGNoYW5nZSBldmVudHMuICovXG4gIGdldCBjaGlwRm9jdXNDaGFuZ2VzKCk6IE9ic2VydmFibGU8R3Jhbml0ZUNoaXBFdmVudD4ge1xuICAgIHJldHVybiBtZXJnZSguLi50aGlzLmNoaXBzLm1hcCgoY2hpcCkgPT4gY2hpcC5jaGlwRm9jdXMpKTtcbiAgfVxuXG4gIC8qKiBDb21iaW5lZCBzdHJlYW0gb2YgYWxsIG9mIHRoZSBjaGlsZCBjaGlwcycgYmx1ciBjaGFuZ2UgZXZlbnRzLiAqL1xuICBnZXQgY2hpcEJsdXJDaGFuZ2VzKCk6IE9ic2VydmFibGU8R3Jhbml0ZUNoaXBFdmVudD4ge1xuICAgIHJldHVybiBtZXJnZSguLi50aGlzLmNoaXBzLm1hcCgoY2hpcCkgPT4gY2hpcC5jaGlwQmx1cikpO1xuICB9XG5cbiAgLyoqIENvbWJpbmVkIHN0cmVhbSBvZiBhbGwgb2YgdGhlIGNoaWxkIGNoaXBzJyByZW1vdmUgY2hhbmdlIGV2ZW50cy4gKi9cbiAgZ2V0IGNoaXBSZW1vdmVDaGFuZ2VzKCk6IE9ic2VydmFibGU8R3Jhbml0ZUNoaXBFdmVudD4ge1xuICAgIHJldHVybiBtZXJnZSguLi50aGlzLmNoaXBzLm1hcCgoY2hpcCkgPT4gY2hpcC5kZXN0cm95ZWQpKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBfZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgcHJpdmF0ZSBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgX2RpcjogRGlyZWN0aW9uYWxpdHksXG4gICAgQE9wdGlvbmFsKCkgX3BhcmVudEZvcm06IE5nRm9ybSxcbiAgICBAT3B0aW9uYWwoKSBfcGFyZW50Rm9ybUdyb3VwOiBGb3JtR3JvdXBEaXJlY3RpdmUsXG4gICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBuZ0NvbnRyb2w6IE5nQ29udHJvbFxuICApIHtcbiAgICBzdXBlcihfcGFyZW50Rm9ybSwgX3BhcmVudEZvcm1Hcm91cCwgbmdDb250cm9sKTtcbiAgICBpZiAodGhpcy5uZ0NvbnRyb2wpIHtcbiAgICAgIHRoaXMubmdDb250cm9sLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBGdW5jdGlvbiB3aGVuIGNoYW5nZWQgKi9cbiAgX29uQ2hhbmdlOiAodmFsdWU6IGFueSkgPT4gdm9pZCA9ICgpID0+IHtcbiAgICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yXG4gIH07XG5cbiAgLyoqIEZ1bmN0aW9uIHdoZW4gY2hhbmdlZCAqL1xuICBfb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4ge1xuICAgIC8vIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3JcbiAgfTtcblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fa2V5TWFuYWdlciA9IG5ldyBGb2N1c0tleU1hbmFnZXI8R3Jhbml0ZUNoaXBDb21wb25lbnQ+KHRoaXMuY2hpcHMpXG4gICAgICAud2l0aFdyYXAoKVxuICAgICAgLndpdGhWZXJ0aWNhbE9yaWVudGF0aW9uKClcbiAgICAgIC53aXRoSG9tZUFuZEVuZCgpXG4gICAgICAud2l0aEhvcml6b250YWxPcmllbnRhdGlvbih0aGlzLl9kaXIgPyB0aGlzLl9kaXIudmFsdWUgOiAnbHRyJyk7XG5cbiAgICBpZiAodGhpcy5fZGlyKSB7XG4gICAgICB0aGlzLl9kaXIuY2hhbmdlXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxuICAgICAgICAuc3Vic2NyaWJlKChkaXIpID0+IHRoaXMuX2tleU1hbmFnZXIud2l0aEhvcml6b250YWxPcmllbnRhdGlvbihkaXIpKTtcbiAgICB9XG5cbiAgICB0aGlzLl9rZXlNYW5hZ2VyLnRhYk91dC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5fYWxsb3dGb2N1c0VzY2FwZSgpO1xuICAgIH0pO1xuXG4gICAgLy8gV2hlbiB0aGUgbGlzdCBjaGFuZ2VzLCByZS1zdWJzY3JpYmVcbiAgICB0aGlzLmNoaXBzLmNoYW5nZXNcbiAgICAgIC5waXBlKHN0YXJ0V2l0aChudWxsKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAvLyBTaW5jZSB0aGlzIGhhcHBlbnMgYWZ0ZXIgdGhlIGNvbnRlbnQgaGFzIGJlZW5cbiAgICAgICAgICAvLyBjaGVja2VkLCB3ZSBuZWVkIHRvIGRlZmVyIGl0IHRvIHRoZSBuZXh0IHRpY2suXG4gICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jQ2hpcHNTdGF0ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcmVzZXRDaGlwcygpO1xuXG4gICAgICAgIC8vIFJlc2V0IGNoaXBzIHNlbGVjdGVkL2Rlc2VsZWN0ZWQgc3RhdHVzXG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVTZWxlY3Rpb24oKTtcblxuICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgd2UgbmVlZCB0byB1cGRhdGUgb3VyIHRhYiBpbmRleFxuICAgICAgICB0aGlzLl91cGRhdGVUYWJJbmRleCgpO1xuXG4gICAgICAgIC8vIENoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGEgZGVzdHJveWVkIGNoaXAgYW5kIG5lZWQgdG8gcmVmb2N1c1xuICAgICAgICB0aGlzLl91cGRhdGVGb2N1c0ZvckRlc3Ryb3llZENoaXBzKCk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9zZWxlY3Rpb25Nb2RlbCA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxHcmFuaXRlQ2hpcENvbXBvbmVudD4oXG4gICAgICB0aGlzLm11bHRpc2VsZWN0LFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgZmFsc2VcbiAgICApO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgfVxuXG4gIG5nRG9DaGVjaygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5uZ0NvbnRyb2wpIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgdGhpcyBvbiBldmVyeSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlLCBiZWNhdXNlIHRoZXJlIGFyZSBzb21lXG4gICAgICAvLyBlcnJvciB0cmlnZ2VycyB0aGF0IHdlIGNhbid0IHN1YnNjcmliZSB0byAoZS5nLiBwYXJlbnQgZm9ybSBzdWJtaXNzaW9ucykuIFRoaXMgbWVhbnNcbiAgICAgIC8vIHRoYXQgd2hhdGV2ZXIgbG9naWMgaXMgaW4gaGVyZSBoYXMgdG8gYmUgc3VwZXIgbGVhbiBvciB3ZSByaXNrIGRlc3Ryb3lpbmcgdGhlIHBlcmZvcm1hbmNlLlxuXG4gICAgICBpZiAodGhpcy5uZ0NvbnRyb2wuZGlzYWJsZWQgIT09IHRoaXMuX2Rpc2FibGVkKSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSAhIXRoaXMubmdDb250cm9sLmRpc2FibGVkO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX2Rlc3Ryb3llZC5uZXh0KCk7XG4gICAgdGhpcy5fZGVzdHJveWVkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZXMuY29tcGxldGUoKTtcblxuICAgIHRoaXMuX2Ryb3BTdWJzY3JpcHRpb25zKCk7XG4gIH1cblxuICAvKiogQXNzb2NpYXRlcyBhbiBIVE1MIGlucHV0IGVsZW1lbnQgd2l0aCB0aGlzIGNoaXAgbGlzdC4gKi9cbiAgcmVnaXN0ZXJJbnB1dChpbnB1dEVsZW1lbnQ6IEdyYW5pdGVDaGlwVGV4dENvbnRyb2wpOiB2b2lkIHtcbiAgICB0aGlzLl9jaGlwSW5wdXQgPSBpbnB1dEVsZW1lbnQ7XG5cbiAgICAvLyBXZSB1c2UgdGhpcyBhdHRyaWJ1dGUgdG8gbWF0Y2ggdGhlIGNoaXAgbGlzdCB0byBpdHMgaW5wdXQgaW4gdGVzdCBoYXJuZXNzZXMuXG4gICAgLy8gU2V0IHRoZSBhdHRyaWJ1dGUgZGlyZWN0bHkgaGVyZSB0byBhdm9pZCBcImNoYW5nZWQgYWZ0ZXIgY2hlY2tlZFwiIGVycm9ycy5cbiAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc2V0QXR0cmlidXRlKFxuICAgICAgJ2RhdGEtZ3Jhbml0ZS1jaGlwLWlucHV0JyxcbiAgICAgIGlucHV0RWxlbWVudC5pZFxuICAgICk7XG4gIH1cblxuICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2V4cGxpY2l0LW1vZHVsZS1ib3VuZGFyeS10eXBlc1xuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jaGlwcykge1xuICAgICAgdGhpcy5fc2V0U2VsZWN0aW9uQnlWYWx1ZSh2YWx1ZSwgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogYW55KSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5fb25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIC8vIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5fb25Ub3VjaGVkID0gZm47XG4gIH1cblxuICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogRm9jdXMgY2hpcCBsaXN0IHdoZW4gY2xpY2sgb24gdGhlIGNvbnRhaW5lci5cbiAgICovXG4gIG9uQ29udGFpbmVyQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuX29yaWdpbmF0ZXNGcm9tQ2hpcChldmVudCkpIHtcbiAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRm9jdXNlcyB0aGUgZmlyc3Qgbm9uLWRpc2FibGVkIGNoaXAgaW4gdGhpcyBjaGlwIGxpc3QsIG9yIHRoZSBhc3NvY2lhdGVkIGlucHV0IHdoZW4gdGhlcmVcbiAgICogYXJlIG5vIGVsaWdpYmxlIGNoaXBzLlxuICAgKi9cbiAgZm9jdXMob3B0aW9ucz86IEZvY3VzT3B0aW9ucyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRm9jdXMgb24gZmlyc3QgZWxlbWVudCBpZiB0aGVyZSdzIG5vIGNoaXBJbnB1dCBpbnNpZGUgY2hpcC1saXN0XG4gICAgaWYgKHRoaXMuX2NoaXBJbnB1dCAmJiB0aGlzLl9jaGlwSW5wdXQuZm9jdXNlZCkge1xuICAgICAgLy8gZG8gbm90aGluZ1xuICAgIH0gZWxzZSBpZiAodGhpcy5jaGlwcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl9rZXlNYW5hZ2VyLnNldEZpcnN0SXRlbUFjdGl2ZSgpO1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9mb2N1c0lucHV0KG9wdGlvbnMpO1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBBdHRlbXB0IHRvIGZvY3VzIGFuIGlucHV0IGlmIHdlIGhhdmUgb25lLiAqL1xuICBfZm9jdXNJbnB1dChvcHRpb25zPzogRm9jdXNPcHRpb25zKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2NoaXBJbnB1dCkge1xuICAgICAgdGhpcy5fY2hpcElucHV0LnNldEZvY3VzKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQYXNzIGV2ZW50cyB0byB0aGUga2V5Ym9hcmQgbWFuYWdlci4gQXZhaWxhYmxlIGhlcmUgZm9yIHRlc3RzLlxuICAgKi9cbiAgX2tleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBpZiAodGFyZ2V0ICYmIHRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyYW5pdGUtY2hpcCcpKSB7XG4gICAgICB0aGlzLl9rZXlNYW5hZ2VyLm9uS2V5ZG93bihldmVudCk7XG4gICAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFdoZW4gYmx1cnJlZCwgbWFyayB0aGUgZmllbGQgYXMgdG91Y2hlZCB3aGVuIGZvY3VzIG1vdmVkIG91dHNpZGUgdGhlIGNoaXAgbGlzdC4gKi9cbiAgX2JsdXIoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl9oYXNGb2N1c2VkQ2hpcCgpKSB7XG4gICAgICB0aGlzLl9rZXlNYW5hZ2VyLnNldEFjdGl2ZUl0ZW0oLTEpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5kaXNhYmxlZCkge1xuICAgICAgaWYgKHRoaXMuX2NoaXBJbnB1dCkge1xuICAgICAgICAvLyBJZiB0aGVyZSdzIGEgY2hpcCBpbnB1dCwgd2Ugc2hvdWxkIGNoZWNrIHdoZXRoZXIgdGhlIGZvY3VzIG1vdmVkIHRvIGNoaXAgaW5wdXQuXG4gICAgICAgIC8vIElmIHRoZSBmb2N1cyBpcyBub3QgbW92ZWQgdG8gY2hpcCBpbnB1dCwgbWFyayB0aGUgZmllbGQgYXMgdG91Y2hlZC4gSWYgdGhlIGZvY3VzIG1vdmVkXG4gICAgICAgIC8vIHRvIGNoaXAgaW5wdXQsIGRvIG5vdGhpbmcuXG4gICAgICAgIC8vIFRpbWVvdXQgaXMgbmVlZGVkIHRvIHdhaXQgZm9yIHRoZSBmb2N1cygpIGV2ZW50IHRyaWdnZXIgb24gY2hpcCBpbnB1dC5cbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgaWYgKCF0aGlzLmZvY3VzZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX21hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSWYgdGhlcmUncyBubyBjaGlwIGlucHV0LCB0aGVuIG1hcmsgdGhlIGZpZWxkIGFzIHRvdWNoZWQuXG4gICAgICAgIHRoaXMuX21hcmtBc1RvdWNoZWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogTWFyayB0aGUgZmllbGQgYXMgdG91Y2hlZCAqL1xuICBfbWFya0FzVG91Y2hlZCgpOiB2b2lkIHtcbiAgICB0aGlzLl9vblRvdWNoZWQoKTtcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgYHRhYmluZGV4YCBmcm9tIHRoZSBjaGlwIGxpc3QgYW5kIHJlc2V0cyBpdCBiYWNrIGFmdGVyd2FyZHMsIGFsbG93aW5nIHRoZVxuICAgKiB1c2VyIHRvIHRhYiBvdXQgb2YgaXQuIFRoaXMgcHJldmVudHMgdGhlIGxpc3QgZnJvbSBjYXB0dXJpbmcgZm9jdXMgYW5kIHJlZGlyZWN0aW5nXG4gICAqIGl0IGJhY2sgdG8gdGhlIGZpcnN0IGNoaXAsIGNyZWF0aW5nIGEgZm9jdXMgdHJhcCwgaWYgaXQgdXNlciB0cmllcyB0byB0YWIgYXdheS5cbiAgICovXG4gIF9hbGxvd0ZvY3VzRXNjYXBlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl90YWJJbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX3RhYkluZGV4ID0gLTE7XG5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLl90YWJJbmRleCA9IHRoaXMuX3VzZXJUYWJJbmRleCB8fCAwO1xuICAgICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB0aGUgdGFiIGluZGV4IGFzIHlvdSBzaG91bGQgbm90IGJlIGFsbG93ZWQgdG8gZm9jdXMgYW4gZW1wdHkgbGlzdC5cbiAgICovXG4gIHByb3RlY3RlZCBfdXBkYXRlVGFiSW5kZXgoKTogdm9pZCB7XG4gICAgLy8gSWYgd2UgaGF2ZSAwIGNoaXBzLCB3ZSBzaG91bGQgbm90IGFsbG93IGtleWJvYXJkIGZvY3VzXG4gICAgdGhpcy5fdGFiSW5kZXggPSB0aGlzLl91c2VyVGFiSW5kZXggfHwgKHRoaXMuY2hpcHMubGVuZ3RoID09PSAwID8gLTEgOiAwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiB0aGUgYW1vdW50IG9mIGNoaXBzIGNoYW5nZWQsIHdlIG5lZWQgdG8gdXBkYXRlIHRoZVxuICAgKiBrZXkgbWFuYWdlciBzdGF0ZSBhbmQgZm9jdXMgdGhlIG5leHQgY2xvc2VzdCBjaGlwLlxuICAgKi9cbiAgcHJvdGVjdGVkIF91cGRhdGVGb2N1c0ZvckRlc3Ryb3llZENoaXBzKCk6IHZvaWQge1xuICAgIC8vIE1vdmUgZm9jdXMgdG8gdGhlIGNsb3Nlc3QgY2hpcC4gSWYgbm8gb3RoZXIgY2hpcHMgcmVtYWluLCBmb2N1cyB0aGUgY2hpcC1saXN0IGl0c2VsZi5cbiAgICBpZiAodGhpcy5fbGFzdERlc3Ryb3llZENoaXBJbmRleCAhPSBudWxsKSB7XG4gICAgICBpZiAodGhpcy5jaGlwcy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgbmV3Q2hpcEluZGV4ID0gTWF0aC5taW4oXG4gICAgICAgICAgdGhpcy5fbGFzdERlc3Ryb3llZENoaXBJbmRleCxcbiAgICAgICAgICB0aGlzLmNoaXBzLmxlbmd0aCAtIDFcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5fa2V5TWFuYWdlci5zZXRBY3RpdmVJdGVtKG5ld0NoaXBJbmRleCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmZvY3VzKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fbGFzdERlc3Ryb3llZENoaXBJbmRleCA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogVXRpbGl0eSB0byBlbnN1cmUgYWxsIGluZGV4ZXMgYXJlIHZhbGlkLlxuICAgKlxuICAgKiBAcGFyYW0gaW5kZXggVGhlIGluZGV4IHRvIGJlIGNoZWNrZWQuXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGluZGV4IGlzIHZhbGlkIGZvciBvdXIgbGlzdCBvZiBjaGlwcy5cbiAgICovXG4gIHByaXZhdGUgX2lzVmFsaWRJbmRleChpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGluZGV4ID49IDAgJiYgaW5kZXggPCB0aGlzLmNoaXBzLmxlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgX3NldFNlbGVjdGlvbkJ5VmFsdWUodmFsdWU6IGFueSwgaXNVc2VySW5wdXQ6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XG4gICAgdGhpcy5fY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB0aGlzLmNoaXBzLmZvckVhY2goKGNoaXApID0+IGNoaXAuZGVzZWxlY3QoKSk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHZhbHVlLmZvckVhY2goKGN1cnJlbnRWYWx1ZSkgPT5cbiAgICAgICAgdGhpcy5fc2VsZWN0VmFsdWUoY3VycmVudFZhbHVlLCBpc1VzZXJJbnB1dClcbiAgICAgICk7XG4gICAgICB0aGlzLl9zb3J0VmFsdWVzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNvcnJlc3BvbmRpbmdDaGlwID0gdGhpcy5fc2VsZWN0VmFsdWUodmFsdWUsIGlzVXNlcklucHV0KTtcblxuICAgICAgLy8gU2hpZnQgZm9jdXMgdG8gdGhlIGFjdGl2ZSBpdGVtLiBOb3RlIHRoYXQgd2Ugc2hvdWxkbid0IGRvIHRoaXMgaW4gbXVsdGlzZWxlY3RcbiAgICAgIC8vIG1vZGUsIGJlY2F1c2Ugd2UgZG9uJ3Qga25vdyB3aGF0IGNoaXAgdGhlIHVzZXIgaW50ZXJhY3RlZCB3aXRoIGxhc3QuXG4gICAgICBpZiAoY29ycmVzcG9uZGluZ0NoaXApIHtcbiAgICAgICAgaWYgKGlzVXNlcklucHV0KSB7XG4gICAgICAgICAgdGhpcy5fa2V5TWFuYWdlci5zZXRBY3RpdmVJdGVtKGNvcnJlc3BvbmRpbmdDaGlwKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBhbmQgc2VsZWN0cyB0aGUgY2hpcCBiYXNlZCBvbiBpdHMgdmFsdWUuXG4gICAqIEByZXR1cm5zIENoaXAgdGhhdCBoYXMgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUuXG4gICAqL1xuICBwcml2YXRlIF9zZWxlY3RWYWx1ZShcbiAgICB2YWx1ZTogYW55LFxuICAgIGlzVXNlcklucHV0OiBib29sZWFuID0gdHJ1ZVxuICApOiBHcmFuaXRlQ2hpcENvbXBvbmVudCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY29ycmVzcG9uZGluZ0NoaXAgPSB0aGlzLmNoaXBzLmZpbmQoKGNoaXApID0+IHtcbiAgICAgIHJldHVybiBjaGlwLnZhbHVlICE9IG51bGwgJiYgdGhpcy5fY29tcGFyZVdpdGgoY2hpcC52YWx1ZSwgdmFsdWUpO1xuICAgIH0pO1xuXG4gICAgaWYgKGNvcnJlc3BvbmRpbmdDaGlwKSB7XG4gICAgICBjb3JyZXNwb25kaW5nQ2hpcC5zZWxlY3QoaXNVc2VySW5wdXQpO1xuICAgICAgdGhpcy5fc2VsZWN0aW9uTW9kZWwuc2VsZWN0KGNvcnJlc3BvbmRpbmdDaGlwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29ycmVzcG9uZGluZ0NoaXA7XG4gIH1cblxuICBwcml2YXRlIF9pbml0aWFsaXplU2VsZWN0aW9uKCk6IHZvaWQge1xuICAgIC8vIERlZmVyIHNldHRpbmcgdGhlIHZhbHVlIGluIG9yZGVyIHRvIGF2b2lkIHRoZSBcIkV4cHJlc3Npb25cbiAgICAvLyBoYXMgY2hhbmdlZCBhZnRlciBpdCB3YXMgY2hlY2tlZFwiIGVycm9ycyBmcm9tIEFuZ3VsYXIuXG4gICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB7XG4gICAgICBpZiAodGhpcy5uZ0NvbnRyb2wpIHtcbiAgICAgICAgdGhpcy5fc2V0U2VsZWN0aW9uQnlWYWx1ZSh0aGlzLm5nQ29udHJvbC52YWx1ZSwgZmFsc2UpO1xuICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGVzZWxlY3RzIGV2ZXJ5IGNoaXAgaW4gdGhlIGxpc3QuXG4gICAqIEBwYXJhbSBza2lwIENoaXAgdGhhdCBzaG91bGQgbm90IGJlIGRlc2VsZWN0ZWQuXG4gICAqL1xuICBwcml2YXRlIF9jbGVhclNlbGVjdGlvbihza2lwPzogR3Jhbml0ZUNoaXBDb21wb25lbnQpOiB2b2lkIHtcbiAgICB0aGlzLl9zZWxlY3Rpb25Nb2RlbC5jbGVhcigpO1xuICAgIHRoaXMuY2hpcHMuZm9yRWFjaCgoY2hpcCkgPT4ge1xuICAgICAgaWYgKGNoaXAgIT09IHNraXApIHtcbiAgICAgICAgY2hpcC5kZXNlbGVjdCgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTb3J0cyB0aGUgbW9kZWwgdmFsdWVzLCBlbnN1cmluZyB0aGF0IHRoZXkga2VlcCB0aGUgc2FtZVxuICAgKiBvcmRlciB0aGF0IHRoZXkgaGF2ZSBpbiB0aGUgcGFuZWwuXG4gICAqL1xuICBwcml2YXRlIF9zb3J0VmFsdWVzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9tdWx0aXBsZSkge1xuICAgICAgdGhpcy5fc2VsZWN0aW9uTW9kZWwuY2xlYXIoKTtcblxuICAgICAgdGhpcy5jaGlwcy5mb3JFYWNoKChjaGlwKSA9PiB7XG4gICAgICAgIGlmIChjaGlwLnNlbGVjdGVkKSB7XG4gICAgICAgICAgdGhpcy5fc2VsZWN0aW9uTW9kZWwuc2VsZWN0KGNoaXApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9jb21wYXJlV2l0aCA9IChvMTogYW55LCBvMjogYW55KSA9PiBvMSA9PT0gbzI7XG5cbiAgcHJpdmF0ZSBfcmVzZXRDaGlwcygpOiB2b2lkIHtcbiAgICB0aGlzLl9kcm9wU3Vic2NyaXB0aW9ucygpO1xuICAgIHRoaXMuX2xpc3RlblRvQ2hpcHNGb2N1cygpO1xuICAgIHRoaXMuX2xpc3RlblRvQ2hpcHNTZWxlY3Rpb24oKTtcbiAgICB0aGlzLl9saXN0ZW5Ub0NoaXBzUmVtb3ZlZCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZHJvcFN1YnNjcmlwdGlvbnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2NoaXBGb2N1c1N1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5fY2hpcEZvY3VzU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLl9jaGlwRm9jdXNTdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jaGlwQmx1clN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5fY2hpcEJsdXJTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuX2NoaXBCbHVyU3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY2hpcFNlbGVjdGlvblN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5fY2hpcFNlbGVjdGlvblN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5fY2hpcFNlbGVjdGlvblN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NoaXBSZW1vdmVTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX2NoaXBSZW1vdmVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuX2NoaXBSZW1vdmVTdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBMaXN0ZW5zIHRvIHVzZXItZ2VuZXJhdGVkIHNlbGVjdGlvbiBldmVudHMgb24gZWFjaCBjaGlwLiAqL1xuICBwcml2YXRlIF9saXN0ZW5Ub0NoaXBzU2VsZWN0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuX2NoaXBTZWxlY3Rpb25TdWJzY3JpcHRpb24gPSB0aGlzLmNoaXBTZWxlY3Rpb25DaGFuZ2VzLnN1YnNjcmliZShcbiAgICAgIChldmVudCkgPT4ge1xuICAgICAgICBldmVudC5zb3VyY2Uuc2VsZWN0ZWRcbiAgICAgICAgICA/IHRoaXMuX3NlbGVjdGlvbk1vZGVsLnNlbGVjdChldmVudC5zb3VyY2UpXG4gICAgICAgICAgOiB0aGlzLl9zZWxlY3Rpb25Nb2RlbC5kZXNlbGVjdChldmVudC5zb3VyY2UpO1xuXG4gICAgICAgIC8vIEZvciBzaW5nbGUgc2VsZWN0aW9uIGNoaXAgbGlzdCwgbWFrZSBzdXJlIHRoZSBkZXNlbGVjdGVkIHZhbHVlIGlzIHVuc2VsZWN0ZWQuXG4gICAgICAgIGlmICghdGhpcy5tdWx0aXNlbGVjdCkge1xuICAgICAgICAgIHRoaXMuY2hpcHMuZm9yRWFjaCgoY2hpcCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9zZWxlY3Rpb25Nb2RlbC5pc1NlbGVjdGVkKGNoaXApICYmIGNoaXAuc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgY2hpcC5kZXNlbGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKiBMaXN0ZW5zIHRvIHVzZXItZ2VuZXJhdGVkIHNlbGVjdGlvbiBldmVudHMgb24gZWFjaCBjaGlwLiAqL1xuICBwcml2YXRlIF9saXN0ZW5Ub0NoaXBzRm9jdXMoKTogdm9pZCB7XG4gICAgdGhpcy5fY2hpcEZvY3VzU3Vic2NyaXB0aW9uID0gdGhpcy5jaGlwRm9jdXNDaGFuZ2VzLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGNoaXBJbmRleDogbnVtYmVyID0gdGhpcy5jaGlwcy50b0FycmF5KCkuaW5kZXhPZihldmVudC5jaGlwKTtcblxuICAgICAgaWYgKHRoaXMuX2lzVmFsaWRJbmRleChjaGlwSW5kZXgpKSB7XG4gICAgICAgIHRoaXMuX2tleU1hbmFnZXIudXBkYXRlQWN0aXZlSXRlbShjaGlwSW5kZXgpO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fY2hpcEJsdXJTdWJzY3JpcHRpb24gPSB0aGlzLmNoaXBCbHVyQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5fYmx1cigpO1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfbGlzdGVuVG9DaGlwc1JlbW92ZWQoKTogdm9pZCB7XG4gICAgdGhpcy5fY2hpcFJlbW92ZVN1YnNjcmlwdGlvbiA9IHRoaXMuY2hpcFJlbW92ZUNoYW5nZXMuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgY29uc3QgY2hpcCA9IGV2ZW50LmNoaXA7XG4gICAgICBjb25zdCBjaGlwSW5kZXggPSB0aGlzLmNoaXBzLnRvQXJyYXkoKS5pbmRleE9mKGV2ZW50LmNoaXApO1xuXG4gICAgICAvLyBJbiBjYXNlIHRoZSBjaGlwIHRoYXQgd2lsbCBiZSByZW1vdmVkIGlzIGN1cnJlbnRseSBmb2N1c2VkLCB3ZSB0ZW1wb3JhcmlseSBzdG9yZVxuICAgICAgLy8gdGhlIGluZGV4IGluIG9yZGVyIHRvIGJlIGFibGUgdG8gZGV0ZXJtaW5lIGFuIGFwcHJvcHJpYXRlIHNpYmxpbmcgY2hpcCB0aGF0IHdpbGxcbiAgICAgIC8vIHJlY2VpdmUgZm9jdXMuXG4gICAgICBpZiAodGhpcy5faXNWYWxpZEluZGV4KGNoaXBJbmRleCkgJiYgY2hpcC5faGFzRm9jdXMpIHtcbiAgICAgICAgdGhpcy5fbGFzdERlc3Ryb3llZENoaXBJbmRleCA9IGNoaXBJbmRleDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBDaGVja3Mgd2hldGhlciBhbiBldmVudCBjb21lcyBmcm9tIGluc2lkZSBhIGNoaXAgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfb3JpZ2luYXRlc0Zyb21DaGlwKGV2ZW50OiBFdmVudCk6IGJvb2xlYW4ge1xuICAgIGxldCBjdXJyZW50RWxlbWVudCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG5cbiAgICB3aGlsZSAoXG4gICAgICBjdXJyZW50RWxlbWVudCAmJlxuICAgICAgY3VycmVudEVsZW1lbnQgIT09IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudFxuICAgICkge1xuICAgICAgaWYgKGN1cnJlbnRFbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZ3Jhbml0ZS1jaGlwJykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRFbGVtZW50ID0gY3VycmVudEVsZW1lbnQucGFyZW50RWxlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKiogQ2hlY2tzIHdoZXRoZXIgYW55IG9mIHRoZSBjaGlwcyBpcyBmb2N1c2VkLiAqL1xuICBwcml2YXRlIF9oYXNGb2N1c2VkQ2hpcCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jaGlwcyAmJiB0aGlzLmNoaXBzLnNvbWUoKGNoaXApID0+IGNoaXAuX2hhc0ZvY3VzKTtcbiAgfVxuXG4gIC8qKiBTeW5jcyB0aGUgbGlzdCdzIHN0YXRlIHdpdGggdGhlIGluZGl2aWR1YWwgY2hpcHMuICovXG4gIHByaXZhdGUgX3N5bmNDaGlwc1N0YXRlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNoaXBzKSB7XG4gICAgICB0aGlzLmNoaXBzLmZvckVhY2goKGNoaXApID0+IHtcbiAgICAgICAgY2hpcC5fY2hpcExpc3REaXNhYmxlZCA9IHRoaXMuX2Rpc2FibGVkO1xuICAgICAgICBjaGlwLl9jaGlwTGlzdE11bHRpcGxlID0gdGhpcy5tdWx0aXNlbGVjdDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19
|