UNPKG

@angular-mdl/core

Version:

Angular components, directives and styles based on material design lite https://getmdl.io.

231 lines 25 kB
import { Component, ElementRef, EventEmitter, forwardRef, HostBinding, HostListener, Injectable, Input, Optional, Output, Renderer2, ViewEncapsulation, } from "@angular/core"; import { FormGroupName, NG_VALUE_ACCESSOR, } from "@angular/forms"; import { toBoolean } from "../common/boolean-property"; import { noop } from "../common/noop"; import * as i0 from "@angular/core"; import * as i1 from "@angular/forms"; const throwNameError = () => { throw new Error(` If you define both a name and a formControlName attribute on your radio button, their values must match. Ex: <mdl-radio formControlName="food" name="food"></mdl-radio> `); }; const IS_FOCUSED = "is-focused"; // Registry for mdl-readio compnents. Is responsible to keep the // right state of the radio buttons of a radio group. It would be // easier if i had a mdl-radio-group component. but this would be // a big braking change. export class MdlRadioGroupRegisty { constructor() { this.defaultFormGroup = "defaultFromGroup"; this.radioComponents = []; } add(radioComponent, formGroupName) { this.radioComponents.push({ radio: radioComponent, group: formGroupName || this.defaultFormGroup, }); } remove(radioComponent) { this.radioComponents = this.radioComponents.filter((radioComponentInArray) => radioComponentInArray.radio !== radioComponent); } select(radioComponent, formGroupName) { // unselect every radioComponent that is not the provided radiocomponent // and has the same name and is in teh same group. const groupToTest = formGroupName || this.defaultFormGroup; this.radioComponents.forEach((component) => { if (component.radio.name === radioComponent.name && component.group === groupToTest) { if (component.radio !== radioComponent) { component.radio.deselect(radioComponent.value); } } }); } } MdlRadioGroupRegisty.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlRadioGroupRegisty, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); MdlRadioGroupRegisty.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlRadioGroupRegisty, providedIn: "root" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlRadioGroupRegisty, decorators: [{ type: Injectable, args: [{ providedIn: "root", }] }] }); /* <mdl-radio name="group1" value="1" [(ngModel)]="radioOption">Value 1</mdl-radio> */ export class MdlRadioComponent { constructor(elementRef, renderer, radioGroupRegistry, formGroupName) { this.elementRef = elementRef; this.renderer = renderer; this.radioGroupRegistry = radioGroupRegistry; this.formGroupName = formGroupName; this.tabindex = null; // eslint-disable-next-line @angular-eslint/no-output-native this.change = new EventEmitter(); // the internal state - used to set the underlaying radio button state. this.checked = false; this.isUpgraded = true; this.isRadio = true; this.onTouchedCallback = noop; this.onChangeCallback = noop; this.disabledIntern = false; this.el = elementRef.nativeElement; } get disabled() { return this.disabledIntern; } set disabled(value) { this.disabledIntern = toBoolean(value); } onClick() { if (this.disabled) { return; } this.optionValue = this.value; this.updateCheckState(); this.onChangeCallback(); this.change.emit(this.optionValue); } ngOnInit() { // we need a name and it must be the same as in the formcontrol. // a radio group without name is useless. this.checkName(); // register the radio button - this is the only chance to unselect the // radio button that is no longer active - scope the radio button with it's group // if there is one. this.radioGroupRegistry.add(this, this.formGroupName); } ngOnDestroy() { this.radioGroupRegistry.remove(this); } writeValue(optionValue) { this.optionValue = optionValue; this.updateCheckState(); } deselect(value) { // called from the registry. the value is the value of the selected radio button // e.g. the radio button get unselected if it isnÄt the selected one. this.writeValue(value); } registerOnChange(fn) { // wrap the callback, so that we can call select on the registry this.onChangeCallback = () => { fn(this.value); this.radioGroupRegistry.select(this, this.formGroupName); }; } registerOnTouched(fn) { this.onTouchedCallback = fn; } setDisabledState(isDisabled) { this.disabled = isDisabled; } onFocus() { this.renderer.addClass(this.el, IS_FOCUSED); } onBlur() { this.renderer.removeClass(this.el, IS_FOCUSED); } spaceKeyPress() { this.checked = false; // in case of space key is pressed radio button value must remain same } updateCheckState() { this.checked = this.optionValue === this.value; } checkName() { if (this.name && this.formControlName && this.name !== this.formControlName) { throwNameError(); } if (!this.name && this.formControlName) { this.name = this.formControlName; } } } MdlRadioComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlRadioComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: MdlRadioGroupRegisty }, { token: i1.FormGroupName, optional: true }], target: i0.ɵɵFactoryTarget.Component }); MdlRadioComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MdlRadioComponent, selector: "mdl-radio", inputs: { name: "name", formControlName: "formControlName", value: "value", tabindex: "tabindex", disabled: "disabled" }, outputs: { change: "change" }, host: { listeners: { "click": "onClick()" }, properties: { "class.is-checked": "this.checked", "class.is-upgraded": "this.isUpgraded", "class.mdl-radio": "this.isRadio", "class.is-disabled": "this.disabled" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MdlRadioComponent), multi: true, }, ], ngImport: i0, template: ` <input type="checkbox" class="mdl-radio__button" [attr.name]="name" (focus)="onFocus()" (blur)="onBlur()" (keyup.space)="spaceKeyPress()" [disabled]="disabled" [attr.tabindex]="tabindex" [(ngModel)]="checked" /> <span class="mdl-radio__label"><ng-content></ng-content></span> <span class="mdl-radio__outer-circle"></span> <span class="mdl-radio__inner-circle"></span> `, isInline: true, dependencies: [{ kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MdlRadioComponent, decorators: [{ type: Component, args: [{ selector: "mdl-radio", providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MdlRadioComponent), multi: true, }, ], template: ` <input type="checkbox" class="mdl-radio__button" [attr.name]="name" (focus)="onFocus()" (blur)="onBlur()" (keyup.space)="spaceKeyPress()" [disabled]="disabled" [attr.tabindex]="tabindex" [(ngModel)]="checked" /> <span class="mdl-radio__label"><ng-content></ng-content></span> <span class="mdl-radio__outer-circle"></span> <span class="mdl-radio__inner-circle"></span> `, encapsulation: ViewEncapsulation.None, }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: MdlRadioGroupRegisty }, { type: i1.FormGroupName, decorators: [{ type: Optional }] }]; }, propDecorators: { name: [{ type: Input }], formControlName: [{ type: Input }], value: [{ type: Input }], tabindex: [{ type: Input }], // eslint-disable-next-line @angular-eslint/no-output-native change: [{ type: Output }], checked: [{ type: HostBinding, args: ["class.is-checked"] }], isUpgraded: [{ type: HostBinding, args: ["class.is-upgraded"] }], isRadio: [{ type: HostBinding, args: ["class.mdl-radio"] }], disabled: [{ type: HostBinding, args: ["class.is-disabled"] }, { type: Input }], onClick: [{ type: HostListener, args: ["click"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRsLXJhZGlvLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvcmUvc3JjL2xpYi9yYWRpby9tZGwtcmFkaW8uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixVQUFVLEVBQ1YsS0FBSyxFQUdMLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBRUwsYUFBYSxFQUNiLGlCQUFpQixHQUNsQixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQUV0QyxNQUFNLGNBQWMsR0FBRyxHQUFTLEVBQUU7SUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQzs7O0tBR2IsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDO0FBRUYsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDO0FBRWhDLGdFQUFnRTtBQUNoRSxpRUFBaUU7QUFDakUsaUVBQWlFO0FBQ2pFLHdCQUF3QjtBQUl4QixNQUFNLE9BQU8sb0JBQW9CO0lBSGpDO1FBSVUscUJBQWdCLEdBQUcsa0JBQWtCLENBQUM7UUFDdEMsb0JBQWUsR0FHakIsRUFBRSxDQUFDO0tBaUNWO0lBL0JDLEdBQUcsQ0FBQyxjQUFpQyxFQUFFLGFBQTRCO1FBQ2pFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDO1lBQ3hCLEtBQUssRUFBRSxjQUFjO1lBQ3JCLEtBQUssRUFBRSxhQUFhLElBQUksSUFBSSxDQUFDLGdCQUFnQjtTQUM5QyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsTUFBTSxDQUFD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QUFDLGlCQUFpQjtnQkFvQjFCLFFBQVE7c0JBRlgsV0FBVzt1QkFBQyxtQkFBbUI7O3NCQUMvQixLQUFLO2dCQVVOLE9BQU87c0JBRE4sWUFBWTt1QkFBQyxPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIEluamVjdGFibGUsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUmVuZGVyZXIyLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7XG4gIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICBGb3JtR3JvdXBOYW1lLFxuICBOR19WQUxVRV9BQ0NFU1NPUixcbn0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyB0b0Jvb2xlYW4gfSBmcm9tIFwiLi4vY29tbW9uL2Jvb2xlYW4tcHJvcGVydHlcIjtcbmltcG9ydCB7IG5vb3AgfSBmcm9tIFwiLi4vY29tbW9uL25vb3BcIjtcblxuY29uc3QgdGhyb3dOYW1lRXJyb3IgPSAoKTogdm9pZCA9PiB7XG4gIHRocm93IG5ldyBFcnJvcihgXG4gICAgICBJZiB5b3UgZGVmaW5lIGJvdGggYSBuYW1lIGFuZCBhIGZvcm1Db250cm9sTmFtZSBhdHRyaWJ1dGUgb24geW91ciByYWRpbyBidXR0b24sIHRoZWlyIHZhbHVlc1xuICAgICAgbXVzdCBtYXRjaC4gRXg6IDxtZGwtcmFkaW8gZm9ybUNvbnRyb2xOYW1lPVwiZm9vZFwiIG5hbWU9XCJmb29kXCI+PC9tZGwtcmFkaW8+XG4gICAgYCk7XG59O1xuXG5jb25zdCBJU19GT0NVU0VEID0gXCJpcy1mb2N1c2VkXCI7XG5cbi8vIFJlZ2lzdHJ5IGZvciBtZGwtcmVhZGlvIGNvbXBuZW50cy4gSXMgcmVzcG9uc2libGUgdG8ga2VlcCB0aGVcbi8vIHJpZ2h0IHN0YXRlIG9mIHRoZSByYWRpbyBidXR0b25zIG9mIGEgcmFkaW8gZ3JvdXAuIEl0IHdvdWxkIGJlXG4vLyBlYXNpZXIgaWYgaSBoYWQgYSBtZGwtcmFkaW8tZ3JvdXAgY29tcG9uZW50LiBidXQgdGhpcyB3b3VsZCBiZVxuLy8gYSBiaWcgYnJha2luZyBjaGFuZ2UuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46IFwicm9vdFwiLFxufSlcbmV4cG9ydCBjbGFzcyBNZGxSYWRpb0dyb3VwUmVnaXN0eSB7XG4gIHByaXZhdGUgZGVmYXVsdEZvcm1Hcm91cCA9IFwiZGVmYXVsdEZyb21Hcm91cFwiO1xuICBwcml2YXRlIHJhZGlvQ29tcG9uZW50czoge1xuICAgIHJhZGlvOiBNZGxSYWRpb0NvbXBvbmVudDtcbiAgICBncm91cDogRm9ybUdyb3VwTmFtZSB8IHN0cmluZztcbiAgfVtdID0gW107XG5cbiAgYWRkKHJhZGlvQ29tcG9uZW50OiBNZGxSYWRpb0NvbXBvbmVudCwgZm9ybUdyb3VwTmFtZTogRm9ybUdyb3VwTmFtZSk6IHZvaWQge1xuICAgIHRoaXMucmFkaW9Db21wb25lbnRzLnB1c2goe1xuICAgICAgcmFkaW86IHJhZGlvQ29tcG9uZW50LFxuICAgICAgZ3JvdXA6IGZvcm1Hcm91cE5hbWUgfHwgdGhpcy5kZWZhdWx0Rm9ybUdyb3VwLFxuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlKHJhZGlvQ29tcG9uZW50OiBNZGxSYWRpb0NvbXBvbmVudCk6IHZvaWQge1xuICAgIHRoaXMucmFkaW9Db21wb25lbnRzID0gdGhpcy5yYWRpb0NvbXBvbmVudHMuZmlsdGVyKFxuICAgICAgKHJhZGlvQ29tcG9uZW50SW5BcnJheSkgPT4gcmFkaW9Db21wb25lbnRJbkFycmF5LnJhZGlvICE9PSByYWRpb0NvbXBvbmVudFxuICAgICk7XG4gIH1cblxuICBzZWxlY3QoXG4gICAgcmFkaW9Db21wb25lbnQ6IE1kbFJhZGlvQ29tcG9uZW50LFxuICAgIGZvcm1Hcm91cE5hbWU6IEZvcm1Hcm91cE5hbWVcbiAgKTogdm9pZCB7XG4gICAgLy8gdW5zZWxlY3QgZXZlcnkgcmFkaW9Db21wb25lbnQgdGhhdCBpcyBub3QgdGhlIHByb3ZpZGVkIHJhZGlvY29tcG9uZW50XG4gICAgLy8gYW5kIGhhcyB0aGUgc2FtZSBuYW1lIGFuZCBpcyBpbiB0ZWggc2FtZSBncm91cC5cbiAgICBjb25zdCBncm91cFRvVGVzdCA9IGZvcm1Hcm91cE5hbWUgfHwgdGhpcy5kZWZhdWx0Rm9ybUdyb3VwO1xuICAgIHRoaXMucmFkaW9Db21wb25lbnRzLmZvckVhY2goKGNvbXBvbmVudCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBjb21wb25lbnQucmFkaW8ubmFtZSA9PT0gcmFkaW9Db21wb25lbnQubmFtZSAmJlxuICAgICAgICBjb21wb25lbnQuZ3JvdXAgPT09IGdyb3VwVG9UZXN0XG4gICAgICApIHtcbiAgICAgICAgaWYgKGNvbXBvbmVudC5yYWRpbyAhPT0gcmFkaW9Db21wb25lbnQpIHtcbiAgICAgICAgICBjb21wb25lbnQucmFkaW8uZGVzZWxlY3QocmFkaW9Db21wb25lbnQudmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuLypcbiA8bWRsLXJhZGlvIG5hbWU9XCJncm91cDFcIiB2YWx1ZT1cIjFcIiBbKG5nTW9kZWwpXT1cInJhZGlvT3B0aW9uXCI+VmFsdWUgMTwvbWRsLXJhZGlvPlxuICovXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJtZGwtcmFkaW9cIixcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBNZGxSYWRpb0NvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICB9LFxuICBdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxpbnB1dFxuICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgIGNsYXNzPVwibWRsLXJhZGlvX19idXR0b25cIlxuICAgICAgW2F0dHIubmFtZV09XCJuYW1lXCJcbiAgICAgIChmb2N1cyk9XCJvbkZvY3VzKClcIlxuICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgKGtleXVwLnNwYWNlKT1cInNwYWNlS2V5UHJlc3MoKVwiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgW2F0dHIudGFiaW5kZXhdPVwidGFiaW5kZXhcIlxuICAgICAgWyhuZ01vZGVsKV09XCJjaGVja2VkXCJcbiAgICAvPlxuICAgIDxzcGFuIGNsYXNzPVwibWRsLXJhZGlvX19sYWJlbFwiPjxuZy1jb250ZW50PjwvbmctY29udGVudD48L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJtZGwtcmFkaW9fX291dGVyLWNpcmNsZVwiPjwvc3Bhbj5cbiAgICA8c3BhbiBjbGFzcz1cIm1kbC1yYWRpb19faW5uZXItY2lyY2xlXCI+PC9zcGFuPlxuICBgLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBNZGxSYWRpb0NvbXBvbmVudFxuICBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uRGVzdHJveVxue1xuICBASW5wdXQoKVxuICBuYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpXG4gIGZvcm1Db250cm9sTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKVxuICB2YWx1ZTogdW5rbm93bjtcbiAgQElucHV0KClcbiAgdGFiaW5kZXggPSBudWxsO1xuICBAT3V0cHV0KClcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtbmF0aXZlXG4gIGNoYW5nZTogRXZlbnRFbWl0dGVyPHVua25vd24+ID0gbmV3IEV2ZW50RW1pdHRlcjx1bmtub3duPigpO1xuICAvLyB0aGUgaW50ZXJuYWwgc3RhdGUgLSB1c2VkIHRvIHNldCB0aGUgdW5kZXJsYXlpbmcgcmFkaW8gYnV0dG9uIHN0YXRlLlxuICBASG9zdEJpbmRpbmcoXCJjbGFzcy5pcy1jaGVja2VkXCIpXG4gIGNoZWNrZWQgPSBmYWxzZTtcbiAgQEhvc3RCaW5kaW5nKFwiY2xhc3MuaXMtdXBncmFkZWRcIikgaXNVcGdyYWRlZCA9IHRydWU7XG4gIEBIb3N0QmluZGluZyhcImNsYXNzLm1kbC1yYWRpb1wiKSBpc1JhZGlvID0gdHJ1ZTtcblxuICBwdWJsaWMgb3B0aW9uVmFsdWU6IHVua25vd247XG5cbiAgcHJpdmF0ZSByZWFkb25seSBlbDogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgb25Ub3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSBub29wO1xuICBwcml2YXRlIG9uQ2hhbmdlQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSBub29wO1xuICBwcml2YXRlIGRpc2FibGVkSW50ZXJuID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICBwcml2YXRlIHJhZGlvR3JvdXBSZWdpc3RyeTogTWRsUmFkaW9Hcm91cFJlZ2lzdHksXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBmb3JtR3JvdXBOYW1lOiBGb3JtR3JvdXBOYW1lXG4gICkge1xuICAgIHRoaXMuZWwgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoXCJjbGFzcy5pcy1kaXNhYmxlZFwiKVxuICBASW5wdXQoKVxuICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZGlzYWJsZWRJbnRlcm47XG4gIH1cblxuICBzZXQgZGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmRpc2FibGVkSW50ZXJuID0gdG9Cb29sZWFuKHZhbHVlKTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoXCJjbGlja1wiKVxuICBvbkNsaWNrKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub3B0aW9uVmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgIHRoaXMudXBkYXRlQ2hlY2tTdGF0ZSgpO1xuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjaygpO1xuICAgIHRoaXMuY2hhbmdlLmVtaXQodGhpcy5vcHRpb25WYWx1ZSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyB3ZSBuZWVkIGEgbmFtZSBhbmQgaXQgbXVzdCBiZSB0aGUgc2FtZSBhcyBpbiB0aGUgZm9ybWNvbnRyb2wuXG4gICAgLy8gYSByYWRpbyBncm91cCB3aXRob3V0IG5hbWUgaXMgdXNlbGVzcy5cbiAgICB0aGlzLmNoZWNrTmFtZSgpO1xuICAgIC8vIHJlZ2lzdGVyIHRoZSByYWRpbyBidXR0b24gLSB0aGlzIGlzIHRoZSBvbmx5IGNoYW5jZSB0byB1bnNlbGVjdCB0aGVcbiAgICAvLyByYWRpbyBidXR0b24gdGhhdCBpcyBubyBsb25nZXIgYWN0aXZlIC0gc2NvcGUgdGhlIHJhZGlvIGJ1dHRvbiB3aXRoIGl0J3MgZ3JvdXBcbiAgICAvLyBpZiB0aGVyZSBpcyBvbmUuXG4gICAgdGhpcy5yYWRpb0dyb3VwUmVnaXN0cnkuYWRkKHRoaXMsIHRoaXMuZm9ybUdyb3VwTmFtZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnJhZGlvR3JvdXBSZWdpc3RyeS5yZW1vdmUodGhpcyk7XG4gIH1cblxuICB3cml0ZVZhbHVlKG9wdGlvblZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgdGhpcy5vcHRpb25WYWx1ZSA9IG9wdGlvblZhbHVlO1xuICAgIHRoaXMudXBkYXRlQ2hlY2tTdGF0ZSgpO1xuICB9XG5cbiAgZGVzZWxlY3QodmFsdWU6IHVua25vd24pOiB2b2lkIHtcbiAgICAvLyBjYWxsZWQgZnJvbSB0aGUgcmVnaXN0cnkuIHRoZSB2YWx1ZSBpcyB0aGUgdmFsdWUgb2YgdGhlIHNlbGVjdGVkIHJhZGlvIGJ1dHRvblxuICAgIC8vIGUuZy4gdGhlIHJhZGlvIGJ1dHRvbiBnZXQgdW5zZWxlY3RlZCBpZiBpdCBpc27DhHQgdGhlIHNlbGVjdGVkIG9uZS5cbiAgICB0aGlzLndyaXRlVmFsdWUodmFsdWUpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHY6IHVua25vd24pID0+IHVua25vd24pOiB2b2lkIHtcbiAgICAvLyB3cmFwIHRoZSBjYWxsYmFjaywgc28gdGhhdCB3ZSBjYW4gY2FsbCBzZWxlY3Qgb24gdGhlIHJlZ2lzdHJ5XG4gICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgZm4odGhpcy52YWx1ZSk7XG4gICAgICB0aGlzLnJhZGlvR3JvdXBSZWdpc3RyeS5zZWxlY3QodGhpcywgdGhpcy5mb3JtR3JvdXBOYW1lKTtcbiAgICB9O1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHVua25vd24pOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZENhbGxiYWNrID0gZm47XG4gIH1cblxuICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgfVxuXG4gIG9uRm9jdXMoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyh0aGlzLmVsLCBJU19GT0NVU0VEKTtcbiAgfVxuXG4gIG9uQmx1cigpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuZWwsIElTX0ZPQ1VTRUQpO1xuICB9XG5cbiAgc3BhY2VLZXlQcmVzcygpOiB2b2lkIHtcbiAgICB0aGlzLmNoZWNrZWQgPSBmYWxzZTsgLy8gaW4gY2FzZSBvZiBzcGFjZSBrZXkgaXMgcHJlc3NlZCByYWRpbyBidXR0b24gdmFsdWUgbXVzdCByZW1haW4gc2FtZVxuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVDaGVja1N0YXRlKCkge1xuICAgIHRoaXMuY2hlY2tlZCA9IHRoaXMub3B0aW9uVmFsdWUgPT09IHRoaXMudmFsdWU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrTmFtZSgpOiB2b2lkIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLm5hbWUgJiZcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2xOYW1lICYmXG4gICAgICB0aGlzLm5hbWUgIT09IHRoaXMuZm9ybUNvbnRyb2xOYW1lXG4gICAgKSB7XG4gICAgICB0aHJvd05hbWVFcnJvcigpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMubmFtZSAmJiB0aGlzLmZvcm1Db250cm9sTmFtZSkge1xuICAgICAgdGhpcy5uYW1lID0gdGhpcy5mb3JtQ29udHJvbE5hbWU7XG4gICAgfVxuICB9XG59XG4iXX0=