@ifsworld/granite-components 10.0.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +4 -28
  2. package/date-picker/lib/date-picker-base.d.ts +1 -1
  3. package/date-picker/lib/date-picker-trigger-for.directive.d.ts +1 -1
  4. package/date-picker/lib/date-picker.component.d.ts +1 -1
  5. package/date-picker/lib/date-range-picker.component.d.ts +1 -1
  6. package/{esm2020 → esm2022}/date-picker/lib/date-picker-base.mjs +4 -4
  7. package/{esm2020 → esm2022}/date-picker/lib/date-picker-trigger-for.directive.mjs +4 -4
  8. package/esm2022/date-picker/lib/date-picker.component.mjs +30 -0
  9. package/{esm2020 → esm2022}/date-picker/lib/date-picker.module.mjs +21 -21
  10. package/esm2022/date-picker/lib/date-range-picker.component.mjs +46 -0
  11. package/{esm2020 → esm2022}/lib/arrange-grid/arrange-grid-item.component.mjs +12 -12
  12. package/{esm2020 → esm2022}/lib/arrange-grid/arrange-grid.component.mjs +7 -7
  13. package/{esm2020 → esm2022}/lib/arrange-grid/arrange-grid.module.mjs +5 -5
  14. package/{esm2020 → esm2022}/lib/badge/badge.component.mjs +5 -5
  15. package/{esm2020 → esm2022}/lib/badge/badge.module.mjs +5 -5
  16. package/esm2022/lib/badge/testing/badge.harness.mjs +25 -0
  17. package/esm2022/lib/button/button.component.mjs +87 -0
  18. package/{esm2020 → esm2022}/lib/button/button.module.mjs +5 -5
  19. package/{esm2020 → esm2022}/lib/checkbox/checkbox-group.component.mjs +4 -4
  20. package/{esm2020 → esm2022}/lib/checkbox/checkbox.component.mjs +4 -4
  21. package/{esm2020 → esm2022}/lib/checkbox/checkbox.module.mjs +5 -5
  22. package/esm2022/lib/chips/chip-input.mjs +195 -0
  23. package/esm2022/lib/chips/chip-list.component.mjs +567 -0
  24. package/esm2022/lib/chips/chip.component.mjs +287 -0
  25. package/{esm2020 → esm2022}/lib/chips/chips.module.mjs +9 -9
  26. package/{esm2020 → esm2022}/lib/core/common-behaviors/disabled.mjs +4 -4
  27. package/{esm2020 → esm2022}/lib/core/core.module.mjs +11 -11
  28. package/esm2022/lib/core/devices/client-input-desktop.directive.mjs +29 -0
  29. package/esm2022/lib/core/devices/client-input-touch.directive.mjs +29 -0
  30. package/esm2022/lib/core/devices/client-output-desktop.directive.mjs +29 -0
  31. package/esm2022/lib/core/devices/client-output-touch.directive.mjs +29 -0
  32. package/{esm2020 → esm2022}/lib/core/pipes/pure-pipes.module.mjs +5 -5
  33. package/{esm2020 → esm2022}/lib/core/pipes/title.pipe.mjs +4 -4
  34. package/{esm2020 → esm2022}/lib/core/radio-checkbox-base.mjs +4 -4
  35. package/{esm2020 → esm2022}/lib/grid/grid.component.mjs +7 -7
  36. package/{esm2020 → esm2022}/lib/grid/grid.module.mjs +5 -5
  37. package/{esm2020 → esm2022}/lib/icon/icon.component.mjs +4 -4
  38. package/{esm2020 → esm2022}/lib/icon/icon.module.mjs +5 -5
  39. package/{esm2020 → esm2022}/lib/input-field/input-field.component.mjs +5 -5
  40. package/{esm2020 → esm2022}/lib/input-field/input-field.module.mjs +5 -5
  41. package/{esm2020 → esm2022}/lib/label/label.component.mjs +4 -4
  42. package/{esm2020 → esm2022}/lib/label/label.module.mjs +5 -5
  43. package/{esm2020 → esm2022}/lib/menu/divider.directive.mjs +4 -4
  44. package/{esm2020 → esm2022}/lib/menu/menu-base.mjs +4 -4
  45. package/{esm2020 → esm2022}/lib/menu/menu-item.component.mjs +6 -6
  46. package/{esm2020 → esm2022}/lib/menu/menu-touch-close.component.mjs +4 -4
  47. package/{esm2020 → esm2022}/lib/menu/menu-touch-title.component.mjs +6 -6
  48. package/esm2022/lib/menu/menu-trigger-for.directive.mjs +704 -0
  49. package/esm2022/lib/menu/menu.component.mjs +30 -0
  50. package/{esm2020 → esm2022}/lib/menu/menu.module.mjs +17 -17
  51. package/esm2022/lib/menu/testing/menu.harness.mjs +109 -0
  52. package/{esm2020 → esm2022}/lib/menu/title.directive.mjs +4 -4
  53. package/{esm2020 → esm2022}/lib/radio-button/radio-button.component.mjs +4 -4
  54. package/{esm2020 → esm2022}/lib/radio-button/radio-button.module.mjs +5 -5
  55. package/{esm2020 → esm2022}/lib/radio-button/radio-group.component.mjs +4 -4
  56. package/{esm2020 → esm2022}/lib/toggle-switch/toggle-switch.component.mjs +4 -4
  57. package/{esm2020 → esm2022}/lib/toggle-switch/toggle-switch.module.mjs +5 -5
  58. package/{esm2020 → esm2022}/table/lib/cell/cell-align/cell-align-classes.directive.mjs +4 -4
  59. package/{esm2020 → esm2022}/table/lib/cell/cell.mjs +4 -4
  60. package/{esm2020 → esm2022}/table/lib/cell/table-data-cell.component.mjs +5 -5
  61. package/{esm2020 → esm2022}/table/lib/cell/table-header-cell.component.mjs +4 -4
  62. package/{esm2020 → esm2022}/table/lib/column/table-column.directive.mjs +4 -4
  63. package/esm2022/table/lib/table-constants.library.mjs +9 -0
  64. package/{esm2020 → esm2022}/table/lib/table.component.mjs +4 -4
  65. package/{esm2020 → esm2022}/table/lib/table.module.mjs +9 -9
  66. package/{esm2020 → esm2022}/tooltip/lib/tooltip-constants.library.mjs +2 -2
  67. package/{esm2020 → esm2022}/tooltip/lib/tooltip-trigger-for.directive.mjs +4 -4
  68. package/{esm2020 → esm2022}/tooltip/lib/tooltip.component.mjs +5 -5
  69. package/{esm2020 → esm2022}/tooltip/lib/tooltip.module.mjs +5 -5
  70. package/fesm2022/ifsworld-granite-components-date-picker.mjs +396 -0
  71. package/{fesm2020 → fesm2022}/ifsworld-granite-components-date-picker.mjs.map +1 -1
  72. package/fesm2022/ifsworld-granite-components-table.mjs +190 -0
  73. package/{fesm2015 → fesm2022}/ifsworld-granite-components-table.mjs.map +1 -1
  74. package/{fesm2020 → fesm2022}/ifsworld-granite-components-tooltip.mjs +12 -12
  75. package/{fesm2020 → fesm2022}/ifsworld-granite-components-tooltip.mjs.map +1 -1
  76. package/{fesm2020 → fesm2022}/ifsworld-granite-components.mjs +340 -341
  77. package/fesm2022/ifsworld-granite-components.mjs.map +1 -0
  78. package/lib/arrange-grid/arrange-grid-item.component.d.ts +5 -5
  79. package/lib/arrange-grid/arrange-grid.component.d.ts +3 -3
  80. package/lib/badge/badge.component.d.ts +1 -1
  81. package/lib/button/button.component.d.ts +2 -2
  82. package/lib/checkbox/checkbox.component.d.ts +1 -1
  83. package/lib/chips/chip-input.d.ts +9 -9
  84. package/lib/chips/chip-list.component.d.ts +33 -33
  85. package/lib/chips/chip.component.d.ts +22 -22
  86. package/lib/core/radio-checkbox-base.d.ts +1 -1
  87. package/lib/grid/grid.component.d.ts +2 -2
  88. package/lib/icon/icon.component.d.ts +1 -1
  89. package/lib/input-field/input-field.component.d.ts +1 -1
  90. package/lib/label/label.component.d.ts +1 -1
  91. package/lib/menu/divider.directive.d.ts +1 -1
  92. package/lib/menu/menu-base.d.ts +1 -1
  93. package/lib/menu/menu-item.component.d.ts +1 -1
  94. package/lib/menu/menu-trigger-for.directive.d.ts +1 -1
  95. package/lib/radio-button/radio-button.component.d.ts +1 -1
  96. package/lib/toggle-switch/toggle-switch.component.d.ts +1 -1
  97. package/package.json +21 -40
  98. package/table/lib/cell/cell-align/cell-align-classes.directive.d.ts +1 -1
  99. package/table/lib/cell/cell.d.ts +1 -1
  100. package/table/lib/cell/table-data-cell.component.d.ts +1 -1
  101. package/table/lib/column/table-column.directive.d.ts +1 -1
  102. package/table/lib/table.component.d.ts +1 -1
  103. package/tooltip/lib/tooltip-trigger-for.directive.d.ts +1 -1
  104. package/esm2020/date-picker/lib/date-picker.component.mjs +0 -30
  105. package/esm2020/date-picker/lib/date-range-picker.component.mjs +0 -46
  106. package/esm2020/lib/badge/testing/badge.harness.mjs +0 -25
  107. package/esm2020/lib/button/button.component.mjs +0 -87
  108. package/esm2020/lib/chips/chip-input.mjs +0 -195
  109. package/esm2020/lib/chips/chip-list.component.mjs +0 -567
  110. package/esm2020/lib/chips/chip.component.mjs +0 -287
  111. package/esm2020/lib/core/devices/client-input-desktop.directive.mjs +0 -29
  112. package/esm2020/lib/core/devices/client-input-touch.directive.mjs +0 -29
  113. package/esm2020/lib/core/devices/client-output-desktop.directive.mjs +0 -29
  114. package/esm2020/lib/core/devices/client-output-touch.directive.mjs +0 -29
  115. package/esm2020/lib/menu/menu-trigger-for.directive.mjs +0 -705
  116. package/esm2020/lib/menu/menu.component.mjs +0 -30
  117. package/esm2020/lib/menu/testing/menu.harness.mjs +0 -109
  118. package/esm2020/table/lib/table-constants.library.mjs +0 -9
  119. package/fesm2015/ifsworld-granite-components-date-picker.mjs +0 -401
  120. package/fesm2015/ifsworld-granite-components-date-picker.mjs.map +0 -1
  121. package/fesm2015/ifsworld-granite-components-table.mjs +0 -190
  122. package/fesm2015/ifsworld-granite-components-tooltip.mjs +0 -169
  123. package/fesm2015/ifsworld-granite-components-tooltip.mjs.map +0 -1
  124. package/fesm2015/ifsworld-granite-components.mjs +0 -4133
  125. package/fesm2015/ifsworld-granite-components.mjs.map +0 -1
  126. package/fesm2020/ifsworld-granite-components-date-picker.mjs +0 -396
  127. package/fesm2020/ifsworld-granite-components-table.mjs +0 -190
  128. package/fesm2020/ifsworld-granite-components-table.mjs.map +0 -1
  129. package/fesm2020/ifsworld-granite-components.mjs.map +0 -1
  130. /package/{esm2020 → esm2022}/date-picker/ifsworld-granite-components-date-picker.mjs +0 -0
  131. /package/{esm2020 → esm2022}/date-picker/index.mjs +0 -0
  132. /package/{esm2020 → esm2022}/ifsworld-granite-components.mjs +0 -0
  133. /package/{esm2020 → esm2022}/index.mjs +0 -0
  134. /package/{esm2020 → esm2022}/lib/core/animation.mjs +0 -0
  135. /package/{esm2020 → esm2022}/lib/core/client-environment.mjs +0 -0
  136. /package/{esm2020 → esm2022}/lib/core/theme.library.mjs +0 -0
  137. /package/{esm2020 → esm2022}/lib/core/types.mjs +0 -0
  138. /package/{esm2020 → esm2022}/lib/menu/menu-desktop-animations.mjs +0 -0
  139. /package/{esm2020 → esm2022}/lib/menu/menu-errors.mjs +0 -0
  140. /package/{esm2020 → esm2022}/lib/menu/menu-panel.mjs +0 -0
  141. /package/{esm2020 → esm2022}/lib/menu/menu-positions.mjs +0 -0
  142. /package/{esm2020 → esm2022}/lib/menu/menu-touch-animations.mjs +0 -0
  143. /package/{esm2020 → esm2022}/table/ifsworld-granite-components-table.mjs +0 -0
  144. /package/{esm2020 → esm2022}/table/index.mjs +0 -0
  145. /package/{esm2020 → esm2022}/table/lib/table.types.mjs +0 -0
  146. /package/{esm2020 → esm2022}/tooltip/ifsworld-granite-components-tooltip.mjs +0 -0
  147. /package/{esm2020 → esm2022}/tooltip/index.mjs +0 -0
