ngx-ui-hero
Version:
Simple, fast and reliable utilities for Angular.
232 lines • 42.4 kB
JavaScript
import { Component, EventEmitter, Inject, Input, IterableDiffers, Optional, Output, ViewChild } from '@angular/core';
import { NG_ASYNC_VALIDATORS, NG_VALIDATORS, NG_VALUE_ACCESSOR, NgModel } from '@angular/forms';
import { ElementBase } from '../../base/element-base';
import { INPUT_FORMS_CONFIG } from '../../input-forms-config.constants';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/forms";
import * as i3 from "../../../ui/directives/debounce.directive";
import * as i4 from "../../../ui/directives/click-outside.directive";
import * as i5 from "../../../ui/directives/auto-focus.directive";
import * as i6 from "ngx-bootstrap/tooltip";
import * as i7 from "../../../data-grid/data-grid.component";
import * as i8 from "../../../data-grid/directives/data-grid-templates.directive";
import * as i9 from "../input-validations/input-validations.component";
let identifier = 0;
export class InputDropdownGridComponent extends ElementBase {
constructor(validators, asyncValidators, config, iterableDiffers) {
super(validators, asyncValidators, config);
this.config = config;
this.iterableDiffers = iterableDiffers;
this.clickOutsideEnabled = true;
this.placeholder = 'Select...';
this.searchPlaceholder = 'Search...';
this.itemsPerPage = 5;
this.maxSize = 5;
this.showInfos = true;
this.onChange = new EventEmitter();
this.onSearch = new EventEmitter();
this.identifier = `input-dropdown-grid-${identifier++}`;
if (config.dropDown) {
Object.assign(this, config.dropDown);
}
this._differData = this.iterableDiffers.find([]).create(null);
}
get data() {
return this._data;
}
set data(value) {
this._data = value;
this.Init();
}
ngOnInit() {
this.Init();
}
ngDoCheck() {
let changesInData = this._differData.diff(this._data);
if (changesInData || !this.modelInitialized || this.value != this._lastModelInitialized) {
this.Init();
}
}
Init() {
this.clearSearch();
if (!this.internalData || this.internalData.length == 0) {
return;
}
if (this.value) {
this.setSelectedItemByTheCurrentModelValue();
this._lastModelInitialized = this.value;
}
else {
this.selectedDisplayText = '';
this._lastModelInitialized = undefined;
}
this.modelInitialized = true;
}
ToggleDropDown(event, value) {
if (this.clickOutsideEnabled) {
if ((value == false && !this.showDropdown) || (value == undefined && this.disabled))
return;
if (value == undefined) {
if (this.showDropdown) {
this.setComboTouched();
}
this.showDropdown = !this.showDropdown;
}
else {
if (!value && this.showDropdown) {
this.setComboTouched();
}
this.showDropdown = value;
}
this.clearSearch();
}
else {
this.clickOutsideEnabled = true;
}
}
Select(row) {
if (this.disabled) {
this.ToggleDropDown(null, false);
return;
}
this.value = this.renderPropertyValue(this.valueProperty, row);
this.onChange.emit(this.value);
this.ToggleDropDown(null, false);
}
OnSearch() {
if (this.lazyLoadedData) {
this.onSearch.emit(this.search);
return;
}
if (!this.search || this.search.length < 3) {
this.clearSearchResults();
return;
}
this.filterData();
}
OnPaginate() {
this.clickOutsideEnabled = false;
}
ClearSelection(e) {
this.value = null;
this.selectedDisplayText = null;
this.comboTouched = true;
this.showDropdown = false;
this.onChange.emit(this.value);
if (e)
e.stopPropagation();
}
OnComboPressed(event) {
if (event.keyCode == 13) {
this.ToggleDropDown(null);
event.preventDefault();
}
}
setSelectedItemByTheCurrentModelValue() {
if (!this.value)
return;
let row = this.data.find(x => this.value == this.renderPropertyValue(this.valueProperty, x));
if (row) {
this.selectedDisplayText = this.renderPropertyValue(this.displayTextProperty, row);
}
}
filterData() {
this.internalData = this.data.filter(x => {
for (let i = 0; i < this.columns.length; i++) {
let columnData = '';
let value = '';
if (this.columns[i].data) {
columnData = this.renderPropertyValue(this.columns[i].data, x);
}
if (this.columns[i].render != undefined) {
value = this.columns[i].render(x, columnData, i);
}
else {
value = columnData;
}
if (value && value.toString().toUpperCase().indexOf(this.search.toUpperCase()) >= 0) {
return true;
}
}
return false;
});
}
clearSearch() {
this.search = '';
this.clearSearchResults();
}
clearSearchResults() {
this.internalData = Object.assign([], this.data);
}
setComboTouched() {
this.comboTouched = true;
}
renderPropertyValue(propertyPath, object) {
let parts = propertyPath.split(".");
let property = object || {};
for (let i = 0; i < parts.length; i++) {
if (!property) {
return null;
}
property = property[parts[i]];
}
return property;
}
}
InputDropdownGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDropdownGridComponent, deps: [{ token: NG_VALIDATORS, optional: true }, { token: NG_ASYNC_VALIDATORS, optional: true }, { token: INPUT_FORMS_CONFIG }, { token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Component });
InputDropdownGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: InputDropdownGridComponent, selector: "input-dropdown-grid", inputs: { placeholder: "placeholder", searchPlaceholder: "searchPlaceholder", displayTextProperty: "displayTextProperty", valueProperty: "valueProperty", columns: "columns", lazyLoadedData: "lazyLoadedData", itemsPerPage: "itemsPerPage", maxSize: "maxSize", showInfos: "showInfos", data: "data" }, outputs: { onChange: "onChange", onSearch: "onSearch" }, providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: InputDropdownGridComponent,
multi: true
}], viewQueries: [{ propertyName: "model", first: true, predicate: NgModel, descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div [id]=\"identifier\" class=\"ui-dropdown-grid\">\n <label *ngIf=\"label\">\n {{label}}\n <span class=\"required-symbol\" *ngIf=\"isRequired\"> *</span>\n <i class=\"fa fa-question-circle ml-2\" tooltip=\"{{help}}\" container=\"body\" *ngIf=\"help\"></i>\n </label>\n\n <input type=\"hidden\" [(ngModel)]=\"value\" />\n <div class=\"combobox d-flex align-items-center\" \n [ngClass]=\"{\n 'has-validations': showValidations,\n 'open': showDropdown, \n 'disabled': disabled,\n 'is-valid': !showDropdown && !disabled && comboTouched && (!isRequired || value),\n 'is-invalid': !showDropdown && !disabled && comboTouched && isRequired && !value\n }\"\n (click)=\"ToggleDropDown($event)\" (keyup)=\"OnComboPressed($event)\" tabindex=\"0\">\n\n <span class=\"mr-auto text-truncate\">{{selectedDisplayText || placeholder}}</span>\n <i class=\"fa fa-times btn-clear-selection\" *ngIf=\"value && !disabled\" (click)=\"ClearSelection($event)\"></i>\n <i class=\"fa\" [ngClass]=\"{'fa-caret-down': !showDropdown, 'fa-caret-up': showDropdown}\"></i>\n </div>\n\n <div class=\"dropdown-options shadow fadeInDown\" *ngIf=\"showDropdown\" (clickOutside)=\"ToggleDropDown($event, false)\">\n <div class=\"options-container\">\n <div class=\"toolbar d-flex align-items-center\">\n <input type=\"text\" auto-focus\n class=\"form-control\" \n name=\"{{identifier}}-search\" \n [(ngModel)]=\"search\" \n placeholder=\"{{searchPlaceholder}}\"\n debounce (callback)=\"OnSearch()\" />\n </div>\n\n <div class=\"p-2\">\n <datagrid \n [data]=\"internalData\" \n [columns]=\"columns\" \n [showActionsColumn]=\"true\"\n [initialColumnToSort]=\"0\" \n [itemsPerPage]=\"itemsPerPage\"\n [maxSize]=\"maxSize\"\n [showInfos]=\"showInfos\" \n actionsColumnWidth=\"60px\"\n (OnPaginate)=\"OnPaginate()\">\n <ng-template actions-column let-row=\"row\" let-rowIndex=\"rowIndex\">\n <button class=\"btn btn-outline-primary btn-sm\" (click)=\"Select(row)\"><i class=\"fa fa-external-link\"></i></button>\n </ng-template>\n </datagrid>\n </div>\n </div>\n </div>\n</div>\n\n<input-validations\n *ngIf=\"showValidations && !disabled && comboTouched && (invalid | async)\"\n [messages]=\"failures | async\">\n</input-validations>\n\n<small class=\"text-muted\" *ngIf=\"description\">{{description}}</small>\n", styles: ["@keyframes fadeInDown{0%{opacity:0;transform:translate3d(0,-5%,0)}to{opacity:1;transform:translateZ(0)}}.fadeInDown{animation-name:fadeInDown;animation-duration:.35s;animation-fill-mode:both}.ui-dropdown-grid{position:relative}.ui-dropdown-grid *{-webkit-user-select:none;user-select:none}.ui-dropdown-grid>.combobox{outline:none;background-color:#fff;padding:.375rem .4rem .375rem .75rem;border:1px solid #ced4da;border-radius:.25rem}.ui-dropdown-grid>.combobox>span{color:#6c757d;font-size:1rem;line-height:1.5}.ui-dropdown-grid>.combobox>i{color:#495057;font-size:14px;margin-left:10px}.ui-dropdown-grid>.combobox.open{border-radius:.25rem .25rem 0 0}.ui-dropdown-grid>.combobox.disabled{background-color:#e9ecef;border-color:#ced4da}.ui-dropdown-grid>.combobox.has-validations.is-invalid{border-color:#dc3545}.ui-dropdown-grid>.combobox.has-validations.is-invalid.open{box-shadow:0 0 0 .2rem #dc354540}.ui-dropdown-grid>.combobox.has-validations.is-valid{border-color:#28a745}.ui-dropdown-grid>.combobox.has-validations.is-valid.open{box-shadow:0 0 0 .2rem #28a74540}.ui-dropdown-grid>.dropdown-options{background-color:#fff;border:1px solid #ced4da;border-radius:0 0 .25rem .25rem;position:absolute;top:100%;left:0;width:100%;z-index:20;margin-top:-1px;min-width:300px}.ui-dropdown-grid>.dropdown-options>.options-container{display:inherit;position:initial;font-family:inherit;background-color:inherit;box-shadow:none;height:auto;width:auto;color:inherit;font-size:inherit;letter-spacing:inherit;line-height:inherit;padding:inherit;border-radius:inherit}.ui-dropdown-grid>.dropdown-options .toolbar{padding:3px;border-bottom:1px solid #ced4da;background-color:#f8f9fa}.ui-dropdown-grid>.dropdown-options .toolbar input[type=text]{background-color:transparent;border:0;padding:.375rem .55rem;box-shadow:none!important}.ui-dropdown-grid>.dropdown-options .empty-results{font-style:italic;padding:12px;display:block;color:#6b6b6b}.btn-clear-selection{cursor:pointer;padding:8px 10px;margin:-5px 0 -5px -5px!important;border-radius:3px}.btn-clear-selection:hover{background-color:#e7e7e7}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.DebounceDirective, selector: "[debounce]", inputs: ["delay"], outputs: ["callback", "arrowsCallback"] }, { kind: "directive", type: i4.ClickOutsideDirective, selector: "[clickOutside]", inputs: ["clickOutsideEnabled", "attachOutsideOnClick", "delayClickOutsideInit", "emitOnBlur", "exclude", "excludeBeforeClick", "clickOutsideEvents"], outputs: ["clickOutside"] }, { kind: "directive", type: i5.AutoFocusDirective, selector: "[auto-focus]" }, { kind: "directive", type: i6.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["containerClass", "tooltipAnimation", "tooltipFadeDuration", "isOpen", "tooltipHtml", "tooltip", "tooltipPlacement", "placement", "tooltipIsOpen", "tooltipEnable", "isDisabled", "tooltipAppendToBody", "container", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "delay", "tooltipTrigger", "triggers", "adaptivePosition"], outputs: ["tooltipChange", "tooltipStateChanged", "onShown", "onHidden"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i7.DataGridComponent, selector: "datagrid", inputs: ["debugMode", "tableId", "columns", "emptyResultsMessage", "infoMessage", "animated", "striped", "bordered", "hoverEffect", "responsive", "showCheckboxColumn", "showSelectAllCheckbox", "selectAllPages", "checkBoxMode", "showSummaries", "allowExports", "exportButtonLabel", "exportedFileName", "exportedExcelSheetName", "initialColumnToSort", "initialSortDirection", "mode", "totalItems", "itemsPerPage", "maxSize", "boundaryLinks", "directionLinks", "rotate", "showActionsColumn", "showInfos", "actionsColumnCaption", "actionsColumnWidth", "firstText", "previousText", "nextText", "lastText", "autoFitMode", "allowColumnResize", "allowColumnFilters", "allowColumnReorder", "fixedHeader", "minHeight", "maxHeight", "userPreferencesKey", "filterPlaceholder", "filterPlacement", "boundedExportCallback", "data"], outputs: ["OnSelectionChanged", "OnRowSelected", "OnRowRendered", "OnPaginate", "OnSort", "OnColumnFiltered"] }, { kind: "directive", type: i8.ActionsColumnDirective, selector: "[actions-column]" }, { kind: "component", type: i9.InputValidationsComponent, selector: "input-validations", inputs: ["messages"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: InputDropdownGridComponent, decorators: [{
type: Component,
args: [{ selector: 'input-dropdown-grid', providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: InputDropdownGridComponent,
multi: true
}], template: "<div [id]=\"identifier\" class=\"ui-dropdown-grid\">\n <label *ngIf=\"label\">\n {{label}}\n <span class=\"required-symbol\" *ngIf=\"isRequired\"> *</span>\n <i class=\"fa fa-question-circle ml-2\" tooltip=\"{{help}}\" container=\"body\" *ngIf=\"help\"></i>\n </label>\n\n <input type=\"hidden\" [(ngModel)]=\"value\" />\n <div class=\"combobox d-flex align-items-center\" \n [ngClass]=\"{\n 'has-validations': showValidations,\n 'open': showDropdown, \n 'disabled': disabled,\n 'is-valid': !showDropdown && !disabled && comboTouched && (!isRequired || value),\n 'is-invalid': !showDropdown && !disabled && comboTouched && isRequired && !value\n }\"\n (click)=\"ToggleDropDown($event)\" (keyup)=\"OnComboPressed($event)\" tabindex=\"0\">\n\n <span class=\"mr-auto text-truncate\">{{selectedDisplayText || placeholder}}</span>\n <i class=\"fa fa-times btn-clear-selection\" *ngIf=\"value && !disabled\" (click)=\"ClearSelection($event)\"></i>\n <i class=\"fa\" [ngClass]=\"{'fa-caret-down': !showDropdown, 'fa-caret-up': showDropdown}\"></i>\n </div>\n\n <div class=\"dropdown-options shadow fadeInDown\" *ngIf=\"showDropdown\" (clickOutside)=\"ToggleDropDown($event, false)\">\n <div class=\"options-container\">\n <div class=\"toolbar d-flex align-items-center\">\n <input type=\"text\" auto-focus\n class=\"form-control\" \n name=\"{{identifier}}-search\" \n [(ngModel)]=\"search\" \n placeholder=\"{{searchPlaceholder}}\"\n debounce (callback)=\"OnSearch()\" />\n </div>\n\n <div class=\"p-2\">\n <datagrid \n [data]=\"internalData\" \n [columns]=\"columns\" \n [showActionsColumn]=\"true\"\n [initialColumnToSort]=\"0\" \n [itemsPerPage]=\"itemsPerPage\"\n [maxSize]=\"maxSize\"\n [showInfos]=\"showInfos\" \n actionsColumnWidth=\"60px\"\n (OnPaginate)=\"OnPaginate()\">\n <ng-template actions-column let-row=\"row\" let-rowIndex=\"rowIndex\">\n <button class=\"btn btn-outline-primary btn-sm\" (click)=\"Select(row)\"><i class=\"fa fa-external-link\"></i></button>\n </ng-template>\n </datagrid>\n </div>\n </div>\n </div>\n</div>\n\n<input-validations\n *ngIf=\"showValidations && !disabled && comboTouched && (invalid | async)\"\n [messages]=\"failures | async\">\n</input-validations>\n\n<small class=\"text-muted\" *ngIf=\"description\">{{description}}</small>\n", styles: ["@keyframes fadeInDown{0%{opacity:0;transform:translate3d(0,-5%,0)}to{opacity:1;transform:translateZ(0)}}.fadeInDown{animation-name:fadeInDown;animation-duration:.35s;animation-fill-mode:both}.ui-dropdown-grid{position:relative}.ui-dropdown-grid *{-webkit-user-select:none;user-select:none}.ui-dropdown-grid>.combobox{outline:none;background-color:#fff;padding:.375rem .4rem .375rem .75rem;border:1px solid #ced4da;border-radius:.25rem}.ui-dropdown-grid>.combobox>span{color:#6c757d;font-size:1rem;line-height:1.5}.ui-dropdown-grid>.combobox>i{color:#495057;font-size:14px;margin-left:10px}.ui-dropdown-grid>.combobox.open{border-radius:.25rem .25rem 0 0}.ui-dropdown-grid>.combobox.disabled{background-color:#e9ecef;border-color:#ced4da}.ui-dropdown-grid>.combobox.has-validations.is-invalid{border-color:#dc3545}.ui-dropdown-grid>.combobox.has-validations.is-invalid.open{box-shadow:0 0 0 .2rem #dc354540}.ui-dropdown-grid>.combobox.has-validations.is-valid{border-color:#28a745}.ui-dropdown-grid>.combobox.has-validations.is-valid.open{box-shadow:0 0 0 .2rem #28a74540}.ui-dropdown-grid>.dropdown-options{background-color:#fff;border:1px solid #ced4da;border-radius:0 0 .25rem .25rem;position:absolute;top:100%;left:0;width:100%;z-index:20;margin-top:-1px;min-width:300px}.ui-dropdown-grid>.dropdown-options>.options-container{display:inherit;position:initial;font-family:inherit;background-color:inherit;box-shadow:none;height:auto;width:auto;color:inherit;font-size:inherit;letter-spacing:inherit;line-height:inherit;padding:inherit;border-radius:inherit}.ui-dropdown-grid>.dropdown-options .toolbar{padding:3px;border-bottom:1px solid #ced4da;background-color:#f8f9fa}.ui-dropdown-grid>.dropdown-options .toolbar input[type=text]{background-color:transparent;border:0;padding:.375rem .55rem;box-shadow:none!important}.ui-dropdown-grid>.dropdown-options .empty-results{font-style:italic;padding:12px;display:block;color:#6b6b6b}.btn-clear-selection{cursor:pointer;padding:8px 10px;margin:-5px 0 -5px -5px!important;border-radius:3px}.btn-clear-selection:hover{background-color:#e7e7e7}\n"] }]
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [NG_VALIDATORS]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [NG_ASYNC_VALIDATORS]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [INPUT_FORMS_CONFIG]
}] }, { type: i0.IterableDiffers }]; }, propDecorators: { model: [{
type: ViewChild,
args: [NgModel, { static: true }]
}], placeholder: [{
type: Input
}], searchPlaceholder: [{
type: Input
}], displayTextProperty: [{
type: Input
}], valueProperty: [{
type: Input
}], columns: [{
type: Input
}], lazyLoadedData: [{
type: Input
}], itemsPerPage: [{
type: Input
}], maxSize: [{
type: Input
}], showInfos: [{
type: Input
}], onChange: [{
type: Output
}], onSearch: [{
type: Output
}], data: [{
type: Input,
args: ['data']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZHJvcGRvd24tZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtdWktaGVyby9zcmMvbGliL2lucHV0LWZvcm1zL2NvbXBvbmVudHMvaW5wdXQtZHJvcGRvd24tZ3JpZC9pbnB1dC1kcm9wZG93bi1ncmlkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC11aS1oZXJvL3NyYy9saWIvaW5wdXQtZm9ybXMvY29tcG9uZW50cy9pbnB1dC1kcm9wZG93bi1ncmlkL2lucHV0LWRyb3Bkb3duLWdyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0gsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdoRyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHdEQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7Ozs7Ozs7Ozs7O0FBRXhFLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztBQVluQixNQUFNLE9BQU8sMEJBQTJCLFNBQVEsV0FBZ0I7SUFvQzlELFlBQ3FDLFVBQTBCLEVBQ3BCLGVBQW9DLEVBQ3hDLE1BQXdCLEVBQ3JELGVBQWdDO1FBRXhDLEtBQUssQ0FBQyxVQUFVLEVBQUUsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBSE4sV0FBTSxHQUFOLE1BQU0sQ0FBa0I7UUFDckQsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBakMxQyx3QkFBbUIsR0FBWSxJQUFJLENB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QVE7c0JBQXhCLE1BQU07Z0JBTUgsSUFBSTtzQkFEUCxLQUFLO3VCQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5qZWN0LCBJbnB1dCwgSXRlcmFibGVEaWZmZXJzLCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTkdfQVNZTkNfVkFMSURBVE9SUywgTkdfVkFMSURBVE9SUywgTkdfVkFMVUVfQUNDRVNTT1IsIE5nTW9kZWwgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IERhdGFHcmlkQ29sdW1uTW9kZWwgfSBmcm9tICcuLi8uLi8uLi9kYXRhLWdyaWQvbW9kZWxzL2RhdGEtZ3JpZC1jb2x1bW4ubW9kZWwnO1xuaW1wb3J0IHsgRWxlbWVudEJhc2UgfSBmcm9tICcuLi8uLi9iYXNlL2VsZW1lbnQtYmFzZSc7XG5pbXBvcnQgeyBBc3luY1ZhbGlkYXRvckFycmF5LCBWYWxpZGF0b3JBcnJheSB9IGZyb20gJy4uLy4uL2Jhc2UvdmFsaWRhdGUnO1xuaW1wb3J0IHsgSW5wdXRGb3Jtc0NvbmZpZyB9IGZyb20gJy4uLy4uL2lucHV0LWZvcm1zLWNvbmZpZyc7XG5pbXBvcnQgeyBJTlBVVF9GT1JNU19DT05GSUcgfSBmcm9tICcuLi8uLi9pbnB1dC1mb3Jtcy1jb25maWcuY29uc3RhbnRzJztcblxubGV0IGlkZW50aWZpZXIgPSAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdpbnB1dC1kcm9wZG93bi1ncmlkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2lucHV0LWRyb3Bkb3duLWdyaWQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9pbnB1dC1kcm9wZG93bi1ncmlkLmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW3tcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICB1c2VFeGlzdGluZzogSW5wdXREcm9wZG93bkdyaWRDb21wb25lbnQsXG4gICAgbXVsdGk6IHRydWVcbiAgfV1cbn0pXG5leHBvcnQgY2xhc3MgSW5wdXREcm9wZG93bkdyaWRDb21wb25lbnQgZXh0ZW5kcyBFbGVtZW50QmFzZTxhbnk+IGltcGxlbWVudHMgT25Jbml0IHsgXG4gIHByaXZhdGUgX2xhc3RNb2RlbEluaXRpYWxpemVkOiBhbnk7XG4gIHByaXZhdGUgX2RpZmZlckRhdGE6IGFueTtcbiAgcHJpdmF0ZSBfZGF0YTogQXJyYXk8YW55PjtcbiAgc2hvd0Ryb3Bkb3duOiBib29sZWFuO1xuICBjb21ib1RvdWNoZWQ6IGJvb2xlYW47XG4gIG1vZGVsSW5pdGlhbGl6ZWQ6IGJvb2xlYW47XG4gIGNsaWNrT3V0c2lkZUVuYWJsZWQ6IGJvb2xlYW4gPSB0cnVlO1xuICBzZWFyY2g6IHN0cmluZztcbiAgc2VsZWN0ZWREaXNwbGF5VGV4dDogc3RyaW5nO1xuICBpbnRlcm5hbERhdGE6IEFycmF5PGFueT47XG4gIFxuICBAVmlld0NoaWxkKE5nTW9kZWwsIHtzdGF0aWM6IHRydWV9KSBtb2RlbDogTmdNb2RlbDtcbiAgQElucHV0KCkgcHVibGljIHBsYWNlaG9sZGVyID0gJ1NlbGVjdC4uLic7XG4gIEBJbnB1dCgpIHB1YmxpYyBzZWFyY2hQbGFjZWhvbGRlciA9ICdTZWFyY2guLi4nO1xuICBASW5wdXQoKSBwdWJsaWMgZGlzcGxheVRleHRQcm9wZXJ0eTogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgdmFsdWVQcm9wZXJ0eTogc3RyaW5nO1xuICBASW5wdXQoKSBwdWJsaWMgY29sdW1uczogQXJyYXk8RGF0YUdyaWRDb2x1bW5Nb2RlbD47IFxuICBASW5wdXQoKSBwdWJsaWMgbGF6eUxvYWRlZERhdGE6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGl0ZW1zUGVyUGFnZT86IG51bWJlciA9IDU7ICBcbiAgQElucHV0KCkgbWF4U2l6ZT86IG51bWJlciA9IDU7ICBcbiAgQElucHV0KCkgc2hvd0luZm9zPzogYm9vbGVhbiA9IHRydWU7ICBcbiAgQE91dHB1dCgpIHB1YmxpYyBvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgcHVibGljIG9uU2VhcmNoID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XG5cbiAgZ2V0IGRhdGEoKTogQXJyYXk8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gIH0gICAgXG4gIEBJbnB1dCgnZGF0YScpXG4gIHNldCBkYXRhKHZhbHVlOiBBcnJheTxhbnk+KSB7XG4gICAgdGhpcy5fZGF0YSA9IHZhbHVlO1xuICAgIHRoaXMuSW5pdCgpO1xuICB9XG4gIFxuICBwdWJsaWMgaWRlbnRpZmllciA9IGBpbnB1dC1kcm9wZG93bi1ncmlkLSR7aWRlbnRpZmllcisrfWA7ICBcbiBcbiAgY29uc3RydWN0b3IoXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChOR19WQUxJREFUT1JTKSB2YWxpZGF0b3JzOiBWYWxpZGF0b3JBcnJheSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE5HX0FTWU5DX1ZBTElEQVRPUlMpIGFzeW5jVmFsaWRhdG9yczogQXN5bmNWYWxpZGF0b3JBcnJheSxcbiAgICBASW5qZWN0KCBJTlBVVF9GT1JNU19DT05GSUcgKSBwdWJsaWMgY29uZmlnOiBJbnB1dEZvcm1zQ29uZmlnLFxuICAgIHByaXZhdGUgaXRlcmFibGVEaWZmZXJzOiBJdGVyYWJsZURpZmZlcnMsXG4gICkge1xuICAgIHN1cGVyKHZhbGlkYXRvcnMsIGFzeW5jVmFsaWRhdG9ycywgY29uZmlnKTtcblxuICAgIGlmIChjb25maWcuZHJvcERvd24pIHtcbiAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgY29uZmlnLmRyb3BEb3duKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kaWZmZXJEYXRhID0gdGhpcy5pdGVyYWJsZURpZmZlcnMuZmluZChbXSkuY3JlYXRlKG51bGwpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5Jbml0KCk7XG4gIH1cbiAgbmdEb0NoZWNrKCk6IHZvaWQge1xuICAgIGxldCBjaGFuZ2VzSW5EYXRhID0gdGhpcy5fZGlmZmVyRGF0YS5kaWZmKHRoaXMuX2RhdGEpO1xuXG4gICAgaWYgKGNoYW5nZXNJbkRhdGEgfHwgIXRoaXMubW9kZWxJbml0aWFsaXplZCB8fCB0aGlzLnZhbHVlICE9IHRoaXMuX2xhc3RNb2RlbEluaXRpYWxpemVkKSB7XG4gICAgICB0aGlzLkluaXQoKTtcbiAgICB9XG4gIH1cblxuICBJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJTZWFyY2goKTtcblxuICAgIGlmICghdGhpcy5pbnRlcm5hbERhdGEgfHwgdGhpcy5pbnRlcm5hbERhdGEubGVuZ3RoID09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy52YWx1ZSkge1xuICAgICAgdGhpcy5zZXRTZWxlY3RlZEl0ZW1CeVRoZUN1cnJlbnRNb2RlbFZhbHVlKCk7XG4gICAgICB0aGlzLl9sYXN0TW9kZWxJbml0aWFsaXplZCA9IHRoaXMudmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWREaXNwbGF5VGV4dCA9ICcnO1xuICAgICAgdGhpcy5fbGFzdE1vZGVsSW5pdGlhbGl6ZWQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIFxuICAgIHRoaXMubW9kZWxJbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICBUb2dnbGVEcm9wRG93bihldmVudDogTW91c2VFdmVudCwgdmFsdWU/OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2xpY2tPdXRzaWRlRW5hYmxlZCkge1xuICAgICAgaWYgKCh2YWx1ZSA9PSBmYWxzZSAmJiAhdGhpcy5zaG93RHJvcGRvd24pIHx8ICh2YWx1ZSA9PSB1bmRlZmluZWQgJiYgdGhpcy5kaXNhYmxlZCkpIHJldHVybjtcbiAgICBcbiAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHRoaXMuc2hvd0Ryb3Bkb3duKSB7XG4gICAgICAgICAgdGhpcy5zZXRDb21ib1RvdWNoZWQoKTtcbiAgICAgICAgfVxuICBcbiAgICAgICAgdGhpcy5zaG93RHJvcGRvd24gPSAhdGhpcy5zaG93RHJvcGRvd247ICAgICAgXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoIXZhbHVlICYmIHRoaXMuc2hvd0Ryb3Bkb3duKSB7XG4gICAgICAgICAgdGhpcy5zZXRDb21ib1RvdWNoZWQoKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgdGhpcy5zaG93RHJvcGRvd24gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgdGhpcy5jbGVhclNlYXJjaCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsaWNrT3V0c2lkZUVuYWJsZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICBTZWxlY3Qocm93OiBhbnkpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgdGhpcy5Ub2dnbGVEcm9wRG93bihudWxsLCBmYWxzZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy52YWx1ZSA9IHRoaXMucmVuZGVyUHJvcGVydHlWYWx1ZSh0aGlzLnZhbHVlUHJvcGVydHksIHJvdyk7XG4gICAgdGhpcy5vbkNoYW5nZS5lbWl0KHRoaXMudmFsdWUpOyAgICBcbiAgICB0aGlzLlRvZ2dsZURyb3BEb3duKG51bGwsIGZhbHNlKTtcbiAgfVxuICBPblNlYXJjaCgpOiB2b2lkIHtcbiAgICBpZih0aGlzLmxhenlMb2FkZWREYXRhKSB7XG4gICAgICB0aGlzLm9uU2VhcmNoLmVtaXQodGhpcy5zZWFyY2gpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zZWFyY2ggfHwgdGhpcy5zZWFyY2gubGVuZ3RoIDwgMykge1xuICAgICAgdGhpcy5jbGVhclNlYXJjaFJlc3VsdHMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmZpbHRlckRhdGEoKTtcbiAgfVxuICBPblBhZ2luYXRlKCk6IHZvaWQge1xuICAgIHRoaXMuY2xpY2tPdXRzaWRlRW5hYmxlZCA9IGZhbHNlO1xuICB9XG4gIENsZWFyU2VsZWN0aW9uKGU/OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgICB0aGlzLnNlbGVjdGVkRGlzcGxheVRleHQgPSBudWxsO1xuICAgIHRoaXMuY29tYm9Ub3VjaGVkID0gdHJ1ZTtcbiAgICB0aGlzLnNob3dEcm9wZG93biA9IGZhbHNlO1xuICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLnZhbHVlKTtcblxuICAgIGlmIChlKSBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICB9XG4gIE9uQ29tYm9QcmVzc2VkKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleUNvZGUgPT0gMTMpIHtcbiAgICAgIHRoaXMuVG9nZ2xlRHJvcERvd24obnVsbCk7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0U2VsZWN0ZWRJdGVtQnlUaGVDdXJyZW50TW9kZWxWYWx1ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMudmFsdWUpIHJldHVybjtcblxuICAgIGxldCByb3cgPSB0aGlzLmRhdGEuZmluZCh4ID0+IHRoaXMudmFsdWUgPT0gdGhpcy5yZW5kZXJQcm9wZXJ0eVZhbHVlKHRoaXMudmFsdWVQcm9wZXJ0eSwgeCkpO1xuICAgIGlmIChyb3cpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWREaXNwbGF5VGV4dCA9IHRoaXMucmVuZGVyUHJvcGVydHlWYWx1ZSh0aGlzLmRpc3BsYXlUZXh0UHJvcGVydHksIHJvdyk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgZmlsdGVyRGF0YSgpOiB2b2lkIHtcbiAgICB0aGlzLmludGVybmFsRGF0YSA9IHRoaXMuZGF0YS5maWx0ZXIoeCA9PiB7XG4gICAgICBcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb2x1bW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBjb2x1bW5EYXRhID0gJyc7XG4gICAgICAgIGxldCB2YWx1ZSA9ICcnO1xuXG4gICAgICAgIGlmICh0aGlzLmNvbHVtbnNbaV0uZGF0YSkge1xuICAgICAgICAgIGNvbHVtbkRhdGEgPSB0aGlzLnJlbmRlclByb3BlcnR5VmFsdWUodGhpcy5jb2x1bW5zW2ldLmRhdGEsIHgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuY29sdW1uc1tpXS5yZW5kZXIgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdmFsdWUgPSB0aGlzLmNvbHVtbnNbaV0ucmVuZGVyKHgsIGNvbHVtbkRhdGEsIGkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gY29sdW1uRGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS50b1N0cmluZygpLnRvVXBwZXJDYXNlKCkuaW5kZXhPZih0aGlzLnNlYXJjaC50b1VwcGVyQ2FzZSgpKSA+PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG4gIHByaXZhdGUgY2xlYXJTZWFyY2goKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2ggPSAnJztcbiAgICB0aGlzLmNsZWFyU2VhcmNoUmVzdWx0cygpO1xuICB9XG4gIHByaXZhdGUgY2xlYXJTZWFyY2hSZXN1bHRzKCk6IHZvaWQge1xuICAgIHRoaXMuaW50ZXJuYWxEYXRhID0gT2JqZWN0LmFzc2lnbihbXSwgdGhpcy5kYXRhKTtcbiAgfVxuICBwcml2YXRlIHNldENvbWJvVG91Y2hlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbWJvVG91Y2hlZCA9IHRydWU7XG4gIH1cbiAgcHJpdmF0ZSByZW5kZXJQcm9wZXJ0eVZhbHVlKHByb3BlcnR5UGF0aDogc3RyaW5nLCBvYmplY3Q6IGFueSk6IGFueSB7XG4gICAgbGV0IHBhcnRzOiBzdHJpbmdbXSA9IHByb3BlcnR5UGF0aC5zcGxpdCggXCIuXCIgKTtcbiAgICBsZXQgcHJvcGVydHk6IGFueSA9IG9iamVjdCB8fCB7fTtcbiAgXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCFwcm9wZXJ0eSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgcHJvcGVydHkgPSBwcm9wZXJ0eVtwYXJ0c1tpXV07XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb3BlcnR5O1xuICB9XG4gXG59XG4iLCI8ZGl2IFtpZF09XCJpZGVudGlmaWVyXCIgY2xhc3M9XCJ1aS1kcm9wZG93bi1ncmlkXCI+XG4gIDxsYWJlbCAqbmdJZj1cImxhYmVsXCI+XG4gICAge3tsYWJlbH19XG4gICAgPHNwYW4gY2xhc3M9XCJyZXF1aXJlZC1zeW1ib2xcIiAqbmdJZj1cImlzUmVxdWlyZWRcIj4gKjwvc3Bhbj5cbiAgICA8aSBjbGFzcz1cImZhIGZhLXF1ZXN0aW9uLWNpcmNsZSBtbC0yXCIgdG9vbHRpcD1cInt7aGVscH19XCIgY29udGFpbmVyPVwiYm9keVwiICpuZ0lmPVwiaGVscFwiPjwvaT5cbiAgPC9sYWJlbD5cblxuICA8aW5wdXQgdHlwZT1cImhpZGRlblwiIFsobmdNb2RlbCldPVwidmFsdWVcIiAvPlxuICA8ZGl2IGNsYXNzPVwiY29tYm9ib3ggZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiIFxuICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICdoYXMtdmFsaWRhdGlvbnMnOiBzaG93VmFsaWRhdGlvbnMsXG4gICAgICAnb3Blbic6IHNob3dEcm9wZG93biwgXG4gICAgICAnZGlzYWJsZWQnOiBkaXNhYmxlZCxcbiAgICAgICdpcy12YWxpZCc6ICFzaG93RHJvcGRvd24gJiYgIWRpc2FibGVkICYmIGNvbWJvVG91Y2hlZCAmJiAoIWlzUmVxdWlyZWQgfHwgdmFsdWUpLFxuICAgICAgJ2lzLWludmFsaWQnOiAhc2hvd0Ryb3Bkb3duICYmICFkaXNhYmxlZCAmJiBjb21ib1RvdWNoZWQgJiYgaXNSZXF1aXJlZCAmJiAhdmFsdWVcbiAgICB9XCJcbiAgICAoY2xpY2spPVwiVG9nZ2xlRHJvcERvd24oJGV2ZW50KVwiIChrZXl1cCk9XCJPbkNvbWJvUHJlc3NlZCgkZXZlbnQpXCIgdGFiaW5kZXg9XCIwXCI+XG5cbiAgICA8c3BhbiBjbGFzcz1cIm1yLWF1dG8gdGV4dC10cnVuY2F0ZVwiPnt7c2VsZWN0ZWREaXNwbGF5VGV4dCB8fCBwbGFjZWhvbGRlcn19PC9zcGFuPlxuICAgIDxpIGNsYXNzPVwiZmEgZmEtdGltZXMgYnRuLWNsZWFyLXNlbGVjdGlvblwiICpuZ0lmPVwidmFsdWUgJiYgIWRpc2FibGVkXCIgKGNsaWNrKT1cIkNsZWFyU2VsZWN0aW9uKCRldmVudClcIj48L2k+XG4gICAgPGkgY2xhc3M9XCJmYVwiIFtuZ0NsYXNzXT1cInsnZmEtY2FyZXQtZG93bic6ICFzaG93RHJvcGRvd24sICdmYS1jYXJldC11cCc6IHNob3dEcm9wZG93bn1cIj48L2k+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1vcHRpb25zIHNoYWRvdyBmYWRlSW5Eb3duXCIgKm5nSWY9XCJzaG93RHJvcGRvd25cIiAoY2xpY2tPdXRzaWRlKT1cIlRvZ2dsZURyb3BEb3duKCRldmVudCwgZmFsc2UpXCI+XG4gICAgPGRpdiBjbGFzcz1cIm9wdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidG9vbGJhciBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGF1dG8tZm9jdXNcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiIFxuICAgICAgICAgIG5hbWU9XCJ7e2lkZW50aWZpZXJ9fS1zZWFyY2hcIiBcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaFwiIFxuICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3tzZWFyY2hQbGFjZWhvbGRlcn19XCJcbiAgICAgICAgICBkZWJvdW5jZSAoY2FsbGJhY2spPVwiT25TZWFyY2goKVwiIC8+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInAtMlwiPlxuICAgICAgICA8ZGF0YWdyaWQgXG4gICAgICAgICAgW2RhdGFdPVwiaW50ZXJuYWxEYXRhXCIgXG4gICAgICAgICAgW2NvbHVtbnNdPVwiY29sdW1uc1wiIFxuICAgICAgICAgIFtzaG93QWN0aW9uc0NvbHVtbl09XCJ0cnVlXCJcbiAgICAgICAgICBbaW5pdGlhbENvbHVtblRvU29ydF09XCIwXCIgICAgICAgICAgXG4gICAgICAgICAgW2l0ZW1zUGVyUGFnZV09XCJpdGVtc1BlclBhZ2VcIlxuICAgICAgICAgIFttYXhTaXplXT1cIm1heFNpemVcIlxuICAgICAgICAgIFtzaG93SW5mb3NdPVwic2hvd0luZm9zXCIgICAgICAgICAgXG4gICAgICAgICAgYWN0aW9uc0NvbHVtbldpZHRoPVwiNjBweFwiXG4gICAgICAgICAgKE9uUGFnaW5hdGUpPVwiT25QYWdpbmF0ZSgpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIGFjdGlvbnMtY29sdW1uIGxldC1yb3c9XCJyb3dcIiBsZXQtcm93SW5kZXg9XCJyb3dJbmRleFwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IGJ0bi1zbVwiIChjbGljayk9XCJTZWxlY3Qocm93KVwiPjxpIGNsYXNzPVwiZmEgZmEtZXh0ZXJuYWwtbGlua1wiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2RhdGFncmlkPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxpbnB1dC12YWxpZGF0aW9uc1xuICAqbmdJZj1cInNob3dWYWxpZGF0aW9ucyAmJiAhZGlzYWJsZWQgJiYgY29tYm9Ub3VjaGVkICYmIChpbnZhbGlkIHwgYXN5bmMpXCJcbiAgW21lc3NhZ2VzXT1cImZhaWx1cmVzIHwgYXN5bmNcIj5cbjwvaW5wdXQtdmFsaWRhdGlvbnM+XG5cbjxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIiAqbmdJZj1cImRlc2NyaXB0aW9uXCI+e3tkZXNjcmlwdGlvbn19PC9zbWFsbD5cbiJdfQ==