mat-contenteditable
Version:
Angular contenteditable directive for Angular forms and Material Design
332 lines (331 loc) • 25.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Directive, ElementRef, Renderer2, HostListener, Input, HostBinding, Optional, Self, } from '@angular/core';
import { MatFormFieldControl } from '@angular/material/form-field';
import { FormGroupDirective, NgControl, NgForm } from '@angular/forms';
import { ErrorStateMatcher, mixinErrorState } from '@angular/material/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Subject } from 'rxjs';
/**
* \@docs-private
*/
class MatInputBase {
/**
* @param {?} _defaultErrorStateMatcher
* @param {?} _parentForm
* @param {?} _parentFormGroup
* @param {?} ngControl
*/
constructor(_defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl) {
this._defaultErrorStateMatcher = _defaultErrorStateMatcher;
this._parentForm = _parentForm;
this._parentFormGroup = _parentFormGroup;
this.ngControl = ngControl;
}
}
if (false) {
/** @type {?} */
MatInputBase.prototype._defaultErrorStateMatcher;
/** @type {?} */
MatInputBase.prototype._parentForm;
/** @type {?} */
MatInputBase.prototype._parentFormGroup;
/**
* \@docs-private
* @type {?}
*/
MatInputBase.prototype.ngControl;
}
/** @type {?} */
export const _MatInputMixinBase = mixinErrorState(MatInputBase);
export class MatContenteditableDirective extends _MatInputMixinBase {
/**
* @param {?} elementRef
* @param {?} renderer
* @param {?} ngControl
* @param {?} _parentForm
* @param {?} _parentFormGroup
* @param {?} _defaultErrorStateMatcher
*/
constructor(elementRef, renderer, ngControl, _parentForm, _parentFormGroup, _defaultErrorStateMatcher) {
super(_defaultErrorStateMatcher, _parentForm, _parentFormGroup, ngControl);
this.elementRef = elementRef;
this.renderer = renderer;
this.ngControl = ngControl;
this.stateChanges = new Subject();
this.id = `mat-input-${MatContenteditableDirective.nextId++}`;
this.focused = false;
this.contentEmpty = ['<br>', '<div><br></div>'];
this._required = false;
this._disabled = false;
this.controlType = 'mat-input';
this.describedBy = '';
this.propValueAccessor = 'innerHTML';
// Setting the value accessor directly (instead of using
// the providers) to avoid running into a circular import.
if (this.ngControl != null) {
this.ngControl.valueAccessor = this;
}
}
/**
* @return {?}
*/
get value() { return this.elementRef.nativeElement[this.propValueAccessor]; }
/**
* @param {?} value
* @return {?}
*/
set value(value) {
if (value !== this.value) {
this.elementRef.nativeElement[this.propValueAccessor] = value;
this.stateChanges.next();
}
}
/**
* @return {?}
*/
get placeholder() {
return this._placeholder;
}
/**
* @param {?} plh
* @return {?}
*/
set placeholder(plh) {
this._placeholder = plh;
this.stateChanges.next();
}
/**
* @return {?}
*/
get empty() {
return !this.value || this.contentEmpty.includes(this.value);
}
/**
* @return {?}
*/
get shouldLabelFloat() { return this.focused || !this.empty; }
/**
* @return {?}
*/
get required() {
return this._required;
}
/**
* @param {?} req
* @return {?}
*/
set required(req) {
this._required = coerceBooleanProperty(req);
this.stateChanges.next();
}
/**
* @return {?}
*/
get disabled() {
return this._disabled;
}
/**
* @param {?} dis
* @return {?}
*/
set disabled(dis) {
this._disabled = coerceBooleanProperty(dis);
this.stateChanges.next();
}
/**
* @return {?}
*/
ngDoCheck() {
if (this.ngControl) {
// We need to re-evaluate this on every change detection cycle, because there are some
// error triggers that we can't subscribe to (e.g. parent form submissions). This means
// that whatever logic is in here has to be super lean or we risk destroying the performance.
this.updateErrorState();
}
}
/**
* @return {?}
*/
callOnChange() {
if (typeof this.onChange === 'function') {
this.onChange(this.elementRef.nativeElement[this.propValueAccessor]);
}
}
/**
* @return {?}
*/
callOnFocused() {
if (this.focused !== true) {
this.focused = true;
this.stateChanges.next();
}
}
/**
* @return {?}
*/
callOnTouched() {
if (typeof this.onTouched === 'function') {
this.onTouched();
}
if (this.focused !== false) {
this.focused = false;
this.stateChanges.next();
}
}
/**
* @param {?} ids
* @return {?}
*/
setDescribedByIds(ids) {
this.describedBy = ids.join(' ');
}
/**
* @return {?}
*/
onContainerClick() { this.elementRef.nativeElement.focus(); }
/**
* Writes a new value to the element.
* This method will be called by the forms API to write
* to the view when programmatic (model -> view) changes are requested.
*
* See: [ControlValueAccessor](https://angular.io/api/forms/ControlValueAccessor#members)
* @param {?} value
* @return {?}
*/
writeValue(value) {
/** @type {?} */
const normalizedValue = value == null ? '' : value;
this.renderer.setProperty(this.elementRef.nativeElement, this.propValueAccessor, normalizedValue);
}
/**
* Registers a callback function that should be called when
* the control's value changes in the UI.
*
* This is called by the forms API on initialization so it can update
* the form model when values propagate from the view (view -> model).
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* Registers a callback function that should be called when the control receives a blur event.
* This is called by the forms API on initialization so it can update the form model on blur.
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* This function is called by the forms API when the control status changes to or from "DISABLED".
* Depending on the value, it should enable or disable the appropriate DOM element.
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
if (isDisabled) {
this.renderer.setAttribute(this.elementRef.nativeElement, 'disabled', 'true');
this.removeDisabledState = this.renderer.listen(this.elementRef.nativeElement, 'keydown', this.listenerDisabledState);
}
else {
if (this.removeDisabledState) {
this.renderer.removeAttribute(this.elementRef.nativeElement, 'disabled');
this.removeDisabledState();
}
}
}
/**
* @param {?} e
* @return {?}
*/
listenerDisabledState(e) {
e.preventDefault();
}
}
/**
* Implemented as part of MatFormFieldControl.
* See https://material.angular.io/guide/creating-a-custom-form-field-control
*/
MatContenteditableDirective.nextId = 0;
MatContenteditableDirective.decorators = [
{ type: Directive, args: [{
selector: '[contenteditable]',
providers: [
{ provide: MatFormFieldControl, useExisting: MatContenteditableDirective },
]
},] }
];
/** @nocollapse */
MatContenteditableDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 },
{ type: NgControl, decorators: [{ type: Optional }, { type: Self }] },
{ type: NgForm, decorators: [{ type: Optional }] },
{ type: FormGroupDirective, decorators: [{ type: Optional }] },
{ type: ErrorStateMatcher }
];
MatContenteditableDirective.propDecorators = {
value: [{ type: Input }],
id: [{ type: HostBinding }],
placeholder: [{ type: Input }],
contentEmpty: [{ type: Input }],
required: [{ type: Input }],
disabled: [{ type: Input }],
errorState: [{ type: HostBinding, args: ['attr.aria-invalid',] }],
errorStateMatcher: [{ type: Input }],
describedBy: [{ type: HostBinding, args: ['attr.aria-describedby',] }],
propValueAccessor: [{ type: Input }],
callOnChange: [{ type: HostListener, args: ['input',] }],
callOnFocused: [{ type: HostListener, args: ['focus',] }],
callOnTouched: [{ type: HostListener, args: ['blur',] }]
};
if (false) {
/**
* Implemented as part of MatFormFieldControl.
* See https://material.angular.io/guide/creating-a-custom-form-field-control
* @type {?}
*/
MatContenteditableDirective.nextId;
/** @type {?} */
MatContenteditableDirective.prototype.stateChanges;
/** @type {?} */
MatContenteditableDirective.prototype.id;
/** @type {?} */
MatContenteditableDirective.prototype._placeholder;
/** @type {?} */
MatContenteditableDirective.prototype.focused;
/** @type {?} */
MatContenteditableDirective.prototype.contentEmpty;
/** @type {?} */
MatContenteditableDirective.prototype._required;
/** @type {?} */
MatContenteditableDirective.prototype._disabled;
/** @type {?} */
MatContenteditableDirective.prototype.errorState;
/** @type {?} */
MatContenteditableDirective.prototype.errorStateMatcher;
/** @type {?} */
MatContenteditableDirective.prototype.controlType;
/** @type {?} */
MatContenteditableDirective.prototype.describedBy;
/** @type {?} */
MatContenteditableDirective.prototype.onChange;
/** @type {?} */
MatContenteditableDirective.prototype.onTouched;
/** @type {?} */
MatContenteditableDirective.prototype.removeDisabledState;
/** @type {?} */
MatContenteditableDirective.prototype.propValueAccessor;
/** @type {?} */
MatContenteditableDirective.prototype.elementRef;
/** @type {?} */
MatContenteditableDirective.prototype.renderer;
/** @type {?} */
MatContenteditableDirective.prototype.ngControl;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0LWNvbnRlbnRlZGl0YWJsZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9tYXQtY29udGVudGVkaXRhYmxlLyIsInNvdXJjZXMiOlsibGliL21hdC1jb250ZW50ZWRpdGFibGUuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFDTCxXQUFXLEVBQ1gsUUFBUSxFQUNSLElBQUksR0FFTCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNuRSxPQUFPLEVBQXdCLGtCQUFrQixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFnRCxNQUFNLHdCQUF3QixDQUFDO0FBQzFILE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzlELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7QUFJL0IsTUFBTSxZQUFZOzs7Ozs7O0lBQ2hCLFlBQW1CLHlCQUE0QyxFQUM1QyxhQUNBLGtCQUVBO1FBSkEsOEJBQXlCLEdBQXpCLHlCQUF5QixDQUFtQjtRQUM1QyxnQkFBVyxHQUFYLFdBQVc7UUFDWCxxQkFBZ0IsR0FBaEIsZ0JBQWdCO1FBRWhCLGNBQVMsR0FBVCxTQUFTO0tBQWU7Q0FDNUM7Ozs7Ozs7Ozs7Ozs7OztBQUNELGFBQWEsa0JBQWtCLEdBQzdCLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQVNoQyxNQUFNLE9BQU8sMkJBQTRCLFNBQVEsa0JBQWtCOzs7Ozs7Ozs7SUE0RWpFLFlBQ1UsWUFDQSxVQUNtQixTQUFvQixFQUNuQyxXQUFtQixFQUNuQixnQkFBb0MsRUFDaEQseUJBQTRDO1FBRTVDLEtBQUssQ0FBQyx5QkFB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WyJpbXBvcnQge1xuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIFJlbmRlcmVyMixcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgSG9zdEJpbmRpbmcsXG4gIE9wdGlvbmFsLFxuICBTZWxmLFxuICBEb0NoZWNrLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9mb3JtLWZpZWxkJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBGb3JtR3JvdXBEaXJlY3RpdmUsIE5nQ29udHJvbCwgTmdGb3JtIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgRXJyb3JTdGF0ZU1hdGNoZXIsIG1peGluRXJyb3JTdGF0ZSwgQ2FuVXBkYXRlRXJyb3JTdGF0ZUN0b3IsIENhblVwZGF0ZUVycm9yU3RhdGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbi8vIEJvaWxlcnBsYXRlIGZvciBhcHBseWluZyBtaXhpbnMgdG8gTWF0SW5wdXQuXG4vKiogQGRvY3MtcHJpdmF0ZSAqL1xuY2xhc3MgTWF0SW5wdXRCYXNlIHtcbiAgY29uc3RydWN0b3IocHVibGljIF9kZWZhdWx0RXJyb3JTdGF0ZU1hdGNoZXI6IEVycm9yU3RhdGVNYXRjaGVyLFxuICAgICAgICAgICAgICBwdWJsaWMgX3BhcmVudEZvcm06IE5nRm9ybSxcbiAgICAgICAgICAgICAgcHVibGljIF9wYXJlbnRGb3JtR3JvdXA6IEZvcm1Hcm91cERpcmVjdGl2ZSxcbiAgICAgICAgICAgICAgLyoqIEBkb2NzLXByaXZhdGUgKi9cbiAgICAgICAgICAgICAgcHVibGljIG5nQ29udHJvbDogTmdDb250cm9sKSB7fVxufVxuZXhwb3J0IGNvbnN0IF9NYXRJbnB1dE1peGluQmFzZTogQ2FuVXBkYXRlRXJyb3JTdGF0ZUN0b3IgJiB0eXBlb2YgTWF0SW5wdXRCYXNlID1cbiAgbWl4aW5FcnJvclN0YXRlKE1hdElucHV0QmFzZSk7XG5cblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2NvbnRlbnRlZGl0YWJsZV0nLFxuICBwcm92aWRlcnM6IFtcbiAgICB7IHByb3ZpZGU6IE1hdEZvcm1GaWVsZENvbnRyb2wsIHVzZUV4aXN0aW5nOiBNYXRDb250ZW50ZWRpdGFibGVEaXJlY3RpdmUgfSxcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBNYXRDb250ZW50ZWRpdGFibGVEaXJlY3RpdmUgZXh0ZW5kcyBfTWF0SW5wdXRNaXhpbkJhc2VcbiAgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTWF0Rm9ybUZpZWxkQ29udHJvbDxzdHJpbmc+LCBEb0NoZWNrLCBDYW5VcGRhdGVFcnJvclN0YXRlIHtcblxuICAvKipcbiAgICogSW1wbGVtZW50ZWQgYXMgcGFydCBvZiBNYXRGb3JtRmllbGRDb250cm9sLlxuICAgKiBTZWUgaHR0cHM6Ly9tYXRlcmlhbC5hbmd1bGFyLmlvL2d1aWRlL2NyZWF0aW5nLWEtY3VzdG9tLWZvcm0tZmllbGQtY29udHJvbFxuICAgKi9cbiAgc3RhdGljIG5leHRJZCA9IDA7XG5cbiAgQElucHV0KClcbiAgZ2V0IHZhbHVlKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFt0aGlzLnByb3BWYWx1ZUFjY2Vzc29yXTsgfVxuICBzZXQgdmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIGlmICh2YWx1ZSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnRbdGhpcy5wcm9wVmFsdWVBY2Nlc3Nvcl0gPSB2YWx1ZTtcbiAgICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgICB9XG4gIH1cblxuICByZWFkb25seSBzdGF0ZUNoYW5nZXM6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIEBIb3N0QmluZGluZygpIGlkID0gYG1hdC1pbnB1dC0ke01hdENvbnRlbnRlZGl0YWJsZURpcmVjdGl2ZS5uZXh0SWQrK31gO1xuXG4gIEBJbnB1dCgpXG4gIGdldCBwbGFjZWhvbGRlcigpIHtcbiAgICByZXR1cm4gdGhpcy5fcGxhY2Vob2xkZXI7XG4gIH1cbiAgc2V0IHBsYWNlaG9sZGVyKHBsaCkge1xuICAgIHRoaXMuX3BsYWNlaG9sZGVyID0gcGxoO1xuICAgIHRoaXMuc3RhdGVDaGFuZ2VzLm5leHQoKTtcbiAgfVxuICBwcml2YXRlIF9wbGFjZWhvbGRlcjogc3RyaW5nO1xuXG4gIGZvY3VzZWQgPSBmYWxzZTtcblxuICBASW5wdXQoKSBjb250ZW50RW1wdHk6IEFycmF5PHN0cmluZz4gPSBbJzxicj4nLCAnPGRpdj48YnI+PC9kaXY+J107XG4gIGdldCBlbXB0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMudmFsdWUgfHwgdGhpcy5jb250ZW50RW1wdHkuaW5jbHVkZXModGhpcy52YWx1ZSk7XG4gIH1cblxuICBnZXQgc2hvdWxkTGFiZWxGbG9hdCgpOiBib29sZWFuIHsgcmV0dXJuIHRoaXMuZm9jdXNlZCB8fCAhdGhpcy5lbXB0eTsgfVxuXG4gIEBJbnB1dCgpXG4gIGdldCByZXF1aXJlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVxdWlyZWQ7XG4gIH1cbiAgc2V0IHJlcXVpcmVkKHJlcSkge1xuICAgIHRoaXMuX3JlcXVpcmVkID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHJlcSk7XG4gICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICB9XG4gIHByaXZhdGUgX3JlcXVpcmVkID0gZmFsc2U7XG5cbiAgQElucHV0KClcbiAgZ2V0IGRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kaXNhYmxlZDtcbiAgfVxuICBzZXQgZGlzYWJsZWQoZGlzKSB7XG4gICAgdGhpcy5fZGlzYWJsZWQgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkoZGlzKTtcbiAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gIH1cbiAgcHJpdmF0ZSBfZGlzYWJsZWQgPSBmYWxzZTtcblxuICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1pbnZhbGlkJykgZXJyb3JTdGF0ZTogYm9vbGVhbjtcbiAgQElucHV0KCkgZXJyb3JTdGF0ZU1hdGNoZXI6IEVycm9yU3RhdGVNYXRjaGVyO1xuXG4gIGNvbnRyb2xUeXBlID0gJ21hdC1pbnB1dCc7XG5cbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtZGVzY3JpYmVkYnknKSBkZXNjcmliZWRCeSA9ICcnO1xuXG5cbiAgLy8gUGFydCBvZiBDb250cm9sVmFsdWVBY2Nlc3NvclxuICBwcml2YXRlIG9uQ2hhbmdlOiAodmFsdWU6IHN0cmluZykgPT4gdm9pZDtcbiAgcHJpdmF0ZSBvblRvdWNoZWQ6ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVtb3ZlRGlzYWJsZWRTdGF0ZTogKCkgPT4gdm9pZDtcblxuICBASW5wdXQoKSBwcm9wVmFsdWVBY2Nlc3NvciA9ICdpbm5lckhUTUwnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBwdWJsaWMgbmdDb250cm9sOiBOZ0NvbnRyb2wsXG4gICAgQE9wdGlvbmFsKCkgX3BhcmVudEZvcm06IE5nRm9ybSxcbiAgICBAT3B0aW9uYWwoKSBfcGFyZW50Rm9ybUdyb3VwOiBGb3JtR3JvdXBEaXJlY3RpdmUsXG4gICAgX2RlZmF1bHRFcnJvclN0YXRlTWF0Y2hlcjogRXJyb3JTdGF0ZU1hdGNoZXIsXG4gICkge1xuICAgIHN1cGVyKF9kZWZhdWx0RXJyb3JTdGF0ZU1hdGNoZXIsIF9wYXJlbnRGb3JtLCBfcGFyZW50Rm9ybUdyb3VwLCBuZ0NvbnRyb2wpO1xuICAgIC8vIFNldHRpbmcgdGhlIHZhbHVlIGFjY2Vzc29yIGRpcmVjdGx5IChpbnN0ZWFkIG9mIHVzaW5nXG4gICAgLy8gdGhlIHByb3ZpZGVycykgdG8gYXZvaWQgcnVubmluZyBpbnRvIGEgY2lyY3VsYXIgaW1wb3J0LlxuICAgIGlmICh0aGlzLm5nQ29udHJvbCAhPSBudWxsKSB7IHRoaXMubmdDb250cm9sLnZhbHVlQWNjZXNzb3IgPSB0aGlzOyB9XG4gIH1cblxuICBuZ0RvQ2hlY2soKSB7XG4gICAgaWYgKHRoaXMubmdDb250cm9sKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIHJlLWV2YWx1YXRlIHRoaXMgb24gZXZlcnkgY2hhbmdlIGRldGVjdGlvbiBjeWNsZSwgYmVjYXVzZSB0aGVyZSBhcmUgc29tZVxuICAgICAgLy8gZXJyb3IgdHJpZ2dlcnMgdGhhdCB3ZSBjYW4ndCBzdWJzY3JpYmUgdG8gKGUuZy4gcGFyZW50IGZvcm0gc3VibWlzc2lvbnMpLiBUaGlzIG1lYW5zXG4gICAgICAvLyB0aGF0IHdoYXRldmVyIGxvZ2ljIGlzIGluIGhlcmUgaGFzIHRvIGJlIHN1cGVyIGxlYW4gb3Igd2UgcmlzayBkZXN0cm95aW5nIHRoZSBwZXJmb3JtYW5jZS5cbiAgICAgIHRoaXMudXBkYXRlRXJyb3JTdGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2lucHV0JylcbiAgY2FsbE9uQ2hhbmdlKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5vbkNoYW5nZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudFt0aGlzLnByb3BWYWx1ZUFjY2Vzc29yXSk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZm9jdXMnKVxuICBjYWxsT25Gb2N1c2VkKCkge1xuICAgIGlmICh0aGlzLmZvY3VzZWQgIT09IHRydWUpIHtcbiAgICAgIHRoaXMuZm9jdXNlZCA9IHRydWU7XG4gICAgICB0aGlzLnN0YXRlQ2hhbmdlcy5uZXh0KCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpXG4gIGNhbGxPblRvdWNoZWQoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm9uVG91Y2hlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZm9jdXNlZCAhPT0gZmFsc2UpIHtcbiAgICAgIHRoaXMuZm9jdXNlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5zdGF0ZUNoYW5nZXMubmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIHNldERlc2NyaWJlZEJ5SWRzKGlkczogc3RyaW5nW10pIHtcbiAgICB0aGlzLmRlc2NyaWJlZEJ5ID0gaWRzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIG9uQ29udGFpbmVyQ2xpY2soKSB7IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmZvY3VzKCk7IH1cblxuICAvKipcbiAgICogV3JpdGVzIGEgbmV3IHZhbHVlIHRvIHRoZSBlbGVtZW50LlxuICAgKiBUaGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBieSB0aGUgZm9ybXMgQVBJIHRvIHdyaXRlXG4gICAqIHRvIHRoZSB2aWV3IHdoZW4gcHJvZ3JhbW1hdGljIChtb2RlbCAtPiB2aWV3KSBjaGFuZ2VzIGFyZSByZXF1ZXN0ZWQuXG4gICAqXG4gICAqIFNlZTogW0NvbnRyb2xWYWx1ZUFjY2Vzc29yXShodHRwczovL2FuZ3VsYXIuaW8vYXBpL2Zvcm1zL0NvbnRyb2xWYWx1ZUFjY2Vzc29yI21lbWJlcnMpXG4gICAqL1xuICB3cml0ZVZhbHVlKHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBub3JtYWxpemVkVmFsdWUgPSB2YWx1ZSA9PSBudWxsID8gJycgOiB2YWx1ZTtcbiAgICB0aGlzLnJlbmRlcmVyLnNldFByb3BlcnR5KHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLnByb3BWYWx1ZUFjY2Vzc29yLCBub3JtYWxpemVkVmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgc2hvdWxkIGJlIGNhbGxlZCB3aGVuXG4gICAqIHRoZSBjb250cm9sJ3MgdmFsdWUgY2hhbmdlcyBpbiB0aGUgVUkuXG4gICAqXG4gICAqIFRoaXMgaXMgY2FsbGVkIGJ5IHRoZSBmb3JtcyBBUEkgb24gaW5pdGlhbGl6YXRpb24gc28gaXQgY2FuIHVwZGF0ZVxuICAgKiB0aGUgZm9ybSBtb2RlbCB3aGVuIHZhbHVlcyBwcm9wYWdhdGUgZnJvbSB0aGUgdmlldyAodmlldyAtPiBtb2RlbCkuXG4gICAqL1xuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIHRoZSBjb250cm9sIHJlY2VpdmVzIGEgYmx1ciBldmVudC5cbiAgICogVGhpcyBpcyBjYWxsZWQgYnkgdGhlIGZvcm1zIEFQSSBvbiBpbml0aWFsaXphdGlvbiBzbyBpdCBjYW4gdXBkYXRlIHRoZSBmb3JtIG1vZGVsIG9uIGJsdXIuXG4gICAqL1xuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIGZvcm1zIEFQSSB3aGVuIHRoZSBjb250cm9sIHN0YXR1cyBjaGFuZ2VzIHRvIG9yIGZyb20gXCJESVNBQkxFRFwiLlxuICAgKiBEZXBlbmRpbmcgb24gdGhlIHZhbHVlLCBpdCBzaG91bGQgZW5hYmxlIG9yIGRpc2FibGUgdGhlIGFwcHJvcHJpYXRlIERPTSBlbGVtZW50LlxuICAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKGlzRGlzYWJsZWQpIHtcbiAgICAgIHRoaXMucmVuZGVyZXIuc2V0QXR0cmlidXRlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnZGlzYWJsZWQnLCAndHJ1ZScpO1xuICAgICAgdGhpcy5yZW1vdmVEaXNhYmxlZFN0YXRlID0gdGhpcy5yZW5kZXJlci5saXN0ZW4odGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsICdrZXlkb3duJywgdGhpcy5saXN0ZW5lckRpc2FibGVkU3RhdGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5yZW1vdmVEaXNhYmxlZFN0YXRlKSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQXR0cmlidXRlKHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCAnZGlzYWJsZWQnKTtcbiAgICAgICAgdGhpcy5yZW1vdmVEaXNhYmxlZFN0YXRlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBsaXN0ZW5lckRpc2FibGVkU3RhdGUoZTogS2V5Ym9hcmRFdmVudCkge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfVxufVxuIl19