@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
106 lines • 21.2 kB
JavaScript
import { Component } from '@angular/core';
import { BaseSearchComponent } from '../base-search.component';
import * as i0 from "@angular/core";
import * as i1 from "../../../date-time-picker/date-time-picker.component";
import * as i2 from "../../../../directives/focus-if/focus-if.directive";
import * as i3 from "@angular/forms";
import * as i4 from "../../../icon/icon.component";
import * as i5 from "../../../popover/popover.directive";
import * as i6 from "@angular/common";
export class SearchDateRangeComponent extends BaseSearchComponent {
constructor() {
super(...arguments);
this.type = 'date-range';
}
get label() {
return this.config.label;
}
get from() {
// if value does not exist the set it
if (!this.value || !this.value.from) {
this.from = new Date();
}
// ensure that the from value is a date object
if (this.value.from instanceof Date === false) {
this.value.from = new Date(this.value.from);
}
return this.value.from;
}
set from(fromValue) {
// create new object based on the current value
const value = Object.assign({}, this.value);
// ensure that the from value is a date
if (fromValue instanceof Date === false) {
fromValue = new Date(fromValue);
}
// set the latest value
value.from = fromValue;
// update the value object while ensuring immutability
this.value = value;
}
get to() {
// if value does not exist the set it
if (!this.value || !this.value.to) {
this.to = new Date();
}
// ensure that the to value is a date object
if (this.value.to instanceof Date === false) {
this.value.to = new Date(this.value.to);
}
return this.value.to;
}
set to(toValue) {
// create new object based on the current value
const value = Object.assign({}, this.value);
// ensure that the to value is a date
if (toValue instanceof Date === false) {
toValue = new Date(toValue);
}
// set the latest value
value.to = toValue;
// update the value object while ensuring immutability
this.value = value;
}
get fromLabel() {
return this.config.fromLabel || 'From';
}
get toLabel() {
return this.config.toLabel || 'To';
}
get fromPlaceholder() {
return this.config.fromPlaceholder;
}
get toPlaceholder() {
return this.config.toPlaceholder;
}
get toDateInputAriaLabel() {
return this.config.toDateInputAriaLabel || 'Selected date';
}
get fromDateInputAriaLabel() {
return this.config.fromDateInputAriaLabel || 'Selected date';
}
/**
* Override the default validation
*/
validate() {
// check if there is a config validation function
if (this.config.validation) {
return super.validate();
}
// create copies of the dates so we can modify time value (to ignore it)
const from = new Date(this.value.from);
const to = new Date(this.value.to);
// set the time to the same so we dont compare it
from.setHours(0, 0, 0, 0);
to.setHours(0, 0, 0, 0);
// valid if the from date is less than or equal to the to date
this.valid = from <= to;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SearchDateRangeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: SearchDateRangeComponent, selector: "ux-search-date-range", usesInheritance: true, ngImport: i0, template: "@if (label) {\n <label class=\"form-label\">{{ label }}</label>\n}\n\n<div class=\"row\">\n <div class=\"col-sm-12\">\n <div class=\"form-inline\" [class.has-error]=\"!valid\">\n\n <div class=\"form-group p-r-md\">\n <label class=\"form-label m-r-xs\">{{ fromLabel }}</label>\n\n <div class=\"input-group date m-nil\">\n <span class=\"input-group-addon p-r-xs\" tabindex=\"1\" (click)=\"fromPopover.show()\">\n <ux-icon name=\"calendar\"></ux-icon>\n </span>\n <input type=\"text\" #fromPopover=\"ux-popover\" [ngModel]=\"from | date:'dd MMMM yyyy'\"\n [uxPopover]=\"fromPopoverTemplate\" placement=\"bottom\" popoverClass=\"date-time-picker-popover\"\n class=\"form-control\" [attr.aria-label]=\"fromDateInputAriaLabel\" [placeholder]=\"fromPlaceholder\" [focusIf]=\"focus\">\n </div>\n </div>\n\n <div class=\"form-group p-r-xs\">\n <label class=\"form-label m-r-xs\">{{ toLabel }}</label>\n\n <div class=\"input-group date m-nil\">\n <span class=\"input-group-addon\" tabindex=\"1\" (click)=\"toPopover.show()\">\n <ux-icon name=\"calendar\"></ux-icon>\n </span>\n <input type=\"text\" #toPopover=\"ux-popover\" [ngModel]=\"to | date:'dd MMMM yyyy'\"\n [uxPopover]=\"toPopoverTemplate\" placement=\"bottom\" popoverClass=\"date-time-picker-popover\"\n class=\"form-control\" [attr.aria-label]=\"toDateInputAriaLabel\" [placeholder]=\"toPlaceholder\">\n </div>\n </div>\n\n </div>\n </div>\n </div>\n\n <ng-template #fromPopoverTemplate>\n <ux-date-time-picker [(date)]=\"from\" [showTime]=\"false\"></ux-date-time-picker>\n </ng-template>\n\n <ng-template #toPopoverTemplate>\n <ux-date-time-picker [(date)]=\"to\" [showTime]=\"false\"></ux-date-time-picker>\n </ng-template>", dependencies: [{ kind: "component", type: i1.DateTimePickerComponent, selector: "ux-date-time-picker", inputs: ["showDate", "showTime", "showTimezone", "showSeconds", "showMeridian", "showSpinners", "weekdays", "months", "monthsShort", "meridians", "nowBtnText", "showNowBtn", "timezones", "startOfWeek", "nowBtnAriaLabel", "date", "timezone", "min", "max"], outputs: ["dateChange", "timezoneChange"] }, { kind: "directive", type: i2.FocusIfDirective, selector: "[focusIf]", inputs: ["focusIfDelay", "focusIfScroll", "focusIf"] }, { kind: "directive", type: i3.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: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.IconComponent, selector: "ux-icon", inputs: ["name", "size", "rotate", "flipHorizontal", "flipVertical"] }, { kind: "directive", type: i5.PopoverDirective, selector: "[uxPopover]", inputs: ["uxPopover", "popoverTitle", "popoverDisabled", "popoverClass", "popoverRole", "popoverContext", "popoverDelay", "showTriggers", "hideTriggers"], exportAs: ["ux-popover"] }, { kind: "pipe", type: i6.DatePipe, name: "date" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SearchDateRangeComponent, decorators: [{
type: Component,
args: [{ selector: 'ux-search-date-range', template: "@if (label) {\n <label class=\"form-label\">{{ label }}</label>\n}\n\n<div class=\"row\">\n <div class=\"col-sm-12\">\n <div class=\"form-inline\" [class.has-error]=\"!valid\">\n\n <div class=\"form-group p-r-md\">\n <label class=\"form-label m-r-xs\">{{ fromLabel }}</label>\n\n <div class=\"input-group date m-nil\">\n <span class=\"input-group-addon p-r-xs\" tabindex=\"1\" (click)=\"fromPopover.show()\">\n <ux-icon name=\"calendar\"></ux-icon>\n </span>\n <input type=\"text\" #fromPopover=\"ux-popover\" [ngModel]=\"from | date:'dd MMMM yyyy'\"\n [uxPopover]=\"fromPopoverTemplate\" placement=\"bottom\" popoverClass=\"date-time-picker-popover\"\n class=\"form-control\" [attr.aria-label]=\"fromDateInputAriaLabel\" [placeholder]=\"fromPlaceholder\" [focusIf]=\"focus\">\n </div>\n </div>\n\n <div class=\"form-group p-r-xs\">\n <label class=\"form-label m-r-xs\">{{ toLabel }}</label>\n\n <div class=\"input-group date m-nil\">\n <span class=\"input-group-addon\" tabindex=\"1\" (click)=\"toPopover.show()\">\n <ux-icon name=\"calendar\"></ux-icon>\n </span>\n <input type=\"text\" #toPopover=\"ux-popover\" [ngModel]=\"to | date:'dd MMMM yyyy'\"\n [uxPopover]=\"toPopoverTemplate\" placement=\"bottom\" popoverClass=\"date-time-picker-popover\"\n class=\"form-control\" [attr.aria-label]=\"toDateInputAriaLabel\" [placeholder]=\"toPlaceholder\">\n </div>\n </div>\n\n </div>\n </div>\n </div>\n\n <ng-template #fromPopoverTemplate>\n <ux-date-time-picker [(date)]=\"from\" [showTime]=\"false\"></ux-date-time-picker>\n </ng-template>\n\n <ng-template #toPopoverTemplate>\n <ux-date-time-picker [(date)]=\"to\" [showTime]=\"false\"></ux-date-time-picker>\n </ng-template>" }]
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zZWFyY2gtYnVpbGRlci9zZWFyY2gtY29tcG9uZW50cy9kYXRlLXJhbmdlL2RhdGUtcmFuZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvc2VhcmNoLWJ1aWxkZXIvc2VhcmNoLWNvbXBvbmVudHMvZGF0ZS1yYW5nZS9kYXRlLXJhbmdlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7O0FBTS9ELE1BQU0sT0FBTyx3QkFBeUIsU0FBUSxtQkFBbUI7SUFKakU7O1FBTUksU0FBSSxHQUFXLFlBQVksQ0FBQztLQW1IL0I7SUFqSEcsSUFBSSxLQUFLO1FBQ0wsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBSSxJQUFJO1FBRUoscUNBQXFDO1FBQ3JDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUVELDhDQUE4QztRQUM5QyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxZQUFZLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUM1QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxL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Q0FBQyxFQUFFLENBQUMsQ0FBQztRQUVuQyxpREFBaUQ7UUFDakQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQixFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXhCLDhEQUE4RDtRQUM5RCxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7SUFDNUIsQ0FBQzsrR0FwSFEsd0JBQXdCO21HQUF4Qix3QkFBd0IsbUZDUHJDLDg0REE0Q2tCOzs0RkRyQ0wsd0JBQXdCO2tCQUpwQyxTQUFTOytCQUNJLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmFzZVNlYXJjaENvbXBvbmVudCB9IGZyb20gJy4uL2Jhc2Utc2VhcmNoLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAndXgtc2VhcmNoLWRhdGUtcmFuZ2UnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kYXRlLXJhbmdlLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBTZWFyY2hEYXRlUmFuZ2VDb21wb25lbnQgZXh0ZW5kcyBCYXNlU2VhcmNoQ29tcG9uZW50IHtcblxuICAgIHR5cGU6IHN0cmluZyA9ICdkYXRlLXJhbmdlJztcblxuICAgIGdldCBsYWJlbCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcubGFiZWw7XG4gICAgfVxuXG4gICAgZ2V0IGZyb20oKSB7XG5cbiAgICAgICAgLy8gaWYgdmFsdWUgZG9lcyBub3QgZXhpc3QgdGhlIHNldCBpdFxuICAgICAgICBpZiAoIXRoaXMudmFsdWUgfHwgIXRoaXMudmFsdWUuZnJvbSkge1xuICAgICAgICAgICAgdGhpcy5mcm9tID0gbmV3IERhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVuc3VyZSB0aGF0IHRoZSBmcm9tIHZhbHVlIGlzIGEgZGF0ZSBvYmplY3RcbiAgICAgICAgaWYgKHRoaXMudmFsdWUuZnJvbSBpbnN0YW5jZW9mIERhdGUgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlLmZyb20gPSBuZXcgRGF0ZSh0aGlzLnZhbHVlLmZyb20pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWUuZnJvbTtcbiAgICB9XG5cbiAgICBzZXQgZnJvbShmcm9tVmFsdWU6IHN0cmluZyB8IG51bWJlciB8IERhdGUpIHtcblxuICAgICAgICAvLyBjcmVhdGUgbmV3IG9iamVjdCBiYXNlZCBvbiB0aGUgY3VycmVudCB2YWx1ZVxuICAgICAgICBjb25zdCB2YWx1ZSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMudmFsdWUpO1xuXG4gICAgICAgIC8vIGVuc3VyZSB0aGF0IHRoZSBmcm9tIHZhbHVlIGlzIGEgZGF0ZVxuICAgICAgICBpZiAoZnJvbVZhbHVlIGluc3RhbmNlb2YgRGF0ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGZyb21WYWx1ZSA9IG5ldyBEYXRlKGZyb21WYWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZXQgdGhlIGxhdGVzdCB2YWx1ZVxuICAgICAgICB2YWx1ZS5mcm9tID0gZnJvbVZhbHVlO1xuXG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgdmFsdWUgb2JqZWN0IHdoaWxlIGVuc3VyaW5nIGltbXV0YWJpbGl0eVxuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IHRvKCkge1xuXG4gICAgICAgIC8vIGlmIHZhbHVlIGRvZXMgbm90IGV4aXN0IHRoZSBzZXQgaXRcbiAgICAgICAgaWYgKCF0aGlzLnZhbHVlIHx8ICF0aGlzLnZhbHVlLnRvKSB7XG4gICAgICAgICAgICB0aGlzLnRvID0gbmV3IERhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVuc3VyZSB0aGF0IHRoZSB0byB2YWx1ZSBpcyBhIGRhdGUgb2JqZWN0XG4gICAgICAgIGlmICh0aGlzLnZhbHVlLnRvIGluc3RhbmNlb2YgRGF0ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUudG8gPSBuZXcgRGF0ZSh0aGlzLnZhbHVlLnRvKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlLnRvO1xuICAgIH1cblxuICAgIHNldCB0byh0b1ZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBEYXRlKSB7XG5cbiAgICAgICAgLy8gY3JlYXRlIG5ldyBvYmplY3QgYmFzZWQgb24gdGhlIGN1cnJlbnQgdmFsdWVcbiAgICAgICAgY29uc3QgdmFsdWUgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnZhbHVlKTtcblxuICAgICAgICAvLyBlbnN1cmUgdGhhdCB0aGUgdG8gdmFsdWUgaXMgYSBkYXRlXG4gICAgICAgIGlmICh0b1ZhbHVlIGluc3RhbmNlb2YgRGF0ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRvVmFsdWUgPSBuZXcgRGF0ZSh0b1ZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNldCB0aGUgbGF0ZXN0IHZhbHVlXG4gICAgICAgIHZhbHVlLnRvID0gdG9WYWx1ZTtcblxuICAgICAgICAvLyB1cGRhdGUgdGhlIHZhbHVlIG9iamVjdCB3aGlsZSBlbnN1cmluZyBpbW11dGFiaWxpdHlcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIGdldCBmcm9tTGFiZWwoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmZyb21MYWJlbCB8fCAnRnJvbSc7XG4gICAgfVxuXG4gICAgZ2V0IHRvTGFiZWwoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnRvTGFiZWwgfHwgJ1RvJztcbiAgICB9XG5cbiAgICBnZXQgZnJvbVBsYWNlaG9sZGVyKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5mcm9tUGxhY2Vob2xkZXI7XG4gICAgfVxuXG4gICAgZ2V0IHRvUGxhY2Vob2xkZXIoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnRvUGxhY2Vob2xkZXI7XG4gICAgfVxuXG4gICAgZ2V0IHRvRGF0ZUlucHV0QXJpYUxhYmVsKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy50b0RhdGVJbnB1dEFyaWFMYWJlbCB8fCAnU2VsZWN0ZWQgZGF0ZSc7XG4gICAgfVxuXG4gICAgZ2V0IGZyb21EYXRlSW5wdXRBcmlhTGFiZWwoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLmZyb21EYXRlSW5wdXRBcmlhTGFiZWwgfHwgJ1NlbGVjdGVkIGRhdGUnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIHRoZSBkZWZhdWx0IHZhbGlkYXRpb25cbiAgICAgKi9cbiAgICB2YWxpZGF0ZSgpOiB2b2lkIHtcblxuICAgICAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhIGNvbmZpZyB2YWxpZGF0aW9uIGZ1bmN0aW9uXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy52YWxpZGF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIudmFsaWRhdGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNyZWF0ZSBjb3BpZXMgb2YgdGhlIGRhdGVzIHNvIHdlIGNhbiBtb2RpZnkgdGltZSB2YWx1ZSAodG8gaWdub3JlIGl0KVxuICAgICAgICBjb25zdCBmcm9tID0gbmV3IERhdGUodGhpcy52YWx1ZS5mcm9tKTtcbiAgICAgICAgY29uc3QgdG8gPSBuZXcgRGF0ZSh0aGlzLnZhbHVlLnRvKTtcblxuICAgICAgICAvLyBzZXQgdGhlIHRpbWUgdG8gdGhlIHNhbWUgc28gd2UgZG9udCBjb21wYXJlIGl0XG4gICAgICAgIGZyb20uc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICAgIHRvLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuXG4gICAgICAgIC8vIHZhbGlkIGlmIHRoZSBmcm9tIGRhdGUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSB0byBkYXRlXG4gICAgICAgIHRoaXMudmFsaWQgPSBmcm9tIDw9IHRvO1xuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hEYXRlUmFuZ2VDb25maWcge1xuICAgIGxhYmVsPzogc3RyaW5nO1xuICAgIGZyb21MYWJlbD86IHN0cmluZztcbiAgICB0b0xhYmVsPzogc3RyaW5nO1xuICAgIGZyb21QbGFjZWhvbGRlcj86IHN0cmluZztcbiAgICB0b1BsYWNlaG9sZGVyPzogc3RyaW5nO1xuICAgIHRvRGF0ZUlucHV0QXJpYUxhYmVsPzogc3RyaW5nO1xuICAgIGZyb21EYXRlSW5wdXRBcmlhTGFiZWw/OiBzdHJpbmc7XG4gICAgdmFsaWRhdGlvbjogKHZhbHVlOiB1bmtub3duKSA9PiBib29sZWFuO1xufSIsIkBpZiAobGFiZWwpIHtcbiAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPnt7IGxhYmVsIH19PC9sYWJlbD5cbn1cblxuPGRpdiBjbGFzcz1cInJvd1wiPlxuICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEyXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0taW5saW5lXCIgW2NsYXNzLmhhcy1lcnJvcl09XCIhdmFsaWRcIj5cblxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcC1yLW1kXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgbS1yLXhzXCI+e3sgZnJvbUxhYmVsIH19PC9sYWJlbD5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAgZGF0ZSBtLW5pbFwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtYWRkb24gcC1yLXhzXCIgdGFiaW5kZXg9XCIxXCIgKGNsaWNrKT1cImZyb21Qb3BvdmVyLnNob3coKVwiPlxuICAgICAgICAgICAgPHV4LWljb24gbmFtZT1cImNhbGVuZGFyXCI+PC91eC1pY29uPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiAjZnJvbVBvcG92ZXI9XCJ1eC1wb3BvdmVyXCIgW25nTW9kZWxdPVwiZnJvbSB8IGRhdGU6J2RkIE1NTU0geXl5eSdcIlxuICAgICAgICAgICAgW3V4UG9wb3Zlcl09XCJmcm9tUG9wb3ZlclRlbXBsYXRlXCIgcGxhY2VtZW50PVwiYm90dG9tXCIgcG9wb3ZlckNsYXNzPVwiZGF0ZS10aW1lLXBpY2tlci1wb3BvdmVyXCJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJmcm9tRGF0ZUlucHV0QXJpYUxhYmVsXCIgW3BsYWNlaG9sZGVyXT1cImZyb21QbGFjZWhvbGRlclwiIFtmb2N1c0lmXT1cImZvY3VzXCI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHAtci14c1wiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgbS1yLXhzXCI+e3sgdG9MYWJlbCB9fTwvbGFiZWw+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAgZGF0ZSBtLW5pbFwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC1hZGRvblwiIHRhYmluZGV4PVwiMVwiIChjbGljayk9XCJ0b1BvcG92ZXIuc2hvdygpXCI+XG4gICAgICAgICAgICAgIDx1eC1pY29uIG5hbWU9XCJjYWxlbmRhclwiPjwvdXgtaWNvbj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiICN0b1BvcG92ZXI9XCJ1eC1wb3BvdmVyXCIgW25nTW9kZWxdPVwidG8gfCBkYXRlOidkZCBNTU1NIHl5eXknXCJcbiAgICAgICAgICAgICAgW3V4UG9wb3Zlcl09XCJ0b1BvcG92ZXJUZW1wbGF0ZVwiIHBsYWNlbWVudD1cImJvdHRvbVwiIHBvcG92ZXJDbGFzcz1cImRhdGUtdGltZS1waWNrZXItcG9wb3ZlclwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJ0b0RhdGVJbnB1dEFyaWFMYWJlbFwiIFtwbGFjZWhvbGRlcl09XCJ0b1BsYWNlaG9sZGVyXCI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPG5nLXRlbXBsYXRlICNmcm9tUG9wb3ZlclRlbXBsYXRlPlxuICAgICAgPHV4LWRhdGUtdGltZS1waWNrZXIgWyhkYXRlKV09XCJmcm9tXCIgW3Nob3dUaW1lXT1cImZhbHNlXCI+PC91eC1kYXRlLXRpbWUtcGlja2VyPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8bmctdGVtcGxhdGUgI3RvUG9wb3ZlclRlbXBsYXRlPlxuICAgICAgPHV4LWRhdGUtdGltZS1waWNrZXIgWyhkYXRlKV09XCJ0b1wiIFtzaG93VGltZV09XCJmYWxzZVwiPjwvdXgtZGF0ZS10aW1lLXBpY2tlcj5cbiAgICA8L25nLXRlbXBsYXRlPiJdfQ==