@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
244 lines • 37.9 kB
JavaScript
import { Component, Injector, ViewChild } from '@angular/core';
import { DateTime } from '@microsoft/windows-admin-center-sdk/core/base/date/date-time';
import { DateType } from '@microsoft/windows-admin-center-sdk/core/base/date/date-type';
import { KeyCode } from '@microsoft/windows-admin-center-sdk/core/data/accessibility-manager';
import { Globalization } from '@microsoft/windows-admin-center-sdk/core/data/globalization';
import { DropdownComponent } from '../../../dropdown/dropdown.component';
import { CalendarFormFieldComponent } from '../calendar/calendar-form-field.component';
import { ClockFormFieldComponent } from '../clock/clock-form-field.component';
import { DateLikeFormFieldComponent } from '../date-like/date-like-form-field.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "../../../dropdown/dropdown.component";
import * as i3 from "../calendar/calendar-form-field.component";
import * as i4 from "../clock/clock-form-field.component";
import * as i5 from "../../validation-alert/validation-alert.component";
import * as i6 from "../form-field-accessor.directive";
import * as i7 from "../form-field-validator.directive";
import * as i8 from "../../form-field-layout/form-field-layout.component";
const _c0 = ["dropDown"];
const _c1 = ["calendar"];
const _c2 = ["clock"];
const _c3 = ["type", "datetime"];
/**
* DateTime Form Field Component
*/
export class DateTimeFormFieldComponent extends DateLikeFormFieldComponent {
/**
* Initializes a new instance of the @see DateTimeFormFieldComponent class.
* @param injector The angular injection service. required by @see SmeInjectableBase decorator in the @see BaseComponent class
*/
constructor(injector) {
super(injector);
this.displayValueValid = false;
this.interMediateValue = new Date();
}
/**
* The source name to use for logging
*/
get logSourceName() {
return 'DateTimeFormFieldComponent';
}
/**
* Handles toggled state changes
*/
onDropdownToggled(expanded) {
if (expanded) {
this.calendar.focus();
}
else {
this.focus();
}
}
/**
* Handles keydown events on the dropdown toggle
*/
onToggleKeydown(event) {
switch (event.keyCode) {
case KeyCode.Enter: {
if (this.dropDown.isOpen) {
this.commitDropDownValue(event);
return;
}
this.dropDown.onToggleClick(event, true);
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
return;
}
case KeyCode.DownArrow: {
if (event.altKey) {
this.dropDown.onToggleClick(event, true);
}
return;
}
default: {
return;
}
}
}
/**
* Handles value changes from the date input
*/
commitDisplayValue() {
const displayDate = new Date(this.displayValue);
this.displayValueValid = !isNaN(displayDate.getTime());
this.expectValueChange = true;
this.markAsDirty();
if (this.displayValueValid) {
const valueAsDate = DateType.convert(this.value, DateType.Date);
DateTime.copyDate(displayDate, valueAsDate);
DateTime.copyTime(displayDate, valueAsDate);
const dateType = MsftSme.isNullOrUndefined(this.dateType) ? this.detectedDateType : this.dateType;
this.value = DateType.convert(valueAsDate, dateType);
}
else {
this.ngModel.control.updateValueAndValidity();
}
}
/**
* Occurs every time the value of the control changes, in the UI or programmatically.
* @param value the value of the form control
*/
onValueChanged(value) {
super.onValueChanged(value);
if (!this.expectValueChange) {
if (!value) {
this.displayValue = '';
}
else {
const valueAsDate = DateType.convert(value, DateType.Date);
this.displayValue = valueAsDate.toLocaleString(Globalization.localeId);
}
if (!this.displayValueValid) {
this.displayValueValid = true;
this.ngModel.control.updateValueAndValidity();
}
}
this.expectValueChange = false;
}
/**
* Called on ng model changes, prevents dropdown changes from going to form model.
*/
onNgModelChange(value, dateChanged) {
const valueAsDate = DateType.convert(value, DateType.Date);
if (dateChanged) {
const year = valueAsDate.getFullYear();
const date = valueAsDate.getDate();
const month = valueAsDate.getMonth();
this.interMediateValue.setFullYear(year, month, date);
return;
}
const hours = valueAsDate.getHours();
const minutes = valueAsDate.getMinutes();
this.interMediateValue.setHours(hours, minutes);
}
/**
* Called when users commits drop down changes, they are saved to model
*/
commitDropDownValue(event) {
this.value = this.interMediateValue;
this.dropDown.onToggleClick(event, true);
}
/**
* Performs validation that is internal to this control
* @param c The form control attached to this instance
*/
validate(c) {
if (!this.displayValueValid) {
return {
invalidDisplayValue: {
message: this.strings.MsftSmeShell.Angular.Form.Date.InvalidDateTime.format(DateTime.getLocaleDateStringFormat(Globalization.localeId.toLowerCase()))
}
};
}
return this.validateAsDateTime(c) || super.validate(c);
}
/**
* Creates the idBag used by this component to store unique element ids.
* id values will be assigned be the @see BaseComponent super class.
*/
createIdBag() {
return {
detailsSpan: '',
dropDownContent: ''
};
}
}
/** @nocollapse */ DateTimeFormFieldComponent.ɵfac = function DateTimeFormFieldComponent_Factory(t) { return new (t || DateTimeFormFieldComponent)(i0.ɵɵdirectiveInject(i0.Injector)); };
/** @nocollapse */ DateTimeFormFieldComponent.ɵcmp = /** @pureOrBreakMyCode */ i0.ɵɵdefineComponent({ type: DateTimeFormFieldComponent, selectors: [["sme-form-field", "type", "datetime"]], viewQuery: function DateTimeFormFieldComponent_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(_c0, 5);
i0.ɵɵviewQuery(_c1, 5);
i0.ɵɵviewQuery(_c2, 5);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.dropDown = _t.first);
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.calendar = _t.first);
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.clock = _t.first);
} }, features: [i0.ɵɵInheritDefinitionFeature], attrs: _c3, decls: 24, vars: 27, consts: [[3, "formField"], [1, "sme-arrange-stack-h", "sme-focus-zone", "sme-form-field-editor"], [1, "sme-combobox", 3, "autoToggle", "disabled", "autoWidth", "toggled"], ["dropDown", ""], [1, "sme-combobox-header", "sme-dropdown-toggle", 3, "keydown"], ["dropdownHeader", ""], ["type", "text", "role", "combobox", "spellcheck", "false", "autocapitalize", "off", "autocomplete", "off", 3, "ngModel", "placeholder", "ngModelChange"], ["textInput", ""], ["type", "button", "tabindex", "-1", "role", "presentation", "aria-hidden", "true", 1, "sme-button-trigger", "sme-button-auto-width", 3, "click"], ["dropDownButton", ""], [1, "sme-icon", "sme-icon-dateTime2"], [1, "sme-dropdown-content", "sme-dropdown-interaction-enabled", "sme-focus-trap", 3, "id"], [1, "sme-datetime-dropdown"], [1, "sme-datetime-main-content"], ["type", "calendar", "orientation", "vertical", 3, "ngModel", "required", "hideHeader", "ngModelChange"], ["calendar", ""], ["type", "clock", "orientation", "vertical", 3, "ngModel", "required", "hideHeader", "ngModelChange"], ["clock", ""], [1, "sme-datetime-confirmation"], ["type", "button", "tabindex", "0", 1, "sme-focus-zone", 3, "click"], [1, "sme-icon", "sme-icon-size-xxs", "sme-icon-accept"], [1, "sme-icon", "sme-icon-size-xxs", "sme-icon-clear"], [3, "alert"]], template: function DateTimeFormFieldComponent_Template(rf, ctx) { if (rf & 1) {
const _r6 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "sme-form-field-layout", 0)(1, "div", 1)(2, "sme-dropdown", 2, 3);
i0.ɵɵlistener("toggled", function DateTimeFormFieldComponent_Template_sme_dropdown_toggled_2_listener($event) { return ctx.onDropdownToggled($event); });
i0.ɵɵelementStart(4, "div", 4, 5);
i0.ɵɵlistener("keydown", function DateTimeFormFieldComponent_Template_div_keydown_4_listener($event) { return ctx.onToggleKeydown($event); });
i0.ɵɵelementStart(6, "input", 6, 7);
i0.ɵɵlistener("ngModelChange", function DateTimeFormFieldComponent_Template_input_ngModelChange_6_listener($event) { return ctx.displayValue = $event; })("ngModelChange", function DateTimeFormFieldComponent_Template_input_ngModelChange_6_listener() { return ctx.commitDisplayValue(); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(8, "button", 8, 9);
i0.ɵɵlistener("click", function DateTimeFormFieldComponent_Template_button_click_8_listener($event) { i0.ɵɵrestoreView(_r6); const _r0 = i0.ɵɵreference(3); return i0.ɵɵresetView(_r0.onToggleClick($event, true)); });
i0.ɵɵelement(10, "span", 10);
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(11, "div", 11)(12, "div", 12)(13, "div", 13)(14, "sme-form-field", 14, 15);
i0.ɵɵlistener("ngModelChange", function DateTimeFormFieldComponent_Template_sme_form_field_ngModelChange_14_listener($event) { return ctx.onNgModelChange($event, true); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(16, "sme-form-field", 16, 17);
i0.ɵɵlistener("ngModelChange", function DateTimeFormFieldComponent_Template_sme_form_field_ngModelChange_16_listener($event) { return ctx.onNgModelChange($event); });
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(18, "div", 18)(19, "button", 19);
i0.ɵɵlistener("click", function DateTimeFormFieldComponent_Template_button_click_19_listener($event) { return ctx.commitDropDownValue($event); });
i0.ɵɵelement(20, "span", 20);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(21, "button", 19);
i0.ɵɵlistener("click", function DateTimeFormFieldComponent_Template_button_click_21_listener($event) { i0.ɵɵrestoreView(_r6); const _r0 = i0.ɵɵreference(3); return i0.ɵɵresetView(_r0.onToggleClick($event, true)); });
i0.ɵɵelement(22, "span", 21);
i0.ɵɵelementEnd()()()()()();
i0.ɵɵelement(23, "sme-validation-alert", 22);
i0.ɵɵelementEnd();
} if (rf & 2) {
const _r0 = i0.ɵɵreference(3);
i0.ɵɵproperty("formField", ctx);
i0.ɵɵadvance(2);
i0.ɵɵproperty("autoToggle", false)("disabled", ctx.disabled)("autoWidth", true);
i0.ɵɵadvance(4);
i0.ɵɵproperty("ngModel", ctx.displayValue)("placeholder", ctx.placeholder);
i0.ɵɵattribute("aria-controls", ctx.idBag.dropDownContent)("aria-label", ctx.label)("disabled", ctx.loadingOrDisabled ? true : null)("aria-owns", ctx.idBag.dropDownContent)("aria-expanded", _r0.isOpen)("aria-autocomplete", "none")("aria-required", ctx.required);
i0.ɵɵadvance(2);
i0.ɵɵclassProp("sme-toggled", _r0.isOpen);
i0.ɵɵattribute("disabled", ctx.loadingOrDisabled ? true : null)("aria-pressed", _r0.isOpen);
i0.ɵɵadvance(3);
i0.ɵɵproperty("id", ctx.idBag.dropDownContent);
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngModel", ctx.interMediateValue)("required", true)("hideHeader", true);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngModel", ctx.interMediateValue)("required", true)("hideHeader", true);
i0.ɵɵadvance(3);
i0.ɵɵattribute("aria-label", ctx.strings.MsftSmeShell.Angular.Common.apply);
i0.ɵɵadvance(2);
i0.ɵɵattribute("aria-label", ctx.strings.MsftSmeShell.Angular.Common.clear);
i0.ɵɵadvance(2);
i0.ɵɵproperty("alert", ctx.alert);
} }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.RequiredValidator, i1.NgModel, i2.DropdownComponent, i3.CalendarFormFieldComponent, i4.ClockFormFieldComponent, i5.ValidationAlertComponent, i6.FormFieldAccessorDirective, i7.FormFieldValidatorDirective, i8.FormFieldLayoutComponent], encapsulation: 2 });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DateTimeFormFieldComponent, [{
type: Component,
args: [{ selector: 'sme-form-field[type="datetime"]', template: "<sme-form-field-layout [formField]=\"this\">\r\n <div class=\"sme-arrange-stack-h sme-focus-zone sme-form-field-editor\">\r\n <sme-dropdown #dropDown [autoToggle]=\"false\" class=\"sme-combobox\" [disabled]=\"disabled\" [autoWidth]=\"true\"\r\n (toggled)=\"onDropdownToggled($event)\">\r\n <div #dropdownHeader class=\"sme-combobox-header sme-dropdown-toggle\" (keydown)=\"onToggleKeydown($event)\">\r\n <input #textInput type=\"text\" role=\"combobox\" [(ngModel)]=\"displayValue\" (ngModelChange)=\"commitDisplayValue()\"\r\n [attr.aria-controls]=\"idBag.dropDownContent\" [attr.aria-label]=\"label\"\r\n [attr.disabled]=\"loadingOrDisabled ? true : null\"\r\n [attr.aria-owns]=\"idBag.dropDownContent\" [attr.aria-expanded]=\"dropDown.isOpen\"\r\n [attr.aria-autocomplete]=\"'none'\" [attr.aria-required]=\"required\" spellcheck=\"false\" autocapitalize=\"off\"\r\n autocomplete=\"off\" [placeholder]=\"placeholder\" />\r\n <button #dropDownButton type=\"button\" [attr.disabled]=\"loadingOrDisabled ? true : null\" tabindex=\"-1\"\r\n role=\"presentation\" aria-hidden=\"true\" [attr.aria-pressed]=\"dropDown.isOpen\"\r\n [class.sme-toggled]=\"dropDown.isOpen\" class=\"sme-button-trigger sme-button-auto-width\"\r\n (click)=\"dropDown.onToggleClick($event, true)\">\r\n <span class=\"sme-icon sme-icon-dateTime2\"></span>\r\n </button>\r\n </div>\r\n <div class=\"sme-dropdown-content sme-dropdown-interaction-enabled sme-focus-trap\" [id]=\"idBag.dropDownContent\">\r\n <div class=\"sme-datetime-dropdown\">\r\n <div class=\"sme-datetime-main-content\">\r\n <sme-form-field #calendar type=\"calendar\" [ngModel]=\"interMediateValue\" (ngModelChange)=\"onNgModelChange($event, true)\"\r\n [required]=\"true\" [hideHeader]=\"true\" orientation=\"vertical\">\r\n </sme-form-field>\r\n <sme-form-field #clock type=\"clock\" [ngModel]=\"interMediateValue\" (ngModelChange)=\"onNgModelChange($event)\"\r\n [required]=\"true\" [hideHeader]=\"true\" orientation=\"vertical\">\r\n </sme-form-field>\r\n </div>\r\n <div class=\"sme-datetime-confirmation\">\r\n <button type=\"button\" class=\"sme-focus-zone\" [attr.aria-label]=\"this.strings.MsftSmeShell.Angular.Common.apply\" tabindex=\"0\"\r\n (click)=\"commitDropDownValue($event)\">\r\n <span class=\"sme-icon sme-icon-size-xxs sme-icon-accept\"></span>\r\n </button>\r\n <button type=\"button\" class=\"sme-focus-zone\" [attr.aria-label]=\"this.strings.MsftSmeShell.Angular.Common.clear\" tabindex=\"0\"\r\n (click)=\"dropDown.onToggleClick($event, true);\">\r\n <span class=\"sme-icon sme-icon-size-xxs sme-icon-clear\"></span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </sme-dropdown>\r\n </div>\r\n <sme-validation-alert [alert]=\"alert\"></sme-validation-alert>\r\n</sme-form-field-layout>\r\n" }]
}], function () { return [{ type: i0.Injector }]; }, { dropDown: [{
type: ViewChild,
args: ['dropDown']
}], calendar: [{
type: ViewChild,
args: ['calendar']
}], clock: [{
type: ViewChild,
args: ['clock']
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUtZm9ybS1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9mb3JtL2Zvcm0tZmllbGQvZGF0ZXRpbWUvZGF0ZXRpbWUtZm9ybS1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9hbmd1bGFyL3NyYy9jb250cm9scy9mb3JtL2Zvcm0tZmllbGQvZGF0ZXRpbWUvZGF0ZXRpbWUtZm9ybS1maWVsZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBVSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHdkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDhEQUE4RCxDQUFDO0FBQ3hGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw4REFBOEQsQ0FBQztBQUN4RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUVBQXFFLENBQUM7QUFDOUYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDZEQUE2RCxDQUFDO0FBQzVGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRXpFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDZDQUE2QyxDQUFDOzs7Ozs7Ozs7Ozs7OztBQUV6Rjs7R0FFRztBQUtILE1BQU0sT0FBTywwQkFBMkIsU0FBUSwwQkFBMEI7SUFzQ3RFOzs7T0FHRztJQUNILFlBQVksUUFBa0I7UUFDMUIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7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aUJBQWlCO1FBQ2pCLCtDQUMrRDtRQURHLHNJQUFpQiwyQkFBdUIsSUFBQztRQUUzRyxpQkFBaUIsRUFBQTtRQUVuQixnQ0FBdUMsa0JBQUE7UUFFbkMsOEdBQVMsK0JBQTJCLElBQUM7UUFDckMsNEJBQWdFO1FBQ2xFLGlCQUFTO1FBQ1QsbUNBQ2tEO1FBQWhELG9LQUFTLGVBQUEsMEJBQStCLElBQUksQ0FBQyxDQUFBLElBQUU7UUFDL0MsNEJBQStEO1FBQ2pFLGlCQUFTLEVBQUEsRUFBQSxFQUFBLEVBQUEsRUFBQTtRQU1uQiw0Q0FBNkQ7UUFDL0QsaUJBQXdCOzs7UUEzQ0QsK0JBQWtCO1FBRWIsZUFBb0I7UUFBcEIsa0NBQW9CLDBCQUFBLG1CQUFBO1FBR00sZUFBMEI7UUFBMUIsMENBQTBCLGdDQUFBO1FBQ3RFLDBEQUE0Qyx5QkFBQSxpREFBQSx3Q0FBQSw2QkFBQSw2QkFBQSwrQkFBQTtRQU81QyxlQUFxQztRQUFyQyx5Q0FBcUM7UUFGRCwrREFBaUQsNEJBQUE7UUFPUCxlQUE0QjtRQUE1Qiw4Q0FBNEI7UUFHOUQsZUFBNkI7UUFBN0IsK0NBQTZCLGtCQUFBLG9CQUFBO1FBR25DLGVBQTZCO1FBQTdCLCtDQUE2QixrQkFBQSxvQkFBQTtRQUtwQixlQUFrRTtRQUFsRSwyRUFBa0U7UUFJbEUsZUFBa0U7UUFBbEUsMkVBQWtFO1FBU25HLGVBQWU7UUFBZixpQ0FBZTs7dUZEdEIxQiwwQkFBMEI7Y0FKdEMsU0FBUzsyQkFDSSxpQ0FBaUM7MkRBYXBDLFFBQVE7a0JBRGQsU0FBUzttQkFBQyxVQUFVO1lBSWQsUUFBUTtrQkFEZCxTQUFTO21CQUFDLFVBQVU7WUFJZCxLQUFLO2tCQURYLFNBQVM7bUJBQUMsT0FBTyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5qZWN0b3IsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBEYXRlTGlrZSB9IGZyb20gJ0BtaWNyb3NvZnQvd2luZG93cy1hZG1pbi1jZW50ZXItc2RrL2NvcmUvYmFzZS9kYXRlL2RhdGUtbGlrZSc7XHJcbmltcG9ydCB7IERhdGVUaW1lIH0gZnJvbSAnQG1pY3Jvc29mdC93aW5kb3dzLWFkbWluLWNlbnRlci1zZGsvY29yZS9iYXNlL2RhdGUvZGF0ZS10aW1lJztcclxuaW1wb3J0IHsgRGF0ZVR5cGUgfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL2Jhc2UvZGF0ZS9kYXRlLXR5cGUnO1xyXG5pbXBvcnQgeyBLZXlDb2RlIH0gZnJvbSAnQG1pY3Jvc29mdC93aW5kb3dzLWFkbWluLWNlbnRlci1zZGsvY29yZS9kYXRhL2FjY2Vzc2liaWxpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IEdsb2JhbGl6YXRpb24gfSBmcm9tICdAbWljcm9zb2Z0L3dpbmRvd3MtYWRtaW4tY2VudGVyLXNkay9jb3JlL2RhdGEvZ2xvYmFsaXphdGlvbic7XHJcbmltcG9ydCB7IERyb3Bkb3duQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vZHJvcGRvd24vZHJvcGRvd24uY29tcG9uZW50JztcclxuaW1wb3J0IHsgVmFsaWRhdGlvbkFsZXJ0cyB9IGZyb20gJy4uLy4uL3ZhbGlkYXRpb24tYWxlcnQvdmFsaWRhdGlvbi1hbGVydCc7XHJcbmltcG9ydCB7IENhbGVuZGFyRm9ybUZpZWxkQ29tcG9uZW50IH0gZnJvbSAnLi4vY2FsZW5kYXIvY2FsZW5kYXItZm9ybS1maWVsZC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDbG9ja0Zvcm1GaWVsZENvbXBvbmVudCB9IGZyb20gJy4uL2Nsb2NrL2Nsb2NrLWZvcm0tZmllbGQuY29tcG9uZW50JztcclxuaW1wb3J0IHsgRGF0ZUxpa2VGb3JtRmllbGRDb21wb25lbnQgfSBmcm9tICcuLi9kYXRlLWxpa2UvZGF0ZS1saWtlLWZvcm0tZmllbGQuY29tcG9uZW50JztcclxuXHJcbi8qKlxyXG4gKiBEYXRlVGltZSBGb3JtIEZpZWxkIENvbXBvbmVudFxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ3NtZS1mb3JtLWZpZWxkW3R5cGU9XCJkYXRldGltZVwiXScsXHJcbiAgICB0ZW1wbGF0ZVVybDogJy4vZGF0ZXRpbWUtZm9ybS1maWVsZC5jb21wb25lbnQuaHRtbCdcclxufSlcclxuZXhwb3J0IGNsYXNzIERhdGVUaW1lRm9ybUZpZWxkQ29tcG9uZW50IGV4dGVuZHMgRGF0ZUxpa2VGb3JtRmllbGRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIHNvdXJjZSBuYW1lIHRvIHVzZSBmb3IgbG9nZ2luZ1xyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgZ2V0IGxvZ1NvdXJjZU5hbWUoKSB7XHJcbiAgICAgICAgcmV0dXJuICdEYXRlVGltZUZvcm1GaWVsZENvbXBvbmVudCc7XHJcbiAgICB9XHJcblxyXG4gICAgQFZpZXdDaGlsZCgnZHJvcERvd24nKVxyXG4gICAgcHVibGljIGRyb3BEb3duOiBEcm9wZG93bkNvbXBvbmVudDtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdjYWxlbmRhcicpXHJcbiAgICBwdWJsaWMgY2FsZW5kYXI6IENhbGVuZGFyRm9ybUZpZWxkQ29tcG9uZW50O1xyXG5cclxuICAgIEBWaWV3Q2hpbGQoJ2Nsb2NrJylcclxuICAgIHB1YmxpYyBjbG9jazogQ2xvY2tGb3JtRmllbGRDb21wb25lbnQ7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY3VycmVudCBlZGl0YWJsZSBkaXNwbGF5IHZhbHVlIG9mIHRoaXMgZmllbGRcclxuICAgICAqL1xyXG4gICAgcHVibGljIGRpc3BsYXlWYWx1ZTogc3RyaW5nO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogaW5kaWNhdGVzIGlmIHRoZSBkaXNwbGF5IHZhbHVlIGlzIHZhbGlkXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBkaXNwbGF5VmFsdWVWYWxpZDogYm9vbGVhbjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIGluZGljYXRlcyBpZiBhIHZhbHVlIGNoYW5nZSBpcyBleHBlY3RlZFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgZXhwZWN0VmFsdWVDaGFuZ2U6IGJvb2xlYW47XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBBbiBpbnRlcm1lZGlhdGUgc3RvcmUgZm9yIGRyb3AgZG93biB2YWx1ZXNcclxuICAgICAqL1xyXG4gICAgcHVibGljIGludGVyTWVkaWF0ZVZhbHVlOiBEYXRlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5pdGlhbGl6ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEBzZWUgRGF0ZVRpbWVGb3JtRmllbGRDb21wb25lbnQgY2xhc3MuXHJcbiAgICAgKiBAcGFyYW0gaW5qZWN0b3IgVGhlIGFuZ3VsYXIgaW5qZWN0aW9uIHNlcnZpY2UuIHJlcXVpcmVkIGJ5IEBzZWUgU21lSW5qZWN0YWJsZUJhc2UgZGVjb3JhdG9yIGluIHRoZSBAc2VlIEJhc2VDb21wb25lbnQgY2xhc3NcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoaW5qZWN0b3I6IEluamVjdG9yKSB7XHJcbiAgICAgICAgc3VwZXIoaW5qZWN0b3IpO1xyXG4gICAgICAgIHRoaXMuZGlzcGxheVZhbHVlVmFsaWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmludGVyTWVkaWF0ZVZhbHVlID0gbmV3IERhdGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhhbmRsZXMgdG9nZ2xlZCBzdGF0ZSBjaGFuZ2VzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBvbkRyb3Bkb3duVG9nZ2xlZChleHBhbmRlZDogYm9vbGVhbikge1xyXG4gICAgICAgIGlmIChleHBhbmRlZCkge1xyXG4gICAgICAgICAgICB0aGlzLmNhbGVuZGFyLmZvY3VzKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5mb2N1cygpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhhbmRsZXMga2V5ZG93biBldmVudHMgb24gdGhlIGRyb3Bkb3duIHRvZ2dsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25Ub2dnbGVLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KSB7XHJcbiAgICAgICAgc3dpdGNoIChldmVudC5rZXlDb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgS2V5Q29kZS5FbnRlcjoge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJvcERvd24uaXNPcGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21taXREcm9wRG93blZhbHVlKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRyb3BEb3duLm9uVG9nZ2xlQ2xpY2soZXZlbnQsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FzZSBLZXlDb2RlLkRvd25BcnJvdzoge1xyXG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmFsdEtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJvcERvd24ub25Ub2dnbGVDbGljayhldmVudCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDogeyByZXR1cm47IH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIYW5kbGVzIHZhbHVlIGNoYW5nZXMgZnJvbSB0aGUgZGF0ZSBpbnB1dFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY29tbWl0RGlzcGxheVZhbHVlKCkge1xyXG4gICAgICAgIGNvbnN0IGRpc3BsYXlEYXRlID0gbmV3IERhdGUodGhpcy5kaXNwbGF5VmFsdWUpO1xyXG4gICAgICAgIHRoaXMuZGlzcGxheVZhbHVlVmFsaWQgPSAhaXNOYU4oZGlzcGxheURhdGUuZ2V0VGltZSgpKTtcclxuICAgICAgICB0aGlzLmV4cGVjdFZhbHVlQ2hhbmdlID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLm1hcmtBc0RpcnR5KCk7XHJcbiAgICAgICAgaWYgKHRoaXMuZGlzcGxheVZhbHVlVmFsaWQpIHtcclxuICAgICAgICAgICAgY29uc3QgdmFsdWVBc0RhdGUgPSBEYXRlVHlwZS5jb252ZXJ0KHRoaXMudmFsdWUsIERhdGVUeXBlLkRhdGUpO1xyXG4gICAgICAgICAgICBEYXRlVGltZS5jb3B5RGF0ZShkaXNwbGF5RGF0ZSwgdmFsdWVBc0RhdGUpO1xyXG4gICAgICAgICAgICBEYXRlVGltZS5jb3B5VGltZShkaXNwbGF5RGF0ZSwgdmFsdWVBc0RhdGUpO1xyXG4gICAgICAgICAgICBjb25zdCBkYXRlVHlwZSA9IE1zZnRTbWUuaXNOdWxsT3JVbmRlZmluZWQodGhpcy5kYXRlVHlwZSkgPyB0aGlzLmRldGVjdGVkRGF0ZVR5cGUgOiB0aGlzLmRhdGVUeXBlO1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gRGF0ZVR5cGUuY29udmVydCh2YWx1ZUFzRGF0ZSwgZGF0ZVR5cGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubmdNb2RlbC5jb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBPY2N1cnMgZXZlcnkgdGltZSB0aGUgdmFsdWUgb2YgdGhlIGNvbnRyb2wgY2hhbmdlcywgaW4gdGhlIFVJIG9yIHByb2dyYW1tYXRpY2FsbHkuXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIG9mIHRoZSBmb3JtIGNvbnRyb2xcclxuICAgICAqL1xyXG4gICAgcHJvdGVjdGVkIG9uVmFsdWVDaGFuZ2VkKHZhbHVlOiBEYXRlTGlrZSkge1xyXG4gICAgICAgIHN1cGVyLm9uVmFsdWVDaGFuZ2VkKHZhbHVlKTtcclxuICAgICAgICBpZiAoIXRoaXMuZXhwZWN0VmFsdWVDaGFuZ2UpIHtcclxuICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWUgPSAnJztcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlQXNEYXRlID0gRGF0ZVR5cGUuY29udmVydCh2YWx1ZSwgRGF0ZVR5cGUuRGF0ZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXlWYWx1ZSA9IHZhbHVlQXNEYXRlLnRvTG9jYWxlU3RyaW5nKEdsb2JhbGl6YXRpb24ubG9jYWxlSWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwbGF5VmFsdWVWYWxpZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5VmFsdWVWYWxpZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5nTW9kZWwuY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5leHBlY3RWYWx1ZUNoYW5nZSA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGVkIG9uIG5nIG1vZGVsIGNoYW5nZXMsIHByZXZlbnRzIGRyb3Bkb3duIGNoYW5nZXMgZnJvbSBnb2luZyB0byBmb3JtIG1vZGVsLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgb25OZ01vZGVsQ2hhbmdlKHZhbHVlOiBEYXRlTGlrZSwgZGF0ZUNoYW5nZWQ/OiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgdmFsdWVBc0RhdGUgPSBEYXRlVHlwZS5jb252ZXJ0KHZhbHVlLCBEYXRlVHlwZS5EYXRlKTtcclxuXHJcbiAgICAgICAgaWYgKGRhdGVDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHllYXIgPSB2YWx1ZUFzRGF0ZS5nZXRGdWxsWWVhcigpO1xyXG4gICAgICAgICAgICBjb25zdCBkYXRlID0gdmFsdWVBc0RhdGUuZ2V0RGF0ZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBtb250aCA9IHZhbHVlQXNEYXRlLmdldE1vbnRoKCk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmludGVyTWVkaWF0ZVZhbHVlLnNldEZ1bGxZZWFyKHllYXIsIG1vbnRoLCBkYXRlKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgaG91cnMgPSB2YWx1ZUFzRGF0ZS5nZXRIb3VycygpO1xyXG4gICAgICAgIGNvbnN0IG1pbnV0ZXMgPSB2YWx1ZUFzRGF0ZS5nZXRNaW51dGVzKCk7XHJcblxyXG4gICAgICAgIHRoaXMuaW50ZXJNZWRpYXRlVmFsdWUuc2V0SG91cnMoaG91cnMsIG1pbnV0ZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGVkIHdoZW4gdXNlcnMgY29tbWl0cyBkcm9wIGRvd24gY2hhbmdlcywgdGhleSBhcmUgc2F2ZWQgdG8gbW9kZWxcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNvbW1pdERyb3BEb3duVmFsdWUoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMuaW50ZXJNZWRpYXRlVmFsdWU7XHJcbiAgICAgICAgdGhpcy5kcm9wRG93bi5vblRvZ2dsZUNsaWNrKGV2ZW50LCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFBlcmZvcm1zIHZhbGlkYXRpb24gdGhhdCBpcyBpbnRlcm5hbCB0byB0aGlzIGNvbnRyb2xcclxuICAgICAqIEBwYXJhbSBjIFRoZSBmb3JtIGNvbnRyb2wgYXR0YWNoZWQgdG8gdGhpcyBpbnN0YW5jZVxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgdmFsaWRhdGUoYzogRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uQWxlcnRzIHtcclxuICAgICAgICBpZiAoIXRoaXMuZGlzcGxheVZhbHVlVmFsaWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgICAgIGludmFsaWREaXNwbGF5VmFsdWU6IHtcclxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiB0aGlzLnN0cmluZ3MuTXNmdFNtZVNoZWxsLkFuZ3VsYXIuRm9ybS5EYXRlLkludmFsaWREYXRlVGltZS5mb3JtYXQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIERhdGVUaW1lLmdldExvY2FsZURhdGVTdHJpbmdGb3JtYXQoR2xvYmFsaXphdGlvbi5sb2NhbGVJZC50b0xvd2VyQ2FzZSgpKSlcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVBc0RhdGVUaW1lKGMpIHx8IHN1cGVyLnZhbGlkYXRlKGMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyB0aGUgaWRCYWcgdXNlZCBieSB0aGlzIGNvbXBvbmVudCB0byBzdG9yZSB1bmlxdWUgZWxlbWVudCBpZHMuXHJcbiAgICAgKiBpZCB2YWx1ZXMgd2lsbCBiZSBhc3NpZ25lZCBiZSB0aGUgQHNlZSBCYXNlQ29tcG9uZW50IHN1cGVyIGNsYXNzLlxyXG4gICAgICovXHJcbiAgICBwcm90ZWN0ZWQgY3JlYXRlSWRCYWcoKTogTXNmdFNtZS5TdHJpbmdNYXA8c3RyaW5nPiB7XHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgZGV0YWlsc1NwYW46ICcnLFxyXG4gICAgICAgICAgICBkcm9wRG93bkNvbnRlbnQ6ICcnXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG4iLCI8c21lLWZvcm0tZmllbGQtbGF5b3V0IFtmb3JtRmllbGRdPVwidGhpc1wiPlxyXG4gIDxkaXYgY2xhc3M9XCJzbWUtYXJyYW5nZS1zdGFjay1oIHNtZS1mb2N1cy16b25lIHNtZS1mb3JtLWZpZWxkLWVkaXRvclwiPlxyXG4gICAgPHNtZS1kcm9wZG93biAjZHJvcERvd24gW2F1dG9Ub2dnbGVdPVwiZmFsc2VcIiBjbGFzcz1cInNtZS1jb21ib2JveFwiIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiIFthdXRvV2lkdGhdPVwidHJ1ZVwiXHJcbiAgICAgICh0b2dnbGVkKT1cIm9uRHJvcGRvd25Ub2dnbGVkKCRldmVudClcIj5cclxuICAgICAgPGRpdiAjZHJvcGRvd25IZWFkZXIgY2xhc3M9XCJzbWUtY29tYm9ib3gtaGVhZGVyIHNtZS1kcm9wZG93bi10b2dnbGVcIiAoa2V5ZG93bik9XCJvblRvZ2dsZUtleWRvd24oJGV2ZW50KVwiPlxyXG4gICAgICAgIDxpbnB1dCAjdGV4dElucHV0IHR5cGU9XCJ0ZXh0XCIgcm9sZT1cImNvbWJvYm94XCIgWyhuZ01vZGVsKV09XCJkaXNwbGF5VmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJjb21taXREaXNwbGF5VmFsdWUoKVwiXHJcbiAgICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImlkQmFnLmRyb3BEb3duQ29udGVudFwiIFthdHRyLmFyaWEtbGFiZWxdPVwibGFiZWxcIlxyXG4gICAgICAgICAgW2F0dHIuZGlzYWJsZWRdPVwibG9hZGluZ09yRGlzYWJsZWQgPyB0cnVlIDogbnVsbFwiXHJcbiAgICAgICAgICBbYXR0ci5hcmlhLW93bnNdPVwiaWRCYWcuZHJvcERvd25Db250ZW50XCIgW2F0dHIuYXJpYS1leHBhbmRlZF09XCJkcm9wRG93bi5pc09wZW5cIlxyXG4gICAgICAgICAgW2F0dHIuYXJpYS1hdXRvY29tcGxldGVdPVwiJ25vbmUnXCIgW2F0dHIuYXJpYS1yZXF1aXJlZF09XCJyZXF1aXJlZFwiIHNwZWxsY2hlY2s9XCJmYWxzZVwiIGF1dG9jYXBpdGFsaXplPVwib2ZmXCJcclxuICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiIC8+XHJcbiAgICAgICAgPGJ1dHRvbiAjZHJvcERvd25CdXR0b24gdHlwZT1cImJ1dHRvblwiIFthdHRyLmRpc2FibGVkXT1cImxvYWRpbmdPckRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIiB0YWJpbmRleD1cIi0xXCJcclxuICAgICAgICAgIHJvbGU9XCJwcmVzZW50YXRpb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIiBbYXR0ci5hcmlhLXByZXNzZWRdPVwiZHJvcERvd24uaXNPcGVuXCJcclxuICAgICAgICAgIFtjbGFzcy5zbWUtdG9nZ2xlZF09XCJkcm9wRG93bi5pc09wZW5cIiBjbGFzcz1cInNtZS1idXR0b24tdHJpZ2dlciBzbWUtYnV0dG9uLWF1dG8td2lkdGhcIlxyXG4gICAgICAgICAgKGNsaWNrKT1cImRyb3BEb3duLm9uVG9nZ2xlQ2xpY2soJGV2ZW50LCB0cnVlKVwiPlxyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJzbWUtaWNvbiBzbWUtaWNvbi1kYXRlVGltZTJcIj48L3NwYW4+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic21lLWRyb3Bkb3duLWNvbnRlbnQgc21lLWRyb3Bkb3duLWludGVyYWN0aW9uLWVuYWJsZWQgc21lLWZvY3VzLXRyYXBcIiBbaWRdPVwiaWRCYWcuZHJvcERvd25Db250ZW50XCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInNtZS1kYXRldGltZS1kcm9wZG93blwiPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNtZS1kYXRldGltZS1tYWluLWNvbnRlbnRcIj5cclxuICAgICAgICAgICAgPHNtZS1mb3JtLWZpZWxkICNjYWxlbmRhciB0eXBlPVwiY2FsZW5kYXJcIiBbbmdNb2RlbF09XCJpbnRlck1lZGlhdGVWYWx1ZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uTmdNb2RlbENoYW5nZSgkZXZlbnQsIHRydWUpXCJcclxuICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiIFtoaWRlSGVhZGVyXT1cInRydWVcIiBvcmllbnRhdGlvbj1cInZlcnRpY2FsXCI+XHJcbiAgICAgICAgICAgIDwvc21lLWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgIDxzbWUtZm9ybS1maWVsZCAjY2xvY2sgdHlwZT1cImNsb2NrXCIgW25nTW9kZWxdPVwiaW50ZXJNZWRpYXRlVmFsdWVcIiAobmdNb2RlbENoYW5nZSk9XCJvbk5nTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIiBbaGlkZUhlYWRlcl09XCJ0cnVlXCIgb3JpZW50YXRpb249XCJ2ZXJ0aWNhbFwiPlxyXG4gICAgICAgICAgICA8L3NtZS1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic21lLWRhdGV0aW1lLWNvbmZpcm1hdGlvblwiPlxyXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNtZS1mb2N1cy16b25lXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJ0aGlzLnN0cmluZ3MuTXNmdFNtZVNoZWxsLkFuZ3VsYXIuQ29tbW9uLmFwcGx5XCIgdGFiaW5kZXg9XCIwXCJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwiY29tbWl0RHJvcERvd25WYWx1ZSgkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzbWUtaWNvbiBzbWUtaWNvbi1zaXplLXh4cyBzbWUtaWNvbi1hY2NlcHRcIj48L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInNtZS1mb2N1cy16b25lXCIgW2F0dHIuYXJpYS1sYWJlbF09XCJ0aGlzLnN0cmluZ3MuTXNmdFNtZVNoZWxsLkFuZ3VsYXIuQ29tbW9uLmNsZWFyXCIgdGFiaW5kZXg9XCIwXCJcclxuICAgICAgICAgICAgICAoY2xpY2spPVwiZHJvcERvd24ub25Ub2dnbGVDbGljaygkZXZlbnQsIHRydWUpO1wiPlxyXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic21lLWljb24gc21lLWljb24tc2l6ZS14eHMgc21lLWljb24tY2xlYXJcIj48L3NwYW4+XHJcbiAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9zbWUtZHJvcGRvd24+XHJcbiAgPC9kaXY+XHJcbiAgPHNtZS12YWxpZGF0aW9uLWFsZXJ0IFthbGVydF09XCJhbGVydFwiPjwvc21lLXZhbGlkYXRpb24tYWxlcnQ+XHJcbjwvc21lLWZvcm0tZmllbGQtbGF5b3V0PlxyXG4iXX0=