@@ -0,0 +1,567 @@
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, ViewEncapsulation, 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: "16.2.12", 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: "16.2.12", 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: [".granite-chip-list{display:flex;flex-direction:row;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}input.granite-chip-input{outline:none;border:none;background-color:transparent;color:var(--granite-color-text);margin:var(--granite-spacing-4)}granite-icon{color:var(--granite-color-text);background-color:transparent}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
512
+ }
513
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", 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
+ }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".granite-chip-list{display:flex;flex-direction:row;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}input.granite-chip-input{outline:none;border:none;background-color:transparent;color:var(--granite-color-text);margin:var(--granite-spacing-4)}granite-icon{color:var(--granite-color-text);background-color:transparent}\n"] }]
530
+ }], ctorParameters: function () { return [{ 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hpcC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvZ3Jhbml0ZS1jb21wb25lbnRzL3NyYy9saWIvY2hpcHMvY2hpcC1saXN0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxFQUVmLFVBQVUsRUFDVixLQUFLLEVBR0wsUUFBUSxFQUNSLFNBQVMsRUFDVCxJQUFJLEVBQ0osaUJBQWlCLEVBQ2pCLFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBRUwsa0JBQWtCLEVBQ2xCLFNBQVMsRUFDVCxNQUFNLEdBQ1AsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsS0FBSyxFQUFjLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDaEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQ0wsb0JBQW9CLEdBR3JCLE1BQU0sa0JBQWtCLENBQUM7Ozs7QUFHMUIsTUFBZSxtQkFBbUI7SUFHaEMsWUFDUyxXQUFtQixFQUNuQixnQkFBb0MsRUFDcEMsU0FBb0I7UUFGcEIsZ0JBQVcsR0FBWCxXQUFXLENBQVE7UUFDbkIscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFvQjtRQUNwQyxjQUFTLEdBQVQsU0FBUyxDQUFXO1FBTHBCLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FB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QUMsaUJBQWlCO2dCQUl4QixlQUFlO3NCQURkLEtBQUs7dUJBQUMsa0JBQWtCO2dCQVN6QixLQUFLO3NCQUxKLGVBQWU7dUJBQUMsb0JBQW9CLEVBQUU7d0JBQ3JDLHVFQUF1RTt3QkFDdkUsOENBQThDO3dCQUM5QyxXQUFXLEVBQUUsSUFBSTtxQkFDbEI7Z0JBb0RHLElBQUk7c0JBRFAsS0FBSztnQkFlRixXQUFXO3NCQURkLEtBQUs7Z0JBY0YsUUFBUTtzQkFEWCxLQUFLO2dCQWNGLFVBQVU7c0JBRGIsS0FBSztnQkFlRixRQUFRO3NCQURYLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGb2N1c0tleU1hbmFnZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5pbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5pbXBvcnQge1xuICBBZnRlckNvbnRlbnRJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBEb0NoZWNrLFxuICBFbGVtZW50UmVmLFxuICBJbnB1dCxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBRdWVyeUxpc3QsXG4gIFNlbGYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBFdmVudEVtaXR0ZXIsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXG4gIEZvcm1Hcm91cERpcmVjdGl2ZSxcbiAgTmdDb250cm9sLFxuICBOZ0Zvcm0sXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IG1lcmdlLCBPYnNlcnZhYmxlLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN0YXJ0V2l0aCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgR3Jhbml0ZUNoaXBDb21wb25lbnQsXG4gIEdyYW5pdGVDaGlwRXZlbnQsXG4gIEdyYW5pdGVDaGlwU2VsZWN0aW9uQ2hhbmdlRXZlbnQsXG59IGZyb20gJy4vY2hpcC5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3Jhbml0ZUNoaXBUZXh0Q29udHJvbCB9IGZyb20gJy4vY2hpcC1pbnB1dCc7XG5cbmFic3RyYWN0IGNsYXNzIEdyYW5pdGVDaGlwTGlzdEJhc2Uge1xuICByZWFkb25seSBzdGF0ZUNoYW5nZXMgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIF9wYXJlbnRGb3JtOiBOZ0Zvcm0sXG4gICAgcHVibGljIF9wYXJlbnRGb3JtR3JvdXA6IEZvcm1Hcm91cERpcmVjdGl2ZSxcbiAgICBwdWJsaWMgbmdDb250cm9sOiBOZ0NvbnRyb2xcbiAgKSB7fVxufVxuXG4vLyBJbmNyZWFzaW5nIGludGVnZXIgZm9yIGdlbmVyYXRpbmcgdW5pcXVlIGlkcyBmb3IgY2hpcC1saXN0IGNvbXBvbmVudHMuXG5sZXQgbmV4dFVuaXF1ZUlkID0gMDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZ3Jhbml0ZS1jaGlwLWxpc3QnLFxuICB0ZW1wbGF0ZTogYDxuZy1jb250ZW50PjwvbmctY29udGVudD5gLFxuICBleHBvcnRBczogJ2dyYW5pdGVDaGlwTGlzdCcsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2dyYW5pdGUtY2hpcC1saXN0JyxcbiAgICAnW2NsYXNzLmdyYW5pdGUtY2hpcC1saXN0LWRpc2FibGVkXSc6ICdkaXNhYmxlZCcsXG4gICAgJ1thdHRyLnRhYmluZGV4XSc6ICdkaXNhYmxlZCA/IG51bGwgOiBfdGFiSW5kZXgnLFxuICAgICdbYXR0ci5yb2xlXSc6ICdyb2xlJyxcbiAgICAnW2F0dHIuYXJpYS1sYWJlbF0nOiAnYXJpYUxhYmVsJyxcbiAgICAnW2F0dHIuYXJpYS1sYWJlbGxlZGJ5XSc6ICdhcmlhTGFiZWxsZWRieScsXG4gICAgJ1thdHRyLmFyaWEtZGlzYWJsZWRdJzogJ2Rpc2FibGVkLnRvU3RyaW5nKCknLFxuICAgICdbYXR0ci5hcmlhLW11bHRpc2VsZWN0YWJsZV0nOiAnbXVsdGlzZWxlY3QnLFxuICAgICdbYXR0ci5hcmlhLW9yaWVudGF0aW9uXSc6ICdhcmlhT3JpZW50YXRpb24nLFxuICAgICdbaWRdJzogJ191aWQnLFxuICAgICcoZm9jdXMpJzogJ2ZvY3VzKCknLFxuICAgICcoYmx1ciknOiAnX2JsdXIoKScsXG4gICAgJyhrZXlkb3duKSc6ICdfa2V5ZG93bigkZXZlbnQpJyxcbiAgfSxcbiAgc3R5bGVVcmxzOiBbJy4vY2hpcC1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBHcmFuaXRlQ2hpcExpc3RDb21wb25lbnRcbiAgZXh0ZW5kcyBHcmFuaXRlQ2hpcExpc3RCYXNlXG4gIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEFmdGVyQ29udGVudEluaXQsIERvQ2hlY2ssIE9uSW5pdCwgT25EZXN0cm95XG57XG4gIEBJbnB1dCgnYXJpYS1sYWJlbCcpXG4gIGFyaWFMYWJlbDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgQElucHV0KCdhcmlhLWxhYmVsbGVkYnknKVxuICBhcmlhTGFiZWxsZWRieTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgQElucHV0KCdhcmlhLW9yaWVudGF0aW9uJylcbiAgYXJpYU9yaWVudGF0aW9uOiAnaG9yaXpvbnRhbCcgfCAndmVydGljYWwnID0gJ2hvcml6b250YWwnO1xuXG4gIC8qKiBUaGUgY2hpcHMgY29udGFpbmVkIHdpdGhpbiB0aGlzIGNoaXAgbGlzdC4gKi9cbiAgQENvbnRlbnRDaGlsZHJlbihHcmFuaXRlQ2hpcENvbXBvbmVudCwge1xuICAgIC8vIFdlIG5lZWQgdG8gdXNlIGBkZXNjZW5kYW50czogdHJ1ZWAsIGJlY2F1c2UgSXZ5IHdpbGwgbm8gbG9uZ2VyIG1hdGNoXG4gICAgLy8gaW5kaXJlY3QgZGVzY2VuZGFudHMgaWYgaXQncyBsZWZ0IGFzIGZhbHNlLlxuICAgIGRlc2NlbmRhbnRzOiB0cnVlLFxuICB9KVxuICBjaGlwczogUXVlcnlMaXN0PEdyYW5pdGVDaGlwQ29tcG9uZW50PjtcblxuICByZWFkb25seSBjb250cm9sVHlwZTogc3RyaW5nID0gJ2dyYW5pdGUtY2hpcC1saXN0JztcblxuICAvKiogVWlkIG9mIHRoZSBjaGlwIGxpc3QgKi9cbiAgX3VpZDogc3RyaW5nID0gYGdyYW5pdGUtY2hpcC1saXN0LSR7bmV4dFVuaXF1ZUlkKyt9YDtcblxuICAvKiogVGFiIGluZGV4IGZvciB0aGUgY2hpcCBsaXN0LiAqL1xuICBfdGFiSW5kZXggPSAwO1xuXG4gIC8qKlxuICAgKiBVc2VyIGRlZmluZWQgdGFiIGluZGV4LlxuICAgKiBXaGVuIGl0IGlzIG5vdCBudWxsLCB1c2UgdXNlciBkZWZpbmVkIHRhYiBpbmRleC4gT3RoZXJ3aXNlIHVzZSBfdGFiSW5kZXhcbiAgICovXG4gIF91c2VyVGFiSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBUaGUgRm9jdXNLZXlNYW5hZ2VyIHdoaWNoIGhhbmRsZXMgZm9jdXMuICovXG4gIF9rZXlNYW5hZ2VyOiBGb2N1c0tleU1hbmFnZXI8R3Jhbml0ZUNoaXBDb21wb25lbnQ+O1xuXG4gIF9zZWxlY3Rpb25Nb2RlbDogU2VsZWN0aW9uTW9kZWw8R3Jhbml0ZUNoaXBDb21wb25lbnQ+O1xuXG4gIC8qKiBUaGUgY2hpcCBpbnB1dCB0byBhZGQgbW9yZSBjaGlwcyAqL1xuICBwcm90ZWN0ZWQgX2NoaXBJbnB1dDogR3Jhbml0ZUNoaXBUZXh0Q29udHJvbDtcblxuICBwcm90ZWN0ZWQgX2Rpc2FibGVkOiBib29sZWFuID0gZmFsc2U7XG4gIHByb3RlY3RlZCBfc2VsZWN0YWJsZTogYm9vbGVhbiA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFdoZW4gYSBjaGlwIGlzIGRlc3Ryb3llZCwgd2Ugc3RvcmUgdGhlIGluZGV4IG9mIHRoZSBkZXN0cm95ZWQgY2hpcCB1bnRpbCB0aGUgY2hpcHNcbiAgICogcXVlcnkgbGlzdCBub3RpZmllcyBhYm91dCB0aGUgdXBkYXRlLiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHdlIGNhbm5vdCBkZXRlcm1pbmUgYW5cbiAgICogYXBwcm9wcmlhdGUgY2hpcCB0aGF0IHNob3VsZCByZWNlaXZlIGZvY3VzIHVudGlsIHRoZSBhcnJheSBvZiBjaGlwcyB1cGRhdGVkIGNvbXBsZXRlbHkuXG4gICAqL1xuICBwcml2YXRlIF9sYXN0RGVzdHJveWVkQ2hpcEluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAvKiogU3ViamVjdCB0aGF0IGVtaXRzIHdoZW4gdGhlIGNvbXBvbmVudCBoYXMgYmVlbiBkZXN0cm95ZWQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3llZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byBmb2N1cyBjaGFuZ2VzIGluIHRoZSBjaGlwcy4gKi9cbiAgcHJpdmF0ZSBfY2hpcEZvY3VzU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsO1xuXG4gIC8qKiBTdWJzY3JpcHRpb24gdG8gYmx1ciBjaGFuZ2VzIGluIHRoZSBjaGlwcy4gKi9cbiAgcHJpdmF0ZSBfY2hpcEJsdXJTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGw7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byBzZWxlY3Rpb24gY2hhbmdlcyBpbiBjaGlwcy4gKi9cbiAgcHJpdmF0ZSBfY2hpcFNlbGVjdGlvblN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uIHwgbnVsbDtcblxuICAvKiogU3Vic2NyaXB0aW9uIHRvIHJlbW92ZSBjaGFuZ2VzIGluIGNoaXBzLiAqL1xuICBwcml2YXRlIF9jaGlwUmVtb3ZlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsO1xuXG4gIC8qKiBUaGUgQVJJQSByb2xlIGFwcGxpZWQgdG8gdGhlIGNoaXAgbGlzdC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IHJvbGUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKHRoaXMuX2V4cGxpY2l0Um9sZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2V4cGxpY2l0Um9sZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5lbXB0eSA/IG51bGwgOiAnbGlzdGJveCc7XG4gIH1cbiAgc2V0IHJvbGUocm9sZTogc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMuX2V4cGxpY2l0Um9sZSA9IHJvbGU7XG4gIH1cbiAgcHJpdmF0ZSBfZXhwbGljaXRSb2xlPzogc3RyaW5nIHwgbnVsbDtcblxuICAvKiogV2hldGhlciB0aGUgdXNlciBzaG91bGQgYmUgYWxsb3dlZCB0byBzZWxlY3QgbXVsdGlzZWxlY3QgY2hpcHMuICovXG4gIEBJbnB1dCgpXG4gIGdldCBtdWx0aXNlbGVjdCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fbXVsdGlwbGU7XG4gIH1cbiAgc2V0IG11bHRpc2VsZWN0KHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fbXVsdGlwbGUgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICAgIHRoaXMuX3N5bmNDaGlwc1N0YXRlKCk7XG4gIH1cbiAgcHJpdmF0ZSBfbXVsdGlwbGU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgY2hpcCBsaXN0IGlzIGRpc2FibGVkLlxuICAgKi9cbiAgQElucHV0KClcbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5nQ29udHJvbCA/ICEhdGhpcy5uZ0NvbnRyb2wuZGlzYWJsZWQgOiB0aGlzLl9kaXNhYmxlZDtcbiAgfVxuICBzZXQgZGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9kaXNhYmxlZCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gICAgdGhpcy5fc3luY0NoaXBzU3RhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIG9yIG5vdCB0aGlzIGNoaXAgbGlzdCBpcyBzZWxlY3RhYmxlLiBXaGVuIGEgY2hpcCBsaXN0IGlzIG5vdCBzZWxlY3RhYmxlLFxuICAgKiB0aGUgc2VsZWN0ZWQgc3RhdGVzIGZvciBhbGwgdGhlIGNoaXBzIGluc2lkZSB0aGUgY2hpcCBsaXN0IGFyZSBhbHdheXMgaWdub3JlZC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBzZWxlY3RhYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3RhYmxlO1xuICB9XG4gIHNldCBzZWxlY3RhYmxlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fc2VsZWN0YWJsZSA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG5cbiAgICBpZiAodGhpcy5jaGlwcykge1xuICAgICAgdGhpcy5jaGlwcy5mb3JFYWNoKFxuICAgICAgICAoY2hpcCkgPT4gKGNoaXAuX2NoaXBMaXN0U2VsZWN0YWJsZSA9IHRoaXMuX3NlbGVjdGFibGUpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIEBJbnB1dCgpXG4gIHNldCB0YWJpbmRleCh2YWx1ZTogbnVtYmVyKSB7XG4gICAgdGhpcy5fdXNlclRhYkluZGV4ID0gdmFsdWU7XG4gICAgdGhpcy5fdGFiSW5kZXggPSB2YWx1ZTtcbiAgfVxuXG4gIC8qKiBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGNoaXAgbGlzdC4gKi9cbiAgZ2V0IGlkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2NoaXBJbnB1dCA/IHRoaXMuX2NoaXBJbnB1dC5pZCA6IHRoaXMuX3VpZDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGFueSBjaGlwcyBvciB0aGUgbWF0Q2hpcElucHV0IGluc2lkZSBvZiB0aGlzIGNoaXAtbGlzdCBoYXMgZm9jdXMuICovXG4gIGdldCBmb2N1c2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAodGhpcy5fY2hpcElucHV0ICYmIHRoaXMuX2NoaXBJbnB1dC5mb2N1c2VkKSB8fCB0aGlzLl9oYXNGb2N1c2VkQ2hpcCgpXG4gICAgKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSBjaGlwIGxpc3QgaXMgZW1wdHkuICovXG4gIGdldCBlbXB0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgKCF0aGlzLl9jaGlwSW5wdXQgfHwgdGhpcy5fY2hpcElucHV0LmVtcHR5KSAmJlxuICAgICAgKCF0aGlzLmNoaXBzIHx8IHRoaXMuY2hpcHMubGVuZ3RoID09PSAwKVxuICAgICk7XG4gIH1cblxuICAvKiogVGhlIGFycmF5IG9mIHNlbGVjdGVkIGNoaXBzIGluc2lkZSBjaGlwIGxpc3QuICovXG4gIGdldCBzZWxlY3RlZCgpOiBHcmFuaXRlQ2hpcENvbXBvbmVudFtdIHwgR3Jhbml0ZUNoaXBDb21wb25lbnQge1xuICAgIHJldHVybiB0aGlzLm11bHRpc2VsZWN0XG4gICAgICA/IHRoaXMuX3NlbGVjdGlvbk1vZGVsPy5zZWxlY3RlZCB8fCBbXVxuICAgICAgOiB0aGlzLl9zZWxlY3Rpb25Nb2RlbD8uc2VsZWN0ZWRbMF07XG4gIH1cblxuICAvKiogQ29tYmluZWQgc3RyZWFtIG9mIGFsbCBvZiB0aGUgY2hpbGQgY2hpcHMnIHNlbGVjdGlvbiBjaGFuZ2UgZXZlbnRzLiAqL1xuICBnZXQgY2hpcFNlbGVjdGlvbkNoYW5nZXMoKTogT2JzZXJ2YWJsZTxHcmFuaXRlQ2hpcFNlbGVjdGlvbkNoYW5nZUV2ZW50PiB7XG4gICAgcmV0dXJuIG1lcmdlKC4uLnRoaXMuY2hpcHMubWFwKChjaGlwKSA9PiBjaGlwLnNlbGVjdGlvbkNoYW5nZSkpO1xuICB9XG5cbiAgLyoqIENvbWJpbmVkIHN0cmVhbSBvZiBhbGwgb2YgdGhlIGNoaWxkIGNoaXBzJyBmb2N1cyBjaGFuZ2UgZXZlbnRzLiAqL1xuICBnZXQgY2hpcEZvY3VzQ2hhbmdlcygpOiBPYnNlcnZhYmxlPEdyYW5pdGVDaGlwRXZlbnQ+IHtcbiAgICByZXR1cm4gbWVyZ2UoLi4udGhpcy5jaGlwcy5tYXAoKGNoaXApID0+IGNoaXAuY2hpcEZvY3VzKSk7XG4gIH1cblxuICAvKiogQ29tYmluZWQgc3RyZWFtIG9mIGFsbCBvZiB0aGUgY2hpbGQgY2hpcHMnIGJsdXIgY2hhbmdlIGV2ZW50cy4gKi9cbiAgZ2V0IGNoaXBCbHVyQ2hhbmdlcygpOiBPYnNlcnZhYmxlPEdyYW5pdGVDaGlwRXZlbnQ+IHtcbiAgICByZXR1cm4gbWVyZ2UoLi4udGhpcy5jaGlwcy5tYXAoKGNoaXApID0+IGNoaXAuY2hpcEJsdXIpKTtcbiAgfVxuXG4gIC8qKiBDb21iaW5lZCBzdHJlYW0gb2YgYWxsIG9mIHRoZSBjaGlsZCBjaGlwcycgcmVtb3ZlIGNoYW5nZSBldmVudHMuICovXG4gIGdldCBjaGlwUmVtb3ZlQ2hhbmdlcygpOiBPYnNlcnZhYmxlPEdyYW5pdGVDaGlwRXZlbnQ+IHtcbiAgICByZXR1cm4gbWVyZ2UoLi4udGhpcy5jaGlwcy5tYXAoKGNoaXApID0+IGNoaXAuZGVzdHJveWVkKSk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIF9kaXI6IERpcmVjdGlvbmFsaXR5LFxuICAgIEBPcHRpb25hbCgpIF9wYXJlbnRGb3JtOiBOZ0Zvcm0sXG4gICAgQE9wdGlvbmFsKCkgX3BhcmVudEZvcm1Hcm91cDogRm9ybUdyb3VwRGlyZWN0aXZlLFxuICAgIEBPcHRpb25hbCgpIEBTZWxmKCkgbmdDb250cm9sOiBOZ0NvbnRyb2xcbiAgKSB7XG4gICAgc3VwZXIoX3BhcmVudEZvcm0sIF9wYXJlbnRGb3JtR3JvdXAsIG5nQ29udHJvbCk7XG4gICAgaWYgKHRoaXMubmdDb250cm9sKSB7XG4gICAgICB0aGlzLm5nQ29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICB9XG4gIH1cblxuICAvKiogRnVuY3Rpb24gd2hlbiBjaGFuZ2VkICovXG4gIF9vbkNoYW5nZTogKHZhbHVlOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7XG4gICAgLy8gSW1wbGVtZW50ZWQgYXMgcGFydCBvZiBDb250cm9sVmFsdWVBY2Nlc3NvclxuICB9O1xuXG4gIC8qKiBGdW5jdGlvbiB3aGVuIGNoYW5nZWQgKi9cbiAgX29uVG91Y2hlZDogKCkgPT4gdm9pZCA9ICgpID0+IHtcbiAgICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yXG4gIH07XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX2tleU1hbmFnZXIgPSBuZXcgRm9jdXNLZXlNYW5hZ2VyPEdyYW5pdGVDaGlwQ29tcG9uZW50Pih0aGlzLmNoaXBzKVxuICAgICAgLndpdGhXcmFwKClcbiAgICAgIC53aXRoVmVydGljYWxPcmllbnRhdGlvbigpXG4gICAgICAud2l0aEhvbWVBbmRFbmQoKVxuICAgICAgLndpdGhIb3Jpem9udGFsT3JpZW50YXRpb24odGhpcy5fZGlyID8gdGhpcy5fZGlyLnZhbHVlIDogJ2x0cicpO1xuXG4gICAgaWYgKHRoaXMuX2Rpcikge1xuICAgICAgdGhpcy5fZGlyLmNoYW5nZVxuICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoZGlyKSA9PiB0aGlzLl9rZXlNYW5hZ2VyLndpdGhIb3Jpem9udGFsT3JpZW50YXRpb24oZGlyKSk7XG4gICAgfVxuXG4gICAgdGhpcy5fa2V5TWFuYWdlci50YWJPdXQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuX2FsbG93Rm9jdXNFc2NhcGUoKTtcbiAgICB9KTtcblxuICAgIC8vIFdoZW4gdGhlIGxpc3QgY2hhbmdlcywgcmUtc3Vic2NyaWJlXG4gICAgdGhpcy5jaGlwcy5jaGFuZ2VzXG4gICAgICAucGlwZShzdGFydFdpdGgobnVsbCksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICAgICAgLy8gU2luY2UgdGhpcyBoYXBwZW5zIGFmdGVyIHRoZSBjb250ZW50IGhhcyBiZWVuXG4gICAgICAgICAgLy8gY2hlY2tlZCwgd2UgbmVlZCB0byBkZWZlciBpdCB0byB0aGUgbmV4dCB0aWNrLlxuICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fc3luY0NoaXBzU3RhdGUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3Jlc2V0Q2hpcHMoKTtcblxuICAgICAgICAvLyBSZXNldCBjaGlwcyBzZWxlY3RlZC9kZXNlbGVjdGVkIHN0YXR1c1xuICAgICAgICB0aGlzLl9pbml0aWFsaXplU2VsZWN0aW9uKCk7XG5cbiAgICAgICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHdlIG5lZWQgdG8gdXBkYXRlIG91ciB0YWIgaW5kZXhcbiAgICAgICAgdGhpcy5fdXBkYXRlVGFiSW5kZXgoKTtcblxuICAgICAgICAvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIGRlc3Ryb3llZCBjaGlwIGFuZCBuZWVkIHRvIHJlZm9jdXNcbiAgICAgICAgdGhpcy5fdXBkYXRlRm9jdXNGb3JEZXN0cm95ZWRDaGlwcygpO1xuXG4gICAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fc2VsZWN0aW9uTW9kZWwgPSBuZXcgU2VsZWN0aW9uTW9kZWw8R3Jhbml0ZUNoaXBDb21wb25lbnQ+KFxuICAgICAgdGhpcy5tdWx0aXNlbGVjdCxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gIH1cblxuICBuZ0RvQ2hlY2soKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubmdDb250cm9sKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIHJlLWV2YWx1YXRlIHRoaXMgb24gZXZlcnkgY2hhbmdlIGRldGVjdGlvbiBjeWNsZSwgYmVjYXVzZSB0aGVyZSBhcmUgc29tZVxuICAgICAgLy8gZXJyb3IgdHJpZ2dlcnMgdGhhdCB3ZSBjYW4ndCBzdWJzY3JpYmUgdG8gKGUuZy4gcGFyZW50IGZvcm0gc3VibWlzc2lvbnMpLiBUaGlzIG1lYW5zXG4gICAgICAvLyB0aGF0IHdoYXRldmVyIGxvZ2ljIGlzIGluIGhlcmUgaGFzIHRvIGJlIHN1cGVyIGxlYW4gb3Igd2UgcmlzayBkZXN0cm95aW5nIHRoZSBwZXJmb3JtYW5jZS5cblxuICAgICAgaWYgKHRoaXMubmdDb250cm9sLmRpc2FibGVkICE9PSB0aGlzLl9kaXNhYmxlZCkge1xuICAgICAgICB0aGlzLmRpc2FibGVkID0gISF0aGlzLm5nQ29udHJvbC5kaXNhYmxlZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9kZXN0cm95ZWQubmV4dCgpO1xuICAgIHRoaXMuX2Rlc3Ryb3llZC5jb21wbGV0ZSgpO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VzLmNvbXBsZXRlKCk7XG5cbiAgICB0aGlzLl9kcm9wU3Vic2NyaXB0aW9ucygpO1xuICB9XG5cbiAgLyoqIEFzc29jaWF0ZXMgYW4gSFRNTCBpbnB1dCBlbGVtZW50IHdpdGggdGhpcyBjaGlwIGxpc3QuICovXG4gIHJlZ2lzdGVySW5wdXQoaW5wdXRFbGVtZW50OiBHcmFuaXRlQ2hpcFRleHRDb250cm9sKTogdm9pZCB7XG4gICAgdGhpcy5fY2hpcElucHV0ID0gaW5wdXRFbGVtZW50O1xuXG4gICAgLy8gV2UgdXNlIHRoaXMgYXR0cmlidXRlIHRvIG1hdGNoIHRoZSBjaGlwIGxpc3QgdG8gaXRzIGlucHV0IGluIHRlc3QgaGFybmVzc2VzLlxuICAgIC8vIFNldCB0aGUgYXR0cmlidXRlIGRpcmVjdGx5IGhlcmUgdG8gYXZvaWQgXCJjaGFuZ2VkIGFmdGVyIGNoZWNrZWRcIiBlcnJvcnMuXG4gICAgdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnNldEF0dHJpYnV0ZShcbiAgICAgICdkYXRhLWdyYW5pdGUtY2hpcC1pbnB1dCcsXG4gICAgICBpbnB1dEVsZW1lbnQuaWRcbiAgICApO1xuICB9XG5cbiAgLy8gSW1wbGVtZW50ZWQgYXMgcGFydCBvZiBDb250cm9sVmFsdWVBY2Nlc3Nvci5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1tb2R1bGUtYm91bmRhcnktdHlwZXNcbiAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2hpcHMpIHtcbiAgICAgIHRoaXMuX3NldFNlbGVjdGlvbkJ5VmFsdWUodmFsdWUsIGZhbHNlKTtcbiAgICB9XG4gIH1cblxuICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IGFueSkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2hhbmdlID0gZm47XG4gIH1cblxuICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuX29uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgLy8gSW1wbGVtZW50ZWQgYXMgcGFydCBvZiBDb250cm9sVmFsdWVBY2Nlc3Nvci5cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvY3VzIGNoaXAgbGlzdCB3aGVuIGNsaWNrIG9uIHRoZSBjb250YWluZXIuXG4gICAqL1xuICBvbkNvbnRhaW5lckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl9vcmlnaW5hdGVzRnJvbUNoaXAoZXZlbnQpKSB7XG4gICAgICB0aGlzLmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZvY3VzZXMgdGhlIGZpcnN0IG5vbi1kaXNhYmxlZCBjaGlwIGluIHRoaXMgY2hpcCBsaXN0LCBvciB0aGUgYXNzb2NpYXRlZCBpbnB1dCB3aGVuIHRoZXJlXG4gICAqIGFyZSBubyBlbGlnaWJsZSBjaGlwcy5cbiAgICovXG4gIGZvY3VzKG9wdGlvbnM/OiBGb2N1c09wdGlvbnMpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEZvY3VzIG9uIGZpcnN0IGVsZW1lbnQgaWYgdGhlcmUncyBubyBjaGlwSW5wdXQgaW5zaWRlIGNoaXAtbGlzdFxuICAgIGlmICh0aGlzLl9jaGlwSW5wdXQgJiYgdGhpcy5fY2hpcElucHV0LmZvY3VzZWQpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICB9IGVsc2UgaWYgKHRoaXMuY2hpcHMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5fa2V5TWFuYWdlci5zZXRGaXJzdEl0ZW1BY3RpdmUoKTtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZm9jdXNJbnB1dChvcHRpb25zKTtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICB9XG4gIH1cblxuICAvKiogQXR0ZW1wdCB0byBmb2N1cyBhbiBpbnB1dCBpZiB3ZSBoYXZlIG9uZS4gKi9cbiAgX2ZvY3VzSW5wdXQob3B0aW9ucz86IEZvY3VzT3B0aW9ucyk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9jaGlwSW5wdXQpIHtcbiAgICAgIHRoaXMuX2NoaXBJbnB1dC5zZXRGb2N1cyhvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFzcyBldmVudHMgdG8gdGhlIGtleWJvYXJkIG1hbmFnZXIuIEF2YWlsYWJsZSBoZXJlIGZvciB0ZXN0cy5cbiAgICovXG4gIF9rZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgaWYgKHRhcmdldCAmJiB0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKCdncmFuaXRlLWNoaXAnKSkge1xuICAgICAgdGhpcy5fa2V5TWFuYWdlci5vbktleWRvd24oZXZlbnQpO1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBXaGVuIGJsdXJyZWQsIG1hcmsgdGhlIGZpZWxkIGFzIHRvdWNoZWQgd2hlbiBmb2N1cyBtb3ZlZCBvdXRzaWRlIHRoZSBjaGlwIGxpc3QuICovXG4gIF9ibHVyKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5faGFzRm9jdXNlZENoaXAoKSkge1xuICAgICAgdGhpcy5fa2V5TWFuYWdlci5zZXRBY3RpdmVJdGVtKC0xKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgIGlmICh0aGlzLl9jaGlwSW5wdXQpIHtcbiAgICAgICAgLy8gSWYgdGhlcmUncyBhIGNoaXAgaW5wdXQsIHdlIHNob3VsZCBjaGVjayB3aGV0aGVyIHRoZSBmb2N1cyBtb3ZlZCB0byBjaGlwIGlucHV0LlxuICAgICAgICAvLyBJZiB0aGUgZm9jdXMgaXMgbm90IG1vdmVkIHRvIGNoaXAgaW5wdXQsIG1hcmsgdGhlIGZpZWxkIGFzIHRvdWNoZWQuIElmIHRoZSBmb2N1cyBtb3ZlZFxuICAgICAgICAvLyB0byBjaGlwIGlucHV0LCBkbyBub3RoaW5nLlxuICAgICAgICAvLyBUaW1lb3V0IGlzIG5lZWRlZCB0byB3YWl0IGZvciB0aGUgZm9jdXMoKSBldmVudCB0cmlnZ2VyIG9uIGNoaXAgaW5wdXQuXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5mb2N1c2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gY2hpcCBpbnB1dCwgdGhlbiBtYXJrIHRoZSBmaWVsZCBhcyB0b3VjaGVkLlxuICAgICAgICB0aGlzLl9tYXJrQXNUb3VjaGVkKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIE1hcmsgdGhlIGZpZWxkIGFzIHRvdWNoZWQgKi9cbiAgX21hcmtBc1RvdWNoZWQoKTogdm9pZCB7XG4gICAgdGhpcy5fb25Ub3VjaGVkKCk7XG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGB0YWJpbmRleGAgZnJvbSB0aGUgY2hpcCBsaXN0IGFuZCByZXNldHMgaXQgYmFjayBhZnRlcndhcmRzLCBhbGxvd2luZyB0aGVcbiAgICogdXNlciB0byB0YWIgb3V0IG9mIGl0LiBUaGlzIHByZXZlbnRzIHRoZSBsaXN0IGZyb20gY2FwdHVyaW5nIGZvY3VzIGFuZCByZWRpcmVjdGluZ1xuICAgKiBpdCBiYWNrIHRvIHRoZSBmaXJzdCBjaGlwLCBjcmVhdGluZyBhIGZvY3VzIHRyYXAsIGlmIGl0IHVzZXIgdHJpZXMgdG8gdGFiIGF3YXkuXG4gICAqL1xuICBfYWxsb3dGb2N1c0VzY2FwZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fdGFiSW5kZXggIT09IC0xKSB7XG4gICAgICB0aGlzLl90YWJJbmRleCA9IC0xO1xuXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fdGFiSW5kZXggPSB0aGlzLl91c2VyVGFiSW5kZXggfHwgMDtcbiAgICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgdGhlIHRhYiBpbmRleCBhcyB5b3Ugc2hvdWxkIG5vdCBiZSBhbGxvd2VkIHRvIGZvY3VzIGFuIGVtcHR5IGxpc3QuXG4gICAqL1xuICBwcm90ZWN0ZWQgX3VwZGF0ZVRhYkluZGV4KCk6IHZvaWQge1xuICAgIC8vIElmIHdlIGhhdmUgMCBjaGlwcywgd2Ugc2hvdWxkIG5vdCBhbGxvdyBrZXlib2FyZCBmb2N1c1xuICAgIHRoaXMuX3RhYkluZGV4ID0gdGhpcy5fdXNlclRhYkluZGV4IHx8ICh0aGlzLmNoaXBzLmxlbmd0aCA9PT0gMCA/IC0xIDogMCk7XG4gIH1cblxuICAvKipcbiAgICogSWYgdGhlIGFtb3VudCBvZiBjaGlwcyBjaGFuZ2VkLCB3ZSBuZWVkIHRvIHVwZGF0ZSB0aGVcbiAgICoga2V5IG1hbmFnZXIgc3RhdGUgYW5kIGZvY3VzIHRoZSBuZXh0IGNsb3Nlc3QgY2hpcC5cbiAgICovXG4gIHByb3RlY3RlZCBfdXBkYXRlRm9jdXNGb3JEZXN0cm95ZWRDaGlwcygpOiB2b2lkIHtcbiAgICAvLyBNb3ZlIGZvY3VzIHRvIHRoZSBjbG9zZXN0IGNoaXAuIElmIG5vIG90aGVyIGNoaXBzIHJlbWFpbiwgZm9jdXMgdGhlIGNoaXAtbGlzdCBpdHNlbGYuXG4gICAgaWYgKHRoaXMuX2xhc3REZXN0cm95ZWRDaGlwSW5kZXggIT0gbnVsbCkge1xuICAgICAgaWYgKHRoaXMuY2hpcHMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IG5ld0NoaXBJbmRleCA9IE1hdGgubWluKFxuICAgICAgICAgIHRoaXMuX2xhc3REZXN0cm95ZWRDaGlwSW5kZXgsXG4gICAgICAgICAgdGhpcy5jaGlwcy5sZW5ndGggLSAxXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuX2tleU1hbmFnZXIuc2V0QWN0aXZlSXRlbShuZXdDaGlwSW5kZXgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mb2N1cygpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2xhc3REZXN0cm95ZWRDaGlwSW5kZXggPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFV0aWxpdHkgdG8gZW5zdXJlIGFsbCBpbmRleGVzIGFyZSB2YWxpZC5cbiAgICpcbiAgICogQHBhcmFtIGluZGV4IFRoZSBpbmRleCB0byBiZSBjaGVja2VkLlxuICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBpbmRleCBpcyB2YWxpZCBmb3Igb3VyIGxpc3Qgb2YgY2hpcHMuXG4gICAqL1xuICBwcml2YXRlIF9pc1ZhbGlkSW5kZXgoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpbmRleCA+PSAwICYmIGluZGV4IDwgdGhpcy5jaGlwcy5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIF9zZXRTZWxlY3Rpb25CeVZhbHVlKHZhbHVlOiBhbnksIGlzVXNlcklucHV0OiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xuICAgIHRoaXMuX2NsZWFyU2VsZWN0aW9uKCk7XG4gICAgdGhpcy5jaGlwcy5mb3JFYWNoKChjaGlwKSA9PiBjaGlwLmRlc2VsZWN0KCkpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICB2YWx1ZS5mb3JFYWNoKChjdXJyZW50VmFsdWUpID0+XG4gICAgICAgIHRoaXMuX3NlbGVjdFZhbHVlKGN1cnJlbnRWYWx1ZSwgaXNVc2VySW5wdXQpXG4gICAgICApO1xuICAgICAgdGhpcy5fc29ydFZhbHVlcygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjb3JyZXNwb25kaW5nQ2hpcCA9IHRoaXMuX3NlbGVjdFZhbHVlKHZhbHVlLCBpc1VzZXJJbnB1dCk7XG5cbiAgICAgIC8vIFNoaWZ0IGZvY3VzIHRvIHRoZSBhY3RpdmUgaXRlbS4gTm90ZSB0aGF0IHdlIHNob3VsZG4ndCBkbyB0aGlzIGluIG11bHRpc2VsZWN0XG4gICAgICAvLyBtb2RlLCBiZWNhdXNlIHdlIGRvbid0IGtub3cgd2hhdCBjaGlwIHRoZSB1c2VyIGludGVyYWN0ZWQgd2l0aCBsYXN0LlxuICAgICAgaWYgKGNvcnJlc3BvbmRpbmdDaGlwKSB7XG4gICAgICAgIGlmIChpc1VzZXJJbnB1dCkge1xuICAgICAgICAgIHRoaXMuX2tleU1hbmFnZXIuc2V0QWN0aXZlSXRlbShjb3JyZXNwb25kaW5nQ2hpcCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgYW5kIHNlbGVjdHMgdGhlIGNoaXAgYmFzZWQgb24gaXRzIHZhbHVlLlxuICAgKiBAcmV0dXJucyBDaGlwIHRoYXQgaGFzIHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlLlxuICAgKi9cbiAgcHJpdmF0ZSBfc2VsZWN0VmFsdWUoXG4gICAgdmFsdWU6IGFueSxcbiAgICBpc1VzZXJJbnB1dDogYm9vbGVhbiA9IHRydWVcbiAgKTogR3Jhbml0ZUNoaXBDb21wb25lbnQgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNvcnJlc3BvbmRpbmdDaGlwID0gdGhpcy5jaGlwcy5maW5kKChjaGlwKSA9PiB7XG4gICAgICByZXR1cm4gY2hpcC52YWx1ZSAhPSBudWxsICYmIHRoaXMuX2NvbXBhcmVXaXRoKGNoaXAudmFsdWUsIHZhbHVlKTtcbiAgICB9KTtcblxuICAgIGlmIChjb3JyZXNwb25kaW5nQ2hpcCkge1xuICAgICAgY29ycmVzcG9uZGluZ0NoaXAuc2VsZWN0KGlzVXNlcklucHV0KTtcbiAgICAgIHRoaXMuX3NlbGVjdGlvbk1vZGVsLnNlbGVjdChjb3JyZXNwb25kaW5nQ2hpcCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvcnJlc3BvbmRpbmdDaGlwO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdGlhbGl6ZVNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICAvLyBEZWZlciBzZXR0aW5nIHRoZSB2YWx1ZSBpbiBvcmRlciB0byBhdm9pZCB0aGUgXCJFeHByZXNzaW9uXG4gICAgLy8gaGFzIGNoYW5nZWQgYWZ0ZXIgaXQgd2FzIGNoZWNrZWRcIiBlcnJvcnMgZnJvbSBBbmd1bGFyLlxuICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKHRoaXMubmdDb250cm9sKSB7XG4gICAgICAgIHRoaXMuX3NldFNlbGVjdGlvbkJ5VmFsdWUodGhpcy5uZ0NvbnRyb2wudmFsdWUsIGZhbHNlKTtcbiAgICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIERlc2VsZWN0cyBldmVyeSBjaGlwIGluIHRoZSBsaXN0LlxuICAgKiBAcGFyYW0gc2tpcCBDaGlwIHRoYXQgc2hvdWxkIG5vdCBiZSBkZXNlbGVjdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfY2xlYXJTZWxlY3Rpb24oc2tpcD86IEdyYW5pdGVDaGlwQ29tcG9uZW50KTogdm9pZCB7XG4gICAgdGhpcy5fc2VsZWN0aW9uTW9kZWwuY2xlYXIoKTtcbiAgICB0aGlzLmNoaXBzLmZvckVhY2goKGNoaXApID0+IHtcbiAgICAgIGlmIChjaGlwICE9PSBza2lwKSB7XG4gICAgICAgIGNoaXAuZGVzZWxlY3QoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogU29ydHMgdGhlIG1vZGVsIHZhbHVlcywgZW5zdXJpbmcgdGhhdCB0aGV5IGtlZXAgdGhlIHNhbWVcbiAgICogb3JkZXIgdGhhdCB0aGV5IGhhdmUgaW4gdGhlIHBhbmVsLlxuICAgKi9cbiAgcHJpdmF0ZSBfc29ydFZhbHVlcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fbXVsdGlwbGUpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGlvbk1vZGVsLmNsZWFyKCk7XG5cbiAgICAgIHRoaXMuY2hpcHMuZm9yRWFjaCgoY2hpcCkgPT4ge1xuICAgICAgICBpZiAoY2hpcC5zZWxlY3RlZCkge1xuICAgICAgICAgIHRoaXMuX3NlbGVjdGlvbk1vZGVsLnNlbGVjdChjaGlwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfY29tcGFyZVdpdGggPSAobzE6IGFueSwgbzI6IGFueSkgPT4gbzEgPT09IG8yO1xuXG4gIHByaXZhdGUgX3Jlc2V0Q2hpcHMoKTogdm9pZCB7XG4gICAgdGhpcy5fZHJvcFN1YnNjcmlwdGlvbnMoKTtcbiAgICB0aGlzLl9saXN0ZW5Ub0NoaXBzRm9jdXMoKTtcbiAgICB0aGlzLl9saXN0ZW5Ub0NoaXBzU2VsZWN0aW9uKCk7XG4gICAgdGhpcy5fbGlzdGVuVG9DaGlwc1JlbW92ZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgX2Ryb3BTdWJzY3JpcHRpb25zKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9jaGlwRm9jdXNTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX2NoaXBGb2N1c1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5fY2hpcEZvY3VzU3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY2hpcEJsdXJTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX2NoaXBCbHVyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLl9jaGlwQmx1clN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NoaXBTZWxlY3Rpb25TdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX2NoaXBTZWxlY3Rpb25TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuX2NoaXBTZWxlY3Rpb25TdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jaGlwUmVtb3ZlU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9jaGlwUmVtb3ZlU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLl9jaGlwUmVtb3ZlU3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKiogTGlzdGVucyB0byB1c2VyLWdlbmVyYXRlZCBzZWxlY3Rpb24gZXZlbnRzIG9uIGVhY2ggY2hpcC4gKi9cbiAgcHJpdmF0ZSBfbGlzdGVuVG9DaGlwc1NlbGVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLl9jaGlwU2VsZWN0aW9uU3Vic2NyaXB0aW9uID0gdGhpcy5jaGlwU2VsZWN0aW9uQ2hhbmdlcy5zdWJzY3JpYmUoXG4gICAgICAoZXZlbnQpID0+IHtcbiAgICAgICAgZXZlbnQuc291cmNlLnNlbGVjdGVkXG4gICAgICAgICAgPyB0aGlzLl9zZWxlY3Rpb25Nb2RlbC5zZWxlY3QoZXZlbnQuc291cmNlKVxuICAgICAgICAgIDogdGhpcy5fc2VsZWN0aW9uTW9kZWwuZGVzZWxlY3QoZXZlbnQuc291cmNlKTtcblxuICAgICAgICAvLyBGb3Igc2luZ2xlIHNlbGVjdGlvbiBjaGlwIGxpc3QsIG1ha2Ugc3VyZSB0aGUgZGVzZWxlY3RlZCB2YWx1ZSBpcyB1bnNlbGVjdGVkLlxuICAgICAgICBpZiAoIXRoaXMubXVsdGlzZWxlY3QpIHtcbiAgICAgICAgICB0aGlzLmNoaXBzLmZvckVhY2goKGNoaXApID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fc2VsZWN0aW9uTW9kZWwuaXNTZWxlY3RlZChjaGlwKSAmJiBjaGlwLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgIGNoaXAuZGVzZWxlY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKiogTGlzdGVucyB0byB1c2VyLWdlbmVyYXRlZCBzZWxlY3Rpb24gZXZlbnRzIG9uIGVhY2ggY2hpcC4gKi9cbiAgcHJpdmF0ZSBfbGlzdGVuVG9DaGlwc0ZvY3VzKCk6IHZvaWQge1xuICAgIHRoaXMuX2NoaXBGb2N1c1N1YnNjcmlwdGlvbiA9IHRoaXMuY2hpcEZvY3VzQ2hhbmdlcy5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBjaGlwSW5kZXg6IG51bWJlciA9IHRoaXMuY2hpcHMudG9BcnJheSgpLmluZGV4T2YoZXZlbnQuY2hpcCk7XG5cbiAgICAgIGlmICh0aGlzLl9pc1ZhbGlkSW5kZXgoY2hpcEluZGV4KSkge1xuICAgICAgICB0aGlzLl9rZXlNYW5hZ2VyLnVwZGF0ZUFjdGl2ZUl0ZW0oY2hpcEluZGV4KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2NoaXBCbHVyU3Vic2NyaXB0aW9uID0gdGhpcy5jaGlwQmx1ckNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuX2JsdXIoKTtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2xpc3RlblRvQ2hpcHNSZW1vdmVkKCk6IHZvaWQge1xuICAgIHRoaXMuX2NoaXBSZW1vdmVTdWJzY3JpcHRpb24gPSB0aGlzLmNoaXBSZW1vdmVDaGFuZ2VzLnN1YnNjcmliZSgoZXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGNoaXAgPSBldmVudC5jaGlwO1xuICAgICAgY29uc3QgY2hpcEluZGV4ID0gdGhpcy5jaGlwcy50b0FycmF5KCkuaW5kZXhPZihldmVudC5jaGlwKTtcblxuICAgICAgLy8gSW4gY2FzZSB0aGUgY2hpcCB0aGF0IHdpbGwgYmUgcmVtb3ZlZCBpcyBjdXJyZW50bHkgZm9jdXNlZCwgd2UgdGVtcG9yYXJpbHkgc3RvcmVcbiAgICAgIC8vIHRoZSBpbmRleCBpbiBvcmRlciB0byBiZSBhYmxlIHRvIGRldGVybWluZSBhbiBhcHByb3ByaWF0ZSBzaWJsaW5nIGNoaXAgdGhhdCB3aWxsXG4gICAgICAvLyByZWNlaXZlIGZvY3VzLlxuICAgICAgaWYgKHRoaXMuX2lzVmFsaWRJbmRleChjaGlwSW5kZXgpICYmIGNoaXAuX2hhc0ZvY3VzKSB7XG4gICAgICAgIHRoaXMuX2xhc3REZXN0cm95ZWRDaGlwSW5kZXggPSBjaGlwSW5kZXg7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKiogQ2hlY2tzIHdoZXRoZXIgYW4gZXZlbnQgY29tZXMgZnJvbSBpbnNpZGUgYSBjaGlwIGVsZW1lbnQuICovXG4gIHByaXZhdGUgX29yaWdpbmF0ZXNGcm9tQ2hpcChldmVudDogRXZlbnQpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudEVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuXG4gICAgd2hpbGUgKFxuICAgICAgY3VycmVudEVsZW1lbnQgJiZcbiAgICAgIGN1cnJlbnRFbGVtZW50ICE9PSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnRcbiAgICApIHtcbiAgICAgIGlmIChjdXJyZW50RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2dyYW5pdGUtY2hpcCcpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBjdXJyZW50RWxlbWVudCA9IGN1cnJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIENoZWNrcyB3aGV0aGVyIGFueSBvZiB0aGUgY2hpcHMgaXMgZm9jdXNlZC4gKi9cbiAgcHJpdmF0ZSBfaGFzRm9jdXNlZENoaXAoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2hpcHMgJiYgdGhpcy5jaGlwcy5zb21lKChjaGlwKSA9PiBjaGlwLl9oYXNGb2N1cyk7XG4gIH1cblxuICAvKiogU3luY3MgdGhlIGxpc3QncyBzdGF0ZSB3aXRoIHRoZSBpbmRpdmlkdWFsIGNoaXBzLiAqL1xuICBwcml2YXRlIF9zeW5jQ2hpcHNTdGF0ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jaGlwcykge1xuICAgICAgdGhpcy5jaGlwcy5mb3JFYWNoKChjaGlwKSA9PiB7XG4gICAgICAgIGNoaXAuX2NoaXBMaXN0RGlzYWJsZWQgPSB0aGlzLl9kaXNhYmxlZDtcbiAgICAgICAgY2hpcC5fY2hpcExpc3RNdWx0aXBsZSA9IHRoaXMubXVsdGlzZWxlY3Q7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==