UNPKG

@doku-dev/doku-fragment

Version:

A new Angular UI library that moving away from Bootstrap and built from scratch.

258 lines 41.6 kB
import { CommonModule, DOCUMENT, DatePipe } from '@angular/common'; import { ChangeDetectionStrategy, Component, Host, HostBinding, Inject, Injector, Input, LOCALE_ID, Optional, Self, ViewEncapsulation, createComponent, } from '@angular/core'; import { Subject, delay, distinctUntilChanged, filter, fromEvent, map, skip, startWith, takeUntil, } from 'rxjs'; import { getClickType } from '../../../utils/get-click-type'; import { updateFloatingPosition } from '../../../utils/update-floating-position'; import { DOKU_FORM_FIELD_ACCESSOR, } from '../../form-field'; import { DokuDatePickerBase } from '../base/date-picker-base.component'; import { DokuDatePickerBasicProps } from '../common/date-picker-basic-props.component'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "../../form-field"; export class DokuDatePicker extends DokuDatePickerBasicProps { constructor(renderer, envInjector, injector, appRef, ngZone, datePipe, cdr, document, localeId, ngControl, formField) { super(); this.renderer = renderer; this.envInjector = envInjector; this.injector = injector; this.appRef = appRef; this.ngZone = ngZone; this.datePipe = datePipe; this.cdr = cdr; this.document = document; this.localeId = localeId; this.ngControl = ngControl; this.formField = formField; this.class = 'd-date-picker'; /** * Whether to close date picker dropdown after selecting the date. * * @default true */ this.closeOnDateClick = true; /** * Date format that will be used for formatting displayed value in the input field. It follows Angular DatePipe's format options. * * @default 'dd/MM/yyyy' */ this.dateFormat = 'dd/MM/yyyy'; /** * Placeholder of the date picker input. * * @default 'dd/mm/yyyy' */ this.placeholder = 'dd/mm/yyyy'; this.isOpen = false; this.destroy$ = new Subject(); if (this.ngControl) { this.ngControl.valueAccessor = this; } this.onClickHandler(); } get formattedValue() { return this.value ? this.datePipe.transform(this.value, this.dateFormat, undefined, this.localeId) : null; } get inputWrapperElement() { return this.formField?.['inputWrapperElement']; } ngOnInit() { this.notifyChange$ .pipe(filter((change) => change === 'value' || change === 'minDate' || change === 'maxDate'), startWith(this.value?.toISOString() || null), map(() => this.value?.toISOString() || null), distinctUntilChanged(), skip(1), takeUntil(this.destroy$)) .subscribe((value) => { this.valueChange.emit(value); }); this.valueChange.pipe(distinctUntilChanged(), takeUntil(this.destroy$)).subscribe((value) => { this.onChange?.(value); this.onTouched?.(); this.cdr.detectChanges(); }); } ngAfterViewInit() { this.ngControl?.statusChanges ?.pipe(startWith(this.ngControl.status), distinctUntilChanged(), delay(0), takeUntil(this.destroy$)) .subscribe(() => { this.disabled = !!this.ngControl?.disabled; }); this.ngControl?.statusChanges ?.pipe(distinctUntilChanged(), delay(0), takeUntil(this.destroy$)) .subscribe((status) => { if (status === 'VALID') { this.onValidate?.('valid'); } else if (status === 'INVALID') { this.onValidate?.('invalid'); } else { this.onValidate?.(); } }); this.notifyChange$ .pipe(filter((change) => change === 'disabled' || change === 'readonly'), startWith({ disabled: this.disabled, readonly: this.readonly }), map(() => ({ disabled: this.disabled, readonly: this.readonly })), distinctUntilChanged((prev, current) => JSON.stringify(prev) === JSON.stringify(current)), delay(0), takeUntil(this.destroy$)) .subscribe(({ disabled, readonly }) => { this.onDisable?.(disabled); this.onReadonly?.(readonly); this.setInputWrapperCursorState(this.inputWrapperElement, { disabled, readonly }); }); } ngOnDestroy() { this.close(); this.destroy$.next(true); this.destroy$.complete(); this.cleanup?.(); } registerOnDisable(fn) { this.onDisable = fn; } registerOnValidate(fn) { this.onValidate = fn; } registerOnReadonly(fn) { this.onReadonly = fn; } writeValue(value) { this.value = value; } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(isDisabled) { this.onDisable?.(isDisabled); } /** * Open the date picker dropdown. */ open() { if (this.isOpen || this.disabled || this.readonly) return; this.isOpen = true; this.portalElement = this.createPortalElement(); this.datePickerBaseRef = this.createDatePickerComponent(); this.renderer.appendChild(this.portalElement, this.datePickerBaseRef.location.nativeElement); this.renderer.appendChild(this.document.body, this.portalElement); this.doAutoUpdateDropdownPosition(); } /** * Close the date picker dropdown. */ close() { if (!this.isOpen) return; this.isOpen = false; if (this.portalElement) this.renderer.removeChild(this.document.body, this.portalElement); this.datePickerBaseRef?.destroy(); } /** * Toggle the date picker dropdown. */ toggle() { this.isOpen ? this.close() : this.open(); } createPortalElement() { const el = this.renderer.createElement('div'); this.renderer.addClass(el, 'd-date-picker-portal'); return el; } createComponentRef(props) { const ref = createComponent(DokuDatePickerBase, { environmentInjector: this.envInjector, elementInjector: props.elementInjector, }); ref.setInput('value', this.value); ref.setInput('minDate', this.minDate); ref.setInput('maxDate', this.maxDate); return ref; } createDatePickerComponent() { const elementInjector = Injector.create({ providers: [], parent: this.injector }); const ref = this.createComponentRef({ elementInjector }); this.appRef.attachView(ref.hostView); const valueChangeListener = ref.instance.valueChange.subscribe((value) => { this.value = value?.start; if (this.closeOnDateClick) this.close(); }); ref.onDestroy(() => { valueChangeListener.unsubscribe(); }); ref.changeDetectorRef.detectChanges(); return ref; } onClickHandler() { fromEvent(this.document, 'click') .pipe(takeUntil(this.destroy$)) .subscribe((event) => { const { clickOutside, clickTrigger } = getClickType(event, [this.inputWrapperElement], [this.portalElement]); if (clickTrigger) return this.toggle(); // Prevent dropdown from being closed when choosing month or year. const nodeName = event.target.nodeName.toLowerCase(); if (nodeName === 'doku-select-option') return; if (clickOutside) return this.close(); }); } doAutoUpdateDropdownPosition() { this.ngZone.runOutsideAngular(() => { if (!this.inputWrapperElement || !this.portalElement) return; this.cleanup = updateFloatingPosition({ triggerElement: this.inputWrapperElement, floatingElement: this.portalElement, placement: 'bottom-start', autoUpdate: true, middleware: { flip: true, shift: true, }, }); }); } setInputWrapperCursorState(inputWrapperElement, props) { if (!inputWrapperElement) return; let cursor = 'pointer'; if (props?.readonly) cursor = 'text'; if (props?.disabled) cursor = 'not-allowed'; inputWrapperElement.style.cursor = cursor; } } DokuDatePicker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DokuDatePicker, deps: [{ token: i0.Renderer2 }, { token: i0.EnvironmentInjector }, { token: i0.Injector }, { token: i0.ApplicationRef }, { token: i0.NgZone }, { token: i1.DatePipe }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }, { token: LOCALE_ID }, { token: i2.NgControl, optional: true, self: true }, { token: i3.DokuFormField, host: true, optional: true }], target: i0.ɵɵFactoryTarget.Component }); DokuDatePicker.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: DokuDatePicker, isStandalone: true, selector: "doku-date-picker", inputs: { closeOnDateClick: "closeOnDateClick", dateFormat: "dateFormat", placeholder: "placeholder" }, host: { properties: { "class": "this.class" } }, providers: [DatePipe, { provide: DOKU_FORM_FIELD_ACCESSOR, useExisting: DokuDatePicker }], exportAs: ["dokuDatePicker"], usesInheritance: true, ngImport: i0, template: "<span *ngIf=\"!formattedValue\" class=\"d-date-picker-placeholder\">\n {{ placeholder }}\n</span>\n\n<span *ngIf=\"formattedValue\" class=\"d-date-picker-value\">\n {{ formattedValue }}\n</span>\n\n<span class=\"icon-calendar\">\n <ng-container *ngTemplateOutlet=\"iconCalendar\"></ng-container>\n</span>\n\n<ng-template #iconCalendar>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M19 5H5C4.44772 5 4 5.44772 4 6V17C4 17.5523 4.44772 18 5 18H19C19.5523 18 20 17.5523 20 17V6C20 5.44772 19.5523 5 19 5Z\"\n stroke=\"currentColor\"\n />\n <path d=\"M4 7.94336H20\" stroke=\"currentColor\" />\n <ellipse cx=\"7.69213\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"7.69213\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"10.6462\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"10.6462\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"13.5998\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"13.5998\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"16.554\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"16.554\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n </svg>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DokuDatePicker, decorators: [{ type: Component, args: [{ selector: 'doku-date-picker', exportAs: 'dokuDatePicker', standalone: true, imports: [CommonModule, DokuDatePickerBase], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [DatePipe, { provide: DOKU_FORM_FIELD_ACCESSOR, useExisting: DokuDatePicker }], template: "<span *ngIf=\"!formattedValue\" class=\"d-date-picker-placeholder\">\n {{ placeholder }}\n</span>\n\n<span *ngIf=\"formattedValue\" class=\"d-date-picker-value\">\n {{ formattedValue }}\n</span>\n\n<span class=\"icon-calendar\">\n <ng-container *ngTemplateOutlet=\"iconCalendar\"></ng-container>\n</span>\n\n<ng-template #iconCalendar>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M19 5H5C4.44772 5 4 5.44772 4 6V17C4 17.5523 4.44772 18 5 18H19C19.5523 18 20 17.5523 20 17V6C20 5.44772 19.5523 5 19 5Z\"\n stroke=\"currentColor\"\n />\n <path d=\"M4 7.94336H20\" stroke=\"currentColor\" />\n <ellipse cx=\"7.69213\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"7.69213\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"10.6462\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"10.6462\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"13.5998\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"13.5998\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"16.554\" cy=\"11.3774\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n <ellipse cx=\"16.554\" cy=\"14.3207\" rx=\"0.984615\" ry=\"0.981132\" fill=\"currentColor\" />\n </svg>\n</ng-template>\n" }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.EnvironmentInjector }, { type: i0.Injector }, { type: i0.ApplicationRef }, { type: i0.NgZone }, { type: i1.DatePipe }, { type: i0.ChangeDetectorRef }, { type: Document, decorators: [{ type: Inject, args: [DOCUMENT] }] }, { type: undefined, decorators: [{ type: Inject, args: [LOCALE_ID] }] }, { type: i2.NgControl, decorators: [{ type: Optional }, { type: Self }] }, { type: i3.DokuFormField, decorators: [{ type: Optional }, { type: Host }] }]; }, propDecorators: { class: [{ type: HostBinding, args: ['class'] }], closeOnDateClick: [{ type: Input }], dateFormat: [{ type: Input }], placeholder: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9rdS1mcmFnbWVudC9zcmMvbGliL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLWZsb2F0L2RhdGUtcGlja2VyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rva3UtZnJhZ21lbnQvc3JjL2xpYi9kYXRlLXBpY2tlci9kYXRlLXBpY2tlci1mbG9hdC9kYXRlLXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQVcsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RSxPQUFPLEVBR0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFHVCxJQUFJLEVBQ0osV0FBVyxFQUNYLE1BQU0sRUFDTixRQUFRLEVBQ1IsS0FBSyxFQUNMLFNBQVMsRUFJVCxRQUFRLEVBRVIsSUFBSSxFQUNKLGlCQUFpQixFQUNqQixlQUFlLEdBQ2hCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFDTCxPQUFPLEVBQ1AsS0FBSyxFQUNMLG9CQUFvQixFQUNwQixNQUFNLEVBQ04sU0FBUyxFQUNULEdBQUcsRUFDSCxJQUFJLEVBQ0osU0FBUyxFQUNULFNBQVMsR0FDVixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNqRixPQUFPLEVBQ0wsd0JBQXdCLEdBSXpCLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDeEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNkNBQTZDLENBQUM7Ozs7O0FBWXZGLE1BQU0s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QUFDLFFBQVEsRUFBRSxFQUFFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLENBQUMsK0VDdkQzRixxL0NBNkJBLDJDRHNCWSxZQUFZOzJGQU1YLGNBQWM7a0JBVjFCLFNBQVM7K0JBQ0Usa0JBQWtCLFlBQ2xCLGdCQUFnQixjQUNkLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxrQkFBa0IsQ0FBQyxpQkFFNUIsaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTSxhQUNwQyxDQUFDLFFBQVEsRUFBRSxFQUFFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxXQUFXLGdCQUFnQixFQUFFLENBQUM7OzBCQThDdEYsTUFBTTsyQkFBQyxRQUFROzswQkFDZixNQUFNOzJCQUFDLFNBQVM7OzBCQUNoQixRQUFROzswQkFBSSxJQUFJOzswQkFDaEIsUUFBUTs7MEJBQUksSUFBSTs0Q0ExQ0EsS0FBSztzQkFEdkIsV0FBVzt1QkFBQyxPQUFPO2dCQVFYLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFPRyxVQUFVO3NCQUFsQixLQUFLO2dCQU9HLFdBQVc7c0JBQW5CLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tb25Nb2R1bGUsIERPQ1VNRU5ULCBEYXRlUGlwZSwgTmdDbGFzcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBBcHBsaWNhdGlvblJlZixcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbXBvbmVudFJlZixcbiAgRW52aXJvbm1lbnRJbmplY3RvcixcbiAgSG9zdCxcbiAgSG9zdEJpbmRpbmcsXG4gIEluamVjdCxcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBMT0NBTEVfSUQsXG4gIE5nWm9uZSxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBSZW5kZXJlcjIsXG4gIFNlbGYsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBjcmVhdGVDb21wb25lbnQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5nQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIFN1YmplY3QsXG4gIGRlbGF5LFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZmlsdGVyLFxuICBmcm9tRXZlbnQsXG4gIG1hcCxcbiAgc2tpcCxcbiAgc3RhcnRXaXRoLFxuICB0YWtlVW50aWwsXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZ2V0Q2xpY2tUeXBlIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvZ2V0LWNsaWNrLXR5cGUnO1xuaW1wb3J0IHsgdXBkYXRlRmxvYXRpbmdQb3NpdGlvbiB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3VwZGF0ZS1mbG9hdGluZy1wb3NpdGlvbic7XG5pbXBvcnQge1xuICBET0tVX0ZPUk1fRklFTERfQUNDRVNTT1IsXG4gIERva3VGb3JtRmllbGQsXG4gIERva3VGb3JtRmllbGRBY2Nlc3NvcixcbiAgRG9rdUZvcm1GaWVsZEFjY2Vzc29yVmFsaWRhdGVWYWx1ZSxcbn0gZnJvbSAnLi4vLi4vZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBEb2t1RGF0ZVBpY2tlckJhc2UgfSBmcm9tICcuLi9iYXNlL2RhdGUtcGlja2VyLWJhc2UuY29tcG9uZW50JztcbmltcG9ydCB7IERva3VEYXRlUGlja2VyQmFzaWNQcm9wcyB9IGZyb20gJy4uL2NvbW1vbi9kYXRlLXBpY2tlci1iYXNpYy1wcm9wcy5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkb2t1LWRhdGUtcGlja2VyJyxcbiAgZXhwb3J0QXM6ICdkb2t1RGF0ZVBpY2tlcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIERva3VEYXRlUGlja2VyQmFzZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtEYXRlUGlwZSwgeyBwcm92aWRlOiBET0tVX0ZPUk1fRklFTERfQUNDRVNTT1IsIHVzZUV4aXN0aW5nOiBEb2t1RGF0ZVBpY2tlciB9XSxcbn0pXG5leHBvcnQgY2xhc3MgRG9rdURhdGVQaWNrZXJcbiAgZXh0ZW5kcyBEb2t1RGF0ZVBpY2tlckJhc2ljUHJvcHNcbiAgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIERva3VGb3JtRmllbGRBY2Nlc3NvciwgQWZ0ZXJWaWV3SW5pdFxue1xuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNsYXNzOiBOZ0NsYXNzWyduZ0NsYXNzJ10gPSAnZC1kYXRlLXBpY2tlcic7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gY2xvc2UgZGF0ZSBwaWNrZXIgZHJvcGRvd24gYWZ0ZXIgc2VsZWN0aW5nIHRoZSBkYXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBASW5wdXQoKSBjbG9zZU9uRGF0ZUNsaWNrID0gdHJ1ZTtcblxuICAvKipcbiAgICogRGF0ZSBmb3JtYXQgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIGZvcm1hdHRpbmcgZGlzcGxheWVkIHZhbHVlIGluIHRoZSBpbnB1dCBmaWVsZC4gSXQgZm9sbG93cyBBbmd1bGFyIERhdGVQaXBlJ3MgZm9ybWF0IG9wdGlvbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0ICdkZC9NTS95eXl5J1xuICAgKi9cbiAgQElucHV0KCkgZGF0ZUZvcm1hdCA9ICdkZC9NTS95eXl5JztcblxuICAvKipcbiAgICogUGxhY2Vob2xkZXIgb2YgdGhlIGRhdGUgcGlja2VyIGlucHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAnZGQvbW0veXl5eSdcbiAgICovXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyID0gJ2RkL21tL3l5eXknO1xuXG4gIHByaXZhdGUgaXNPcGVuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBwb3J0YWxFbGVtZW50PzogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgZGF0ZVBpY2tlckJhc2VSZWY/OiBDb21wb25lbnRSZWY8RG9rdURhdGVQaWNrZXJCYXNlPjtcblxuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSBjbGVhbnVwPzogKCkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHJvdGVjdGVkIGVudkluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yLFxuICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCBhcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgcHJpdmF0ZSBkYXRlUGlwZTogRGF0ZVBpcGUsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50LFxuICAgIEBJbmplY3QoTE9DQUxFX0lEKSBwcml2YXRlIGxvY2FsZUlkOiBzdHJpbmcsXG4gICAgQE9wdGlvbmFsKCkgQFNlbGYoKSBwcml2YXRlIG5nQ29udHJvbD86IE5nQ29udHJvbCxcbiAgICBAT3B0aW9uYWwoKSBASG9zdCgpIHByaXZhdGUgZm9ybUZpZWxkPzogRG9rdUZvcm1GaWVsZFxuICApIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKHRoaXMubmdDb250cm9sKSB7XG4gICAgICB0aGlzLm5nQ29udHJvbC52YWx1ZUFjY2Vzc29yID0gdGhpcztcbiAgICB9XG5cbiAgICB0aGlzLm9uQ2xpY2tIYW5kbGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IGZvcm1hdHRlZFZhbHVlKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnZhbHVlXG4gICAgICA/IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKHRoaXMudmFsdWUsIHRoaXMuZGF0ZUZvcm1hdCwgdW5kZWZpbmVkLCB0aGlzLmxvY2FsZUlkKVxuICAgICAgOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgaW5wdXRXcmFwcGVyRWxlbWVudCgpOiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZm9ybUZpZWxkPy5bJ2lucHV0V3JhcHBlckVsZW1lbnQnXTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubm90aWZ5Q2hhbmdlJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoY2hhbmdlKSA9PiBjaGFuZ2UgPT09ICd2YWx1ZScgfHwgY2hhbmdlID09PSAnbWluRGF0ZScgfHwgY2hhbmdlID09PSAnbWF4RGF0ZScpLFxuICAgICAgICBzdGFydFdpdGgodGhpcy52YWx1ZT8udG9JU09TdHJpbmcoKSB8fCBudWxsKSxcbiAgICAgICAgbWFwKCgpID0+IHRoaXMudmFsdWU/LnRvSVNPU3RyaW5nKCkgfHwgbnVsbCksXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXG4gICAgICAgIHNraXAoMSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHZhbHVlKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy52YWx1ZUNoYW5nZS5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgdGhpcy5vbkNoYW5nZT8uKHZhbHVlKTtcbiAgICAgIHRoaXMub25Ub3VjaGVkPy4oKTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLm5nQ29udHJvbD8uc3RhdHVzQ2hhbmdlc1xuICAgICAgPy5waXBlKFxuICAgICAgICBzdGFydFdpdGgodGhpcy5uZ0NvbnRyb2wuc3RhdHVzKSxcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcbiAgICAgICAgZGVsYXkoMCksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSAhIXRoaXMubmdDb250cm9sPy5kaXNhYmxlZDtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5uZ0NvbnRyb2w/LnN0YXR1c0NoYW5nZXNcbiAgICAgID8ucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCBkZWxheSgwKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSgoc3RhdHVzKSA9PiB7XG4gICAgICAgIGlmIChzdGF0dXMgPT09ICdWQUxJRCcpIHtcbiAgICAgICAgICB0aGlzLm9uVmFsaWRhdGU/LigndmFsaWQnKTtcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0dXMgPT09ICdJTlZBTElEJykge1xuICAgICAgICAgIHRoaXMub25WYWxpZGF0ZT8uKCdpbnZhbGlkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5vblZhbGlkYXRlPy4oKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICB0aGlzLm5vdGlmeUNoYW5nZSRcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoKGNoYW5nZSkgPT4gY2hhbmdlID09PSAnZGlzYWJsZWQnIHx8IGNoYW5nZSA9PT0gJ3JlYWRvbmx5JyksXG4gICAgICAgIHN0YXJ0V2l0aCh7IGRpc2FibGVkOiB0aGlzLmRpc2FibGVkLCByZWFkb25seTogdGhpcy5yZWFkb25seSB9KSxcbiAgICAgICAgbWFwKCgpID0+ICh7IGRpc2FibGVkOiB0aGlzLmRpc2FibGVkLCByZWFkb25seTogdGhpcy5yZWFkb25seSB9KSksXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKChwcmV2LCBjdXJyZW50KSA9PiBKU09OLnN0cmluZ2lmeShwcmV2KSA9PT0gSlNPTi5zdHJpbmdpZnkoY3VycmVudCkpLFxuICAgICAgICBkZWxheSgwKSxcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCh7IGRpc2FibGVkLCByZWFkb25seSB9KSA9PiB7XG4gICAgICAgIHRoaXMub25EaXNhYmxlPy4oZGlzYWJsZWQpO1xuICAgICAgICB0aGlzLm9uUmVhZG9ubHk/LihyZWFkb25seSk7XG4gICAgICAgIHRoaXMuc2V0SW5wdXRXcmFwcGVyQ3Vyc29yU3RhdGUodGhpcy5pbnB1dFdyYXBwZXJFbGVtZW50LCB7IGRpc2FibGVkLCByZWFkb25seSB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5jbG9zZSgpO1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5jbGVhbnVwPy4oKTtcbiAgfVxuXG4gIG9uRGlzYWJsZT86ICgodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICBvblJlYWRvbmx5PzogKCh2YWx1ZTogYm9vbGVhbikgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gIG9uVmFsaWRhdGU/OiAoKHZhbHVlPzogRG9rdUZvcm1GaWVsZEFjY2Vzc29yVmFsaWRhdGVWYWx1ZSB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG4gIHJlZ2lzdGVyT25EaXNhYmxlKGZuOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uRGlzYWJsZSA9IGZuO1xuICB9XG4gIHJlZ2lzdGVyT25WYWxpZGF0ZT8oZm46ICh2YWx1ZT86IERva3VGb3JtRmllbGRBY2Nlc3NvclZhbGlkYXRlVmFsdWUgfCB1bmRlZmluZWQpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVmFsaWRhdGUgPSBmbjtcbiAgfVxuICByZWdpc3Rlck9uUmVhZG9ubHkoZm46ICh2YWx1ZTogYm9vbGVhbikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25SZWFkb25seSA9IGZuO1xuICB9XG5cbiAgb25DaGFuZ2U/OiAodmFsdWU6IHVua25vd24pID0+IHZvaWQ7XG4gIG9uVG91Y2hlZD86ICgpID0+IHZvaWQ7XG4gIHdyaXRlVmFsdWUodmFsdWU/OiBEYXRlIHwgc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgfVxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IHVua25vd24pID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIH1cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG4gIHNldERpc2FibGVkU3RhdGU/KGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLm9uRGlzYWJsZT8uKGlzRGlzYWJsZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIE9wZW4gdGhlIGRhdGUgcGlja2VyIGRyb3Bkb3duLlxuICAgKi9cbiAgb3BlbigpIHtcbiAgICBpZiAodGhpcy5pc09wZW4gfHwgdGhpcy5kaXNhYmxlZCB8fCB0aGlzLnJlYWRvbmx5KSByZXR1cm47XG4gICAgdGhpcy5pc09wZW4gPSB0cnVlO1xuXG4gICAgdGhpcy5wb3J0YWxFbGVtZW50ID0gdGhpcy5jcmVhdGVQb3J0YWxFbGVtZW50KCk7XG4gICAgdGhpcy5kYXRlUGlja2VyQmFzZVJlZiA9IHRoaXMuY3JlYXRlRGF0ZVBpY2tlckNvbXBvbmVudCgpO1xuXG4gICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLnBvcnRhbEVsZW1lbnQsIHRoaXMuZGF0ZVBpY2tlckJhc2VSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG4gICAgdGhpcy5yZW5kZXJlci5hcHBlbmRDaGlsZCh0aGlzLmRvY3VtZW50LmJvZHksIHRoaXMucG9ydGFsRWxlbWVudCk7XG5cbiAgICB0aGlzLmRvQXV0b1VwZGF0ZURyb3Bkb3duUG9zaXRpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSB0aGUgZGF0ZSBwaWNrZXIgZHJvcGRvd24uXG4gICAqL1xuICBjbG9zZSgpIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKSByZXR1cm47XG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcblxuICAgIGlmICh0aGlzLnBvcnRhbEVsZW1lbnQpIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2hpbGQodGhpcy5kb2N1bWVudC5ib2R5LCB0aGlzLnBvcnRhbEVsZW1lbnQpO1xuICAgIHRoaXMuZGF0ZVBpY2tlckJhc2VSZWY/LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUb2dnbGUgdGhlIGRhdGUgcGlja2VyIGRyb3Bkb3duLlxuICAgKi9cbiAgdG9nZ2xlKCkge1xuICAgIHRoaXMuaXNPcGVuID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVBvcnRhbEVsZW1lbnQoKSB7XG4gICAgY29uc3QgZWwgPSB0aGlzLnJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ2RpdicpIGFzIEhUTUxEaXZFbGVtZW50O1xuICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3MoZWwsICdkLWRhdGUtcGlja2VyLXBvcnRhbCcpO1xuICAgIHJldHVybiBlbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVDb21wb25lbnRSZWYocHJvcHM6IHsgZWxlbWVudEluamVjdG9yOiBJbmplY3RvciB9KSB7XG4gICAgY29uc3QgcmVmID0gY3JlYXRlQ29tcG9uZW50KERva3VEYXRlUGlja2VyQmFzZSwge1xuICAgICAgZW52aXJvbm1lbnRJbmplY3RvcjogdGhpcy5lbnZJbmplY3RvcixcbiAgICAgIGVsZW1lbnRJbmplY3RvcjogcHJvcHMuZWxlbWVudEluamVjdG9yLFxuICAgIH0pO1xuICAgIHJlZi5zZXRJbnB1dCgndmFsdWUnLCB0aGlzLnZhbHVlKTtcbiAgICByZWYuc2V0SW5wdXQoJ21pbkRhdGUnLCB0aGlzLm1pbkRhdGUpO1xuICAgIHJlZi5zZXRJbnB1dCgnbWF4RGF0ZScsIHRoaXMubWF4RGF0ZSk7XG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGF0ZVBpY2tlckNvbXBvbmVudCgpIHtcbiAgICBjb25zdCBlbGVtZW50SW5qZWN0b3IgPSBJbmplY3Rvci5jcmVhdGUoeyBwcm92aWRlcnM6IFtdLCBwYXJlbnQ6IHRoaXMuaW5qZWN0b3IgfSk7XG5cbiAgICBjb25zdCByZWYgPSB0aGlzLmNyZWF0ZUNvbXBvbmVudFJlZih7IGVsZW1lbnRJbmplY3RvciB9KTtcblxuICAgIHRoaXMuYXBwUmVmLmF0dGFjaFZpZXcocmVmLmhvc3RWaWV3KTtcblxuICAgIGNvbnN0IHZhbHVlQ2hhbmdlTGlzdGVuZXIgPSByZWYuaW5zdGFuY2UudmFsdWVDaGFuZ2Uuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlPy5zdGFydDtcbiAgICAgIGlmICh0aGlzLmNsb3NlT25EYXRlQ2xpY2spIHRoaXMuY2xvc2UoKTtcbiAgICB9KTtcblxuICAgIHJlZi5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgdmFsdWVDaGFuZ2VMaXN0ZW5lci51bnN1YnNjcmliZSgpO1xuICAgIH0pO1xuXG4gICAgcmVmLmNoYW5nZURldGVjdG9yUmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkNsaWNrSGFuZGxlcigpIHtcbiAgICBmcm9tRXZlbnQodGhpcy5kb2N1bWVudCwgJ2NsaWNrJylcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY2xpY2tPdXRzaWRlLCBjbGlja1RyaWdnZXIgfSA9IGdldENsaWNrVHlwZShcbiAgICAgICAgICBldmVudCxcbiAgICAgICAgICBbdGhpcy5pbnB1dFdyYXBwZXJFbGVtZW50XSxcbiAgICAgICAgICBbdGhpcy5wb3J0YWxFbGVtZW50XVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChjbGlja1RyaWdnZXIpIHJldHVybiB0aGlzLnRvZ2dsZSgpO1xuXG4gICAgICAgIC8vIFByZXZlbnQgZHJvcGRvd24gZnJvbSBiZWluZyBjbG9zZWQgd2hlbiBjaG9vc2luZyBtb250aCBvciB5ZWFyLlxuICAgICAgICBjb25zdCBub2RlTmFtZSA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChub2RlTmFtZSA9PT0gJ2Rva3Utc2VsZWN0LW9wdGlvbicpIHJldHVybjtcblxuICAgICAgICBpZiAoY2xpY2tPdXRzaWRlKSByZXR1cm4gdGhpcy5jbG9zZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRvQXV0b1VwZGF0ZURyb3Bkb3duUG9zaXRpb24oKSB7XG4gICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLmlucHV0V3JhcHBlckVsZW1lbnQgfHwgIXRoaXMucG9ydGFsRWxlbWVudCkgcmV0dXJuO1xuICAgICAgdGhpcy5jbGVhbnVwID0gdXBkYXRlRmxvYXRpbmdQb3NpdGlvbih7XG4gICAgICAgIHRyaWdnZXJFbGVtZW50OiB0aGlzLmlucHV0V3JhcHBlckVsZW1lbnQsXG4gICAgICAgIGZsb2F0aW5nRWxlbWVudDogdGhpcy5wb3J0YWxFbGVtZW50LFxuICAgICAgICBwbGFjZW1lbnQ6ICdib3R0b20tc3RhcnQnLFxuICAgICAgICBhdXRvVXBkYXRlOiB0cnVlLFxuICAgICAgICBtaWRkbGV3YXJlOiB7XG4gICAgICAgICAgZmxpcDogdHJ1ZSxcbiAgICAgICAgICBzaGlmdDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRJbnB1dFdyYXBwZXJDdXJzb3JTdGF0ZShcbiAgICBpbnB1dFdyYXBwZXJFbGVtZW50PzogSFRNTEVsZW1lbnQsXG4gICAgcHJvcHM/OiB7IGRpc2FibGVkPzogYm9vbGVhbjsgcmVhZG9ubHk/OiBib29sZWFuIH1cbiAgKTogdm9pZCB7XG4gICAgaWYgKCFpbnB1dFdyYXBwZXJFbGVtZW50KSByZXR1cm47XG5cbiAgICBsZXQgY3Vyc29yID0gJ3BvaW50ZXInO1xuICAgIGlmIChwcm9wcz8ucmVhZG9ubHkpIGN1cnNvciA9ICd0ZXh0JztcbiAgICBpZiAocHJvcHM/LmRpc2FibGVkKSBjdXJzb3IgPSAnbm90LWFsbG93ZWQnO1xuICAgIGlucHV0V3JhcHBlckVsZW1lbnQuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xuICB9XG59XG4iLCI8c3BhbiAqbmdJZj1cIiFmb3JtYXR0ZWRWYWx1ZVwiIGNsYXNzPVwiZC1kYXRlLXBpY2tlci1wbGFjZWhvbGRlclwiPlxuICB7eyBwbGFjZWhvbGRlciB9fVxuPC9zcGFuPlxuXG48c3BhbiAqbmdJZj1cImZvcm1hdHRlZFZhbHVlXCIgY2xhc3M9XCJkLWRhdGUtcGlja2VyLXZhbHVlXCI+XG4gIHt7IGZvcm1hdHRlZFZhbHVlIH19XG48L3NwYW4+XG5cbjxzcGFuIGNsYXNzPVwiaWNvbi1jYWxlbmRhclwiPlxuICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaWNvbkNhbGVuZGFyXCI+PC9uZy1jb250YWluZXI+XG48L3NwYW4+XG5cbjxuZy10ZW1wbGF0ZSAjaWNvbkNhbGVuZGFyPlxuICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjI0XCIgaGVpZ2h0PVwiMjRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIj5cbiAgICA8cGF0aFxuICAgICAgZD1cIk0xOSA1SDVDNC40NDc3MiA1IDQgNS40NDc3MiA0IDZWMTdDNCAxNy41NTIzIDQuNDQ3NzIgMTggNSAxOEgxOUMxOS41NTIzIDE4IDIwIDE3LjU1MjMgMjAgMTdWNkMyMCA1LjQ0NzcyIDE5LjU1MjMgNSAxOSA1WlwiXG4gICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIlxuICAgIC8+XG4gICAgPHBhdGggZD1cIk00IDcuOTQzMzZIMjBcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiAvPlxuICAgIDxlbGxpcHNlIGN4PVwiNy42OTIxM1wiIGN5PVwiMTEuMzc3NFwiIHJ4PVwiMC45ODQ2MTVcIiByeT1cIjAuOTgxMTMyXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIC8+XG4gICAgPGVsbGlwc2UgY3g9XCI3LjY5MjEzXCIgY3k9XCIxNC4zMjA3XCIgcng9XCIwLjk4NDYxNVwiIHJ5PVwiMC45ODExMzJcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgLz5cbiAgICA8ZWxsaXBzZSBjeD1cIjEwLjY0NjJcIiBjeT1cIjExLjM3NzRcIiByeD1cIjAuOTg0NjE1XCIgcnk9XCIwLjk4MTEzMlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiAvPlxuICAgIDxlbGxpcHNlIGN4PVwiMTAuNjQ2MlwiIGN5PVwiMTQuMzIwN1wiIHJ4PVwiMC45ODQ2MTVcIiByeT1cIjAuOTgxMTMyXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIC8+XG4gICAgPGVsbGlwc2UgY3g9XCIxMy41OTk4XCIgY3k9XCIxMS4zNzc0XCIgcng9XCIwLjk4NDYxNVwiIHJ5PVwiMC45ODExMzJcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgLz5cbiAgICA8ZWxsaXBzZSBjeD1cIjEzLjU5OThcIiBjeT1cIjE0LjMyMDdcIiByeD1cIjAuOTg0NjE1XCIgcnk9XCIwLjk4MTEzMlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiAvPlxuICAgIDxlbGxpcHNlIGN4PVwiMTYuNTU0XCIgY3k9XCIxMS4zNzc0XCIgcng9XCIwLjk4NDYxNVwiIHJ5PVwiMC45ODExMzJcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgLz5cbiAgICA8ZWxsaXBzZSBjeD1cIjE2LjU1NFwiIGN5PVwiMTQuMzIwN1wiIHJ4PVwiMC45ODQ2MTVcIiByeT1cIjAuOTgxMTMyXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIC8+XG4gIDwvc3ZnPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==