@clr/angular
Version:
Angular components for Clarity
290 lines • 39 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { isPlatformBrowser } from '@angular/common';
import { Directive, EventEmitter, HostBinding, HostListener, Inject, Input, Optional, Output, PLATFORM_ID, Self, } from '@angular/core';
import { of } from 'rxjs';
import { filter, switchMap } from 'rxjs/operators';
import { isBooleanAttributeSet } from '../../utils/component/is-boolean-attribute-set';
import { WrappedFormControl } from '../common/wrapped-control';
import { ClrDateContainer } from './date-container';
import { DayModel } from './model/day.model';
import { DateFormControlService } from './providers/date-form-control.service';
import { DateIOService } from './providers/date-io.service';
import { DateNavigationService } from './providers/date-navigation.service';
import { DatepickerEnabledService } from './providers/datepicker-enabled.service';
import { DatepickerFocusService } from './providers/datepicker-focus.service';
import { datesAreEqual } from './utils/date-utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "./date-container";
import * as i3 from "./providers/date-io.service";
import * as i4 from "./providers/date-navigation.service";
import * as i5 from "./providers/datepicker-enabled.service";
import * as i6 from "./providers/date-form-control.service";
import * as i7 from "../common/providers/focus.service";
import * as i8 from "./providers/datepicker-focus.service";
// There are four ways the datepicker value is set
// 1. Value set by user typing into text input as a string ex: '01/28/2015'
// 2. Value set explicitly by Angular Forms APIs as a string ex: '01/28/2015'
// 3. Value set by user via datepicker UI as a Date Object
// 4. Value set via `clrDate` input as a Date Object
export class ClrDateInput extends WrappedFormControl {
constructor(viewContainerRef, injector, el, renderer, control, container, dateIOService, dateNavigationService, datepickerEnabledService, dateFormControlService, platformId, focusService, datepickerFocusService) {
super(viewContainerRef, ClrDateContainer, injector, control, renderer, el);
this.el = el;
this.renderer = renderer;
this.control = control;
this.container = container;
this.dateIOService = dateIOService;
this.dateNavigationService = dateNavigationService;
this.datepickerEnabledService = datepickerEnabledService;
this.dateFormControlService = dateFormControlService;
this.platformId = platformId;
this.focusService = focusService;
this.datepickerFocusService = datepickerFocusService;
this.dateChange = new EventEmitter(false);
this.index = 1;
}
set date(date) {
if (this.previousDateChange !== date) {
this.updateDate(this.getValidDateValueFromDate(date));
}
if (!this.initialClrDateInputValue) {
this.initialClrDateInputValue = date;
}
}
set min(dateString) {
this.dateIOService.setMinDate(dateString);
}
set max(dateString) {
this.dateIOService.setMaxDate(dateString);
}
get disabled() {
if (this.dateFormControlService) {
return this.dateFormControlService.disabled;
}
return null;
}
set disabled(value) {
if (this.dateFormControlService) {
this.dateFormControlService.setDisabled(isBooleanAttributeSet(value));
}
}
get placeholderText() {
return this.placeholder ? this.placeholder : this.dateIOService.placeholderText;
}
get inputType() {
return isPlatformBrowser(this.platformId) && this.usingNativeDatepicker() ? 'date' : 'text';
}
ngOnInit() {
super.ngOnInit();
this.populateServicesFromContainerComponent();
this.subscriptions.push(this.listenForUserSelectedDayChanges(), this.listenForControlValueChanges(), this.listenForTouchChanges(), this.listenForDirtyChanges(), this.listenForInputRefocus());
}
ngAfterViewInit() {
// I don't know why I have to do this but after using the new HostWrapping Module I have to delay the processing
// of the initial Input set by the user to here. If I do not 2 issues occur:
// 1. The Input setter is called before ngOnInit. ngOnInit initializes the services without which the setter fails.
// 2. The Renderer doesn't work before ngAfterViewInit (It used to before the new HostWrapping Module for some reason).
// I need the renderer to set the value property on the input to make sure that if the user has supplied a Date
// input object, we reflect it with the right date on the input field using the IO service. I am not sure if
// these are major issues or not but just noting them down here.
this.processInitialInputs();
}
setFocusStates() {
this.setFocus(true);
}
triggerValidation() {
super.triggerValidation();
this.setFocus(false);
}
onValueChange(target) {
const validDateValue = this.dateIOService.getDateValueFromDateString(target.value);
if (this.usingClarityDatepicker() && validDateValue) {
this.updateDate(validDateValue, true);
}
else if (this.usingNativeDatepicker()) {
const [year, month, day] = target.value.split('-');
this.updateDate(new Date(+year, +month - 1, +day), true);
}
else {
this.emitDateOutput(null);
}
}
usingClarityDatepicker() {
return this.datepickerEnabledService.isEnabled;
}
usingNativeDatepicker() {
return !this.datepickerEnabledService.isEnabled;
}
setFocus(focus) {
if (this.focusService) {
this.focusService.focused = focus;
}
}
populateServicesFromContainerComponent() {
if (!this.container) {
this.dateIOService = this.getProviderFromContainer(DateIOService);
this.dateNavigationService = this.getProviderFromContainer(DateNavigationService);
this.datepickerEnabledService = this.getProviderFromContainer(DatepickerEnabledService);
this.dateFormControlService = this.getProviderFromContainer(DateFormControlService);
}
}
processInitialInputs() {
if (this.datepickerHasFormControl()) {
this.updateDate(this.dateIOService.getDateValueFromDateString(this.control.value));
}
else {
this.updateDate(this.initialClrDateInputValue);
}
}
updateDate(value, setByUserInteraction = false) {
const date = this.getValidDateValueFromDate(value);
if (setByUserInteraction) {
this.emitDateOutput(date);
}
else {
this.previousDateChange = date;
}
if (this.dateNavigationService) {
this.dateNavigationService.selectedDay = date
? new DayModel(date.getFullYear(), date.getMonth(), date.getDate())
: null;
}
this.updateInput(date);
}
updateInput(date) {
if (date) {
const dateString = this.dateIOService.toLocaleDisplayFormatString(date);
if (this.usingNativeDatepicker()) {
// valueAsDate expects UTC, date from input is time-zoned
date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
this.renderer.setProperty(this.el.nativeElement, 'valueAsDate', date);
}
else if (this.datepickerHasFormControl() && dateString !== this.control.value) {
this.control.control.setValue(dateString);
}
else {
this.renderer.setProperty(this.el.nativeElement, 'value', dateString);
}
}
else {
this.renderer.setProperty(this.el.nativeElement, 'value', '');
}
}
getValidDateValueFromDate(date) {
if (this.dateIOService) {
const dateString = this.dateIOService.toLocaleDisplayFormatString(date);
return this.dateIOService.getDateValueFromDateString(dateString);
}
else {
return null;
}
}
emitDateOutput(date) {
if (!datesAreEqual(date, this.previousDateChange)) {
this.dateChange.emit(date);
this.previousDateChange = date;
}
else if (!date && this.previousDateChange) {
this.dateChange.emit(null);
this.previousDateChange = null;
}
}
datepickerHasFormControl() {
return !!this.control;
}
listenForControlValueChanges() {
return of(this.datepickerHasFormControl())
.pipe(filter(hasControl => hasControl), switchMap(() => this.control.valueChanges),
// only update date value if not being set by user
filter(() => !this.datepickerFocusService.elementIsFocused(this.el.nativeElement)))
.subscribe((value) => this.updateDate(this.dateIOService.getDateValueFromDateString(value)));
}
listenForUserSelectedDayChanges() {
return this.dateNavigationService.selectedDayChange.subscribe(dayModel => this.updateDate(dayModel.toDate(), true));
}
listenForTouchChanges() {
return this.dateFormControlService.touchedChange
.pipe(filter(() => this.datepickerHasFormControl()))
.subscribe(() => this.control.control.markAsTouched());
}
listenForDirtyChanges() {
return this.dateFormControlService.dirtyChange
.pipe(filter(() => this.datepickerHasFormControl()))
.subscribe(() => this.control.control.markAsDirty());
}
listenForInputRefocus() {
return this.dateNavigationService.selectedDayChange
.pipe(filter(date => !!date))
.subscribe(() => this.datepickerFocusService.focusInput(this.el.nativeElement));
}
}
ClrDateInput.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDateInput, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.NgControl, optional: true, self: true }, { token: i2.ClrDateContainer, optional: true }, { token: i3.DateIOService, optional: true }, { token: i4.DateNavigationService, optional: true }, { token: i5.DatepickerEnabledService, optional: true }, { token: i6.DateFormControlService, optional: true }, { token: PLATFORM_ID }, { token: i7.FocusService, optional: true }, { token: i8.DatepickerFocusService }], target: i0.ɵɵFactoryTarget.Directive });
ClrDateInput.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.2", type: ClrDateInput, selector: "[clrDate]", inputs: { placeholder: "placeholder", date: ["clrDate", "date"], min: "min", max: "max", disabled: "disabled" }, outputs: { dateChange: "clrDateChange" }, host: { listeners: { "focus": "setFocusStates()", "blur": "triggerValidation()", "change": "onValueChange($event.target)" }, properties: { "class.clr-input": "true", "disabled": "this.disabled", "attr.placeholder": "this.placeholderText", "attr.type": "this.inputType" } }, providers: [DatepickerFocusService], usesInheritance: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDateInput, decorators: [{
type: Directive,
args: [{
selector: '[clrDate]',
host: {
'[class.clr-input]': 'true',
},
providers: [DatepickerFocusService],
}]
}], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.NgControl, decorators: [{
type: Self
}, {
type: Optional
}] }, { type: i2.ClrDateContainer, decorators: [{
type: Optional
}] }, { type: i3.DateIOService, decorators: [{
type: Optional
}] }, { type: i4.DateNavigationService, decorators: [{
type: Optional
}] }, { type: i5.DatepickerEnabledService, decorators: [{
type: Optional
}] }, { type: i6.DateFormControlService, decorators: [{
type: Optional
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }, { type: i7.FocusService, decorators: [{
type: Optional
}] }, { type: i8.DatepickerFocusService }]; }, propDecorators: { placeholder: [{
type: Input
}], dateChange: [{
type: Output,
args: ['clrDateChange']
}], date: [{
type: Input,
args: ['clrDate']
}], min: [{
type: Input
}], max: [{
type: Input
}], disabled: [{
type: Input,
args: ['disabled']
}, {
type: HostBinding,
args: ['disabled']
}], placeholderText: [{
type: HostBinding,
args: ['attr.placeholder']
}], inputType: [{
type: HostBinding,
args: ['attr.type']
}], setFocusStates: [{
type: HostListener,
args: ['focus']
}], triggerValidation: [{
type: HostListener,
args: ['blur']
}], onValueChange: [{
type: HostListener,
args: ['change', ['$event.target']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1pbnB1dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIvc3JjL2Zvcm1zL2RhdGVwaWNrZXIvZGF0ZS1pbnB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDcEQsT0FBTyxFQUVMLFNBQVMsRUFFVCxZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixNQUFNLEVBRU4sS0FBSyxFQUdMLFFBQVEsRUFDUixNQUFNLEVBQ04sV0FBVyxFQUVYLElBQUksR0FFTCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFCLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFFdkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQy9FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUM1RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNsRixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7QUFFbkQsa0RBQWtEO0FBQ2xELDJFQUEyRTtBQUMzRSw2RUFBNkU7QUFDN0UsMERBQTBEO0FBQzFELG9EQUFvRDtBQVNwRCxNQUFNLE9BQU8sWUFBYSxTQUFRLGtCQUFvQztJQVdwRSxZQUNFLGdCQUFrQyxFQUNsQyxRQUFrQixFQUNDLEVBQWMsRUFDZCxRQUFtQixFQUc1QixPQUFrQixFQUNSLFNBQTJCLEVBQzNCLGFBQTRCLEVBQzVCLHFCQUE0QyxFQUM1Qyx3QkFBa0QsRUFDbEQsc0JBQThDLEVBQ3JDLFVBQWUsRUFDeEIsWUFBMEIsRUFDdEMsc0JBQThDO1FBRXRELEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQWR4RCxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQ2QsYUFBUSxHQUFSLFFBQVEsQ0FBVztRQUc1QixZQUFPLEdBQVAsT0FBTyxDQUFXO1FBQ1IsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFDM0Isa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsMEJBQXFCLEdBQXJCLHFCQUFxQixDQUF1QjtRQUM1Qyw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDckMsZUFBVSxHQUFWLFVBQVUsQ0FBSztRQUN4QixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUN0QywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBdEIvQixlQUFVLEdBQUcsSUFBSSxZQUFZLENBQU8sS0FBSyxDQUFDLENBQUM7UUFFakQsVUFBSyxHQUFHLENBQUMsQ0FBQztJQXVCN0IsQ0FBQztJQUVELElBQ0ksSUFBSSxDQUFDLElBQW1CO1FBQzFCLElBQUksSUFBSSxDQUFDLGtCQUFrQixLQUFLLElBQUksRUFBRTtZQUNwQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFZLENBQUMsQ0FBQyxDQUFDO1NBQy9EO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRTtZQUNsQyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBWSxDQUFDO1NBQzlDO0lBQ0gsQ0FBQztJQUVELElBQ0ksR0FBRyxDQUFDLFVBQWtCO1FBQ3hCLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxJQUNJLEdBQUcsQ0FBQyxVQUFrQjtRQUN4QixJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUU7WUFDL0IsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsUUFBUSxDQUFDO1NBQzdDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsSUFFSSxRQUFRLENBQUMsS0FBdUI7UUFDbEMsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUU7WUFDL0IsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1NBQ3ZFO0lBQ0gsQ0FBQztJQUVELElBQ0ksZUFBZTtRQUNqQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDO0lBQ2xGLENBQUM7SUFFRCxJQUNJLFNBQVM7UUFDWCxPQUFPLGlCQUFpQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDOUYsQ0FBQztJQUVRLFFBQVE7UUFDZixLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLENBQUM7UUFFOUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQ3JCLElBQUksQ0FBQywrQkFBK0IsRUFBRSxFQUN0QyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsRUFDbkMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQzVCLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxFQUM1QixJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FDN0IsQ0FBQztJQUNKLENBQUM7SUFFRCxlQUFlO1FBQ2IsZ0hBQWdIO1FBQ2hILDRFQUE0RTtRQUM1RSxtSEFBbUg7UUFDbkgsdUhBQXVIO1FBQ3ZILCtHQUErRztRQUMvRyw0R0FBNEc7UUFDNUcsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFHRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QixDQUFDO0lBR1EsaUJBQWlCO1FBQ3hCLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUdELGFBQWEsQ0FBQyxNQUF3QjtRQUNwQyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuRixJQUFJLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLGNBQWMsRUFBRTtZQUNuRCxJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztTQUN2QzthQUFNLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUU7WUFDdkMsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztTQUMxRDthQUFNO1lBQ0wsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUMzQjtJQUNILENBQUM7SUFFTyxzQkFBc0I7UUFDNUIsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUMsU0FBUyxDQUFDO0lBQ2pELENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsT0FBTyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLENBQUM7SUFDbEQsQ0FBQztJQUVPLFFBQVEsQ0FBQyxLQUFjO1FBQzdCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7U0FDbkM7SUFDSCxDQUFDO0lBRU8sc0NBQXNDO1FBQzVDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ25CLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNsRixJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLHdCQUF3QixDQUFDLENBQUM7WUFDeEYsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1NBQ3JGO0lBQ0gsQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixJQUFJLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxFQUFFO1lBQ25DLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDcEY7YUFBTTtZQUNMLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUM7U0FDaEQ7SUFDSCxDQUFDO0lBRU8sVUFBVSxDQUFDLEtBQVcsRUFBRSxvQkFBb0IsR0FBRyxLQUFLO1FBQzFELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVuRCxJQUFJLG9CQUFvQixFQUFFO1lBQ3hCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDM0I7YUFBTTtZQUNMLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7U0FDaEM7UUFFRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtZQUM5QixJQUFJLENBQUMscUJBQXFCLENBQUMsV0FBVyxHQUFHLElBQUk7Z0JBQzNDLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDbkUsQ0FBQyxDQUFDLElBQUksQ0FBQztTQUNWO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRU8sV0FBVyxDQUFDLElBQVU7UUFDNUIsSUFBSSxJQUFJLEVBQUU7WUFDUixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hFLElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLEVBQUU7Z0JBQ2hDLHlEQUF5RDtnQkFDekQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztnQkFDOUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ3ZFO2lCQUFNLElBQUksSUFBSSxDQUFDLHdCQUF3QixFQUFFLElBQUksVUFBVSxLQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFO2dCQUMvRSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDM0M7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2FBQ3ZFO1NBQ0Y7YUFBTTtZQUNMLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztTQUMvRDtJQUNILENBQUM7SUFFTyx5QkFBeUIsQ0FBQyxJQUFVO1FBQzFDLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN0QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hFLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQywwQkFBMEIsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUNsRTthQUFNO1lBQ0wsT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUM7SUFFTyxjQUFjLENBQUMsSUFBVTtRQUMvQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRTtZQUNqRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO1NBQ2hDO2FBQU0sSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFDM0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDM0IsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztTQUNoQztJQUNILENBQUM7SUFFTyx3QkFBd0I7UUFDOUIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDO0lBRU8sNEJBQTRCO1FBQ2xDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO2FBQ3ZDLElBQUksQ0FDSCxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFDaEMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO1FBQzFDLGtEQUFrRDtRQUNsRCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUNuRjthQUNBLFNBQVMsQ0FBQyxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLDBCQUEwQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6RyxDQUFDO0lBRU8sK0JBQStCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDdEgsQ0FBQztJQUVPLHFCQUFxQjtRQUMzQixPQUFPLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxhQUFhO2FBQzdDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUMsQ0FBQzthQUNuRCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRU8scUJBQXFCO1FBQzNCLE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDLFdBQVc7YUFDM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDO2FBQ25ELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFTyxxQkFBcUI7UUFDM0IsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsaUJBQWlCO2FBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDNUIsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7O3lHQXJQVSxZQUFZLGtiQXdCYixXQUFXOzZGQXhCVixZQUFZLGlkQUZaLENBQUMsc0JBQXNCLENBQUM7MkZBRXhCLFlBQVk7a0JBUHhCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLFdBQVc7b0JBQ3JCLElBQUksRUFBRTt3QkFDSixtQkFBbUIsRUFBRSxNQUFNO3FCQUM1QjtvQkFDRCxTQUFTLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQztpQkFDcEM7OzBCQWlCSSxJQUFJOzswQkFDSixRQUFROzswQkFFUixRQUFROzswQkFDUixRQUFROzswQkFDUixRQUFROzswQkFDUixRQUFROzswQkFDUixRQUFROzswQkFDUixNQUFNOzJCQUFDLFdBQVc7OzBCQUNsQixRQUFRO2lGQXRCRixXQUFXO3NCQUFuQixLQUFLO2dCQUNtQixVQUFVO3NCQUFsQyxNQUFNO3VCQUFDLGVBQWU7Z0JBNEJuQixJQUFJO3NCQURQLEtBQUs7dUJBQUMsU0FBUztnQkFZWixHQUFHO3NCQUROLEtBQUs7Z0JBTUYsR0FBRztzQkFETixLQUFLO2dCQWNGLFFBQVE7c0JBRlgsS0FBSzt1QkFBQyxVQUFVOztzQkFDaEIsV0FBVzt1QkFBQyxVQUFVO2dCQVFuQixlQUFlO3NCQURsQixXQUFXO3VCQUFDLGtCQUFrQjtnQkFNM0IsU0FBUztzQkFEWixXQUFXO3VCQUFDLFdBQVc7Z0JBOEJ4QixjQUFjO3NCQURiLFlBQVk7dUJBQUMsT0FBTztnQkFNWixpQkFBaUI7c0JBRHpCLFlBQVk7dUJBQUMsTUFBTTtnQkFPcEIsYUFBYTtzQkFEWixZQUFZO3VCQUFDLFFBQVEsRUFBRSxDQUFDLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAyMyBWTXdhcmUsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuXG4gKiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIEluamVjdCxcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUExBVEZPUk1fSUQsXG4gIFJlbmRlcmVyMixcbiAgU2VsZixcbiAgVmlld0NvbnRhaW5lclJlZixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGlzQm9vbGVhbkF0dHJpYnV0ZVNldCB9IGZyb20gJy4uLy4uL3V0aWxzL2NvbXBvbmVudC9pcy1ib29sZWFuLWF0dHJpYnV0ZS1zZXQnO1xuaW1wb3J0IHsgRm9jdXNTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3Byb3ZpZGVycy9mb2N1cy5zZXJ2aWNlJztcbmltcG9ydCB7IFdyYXBwZWRGb3JtQ29udHJvbCB9IGZyb20gJy4uL2NvbW1vbi93cmFwcGVkLWNvbnRyb2wnO1xuaW1wb3J0IHsgQ2xyRGF0ZUNvbnRhaW5lciB9IGZyb20gJy4vZGF0ZS1jb250YWluZXInO1xuaW1wb3J0IHsgRGF5TW9kZWwgfSBmcm9tICcuL21vZGVsL2RheS5tb2RlbCc7XG5pbXBvcnQgeyBEYXRlRm9ybUNvbnRyb2xTZXJ2aWNlIH0gZnJvbSAnLi9wcm92aWRlcnMvZGF0ZS1mb3JtLWNvbnRyb2wuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlSU9TZXJ2aWNlIH0gZnJvbSAnLi9wcm92aWRlcnMvZGF0ZS1pby5zZXJ2aWNlJztcbmltcG9ydCB7IERhdGVOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4vcHJvdmlkZXJzL2RhdGUtbmF2aWdhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IERhdGVwaWNrZXJFbmFibGVkU2VydmljZSB9IGZyb20gJy4vcHJvdmlkZXJzL2RhdGVwaWNrZXItZW5hYmxlZC5zZXJ2aWNlJztcbmltcG9ydCB7IERhdGVwaWNrZXJGb2N1c1NlcnZpY2UgfSBmcm9tICcuL3Byb3ZpZGVycy9kYXRlcGlja2VyLWZvY3VzLnNlcnZpY2UnO1xuaW1wb3J0IHsgZGF0ZXNBcmVFcXVhbCB9IGZyb20gJy4vdXRpbHMvZGF0ZS11dGlscyc7XG5cbi8vIFRoZXJlIGFyZSBmb3VyIHdheXMgdGhlIGRhdGVwaWNrZXIgdmFsdWUgaXMgc2V0XG4vLyAxLiBWYWx1ZSBzZXQgYnkgdXNlciB0eXBpbmcgaW50byB0ZXh0IGlucHV0IGFzIGEgc3RyaW5nIGV4OiAnMDEvMjgvMjAxNSdcbi8vIDIuIFZhbHVlIHNldCBleHBsaWNpdGx5IGJ5IEFuZ3VsYXIgRm9ybXMgQVBJcyBhcyBhIHN0cmluZyBleDogJzAxLzI4LzIwMTUnXG4vLyAzLiBWYWx1ZSBzZXQgYnkgdXNlciB2aWEgZGF0ZXBpY2tlciBVSSBhcyBhIERhdGUgT2JqZWN0XG4vLyA0LiBWYWx1ZSBzZXQgdmlhIGBjbHJEYXRlYCBpbnB1dCBhcyBhIERhdGUgT2JqZWN0XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjbHJEYXRlXScsXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzLmNsci1pbnB1dF0nOiAndHJ1ZScsXG4gIH0sXG4gIHByb3ZpZGVyczogW0RhdGVwaWNrZXJGb2N1c1NlcnZpY2VdLFxufSlcbmV4cG9ydCBjbGFzcyBDbHJEYXRlSW5wdXQgZXh0ZW5kcyBXcmFwcGVkRm9ybUNvbnRyb2w8Q2xyRGF0ZUNvbnRhaW5lcj4gaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9kYXRlOiBEYXRlIHwgbnVsbCB8IHN0cmluZztcblxuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nO1xuICBAT3V0cHV0KCdjbHJEYXRlQ2hhbmdlJykgZGF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZT4oZmFsc2UpO1xuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBpbmRleCA9IDE7XG5cbiAgcHJpdmF0ZSBpbml0aWFsQ2xyRGF0ZUlucHV0VmFsdWU6IERhdGU7XG4gIHByaXZhdGUgcHJldmlvdXNEYXRlQ2hhbmdlOiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXG4gICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCBvdmVycmlkZSBlbDogRWxlbWVudFJlZixcbiAgICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBAU2VsZigpXG4gICAgQE9wdGlvbmFsKClcbiAgICBwcm90ZWN0ZWQgY29udHJvbDogTmdDb250cm9sLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgY29udGFpbmVyOiBDbHJEYXRlQ29udGFpbmVyLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZGF0ZUlPU2VydmljZTogRGF0ZUlPU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGRhdGVOYXZpZ2F0aW9uU2VydmljZTogRGF0ZU5hdmlnYXRpb25TZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZGF0ZXBpY2tlckVuYWJsZWRTZXJ2aWNlOiBEYXRlcGlja2VyRW5hYmxlZFNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkYXRlRm9ybUNvbnRyb2xTZXJ2aWNlOiBEYXRlRm9ybUNvbnRyb2xTZXJ2aWNlLFxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogYW55LFxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgZm9jdXNTZXJ2aWNlOiBGb2N1c1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBkYXRlcGlja2VyRm9jdXNTZXJ2aWNlOiBEYXRlcGlja2VyRm9jdXNTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKHZpZXdDb250YWluZXJSZWYsIENsckRhdGVDb250YWluZXIsIGluamVjdG9yLCBjb250cm9sLCByZW5kZXJlciwgZWwpO1xuICB9XG5cbiAgQElucHV0KCdjbHJEYXRlJylcbiAgc2V0IGRhdGUoZGF0ZTogRGF0ZSB8IHN0cmluZykge1xuICAgIGlmICh0aGlzLnByZXZpb3VzRGF0ZUNoYW5nZSAhPT0gZGF0ZSkge1xuICAgICAgdGhpcy51cGRhdGVEYXRlKHRoaXMuZ2V0VmFsaWREYXRlVmFsdWVGcm9tRGF0ZShkYXRlIGFzIERhdGUpKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaW5pdGlhbENsckRhdGVJbnB1dFZhbHVlKSB7XG4gICAgICB0aGlzLmluaXRpYWxDbHJEYXRlSW5wdXRWYWx1ZSA9IGRhdGUgYXMgRGF0ZTtcbiAgICB9XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgbWluKGRhdGVTdHJpbmc6IHN0cmluZykge1xuICAgIHRoaXMuZGF0ZUlPU2VydmljZS5zZXRNaW5EYXRlKGRhdGVTdHJpbmcpO1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IG1heChkYXRlU3RyaW5nOiBzdHJpbmcpIHtcbiAgICB0aGlzLmRhdGVJT1NlcnZpY2Uuc2V0TWF4RGF0ZShkYXRlU3RyaW5nKTtcbiAgfVxuXG4gIGdldCBkaXNhYmxlZCgpIHtcbiAgICBpZiAodGhpcy5kYXRlRm9ybUNvbnRyb2xTZXJ2aWNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5kYXRlRm9ybUNvbnRyb2xTZXJ2aWNlLmRpc2FibGVkO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIEBJbnB1dCgnZGlzYWJsZWQnKVxuICBASG9zdEJpbmRpbmcoJ2Rpc2FibGVkJylcbiAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuZGF0ZUZvcm1Db250cm9sU2VydmljZSkge1xuICAgICAgdGhpcy5kYXRlRm9ybUNvbnRyb2xTZXJ2aWNlLnNldERpc2FibGVkKGlzQm9vbGVhbkF0dHJpYnV0ZVNldCh2YWx1ZSkpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0QmluZGluZygnYXR0ci5wbGFjZWhvbGRlcicpXG4gIGdldCBwbGFjZWhvbGRlclRleHQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5wbGFjZWhvbGRlciA/IHRoaXMucGxhY2Vob2xkZXIgOiB0aGlzLmRhdGVJT1NlcnZpY2UucGxhY2Vob2xkZXJUZXh0O1xuICB9XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLnR5cGUnKVxuICBnZXQgaW5wdXRUeXBlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkgJiYgdGhpcy51c2luZ05hdGl2ZURhdGVwaWNrZXIoKSA/ICdkYXRlJyA6ICd0ZXh0JztcbiAgfVxuXG4gIG92ZXJyaWRlIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG4gICAgdGhpcy5wb3B1bGF0ZVNlcnZpY2VzRnJvbUNvbnRhaW5lckNvbXBvbmVudCgpO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLmxpc3RlbkZvclVzZXJTZWxlY3RlZERheUNoYW5nZXMoKSxcbiAgICAgIHRoaXMubGlzdGVuRm9yQ29udHJvbFZhbHVlQ2hhbmdlcygpLFxuICAgICAgdGhpcy5saXN0ZW5Gb3JUb3VjaENoYW5nZXMoKSxcbiAgICAgIHRoaXMubGlzdGVuRm9yRGlydHlDaGFuZ2VzKCksXG4gICAgICB0aGlzLmxpc3RlbkZvcklucHV0UmVmb2N1cygpXG4gICAgKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAvLyBJIGRvbid0IGtub3cgd2h5IEkgaGF2ZSB0byBkbyB0aGlzIGJ1dCBhZnRlciB1c2luZyB0aGUgbmV3IEhvc3RXcmFwcGluZyBNb2R1bGUgSSBoYXZlIHRvIGRlbGF5IHRoZSBwcm9jZXNzaW5nXG4gICAgLy8gb2YgdGhlIGluaXRpYWwgSW5wdXQgc2V0IGJ5IHRoZSB1c2VyIHRvIGhlcmUuIElmIEkgZG8gbm90IDIgaXNzdWVzIG9jY3VyOlxuICAgIC8vIDEuIFRoZSBJbnB1dCBzZXR0ZXIgaXMgY2FsbGVkIGJlZm9yZSBuZ09uSW5pdC4gbmdPbkluaXQgaW5pdGlhbGl6ZXMgdGhlIHNlcnZpY2VzIHdpdGhvdXQgd2hpY2ggdGhlIHNldHRlciBmYWlscy5cbiAgICAvLyAyLiBUaGUgUmVuZGVyZXIgZG9lc24ndCB3b3JrIGJlZm9yZSBuZ0FmdGVyVmlld0luaXQgKEl0IHVzZWQgdG8gYmVmb3JlIHRoZSBuZXcgSG9zdFdyYXBwaW5nIE1vZHVsZSBmb3Igc29tZSByZWFzb24pLlxuICAgIC8vIEkgbmVlZCB0aGUgcmVuZGVyZXIgdG8gc2V0IHRoZSB2YWx1ZSBwcm9wZXJ0eSBvbiB0aGUgaW5wdXQgdG8gbWFrZSBzdXJlIHRoYXQgaWYgdGhlIHVzZXIgaGFzIHN1cHBsaWVkIGEgRGF0ZVxuICAgIC8vIGlucHV0IG9iamVjdCwgd2UgcmVmbGVjdCBpdCB3aXRoIHRoZSByaWdodCBkYXRlIG9uIHRoZSBpbnB1dCBmaWVsZCB1c2luZyB0aGUgSU8gc2VydmljZS4gSSBhbSBub3Qgc3VyZSBpZlxuICAgIC8vIHRoZXNlIGFyZSBtYWpvciBpc3N1ZXMgb3Igbm90IGJ1dCBqdXN0IG5vdGluZyB0aGVtIGRvd24gaGVyZS5cbiAgICB0aGlzLnByb2Nlc3NJbml0aWFsSW5wdXRzKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdmb2N1cycpXG4gIHNldEZvY3VzU3RhdGVzKCkge1xuICAgIHRoaXMuc2V0Rm9jdXModHJ1ZSk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdibHVyJylcbiAgb3ZlcnJpZGUgdHJpZ2dlclZhbGlkYXRpb24oKSB7XG4gICAgc3VwZXIudHJpZ2dlclZhbGlkYXRpb24oKTtcbiAgICB0aGlzLnNldEZvY3VzKGZhbHNlKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2NoYW5nZScsIFsnJGV2ZW50LnRhcmdldCddKVxuICBvblZhbHVlQ2hhbmdlKHRhcmdldDogSFRNTElucHV0RWxlbWVudCkge1xuICAgIGNvbnN0IHZhbGlkRGF0ZVZhbHVlID0gdGhpcy5kYXRlSU9TZXJ2aWNlLmdldERhdGVWYWx1ZUZyb21EYXRlU3RyaW5nKHRhcmdldC52YWx1ZSk7XG4gICAgaWYgKHRoaXMudXNpbmdDbGFyaXR5RGF0ZXBpY2tlcigpICYmIHZhbGlkRGF0ZVZhbHVlKSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGUodmFsaWREYXRlVmFsdWUsIHRydWUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy51c2luZ05hdGl2ZURhdGVwaWNrZXIoKSkge1xuICAgICAgY29uc3QgW3llYXIsIG1vbnRoLCBkYXldID0gdGFyZ2V0LnZhbHVlLnNwbGl0KCctJyk7XG4gICAgICB0aGlzLnVwZGF0ZURhdGUobmV3IERhdGUoK3llYXIsICttb250aCAtIDEsICtkYXkpLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0RGF0ZU91dHB1dChudWxsKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVzaW5nQ2xhcml0eURhdGVwaWNrZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZXBpY2tlckVuYWJsZWRTZXJ2aWNlLmlzRW5hYmxlZDtcbiAgfVxuXG4gIHByaXZhdGUgdXNpbmdOYXRpdmVEYXRlcGlja2VyKCkge1xuICAgIHJldHVybiAhdGhpcy5kYXRlcGlja2VyRW5hYmxlZFNlcnZpY2UuaXNFbmFibGVkO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRGb2N1cyhmb2N1czogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLmZvY3VzU2VydmljZSkge1xuICAgICAgdGhpcy5mb2N1c1NlcnZpY2UuZm9jdXNlZCA9IGZvY3VzO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcG9wdWxhdGVTZXJ2aWNlc0Zyb21Db250YWluZXJDb21wb25lbnQoKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRhaW5lcikge1xuICAgICAgdGhpcy5kYXRlSU9TZXJ2aWNlID0gdGhpcy5nZXRQcm92aWRlckZyb21Db250YWluZXIoRGF0ZUlPU2VydmljZSk7XG4gICAgICB0aGlzLmRhdGVOYXZpZ2F0aW9uU2VydmljZSA9IHRoaXMuZ2V0UHJvdmlkZXJGcm9tQ29udGFpbmVyKERhdGVOYXZpZ2F0aW9uU2VydmljZSk7XG4gICAgICB0aGlzLmRhdGVwaWNrZXJFbmFibGVkU2VydmljZSA9IHRoaXMuZ2V0UHJvdmlkZXJGcm9tQ29udGFpbmVyKERhdGVwaWNrZXJFbmFibGVkU2VydmljZSk7XG4gICAgICB0aGlzLmRhdGVGb3JtQ29udHJvbFNlcnZpY2UgPSB0aGlzLmdldFByb3ZpZGVyRnJvbUNvbnRhaW5lcihEYXRlRm9ybUNvbnRyb2xTZXJ2aWNlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NJbml0aWFsSW5wdXRzKCkge1xuICAgIGlmICh0aGlzLmRhdGVwaWNrZXJIYXNGb3JtQ29udHJvbCgpKSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGUodGhpcy5kYXRlSU9TZXJ2aWNlLmdldERhdGVWYWx1ZUZyb21EYXRlU3RyaW5nKHRoaXMuY29udHJvbC52YWx1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGUodGhpcy5pbml0aWFsQ2xyRGF0ZUlucHV0VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRGF0ZSh2YWx1ZTogRGF0ZSwgc2V0QnlVc2VySW50ZXJhY3Rpb24gPSBmYWxzZSkge1xuICAgIGNvbnN0IGRhdGUgPSB0aGlzLmdldFZhbGlkRGF0ZVZhbHVlRnJvbURhdGUodmFsdWUpO1xuXG4gICAgaWYgKHNldEJ5VXNlckludGVyYWN0aW9uKSB7XG4gICAgICB0aGlzLmVtaXREYXRlT3V0cHV0KGRhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnByZXZpb3VzRGF0ZUNoYW5nZSA9IGRhdGU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZGF0ZU5hdmlnYXRpb25TZXJ2aWNlKSB7XG4gICAgICB0aGlzLmRhdGVOYXZpZ2F0aW9uU2VydmljZS5zZWxlY3RlZERheSA9IGRhdGVcbiAgICAgICAgPyBuZXcgRGF5TW9kZWwoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIGRhdGUuZ2V0RGF0ZSgpKVxuICAgICAgICA6IG51bGw7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVJbnB1dChkYXRlKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlSW5wdXQoZGF0ZTogRGF0ZSkge1xuICAgIGlmIChkYXRlKSB7XG4gICAgICBjb25zdCBkYXRlU3RyaW5nID0gdGhpcy5kYXRlSU9TZXJ2aWNlLnRvTG9jYWxlRGlzcGxheUZvcm1hdFN0cmluZyhkYXRlKTtcbiAgICAgIGlmICh0aGlzLnVzaW5nTmF0aXZlRGF0ZXBpY2tlcigpKSB7XG4gICAgICAgIC8vIHZhbHVlQXNEYXRlIGV4cGVjdHMgVVRDLCBkYXRlIGZyb20gaW5wdXQgaXMgdGltZS16b25lZFxuICAgICAgICBkYXRlLnNldE1pbnV0ZXMoZGF0ZS5nZXRNaW51dGVzKCkgLSBkYXRlLmdldFRpbWV6b25lT2Zmc2V0KCkpO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ3ZhbHVlQXNEYXRlJywgZGF0ZSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGF0ZXBpY2tlckhhc0Zvcm1Db250cm9sKCkgJiYgZGF0ZVN0cmluZyAhPT0gdGhpcy5jb250cm9sLnZhbHVlKSB7XG4gICAgICAgIHRoaXMuY29udHJvbC5jb250cm9sLnNldFZhbHVlKGRhdGVTdHJpbmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICd2YWx1ZScsIGRhdGVTdHJpbmcpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJ3ZhbHVlJywgJycpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VmFsaWREYXRlVmFsdWVGcm9tRGF0ZShkYXRlOiBEYXRlKSB7XG4gICAgaWYgKHRoaXMuZGF0ZUlPU2VydmljZSkge1xuICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IHRoaXMuZGF0ZUlPU2VydmljZS50b0xvY2FsZURpc3BsYXlGb3JtYXRTdHJpbmcoZGF0ZSk7XG4gICAgICByZXR1cm4gdGhpcy5kYXRlSU9TZXJ2aWNlLmdldERhdGVWYWx1ZUZyb21EYXRlU3RyaW5nKGRhdGVTdHJpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVtaXREYXRlT3V0cHV0KGRhdGU6IERhdGUpIHtcbiAgICBpZiAoIWRhdGVzQXJlRXF1YWwoZGF0ZSwgdGhpcy5wcmV2aW91c0RhdGVDaGFuZ2UpKSB7XG4gICAgICB0aGlzLmRhdGVDaGFuZ2UuZW1pdChkYXRlKTtcbiAgICAgIHRoaXMucHJldmlvdXNEYXRlQ2hhbmdlID0gZGF0ZTtcbiAgICB9IGVsc2UgaWYgKCFkYXRlICYmIHRoaXMucHJldmlvdXNEYXRlQ2hhbmdlKSB7XG4gICAgICB0aGlzLmRhdGVDaGFuZ2UuZW1pdChudWxsKTtcbiAgICAgIHRoaXMucHJldmlvdXNEYXRlQ2hhbmdlID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRhdGVwaWNrZXJIYXNGb3JtQ29udHJvbCgpIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbnRyb2w7XG4gIH1cblxuICBwcml2YXRlIGxpc3RlbkZvckNvbnRyb2xWYWx1ZUNoYW5nZXMoKSB7XG4gICAgcmV0dXJuIG9mKHRoaXMuZGF0ZXBpY2tlckhhc0Zvcm1Db250cm9sKCkpXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKGhhc0NvbnRyb2wgPT4gaGFzQ29udHJvbCksXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLmNvbnRyb2wudmFsdWVDaGFuZ2VzKSxcbiAgICAgICAgLy8gb25seSB1cGRhdGUgZGF0ZSB2YWx1ZSBpZiBub3QgYmVpbmcgc2V0IGJ5IHVzZXJcbiAgICAgICAgZmlsdGVyKCgpID0+ICF0aGlzLmRhdGVwaWNrZXJGb2N1c1NlcnZpY2UuZWxlbWVudElzRm9jdXNlZCh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWU6IHN0cmluZykgPT4gdGhpcy51cGRhdGVEYXRlKHRoaXMuZGF0ZUlPU2VydmljZS5nZXREYXRlVmFsdWVGcm9tRGF0ZVN0cmluZyh2YWx1ZSkpKTtcbiAgfVxuXG4gIHByaXZhdGUgbGlzdGVuRm9yVXNlclNlbGVjdGVkRGF5Q2hhbmdlcygpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRlTmF2aWdhdGlvblNlcnZpY2Uuc2VsZWN0ZWREYXlDaGFuZ2Uuc3Vic2NyaWJlKGRheU1vZGVsID0+IHRoaXMudXBkYXRlRGF0ZShkYXlNb2RlbC50b0RhdGUoKSwgdHJ1ZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBsaXN0ZW5Gb3JUb3VjaENoYW5nZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZUZvcm1Db250cm9sU2VydmljZS50b3VjaGVkQ2hhbmdlXG4gICAgICAucGlwZShmaWx0ZXIoKCkgPT4gdGhpcy5kYXRlcGlja2VySGFzRm9ybUNvbnRyb2woKSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuY29udHJvbC5jb250cm9sLm1hcmtBc1RvdWNoZWQoKSk7XG4gIH1cblxuICBwcml2YXRlIGxpc3RlbkZvckRpcnR5Q2hhbmdlcygpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRlRm9ybUNvbnRyb2xTZXJ2aWNlLmRpcnR5Q2hhbmdlXG4gICAgICAucGlwZShmaWx0ZXIoKCkgPT4gdGhpcy5kYXRlcGlja2VySGFzRm9ybUNvbnRyb2woKSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuY29udHJvbC5jb250cm9sLm1hcmtBc0RpcnR5KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBsaXN0ZW5Gb3JJbnB1dFJlZm9jdXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZU5hdmlnYXRpb25TZXJ2aWNlLnNlbGVjdGVkRGF5Q2hhbmdlXG4gICAgICAucGlwZShmaWx0ZXIoZGF0ZSA9PiAhIWRhdGUpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLmRhdGVwaWNrZXJGb2N1c1NlcnZpY2UuZm9jdXNJbnB1dCh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpKTtcbiAgfVxufVxuIl19