1 | /**
|
---|
2 | * @license
|
---|
3 | * Copyright Google LLC All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Use of this source code is governed by an MIT-style license that can be
|
---|
6 | * found in the LICENSE file at https://angular.io/license
|
---|
7 | */
|
---|
8 | import { FocusKeyManager } from '@angular/cdk/a11y';
|
---|
9 | import { Directionality } from '@angular/cdk/bidi';
|
---|
10 | import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
|
---|
11 | import { ENTER, hasModifierKey, SPACE } from '@angular/cdk/keycodes';
|
---|
12 | import { DOCUMENT } from '@angular/common';
|
---|
13 | import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, Inject, InjectionToken, Input, Optional, Output, QueryList, TemplateRef, ViewChild, ViewEncapsulation, } from '@angular/core';
|
---|
14 | import { _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
|
---|
15 | import { of as observableOf, Subject } from 'rxjs';
|
---|
16 | import { startWith, takeUntil } from 'rxjs/operators';
|
---|
17 | import { CdkStepHeader } from './step-header';
|
---|
18 | import { CdkStepLabel } from './step-label';
|
---|
19 | /** Used to generate unique ID for each stepper component. */
|
---|
20 | let nextId = 0;
|
---|
21 | /** Change event emitted on selection changes. */
|
---|
22 | export class StepperSelectionEvent {
|
---|
23 | }
|
---|
24 | /** Enum to represent the different states of the steps. */
|
---|
25 | export const STEP_STATE = {
|
---|
26 | NUMBER: 'number',
|
---|
27 | EDIT: 'edit',
|
---|
28 | DONE: 'done',
|
---|
29 | ERROR: 'error'
|
---|
30 | };
|
---|
31 | /** InjectionToken that can be used to specify the global stepper options. */
|
---|
32 | export const STEPPER_GLOBAL_OPTIONS = new InjectionToken('STEPPER_GLOBAL_OPTIONS');
|
---|
33 | export class CdkStep {
|
---|
34 | constructor(_stepper, stepperOptions) {
|
---|
35 | this._stepper = _stepper;
|
---|
36 | /** Whether user has attempted to move away from the step. */
|
---|
37 | this.interacted = false;
|
---|
38 | /** Emits when the user has attempted to move away from the step. */
|
---|
39 | this.interactedStream = new EventEmitter();
|
---|
40 | this._editable = true;
|
---|
41 | this._optional = false;
|
---|
42 | this._completedOverride = null;
|
---|
43 | this._customError = null;
|
---|
44 | this._stepperOptions = stepperOptions ? stepperOptions : {};
|
---|
45 | this._displayDefaultIndicatorType = this._stepperOptions.displayDefaultIndicatorType !== false;
|
---|
46 | }
|
---|
47 | /** Whether the user can return to this step once it has been marked as completed. */
|
---|
48 | get editable() {
|
---|
49 | return this._editable;
|
---|
50 | }
|
---|
51 | set editable(value) {
|
---|
52 | this._editable = coerceBooleanProperty(value);
|
---|
53 | }
|
---|
54 | /** Whether the completion of step is optional. */
|
---|
55 | get optional() {
|
---|
56 | return this._optional;
|
---|
57 | }
|
---|
58 | set optional(value) {
|
---|
59 | this._optional = coerceBooleanProperty(value);
|
---|
60 | }
|
---|
61 | /** Whether step is marked as completed. */
|
---|
62 | get completed() {
|
---|
63 | return this._completedOverride == null ? this._getDefaultCompleted() : this._completedOverride;
|
---|
64 | }
|
---|
65 | set completed(value) {
|
---|
66 | this._completedOverride = coerceBooleanProperty(value);
|
---|
67 | }
|
---|
68 | _getDefaultCompleted() {
|
---|
69 | return this.stepControl ? this.stepControl.valid && this.interacted : this.interacted;
|
---|
70 | }
|
---|
71 | /** Whether step has an error. */
|
---|
72 | get hasError() {
|
---|
73 | return this._customError == null ? this._getDefaultError() : this._customError;
|
---|
74 | }
|
---|
75 | set hasError(value) {
|
---|
76 | this._customError = coerceBooleanProperty(value);
|
---|
77 | }
|
---|
78 | _getDefaultError() {
|
---|
79 | return this.stepControl && this.stepControl.invalid && this.interacted;
|
---|
80 | }
|
---|
81 | /** Selects this step component. */
|
---|
82 | select() {
|
---|
83 | this._stepper.selected = this;
|
---|
84 | }
|
---|
85 | /** Resets the step to its initial state. Note that this includes resetting form data. */
|
---|
86 | reset() {
|
---|
87 | this.interacted = false;
|
---|
88 | if (this._completedOverride != null) {
|
---|
89 | this._completedOverride = false;
|
---|
90 | }
|
---|
91 | if (this._customError != null) {
|
---|
92 | this._customError = false;
|
---|
93 | }
|
---|
94 | if (this.stepControl) {
|
---|
95 | this.stepControl.reset();
|
---|
96 | }
|
---|
97 | }
|
---|
98 | ngOnChanges() {
|
---|
99 | // Since basically all inputs of the MatStep get proxied through the view down to the
|
---|
100 | // underlying MatStepHeader, we have to make sure that change detection runs correctly.
|
---|
101 | this._stepper._stateChanged();
|
---|
102 | }
|
---|
103 | _markAsInteracted() {
|
---|
104 | if (!this.interacted) {
|
---|
105 | this.interacted = true;
|
---|
106 | this.interactedStream.emit(this);
|
---|
107 | }
|
---|
108 | }
|
---|
109 | /** Determines whether the error state can be shown. */
|
---|
110 | _showError() {
|
---|
111 | var _a;
|
---|
112 | // We want to show the error state either if the user opted into/out of it using the
|
---|
113 | // global options, or if they've explicitly set it through the `hasError` input.
|
---|
114 | return (_a = this._stepperOptions.showError) !== null && _a !== void 0 ? _a : this._customError != null;
|
---|
115 | }
|
---|
116 | }
|
---|
117 | CdkStep.decorators = [
|
---|
118 | { type: Component, args: [{
|
---|
119 | selector: 'cdk-step',
|
---|
120 | exportAs: 'cdkStep',
|
---|
121 | template: '<ng-template><ng-content></ng-content></ng-template>',
|
---|
122 | encapsulation: ViewEncapsulation.None,
|
---|
123 | changeDetection: ChangeDetectionStrategy.OnPush
|
---|
124 | },] }
|
---|
125 | ];
|
---|
126 | CdkStep.ctorParameters = () => [
|
---|
127 | { type: CdkStepper, decorators: [{ type: Inject, args: [forwardRef(() => CdkStepper),] }] },
|
---|
128 | { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [STEPPER_GLOBAL_OPTIONS,] }] }
|
---|
129 | ];
|
---|
130 | CdkStep.propDecorators = {
|
---|
131 | stepLabel: [{ type: ContentChild, args: [CdkStepLabel,] }],
|
---|
132 | content: [{ type: ViewChild, args: [TemplateRef, { static: true },] }],
|
---|
133 | stepControl: [{ type: Input }],
|
---|
134 | interactedStream: [{ type: Output, args: ['interacted',] }],
|
---|
135 | label: [{ type: Input }],
|
---|
136 | errorMessage: [{ type: Input }],
|
---|
137 | ariaLabel: [{ type: Input, args: ['aria-label',] }],
|
---|
138 | ariaLabelledby: [{ type: Input, args: ['aria-labelledby',] }],
|
---|
139 | state: [{ type: Input }],
|
---|
140 | editable: [{ type: Input }],
|
---|
141 | optional: [{ type: Input }],
|
---|
142 | completed: [{ type: Input }],
|
---|
143 | hasError: [{ type: Input }]
|
---|
144 | };
|
---|
145 | export class CdkStepper {
|
---|
146 | constructor(_dir, _changeDetectorRef, _elementRef,
|
---|
147 | /**
|
---|
148 | * @deprecated No longer in use, to be removed.
|
---|
149 | * @breaking-change 13.0.0
|
---|
150 | */
|
---|
151 | _document) {
|
---|
152 | this._dir = _dir;
|
---|
153 | this._changeDetectorRef = _changeDetectorRef;
|
---|
154 | this._elementRef = _elementRef;
|
---|
155 | /** Emits when the component is destroyed. */
|
---|
156 | this._destroyed = new Subject();
|
---|
157 | /** Steps that belong to the current stepper, excluding ones from nested steppers. */
|
---|
158 | this.steps = new QueryList();
|
---|
159 | /** List of step headers sorted based on their DOM order. */
|
---|
160 | this._sortedHeaders = new QueryList();
|
---|
161 | this._linear = false;
|
---|
162 | this._selectedIndex = 0;
|
---|
163 | /** Event emitted when the selected step has changed. */
|
---|
164 | this.selectionChange = new EventEmitter();
|
---|
165 | /**
|
---|
166 | * @deprecated To be turned into a private property. Use `orientation` instead.
|
---|
167 | * @breaking-change 13.0.0
|
---|
168 | */
|
---|
169 | this._orientation = 'horizontal';
|
---|
170 | this._groupId = nextId++;
|
---|
171 | }
|
---|
172 | /** Whether the validity of previous steps should be checked or not. */
|
---|
173 | get linear() {
|
---|
174 | return this._linear;
|
---|
175 | }
|
---|
176 | set linear(value) {
|
---|
177 | this._linear = coerceBooleanProperty(value);
|
---|
178 | }
|
---|
179 | /** The index of the selected step. */
|
---|
180 | get selectedIndex() {
|
---|
181 | return this._selectedIndex;
|
---|
182 | }
|
---|
183 | set selectedIndex(index) {
|
---|
184 | var _a;
|
---|
185 | const newIndex = coerceNumberProperty(index);
|
---|
186 | if (this.steps && this._steps) {
|
---|
187 | // Ensure that the index can't be out of bounds.
|
---|
188 | if (!this._isValidIndex(index) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
---|
189 | throw Error('cdkStepper: Cannot assign out-of-bounds value to `selectedIndex`.');
|
---|
190 | }
|
---|
191 | (_a = this.selected) === null || _a === void 0 ? void 0 : _a._markAsInteracted();
|
---|
192 | if (this._selectedIndex !== newIndex && !this._anyControlsInvalidOrPending(newIndex) &&
|
---|
193 | (newIndex >= this._selectedIndex || this.steps.toArray()[newIndex].editable)) {
|
---|
194 | this._updateSelectedItemIndex(index);
|
---|
195 | }
|
---|
196 | }
|
---|
197 | else {
|
---|
198 | this._selectedIndex = newIndex;
|
---|
199 | }
|
---|
200 | }
|
---|
201 | /** The step that is selected. */
|
---|
202 | get selected() {
|
---|
203 | return this.steps ? this.steps.toArray()[this.selectedIndex] : undefined;
|
---|
204 | }
|
---|
205 | set selected(step) {
|
---|
206 | this.selectedIndex = (step && this.steps) ? this.steps.toArray().indexOf(step) : -1;
|
---|
207 | }
|
---|
208 | /** Orientation of the stepper. */
|
---|
209 | get orientation() { return this._orientation; }
|
---|
210 | set orientation(value) {
|
---|
211 | // This is a protected method so that `MatSteppter` can hook into it.
|
---|
212 | this._orientation = value;
|
---|
213 | if (this._keyManager) {
|
---|
214 | this._keyManager.withVerticalOrientation(value === 'vertical');
|
---|
215 | }
|
---|
216 | }
|
---|
217 | ngAfterContentInit() {
|
---|
218 | this._steps.changes
|
---|
219 | .pipe(startWith(this._steps), takeUntil(this._destroyed))
|
---|
220 | .subscribe((steps) => {
|
---|
221 | this.steps.reset(steps.filter(step => step._stepper === this));
|
---|
222 | this.steps.notifyOnChanges();
|
---|
223 | });
|
---|
224 | }
|
---|
225 | ngAfterViewInit() {
|
---|
226 | // If the step headers are defined outside of the `ngFor` that renders the steps, like in the
|
---|
227 | // Material stepper, they won't appear in the `QueryList` in the same order as they're
|
---|
228 | // rendered in the DOM which will lead to incorrect keyboard navigation. We need to sort
|
---|
229 | // them manually to ensure that they're correct. Alternatively, we can change the Material
|
---|
230 | // template to inline the headers in the `ngFor`, but that'll result in a lot of
|
---|
231 | // code duplciation. See #23539.
|
---|
232 | this._stepHeader.changes
|
---|
233 | .pipe(startWith(this._stepHeader), takeUntil(this._destroyed))
|
---|
234 | .subscribe((headers) => {
|
---|
235 | this._sortedHeaders.reset(headers.toArray().sort((a, b) => {
|
---|
236 | const documentPosition = a._elementRef.nativeElement.compareDocumentPosition(b._elementRef.nativeElement);
|
---|
237 | // `compareDocumentPosition` returns a bitmask so we have to use a bitwise operator.
|
---|
238 | // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
---|
239 | // tslint:disable-next-line:no-bitwise
|
---|
240 | return documentPosition & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
|
---|
241 | }));
|
---|
242 | this._sortedHeaders.notifyOnChanges();
|
---|
243 | });
|
---|
244 | // Note that while the step headers are content children by default, any components that
|
---|
245 | // extend this one might have them as view children. We initialize the keyboard handling in
|
---|
246 | // AfterViewInit so we're guaranteed for both view and content children to be defined.
|
---|
247 | this._keyManager = new FocusKeyManager(this._sortedHeaders)
|
---|
248 | .withWrap()
|
---|
249 | .withHomeAndEnd()
|
---|
250 | .withVerticalOrientation(this._orientation === 'vertical');
|
---|
251 | (this._dir ? this._dir.change : observableOf())
|
---|
252 | .pipe(startWith(this._layoutDirection()), takeUntil(this._destroyed))
|
---|
253 | .subscribe(direction => this._keyManager.withHorizontalOrientation(direction));
|
---|
254 | this._keyManager.updateActiveItem(this._selectedIndex);
|
---|
255 | // No need to `takeUntil` here, because we're the ones destroying `steps`.
|
---|
256 | this.steps.changes.subscribe(() => {
|
---|
257 | if (!this.selected) {
|
---|
258 | this._selectedIndex = Math.max(this._selectedIndex - 1, 0);
|
---|
259 | }
|
---|
260 | });
|
---|
261 | // The logic which asserts that the selected index is within bounds doesn't run before the
|
---|
262 | // steps are initialized, because we don't how many steps there are yet so we may have an
|
---|
263 | // invalid index on init. If that's the case, auto-correct to the default so we don't throw.
|
---|
264 | if (!this._isValidIndex(this._selectedIndex)) {
|
---|
265 | this._selectedIndex = 0;
|
---|
266 | }
|
---|
267 | }
|
---|
268 | ngOnDestroy() {
|
---|
269 | this.steps.destroy();
|
---|
270 | this._sortedHeaders.destroy();
|
---|
271 | this._destroyed.next();
|
---|
272 | this._destroyed.complete();
|
---|
273 | }
|
---|
274 | /** Selects and focuses the next step in list. */
|
---|
275 | next() {
|
---|
276 | this.selectedIndex = Math.min(this._selectedIndex + 1, this.steps.length - 1);
|
---|
277 | }
|
---|
278 | /** Selects and focuses the previous step in list. */
|
---|
279 | previous() {
|
---|
280 | this.selectedIndex = Math.max(this._selectedIndex - 1, 0);
|
---|
281 | }
|
---|
282 | /** Resets the stepper to its initial state. Note that this includes clearing form data. */
|
---|
283 | reset() {
|
---|
284 | this._updateSelectedItemIndex(0);
|
---|
285 | this.steps.forEach(step => step.reset());
|
---|
286 | this._stateChanged();
|
---|
287 | }
|
---|
288 | /** Returns a unique id for each step label element. */
|
---|
289 | _getStepLabelId(i) {
|
---|
290 | return `cdk-step-label-${this._groupId}-${i}`;
|
---|
291 | }
|
---|
292 | /** Returns unique id for each step content element. */
|
---|
293 | _getStepContentId(i) {
|
---|
294 | return `cdk-step-content-${this._groupId}-${i}`;
|
---|
295 | }
|
---|
296 | /** Marks the component to be change detected. */
|
---|
297 | _stateChanged() {
|
---|
298 | this._changeDetectorRef.markForCheck();
|
---|
299 | }
|
---|
300 | /** Returns position state of the step with the given index. */
|
---|
301 | _getAnimationDirection(index) {
|
---|
302 | const position = index - this._selectedIndex;
|
---|
303 | if (position < 0) {
|
---|
304 | return this._layoutDirection() === 'rtl' ? 'next' : 'previous';
|
---|
305 | }
|
---|
306 | else if (position > 0) {
|
---|
307 | return this._layoutDirection() === 'rtl' ? 'previous' : 'next';
|
---|
308 | }
|
---|
309 | return 'current';
|
---|
310 | }
|
---|
311 | /** Returns the type of icon to be displayed. */
|
---|
312 | _getIndicatorType(index, state = STEP_STATE.NUMBER) {
|
---|
313 | const step = this.steps.toArray()[index];
|
---|
314 | const isCurrentStep = this._isCurrentStep(index);
|
---|
315 | return step._displayDefaultIndicatorType ? this._getDefaultIndicatorLogic(step, isCurrentStep) :
|
---|
316 | this._getGuidelineLogic(step, isCurrentStep, state);
|
---|
317 | }
|
---|
318 | _getDefaultIndicatorLogic(step, isCurrentStep) {
|
---|
319 | if (step._showError() && step.hasError && !isCurrentStep) {
|
---|
320 | return STEP_STATE.ERROR;
|
---|
321 | }
|
---|
322 | else if (!step.completed || isCurrentStep) {
|
---|
323 | return STEP_STATE.NUMBER;
|
---|
324 | }
|
---|
325 | else {
|
---|
326 | return step.editable ? STEP_STATE.EDIT : STEP_STATE.DONE;
|
---|
327 | }
|
---|
328 | }
|
---|
329 | _getGuidelineLogic(step, isCurrentStep, state = STEP_STATE.NUMBER) {
|
---|
330 | if (step._showError() && step.hasError && !isCurrentStep) {
|
---|
331 | return STEP_STATE.ERROR;
|
---|
332 | }
|
---|
333 | else if (step.completed && !isCurrentStep) {
|
---|
334 | return STEP_STATE.DONE;
|
---|
335 | }
|
---|
336 | else if (step.completed && isCurrentStep) {
|
---|
337 | return state;
|
---|
338 | }
|
---|
339 | else if (step.editable && isCurrentStep) {
|
---|
340 | return STEP_STATE.EDIT;
|
---|
341 | }
|
---|
342 | else {
|
---|
343 | return state;
|
---|
344 | }
|
---|
345 | }
|
---|
346 | _isCurrentStep(index) {
|
---|
347 | return this._selectedIndex === index;
|
---|
348 | }
|
---|
349 | /** Returns the index of the currently-focused step header. */
|
---|
350 | _getFocusIndex() {
|
---|
351 | return this._keyManager ? this._keyManager.activeItemIndex : this._selectedIndex;
|
---|
352 | }
|
---|
353 | _updateSelectedItemIndex(newIndex) {
|
---|
354 | const stepsArray = this.steps.toArray();
|
---|
355 | this.selectionChange.emit({
|
---|
356 | selectedIndex: newIndex,
|
---|
357 | previouslySelectedIndex: this._selectedIndex,
|
---|
358 | selectedStep: stepsArray[newIndex],
|
---|
359 | previouslySelectedStep: stepsArray[this._selectedIndex],
|
---|
360 | });
|
---|
361 | // If focus is inside the stepper, move it to the next header, otherwise it may become
|
---|
362 | // lost when the active step content is hidden. We can't be more granular with the check
|
---|
363 | // (e.g. checking whether focus is inside the active step), because we don't have a
|
---|
364 | // reference to the elements that are rendering out the content.
|
---|
365 | this._containsFocus() ? this._keyManager.setActiveItem(newIndex) :
|
---|
366 | this._keyManager.updateActiveItem(newIndex);
|
---|
367 | this._selectedIndex = newIndex;
|
---|
368 | this._stateChanged();
|
---|
369 | }
|
---|
370 | _onKeydown(event) {
|
---|
371 | const hasModifier = hasModifierKey(event);
|
---|
372 | const keyCode = event.keyCode;
|
---|
373 | const manager = this._keyManager;
|
---|
374 | if (manager.activeItemIndex != null && !hasModifier &&
|
---|
375 | (keyCode === SPACE || keyCode === ENTER)) {
|
---|
376 | this.selectedIndex = manager.activeItemIndex;
|
---|
377 | event.preventDefault();
|
---|
378 | }
|
---|
379 | else {
|
---|
380 | manager.onKeydown(event);
|
---|
381 | }
|
---|
382 | }
|
---|
383 | _anyControlsInvalidOrPending(index) {
|
---|
384 | if (this._linear && index >= 0) {
|
---|
385 | return this.steps.toArray().slice(0, index).some(step => {
|
---|
386 | const control = step.stepControl;
|
---|
387 | const isIncomplete = control ? (control.invalid || control.pending || !step.interacted) : !step.completed;
|
---|
388 | return isIncomplete && !step.optional && !step._completedOverride;
|
---|
389 | });
|
---|
390 | }
|
---|
391 | return false;
|
---|
392 | }
|
---|
393 | _layoutDirection() {
|
---|
394 | return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
|
---|
395 | }
|
---|
396 | /** Checks whether the stepper contains the focused element. */
|
---|
397 | _containsFocus() {
|
---|
398 | const stepperElement = this._elementRef.nativeElement;
|
---|
399 | const focusedElement = _getFocusedElementPierceShadowDom();
|
---|
400 | return stepperElement === focusedElement || stepperElement.contains(focusedElement);
|
---|
401 | }
|
---|
402 | /** Checks whether the passed-in index is a valid step index. */
|
---|
403 | _isValidIndex(index) {
|
---|
404 | return index > -1 && (!this.steps || index < this.steps.length);
|
---|
405 | }
|
---|
406 | }
|
---|
407 | CdkStepper.decorators = [
|
---|
408 | { type: Directive, args: [{
|
---|
409 | selector: '[cdkStepper]',
|
---|
410 | exportAs: 'cdkStepper',
|
---|
411 | },] }
|
---|
412 | ];
|
---|
413 | CdkStepper.ctorParameters = () => [
|
---|
414 | { type: Directionality, decorators: [{ type: Optional }] },
|
---|
415 | { type: ChangeDetectorRef },
|
---|
416 | { type: ElementRef },
|
---|
417 | { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
|
---|
418 | ];
|
---|
419 | CdkStepper.propDecorators = {
|
---|
420 | _steps: [{ type: ContentChildren, args: [CdkStep, { descendants: true },] }],
|
---|
421 | _stepHeader: [{ type: ContentChildren, args: [CdkStepHeader, { descendants: true },] }],
|
---|
422 | linear: [{ type: Input }],
|
---|
423 | selectedIndex: [{ type: Input }],
|
---|
424 | selected: [{ type: Input }],
|
---|
425 | selectionChange: [{ type: Output }],
|
---|
426 | orientation: [{ type: Input }]
|
---|
427 | };
|
---|
428 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcHBlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jZGsvc3RlcHBlci9zdGVwcGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBa0IsZUFBZSxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDbkUsT0FBTyxFQUFZLGNBQWMsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQzVELE9BQU8sRUFFTCxxQkFBcUIsRUFDckIsb0JBQW9CLEVBRXJCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFDLEtBQUssRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDbkUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixNQUFNLEVBQ04sY0FBYyxFQUNkLEtBQUssRUFHTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFNBQVMsRUFDVCxXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixHQUVsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsaUNBQWlDLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RSxPQUFPLEVBQWEsRUFBRSxJQUFJLFlBQVksRUFBRSxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDN0QsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUVwRCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzVDLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFMUMsNkRBQTZEO0FBQzdELElBQUksTUFBTSxHQUFHLENBQUMsQ0FB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S0FBSzs0QkFVTCxLQUFLO3VCQTBCTCxLQUFLOzhCQVNMLE1BQU07MEJBTU4sS0FBSyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0ZvY3VzYWJsZU9wdGlvbiwgRm9jdXNLZXlNYW5hZ2VyfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQge0RpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7XG4gIEJvb2xlYW5JbnB1dCxcbiAgY29lcmNlQm9vbGVhblByb3BlcnR5LFxuICBjb2VyY2VOdW1iZXJQcm9wZXJ0eSxcbiAgTnVtYmVySW5wdXRcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcbmltcG9ydCB7RU5URVIsIGhhc01vZGlmaWVyS2V5LCBTUEFDRX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3QsXG4gIEluamVjdGlvblRva2VuLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFF1ZXJ5TGlzdCxcbiAgVGVtcGxhdGVSZWYsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIEFmdGVyQ29udGVudEluaXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtfZ2V0Rm9jdXNlZEVsZW1lbnRQaWVyY2VTaGFkb3dEb219IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5pbXBvcnQge09ic2VydmFibGUsIG9mIGFzIG9ic2VydmFibGVPZiwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge3N0YXJ0V2l0aCwgdGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7Q2RrU3RlcEhlYWRlcn0gZnJvbSAnLi9zdGVwLWhlYWRlcic7XG5pbXBvcnQge0Nka1N0ZXBMYWJlbH0gZnJvbSAnLi9zdGVwLWxhYmVsJztcblxuLyoqIFVzZWQgdG8gZ2VuZXJhdGUgdW5pcXVlIElEIGZvciBlYWNoIHN0ZXBwZXIgY29tcG9uZW50LiAqL1xubGV0IG5leHRJZCA9IDA7XG5cbi8qKlxuICogUG9zaXRpb24gc3RhdGUgb2YgdGhlIGNvbnRlbnQgb2YgZWFjaCBzdGVwIGluIHN0ZXBwZXIgdGhhdCBpcyB1c2VkIGZvciB0cmFuc2l0aW9uaW5nXG4gKiB0aGUgY29udGVudCBpbnRvIGNvcnJlY3QgcG9zaXRpb24gdXBvbiBzdGVwIHNlbGVjdGlvbiBjaGFuZ2UuXG4gKi9cbmV4cG9ydCB0eXBlIFN0ZXBDb250ZW50UG9zaXRpb25TdGF0ZSA9ICdwcmV2aW91cyd8J2N1cnJlbnQnfCduZXh0JztcblxuLyoqIFBvc3NpYmxlIG9yaWVudGF0aW9uIG9mIGEgc3RlcHBlci4gKi9cbmV4cG9ydCB0eXBlIFN0ZXBwZXJPcmllbnRhdGlvbiA9ICdob3Jpem9udGFsJ3wndmVydGljYWwnO1xuXG4vKiogQ2hhbmdlIGV2ZW50IGVtaXR0ZWQgb24gc2VsZWN0aW9uIGNoYW5nZXMuICovXG5leHBvcnQgY2xhc3MgU3RlcHBlclNlbGVjdGlvbkV2ZW50IHtcbiAgLyoqIEluZGV4IG9mIHRoZSBzdGVwIG5vdyBzZWxlY3RlZC4gKi9cbiAgc2VsZWN0ZWRJbmRleDogbnVtYmVyO1xuXG4gIC8qKiBJbmRleCBvZiB0aGUgc3RlcCBwcmV2aW91c2x5IHNlbGVjdGVkLiAqL1xuICBwcmV2aW91c2x5U2VsZWN0ZWRJbmRleDogbnVtYmVyO1xuXG4gIC8qKiBUaGUgc3RlcCBpbnN0YW5jZSBub3cgc2VsZWN0ZWQuICovXG4gIHNlbGVjdGVkU3RlcDogQ2RrU3RlcDtcblxuICAvKiogVGhlIHN0ZXAgaW5zdGFuY2UgcHJldmlvdXNseSBzZWxlY3RlZC4gKi9cbiAgcHJldmlvdXNseVNlbGVjdGVkU3RlcDogQ2RrU3RlcDtcbn1cblxuLyoqIFRoZSBzdGF0ZSBvZiBlYWNoIHN0ZXAuICovXG5leHBvcnQgdHlwZSBTdGVwU3RhdGUgPSAnbnVtYmVyJ3wnZWRpdCd8J2RvbmUnfCdlcnJvcid8c3RyaW5nO1xuXG4vKiogRW51bSB0byByZXByZXNlbnQgdGhlIGRpZmZlcmVudCBzdGF0ZXMgb2YgdGhlIHN0ZXBzLiAqL1xuZXhwb3J0IGNvbnN0IFNURVBfU1RBVEUgPSB7XG4gIE5VTUJFUjogJ251bWJlcicsXG4gIEVESVQ6ICdlZGl0JyxcbiAgRE9ORTogJ2RvbmUnLFxuICBFUlJPUjogJ2Vycm9yJ1xufTtcblxuLyoqIEluamVjdGlvblRva2VuIHRoYXQgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSB0aGUgZ2xvYmFsIHN0ZXBwZXIgb3B0aW9ucy4gKi9cbmV4cG9ydCBjb25zdCBTVEVQUEVSX0dMT0JBTF9PUFRJT05TID0gbmV3IEluamVjdGlvblRva2VuPFN0ZXBwZXJPcHRpb25zPignU1RFUFBFUl9HTE9CQUxfT1BUSU9OUycpO1xuXG4vKiogQ29uZmlndXJhYmxlIG9wdGlvbnMgZm9yIHN0ZXBwZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0ZXBwZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHN0ZXBwZXIgc2hvdWxkIGRpc3BsYXkgYW4gZXJyb3Igc3RhdGUgb3Igbm90LlxuICAgKiBEZWZhdWx0IGJlaGF2aW9yIGlzIGFzc3VtZWQgdG8gYmUgZmFsc2UuXG4gICAqL1xuICBzaG93RXJyb3I/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzdGVwcGVyIHNob3VsZCBkaXNwbGF5IHRoZSBkZWZhdWx0IGluZGljYXRvciB0eXBlXG4gICAqIG9yIG5vdC5cbiAgICogRGVmYXVsdCBiZWhhdmlvciBpcyBhc3N1bWVkIHRvIGJlIHRydWUuXG4gICAqL1xuICBkaXNwbGF5RGVmYXVsdEluZGljYXRvclR5cGU/OiBib29sZWFuO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjZGstc3RlcCcsXG4gIGV4cG9ydEFzOiAnY2RrU3RlcCcsXG4gIHRlbXBsYXRlOiAnPG5nLXRlbXBsYXRlPjxuZy1jb250ZW50PjwvbmctY29udGVudD48L25nLXRlbXBsYXRlPicsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBDZGtTdGVwIGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgcHJpdmF0ZSBfc3RlcHBlck9wdGlvbnM6IFN0ZXBwZXJPcHRpb25zO1xuICBfZGlzcGxheURlZmF1bHRJbmRpY2F0b3JUeXBlOiBib29sZWFuO1xuXG4gIC8qKiBUZW1wbGF0ZSBmb3Igc3RlcCBsYWJlbCBpZiBpdCBleGlzdHMuICovXG4gIEBDb250ZW50Q2hpbGQoQ2RrU3RlcExhYmVsKSBzdGVwTGFiZWw6IENka1N0ZXBMYWJlbDtcblxuICAvKiogVGVtcGxhdGUgZm9yIHN0ZXAgY29udGVudC4gKi9cbiAgQFZpZXdDaGlsZChUZW1wbGF0ZVJlZiwge3N0YXRpYzogdHJ1ZX0pIGNvbnRlbnQ6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgLyoqIFRoZSB0b3AgbGV2ZWwgYWJzdHJhY3QgY29udHJvbCBvZiB0aGUgc3RlcC4gKi9cbiAgQElucHV0KCkgc3RlcENvbnRyb2w6IEFic3RyYWN0Q29udHJvbExpa2U7XG5cbiAgLyoqIFdoZXRoZXIgdXNlciBoYXMgYXR0ZW1wdGVkIHRvIG1vdmUgYXdheSBmcm9tIHRoZSBzdGVwLiAqL1xuICBpbnRlcmFjdGVkID0gZmFsc2U7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHVzZXIgaGFzIGF0dGVtcHRlZCB0byBtb3ZlIGF3YXkgZnJvbSB0aGUgc3RlcC4gKi9cbiAgQE91dHB1dCgnaW50ZXJhY3RlZCcpXG4gIHJlYWRvbmx5IGludGVyYWN0ZWRTdHJlYW06IEV2ZW50RW1pdHRlcjxDZGtTdGVwPiA9IG5ldyBFdmVudEVtaXR0ZXI8Q2RrU3RlcD4oKTtcblxuICAvKiogUGxhaW4gdGV4dCBsYWJlbCBvZiB0aGUgc3RlcC4gKi9cbiAgQElucHV0KCkgbGFiZWw6IHN0cmluZztcblxuICAvKiogRXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IHdoZW4gdGhlcmUncyBhbiBlcnJvci4gKi9cbiAgQElucHV0KCkgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG5cbiAgLyoqIEFyaWEgbGFiZWwgZm9yIHRoZSB0YWIuICovXG4gIEBJbnB1dCgnYXJpYS1sYWJlbCcpIGFyaWFMYWJlbDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgdGhhdCB0aGUgdGFiIGlzIGxhYmVsbGVkIGJ5LlxuICAgKiBXaWxsIGJlIGNsZWFyZWQgaWYgYGFyaWEtbGFiZWxgIGlzIHNldCBhdCB0aGUgc2FtZSB0aW1lLlxuICAgKi9cbiAgQElucHV0KCdhcmlhLWxhYmVsbGVkYnknKSBhcmlhTGFiZWxsZWRieTogc3RyaW5nO1xuXG4gIC8qKiBTdGF0ZSBvZiB0aGUgc3RlcC4gKi9cbiAgQElucHV0KCkgc3RhdGU6IFN0ZXBTdGF0ZTtcblxuICAvKiogV2hldGhlciB0aGUgdXNlciBjYW4gcmV0dXJuIHRvIHRoaXMgc3RlcCBvbmNlIGl0IGhhcyBiZWVuIG1hcmtlZCBhcyBjb21wbGV0ZWQuICovXG4gIEBJbnB1dCgpXG4gIGdldCBlZGl0YWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fZWRpdGFibGU7XG4gIH1cbiAgc2V0IGVkaXRhYmxlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZWRpdGFibGUgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xuICB9XG4gIHByaXZhdGUgX2VkaXRhYmxlID0gdHJ1ZTtcblxuICAvKiogV2hldGhlciB0aGUgY29tcGxldGlvbiBvZiBzdGVwIGlzIG9wdGlvbmFsLiAqL1xuICBASW5wdXQoKVxuICBnZXQgb3B0aW9uYWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbmFsO1xuICB9XG4gIHNldCBvcHRpb25hbCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX29wdGlvbmFsID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBwcml2YXRlIF9vcHRpb25hbCA9IGZhbHNlO1xuXG4gIC8qKiBXaGV0aGVyIHN0ZXAgaXMgbWFya2VkIGFzIGNvbXBsZXRlZC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IGNvbXBsZXRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY29tcGxldGVkT3ZlcnJpZGUgPT0gbnVsbCA/IHRoaXMuX2dldERlZmF1bHRDb21wbGV0ZWQoKSA6IHRoaXMuX2NvbXBsZXRlZE92ZXJyaWRlO1xuICB9XG4gIHNldCBjb21wbGV0ZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9jb21wbGV0ZWRPdmVycmlkZSA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gIH1cbiAgX2NvbXBsZXRlZE92ZXJyaWRlOiBib29sZWFufG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgX2dldERlZmF1bHRDb21wbGV0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RlcENvbnRyb2wgPyB0aGlzLnN0ZXBDb250cm9sLnZhbGlkICYmIHRoaXMuaW50ZXJhY3RlZCA6IHRoaXMuaW50ZXJhY3RlZDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHN0ZXAgaGFzIGFuIGVycm9yLiAqL1xuICBASW5wdXQoKVxuICBnZXQgaGFzRXJyb3IoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2N1c3RvbUVycm9yID09IG51bGwgPyB0aGlzLl9nZXREZWZhdWx0RXJyb3IoKSA6IHRoaXMuX2N1c3RvbUVycm9yO1xuICB9XG4gIHNldCBoYXNFcnJvcih2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2N1c3RvbUVycm9yID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcbiAgfVxuICBwcml2YXRlIF9jdXN0b21FcnJvcjogYm9vbGVhbnxudWxsID0gbnVsbDtcblxuICBwcml2YXRlIF9nZXREZWZhdWx0RXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RlcENvbnRyb2wgJiYgdGhpcy5zdGVwQ29udHJvbC5pbnZhbGlkICYmIHRoaXMuaW50ZXJhY3RlZDtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IENka1N0ZXBwZXIpKSBwdWJsaWMgX3N0ZXBwZXI6IENka1N0ZXBwZXIsXG4gICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNURVBQRVJfR0xPQkFMX09QVElPTlMpIHN0ZXBwZXJPcHRpb25zPzogU3RlcHBlck9wdGlvbnMpIHtcbiAgICB0aGlzLl9zdGVwcGVyT3B0aW9ucyA9IHN0ZXBwZXJPcHRpb25zID8gc3RlcHBlck9wdGlvbnMgOiB7fTtcbiAgICB0aGlzLl9kaXNwbGF5RGVmYXVsdEluZGljYXRvclR5cGUgPSB0aGlzLl9zdGVwcGVyT3B0aW9ucy5kaXNwbGF5RGVmYXVsdEluZGljYXRvclR5cGUgIT09IGZhbHNlO1xuICB9XG5cbiAgLyoqIFNlbGVjdHMgdGhpcyBzdGVwIGNvbXBvbmVudC4gKi9cbiAgc2VsZWN0KCk6IHZvaWQge1xuICAgIHRoaXMuX3N0ZXBwZXIuc2VsZWN0ZWQgPSB0aGlzO1xuICB9XG5cbiAgLyoqIFJlc2V0cyB0aGUgc3RlcCB0byBpdHMgaW5pdGlhbCBzdGF0ZS4gTm90ZSB0aGF0IHRoaXMgaW5jbHVkZXMgcmVzZXR0aW5nIGZvcm0gZGF0YS4gKi9cbiAgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbnRlcmFjdGVkID0gZmFsc2U7XG5cbiAgICBpZiAodGhpcy5fY29tcGxldGVkT3ZlcnJpZGUgIT0gbnVsbCkge1xuICAgICAgdGhpcy5fY29tcGxldGVkT3ZlcnJpZGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fY3VzdG9tRXJyb3IgIT0gbnVsbCkge1xuICAgICAgdGhpcy5fY3VzdG9tRXJyb3IgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGVwQ29udHJvbCkge1xuICAgICAgdGhpcy5zdGVwQ29udHJvbC5yZXNldCgpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIC8vIFNpbmNlIGJhc2ljYWxseSBhbGwgaW5wdXRzIG9mIHRoZSBNYXRTdGVwIGdldCBwcm94aWVkIHRocm91Z2ggdGhlIHZpZXcgZG93biB0byB0aGVcbiAgICAvLyB1bmRlcmx5aW5nIE1hdFN0ZXBIZWFkZXIsIHdlIGhhdmUgdG8gbWFrZSBzdXJlIHRoYXQgY2hhbmdlIGRldGVjdGlvbiBydW5zIGNvcnJlY3RseS5cbiAgICB0aGlzLl9zdGVwcGVyLl9zdGF0ZUNoYW5nZWQoKTtcbiAgfVxuXG4gIF9tYXJrQXNJbnRlcmFjdGVkKCkge1xuICAgIGlmICghdGhpcy5pbnRlcmFjdGVkKSB7XG4gICAgICB0aGlzLmludGVyYWN0ZWQgPSB0cnVlO1xuICAgICAgdGhpcy5pbnRlcmFjdGVkU3RyZWFtLmVtaXQodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIERldGVybWluZXMgd2hldGhlciB0aGUgZXJyb3Igc3RhdGUgY2FuIGJlIHNob3duLiAqL1xuICBfc2hvd0Vycm9yKCk6IGJvb2xlYW4ge1xuICAgIC8vIFdlIHdhbnQgdG8gc2hvdyB0aGUgZXJyb3Igc3RhdGUgZWl0aGVyIGlmIHRoZSB1c2VyIG9wdGVkIGludG8vb3V0IG9mIGl0IHVzaW5nIHRoZVxuICAgIC8vIGdsb2JhbCBvcHRpb25zLCBvciBpZiB0aGV5J3ZlIGV4cGxpY2l0bHkgc2V0IGl0IHRocm91Z2ggdGhlIGBoYXNFcnJvcmAgaW5wdXQuXG4gICAgcmV0dXJuIHRoaXMuX3N0ZXBwZXJPcHRpb25zLnNob3dFcnJvciA/PyB0aGlzLl9jdXN0b21FcnJvciAhPSBudWxsO1xuICB9XG5cbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2VkaXRhYmxlOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9oYXNFcnJvcjogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfb3B0aW9uYWw6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2NvbXBsZXRlZDogQm9vbGVhbklucHV0O1xufVxuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbY2RrU3RlcHBlcl0nLFxuICBleHBvcnRBczogJ2Nka1N0ZXBwZXInLFxufSlcbmV4cG9ydCBjbGFzcyBDZGtTdGVwcGVyIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcbiAgLyoqIEVtaXRzIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBfZGVzdHJveWVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKiogVXNlZCBmb3IgbWFuYWdpbmcga2V5Ym9hcmQgZm9jdXMuICovXG4gIHByaXZhdGUgX2tleU1hbmFnZXI6IEZvY3VzS2V5TWFuYWdlcjxGb2N1c2FibGVPcHRpb24+O1xuXG4gIC8qKiBGdWxsIGxpc3Qgb2Ygc3RlcHMgaW5zaWRlIHRoZSBzdGVwcGVyLCBpbmNsdWRpbmcgaW5zaWRlIG5lc3RlZCBzdGVwcGVycy4gKi9cbiAgQENvbnRlbnRDaGlsZHJlbihDZGtTdGVwLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfc3RlcHM6IFF1ZXJ5TGlzdDxDZGtTdGVwPjtcblxuICAvKiogU3RlcHMgdGhhdCBiZWxvbmcgdG8gdGhlIGN1cnJlbnQgc3RlcHBlciwgZXhjbHVkaW5nIG9uZXMgZnJvbSBuZXN0ZWQgc3RlcHBlcnMuICovXG4gIHJlYWRvbmx5IHN0ZXBzOiBRdWVyeUxpc3Q8Q2RrU3RlcD4gPSBuZXcgUXVlcnlMaXN0PENka1N0ZXA+KCk7XG5cbiAgLyoqIFRoZSBsaXN0IG9mIHN0ZXAgaGVhZGVycyBvZiB0aGUgc3RlcHMgaW4gdGhlIHN0ZXBwZXIuICovXG4gIEBDb250ZW50Q2hpbGRyZW4oQ2RrU3RlcEhlYWRlciwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX3N0ZXBIZWFkZXI6IFF1ZXJ5TGlzdDxDZGtTdGVwSGVhZGVyPjtcblxuICAvKiogTGlzdCBvZiBzdGVwIGhlYWRlcnMgc29ydGVkIGJhc2VkIG9uIHRoZWlyIERPTSBvcmRlci4gKi9cbiAgcHJpdmF0ZSBfc29ydGVkSGVhZGVycyA9IG5ldyBRdWVyeUxpc3Q8Q2RrU3RlcEhlYWRlcj4oKTtcblxuICAvKiogV2hldGhlciB0aGUgdmFsaWRpdHkgb2YgcHJldmlvdXMgc3RlcHMgc2hvdWxkIGJlIGNoZWNrZWQgb3Igbm90LiAqL1xuICBASW5wdXQoKVxuICBnZXQgbGluZWFyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9saW5lYXI7XG4gIH1cbiAgc2V0IGxpbmVhcih2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2xpbmVhciA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gIH1cbiAgcHJpdmF0ZSBfbGluZWFyID0gZmFsc2U7XG5cbiAgLyoqIFRoZSBpbmRleCBvZiB0aGUgc2VsZWN0ZWQgc3RlcC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IHNlbGVjdGVkSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkSW5kZXg7XG4gIH1cbiAgc2V0IHNlbGVjdGVkSW5kZXgoaW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IG5ld0luZGV4ID0gY29lcmNlTnVtYmVyUHJvcGVydHkoaW5kZXgpO1xuXG4gICAgaWYgKHRoaXMuc3RlcHMgJiYgdGhpcy5fc3RlcHMpIHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBpbmRleCBjYW4ndCBiZSBvdXQgb2YgYm91bmRzLlxuICAgICAgaWYgKCF0aGlzLl9pc1ZhbGlkSW5kZXgoaW5kZXgpICYmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdjZGtTdGVwcGVyOiBDYW5ub3QgYXNzaWduIG91dC1vZi1ib3VuZHMgdmFsdWUgdG8gYHNlbGVjdGVkSW5kZXhgLicpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnNlbGVjdGVkPy5fbWFya0FzSW50ZXJhY3RlZCgpO1xuXG4gICAgICBpZiAodGhpcy5fc2VsZWN0ZWRJbmRleCAhPT0gbmV3SW5kZXggJiYgIXRoaXMuX2FueUNvbnRyb2xzSW52YWxpZE9yUGVuZGluZyhuZXdJbmRleCkgJiZcbiAgICAgICAgICAobmV3SW5kZXggPj0gdGhpcy5fc2VsZWN0ZWRJbmRleCB8fCB0aGlzLnN0ZXBzLnRvQXJyYXkoKVtuZXdJbmRleF0uZWRpdGFibGUpKSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkSXRlbUluZGV4KGluZGV4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IG5ld0luZGV4O1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF9zZWxlY3RlZEluZGV4ID0gMDtcblxuICAvKiogVGhlIHN0ZXAgdGhhdCBpcyBzZWxlY3RlZC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IHNlbGVjdGVkKCk6IENka1N0ZXAgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnN0ZXBzID8gdGhpcy5zdGVwcy50b0FycmF5KClbdGhpcy5zZWxlY3RlZEluZGV4XSA6IHVuZGVmaW5lZDtcbiAgfVxuICBzZXQgc2VsZWN0ZWQoc3RlcDogQ2RrU3RlcCB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IChzdGVwICYmIHRoaXMuc3RlcHMpID8gdGhpcy5zdGVwcy50b0FycmF5KCkuaW5kZXhPZihzdGVwKSA6IC0xO1xuICB9XG5cbiAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgc2VsZWN0ZWQgc3RlcCBoYXMgY2hhbmdlZC4gKi9cbiAgQE91dHB1dCgpIHJlYWRvbmx5IHNlbGVjdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8U3RlcHBlclNlbGVjdGlvbkV2ZW50PigpO1xuXG4gIC8qKiBVc2VkIHRvIHRyYWNrIHVuaXF1ZSBJRCBmb3IgZWFjaCBzdGVwcGVyIGNvbXBvbmVudC4gKi9cbiAgX2dyb3VwSWQ6IG51bWJlcjtcblxuICAvKiogT3JpZW50YXRpb24gb2YgdGhlIHN0ZXBwZXIuICovXG4gIEBJbnB1dCgpXG4gIGdldCBvcmllbnRhdGlvbigpOiBTdGVwcGVyT3JpZW50YXRpb24geyByZXR1cm4gdGhpcy5fb3JpZW50YXRpb247IH1cbiAgc2V0IG9yaWVudGF0aW9uKHZhbHVlOiBTdGVwcGVyT3JpZW50YXRpb24pIHtcbiAgICAvLyBUaGlzIGlzIGEgcHJvdGVjdGVkIG1ldGhvZCBzbyB0aGF0IGBNYXRTdGVwcHRlcmAgY2FuIGhvb2sgaW50byBpdC5cbiAgICB0aGlzLl9vcmllbnRhdGlvbiA9IHZhbHVlO1xuXG4gICAgaWYgKHRoaXMuX2tleU1hbmFnZXIpIHtcbiAgICAgIHRoaXMuX2tleU1hbmFnZXIud2l0aFZlcnRpY2FsT3JpZW50YXRpb24odmFsdWUgPT09ICd2ZXJ0aWNhbCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBUbyBiZSB0dXJuZWQgaW50byBhIHByaXZhdGUgcHJvcGVydHkuIFVzZSBgb3JpZW50YXRpb25gIGluc3RlYWQuXG4gICAqIEBicmVha2luZy1jaGFuZ2UgMTMuMC4wXG4gICAqL1xuICBwcm90ZWN0ZWQgX29yaWVudGF0aW9uOiBTdGVwcGVyT3JpZW50YXRpb24gPSAnaG9yaXpvbnRhbCc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBAT3B0aW9uYWwoKSBwcml2YXRlIF9kaXI6IERpcmVjdGlvbmFsaXR5LCBwcml2YXRlIF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICAgIC8qKlxuICAgICAgICogQGRlcHJlY2F0ZWQgTm8gbG9uZ2VyIGluIHVzZSwgdG8gYmUgcmVtb3ZlZC5cbiAgICAgICAqIEBicmVha2luZy1jaGFuZ2UgMTMuMC4wXG4gICAgICAgKi9cbiAgICAgIEBJbmplY3QoRE9DVU1FTlQpIF9kb2N1bWVudDogYW55KSB7XG4gICAgdGhpcy5fZ3JvdXBJZCA9IG5leHRJZCsrO1xuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgIHRoaXMuX3N0ZXBzLmNoYW5nZXNcbiAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9zdGVwcyksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxuICAgICAgLnN1YnNjcmliZSgoc3RlcHM6IFF1ZXJ5TGlzdDxDZGtTdGVwPikgPT4ge1xuICAgICAgICB0aGlzLnN0ZXBzLnJlc2V0KHN0ZXBzLmZpbHRlcihzdGVwID0+IHN0ZXAuX3N0ZXBwZXIgPT09IHRoaXMpKTtcbiAgICAgICAgdGhpcy5zdGVwcy5ub3RpZnlPbkNoYW5nZXMoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8vIElmIHRoZSBzdGVwIGhlYWRlcnMgYXJlIGRlZmluZWQgb3V0c2lkZSBvZiB0aGUgYG5nRm9yYCB0aGF0IHJlbmRlcnMgdGhlIHN0ZXBzLCBsaWtlIGluIHRoZVxuICAgIC8vIE1hdGVyaWFsIHN0ZXBwZXIsIHRoZXkgd29uJ3QgYXBwZWFyIGluIHRoZSBgUXVlcnlMaXN0YCBpbiB0aGUgc2FtZSBvcmRlciBhcyB0aGV5J3JlXG4gICAgLy8gcmVuZGVyZWQgaW4gdGhlIERPTSB3aGljaCB3aWxsIGxlYWQgdG8gaW5jb3JyZWN0IGtleWJvYXJkIG5hdmlnYXRpb24uIFdlIG5lZWQgdG8gc29ydFxuICAgIC8vIHRoZW0gbWFudWFsbHkgdG8gZW5zdXJlIHRoYXQgdGhleSdyZSBjb3JyZWN0LiBBbHRlcm5hdGl2ZWx5LCB3ZSBjYW4gY2hhbmdlIHRoZSBNYXRlcmlhbFxuICAgIC8vIHRlbXBsYXRlIHRvIGlubGluZSB0aGUgaGVhZGVycyBpbiB0aGUgYG5nRm9yYCwgYnV0IHRoYXQnbGwgcmVzdWx0IGluIGEgbG90IG9mXG4gICAgLy8gY29kZSBkdXBsY2lhdGlvbi4gU2VlICMyMzUzOS5cbiAgICB0aGlzLl9zdGVwSGVhZGVyLmNoYW5nZXNcbiAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9zdGVwSGVhZGVyKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXG4gICAgICAuc3Vic2NyaWJlKChoZWFkZXJzOiBRdWVyeUxpc3Q8Q2RrU3RlcEhlYWRlcj4pID0+IHtcbiAgICAgICAgdGhpcy5fc29ydGVkSGVhZGVycy5yZXNldChoZWFkZXJzLnRvQXJyYXkoKS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgZG9jdW1lbnRQb3NpdGlvbiA9XG4gICAgICAgICAgICBhLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYi5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcblxuICAgICAgICAgIC8vIGBjb21wYXJlRG9jdW1lbnRQb3NpdGlvbmAgcmV0dXJucyBhIGJpdG1hc2sgc28gd2UgaGF2ZSB0byB1c2UgYSBiaXR3aXNlIG9wZXJhdG9yLlxuICAgICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Ob2RlL2NvbXBhcmVEb2N1bWVudFBvc2l0aW9uXG4gICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgICByZXR1cm4gZG9jdW1lbnRQb3NpdGlvbiAmIE5vZGUuRE9DVU1FTlRfUE9TSVRJT05fRk9MTE9XSU5HID8gLTEgOiAxO1xuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuX3NvcnRlZEhlYWRlcnMubm90aWZ5T25DaGFuZ2VzKCk7XG4gICAgICB9KTtcblxuICAgIC8vIE5vdGUgdGhhdCB3aGlsZSB0aGUgc3RlcCBoZWFkZXJzIGFyZSBjb250ZW50IGNoaWxkcmVuIGJ5IGRlZmF1bHQsIGFueSBjb21wb25lbnRzIHRoYXRcbiAgICAvLyBleHRlbmQgdGhpcyBvbmUgbWlnaHQgaGF2ZSB0aGVtIGFzIHZpZXcgY2hpbGRyZW4uIFdlIGluaXRpYWxpemUgdGhlIGtleWJvYXJkIGhhbmRsaW5nIGluXG4gICAgLy8gQWZ0ZXJWaWV3SW5pdCBzbyB3ZSdyZSBndWFyYW50ZWVkIGZvciBib3RoIHZpZXcgYW5kIGNvbnRlbnQgY2hpbGRyZW4gdG8gYmUgZGVmaW5lZC5cbiAgICB0aGlzLl9rZXlNYW5hZ2VyID0gbmV3IEZvY3VzS2V5TWFuYWdlcjxGb2N1c2FibGVPcHRpb24+KHRoaXMuX3NvcnRlZEhlYWRlcnMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAud2l0aFdyYXAoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgLndpdGhIb21lQW5kRW5kKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIC53aXRoVmVydGljYWxPcmllbnRhdGlvbih0aGlzLl9vcmllbnRhdGlvbiA9PT0gJ3ZlcnRpY2FsJyk7XG5cbiAgICAodGhpcy5fZGlyID8gKHRoaXMuX2Rpci5jaGFuZ2UgYXMgT2JzZXJ2YWJsZTxEaXJlY3Rpb24+KSA6IG9ic2VydmFibGVPZjxEaXJlY3Rpb24+KCkpXG4gICAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9sYXlvdXREaXJlY3Rpb24oKSksIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxuICAgICAgICAuc3Vic2NyaWJlKGRpcmVjdGlvbiA9PiB0aGlzLl9rZXlNYW5hZ2VyLndpdGhIb3Jpem9udGFsT3JpZW50YXRpb24oZGlyZWN0aW9uKSk7XG5cbiAgICB0aGlzLl9rZXlNYW5hZ2VyLnVwZGF0ZUFjdGl2ZUl0ZW0odGhpcy5fc2VsZWN0ZWRJbmRleCk7XG5cbiAgICAvLyBObyBuZWVkIHRvIGB0YWtlVW50aWxgIGhlcmUsIGJlY2F1c2Ugd2UncmUgdGhlIG9uZXMgZGVzdHJveWluZyBgc3RlcHNgLlxuICAgIHRoaXMuc3RlcHMuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkKSB7XG4gICAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSBNYXRoLm1heCh0aGlzLl9zZWxlY3RlZEluZGV4IC0gMSwgMCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBUaGUgbG9naWMgd2hpY2ggYXNzZXJ0cyB0aGF0IHRoZSBzZWxlY3RlZCBpbmRleCBpcyB3aXRoaW4gYm91bmRzIGRvZXNuJ3QgcnVuIGJlZm9yZSB0aGVcbiAgICAvLyBzdGVwcyBhcmUgaW5pdGlhbGl6ZWQsIGJlY2F1c2Ugd2UgZG9uJ3QgaG93IG1hbnkgc3RlcHMgdGhlcmUgYXJlIHlldCBzbyB3ZSBtYXkgaGF2ZSBhblxuICAgIC8vIGludmFsaWQgaW5kZXggb24gaW5pdC4gSWYgdGhhdCdzIHRoZSBjYXNlLCBhdXRvLWNvcnJlY3QgdG8gdGhlIGRlZmF1bHQgc28gd2UgZG9uJ3QgdGhyb3cuXG4gICAgaWYgKCF0aGlzLl9pc1ZhbGlkSW5kZXgodGhpcy5fc2VsZWN0ZWRJbmRleCkpIHtcbiAgICAgIHRoaXMuX3NlbGVjdGVkSW5kZXggPSAwO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3RlcHMuZGVzdHJveSgpO1xuICAgIHRoaXMuX3NvcnRlZEhlYWRlcnMuZGVzdHJveSgpO1xuICAgIHRoaXMuX2Rlc3Ryb3llZC5uZXh0KCk7XG4gICAgdGhpcy5fZGVzdHJveWVkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKiogU2VsZWN0cyBhbmQgZm9jdXNlcyB0aGUgbmV4dCBzdGVwIGluIGxpc3QuICovXG4gIG5leHQoKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gTWF0aC5taW4odGhpcy5fc2VsZWN0ZWRJbmRleCArIDEsIHRoaXMuc3RlcHMubGVuZ3RoIC0gMSk7XG4gIH1cblxuICAvKiogU2VsZWN0cyBhbmQgZm9jdXNlcyB0aGUgcHJldmlvdXMgc3RlcCBpbiBsaXN0LiAqL1xuICBwcmV2aW91cygpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkSW5kZXggPSBNYXRoLm1heCh0aGlzLl9zZWxlY3RlZEluZGV4IC0gMSwgMCk7XG4gIH1cblxuICAvKiogUmVzZXRzIHRoZSBzdGVwcGVyIHRvIGl0cyBpbml0aWFsIHN0YXRlLiBOb3RlIHRoYXQgdGhpcyBpbmNsdWRlcyBjbGVhcmluZyBmb3JtIGRhdGEuICovXG4gIHJlc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkSXRlbUluZGV4KDApO1xuICAgIHRoaXMuc3RlcHMuZm9yRWFjaChzdGVwID0+IHN0ZXAucmVzZXQoKSk7XG4gICAgdGhpcy5fc3RhdGVDaGFuZ2VkKCk7XG4gIH1cblxuICAvKiogUmV0dXJucyBhIHVuaXF1ZSBpZCBmb3IgZWFjaCBzdGVwIGxhYmVsIGVsZW1lbnQuICovXG4gIF9nZXRTdGVwTGFiZWxJZChpOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBgY2RrLXN0ZXAtbGFiZWwtJHt0aGlzLl9ncm91cElkfS0ke2l9YDtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHVuaXF1ZSBpZCBmb3IgZWFjaCBzdGVwIGNvbnRlbnQgZWxlbWVudC4gKi9cbiAgX2dldFN0ZXBDb250ZW50SWQoaTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYGNkay1zdGVwLWNvbnRlbnQtJHt0aGlzLl9ncm91cElkfS0ke2l9YDtcbiAgfVxuXG4gIC8qKiBNYXJrcyB0aGUgY29tcG9uZW50IHRvIGJlIGNoYW5nZSBkZXRlY3RlZC4gKi9cbiAgX3N0YXRlQ2hhbmdlZCgpIHtcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHBvc2l0aW9uIHN0YXRlIG9mIHRoZSBzdGVwIHdpdGggdGhlIGdpdmVuIGluZGV4LiAqL1xuICBfZ2V0QW5pbWF0aW9uRGlyZWN0aW9uKGluZGV4OiBudW1iZXIpOiBTdGVwQ29udGVudFBvc2l0aW9uU3RhdGUge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gaW5kZXggLSB0aGlzLl9zZWxlY3RlZEluZGV4O1xuICAgIGlmIChwb3NpdGlvbiA8IDApIHtcbiAgICAgIHJldHVybiB0aGlzLl9sYXlvdXREaXJlY3Rpb24oKSA9PT0gJ3J0bCcgPyAnbmV4dCcgOiAncHJldmlvdXMnO1xuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPiAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbGF5b3V0RGlyZWN0aW9uKCkgPT09ICdydGwnID8gJ3ByZXZpb3VzJyA6ICduZXh0JztcbiAgICB9XG4gICAgcmV0dXJuICdjdXJyZW50JztcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSB0eXBlIG9mIGljb24gdG8gYmUgZGlzcGxheWVkLiAqL1xuICBfZ2V0SW5kaWNhdG9yVHlwZShpbmRleDogbnVtYmVyLCBzdGF0ZTogU3RlcFN0YXRlID0gU1RFUF9TVEFURS5OVU1CRVIpOiBTdGVwU3RhdGUge1xuICAgIGNvbnN0IHN0ZXAgPSB0aGlzLnN0ZXBzLnRvQXJyYXkoKVtpbmRleF07XG4gICAgY29uc3QgaXNDdXJyZW50U3RlcCA9IHRoaXMuX2lzQ3VycmVudFN0ZXAoaW5kZXgpO1xuXG4gICAgcmV0dXJuIHN0ZXAuX2Rpc3BsYXlEZWZhdWx0SW5kaWNhdG9yVHlwZSA/IHRoaXMuX2dldERlZmF1bHRJbmRpY2F0b3JMb2dpYyhzdGVwLCBpc0N1cnJlbnRTdGVwKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2dldEd1aWRlbGluZUxvZ2ljKHN0ZXAsIGlzQ3VycmVudFN0ZXAsIHN0YXRlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldERlZmF1bHRJbmRpY2F0b3JMb2dpYyhzdGVwOiBDZGtTdGVwLCBpc0N1cnJlbnRTdGVwOiBib29sZWFuKTogU3RlcFN0YXRlIHtcbiAgICBpZiAoc3RlcC5fc2hvd0Vycm9yKCkgJiYgc3RlcC5oYXNFcnJvciAmJiAhaXNDdXJyZW50U3RlcCkge1xuICAgICAgcmV0dXJuIFNURVBfU1RBVEUuRVJST1I7XG4gICAgfSBlbHNlIGlmICghc3RlcC5jb21wbGV0ZWQgfHwgaXNDdXJyZW50U3RlcCkge1xuICAgICAgcmV0dXJuIFNURVBfU1RBVEUuTlVNQkVSO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3RlcC5lZGl0YWJsZSA/IFNURVBfU1RBVEUuRURJVCA6IFNURVBfU1RBVEUuRE9ORTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9nZXRHdWlkZWxpbmVMb2dpYyhcbiAgICAgIHN0ZXA6IENka1N0ZXAsIGlzQ3VycmVudFN0ZXA6IGJvb2xlYW4sIHN0YXRlOiBTdGVwU3RhdGUgPSBTVEVQX1NUQVRFLk5VTUJFUik6IFN0ZXBTdGF0ZSB7XG4gICAgaWYgKHN0ZXAuX3Nob3dFcnJvcigpICYmIHN0ZXAuaGFzRXJyb3IgJiYgIWlzQ3VycmVudFN0ZXApIHtcbiAgICAgIHJldHVybiBTVEVQX1NUQVRFLkVSUk9SO1xuICAgIH0gZWxzZSBpZiAoc3RlcC5jb21wbGV0ZWQgJiYgIWlzQ3VycmVudFN0ZXApIHtcbiAgICAgIHJldHVybiBTVEVQX1NUQVRFLkRPTkU7XG4gICAgfSBlbHNlIGlmIChzdGVwLmNvbXBsZXRlZCAmJiBpc0N1cnJlbnRTdGVwKSB7XG4gICAgICByZXR1cm4gc3RhdGU7XG4gICAgfSBlbHNlIGlmIChzdGVwLmVkaXRhYmxlICYmIGlzQ3VycmVudFN0ZXApIHtcbiAgICAgIHJldHVybiBTVEVQX1NUQVRFLkVESVQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9pc0N1cnJlbnRTdGVwKGluZGV4OiBudW1iZXIpIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRJbmRleCA9PT0gaW5kZXg7XG4gIH1cblxuICAvKiogUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnRseS1mb2N1c2VkIHN0ZXAgaGVhZGVyLiAqL1xuICBfZ2V0Rm9jdXNJbmRleCgpIHtcbiAgICByZXR1cm4gdGhpcy5fa2V5TWFuYWdlciA/IHRoaXMuX2tleU1hbmFnZXIuYWN0aXZlSXRlbUluZGV4IDogdGhpcy5fc2VsZWN0ZWRJbmRleDtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZVNlbGVjdGVkSXRlbUluZGV4KG5ld0luZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzdGVwc0FycmF5ID0gdGhpcy5zdGVwcy50b0FycmF5KCk7XG4gICAgdGhpcy5zZWxlY3Rpb25DaGFuZ2UuZW1pdCh7XG4gICAgICBzZWxlY3RlZEluZGV4OiBuZXdJbmRleCxcbiAgICAgIHByZXZpb3VzbHlTZWxlY3RlZEluZGV4OiB0aGlzLl9zZWxlY3RlZEluZGV4LFxuICAgICAgc2VsZWN0ZWRTdGVwOiBzdGVwc0FycmF5W25ld0luZGV4XSxcbiAgICAgIHByZXZpb3VzbHlTZWxlY3RlZFN0ZXA6IHN0ZXBzQXJyYXlbdGhpcy5fc2VsZWN0ZWRJbmRleF0sXG4gICAgfSk7XG5cbiAgICAvLyBJZiBmb2N1cyBpcyBpbnNpZGUgdGhlIHN0ZXBwZXIsIG1vdmUgaXQgdG8gdGhlIG5leHQgaGVhZGVyLCBvdGhlcndpc2UgaXQgbWF5IGJlY29tZVxuICAgIC8vIGxvc3Qgd2hlbiB0aGUgYWN0aXZlIHN0ZXAgY29udGVudCBpcyBoaWRkZW4uIFdlIGNhbid0IGJlIG1vcmUgZ3JhbnVsYXIgd2l0aCB0aGUgY2hlY2tcbiAgICAvLyAoZS5nLiBjaGVja2luZyB3aGV0aGVyIGZvY3VzIGlzIGluc2lkZSB0aGUgYWN0aXZlIHN0ZXApLCBiZWNhdXNlIHdlIGRvbid0IGhhdmUgYVxuICAgIC8vIHJlZmVyZW5jZSB0byB0aGUgZWxlbWVudHMgdGhhdCBhcmUgcmVuZGVyaW5nIG91dCB0aGUgY29udGVudC5cbiAgICB0aGlzLl9jb250YWluc0ZvY3VzKCkgPyB0aGlzLl9rZXlNYW5hZ2VyLnNldEFjdGl2ZUl0ZW0obmV3SW5kZXgpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9rZXlNYW5hZ2VyLnVwZGF0ZUFjdGl2ZUl0ZW0obmV3SW5kZXgpO1xuXG4gICAgdGhpcy5fc2VsZWN0ZWRJbmRleCA9IG5ld0luZGV4O1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCgpO1xuICB9XG5cbiAgX29uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGNvbnN0IGhhc01vZGlmaWVyID0gaGFzTW9kaWZpZXJLZXkoZXZlbnQpO1xuICAgIGNvbnN0IGtleUNvZGUgPSBldmVudC5rZXlDb2RlO1xuICAgIGNvbnN0IG1hbmFnZXIgPSB0aGlzLl9rZXlNYW5hZ2VyO1xuXG4gICAgaWYgKG1hbmFnZXIuYWN0aXZlSXRlbUluZGV4ICE9IG51bGwgJiYgIWhhc01vZGlmaWVyICYmXG4gICAgICAgIChrZXlDb2RlID09PSBTUEFDRSB8fCBrZXlDb2RlID09PSBFTlRFUikpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IG1hbmFnZXIuYWN0aXZlSXRlbUluZGV4O1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWFuYWdlci5vbktleWRvd24oZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2FueUNvbnRyb2xzSW52YWxpZE9yUGVuZGluZyhpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX2xpbmVhciAmJiBpbmRleCA+PSAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5zdGVwcy50b0FycmF5KCkuc2xpY2UoMCwgaW5kZXgpLnNvbWUoc3RlcCA9PiB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2wgPSBzdGVwLnN0ZXBDb250cm9sO1xuICAgICAgICBjb25zdCBpc0luY29tcGxldGUgPVxuICAgICAgICAgICAgY29udHJvbCA/IChjb250cm9sLmludmFsaWQgfHwgY29udHJvbC5wZW5kaW5nIHx8ICFzdGVwLmludGVyYWN0ZWQpIDogIXN0ZXAuY29tcGxldGVkO1xuICAgICAgICByZXR1cm4gaXNJbmNvbXBsZXRlICYmICFzdGVwLm9wdGlvbmFsICYmICFzdGVwLl9jb21wbGV0ZWRPdmVycmlkZTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgX2xheW91dERpcmVjdGlvbigpOiBEaXJlY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLl9kaXIgJiYgdGhpcy5fZGlyLnZhbHVlID09PSAncnRsJyA/ICdydGwnIDogJ2x0cic7XG4gIH1cblxuICAvKiogQ2hlY2tzIHdoZXRoZXIgdGhlIHN0ZXBwZXIgY29udGFpbnMgdGhlIGZvY3VzZWQgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfY29udGFpbnNGb2N1cygpOiBib29sZWFuIHtcbiAgICBjb25zdCBzdGVwcGVyRWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBmb2N1c2VkRWxlbWVudCA9IF9nZXRGb2N1c2VkRWxlbWVudFBpZXJjZVNoYWRvd0RvbSgpO1xuICAgIHJldHVybiBzdGVwcGVyRWxlbWVudCA9PT0gZm9jdXNlZEVsZW1lbnQgfHwgc3RlcHBlckVsZW1lbnQuY29udGFpbnMoZm9jdXNlZEVsZW1lbnQpO1xuICB9XG5cbiAgLyoqIENoZWNrcyB3aGV0aGVyIHRoZSBwYXNzZWQtaW4gaW5kZXggaXMgYSB2YWxpZCBzdGVwIGluZGV4LiAqL1xuICBwcml2YXRlIF9pc1ZhbGlkSW5kZXgoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpbmRleCA+IC0xICYmICghdGhpcy5zdGVwcyB8fCBpbmRleCA8IHRoaXMuc3RlcHMubGVuZ3RoKTtcbiAgfVxuXG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9lZGl0YWJsZTogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfb3B0aW9uYWw6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2NvbXBsZXRlZDogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfaGFzRXJyb3I6IEJvb2xlYW5JbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX2xpbmVhcjogQm9vbGVhbklucHV0O1xuICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfc2VsZWN0ZWRJbmRleDogTnVtYmVySW5wdXQ7XG59XG5cblxuLyoqXG4gKiBTaW1wbGlmaWVkIHJlcHJlc2VudGF0aW9uIG9mIGFuIFwiQWJzdHJhY3RDb250cm9sXCIgZnJvbSBAYW5ndWxhci9mb3Jtcy5cbiAqIFVzZWQgdG8gYXZvaWQgaGF2aW5nIHRvIGJyaW5nIGluIEBhbmd1bGFyL2Zvcm1zIGZvciBhIHNpbmdsZSBvcHRpb25hbCBpbnRlcmZhY2UuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbmludGVyZmFjZSBBYnN0cmFjdENvbnRyb2xMaWtlIHtcbiAgYXN5bmNWYWxpZGF0b3I6ICgoY29udHJvbDogYW55KSA9PiBhbnkpIHwgbnVsbDtcbiAgZGlydHk6IGJvb2xlYW47XG4gIGRpc2FibGVkOiBib29sZWFuO1xuICBlbmFibGVkOiBib29sZWFuO1xuICBlcnJvcnM6IHtba2V5OiBzdHJpbmddOiBhbnl9IHwgbnVsbDtcbiAgaW52YWxpZDogYm9vbGVhbjtcbiAgcGFyZW50OiBhbnk7XG4gIHBlbmRpbmc6IGJvb2xlYW47XG4gIHByaXN0aW5lOiBib29sZWFuO1xuICByb290OiBBYnN0cmFjdENvbnRyb2xMaWtlO1xuICBzdGF0dXM6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhdHVzQ2hhbmdlczogT2JzZXJ2YWJsZTxhbnk+O1xuICB0b3VjaGVkOiBib29sZWFuO1xuICB1bnRvdWNoZWQ6IGJvb2xlYW47XG4gIHVwZGF0ZU9uOiBhbnk7XG4gIHZhbGlkOiBib29sZWFuO1xuICB2YWxpZGF0b3I6ICgoY29udHJvbDogYW55KSA9PiBhbnkpIHwgbnVsbDtcbiAgdmFsdWU6IGFueTtcbiAgcmVhZG9ubHkgdmFsdWVDaGFuZ2VzOiBPYnNlcnZhYmxlPGFueT47XG4gIGNsZWFyQXN5bmNWYWxpZGF0b3JzKCk6IHZvaWQ7XG4gIGNsZWFyVmFsaWRhdG9ycygpOiB2b2lkO1xuICBkaXNhYmxlKG9wdHM/OiBhbnkpOiB2b2lkO1xuICBlbmFibGUob3B0cz86IGFueSk6IHZvaWQ7XG4gIGdldChwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdIHwgc3RyaW5nKTogQWJzdHJhY3RDb250cm9sTGlrZSB8IG51bGw7XG4gIGdldEVycm9yKGVycm9yQ29kZTogc3RyaW5nLCBwYXRoPzogKHN0cmluZyB8IG51bWJlcilbXSB8IHN0cmluZyk6IGFueTtcbiAgaGFzRXJyb3IoZXJyb3JDb2RlOiBzdHJpbmcsIHBhdGg/OiAoc3RyaW5nIHwgbnVtYmVyKVtdIHwgc3RyaW5nKTogYm9vbGVhbjtcbiAgbWFya0FsbEFzVG91Y2hlZCgpOiB2b2lkO1xuICBtYXJrQXNEaXJ0eShvcHRzPzogYW55KTogdm9pZDtcbiAgbWFya0FzUGVuZGluZyhvcHRzPzogYW55KTogdm9pZDtcbiAgbWFya0FzUHJpc3RpbmUob3B0cz86IGFueSk6IHZvaWQ7XG4gIG1hcmtBc1RvdWNoZWQob3B0cz86IGFueSk6IHZvaWQ7XG4gIG1hcmtBc1VudG91Y2hlZChvcHRzPzogYW55KTogdm9pZDtcbiAgcGF0Y2hWYWx1ZSh2YWx1ZTogYW55LCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcbiAgcmVzZXQodmFsdWU/OiBhbnksIG9wdGlvbnM/OiBPYmplY3QpOiB2b2lkO1xuICBzZXRBc3luY1ZhbGlkYXRvcnMobmV3VmFsaWRhdG9yOiAoY29udHJvbDogYW55KSA9PiBhbnkgfFxuICAgICgoY29udHJvbDogYW55KSA9PiBhbnkpW10gfCBudWxsKTogdm9pZDtcbiAgc2V0RXJyb3JzKGVycm9yczoge1trZXk6IHN0cmluZ106IGFueX0gfCBudWxsLCBvcHRzPzogYW55KTogdm9pZDtcbiAgc2V0UGFyZW50KHBhcmVudDogYW55KTogdm9pZDtcbiAgc2V0VmFsaWRhdG9ycyhuZXdWYWxpZGF0b3I6IChjb250cm9sOiBhbnkpID0+IGFueSB8XG4gICAgKChjb250cm9sOiBhbnkpID0+IGFueSlbXSB8IG51bGwpOiB2b2lkO1xuICBzZXRWYWx1ZSh2YWx1ZTogYW55LCBvcHRpb25zPzogT2JqZWN0KTogdm9pZDtcbiAgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eShvcHRzPzogYW55KTogdm9pZDtcbiAgcGF0Y2hWYWx1ZSh2YWx1ZTogYW55LCBvcHRpb25zPzogYW55KTogdm9pZDtcbiAgcmVzZXQoZm9ybVN0YXRlPzogYW55LCBvcHRpb25zPzogYW55KTogdm9pZDtcbiAgc2V0VmFsdWUodmFsdWU6IGFueSwgb3B0aW9ucz86IGFueSk6IHZvaWQ7XG59XG4iXX0= |
---|