ngx-tagify
Version:
Angular library that wraps @yaireo/tagify
229 lines • 28.5 kB
JavaScript
import { Component, EventEmitter, forwardRef, Input, Output, ViewChild, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { asyncScheduler, BehaviorSubject, fromEvent, Subject, } from 'rxjs';
import { takeUntil, throttleTime } from 'rxjs/operators';
import Tagify from '@yaireo/tagify';
import * as i0 from "@angular/core";
import * as i1 from "./tagify.service";
import * as i2 from "@angular/common";
export class TagifyComponent {
set inputClass(v) {
this.setTagsClass(v);
this.inputClassValue = v;
}
set readonly(v) {
this.readonlyValue = !!v;
this.setReadonly();
}
set disabled(v) {
this.disabledValue = !!v;
this.setDisabled();
}
get value() {
return this.valueData;
}
set value(v) {
if (v !== this.valueData) {
this.valueData = v;
this.onChange(v);
}
}
constructor(tagifyService, element) {
this.tagifyService = tagifyService;
this.element = element;
this.valueType = 'undefined';
this.onChange = Function.prototype;
this.onTouched = Function.prototype;
this.unsubscribe$ = new Subject();
this.value$ = new BehaviorSubject(null);
this.skip = false;
this.inputClassValue = '';
this.readonlyValue = false;
this.disabledValue = false;
this.settings = {};
this.name = '';
this.add = new EventEmitter();
this.remove = new EventEmitter();
this.tInput = new EventEmitter();
}
ngAfterViewInit() {
this.settings.callbacks = this.settings.callbacks || {};
if (!Object.prototype.hasOwnProperty.call(this.settings.callbacks, 'add')) {
this.settings.callbacks.add = () => this.add.emit({
tags: this.tagify.value,
added: this.tagify.value[this.tagify.value.length - 1],
});
}
if (!Object.prototype.hasOwnProperty.call(this.settings.callbacks, 'remove')) {
this.settings.callbacks.remove = () => this.remove.emit(this.tagify.value);
}
const innerText = this.element.nativeElement.textContent;
this.tagify = new Tagify(this.inputRef.nativeElement, this.settings);
// add to service if name is provided
if (this.name.length) {
this.tagifyService.add(this.name, this.tagify);
}
this.setReadonly();
this.setDisabled();
// if there is some text inside component, load this value and skip first change check
if (innerText.length) {
this.tagify.loadOriginalValues(innerText);
this.skip = true;
setTimeout(() => {
this.setValue();
});
}
// listen to value changes from outside
this.value$.pipe(takeUntil(this.unsubscribe$)).subscribe((tags) => {
if (tags === null)
return;
if (this.skip) {
this.skip = false;
return;
}
if (this.valueType === 'undefined') {
this.valueType = typeof tags;
}
// if string is passed, e.g. via reactive forms
if (typeof tags === 'string') {
this.tagify.loadOriginalValues(tags);
setTimeout(() => {
this.setValue();
});
return;
}
// add all tags (already existing tags will be skipped
this.tagify.addTags(tags, false, true);
// remove all tags that are not part of value anymore
this.tagify.value.forEach((v) => {
if (!tags.find((t) => t.value === v.value)) {
// somehow removeTags() with string parameter doesn't always find the tag element
// this is a workaround for finding the right tag element
const tagElm = this.tagify
.getTagElms()
.find((el) => el.attributes.getNamedItem('value').textContent === v.value);
this.tagify.removeTags(tagElm);
}
});
});
// listen to tagify events
this.tagify.on('input', (e) => {
const value = 'value' in e.detail ? e.detail.value : e.detail.textContent;
this.tInput.emit(value);
if (this.valueType === 'string' && this.tagify.settings.mode === 'mix') {
this.value = this.tagify.getMixedTagsAsString();
}
});
fromEvent(this.tagify, 'change')
.pipe(
// throttle used to reduce number of value changes when adding/removing a bunch of tags
throttleTime(0, asyncScheduler, { leading: false, trailing: true }), takeUntil(this.unsubscribe$))
.subscribe(() => {
this.setValue();
});
// listen to suggestions updates
if (this.whitelist) {
this.whitelist.pipe(takeUntil(this.unsubscribe$)).subscribe((list) => {
this.tagify.settings.whitelist = list;
});
}
}
writeValue(tags) {
this.value$.next(tags);
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
setValue() {
if (this.valueType === 'string') {
if (this.tagify.settings.mode === 'mix') {
this.value = this.tagify.getMixedTagsAsString();
}
else {
this.value = this.tagify.DOM.originalInput.value;
}
}
else {
this.value = this.tagify.value.slice();
}
}
/**
* Tagify creates a `tags` element to which the classes of the `input` element are applied.
* Changes of `inputClass` are applied automatically to the `input` element, but have to be
* manually applied to the `tags` element.
*/
setTagsClass(v) {
const tagsElement = this.element.nativeElement.querySelector('tags');
if (tagsElement) {
tagsElement.classList.remove(...this.inputClassValue.split(/\s+/));
tagsElement.classList.add(...v.split(/\s+/));
}
}
setReadonly() {
if (this.tagify) {
this.tagify.setReadonly(this.readonlyValue);
}
}
setDisabled() {
if (this.tagify) {
this.tagify.setDisabled(this.disabledValue);
}
}
ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
this.tagify.destroy();
if (this.name.length) {
this.tagifyService.remove(this.name);
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TagifyComponent, deps: [{ token: i1.TagifyService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TagifyComponent, selector: "tagify", inputs: { settings: "settings", name: "name", whitelist: "whitelist", inputClass: "inputClass", readonly: "readonly", disabled: "disabled" }, outputs: { add: "add", remove: "remove", tInput: "tInput" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TagifyComponent),
multi: true,
},
], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true, static: true }], ngImport: i0, template: `<input [ngClass]="inputClassValue" #inputRef />
<span style="display: none"><ng-content></ng-content></span>`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TagifyComponent, decorators: [{
type: Component,
args: [{
selector: 'tagify',
template: `<input [ngClass]="inputClassValue" #inputRef />
<span style="display: none"><ng-content></ng-content></span>`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => TagifyComponent),
multi: true,
},
],
}]
}], ctorParameters: () => [{ type: i1.TagifyService }, { type: i0.ElementRef }], propDecorators: { inputRef: [{
type: ViewChild,
args: ['inputRef', { static: true }]
}], settings: [{
type: Input
}], name: [{
type: Input
}], whitelist: [{
type: Input
}], inputClass: [{
type: Input
}], readonly: [{
type: Input
}], disabled: [{
type: Input
}], add: [{
type: Output
}], remove: [{
type: Output
}], tInput: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnaWZ5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10YWdpZnkvc3JjL2xpYi90YWdpZnkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBRVQsWUFBWSxFQUNaLFVBQVUsRUFDVixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUNMLGNBQWMsRUFDZCxlQUFlLEVBQ2YsU0FBUyxFQUVULE9BQU8sR0FDUixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxNQUFtQyxNQUFNLGdCQUFnQixDQUFDOzs7O0FBZWpFLE1BQU0sT0FBTyxlQUFlO0lBMEIxQixJQUFhLFVBQVUsQ0FBQyxDQUFTO1FBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVELElBQWEsUUFBUSxDQUFDLENBQVU7UUFDOUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsSUFBYSxRQUFRLENBQUMsQ0FBVTtRQUM5QixJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksS0FBSyxDQUFDLENBQXFCO1FBQzdC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QUFDLE9BQU8sRUFBRSxDQUFDO1FBRXRCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkMsQ0FBQztJQUNILENBQUM7K0dBbE9VLGVBQWU7bUdBQWYsZUFBZSw0T0FSZjtZQUNUO2dCQUNFLE9BQU8sRUFBRSxpQkFBaUI7Z0JBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDO2dCQUM5QyxLQUFLLEVBQUUsSUFBSTthQUNaO1NBQ0YsOElBUlM7aUVBQ3FEOzs0RkFTcEQsZUFBZTtrQkFaM0IsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsUUFBUTtvQkFDbEIsUUFBUSxFQUFFO2lFQUNxRDtvQkFDL0QsU0FBUyxFQUFFO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLGdCQUFnQixDQUFDOzRCQUM5QyxLQUFLLEVBQUUsSUFBSTt5QkFDWjtxQkFDRjtpQkFDRjsyR0FtQkMsUUFBUTtzQkFEUCxTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBRzlCLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsSUFBSTtzQkFBWixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRU8sVUFBVTtzQkFBdEIsS0FBSztnQkFLTyxRQUFRO3NCQUFwQixLQUFLO2dCQUtPLFFBQVE7c0JBQXBCLEtBQUs7Z0JBZ0JJLEdBQUc7c0JBQVosTUFBTTtnQkFDRyxNQUFNO3NCQUFmLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIGFzeW5jU2NoZWR1bGVyLFxuICBCZWhhdmlvclN1YmplY3QsXG4gIGZyb21FdmVudCxcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwsIHRocm90dGxlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCBUYWdpZnksIHsgVGFnRGF0YSwgVGFnaWZ5U2V0dGluZ3MgfSBmcm9tICdAeWFpcmVvL3RhZ2lmeSc7XG5pbXBvcnQgeyBUYWdpZnlTZXJ2aWNlIH0gZnJvbSAnLi90YWdpZnkuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RhZ2lmeScsXG4gIHRlbXBsYXRlOiBgPGlucHV0IFtuZ0NsYXNzXT1cImlucHV0Q2xhc3NWYWx1ZVwiICNpbnB1dFJlZiAvPlxuICAgIDxzcGFuIHN0eWxlPVwiZGlzcGxheTogbm9uZVwiPjxuZy1jb250ZW50PjwvbmctY29udGVudD48L3NwYW4+YCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBUYWdpZnlDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVGFnaWZ5Q29tcG9uZW50XG4gIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uRGVzdHJveVxue1xuICBwcml2YXRlIHZhbHVlRGF0YTogc3RyaW5nIHwgVGFnRGF0YVtdO1xuICBwcml2YXRlIHZhbHVlVHlwZSA9ICd1bmRlZmluZWQnO1xuICBwcml2YXRlIG9uQ2hhbmdlOiBhbnkgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG4gIHByaXZhdGUgb25Ub3VjaGVkOiBhbnkgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG5cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHZhbHVlJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nIHwgVGFnRGF0YVtdPihudWxsKTtcbiAgcHJpdmF0ZSB0YWdpZnk6IFRhZ2lmeTtcbiAgcHJpdmF0ZSBza2lwID0gZmFsc2U7XG5cbiAgaW5wdXRDbGFzc1ZhbHVlID0gJyc7XG4gIHByaXZhdGUgcmVhZG9ubHlWYWx1ZSA9IGZhbHNlO1xuICBwcml2YXRlIGRpc2FibGVkVmFsdWUgPSBmYWxzZTtcblxuICBAVmlld0NoaWxkKCdpbnB1dFJlZicsIHsgc3RhdGljOiB0cnVlIH0pXG4gIGlucHV0UmVmOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+O1xuXG4gIEBJbnB1dCgpIHNldHRpbmdzOiBUYWdpZnlTZXR0aW5ncyA9IHt9O1xuXG4gIEBJbnB1dCgpIG5hbWUgPSAnJztcblxuICBASW5wdXQoKSB3aGl0ZWxpc3Q6IE9ic2VydmFibGU8c3RyaW5nW10gfCBUYWdEYXRhW10+O1xuXG4gIEBJbnB1dCgpIHNldCBpbnB1dENsYXNzKHY6IHN0cmluZykge1xuICAgIHRoaXMuc2V0VGFnc0NsYXNzKHYpO1xuICAgIHRoaXMuaW5wdXRDbGFzc1ZhbHVlID0gdjtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCByZWFkb25seSh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5yZWFkb25seVZhbHVlID0gISF2O1xuICAgIHRoaXMuc2V0UmVhZG9ubHkoKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHNldCBkaXNhYmxlZCh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5kaXNhYmxlZFZhbHVlID0gISF2O1xuICAgIHRoaXMuc2V0RGlzYWJsZWQoKTtcbiAgfVxuXG4gIGdldCB2YWx1ZSgpOiBzdHJpbmcgfCBUYWdEYXRhW10ge1xuICAgIHJldHVybiB0aGlzLnZhbHVlRGF0YTtcbiAgfVxuXG4gIHNldCB2YWx1ZSh2OiBzdHJpbmcgfCBUYWdEYXRhW10pIHtcbiAgICBpZiAodiAhPT0gdGhpcy52YWx1ZURhdGEpIHtcbiAgICAgIHRoaXMudmFsdWVEYXRhID0gdjtcbiAgICAgIHRoaXMub25DaGFuZ2Uodik7XG4gICAgfVxuICB9XG5cbiAgQE91dHB1dCgpIGFkZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHJlbW92ZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHRJbnB1dCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdGFnaWZ5U2VydmljZTogVGFnaWZ5U2VydmljZSxcbiAgICBwcml2YXRlIGVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuc2V0dGluZ3MuY2FsbGJhY2tzID0gdGhpcy5zZXR0aW5ncy5jYWxsYmFja3MgfHwge307XG5cbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLnNldHRpbmdzLmNhbGxiYWNrcywgJ2FkZCcpKSB7XG4gICAgICB0aGlzLnNldHRpbmdzLmNhbGxiYWNrcy5hZGQgPSAoKSA9PlxuICAgICAgICB0aGlzLmFkZC5lbWl0KHtcbiAgICAgICAgICB0YWdzOiB0aGlzLnRhZ2lmeS52YWx1ZSxcbiAgICAgICAgICBhZGRlZDogdGhpcy50YWdpZnkudmFsdWVbdGhpcy50YWdpZnkudmFsdWUubGVuZ3RoIC0gMV0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5zZXR0aW5ncy5jYWxsYmFja3MsICdyZW1vdmUnKVxuICAgICkge1xuICAgICAgdGhpcy5zZXR0aW5ncy5jYWxsYmFja3MucmVtb3ZlID0gKCkgPT5cbiAgICAgICAgdGhpcy5yZW1vdmUuZW1pdCh0aGlzLnRhZ2lmeS52YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5uZXJUZXh0ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQudGV4dENvbnRlbnQ7XG5cbiAgICB0aGlzLnRhZ2lmeSA9IG5ldyBUYWdpZnkodGhpcy5pbnB1dFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLnNldHRpbmdzKTtcblxuICAgIC8vIGFkZCB0byBzZXJ2aWNlIGlmIG5hbWUgaXMgcHJvdmlkZWRcbiAgICBpZiAodGhpcy5uYW1lLmxlbmd0aCkge1xuICAgICAgdGhpcy50YWdpZnlTZXJ2aWNlLmFkZCh0aGlzLm5hbWUsIHRoaXMudGFnaWZ5KTtcbiAgICB9XG5cbiAgICB0aGlzLnNldFJlYWRvbmx5KCk7XG4gICAgdGhpcy5zZXREaXNhYmxlZCgpO1xuXG4gICAgLy8gaWYgdGhlcmUgaXMgc29tZSB0ZXh0IGluc2lkZSBjb21wb25lbnQsIGxvYWQgdGhpcyB2YWx1ZSBhbmQgc2tpcCBmaXJzdCBjaGFuZ2UgY2hlY2tcbiAgICBpZiAoaW5uZXJUZXh0Lmxlbmd0aCkge1xuICAgICAgdGhpcy50YWdpZnkubG9hZE9yaWdpbmFsVmFsdWVzKGlubmVyVGV4dCk7XG4gICAgICB0aGlzLnNraXAgPSB0cnVlO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0VmFsdWUoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGxpc3RlbiB0byB2YWx1ZSBjaGFuZ2VzIGZyb20gb3V0c2lkZVxuICAgIHRoaXMudmFsdWUkLnBpcGUodGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUkKSkuc3Vic2NyaWJlKCh0YWdzKSA9PiB7XG4gICAgICBpZiAodGFncyA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgICBpZiAodGhpcy5za2lwKSB7XG4gICAgICAgIHRoaXMuc2tpcCA9IGZhbHNlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnZhbHVlVHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhpcy52YWx1ZVR5cGUgPSB0eXBlb2YgdGFncztcbiAgICAgIH1cblxuICAgICAgLy8gaWYgc3RyaW5nIGlzIHBhc3NlZCwgZS5nLiB2aWEgcmVhY3RpdmUgZm9ybXNcbiAgICAgIGlmICh0eXBlb2YgdGFncyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhpcy50YWdpZnkubG9hZE9yaWdpbmFsVmFsdWVzKHRhZ3MpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLnNldFZhbHVlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBhbGwgdGFncyAoYWxyZWFkeSBleGlzdGluZyB0YWdzIHdpbGwgYmUgc2tpcHBlZFxuICAgICAgdGhpcy50YWdpZnkuYWRkVGFncyh0YWdzLCBmYWxzZSwgdHJ1ZSk7XG5cbiAgICAgIC8vIHJlbW92ZSBhbGwgdGFncyB0aGF0IGFyZSBub3QgcGFydCBvZiB2YWx1ZSBhbnltb3JlXG4gICAgICB0aGlzLnRhZ2lmeS52YWx1ZS5mb3JFYWNoKCh2KSA9PiB7XG4gICAgICAgIGlmICghdGFncy5maW5kKCh0KSA9PiB0LnZhbHVlID09PSB2LnZhbHVlKSkge1xuICAgICAgICAgIC8vIHNvbWVob3cgcmVtb3ZlVGFncygpIHdpdGggc3RyaW5nIHBhcmFtZXRlciBkb2Vzbid0IGFsd2F5cyBmaW5kIHRoZSB0YWcgZWxlbWVudFxuICAgICAgICAgIC8vIHRoaXMgaXMgYSB3b3JrYXJvdW5kIGZvciBmaW5kaW5nIHRoZSByaWdodCB0YWcgZWxlbWVudFxuICAgICAgICAgIGNvbnN0IHRhZ0VsbSA9IHRoaXMudGFnaWZ5XG4gICAgICAgICAgICAuZ2V0VGFnRWxtcygpXG4gICAgICAgICAgICAuZmluZChcbiAgICAgICAgICAgICAgKGVsKSA9PlxuICAgICAgICAgICAgICAgIGVsLmF0dHJpYnV0ZXMuZ2V0TmFtZWRJdGVtKCd2YWx1ZScpLnRleHRDb250ZW50ID09PSB2LnZhbHVlLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLnRhZ2lmeS5yZW1vdmVUYWdzKHRhZ0VsbSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gbGlzdGVuIHRvIHRhZ2lmeSBldmVudHNcbiAgICB0aGlzLnRhZ2lmeS5vbignaW5wdXQnLCAoZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSAndmFsdWUnIGluIGUuZGV0YWlsID8gZS5kZXRhaWwudmFsdWUgOiBlLmRldGFpbC50ZXh0Q29udGVudDtcbiAgICAgIHRoaXMudElucHV0LmVtaXQodmFsdWUpO1xuICAgICAgaWYgKHRoaXMudmFsdWVUeXBlID09PSAnc3RyaW5nJyAmJiB0aGlzLnRhZ2lmeS5zZXR0aW5ncy5tb2RlID09PSAnbWl4Jykge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy50YWdpZnkuZ2V0TWl4ZWRUYWdzQXNTdHJpbmcoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGZyb21FdmVudCh0aGlzLnRhZ2lmeSwgJ2NoYW5nZScpXG4gICAgICAucGlwZShcbiAgICAgICAgLy8gdGhyb3R0bGUgdXNlZCB0byByZWR1Y2UgbnVtYmVyIG9mIHZhbHVlIGNoYW5nZXMgd2hlbiBhZGRpbmcvcmVtb3ZpbmcgYSBidW5jaCBvZiB0YWdzXG4gICAgICAgIHRocm90dGxlVGltZSgwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiBmYWxzZSwgdHJhaWxpbmc6IHRydWUgfSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLnVuc3Vic2NyaWJlJCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZSgpO1xuICAgICAgfSk7XG5cbiAgICAvLyBsaXN0ZW4gdG8gc3VnZ2VzdGlvbnMgdXBkYXRlc1xuICAgIGlmICh0aGlzLndoaXRlbGlzdCkge1xuICAgICAgdGhpcy53aGl0ZWxpc3QucGlwZSh0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZSQpKS5zdWJzY3JpYmUoKGxpc3QpID0+IHtcbiAgICAgICAgdGhpcy50YWdpZnkuc2V0dGluZ3Mud2hpdGVsaXN0ID0gbGlzdDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodGFnczogc3RyaW5nIHwgVGFnRGF0YVtdKSB7XG4gICAgdGhpcy52YWx1ZSQubmV4dCh0YWdzKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSkge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRWYWx1ZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52YWx1ZVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAodGhpcy50YWdpZnkuc2V0dGluZ3MubW9kZSA9PT0gJ21peCcpIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMudGFnaWZ5LmdldE1peGVkVGFnc0FzU3RyaW5nKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbHVlID0gdGhpcy50YWdpZnkuRE9NLm9yaWdpbmFsSW5wdXQudmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudmFsdWUgPSB0aGlzLnRhZ2lmeS52YWx1ZS5zbGljZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUYWdpZnkgY3JlYXRlcyBhIGB0YWdzYCBlbGVtZW50IHRvIHdoaWNoIHRoZSBjbGFzc2VzIG9mIHRoZSBgaW5wdXRgIGVsZW1lbnQgYXJlIGFwcGxpZWQuXG4gICAqIENoYW5nZXMgb2YgYGlucHV0Q2xhc3NgIGFyZSBhcHBsaWVkIGF1dG9tYXRpY2FsbHkgdG8gdGhlIGBpbnB1dGAgZWxlbWVudCwgYnV0IGhhdmUgdG8gYmVcbiAgICogbWFudWFsbHkgYXBwbGllZCB0byB0aGUgYHRhZ3NgIGVsZW1lbnQuXG4gICAqL1xuICBwcml2YXRlIHNldFRhZ3NDbGFzcyh2OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0YWdzRWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3RhZ3MnKTtcbiAgICBpZiAodGFnc0VsZW1lbnQpIHtcbiAgICAgIHRhZ3NFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoLi4udGhpcy5pbnB1dENsYXNzVmFsdWUuc3BsaXQoL1xccysvKSk7XG4gICAgICB0YWdzRWxlbWVudC5jbGFzc0xpc3QuYWRkKC4uLnYuc3BsaXQoL1xccysvKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXRSZWFkb25seSgpIHtcbiAgICBpZiAodGhpcy50YWdpZnkpIHtcbiAgICAgIHRoaXMudGFnaWZ5LnNldFJlYWRvbmx5KHRoaXMucmVhZG9ubHlWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzZXREaXNhYmxlZCgpIHtcbiAgICBpZiAodGhpcy50YWdpZnkpIHtcbiAgICAgIHRoaXMudGFnaWZ5LnNldERpc2FibGVkKHRoaXMuZGlzYWJsZWRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnN1YnNjcmliZSQubmV4dCgpO1xuICAgIHRoaXMudW5zdWJzY3JpYmUkLmNvbXBsZXRlKCk7XG5cbiAgICB0aGlzLnRhZ2lmeS5kZXN0cm95KCk7XG5cbiAgICBpZiAodGhpcy5uYW1lLmxlbmd0aCkge1xuICAgICAgdGhpcy50YWdpZnlTZXJ2aWNlLnJlbW92ZSh0aGlzLm5hbWUpO1xuICAgIH1cbiAgfVxufVxuIl19