UNPKG

@herculesproject/datetime-picker

Version:
628 lines 51.8 kB
/** * @fileoverview added by tsickle * Generated from: lib/datetime-input.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { DOWN_ARROW } from '@angular/cdk/keycodes'; import { Directive, ElementRef, EventEmitter, forwardRef, Inject, Input, Optional, Output } from '@angular/core'; import { NG_VALIDATORS, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; import { MatFormField } from '@angular/material/form-field'; import { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input'; import { Subscription } from 'rxjs'; import { NgxMatDateAdapter } from './core/date-adapter'; import { NGX_MAT_DATE_FORMATS } from './core/date-formats'; import { NgxMatDatetimePicker } from './datetime-picker.component'; import { createMissingDateImplError } from './utils/date-utils'; /** * \@docs-private * @type {?} */ export const MAT_DATEPICKER_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => NgxMatDatetimeInput)), multi: true }; /** * \@docs-private * @type {?} */ export const MAT_DATEPICKER_VALIDATORS = { provide: NG_VALIDATORS, useExisting: forwardRef((/** * @return {?} */ () => NgxMatDatetimeInput)), multi: true }; /** * An event used for datepicker input and change events. We don't always have access to a native * input or change event because the event may have been triggered by the user clicking on the * calendar popup. For consistency, we always use MatDatetimePickerInputEvent instead. * @template D */ export class MatDatetimePickerInputEvent { /** * @param {?} target * @param {?} targetElement */ constructor(target, targetElement) { this.target = target; this.targetElement = targetElement; this.value = this.target.value; } } if (false) { /** * The new value for the target datepicker input. * @type {?} */ MatDatetimePickerInputEvent.prototype.value; /** * Reference to the datepicker input component that emitted the event. * @type {?} */ MatDatetimePickerInputEvent.prototype.target; /** * Reference to the native input element associated with the datepicker input. * @type {?} */ MatDatetimePickerInputEvent.prototype.targetElement; } /** * Directive used to connect an input to a matDatetimePicker. * @template D */ export class NgxMatDatetimeInput { /** * @param {?} _elementRef * @param {?} _dateAdapter * @param {?} _dateFormats * @param {?} _formField */ constructor(_elementRef, _dateAdapter, _dateFormats, _formField) { this._elementRef = _elementRef; this._dateAdapter = _dateAdapter; this._dateFormats = _dateFormats; this._formField = _formField; /** * Emits when a `change` event is fired on this `<input>`. */ this.dateChange = new EventEmitter(); /** * Emits when an `input` event is fired on this `<input>`. */ this.dateInput = new EventEmitter(); /** * Emits when the value changes (either due to user input or programmatic change). */ this._valueChange = new EventEmitter(); /** * Emits when the disabled state has changed */ this.stateChanges = new EventEmitter(); this._onTouched = (/** * @return {?} */ () => { }); this._cvaOnChange = (/** * @return {?} */ () => { }); this._validatorOnChange = (/** * @return {?} */ () => { }); this._datepickerSubscription = Subscription.EMPTY; this._localeSubscription = Subscription.EMPTY; /** * The form control validator for whether the input parses. */ this._parseValidator = (/** * @return {?} */ () => { return this._lastValueValid ? null : { 'matDatetimePickerParse': { 'text': this._elementRef.nativeElement.value } }; }); /** * The form control validator for the min date. */ this._minValidator = (/** * @param {?} control * @return {?} */ (control) => { /** @type {?} */ const controlValue = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value)); return (!this.min || !controlValue || this._dateAdapter.compareDateWithTime(this.min, controlValue, this._datepicker.showSeconds) <= 0) ? null : { 'matDatetimePickerMin': { 'min': this.min, 'actual': controlValue } }; }); /** * The form control validator for the max date. */ this._maxValidator = (/** * @param {?} control * @return {?} */ (control) => { /** @type {?} */ const controlValue = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value)); return (!this.max || !controlValue || this._dateAdapter.compareDateWithTime(this.max, controlValue, this._datepicker.showSeconds) >= 0) ? null : { 'matDatetimePickerMax': { 'max': this.max, 'actual': controlValue } }; }); /** * The form control validator for the date filter. */ this._filterValidator = (/** * @param {?} control * @return {?} */ (control) => { /** @type {?} */ const controlValue = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value)); return !this._dateFilter || !controlValue || this._dateFilter(controlValue) ? null : { 'matDatetimePickerFilter': true }; }); /** * The combined form control validator for this input. */ this._validator = Validators.compose([this._parseValidator, this._minValidator, this._maxValidator, this._filterValidator]); /** * Whether the last value set on the input was valid. */ this._lastValueValid = false; if (!this._dateAdapter) { throw createMissingDateImplError('NgxMatDateAdapter'); } if (!this._dateFormats) { throw createMissingDateImplError('NGX_MAT_DATE_FORMATS'); } // Update the displayed date when the locale changes. this._localeSubscription = _dateAdapter.localeChanges.subscribe((/** * @return {?} */ () => { this.value = this.value; })); } /** * The datepicker that this input is associated with. * @param {?} value * @return {?} */ set ngxMatDatetimePicker(value) { if (!value) { return; } this._datepicker = value; this._datepicker._registerInput(this); this._datepickerSubscription.unsubscribe(); this._datepickerSubscription = this._datepicker._selectedChanged.subscribe((/** * @param {?} selected * @return {?} */ (selected) => { this.value = selected; this._cvaOnChange(selected); this._onTouched(); this.dateInput.emit(new MatDatetimePickerInputEvent(this, this._elementRef.nativeElement)); this.dateChange.emit(new MatDatetimePickerInputEvent(this, this._elementRef.nativeElement)); })); } /** * Function that can be used to filter out dates within the datepicker. * @param {?} value * @return {?} */ set ngxMatDatetimePickerFilter(value) { this._dateFilter = value; this._validatorOnChange(); } /** * The value of the input. * @return {?} */ get value() { return this._value; } /** * @param {?} value * @return {?} */ set value(value) { value = this._dateAdapter.deserialize(value); this._lastValueValid = !value || this._dateAdapter.isValid(value); value = this._getValidDateOrNull(value); /** @type {?} */ const oldDate = this.value; this._value = value; this._formatValue(value); if (!this._dateAdapter.sameDate(oldDate, value)) { this._valueChange.emit(value); } } /** * The minimum valid date. * @return {?} */ get min() { return this._min; } /** * @param {?} value * @return {?} */ set min(value) { this._min = this._getValidDateOrNull(this._dateAdapter.deserialize(value)); this._validatorOnChange(); } /** * The maximum valid date. * @return {?} */ get max() { return this._max; } /** * @param {?} value * @return {?} */ set max(value) { this._max = this._getValidDateOrNull(this._dateAdapter.deserialize(value)); this._validatorOnChange(); } /** * Whether the datepicker-input is disabled. * @return {?} */ get disabled() { return !!this._disabled; } /** * @param {?} value * @return {?} */ set disabled(value) { /** @type {?} */ const newValue = value != null && `${value}` !== 'false'; /** @type {?} */ const element = this._elementRef.nativeElement; if (this._disabled !== newValue) { this._disabled = newValue; this.stateChanges.emit(undefined); } // We need to null check the `blur` method, because it's undefined during SSR. if (newValue && element.blur) { // Normally, native input elements automatically blur if they turn disabled. This behavior // is problematic, because it would mean that it triggers another change detection cycle, // which then causes a changed after checked error if the input element was focused before. element.blur(); } } /** * @return {?} */ ngOnDestroy() { this._datepickerSubscription.unsubscribe(); this._localeSubscription.unsubscribe(); this._valueChange.complete(); this.stateChanges.complete(); } /** * \@docs-private * @param {?} fn * @return {?} */ registerOnValidatorChange(fn) { this._validatorOnChange = fn; } /** * \@docs-private * @param {?} c * @return {?} */ validate(c) { return this._validator ? this._validator(c) : null; } /** * @deprecated * \@breaking-change 8.0.0 Use `getConnectedOverlayOrigin` instead * @return {?} */ getPopupConnectionElementRef() { return this.getConnectedOverlayOrigin(); } /** * Gets the element that the datepicker popup should be connected to. * @return {?} The element to connect the popup to. */ getConnectedOverlayOrigin() { return this._formField ? this._formField.getConnectedOverlayOrigin() : this._elementRef; } // Implemented as part of ControlValueAccessor. /** * @param {?} value * @return {?} */ writeValue(value) { this.value = value; } // Implemented as part of ControlValueAccessor. /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this._cvaOnChange = fn; } // Implemented as part of ControlValueAccessor. /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this._onTouched = fn; } // Implemented as part of ControlValueAccessor. /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * @param {?} event * @return {?} */ _onKeydown(event) { /** @type {?} */ const isAltDownArrow = event.altKey && event.keyCode === DOWN_ARROW; if (this._datepicker && isAltDownArrow && !this._elementRef.nativeElement.readOnly) { this._datepicker.open(); event.preventDefault(); } } /** * @param {?} value * @return {?} */ _onInput(value) { /** @type {?} */ const lastValueWasValid = this._lastValueValid; /** @type {?} */ let date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput); this._lastValueValid = !date || this._dateAdapter.isValid(date); date = this._getValidDateOrNull(date); /** @type {?} */ const isSameTime = this._dateAdapter.isSameTime(date, this._value); if ((date != null && (!isSameTime || !this._dateAdapter.sameDate(date, this._value))) || (date == null && this._value != null)) { this._value = date; this._cvaOnChange(date); this._valueChange.emit(date); this.dateInput.emit(new MatDatetimePickerInputEvent(this, this._elementRef.nativeElement)); } else if (lastValueWasValid !== this._lastValueValid) { this._validatorOnChange(); } } /** * @return {?} */ _onChange() { this.dateChange.emit(new MatDatetimePickerInputEvent(this, this._elementRef.nativeElement)); } /** * Returns the palette used by the input's form field, if any. * @return {?} */ _getThemePalette() { return this._formField ? this._formField.color : undefined; } /** * Handles blur events on the input. * @return {?} */ _onBlur() { // Reformat the input only if we have a valid value. if (this.value) { this._formatValue(this.value); } this._onTouched(); } /** * Handles focus events on the input. * @return {?} */ _onFocus() { // Close datetime picker if opened if (this._datepicker && this._datepicker.opened) { this._datepicker.cancel(); } } /** * Formats a value and sets it on the input element. * @private * @param {?} value * @return {?} */ _formatValue(value) { this._elementRef.nativeElement.value = value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : ''; } /** * @private * @param {?} obj The object to check. * @return {?} The given object if it is both a date instance and valid, otherwise null. */ _getValidDateOrNull(obj) { return (this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj)) ? obj : null; } } NgxMatDatetimeInput.decorators = [ { type: Directive, args: [{ selector: 'input[ngxMatDatetimePicker]', providers: [ MAT_DATEPICKER_VALUE_ACCESSOR, MAT_DATEPICKER_VALIDATORS, { provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: NgxMatDatetimeInput }, ], host: { '[attr.aria-haspopup]': '_datepicker ? "dialog" : null', '[attr.aria-owns]': '(_datepicker?.opened && _datepicker.id) || null', '[attr.min]': 'min ? _dateAdapter.toIso8601(min) : null', '[attr.max]': 'max ? _dateAdapter.toIso8601(max) : null', '[disabled]': 'disabled', '(input)': '_onInput($event.target.value)', '(change)': '_onChange()', '(blur)': '_onBlur()', '(focus)': '_onFocus()', '(keydown)': '_onKeydown($event)', }, exportAs: 'ngxMatDatetimePickerInput', },] } ]; /** @nocollapse */ NgxMatDatetimeInput.ctorParameters = () => [ { type: ElementRef }, { type: NgxMatDateAdapter, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NGX_MAT_DATE_FORMATS,] }] }, { type: MatFormField, decorators: [{ type: Optional }] } ]; NgxMatDatetimeInput.propDecorators = { ngxMatDatetimePicker: [{ type: Input }], ngxMatDatetimePickerFilter: [{ type: Input }], value: [{ type: Input }], min: [{ type: Input }], max: [{ type: Input }], disabled: [{ type: Input }], dateChange: [{ type: Output }], dateInput: [{ type: Output }] }; if (false) { /** @type {?} */ NgxMatDatetimeInput.prototype._datepicker; /** @type {?} */ NgxMatDatetimeInput.prototype._dateFilter; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._value; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._min; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._max; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._disabled; /** * Emits when a `change` event is fired on this `<input>`. * @type {?} */ NgxMatDatetimeInput.prototype.dateChange; /** * Emits when an `input` event is fired on this `<input>`. * @type {?} */ NgxMatDatetimeInput.prototype.dateInput; /** * Emits when the value changes (either due to user input or programmatic change). * @type {?} */ NgxMatDatetimeInput.prototype._valueChange; /** * Emits when the disabled state has changed * @type {?} */ NgxMatDatetimeInput.prototype.stateChanges; /** @type {?} */ NgxMatDatetimeInput.prototype._onTouched; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._cvaOnChange; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._validatorOnChange; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._datepickerSubscription; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._localeSubscription; /** * The form control validator for whether the input parses. * @type {?} * @private */ NgxMatDatetimeInput.prototype._parseValidator; /** * The form control validator for the min date. * @type {?} * @private */ NgxMatDatetimeInput.prototype._minValidator; /** * The form control validator for the max date. * @type {?} * @private */ NgxMatDatetimeInput.prototype._maxValidator; /** * The form control validator for the date filter. * @type {?} * @private */ NgxMatDatetimeInput.prototype._filterValidator; /** * The combined form control validator for this input. * @type {?} * @private */ NgxMatDatetimeInput.prototype._validator; /** * Whether the last value set on the input was valid. * @type {?} * @private */ NgxMatDatetimeInput.prototype._lastValueValid; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._elementRef; /** @type {?} */ NgxMatDatetimeInput.prototype._dateAdapter; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._dateFormats; /** * @type {?} * @private */ NgxMatDatetimeInput.prototype._formField; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUtaW5wdXQuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vcHJvamVjdHMvZGF0ZXRpbWUtcGlja2VyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9kYXRldGltZS1pbnB1dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFhLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUgsT0FBTyxFQUF5QyxhQUFhLEVBQUUsaUJBQWlCLEVBQTRDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRS9KLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hELE9BQU8sRUFBcUIsb0JBQW9CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7Ozs7QUFHaEUsTUFBTSxPQUFPLDZCQUE2QixHQUFRO0lBQzlDLE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVU7OztJQUFDLEdBQUcsRUFBRSxDQUFDLG1CQUFtQixFQUFDO0lBQ2xELEtBQUssRUFBRSxJQUFJO0NBQ2Q7Ozs7O0FBR0QsTUFBTSxPQUFPLHlCQUF5QixHQUFRO0lBQzFDLE9BQU8sRUFBRSxhQUFhO0lBQ3RCLFdBQVcsRUFB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QTRDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IERPV05fQVJST1cgfSBmcm9tICdAYW5ndWxhci9jZGsva2V5Y29kZXMnO1xuaW1wb3J0IHsgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIGZvcndhcmRSZWYsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT3B0aW9uYWwsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMSURBVE9SUywgTkdfVkFMVUVfQUNDRVNTT1IsIFZhbGlkYXRpb25FcnJvcnMsIFZhbGlkYXRvciwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBUaGVtZVBhbGV0dGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTUFUX0lOUFVUX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOZ3hNYXREYXRlQWRhcHRlciB9IGZyb20gJy4vY29yZS9kYXRlLWFkYXB0ZXInO1xuaW1wb3J0IHsgTmd4TWF0RGF0ZUZvcm1hdHMsIE5HWF9NQVRfREFURV9GT1JNQVRTIH0gZnJvbSAnLi9jb3JlL2RhdGUtZm9ybWF0cyc7XG5pbXBvcnQgeyBOZ3hNYXREYXRldGltZVBpY2tlciB9IGZyb20gJy4vZGF0ZXRpbWUtcGlja2VyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBjcmVhdGVNaXNzaW5nRGF0ZUltcGxFcnJvciB9IGZyb20gJy4vdXRpbHMvZGF0ZS11dGlscyc7XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgY29uc3QgTUFUX0RBVEVQSUNLRVJfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOZ3hNYXREYXRldGltZUlucHV0KSxcbiAgICBtdWx0aTogdHJ1ZVxufTtcblxuLyoqIEBkb2NzLXByaXZhdGUgKi9cbmV4cG9ydCBjb25zdCBNQVRfREFURVBJQ0tFUl9WQUxJREFUT1JTOiBhbnkgPSB7XG4gICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBOZ3hNYXREYXRldGltZUlucHV0KSxcbiAgICBtdWx0aTogdHJ1ZVxufTtcblxuXG4vKipcbiAqIEFuIGV2ZW50IHVzZWQgZm9yIGRhdGVwaWNrZXIgaW5wdXQgYW5kIGNoYW5nZSBldmVudHMuIFdlIGRvbid0IGFsd2F5cyBoYXZlIGFjY2VzcyB0byBhIG5hdGl2ZVxuICogaW5wdXQgb3IgY2hhbmdlIGV2ZW50IGJlY2F1c2UgdGhlIGV2ZW50IG1heSBoYXZlIGJlZW4gdHJpZ2dlcmVkIGJ5IHRoZSB1c2VyIGNsaWNraW5nIG9uIHRoZVxuICogY2FsZW5kYXIgcG9wdXAuIEZvciBjb25zaXN0ZW5jeSwgd2UgYWx3YXlzIHVzZSBNYXREYXRldGltZVBpY2tlcklucHV0RXZlbnQgaW5zdGVhZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1hdERhdGV0aW1lUGlja2VySW5wdXRFdmVudDxEPiB7XG4gICAgLyoqIFRoZSBuZXcgdmFsdWUgZm9yIHRoZSB0YXJnZXQgZGF0ZXBpY2tlciBpbnB1dC4gKi9cbiAgICB2YWx1ZTogRCB8IG51bGw7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgLyoqIFJlZmVyZW5jZSB0byB0aGUgZGF0ZXBpY2tlciBpbnB1dCBjb21wb25lbnQgdGhhdCBlbWl0dGVkIHRoZSBldmVudC4gKi9cbiAgICAgICAgcHVibGljIHRhcmdldDogTmd4TWF0RGF0ZXRpbWVJbnB1dDxEPixcbiAgICAgICAgLyoqIFJlZmVyZW5jZSB0byB0aGUgbmF0aXZlIGlucHV0IGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIHRoZSBkYXRlcGlja2VyIGlucHV0LiAqL1xuICAgICAgICBwdWJsaWMgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMudGFyZ2V0LnZhbHVlO1xuICAgIH1cbn1cblxuXG4vKiogRGlyZWN0aXZlIHVzZWQgdG8gY29ubmVjdCBhbiBpbnB1dCB0byBhIG1hdERhdGV0aW1lUGlja2VyLiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdpbnB1dFtuZ3hNYXREYXRldGltZVBpY2tlcl0nLFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICBNQVRfREFURVBJQ0tFUl9WQUxVRV9BQ0NFU1NPUixcbiAgICAgICAgTUFUX0RBVEVQSUNLRVJfVkFMSURBVE9SUyxcbiAgICAgICAgeyBwcm92aWRlOiBNQVRfSU5QVVRfVkFMVUVfQUNDRVNTT1IsIHVzZUV4aXN0aW5nOiBOZ3hNYXREYXRldGltZUlucHV0IH0sXG4gICAgXSxcbiAgICBob3N0OiB7XG4gICAgICAgICdbYXR0ci5hcmlhLWhhc3BvcHVwXSc6ICdfZGF0ZXBpY2tlciA/IFwiZGlhbG9nXCIgOiBudWxsJyxcbiAgICAgICAgJ1thdHRyLmFyaWEtb3duc10nOiAnKF9kYXRlcGlja2VyPy5vcGVuZWQgJiYgX2RhdGVwaWNrZXIuaWQpIHx8IG51bGwnLFxuICAgICAgICAnW2F0dHIubWluXSc6ICdtaW4gPyBfZGF0ZUFkYXB0ZXIudG9Jc284NjAxKG1pbikgOiBudWxsJyxcbiAgICAgICAgJ1thdHRyLm1heF0nOiAnbWF4ID8gX2RhdGVBZGFwdGVyLnRvSXNvODYwMShtYXgpIDogbnVsbCcsXG4gICAgICAgICdbZGlzYWJsZWRdJzogJ2Rpc2FibGVkJyxcbiAgICAgICAgJyhpbnB1dCknOiAnX29uSW5wdXQoJGV2ZW50LnRhcmdldC52YWx1ZSknLFxuICAgICAgICAnKGNoYW5nZSknOiAnX29uQ2hhbmdlKCknLFxuICAgICAgICAnKGJsdXIpJzogJ19vbkJsdXIoKScsXG4gICAgICAgICcoZm9jdXMpJzogJ19vbkZvY3VzKCknLFxuICAgICAgICAnKGtleWRvd24pJzogJ19vbktleWRvd24oJGV2ZW50KScsXG4gICAgfSxcbiAgICBleHBvcnRBczogJ25neE1hdERhdGV0aW1lUGlja2VySW5wdXQnLFxufSlcbmV4cG9ydCBjbGFzcyBOZ3hNYXREYXRldGltZUlucHV0PEQ+IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uRGVzdHJveSwgVmFsaWRhdG9yIHtcbiAgICAvKiogVGhlIGRhdGVwaWNrZXIgdGhhdCB0aGlzIGlucHV0IGlzIGFzc29jaWF0ZWQgd2l0aC4gKi9cbiAgICBASW5wdXQoKVxuICAgIHNldCBuZ3hNYXREYXRldGltZVBpY2tlcih2YWx1ZTogTmd4TWF0RGF0ZXRpbWVQaWNrZXI8RD4pIHtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fZGF0ZXBpY2tlciA9IHZhbHVlO1xuICAgICAgICB0aGlzLl9kYXRlcGlja2VyLl9yZWdpc3RlcklucHV0KHRoaXMpO1xuICAgICAgICB0aGlzLl9kYXRlcGlja2VyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG5cbiAgICAgICAgdGhpcy5fZGF0ZXBpY2tlclN1YnNjcmlwdGlvbiA9IHRoaXMuX2RhdGVwaWNrZXIuX3NlbGVjdGVkQ2hhbmdlZC5zdWJzY3JpYmUoKHNlbGVjdGVkOiBEKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gc2VsZWN0ZWQ7XG4gICAgICAgICAgICB0aGlzLl9jdmFPbkNoYW5nZShzZWxlY3RlZCk7XG4gICAgICAgICAgICB0aGlzLl9vblRvdWNoZWQoKTtcbiAgICAgICAgICAgIHRoaXMuZGF0ZUlucHV0LmVtaXQobmV3IE1hdERhdGV0aW1lUGlja2VySW5wdXRFdmVudCh0aGlzLCB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpKTtcbiAgICAgICAgICAgIHRoaXMuZGF0ZUNoYW5nZS5lbWl0KG5ldyBNYXREYXRldGltZVBpY2tlcklucHV0RXZlbnQodGhpcywgdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfZGF0ZXBpY2tlcjogTmd4TWF0RGF0ZXRpbWVQaWNrZXI8RD47XG5cbiAgICAvKiogRnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBmaWx0ZXIgb3V0IGRhdGVzIHdpdGhpbiB0aGUgZGF0ZXBpY2tlci4gKi9cbiAgICBASW5wdXQoKVxuICAgIHNldCBuZ3hNYXREYXRldGltZVBpY2tlckZpbHRlcih2YWx1ZTogKGRhdGU6IEQgfCBudWxsKSA9PiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuX2RhdGVGaWx0ZXIgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yT25DaGFuZ2UoKTtcbiAgICB9XG4gICAgX2RhdGVGaWx0ZXI6IChkYXRlOiBEIHwgbnVsbCkgPT4gYm9vbGVhbjtcblxuICAgIC8qKiBUaGUgdmFsdWUgb2YgdGhlIGlucHV0LiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IHZhbHVlKCk6IEQgfCBudWxsIHsgcmV0dXJuIHRoaXMuX3ZhbHVlOyB9XG4gICAgc2V0IHZhbHVlKHZhbHVlOiBEIHwgbnVsbCkge1xuICAgICAgICB2YWx1ZSA9IHRoaXMuX2RhdGVBZGFwdGVyLmRlc2VyaWFsaXplKHZhbHVlKTtcbiAgICAgICAgdGhpcy5fbGFzdFZhbHVlVmFsaWQgPSAhdmFsdWUgfHwgdGhpcy5fZGF0ZUFkYXB0ZXIuaXNWYWxpZCh2YWx1ZSk7XG4gICAgICAgIHZhbHVlID0gdGhpcy5fZ2V0VmFsaWREYXRlT3JOdWxsKHZhbHVlKTtcbiAgICAgICAgY29uc3Qgb2xkRGF0ZSA9IHRoaXMudmFsdWU7XG4gICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX2Zvcm1hdFZhbHVlKHZhbHVlKTtcblxuICAgICAgICBpZiAoIXRoaXMuX2RhdGVBZGFwdGVyLnNhbWVEYXRlKG9sZERhdGUsIHZhbHVlKSkge1xuICAgICAgICAgICAgdGhpcy5fdmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJpdmF0ZSBfdmFsdWU6IEQgfCBudWxsO1xuXG4gICAgLyoqIFRoZSBtaW5pbXVtIHZhbGlkIGRhdGUuICovXG4gICAgQElucHV0KClcbiAgICBnZXQgbWluKCk6IEQgfCBudWxsIHsgcmV0dXJuIHRoaXMuX21pbjsgfVxuICAgIHNldCBtaW4odmFsdWU6IEQgfCBudWxsKSB7XG4gICAgICAgIHRoaXMuX21pbiA9IHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbCh0aGlzLl9kYXRlQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSkpO1xuICAgICAgICB0aGlzLl92YWxpZGF0b3JPbkNoYW5nZSgpO1xuICAgIH1cbiAgICBwcml2YXRlIF9taW46IEQgfCBudWxsO1xuXG4gICAgLyoqIFRoZSBtYXhpbXVtIHZhbGlkIGRhdGUuICovXG4gICAgQElucHV0KClcbiAgICBnZXQgbWF4KCk6IEQgfCBudWxsIHsgcmV0dXJuIHRoaXMuX21heDsgfVxuICAgIHNldCBtYXgodmFsdWU6IEQgfCBudWxsKSB7XG4gICAgICAgIHRoaXMuX21heCA9IHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbCh0aGlzLl9kYXRlQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSkpO1xuICAgICAgICB0aGlzLl92YWxpZGF0b3JPbkNoYW5nZSgpO1xuICAgIH1cbiAgICBwcml2YXRlIF9tYXg6IEQgfCBudWxsO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGRhdGVwaWNrZXItaW5wdXQgaXMgZGlzYWJsZWQuICovXG4gICAgQElucHV0KClcbiAgICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7IHJldHVybiAhIXRoaXMuX2Rpc2FibGVkOyB9XG4gICAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlID0gdmFsdWUgIT0gbnVsbCAmJiBgJHt2YWx1ZX1gICE9PSAnZmFsc2UnO1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuXG4gICAgICAgIGlmICh0aGlzLl9kaXNhYmxlZCAhPT0gbmV3VmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2Rpc2FibGVkID0gbmV3VmFsdWU7XG4gICAgICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlcy5lbWl0KHVuZGVmaW5lZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBXZSBuZWVkIHRvIG51bGwgY2hlY2sgdGhlIGBibHVyYCBtZXRob2QsIGJlY2F1c2UgaXQncyB1bmRlZmluZWQgZHVyaW5nIFNTUi5cbiAgICAgICAgaWYgKG5ld1ZhbHVlICYmIGVsZW1lbnQuYmx1cikge1xuICAgICAgICAgICAgLy8gTm9ybWFsbHksIG5hdGl2ZSBpbnB1dCBlbGVtZW50cyBhdXRvbWF0aWNhbGx5IGJsdXIgaWYgdGhleSB0dXJuIGRpc2FibGVkLiBUaGlzIGJlaGF2aW9yXG4gICAgICAgICAgICAvLyBpcyBwcm9ibGVtYXRpYywgYmVjYXVzZSBpdCB3b3VsZCBtZWFuIHRoYXQgaXQgdHJpZ2dlcnMgYW5vdGhlciBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlLFxuICAgICAgICAgICAgLy8gd2hpY2ggdGhlbiBjYXVzZXMgYSBjaGFuZ2VkIGFmdGVyIGNoZWNrZWQgZXJyb3IgaWYgdGhlIGlucHV0IGVsZW1lbnQgd2FzIGZvY3VzZWQgYmVmb3JlLlxuICAgICAgICAgICAgZWxlbWVudC5ibHVyKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJpdmF0ZSBfZGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgICAvKiogRW1pdHMgd2hlbiBhIGBjaGFuZ2VgIGV2ZW50IGlzIGZpcmVkIG9uIHRoaXMgYDxpbnB1dD5gLiAqL1xuICAgIEBPdXRwdXQoKSByZWFkb25seSBkYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8TWF0RGF0ZXRpbWVQaWNrZXJJbnB1dEV2ZW50PEQ+PiA9XG4gICAgICAgIG5ldyBFdmVudEVtaXR0ZXI8TWF0RGF0ZXRpbWVQaWNrZXJJbnB1dEV2ZW50PEQ+PigpO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gYW4gYGlucHV0YCBldmVudCBpcyBmaXJlZCBvbiB0aGlzIGA8aW5wdXQ+YC4gKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgZGF0ZUlucHV0OiBFdmVudEVtaXR0ZXI8TWF0RGF0ZXRpbWVQaWNrZXJJbnB1dEV2ZW50PEQ+PiA9XG4gICAgICAgIG5ldyBFdmVudEVtaXR0ZXI8TWF0RGF0ZXRpbWVQaWNrZXJJbnB1dEV2ZW50PEQ+PigpO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gdGhlIHZhbHVlIGNoYW5nZXMgKGVpdGhlciBkdWUgdG8gdXNlciBpbnB1dCBvciBwcm9ncmFtbWF0aWMgY2hhbmdlKS4gKi9cbiAgICBfdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPEQgfCBudWxsPigpO1xuXG4gICAgLyoqIEVtaXRzIHdoZW4gdGhlIGRpc2FibGVkIHN0YXRlIGhhcyBjaGFuZ2VkICovXG4gICAgc3RhdGVDaGFuZ2VzID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgX29uVG91Y2hlZCA9ICgpID0+IHsgfTtcblxuICAgIHByaXZhdGUgX2N2YU9uQ2hhbmdlOiAodmFsdWU6IGFueSkgPT4gdm9pZCA9ICgpID0+IHsgfTtcblxuICAgIHByaXZhdGUgX3ZhbGlkYXRvck9uQ2hhbmdlID0gKCkgPT4geyB9O1xuXG4gICAgcHJpdmF0ZSBfZGF0ZXBpY2tlclN1YnNjcmlwdGlvbiA9IFN1YnNjcmlwdGlvbi5FTVBUWTtcblxuICAgIHByaXZhdGUgX2xvY2FsZVN1YnNjcmlwdGlvbiA9IFN1YnNjcmlwdGlvbi5FTVBUWTtcblxuICAgIC8qKiBUaGUgZm9ybSBjb250cm9sIHZhbGlkYXRvciBmb3Igd2hldGhlciB0aGUgaW5wdXQgcGFyc2VzLiAqL1xuICAgIHByaXZhdGUgX3BhcnNlVmFsaWRhdG9yOiBWYWxpZGF0b3JGbiA9ICgpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXN0VmFsdWVWYWxpZCA/XG4gICAgICAgICAgICBudWxsIDogeyAnbWF0RGF0ZXRpbWVQaWNrZXJQYXJzZSc6IHsgJ3RleHQnOiB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQudmFsdWUgfSB9O1xuICAgIH1cblxuICAgIC8qKiBUaGUgZm9ybSBjb250cm9sIHZhbGlkYXRvciBmb3IgdGhlIG1pbiBkYXRlLiAqL1xuICAgIHByaXZhdGUgX21pblZhbGlkYXRvcjogVmFsaWRhdG9yRm4gPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwgPT4ge1xuICAgICAgICBjb25zdCBjb250cm9sVmFsdWUgPSB0aGlzLl9nZXRWYWxpZERhdGVPck51bGwodGhpcy5fZGF0ZUFkYXB0ZXIuZGVzZXJpYWxpemUoY29udHJvbC52YWx1ZSkpO1xuICAgICAgICByZXR1cm4gKCF0aGlzLm1pbiB8fCAhY29udHJvbFZhbHVlIHx8XG4gICAgICAgICAgICB0aGlzLl9kYXRlQWRhcHRlci5jb21wYXJlRGF0ZVdpdGhUaW1lKHRoaXMubWluLCBjb250cm9sVmFsdWUsIHRoaXMuX2RhdGVwaWNrZXIuc2hvd1NlY29uZHMpIDw9IDApID9cbiAgICAgICAgICAgIG51bGwgOiB7ICdtYXREYXRldGltZVBpY2tlck1pbic6IHsgJ21pbic6IHRoaXMubWluLCAnYWN0dWFsJzogY29udHJvbFZhbHVlIH0gfTtcbiAgICB9XG5cbiAgICAvKiogVGhlIGZvcm0gY29udHJvbCB2YWxpZGF0b3IgZm9yIHRoZSBtYXggZGF0ZS4gKi9cbiAgICBwcml2YXRlIF9tYXhWYWxpZGF0b3I6IFZhbGlkYXRvckZuID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcbiAgICAgICAgY29uc3QgY29udHJvbFZhbHVlID0gdGhpcy5fZ2V0VmFsaWREYXRlT3JOdWxsKHRoaXMuX2RhdGVBZGFwdGVyLmRlc2VyaWFsaXplKGNvbnRyb2wudmFsdWUpKTtcbiAgICAgICAgcmV0dXJuICghdGhpcy5tYXggfHwgIWNvbnRyb2xWYWx1ZSB8fFxuICAgICAgICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuY29tcGFyZURhdGVXaXRoVGltZSh0aGlzLm1heCwgY29udHJvbFZhbHVlLCB0aGlzLl9kYXRlcGlja2VyLnNob3dTZWNvbmRzKSA+PSAwKSA/XG4gICAgICAgICAgICBudWxsIDogeyAnbWF0RGF0ZXRpbWVQaWNrZXJNYXgnOiB7ICdtYXgnOiB0aGlzLm1heCwgJ2FjdHVhbCc6IGNvbnRyb2xWYWx1ZSB9IH07XG4gICAgfVxuXG4gICAgLyoqIFRoZSBmb3JtIGNvbnRyb2wgdmFsaWRhdG9yIGZvciB0aGUgZGF0ZSBmaWx0ZXIuICovXG4gICAgcHJpdmF0ZSBfZmlsdGVyVmFsaWRhdG9yOiBWYWxpZGF0b3JGbiA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCA9PiB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbCh0aGlzLl9kYXRlQWRhcHRlci5kZXNlcmlhbGl6ZShjb250cm9sLnZhbHVlKSk7XG4gICAgICAgIHJldHVybiAhdGhpcy5fZGF0ZUZpbHRlciB8fCAhY29udHJvbFZhbHVlIHx8IHRoaXMuX2RhdGVGaWx0ZXIoY29udHJvbFZhbHVlKSA/XG4gICAgICAgICAgICBudWxsIDogeyAnbWF0RGF0ZXRpbWVQaWNrZXJGaWx0ZXInOiB0cnVlIH07XG4gICAgfVxuXG4gICAgLyoqIFRoZSBjb21iaW5lZCBmb3JtIGNvbnRyb2wgdmFsaWRhdG9yIGZvciB0aGlzIGlucHV0LiAqL1xuICAgIHByaXZhdGUgX3ZhbGlkYXRvcjogVmFsaWRhdG9yRm4gfCBudWxsID1cbiAgICAgICAgVmFsaWRhdG9ycy5jb21wb3NlKFxuICAgICAgICAgICAgW3RoaXMuX3BhcnNlVmFsaWRhdG9yLCB0aGlzLl9taW5WYWxpZGF0b3IsIHRoaXMuX21heFZhbGlkYXRvciwgdGhpcy5fZmlsdGVyVmFsaWRhdG9yXSk7XG5cbiAgICAvKiogV2hldGhlciB0aGUgbGFzdCB2YWx1ZSBzZXQgb24gdGhlIGlucHV0IHdhcyB2YWxpZC4gKi9cbiAgICBwcml2YXRlIF9sYXN0VmFsdWVWYWxpZCA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD4sXG4gICAgICAgIEBPcHRpb25hbCgpIHB1YmxpYyBfZGF0ZUFkYXB0ZXI6IE5neE1hdERhdGVBZGFwdGVyPEQ+LFxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE5HWF9NQVRfREFURV9GT1JNQVRTKSBwcml2YXRlIF9kYXRlRm9ybWF0czogTmd4TWF0RGF0ZUZvcm1hdHMsXG4gICAgICAgIEBPcHRpb25hbCgpIHByaXZhdGUgX2Zvcm1GaWVsZDogTWF0Rm9ybUZpZWxkKSB7XG4gICAgICAgIGlmICghdGhpcy5fZGF0ZUFkYXB0ZXIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU1pc3NpbmdEYXRlSW1wbEVycm9yKCdOZ3hNYXREYXRlQWRhcHRlcicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5fZGF0ZUZvcm1hdHMpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU1pc3NpbmdEYXRlSW1wbEVycm9yKCdOR1hfTUFUX0RBVEVfRk9STUFUUycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBkYXRlIHRoZSBkaXNwbGF5ZWQgZGF0ZSB3aGVuIHRoZSBsb2NhbGUgY2hhbmdlcy5cbiAgICAgICAgdGhpcy5fbG9jYWxlU3Vic2NyaXB0aW9uID0gX2RhdGVBZGFwdGVyLmxvY2FsZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fZGF0ZXBpY2tlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl9sb2NhbGVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5fdmFsdWVDaGFuZ2UuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKiogQGRvY3MtcHJpdmF0ZSAqL1xuICAgIHJlZ2lzdGVyT25WYWxpZGF0b3JDaGFuZ2UoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yT25DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICAvKiogQGRvY3MtcHJpdmF0ZSAqL1xuICAgIHZhbGlkYXRlKGM6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvciA/IHRoaXMuX3ZhbGlkYXRvcihjKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKiBAYnJlYWtpbmctY2hhbmdlIDguMC4wIFVzZSBgZ2V0Q29ubmVjdGVkT3ZlcmxheU9yaWdpbmAgaW5zdGVhZFxuICAgICAqL1xuICAgIGdldFBvcHVwQ29ubmVjdGlvbkVsZW1lbnRSZWYoKTogRWxlbWVudFJlZiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldENvbm5lY3RlZE92ZXJsYXlPcmlnaW4oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBlbGVtZW50IHRoYXQgdGhlIGRhdGVwaWNrZXIgcG9wdXAgc2hvdWxkIGJlIGNvbm5lY3RlZCB0by5cbiAgICAgKiBAcmV0dXJuIFRoZSBlbGVtZW50IHRvIGNvbm5lY3QgdGhlIHBvcHVwIHRvLlxuICAgICAqL1xuICAgIGdldENvbm5lY3RlZE92ZXJsYXlPcmlnaW4oKTogRWxlbWVudFJlZiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb3JtRmllbGQgPyB0aGlzLl9mb3JtRmllbGQuZ2V0Q29ubmVjdGVkT3ZlcmxheU9yaWdpbigpIDogdGhpcy5fZWxlbWVudFJlZjtcbiAgICB9XG5cbiAgICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICAgIHdyaXRlVmFsdWUodmFsdWU6IEQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gICAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHZhbHVlOiBhbnkpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fY3ZhT25DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICAvLyBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX29uVG91Y2hlZCA9IGZuO1xuICAgIH1cblxuICAgIC8vIEltcGxlbWVudGVkIGFzIHBhcnQgb2YgQ29udHJvbFZhbHVlQWNjZXNzb3IuXG4gICAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICAgIH1cblxuICAgIF9vbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgaXNBbHREb3duQXJyb3cgPSBldmVudC5hbHRLZXkgJiYgZXZlbnQua2V5Q29kZSA9PT0gRE9XTl9BUlJPVztcblxuICAgICAgICBpZiAodGhpcy5fZGF0ZXBpY2tlciAmJiBpc0FsdERvd25BcnJvdyAmJiAhdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnJlYWRPbmx5KSB7XG4gICAgICAgICAgICB0aGlzLl9kYXRlcGlja2VyLm9wZW4oKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfb25JbnB1dCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGxhc3RWYWx1ZVdhc1ZhbGlkID0gdGhpcy5fbGFzdFZhbHVlVmFsaWQ7XG4gICAgICAgIGxldCBkYXRlID0gdGhpcy5fZGF0ZUFkYXB0ZXIucGFyc2UodmFsdWUsIHRoaXMuX2RhdGVGb3JtYXRzLnBhcnNlLmRhdGVJbnB1dCk7XG4gICAgICAgIHRoaXMuX2xhc3RWYWx1ZVZhbGlkID0gIWRhdGUgfHwgdGhpcy5fZGF0ZUFkYXB0ZXIuaXNWYWxpZChkYXRlKTtcbiAgICAgICAgZGF0ZSA9IHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbChkYXRlKTtcblxuICAgICAgICBjb25zdCBpc1NhbWVUaW1lID0gdGhpcy5fZGF0ZUFkYXB0ZXIuaXNTYW1lVGltZShkYXRlLCB0aGlzLl92YWx1ZSk7XG5cbiAgICAgICAgaWYgKChkYXRlICE9IG51bGwgJiYgKCFpc1NhbWVUaW1lIHx8ICF0aGlzLl9kYXRlQWRhcHRlci5zYW1lRGF0ZShkYXRlLCB0aGlzLl92YWx1ZSkpKVxuICAgICAgICAgICAgfHwgKGRhdGUgPT0gbnVsbCAmJiB0aGlzLl92YWx1ZSAhPSBudWxsKSkge1xuICAgICAgICAgICAgdGhpcy5fdmFsdWUgPSBkYXRlO1xuICAgICAgICAgICAgdGhpcy5fY3ZhT25DaGFuZ2UoZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLl92YWx1ZUNoYW5nZS5lbWl0KGRhdGUpO1xuICAgICAgICAgICAgdGhpcy5kYXRlSW5wdXQuZW1pdChuZXcgTWF0RGF0ZXRpbWVQaWNrZXJJbnB1dEV2ZW50KHRoaXMsIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkpO1xuICAgICAgICB9IGVsc2UgaWYgKGxhc3RWYWx1ZVdhc1ZhbGlkICE9PSB0aGlzLl9sYXN0VmFsdWVWYWxpZCkge1xuICAgICAgICAgICAgdGhpcy5fdmFsaWRhdG9yT25DaGFuZ2UoKTtcbiAgICAgICAgfVxuICAgIH1