UNPKG

@progress/telerik-angular-native-report-viewer

Version:

Progress® Telerik® Native Report Viewer for Angular

259 lines (251 loc) 35.8 kB
import { Component, Input, ViewChild } from '@angular/core'; import { DatePickerComponent } from '@progress/kendo-angular-dateinputs'; import { debounceTime } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "../reporting-angular-viewer.service"; import * as i2 from "@angular/common"; import * as i3 from "@progress/kendo-angular-dropdowns"; import * as i4 from "@progress/kendo-angular-inputs"; import * as i5 from "@progress/kendo-angular-buttons"; import * as i6 from "@progress/kendo-angular-dateinputs"; const SystemBooleanType = 'System.Boolean'; const SystemDateTimeType = 'System.DateTime'; export class ParametersSectionComponent { static isInvalidInput(parameter) { if (parameter.allowNull) { return false; } if (parameter.multivalue) { return parameter.value == null || parameter.value.length === 0; } return parameter.value == null; } constructor(service, cdr) { this.service = service; this.cdr = cdr; this.loading = true; this.parameter = { name: '', type: '', text: '', multivalue: false, allowNull: false, allowBlank: false, isVisible: false, autoRefresh: false, hasChildParameters: false, childParameters: [], availableValues: [], value: '', id: '', label: '' }; this.datepickerValue = new Date(); this.isInvalidInput = ParametersSectionComponent.isInvalidInput; } ngAfterViewInit() { this.datePicker?.valueChange.asObservable().pipe(debounceTime(this.parameter.autoRefresh ? 2000 : 0)).subscribe(value => { this.onValueChange(this.parameter, adjustTimezone(value)); }); const reportDateParam = this.service.parameters.find(p => p.type === SystemDateTimeType && p.id === this.parameter.id); this.datepickerValue = new Date(reportDateParam?.value); } onClearSelectionClick(param) { param.value = ''; } onSelectAllClick(parameter) { parameter.value = parameter.availableValues.map((val) => val.value); this.service.options.reportSource.parameters = JSON.parse(JSON.stringify(this.service.options.reportSource.parameters)); this.service.options.reportSource.parameters[parameter.id] = parameter.value; if (!parameter.autoRefresh || !this.service.controller.autoRunEnabled) return; this.service.applyParameter(parameter.id, parameter.value); } onValueChange(parameter, value) { //TODO: should be removed once the common viewer accepts lower case true/false values if (parameter.type === SystemBooleanType) { value = value.target.checked ? 'True' : 'False'; } parameter.value = value; this.service.options.reportSource.parameters = JSON.parse(JSON.stringify(this.service.options.reportSource.parameters)); // Can't check for all falsy values because 0 is falsy, won't work with integer parameters if (value === undefined || value === null || value.length === 0) { parameter.value = value = null; if (!parameter.allowNull) return; } if (parameter.childParameters?.length > 0) { parameter.childParameters.forEach((param) => { delete this.service.options.reportSource.parameters[param.toString()]; }); this.service.options.reportSource.parameters[parameter.id] = parameter.value; if (!parameter.autoRefresh || !this.service.controller.autoRunEnabled) return; this.service.controller.setParameters(this.service.options.reportSource.parameters); this.service.controller.refreshReport(true, ''); } else { this.service.options.reportSource.parameters[parameter.id] = value; if (!parameter.autoRefresh || !this.service.controller.autoRunEnabled) return; this.service.applyParameter(parameter.id, value); this.cdr.detectChanges(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ParametersSectionComponent, deps: [{ token: i1.ReportingAngularViewerService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ParametersSectionComponent, selector: "parameters-section", inputs: { loading: "loading", parameter: "parameter" }, viewQueries: [{ propertyName: "datePicker", first: true, predicate: DatePickerComponent, descendants: true }], ngImport: i0, template: ` <div *ngIf="parameter.isVisible" class="k-card trv-parameter-container"> <div class="k-card-header trv-parameter-header"> <div class="k-card-title trv-parameter-title" [title]="parameter.text">{{parameter.text}}</div> </div> <div class="k-card-body trv-parameter-value"> <div *ngIf="isInvalidInput(parameter)" class="k-notification k-notification-error trv-parameter-error"> <div class="k-notification-wrap"> <span class="k-icon k-i-warning"></span> <span class="k-notification-content trv-parameter-error-message">{{' ' + service.options.messages.ReportViewer_InvalidParameter}}</span> </div> </div> <div class="trv-parameter-editor-available-values"> <kendo-multiselect *ngIf="parameter.multivalue && parameter.availableValues" [data]="parameter.availableValues" [valuePrimitive]="true" textField="name" valueField="value" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" [kendoDropDownFilter]="{caseSensitive: false, operator: 'contains'}" > </kendo-multiselect> <kendo-combobox *ngIf="!parameter.multivalue && parameter.availableValues" [data]="parameter.availableValues" [valuePrimitive]="true" textField="name" valueField="value" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" > </kendo-combobox> <div *ngIf="parameter.availableValues" class="k-actions k-actions-end trv-parameter-actions"> <button kendoButton *ngIf="parameter.multivalue" fillMode="outline" class="trv-select-all" (click)="onSelectAllClick(parameter)">Select all</button> </div> <kendo-datepicker *ngIf="parameter.type === 'System.DateTime' && !parameter.availableValues" [value]="datepickerValue" [disabled]="loading" > </kendo-datepicker> <kendo-numerictextbox *ngIf="(parameter.type === 'System.Int64' || parameter.type ==='System.Double') && !parameter.availableValues" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" > </kendo-numerictextbox> <kendo-textbox *ngIf="parameter.type === 'System.String' && !parameter.availableValues" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" > </kendo-textbox> <input *ngIf="parameter.type === 'System.Boolean' && !parameter.availableValues" type="checkbox" kendoCheckBox [id]="parameter.id" [checked]="(parameter.value && parameter.value !== 'False') || parameter.value === 'True'" (change)="onValueChange(parameter, $event)" [disabled]="loading" /> </div> </div> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.FilterDirective, selector: "[kendoDropDownFilter]", inputs: ["data", "kendoDropDownFilter", "filterable"] }, { kind: "component", type: i4.NumericTextBoxComponent, selector: "kendo-numerictextbox", inputs: ["focusableId", "disabled", "readonly", "title", "autoCorrect", "format", "max", "min", "decimals", "placeholder", "step", "spinners", "rangeValidation", "tabindex", "tabIndex", "changeValueOnScroll", "selectOnFocus", "value", "maxlength", "size", "rounded", "fillMode", "inputAttributes"], outputs: ["valueChange", "focus", "blur", "inputFocus", "inputBlur"], exportAs: ["kendoNumericTextBox"] }, { kind: "component", type: i3.ComboBoxComponent, selector: "kendo-combobox", inputs: ["icon", "svgIcon", "inputAttributes", "showStickyHeader", "focusableId", "allowCustom", "data", "value", "textField", "valueField", "valuePrimitive", "valueNormalizer", "placeholder", "adaptiveMode", "title", "subtitle", "popupSettings", "listHeight", "loading", "suggest", "clearButton", "disabled", "itemDisabled", "readonly", "tabindex", "tabIndex", "filterable", "virtual", "size", "rounded", "fillMode"], outputs: ["valueChange", "selectionChange", "filterChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "escape"], exportAs: ["kendoComboBox"] }, { kind: "component", type: i3.MultiSelectComponent, selector: "kendo-multiselect", inputs: ["showStickyHeader", "focusableId", "autoClose", "loading", "data", "value", "valueField", "textField", "tabindex", "tabIndex", "size", "rounded", "fillMode", "placeholder", "adaptiveMode", "title", "subtitle", "disabled", "itemDisabled", "checkboxes", "readonly", "filterable", "virtual", "popupSettings", "listHeight", "valuePrimitive", "clearButton", "tagMapper", "allowCustom", "valueNormalizer", "inputAttributes"], outputs: ["filterChange", "valueChange", "open", "opened", "close", "closed", "focus", "blur", "inputFocus", "inputBlur", "removeTag"], exportAs: ["kendoMultiSelect"] }, { kind: "component", type: i5.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i6.DatePickerComponent, selector: "kendo-datepicker", inputs: ["focusableId", "cellTemplate", "clearButton", "inputAttributes", "monthCellTemplate", "yearCellTemplate", "decadeCellTemplate", "centuryCellTemplate", "weekNumberTemplate", "headerTitleTemplate", "headerTemplate", "footerTemplate", "footer", "navigationItemTemplate", "weekDaysFormat", "showOtherMonthDays", "activeView", "bottomView", "topView", "calendarType", "animateCalendarNavigation", "disabled", "readonly", "readOnlyInput", "popupSettings", "navigation", "min", "max", "incompleteDateValidation", "autoCorrectParts", "autoSwitchParts", "autoSwitchKeys", "enableMouseWheel", "allowCaretMode", "autoFill", "focusedDate", "value", "format", "twoDigitYearMax", "formatPlaceholder", "placeholder", "tabindex", "tabIndex", "disabledDates", "title", "subtitle", "rangeValidation", "disabledDatesValidation", "weekNumber", "size", "rounded", "fillMode", "adaptiveMode"], outputs: ["valueChange", "focus", "blur", "open", "close", "escape"], exportAs: ["kendo-datepicker"] }, { kind: "component", type: i4.TextBoxComponent, selector: "kendo-textbox", inputs: ["focusableId", "title", "type", "disabled", "readonly", "tabindex", "value", "selectOnFocus", "showSuccessIcon", "showErrorIcon", "clearButton", "successIcon", "successSvgIcon", "errorIcon", "errorSvgIcon", "clearButtonIcon", "clearButtonSvgIcon", "size", "rounded", "fillMode", "tabIndex", "placeholder", "maxlength", "inputAttributes"], outputs: ["valueChange", "inputFocus", "inputBlur", "focus", "blur"], exportAs: ["kendoTextBox"] }, { kind: "directive", type: i4.CheckBoxDirective, selector: "input[kendoCheckBox]", inputs: ["size", "rounded"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ParametersSectionComponent, decorators: [{ type: Component, args: [{ selector: 'parameters-section', template: ` <div *ngIf="parameter.isVisible" class="k-card trv-parameter-container"> <div class="k-card-header trv-parameter-header"> <div class="k-card-title trv-parameter-title" [title]="parameter.text">{{parameter.text}}</div> </div> <div class="k-card-body trv-parameter-value"> <div *ngIf="isInvalidInput(parameter)" class="k-notification k-notification-error trv-parameter-error"> <div class="k-notification-wrap"> <span class="k-icon k-i-warning"></span> <span class="k-notification-content trv-parameter-error-message">{{' ' + service.options.messages.ReportViewer_InvalidParameter}}</span> </div> </div> <div class="trv-parameter-editor-available-values"> <kendo-multiselect *ngIf="parameter.multivalue && parameter.availableValues" [data]="parameter.availableValues" [valuePrimitive]="true" textField="name" valueField="value" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" [kendoDropDownFilter]="{caseSensitive: false, operator: 'contains'}" > </kendo-multiselect> <kendo-combobox *ngIf="!parameter.multivalue && parameter.availableValues" [data]="parameter.availableValues" [valuePrimitive]="true" textField="name" valueField="value" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" > </kendo-combobox> <div *ngIf="parameter.availableValues" class="k-actions k-actions-end trv-parameter-actions"> <button kendoButton *ngIf="parameter.multivalue" fillMode="outline" class="trv-select-all" (click)="onSelectAllClick(parameter)">Select all</button> </div> <kendo-datepicker *ngIf="parameter.type === 'System.DateTime' && !parameter.availableValues" [value]="datepickerValue" [disabled]="loading" > </kendo-datepicker> <kendo-numerictextbox *ngIf="(parameter.type === 'System.Int64' || parameter.type ==='System.Double') && !parameter.availableValues" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" > </kendo-numerictextbox> <kendo-textbox *ngIf="parameter.type === 'System.String' && !parameter.availableValues" [value]="parameter.value" (valueChange)="onValueChange(parameter, $event)" [disabled]="loading" > </kendo-textbox> <input *ngIf="parameter.type === 'System.Boolean' && !parameter.availableValues" type="checkbox" kendoCheckBox [id]="parameter.id" [checked]="(parameter.value && parameter.value !== 'False') || parameter.value === 'True'" (change)="onValueChange(parameter, $event)" [disabled]="loading" /> </div> </div> </div> ` }] }], ctorParameters: function () { return [{ type: i1.ReportingAngularViewerService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { datePicker: [{ type: ViewChild, args: [DatePickerComponent] }], loading: [{ type: Input }], parameter: [{ type: Input }] } }); // TODO: This method is taken from HTML viewer export function adjustTimezone(date) { let result = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds())); return result; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVycy1zZWN0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcGFyYW1ldGVycy9wYXJhbWV0ZXJzLXNlY3Rpb24uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBRTlGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7O0FBR3BDLE1BQU0saUJBQWlCLEdBQUcsZ0JBQWdCLENBQUM7QUFDM0MsTUFBTSxrQkFBa0IsR0FBRyxpQkFBaUIsQ0FBQztBQTZFN0MsTUFBTSxPQUFPLDBCQUEwQjtJQXdCNUIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUF3QjtRQUNqRCxJQUFJLFNBQVMsQ0FBQyxTQUFTLEVBQUU7WUFDckIsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFFRCxJQUFJLFNBQVMsQ0FBQyxVQUFVLEVBQUU7WUFDdEIsT0FBTyxTQUFTLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7U0FDbEU7UUFFRCxPQUFPLFNBQVMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDO0lBQ25DLENBQUM7SUFFRCxZQUEwQixPQUFzQyxFQUFXLEdBQXNCO1FBQXZFLFlBQU8sR0FBUCxPQUFPLENBQStCO1FBQVcsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFqQ2pGLFlBQU8sR0FBRyxJQUFJLENBQUM7UUFDZixjQUFTLEdBQWtCO1lBQ3ZDLElBQUksRUFBRSxFQUFFO1lBQ1IsSUFBSSxFQUFFLEVBQUU7WUFDUixJQUFJLEVBQUUsRUFBRTtZQUNSLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLFNBQVMsRUFBRSxL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c0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBJbnB1dCwgVmlld0NoaWxkLCBDaGFuZ2VEZXRlY3RvclJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVwb3J0aW5nQW5ndWxhclZpZXdlclNlcnZpY2UgfSBmcm9tICcuLi9yZXBvcnRpbmctYW5ndWxhci12aWV3ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlUGlja2VyQ29tcG9uZW50IH0gZnJvbSAnQHByb2dyZXNzL2tlbmRvLWFuZ3VsYXItZGF0ZWlucHV0cyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFBhcmFtZXRlckluZm8sIFBhcmFtZXRlclZhbHVlIH0gZnJvbSAnQHByb2dyZXNzL3RlbGVyaWstY29tbW9uLXJlcG9ydC12aWV3ZXInO1xuXG5jb25zdCBTeXN0ZW1Cb29sZWFuVHlwZSA9ICdTeXN0ZW0uQm9vbGVhbic7XG5jb25zdCBTeXN0ZW1EYXRlVGltZVR5cGUgPSAnU3lzdGVtLkRhdGVUaW1lJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdwYXJhbWV0ZXJzLXNlY3Rpb24nLFxuICAgIHRlbXBsYXRlOiBgXG4gICAgICAgIDxkaXYgKm5nSWY9XCJwYXJhbWV0ZXIuaXNWaXNpYmxlXCIgY2xhc3M9XCJrLWNhcmQgdHJ2LXBhcmFtZXRlci1jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJrLWNhcmQtaGVhZGVyIHRydi1wYXJhbWV0ZXItaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImstY2FyZC10aXRsZSB0cnYtcGFyYW1ldGVyLXRpdGxlXCIgW3RpdGxlXT1cInBhcmFtZXRlci50ZXh0XCI+e3twYXJhbWV0ZXIudGV4dH19PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJrLWNhcmQtYm9keSB0cnYtcGFyYW1ldGVyLXZhbHVlXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzSW52YWxpZElucHV0KHBhcmFtZXRlcilcIiBjbGFzcz1cImstbm90aWZpY2F0aW9uIGstbm90aWZpY2F0aW9uLWVycm9yIHRydi1wYXJhbWV0ZXItZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImstbm90aWZpY2F0aW9uLXdyYXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiay1pY29uIGstaS13YXJuaW5nXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJrLW5vdGlmaWNhdGlvbi1jb250ZW50IHRydi1wYXJhbWV0ZXItZXJyb3ItbWVzc2FnZVwiPnt7JyAnICsgc2VydmljZS5vcHRpb25zLm1lc3NhZ2VzLlJlcG9ydFZpZXdlcl9JbnZhbGlkUGFyYW1ldGVyfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0cnYtcGFyYW1ldGVyLWVkaXRvci1hdmFpbGFibGUtdmFsdWVzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxrZW5kby1tdWx0aXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwYXJhbWV0ZXIubXVsdGl2YWx1ZSAmJiBwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhXT1cInBhcmFtZXRlci5hdmFpbGFibGVWYWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlUHJpbWl0aXZlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dEZpZWxkPVwibmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZUZpZWxkPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInBhcmFtZXRlci52YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwib25WYWx1ZUNoYW5nZShwYXJhbWV0ZXIsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImxvYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2tlbmRvRHJvcERvd25GaWx0ZXJdPVwie2Nhc2VTZW5zaXRpdmU6IGZhbHNlLCBvcGVyYXRvcjogJ2NvbnRhaW5zJ31cIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8L2tlbmRvLW11bHRpc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8a2VuZG8tY29tYm9ib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXBhcmFtZXRlci5tdWx0aXZhbHVlICYmIHBhcmFtZXRlci5hdmFpbGFibGVWYWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGFdPVwicGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVQcmltaXRpdmVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0RmllbGQ9XCJuYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlRmllbGQ9XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGFyYW1ldGVyLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKHBhcmFtZXRlciwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwva2VuZG8tY29tYm9ib3g+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCIgY2xhc3M9XCJrLWFjdGlvbnMgay1hY3Rpb25zLWVuZCB0cnYtcGFyYW1ldGVyLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24ga2VuZG9CdXR0b24gKm5nSWY9XCJwYXJhbWV0ZXIubXVsdGl2YWx1ZVwiIGZpbGxNb2RlPVwib3V0bGluZVwiIGNsYXNzPVwidHJ2LXNlbGVjdC1hbGxcIiAoY2xpY2spPVwib25TZWxlY3RBbGxDbGljayhwYXJhbWV0ZXIpXCI+U2VsZWN0IGFsbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8a2VuZG8tZGF0ZXBpY2tlciAqbmdJZj1cInBhcmFtZXRlci50eXBlID09PSAnU3lzdGVtLkRhdGVUaW1lJyAmJiAhcGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwiZGF0ZXBpY2tlclZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9rZW5kby1kYXRlcGlja2VyPlxuXG4gICAgICAgICAgICAgICAgICAgIDxrZW5kby1udW1lcmljdGV4dGJveCAqbmdJZj1cIihwYXJhbWV0ZXIudHlwZSA9PT0gJ1N5c3RlbS5JbnQ2NCcgfHwgcGFyYW1ldGVyLnR5cGUgPT09J1N5c3RlbS5Eb3VibGUnKSAmJiAhcGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwicGFyYW1ldGVyLnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvblZhbHVlQ2hhbmdlKHBhcmFtZXRlciwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibG9hZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwva2VuZG8tbnVtZXJpY3RleHRib3g+XG5cbiAgICAgICAgICAgICAgICAgICAgPGtlbmRvLXRleHRib3ggKm5nSWY9XCJwYXJhbWV0ZXIudHlwZSA9PT0gJ1N5c3RlbS5TdHJpbmcnICYmICFwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJwYXJhbWV0ZXIudmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHZhbHVlQ2hhbmdlKT1cIm9uVmFsdWVDaGFuZ2UocGFyYW1ldGVyLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9rZW5kby10ZXh0Ym94PlxuXG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cInBhcmFtZXRlci50eXBlID09PSAnU3lzdGVtLkJvb2xlYW4nICYmICFwYXJhbWV0ZXIuYXZhaWxhYmxlVmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBrZW5kb0NoZWNrQm94XG4gICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwicGFyYW1ldGVyLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cIihwYXJhbWV0ZXIudmFsdWUgJiYgcGFyYW1ldGVyLnZhbHVlICE9PSAnRmFsc2UnKSB8fCBwYXJhbWV0ZXIudmFsdWUgPT09ICdUcnVlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uVmFsdWVDaGFuZ2UocGFyYW1ldGVyLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJsb2FkaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgYFxufSlcbmV4cG9ydCBjbGFzcyBQYXJhbWV0ZXJzU2VjdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAgIEBWaWV3Q2hpbGQoRGF0ZVBpY2tlckNvbXBvbmVudCkgcHVibGljIGRhdGVQaWNrZXI6IERhdGVQaWNrZXJDb21wb25lbnQ7XG5cbiAgICBASW5wdXQoKSBwdWJsaWMgbG9hZGluZyA9IHRydWU7XG4gICAgQElucHV0KCkgcHVibGljIHBhcmFtZXRlcjogUGFyYW1ldGVySW5mbyA9IHtcbiAgICAgICAgbmFtZTogJycsXG4gICAgICAgIHR5cGU6ICcnLFxuICAgICAgICB0ZXh0OiAnJyxcbiAgICAgICAgbXVsdGl2YWx1ZTogZmFsc2UsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsIFxuICAgICAgICBhbGxvd0JsYW5rOiBmYWxzZSxcbiAgICAgICAgaXNWaXNpYmxlOiBmYWxzZSwgXG4gICAgICAgIGF1dG9SZWZyZXNoOiBmYWxzZSxcbiAgICAgICAgaGFzQ2hpbGRQYXJhbWV0ZXJzOiBmYWxzZSxcbiAgICAgICAgY2hpbGRQYXJhbWV0ZXJzOiBbXSxcbiAgICAgICAgYXZhaWxhYmxlVmFsdWVzOiBbXSxcbiAgICAgICAgdmFsdWU6ICcnLFxuICAgICAgICBpZDogJycsXG4gICAgICAgIGxhYmVsOiAnJ1xuICAgIH07XG5cbiAgICBwdWJsaWMgZGF0ZXBpY2tlclZhbHVlOiBEYXRlID0gbmV3IERhdGUoKTtcbiAgICBpc0ludmFsaWRJbnB1dCA9IFBhcmFtZXRlcnNTZWN0aW9uQ29tcG9uZW50LmlzSW52YWxpZElucHV0XG5cbiAgICBwdWJsaWMgc3RhdGljIGlzSW52YWxpZElucHV0KHBhcmFtZXRlcjogUGFyYW1ldGVySW5mbyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAocGFyYW1ldGVyLmFsbG93TnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhcmFtZXRlci5tdWx0aXZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyYW1ldGVyLnZhbHVlID09IG51bGwgfHwgcGFyYW1ldGVyLnZhbHVlLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJhbWV0ZXIudmFsdWUgPT0gbnVsbDtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHNlcnZpY2U6IFJlcG9ydGluZ0FuZ3VsYXJWaWV3ZXJTZXJ2aWNlLCAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gICAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kYXRlUGlja2VyPy52YWx1ZUNoYW5nZS5hc09ic2VydmFibGUoKS5waXBlKGRlYm91bmNlVGltZSh0aGlzLnBhcmFtZXRlci5hdXRvUmVmcmVzaCA/IDIwMDAgOiAwKSkuc3Vic2NyaWJlKHZhbHVlID0+IHtcbiAgICAgICAgICAgIHRoaXMub25WYWx1ZUNoYW5nZSh0aGlzLnBhcmFtZXRlciwgYWRqdXN0VGltZXpvbmUodmFsdWUpKTtcbiAgICAgICAgfSk7XG4gICAgICAgICAgICBcbiAgICAgICAgY29uc3QgcmVwb3J0RGF0ZVBhcmFtOiBQYXJhbWV0ZXJJbmZvID0gPFBhcmFtZXRlckluZm8+dGhpcy5zZXJ2aWNlLnBhcmFtZXRlcnMuZmluZChwID0+IHAudHlwZSA9PT0gU3lzdGVtRGF0ZVRpbWVUeXBlICYmIHAuaWQgPT09IHRoaXMucGFyYW1ldGVyLmlkKTtcbiAgICAgICAgdGhpcy5kYXRlcGlja2VyVmFsdWUgPSBuZXcgRGF0ZSg8c3RyaW5nPnJlcG9ydERhdGVQYXJhbT8udmFsdWUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbkNsZWFyU2VsZWN0aW9uQ2xpY2socGFyYW06IFBhcmFtZXRlckluZm8pOiB2b2lkIHtcbiAgICAgICAgcGFyYW0udmFsdWUgPSAnJztcbiAgICB9XG5cbiAgICBwdWJsaWMgb25TZWxlY3RBbGxDbGljayhwYXJhbWV0ZXI6IFBhcmFtZXRlckluZm8pOiB2b2lkIHtcbiAgICAgICAgcGFyYW1ldGVyLnZhbHVlID0gcGFyYW1ldGVyLmF2YWlsYWJsZVZhbHVlcy5tYXAoKHZhbDogUGFyYW1ldGVyVmFsdWUpID0+IHZhbC52YWx1ZSk7XG5cbiAgICAgICAgdGhpcy5zZXJ2aWNlLm9wdGlvbnMucmVwb3J0U291cmNlLnBhcmFtZXRlcnMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuc2VydmljZS5vcHRpb25zLnJlcG9ydFNvdXJjZS5wYXJhbWV0ZXJzKSk7XG4gICAgICAgIHRoaXMuc2VydmljZS5vcHRpb25zLnJlcG9ydFNvdXJjZS5wYXJhbWV0ZXJzW3BhcmFtZXRlci5pZF0gPSBwYXJhbWV0ZXIudmFsdWU7XG5cbiAgICAgICAgaWYgKCFwYXJhbWV0ZXIuYXV0b1JlZnJlc2ggfHwgIXRoaXMuc2VydmljZS5jb250cm9sbGVyLmF1dG9SdW5FbmFibGVkKSByZXR1cm47XG5cbiAgICAgICAgdGhpcy5zZXJ2aWNlLmFwcGx5UGFyYW1ldGVyKHBhcmFtZXRlci5pZCwgcGFyYW1ldGVyLnZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgb25WYWx1ZUNoYW5nZShwYXJhbWV0ZXI6IFBhcmFtZXRlckluZm8sIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgLy9UT0RPOiBzaG91bGQgYmUgcmVtb3ZlZCBvbmNlIHRoZSBjb21tb24gdmlld2VyIGFjY2VwdHMgbG93ZXIgY2FzZSB0cnVlL2ZhbHNlIHZhbHVlc1xuICAgICAgICBpZiAocGFyYW1ldGVyLnR5cGUgPT09IFN5c3RlbUJvb2xlYW5UeXBlKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRhcmdldC5jaGVja2VkID8gJ1RydWUnIDogJ0ZhbHNlJztcbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtZXRlci52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVycyA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5zZXJ2aWNlLm9wdGlvbnMucmVwb3J0U291cmNlLnBhcmFtZXRlcnMpKTtcblxuICAgICAgICAvLyBDYW4ndCBjaGVjayBmb3IgYWxsIGZhbHN5IHZhbHVlcyBiZWNhdXNlIDAgaXMgZmFsc3ksIHdvbid0IHdvcmsgd2l0aCBpbnRlZ2VyIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUubGVuZ3RoID09PSAwKXtcbiAgICAgICAgICAgIHBhcmFtZXRlci52YWx1ZSA9IHZhbHVlID0gbnVsbDtcblxuICAgICAgICAgICAgaWYoIXBhcmFtZXRlci5hbGxvd051bGwpIHJldHVybjtcbiAgICAgICAgfSBcblxuICAgICAgICBpZiAocGFyYW1ldGVyLmNoaWxkUGFyYW1ldGVycz8ubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgcGFyYW1ldGVyLmNoaWxkUGFyYW1ldGVycy5mb3JFYWNoKChwYXJhbTogUGFyYW1ldGVySW5mbykgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVyc1twYXJhbS50b1N0cmluZygpXTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVyc1twYXJhbWV0ZXIuaWRdID0gcGFyYW1ldGVyLnZhbHVlO1xuXG4gICAgICAgICAgICBpZiAoIXBhcmFtZXRlci5hdXRvUmVmcmVzaCB8fCAhdGhpcy5zZXJ2aWNlLmNvbnRyb2xsZXIuYXV0b1J1bkVuYWJsZWQpIHJldHVybjtcblxuICAgICAgICAgICAgdGhpcy5zZXJ2aWNlLmNvbnRyb2xsZXIuc2V0UGFyYW1ldGVycyh0aGlzLnNlcnZpY2Uub3B0aW9ucy5yZXBvcnRTb3VyY2UucGFyYW1ldGVycyk7XG4gICAgICAgICAgICB0aGlzLnNlcnZpY2UuY29udHJvbGxlci5yZWZyZXNoUmVwb3J0KHRydWUsICcnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5vcHRpb25zLnJlcG9ydFNvdXJjZS5wYXJhbWV0ZXJzW3BhcmFtZXRlci5pZF0gPSB2YWx1ZTtcblxuICAgICAgICAgICAgaWYgKCFwYXJhbWV0ZXIuYXV0b1JlZnJlc2ggfHwgIXRoaXMuc2VydmljZS5jb250cm9sbGVyLmF1dG9SdW5FbmFibGVkKSByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMuc2VydmljZS5hcHBseVBhcmFtZXRlcihwYXJhbWV0ZXIuaWQsIHZhbHVlKTtcblxuICAgICAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyBUT0RPOiBUaGlzIG1ldGhvZCBpcyB0YWtlbiBmcm9tIEhUTUwgdmlld2VyXG5leHBvcnQgZnVuY3Rpb24gYWRqdXN0VGltZXpvbmUoZGF0ZTogRGF0ZSkge1xuICAgIGxldCByZXN1bHQgPSBuZXcgRGF0ZShcbiAgICAgICAgRGF0ZS5VVEMoXG4gICAgICAgICAgICBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICAgICAgICBkYXRlLmdldE1vbnRoKCksXG4gICAgICAgICAgICBkYXRlLmdldERhdGUoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgIGRhdGUuZ2V0TWludXRlcygpLFxuICAgICAgICAgICAgZGF0ZS5nZXRTZWNvbmRzKCksXG4gICAgICAgICAgICBkYXRlLmdldE1pbGxpc2Vjb25kcygpXG4gICAgICAgIClcbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG4iXX0=