stimulsoft-forms
Version:
Stimulsoft PDF Forms
446 lines • 42.6 kB
JavaScript
import { Component, Input, ViewChild } from "@angular/core";
import StiRectangleGeometryLayout from "../computed/StiRectangleGeometryLayout";
import { StiDragPreviewElement } from "../elements/StiDragPreviewElement";
import { StiBorderArea } from "../properties/StiBorderArea";
import { StiLabelAlignment } from "../system/enums";
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "./sti-text-box/sti-text-box.component";
import * as i3 from "./sti-number-box/sti-number-box.component";
import * as i4 from "./sti-combo-box/sti-combo-box.component";
import * as i5 from "./sti-list-box/sti-list-box.component";
import * as i6 from "./sti-single-selection/sti-single-selection.component";
import * as i7 from "./sti-multiple-selection/sti-multiple-selection.component";
import * as i8 from "./sti-check-box/sti-check-box.component";
import * as i9 from "./sti-line/sti-line.component";
import * as i10 from "./sti-signature/sti-signature.component";
import * as i11 from "./sti-date-time-box/sti-date-time-box.component";
import * as i12 from "./sti-table/sti-table.component";
import * as i13 from "./sti-image/sti-image.component";
import * as i14 from "./sti-button/sti-button.component";
import * as i15 from "./sti-barcode/sti-barcode.component";
import * as i16 from "./sti-text/sti-text.component";
import * as i17 from "./sti-drag-preview-adorner/sti-drag-preview-adorner.component";
import * as i18 from "./sti-label/sti-label.component";
import * as i19 from "./sti-address/sti-address.component";
import * as i20 from "./sti-pdf-signature/sti-pdf-signature.component";
import * as i21 from "../services/model.service";
import * as i22 from "./sti-component";
import * as i23 from "./sti-editable-content.component";
export class StiComponentHolderComponent {
constructor() {
this.isClone = false;
}
ngOnInit() { }
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiComponentHolderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: StiComponentHolderComponent, selector: "sti-component-holder", inputs: { element: "element", isClone: "isClone" }, ngImport: i0, template: `
<ng-container *ngIf="element != null">
<sti-address-component
[element]="element"
*ngIf="element.type === 'AddressElement'"
[isClone]="isClone"
></sti-address-component>
<sti-textbox-component
[element]="element"
*ngIf="element.type === 'Text_BoxElement'"
[isClone]="isClone"
></sti-textbox-component>
<sti-text-component
[element]="element"
*ngIf="element.type === 'TextElement'"
[isClone]="isClone"
></sti-text-component>
<sti-table-component
[element]="element"
*ngIf="element.type === 'TableElement'"
[isClone]="isClone"
></sti-table-component>
<sti-singleselection-component
[element]="element"
*ngIf="element.type === 'Single_SelectionElement'"
[isClone]="isClone"
></sti-singleselection-component>
<sti-signature-component [element]="element" *ngIf="element.type === 'SignatureElement'" [isClone]="isClone">
</sti-signature-component>
<sti-pdf-signature-component
[element]="element"
*ngIf="element.type === 'PDFSignatureElement'"
[isClone]="isClone"
></sti-pdf-signature-component>
<sti-panel-component
[element]="element"
*ngIf="element.type === 'PanelElement'"
[isClone]="isClone"
></sti-panel-component>
<sti-numberbox-component
[element]="element"
*ngIf="element.type === 'Number_BoxElement'"
[isClone]="isClone"
></sti-numberbox-component>
<sti-multipleselection-component
[element]="element"
*ngIf="element.type === 'Multiple_SelectionElement'"
[isClone]="isClone"
></sti-multipleselection-component>
<sti-listbox-component
[element]="element"
*ngIf="element.type === 'List_BoxElement'"
[isClone]="isClone"
></sti-listbox-component>
<sti-label-component
[element]="element"
*ngIf="element.type === 'LabelElement'"
[isClone]="isClone"
></sti-label-component>
<sti-image-component
[element]="element"
*ngIf="element.type === 'ImageElement'"
[isClone]="isClone"
></sti-image-component>
<sti-drag-preview-adorner [element]="element" *ngIf="element.type === 'Drag_Preview'"></sti-drag-preview-adorner>
<sti-line-component
[element]="element"
*ngIf="element.type === 'LineElement'"
[isClone]="isClone"
></sti-line-component>
<sti-datetimebox-component
[element]="element"
*ngIf="element.type === 'DateTime_BoxElement'"
[isClone]="isClone"
></sti-datetimebox-component>
<sti-combobox-component
[element]="element"
*ngIf="element.type === 'Combo_BoxElement'"
[isClone]="isClone"
></sti-combobox-component>
<sti-checkbox-component
[element]="element"
*ngIf="element.type === 'Check_BoxElement'"
[isClone]="isClone"
></sti-checkbox-component>
<sti-button-component
[element]="element"
*ngIf="element.type === 'ButtonElement'"
[isClone]="isClone"
></sti-button-component>
<sti-barcode-component
[element]="element"
*ngIf="element.type === 'BarCodeElement'"
[isClone]="isClone"
></sti-barcode-component>
</ng-container>
`, isInline: true, dependencies: [{ kind: "directive", type: i0.forwardRef(() => i1.NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i0.forwardRef(() => i2.StiTextBoxComponent), selector: "sti-textbox-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i3.StiNumberBoxComponent), selector: "sti-numberbox-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i4.StiComboBoxComponent), selector: "sti-combobox-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i5.StiListBoxComponent), selector: "sti-listbox-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i6.StiSingleSelectionComponent), selector: "sti-singleselection-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i7.StiMultipleSelectionComponent), selector: "sti-multipleselection-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i8.StiCheckBoxComponent), selector: "sti-checkbox-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i9.StiLineComponent), selector: "sti-line-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i10.StiSignatureComponent), selector: "sti-signature-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => StiPanelComponent), selector: "sti-panel-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i11.StiDateTimeBoxComponent), selector: "sti-datetimebox-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i12.StiTableComponent), selector: "sti-table-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i13.StiImageComponent), selector: "sti-image-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i14.StiButtonComponent), selector: "sti-button-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i15.StiBarcodeComponent), selector: "sti-barcode-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i16.StiTextComponent), selector: "sti-text-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i17.StiDragPreviewAdornerComponent), selector: "sti-drag-preview-adorner", inputs: ["element"] }, { kind: "component", type: i0.forwardRef(() => i18.StiLabelComponent), selector: "sti-label-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i19.StiAddressComponent), selector: "sti-address-component", inputs: ["element", "isClone"] }, { kind: "component", type: i0.forwardRef(() => i20.StiPDFSignatureComponent), selector: "sti-pdf-signature-component", inputs: ["element", "isClone"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiComponentHolderComponent, decorators: [{
type: Component,
args: [{
selector: "sti-component-holder",
template: `
<ng-container *ngIf="element != null">
<sti-address-component
[element]="element"
*ngIf="element.type === 'AddressElement'"
[isClone]="isClone"
></sti-address-component>
<sti-textbox-component
[element]="element"
*ngIf="element.type === 'Text_BoxElement'"
[isClone]="isClone"
></sti-textbox-component>
<sti-text-component
[element]="element"
*ngIf="element.type === 'TextElement'"
[isClone]="isClone"
></sti-text-component>
<sti-table-component
[element]="element"
*ngIf="element.type === 'TableElement'"
[isClone]="isClone"
></sti-table-component>
<sti-singleselection-component
[element]="element"
*ngIf="element.type === 'Single_SelectionElement'"
[isClone]="isClone"
></sti-singleselection-component>
<sti-signature-component [element]="element" *ngIf="element.type === 'SignatureElement'" [isClone]="isClone">
</sti-signature-component>
<sti-pdf-signature-component
[element]="element"
*ngIf="element.type === 'PDFSignatureElement'"
[isClone]="isClone"
></sti-pdf-signature-component>
<sti-panel-component
[element]="element"
*ngIf="element.type === 'PanelElement'"
[isClone]="isClone"
></sti-panel-component>
<sti-numberbox-component
[element]="element"
*ngIf="element.type === 'Number_BoxElement'"
[isClone]="isClone"
></sti-numberbox-component>
<sti-multipleselection-component
[element]="element"
*ngIf="element.type === 'Multiple_SelectionElement'"
[isClone]="isClone"
></sti-multipleselection-component>
<sti-listbox-component
[element]="element"
*ngIf="element.type === 'List_BoxElement'"
[isClone]="isClone"
></sti-listbox-component>
<sti-label-component
[element]="element"
*ngIf="element.type === 'LabelElement'"
[isClone]="isClone"
></sti-label-component>
<sti-image-component
[element]="element"
*ngIf="element.type === 'ImageElement'"
[isClone]="isClone"
></sti-image-component>
<sti-drag-preview-adorner [element]="element" *ngIf="element.type === 'Drag_Preview'"></sti-drag-preview-adorner>
<sti-line-component
[element]="element"
*ngIf="element.type === 'LineElement'"
[isClone]="isClone"
></sti-line-component>
<sti-datetimebox-component
[element]="element"
*ngIf="element.type === 'DateTime_BoxElement'"
[isClone]="isClone"
></sti-datetimebox-component>
<sti-combobox-component
[element]="element"
*ngIf="element.type === 'Combo_BoxElement'"
[isClone]="isClone"
></sti-combobox-component>
<sti-checkbox-component
[element]="element"
*ngIf="element.type === 'Check_BoxElement'"
[isClone]="isClone"
></sti-checkbox-component>
<sti-button-component
[element]="element"
*ngIf="element.type === 'ButtonElement'"
[isClone]="isClone"
></sti-button-component>
<sti-barcode-component
[element]="element"
*ngIf="element.type === 'BarCodeElement'"
[isClone]="isClone"
></sti-barcode-component>
</ng-container>
`,
}]
}], ctorParameters: () => [], propDecorators: { element: [{
type: Input
}], isClone: [{
type: Input
}] } });
//==========================================================
export class StiPanelComponent {
get elements() {
return this.element?.elements;
}
get borderArea() {
if (!this.isClone) {
let borderArea = new StiBorderArea();
borderArea.top =
this.ref?.nativeElement?.offsetTop -
(this.element.label.alignment != StiLabelAlignment.Top ? this.element.padding.top : 0);
borderArea.left = this.ref?.nativeElement?.offsetLeft;
borderArea.width = this.ref?.nativeElement?.offsetWidth - this.element.padding.left - this.element.padding.right;
borderArea.height = this.ref?.nativeElement?.offsetHeight;
borderArea.border = this.element.border;
return borderArea;
}
}
get align() {
return "start";
}
get minWidth() {
if (this.elements?.length > 0) {
let minWidth = this.elements[0]?.x + this.elements[0]?.width;
this.elements.forEach((element) => {
if (minWidth < element.x + element.width) {
minWidth = element.x + element.width;
}
});
return minWidth;
}
return "min-content";
}
get minHeight() {
if (!this.model.draggingElement) {
if (this.elements?.length > 0) {
let maxBottomPoint = 0;
this.elements?.forEach((element) => {
if (!(element instanceof StiDragPreviewElement) && element.geometry.bottom > maxBottomPoint) {
maxBottomPoint = element.geometry.bottom;
}
});
if (this.currentBottomPoint != maxBottomPoint) {
this.render.insertElement(this.element);
this.render.checkOutputs(this.model.getElementPage(this.element));
this.currentBottomPoint = maxBottomPoint;
}
return maxBottomPoint > 0 ? maxBottomPoint : 5;
}
else {
return 5;
}
}
}
constructor(model, render) {
this.model = model;
this.render = render;
this.isClone = false;
}
ngAfterViewInit() {
if (!this.isClone) {
this.element.element = this.ref;
}
}
ngOnInit() { }
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiPanelComponent, deps: [{ token: i21.StiModelService }, { token: StiRectangleGeometryLayout }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: StiPanelComponent, selector: "sti-panel-component", inputs: { element: "element", isClone: "isClone" }, viewQueries: [{ propertyName: "ref", first: true, predicate: ["ref"], descendants: true }], ngImport: i0, template: ` <sti-component [element]="element" [borderArea]="borderArea" [isClone]="isClone" class="sti-panel">
<sti-editable-content-component
*ngIf="element?.label.value?.length > 0 && element?.isLabelTopAlignment()"
[editableContent]="element.label"
[style.text-align]="element?.getContentAlign()"
[style.align-self]="align"
[hideEmpty]="element.showLabelPlaceholder(model?.selectedComponent?.element == element)"
[style.width]="element?.getLabelWidth()"
></sti-editable-content-component>
<table [style.width]="'100%'" [style.height]="'100%'" [style.margin-top.px]="element?.getTopMargin()">
<tr>
<td
*ngIf="element?.label.value?.length > 0 && !element?.isLabelTopAlignment()"
[style.display]="'flex'"
[style.height]="'100%'"
[style.width]="element?.getLabelWidth()"
[style.align-items]="element?.getVerticalAlignment()"
>
<sti-editable-content-component
*ngIf="element?.label.value?.length > 0"
[editableContent]="element?.label"
[required]="element.required"
[style.text-align]="element?.getContentAlign()"
[style.width]="element?.getLabelWidth()"
[hideEmpty]="element?.showLabelPlaceholder(model?.selectedComponent?.element == element)"
></sti-editable-content-component>
</td>
<td [style.width]="'100%'" [style.height]="'100%'">
<div
#ref
class="sti-panel-container"
[style.height]="'100%'"
[style.min-width.px]="minWidth"
[style.min-height.px]="minHeight"
[style.align-self]="'center'"
[style.overflow]="'hidden'"
[style.background-color]="
(!element.isAdded &&
element.backgroundColor.r == 255 &&
element.backgroundColor.g == 255 &&
element.backgroundColor.b == 255) ||
element.backgroundColor.a == 0
? 'transparent'
: element?.backgroundColor.toHtmlColor()
"
>
<div *ngFor="let element of elements" [disabled]="element?.readOnly ? true : false">
<sti-component-holder [element]="element"></sti-component-holder>
</div>
</div>
</td>
</tr>
<tr *ngIf="element?.description.value?.length > 0">
<td *ngIf="element?.label.value?.length > 0 && !element?.isLabelTopAlignment()"></td>
<td [style.maxWidth.px]="element.maxWidth + 1">
<sti-editable-content-component
*ngIf="element?.description.value?.length > 0"
[editableContent]="element.description"
>
</sti-editable-content-component>
</td>
</tr>
</table>
</sti-component>`, isInline: true, styles: ["table{border-spacing:0}tr{height:max-content;padding:0;margin:0}td{height:100%;padding:0;margin:0}.sti-panel-container{min-height:5px;position:relative}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i22.StiComponent, selector: "sti-component", inputs: ["element", "class", "isClone", "borderArea"] }, { kind: "component", type: StiComponentHolderComponent, selector: "sti-component-holder", inputs: ["element", "isClone"] }, { kind: "component", type: i23.StiEditableContentComponent, selector: "sti-editable-content-component", inputs: ["editableContent", "displayContent", "required", "eParent", "hideEmpty", "active", "alignment", "isTableTotalHeader", "disablePadding", "fromButton", "parentCursor", "isTableHeader"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiPanelComponent, decorators: [{
type: Component,
args: [{ selector: "sti-panel-component", template: ` <sti-component [element]="element" [borderArea]="borderArea" [isClone]="isClone" class="sti-panel">
<sti-editable-content-component
*ngIf="element?.label.value?.length > 0 && element?.isLabelTopAlignment()"
[editableContent]="element.label"
[style.text-align]="element?.getContentAlign()"
[style.align-self]="align"
[hideEmpty]="element.showLabelPlaceholder(model?.selectedComponent?.element == element)"
[style.width]="element?.getLabelWidth()"
></sti-editable-content-component>
<table [style.width]="'100%'" [style.height]="'100%'" [style.margin-top.px]="element?.getTopMargin()">
<tr>
<td
*ngIf="element?.label.value?.length > 0 && !element?.isLabelTopAlignment()"
[style.display]="'flex'"
[style.height]="'100%'"
[style.width]="element?.getLabelWidth()"
[style.align-items]="element?.getVerticalAlignment()"
>
<sti-editable-content-component
*ngIf="element?.label.value?.length > 0"
[editableContent]="element?.label"
[required]="element.required"
[style.text-align]="element?.getContentAlign()"
[style.width]="element?.getLabelWidth()"
[hideEmpty]="element?.showLabelPlaceholder(model?.selectedComponent?.element == element)"
></sti-editable-content-component>
</td>
<td [style.width]="'100%'" [style.height]="'100%'">
<div
#ref
class="sti-panel-container"
[style.height]="'100%'"
[style.min-width.px]="minWidth"
[style.min-height.px]="minHeight"
[style.align-self]="'center'"
[style.overflow]="'hidden'"
[style.background-color]="
(!element.isAdded &&
element.backgroundColor.r == 255 &&
element.backgroundColor.g == 255 &&
element.backgroundColor.b == 255) ||
element.backgroundColor.a == 0
? 'transparent'
: element?.backgroundColor.toHtmlColor()
"
>
<div *ngFor="let element of elements" [disabled]="element?.readOnly ? true : false">
<sti-component-holder [element]="element"></sti-component-holder>
</div>
</div>
</td>
</tr>
<tr *ngIf="element?.description.value?.length > 0">
<td *ngIf="element?.label.value?.length > 0 && !element?.isLabelTopAlignment()"></td>
<td [style.maxWidth.px]="element.maxWidth + 1">
<sti-editable-content-component
*ngIf="element?.description.value?.length > 0"
[editableContent]="element.description"
>
</sti-editable-content-component>
</td>
</tr>
</table>
</sti-component>`, styles: ["table{border-spacing:0}tr{height:max-content;padding:0;margin:0}td{height:100%;padding:0;margin:0}.sti-panel-container{min-height:5px;position:relative}\n"] }]
}], ctorParameters: () => [{ type: i21.StiModelService }, { type: StiRectangleGeometryLayout }], propDecorators: { ref: [{
type: ViewChild,
args: ["ref"]
}], element: [{
type: Input
}], isClone: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RpLWNvbXBvbmVudHMtaG9sZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0aW11bHNvZnQtZm9ybXMvc3JjL2xpYi9jb21wb25lbnRzL3N0aS1jb21wb25lbnRzLWhvbGRlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixTQUFTLEVBQWMsS0FBSyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLDBCQUEwQixNQUFNLHdDQUF3QyxDQUFDO0FBRWhGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRTFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUU1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXNHcEQsTUFBTSxPQUFPLDJCQUEyQjtJQUl0QztRQUZTLFlBQU8sR0FBWSxLQUFLLENBQUM7SUFFbkIsQ0FBQztJQUVoQixRQUFRLEtBQUksQ0FBQzsrR0FORiwyQkFBMkI7bUdBQTNCLDJCQUEyQixnSEFsRzVCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnR1QseStDQW1HVSxpQkFBaUI7OzRGQWpHakIsMkJBQTJCO2tCQXBHdkMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsc0JBQXNCO29CQUNoQyxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdHVDtpQkFDRjt3REFFVSxPQUFPO3NCQUFmLEtBQUs7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O3NCQUFmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIElucHV0LCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCBTdGlSZWN0YW5nbGVHZW9tZXRyeUxheW91dCBmcm9tIFwiLi4vY29tcHV0ZWQvU3RpUmVjdGFuZ2xlR2VvbWV0cnlMYXlvdXRcIjtcclxuaW1wb3J0IHsgU3RpRm9ybUVsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudHMvYmFzZS9TdGlGb3JtRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlEcmFnUHJldmlld0VsZW1lbnQgfSBmcm9tIFwiLi4vZWxlbWVudHMvU3RpRHJhZ1ByZXZpZXdFbGVtZW50XCI7XHJcbmltcG9ydCB7IFN0aVBhbmVsRWxlbWVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9TdGlQYW5lbEVsZW1lbnRcIjtcclxuaW1wb3J0IHsgU3RpQm9yZGVyQXJlYSB9IGZyb20gXCIuLi9wcm9wZXJ0aWVzL1N0aUJvcmRlckFyZWFcIjtcclxuaW1wb3J0IHsgU3RpTW9kZWxTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL21vZGVsLnNlcnZpY2VcIjtcclxuaW1wb3J0IHsgU3RpTGFiZWxBbGlnbm1lbnQgfSBmcm9tIFwiLi4vc3lzdGVtL2VudW1zXCI7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogXCJzdGktY29tcG9uZW50LWhvbGRlclwiLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZWxlbWVudCAhPSBudWxsXCI+XHJcbiAgICAgIDxzdGktYWRkcmVzcy1jb21wb25lbnRcclxuICAgICAgICBbZWxlbWVudF09XCJlbGVtZW50XCJcclxuICAgICAgICAqbmdJZj1cImVsZW1lbnQudHlwZSA9PT0gJ0FkZHJlc3NFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS1hZGRyZXNzLWNvbXBvbmVudD5cclxuICAgICAgPHN0aS10ZXh0Ym94LWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnVGV4dF9Cb3hFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS10ZXh0Ym94LWNvbXBvbmVudD5cclxuICAgICAgPHN0aS10ZXh0LWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnVGV4dEVsZW1lbnQnXCJcclxuICAgICAgICBbaXNDbG9uZV09XCJpc0Nsb25lXCJcclxuICAgICAgPjwvc3RpLXRleHQtY29tcG9uZW50PlxyXG4gICAgICA8c3RpLXRhYmxlLWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnVGFibGVFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS10YWJsZS1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktc2luZ2xlc2VsZWN0aW9uLWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnU2luZ2xlX1NlbGVjdGlvbkVsZW1lbnQnXCJcclxuICAgICAgICBbaXNDbG9uZV09XCJpc0Nsb25lXCJcclxuICAgICAgPjwvc3RpLXNpbmdsZXNlbGVjdGlvbi1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktc2lnbmF0dXJlLWNvbXBvbmVudCBbZWxlbWVudF09XCJlbGVtZW50XCIgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdTaWduYXR1cmVFbGVtZW50J1wiIFtpc0Nsb25lXT1cImlzQ2xvbmVcIj5cclxuICAgICAgPC9zdGktc2lnbmF0dXJlLWNvbXBvbmVudD5cclxuICAgICAgPHN0aS1wZGYtc2lnbmF0dXJlLWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnUERGU2lnbmF0dXJlRWxlbWVudCdcIlxyXG4gICAgICAgIFtpc0Nsb25lXT1cImlzQ2xvbmVcIlxyXG4gICAgICA+PC9zdGktcGRmLXNpZ25hdHVyZS1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktcGFuZWwtY29tcG9uZW50XHJcbiAgICAgICAgW2VsZW1lbnRdPVwiZWxlbWVudFwiXHJcbiAgICAgICAgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdQYW5lbEVsZW1lbnQnXCJcclxuICAgICAgICBbaXNDbG9uZV09XCJpc0Nsb25lXCJcclxuICAgICAgPjwvc3RpLXBhbmVsLWNvbXBvbmVudD5cclxuICAgICAgPHN0aS1udW1iZXJib3gtY29tcG9uZW50XHJcbiAgICAgICAgW2VsZW1lbnRdPVwiZWxlbWVudFwiXHJcbiAgICAgICAgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdOdW1iZXJfQm94RWxlbWVudCdcIlxyXG4gICAgICAgIFtpc0Nsb25lXT1cImlzQ2xvbmVcIlxyXG4gICAgICA+PC9zdGktbnVtYmVyYm94LWNvbXBvbmVudD5cclxuICAgICAgPHN0aS1tdWx0aXBsZXNlbGVjdGlvbi1jb21wb25lbnRcclxuICAgICAgICBbZWxlbWVudF09XCJlbGVtZW50XCJcclxuICAgICAgICAqbmdJZj1cImVsZW1lbnQudHlwZSA9PT0gJ011bHRpcGxlX1NlbGVjdGlvbkVsZW1lbnQnXCJcclxuICAgICAgICBbaXNDbG9uZV09XCJpc0Nsb25lXCJcclxuICAgICAgPjwvc3RpLW11bHRpcGxlc2VsZWN0aW9uLWNvbXBvbmVudD5cclxuICAgICAgPHN0aS1saXN0Ym94LWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnTGlzdF9Cb3hFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS1saXN0Ym94LWNvbXBvbmVudD5cclxuICAgICAgPHN0aS1sYWJlbC1jb21wb25lbnRcclxuICAgICAgICBbZWxlbWVudF09XCJlbGVtZW50XCJcclxuICAgICAgICAqbmdJZj1cImVsZW1lbnQudHlwZSA9PT0gJ0xhYmVsRWxlbWVudCdcIlxyXG4gICAgICAgIFtpc0Nsb25lXT1cImlzQ2xvbmVcIlxyXG4gICAgICA+PC9zdGktbGFiZWwtY29tcG9uZW50PlxyXG4gICAgICA8c3RpLWltYWdlLWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnSW1hZ2VFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS1pbWFnZS1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktZHJhZy1wcmV2aWV3LWFkb3JuZXIgW2VsZW1lbnRdPVwiZWxlbWVudFwiICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnRHJhZ19QcmV2aWV3J1wiPjwvc3RpLWRyYWctcHJldmlldy1hZG9ybmVyPlxyXG4gICAgICA8c3RpLWxpbmUtY29tcG9uZW50XHJcbiAgICAgICAgW2VsZW1lbnRdPVwiZWxlbWVudFwiXHJcbiAgICAgICAgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdMaW5lRWxlbWVudCdcIlxyXG4gICAgICAgIFtpc0Nsb25lXT1cImlzQ2xvbmVcIlxyXG4gICAgICA+PC9zdGktbGluZS1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktZGF0ZXRpbWVib3gtY29tcG9uZW50XHJcbiAgICAgICAgW2VsZW1lbnRdPVwiZWxlbWVudFwiXHJcbiAgICAgICAgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdEYXRlVGltZV9Cb3hFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS1kYXRldGltZWJveC1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktY29tYm9ib3gtY29tcG9uZW50XHJcbiAgICAgICAgW2VsZW1lbnRdPVwiZWxlbWVudFwiXHJcbiAgICAgICAgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdDb21ib19Cb3hFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS1jb21ib2JveC1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktY2hlY2tib3gtY29tcG9uZW50XHJcbiAgICAgICAgW2VsZW1lbnRdPVwiZWxlbWVudFwiXHJcbiAgICAgICAgKm5nSWY9XCJlbGVtZW50LnR5cGUgPT09ICdDaGVja19Cb3hFbGVtZW50J1wiXHJcbiAgICAgICAgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiXHJcbiAgICAgID48L3N0aS1jaGVja2JveC1jb21wb25lbnQ+XHJcbiAgICAgIDxzdGktYnV0dG9uLWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnQnV0dG9uRWxlbWVudCdcIlxyXG4gICAgICAgIFtpc0Nsb25lXT1cImlzQ2xvbmVcIlxyXG4gICAgICA+PC9zdGktYnV0dG9uLWNvbXBvbmVudD5cclxuICAgICAgPHN0aS1iYXJjb2RlLWNvbXBvbmVudFxyXG4gICAgICAgIFtlbGVtZW50XT1cImVsZW1lbnRcIlxyXG4gICAgICAgICpuZ0lmPVwiZWxlbWVudC50eXBlID09PSAnQmFyQ29kZUVsZW1lbnQnXCJcclxuICAgICAgICBbaXNDbG9uZV09XCJpc0Nsb25lXCJcclxuICAgICAgPjwvc3RpLWJhcmNvZGUtY29tcG9uZW50PlxyXG4gICAgPC9uZy1jb250YWluZXI+XHJcbiAgYCxcclxufSlcclxuZXhwb3J0IGNsYXNzIFN0aUNvbXBvbmVudEhvbGRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgQElucHV0KCkgZWxlbWVudDogU3RpRm9ybUVsZW1lbnQ7XHJcbiAgQElucHV0KCkgaXNDbG9uZTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHt9XHJcblxyXG4gIG5nT25Jbml0KCkge31cclxufVxyXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6IFwic3RpLXBhbmVsLWNvbXBvbmVudFwiLFxyXG4gIHRlbXBsYXRlOiBgIDxzdGktY29tcG9uZW50IFtlbGVtZW50XT1cImVsZW1lbnRcIiBbYm9yZGVyQXJlYV09XCJib3JkZXJBcmVhXCIgW2lzQ2xvbmVdPVwiaXNDbG9uZVwiIGNsYXNzPVwic3RpLXBhbmVsXCI+XHJcbiAgICA8c3RpLWVkaXRhYmxlLWNvbnRlbnQtY29tcG9uZW50XHJcbiAgICAgICpuZ0lmPVwiZWxlbWVudD8ubGFiZWwudmFsdWU/Lmxlbmd0aCA+IDAgJiYgZWxlbWVudD8uaXNMYWJlbFRvcEFsaWdubWVudCgpXCJcclxuICAgICAgW2VkaXRhYmxlQ29udGVudF09XCJlbGVtZW50LmxhYmVsXCJcclxuICAgICAgW3N0eWxlLnRleHQtYWxpZ25dPVwiZWxlbWVudD8uZ2V0Q29udGVudEFsaWduKClcIlxyXG4gICAgICBbc3R5bGUuYWxpZ24tc2VsZl09XCJhbGlnblwiXHJcbiAgICAgIFtoaWRlRW1wdHldPVwiZWxlbWVudC5zaG93TGFiZWxQbGFjZWhvbGRlcihtb2RlbD8uc2VsZWN0ZWRDb21wb25lbnQ/LmVsZW1lbnQgPT0gZWxlbWVudClcIlxyXG4gICAgICBbc3R5bGUud2lkdGhdPVwiZWxlbWVudD8uZ2V0TGFiZWxXaWR0aCgpXCJcclxuICAgID48L3N0aS1lZGl0YWJsZS1jb250ZW50LWNvbXBvbmVudD5cclxuICAgIDx0YWJsZSBbc3R5bGUud2lkdGhdPVwiJzEwMCUnXCIgW3N0eWxlLmhlaWdodF09XCInMTAwJSdcIiBbc3R5bGUubWFyZ2luLXRvcC5weF09XCJlbGVtZW50Py5nZXRUb3BNYXJnaW4oKVwiPlxyXG4gICAgICA8dHI+XHJcbiAgICAgICAgPHRkXHJcbiAgICAgICAgICAqbmdJZj1cImVsZW1lbnQ/LmxhYmVsLnZhbHVlPy5sZW5ndGggPiAwICYmICFlbGVtZW50Py5pc0xhYmVsVG9wQWxpZ25tZW50KClcIlxyXG4gICAgICAgICAgW3N0eWxlLmRpc3BsYXldPVwiJ2ZsZXgnXCJcclxuICAgICAgICAgIFtzdHlsZS5oZWlnaHRdPVwiJzEwMCUnXCJcclxuICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJlbGVtZW50Py5nZXRMYWJlbFdpZHRoKClcIlxyXG4gICAgICAgICAgW3N0eWxlLmFsaWduLWl0ZW1zXT1cImVsZW1lbnQ/LmdldFZlcnRpY2FsQWxpZ25tZW50KClcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxzdGktZWRpdGFibGUtY29udGVudC1jb21wb25lbnRcclxuICAgICAgICAgICAgKm5nSWY9XCJlbGVtZW50Py5sYWJlbC52YWx1ZT8ubGVuZ3RoID4gMFwiXHJcbiAgICAgICAgICAgIFtlZGl0YWJsZUNvbnRlbnRdPVwiZWxlbWVudD8ubGFiZWxcIlxyXG4gICAgICAgICAgICBbcmVxdWlyZWRdPVwiZWxlbWVudC5yZXF1aXJlZFwiXHJcbiAgICAgICAgICAgIFtzdHlsZS50ZXh0LWFsaWduXT1cImVsZW1lbnQ/LmdldENvbnRlbnRBbGlnbigpXCJcclxuICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cImVsZW1lbnQ/LmdldExhYmVsV2lkdGgoKVwiXHJcbiAgICAgICAgICAgIFtoaWRlRW1wdHldPVwiZWxlbWVudD8uc2hvd0xhYmVsUGxhY2Vob2xkZXIobW9kZWw/LnNlbGVjdGVkQ29tcG9uZW50Py5lbGVtZW50ID09IGVsZW1lbnQpXCJcclxuICAgICAgICAgID48L3N0aS1lZGl0YWJsZS1jb250ZW50LWNvbXBvbmVudD5cclxuICAgICAgICA8L3RkPlxyXG4gICAgICAgIDx0ZCBbc3R5bGUud2lkdGhdPVwiJzEwMCUnXCIgW3N0eWxlLmhlaWdodF09XCInMTAwJSdcIj5cclxuICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgI3JlZlxyXG4gICAgICAgICAgICBjbGFzcz1cInN0aS1wYW5lbC1jb250YWluZXJcIlxyXG4gICAgICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cIicxMDAlJ1wiXHJcbiAgICAgICAgICAgIFtzdHlsZS5taW4td2lkdGgucHhdPVwibWluV2lkdGhcIlxyXG4gICAgICAgICAgICBbc3R5bGUubWluLWhlaWdodC5weF09XCJtaW5IZWlnaHRcIlxyXG4gICAgICAgICAgICBbc3R5bGUuYWxpZ24tc2VsZl09XCInY2VudGVyJ1wiXHJcbiAgICAgICAgICAgIFtzdHlsZS5vdmVyZmxvd109XCInaGlkZGVuJ1wiXHJcbiAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cIlxyXG4gICAgICAgICAgICAgICghZWxlbWVudC5pc0FkZGVkICYmXHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LmJhY2tncm91bmRDb2xvci5yID09IDI1NSAmJlxyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5iYWNrZ3JvdW5kQ29sb3IuZyA9PSAyNTUgJiZcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuYmFja2dyb3VuZENvbG9yLmIgPT0gMjU1KSB8fFxyXG4gICAgICAgICAgICAgIGVsZW1lbnQuYmFja2dyb3VuZENvbG9yLmEgPT0gMFxyXG4gICAgICAgICAgICAgICAgPyAndHJhbnNwYXJlbnQnXHJcbiAgICAgICAgICAgICAgICA6IGVsZW1lbnQ/LmJhY2tncm91bmRDb2xvci50b0h0bWxDb2xvcigpXHJcbiAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGVsZW1lbnQgb2YgZWxlbWVudHNcIiBbZGlzYWJsZWRdPVwiZWxlbWVudD8ucmVhZE9ubHkgPyB0cnVlIDogZmFsc2VcIj5cclxuICAgICAgICAgICAgICA8c3RpLWNvbXBvbmVudC1ob2xkZXIgW2VsZW1lbnRdPVwiZWxlbWVudFwiPjwvc3RpLWNvbXBvbmVudC1ob2xkZXI+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZD5cclxuICAgICAgPC90cj5cclxuICAgICAgPHRyICpuZ0lmPVwiZWxlbWVudD8uZGVzY3JpcHRpb24udmFsdWU/Lmxlbmd0aCA+IDBcIj5cclxuICAgICAgICA8dGQgKm5nSWY9XCJlbGVtZW50Py5sYWJlbC52YWx1ZT8ubGVuZ3RoID4gMCAmJiAhZWxlbWVudD8uaXNMYWJlbFRvcEFsaWdubWVudCgpXCI+PC90ZD5cclxuICAgICAgICA8dGQgW3N0eWxlLm1heFdpZHRoLnB4XT1cImVsZW1lbnQubWF4V2lkdGggKyAxXCI+XHJcbiAgICAgICAgICA8c3RpLWVkaXRhYmxlLWNvbnRlbnQtY29tcG9uZW50XHJcbiAgICAgICAgICAgICpuZ0lmPVwiZWxlbWVudD8uZGVzY3JpcHRpb24udmFsdWU/Lmxlbmd0aCA+IDBcIlxyXG4gICAgICAgICAgICBbZWRpdGFibGVDb250ZW50XT1cImVsZW1lbnQuZGVzY3JpcHRpb25cIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgPC9zdGktZWRpdGFibGUtY29udGVudC1jb21wb25lbnQ+XHJcbiAgICAgICAgPC90ZD5cclxuICAgICAgPC90cj5cclxuICAgIDwvdGFibGU+XHJcbiAgPC9zdGktY29tcG9uZW50PmAsXHJcbiAgc3R5bGVzOiBbXHJcbiAgICBgXHJcbiAgICAgIHRhYmxlIHtcclxuICAgICAgICBib3JkZXItc3BhY2luZzogMDtcclxuICAgICAgfVxyXG4gICAgICB0ciB7XHJcbiAgICAgICAgaGVpZ2h0OiBtYXgtY29udGVudDtcclxuICAgICAgICBwYWRkaW5nOiAwO1xyXG4gICAgICAgIG1hcmdpbjogMDtcclxuICAgICAgfVxyXG4gICAgICB0ZCB7XHJcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgICAgIHBhZGRpbmc6IDA7XHJcbiAgICAgICAgbWFyZ2luOiAwO1xyXG4gICAgICB9XHJcbiAgICAgIC5zdGktcGFuZWwtY29udGFpbmVyIHtcclxuICAgICAgICBtaW4taGVpZ2h0OiA1cHg7XHJcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gICAgICB9XHJcbiAgICBgLFxyXG4gIF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTdGlQYW5lbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCB7XHJcbiAgQFZpZXdDaGlsZChcInJlZlwiKSByZWY6IEVsZW1lbnRSZWY7XHJcbiAgQElucHV0KCkgZWxlbWVudDogU3RpUGFuZWxFbGVtZW50O1xyXG4gIEBJbnB1dCgpIGlzQ2xvbmU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwdWJsaWMgY3VycmVudEJvdHRvbVBvaW50OiBudW1iZXI7XHJcbiAgZ2V0IGVsZW1lbnRzKCk6IFN0aUZvcm1FbGVtZW50W10ge1xyXG4gICAgcmV0dXJuIHRoaXMuZWxlbWVudD8uZWxlbWVudHM7XHJcbiAgfVxyXG4gIHB1YmxpYyBnZXQgYm9yZGVyQXJlYSgpIHtcclxuICAgIGlmICghdGhpcy5pc0Nsb25lKSB7XHJcbiAgICAgIGxldCBib3JkZXJBcmVhID0gbmV3IFN0aUJvcmRlckFyZWEoKTtcclxuICAgICAgYm9yZGVyQXJlYS50b3AgPVxyXG4gICAgICAgIHRoaXMucmVmPy5uYXRpdmVFbGVtZW50Py5vZmZzZXRUb3AgLVxyXG4gICAgICAgICh0aGlzLmVsZW1lbnQubGFiZWwuYWxpZ25tZW50ICE9IFN0aUxhYmVsQWxpZ25tZW50LlRvcCA/IHRoaXMuZWxlbWVudC5wYWRkaW5nLnRvcCA6IDApO1xyXG4gICAgICBib3JkZXJBcmVhLmxlZnQgPSB0aGlzLnJlZj8ubmF0aXZlRWxlbWVudD8ub2Zmc2V0TGVmdDtcclxuICAgICAgYm9yZGVyQXJlYS53aWR0aCA9IHRoaXMucmVmPy5uYXRpdmVFbGVtZW50Py5vZmZzZXRXaWR0aCAtIHRoaXMuZWxlbWVudC5wYWRkaW5nLmxlZnQgLSB0aGlzLmVsZW1lbnQucGFkZGluZy5yaWdodDtcclxuICAgICAgYm9yZGVyQXJlYS5oZWlnaHQgPSB0aGlzLnJlZj8ubmF0aXZlRWxlbWVudD8ub2Zmc2V0SGVpZ2h0O1xyXG4gICAgICBib3JkZXJBcmVhLmJvcmRlciA9IHRoaXMuZWxlbWVudC5ib3JkZXI7XHJcbiAgICAgIHJldHVybiBib3JkZXJBcmVhO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBhbGlnbigpIHtcclxuICAgIHJldHVybiBcInN0YXJ0XCI7XHJcbiAgfVxyXG4gIGdldCBtaW5XaWR0aCgpIHtcclxuICAgIGlmICh0aGlzLmVsZW1lbnRzPy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGxldCBtaW5XaWR0aCA9IHRoaXMuZWxlbWVudHNbMF0/LnggKyB0aGlzLmVsZW1lbnRzWzBdPy53aWR0aDtcclxuICAgICAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgaWYgKG1pbldpZHRoIDwgZWxlbWVudC54ICsgZWxlbWVudC53aWR0aCkge1xyXG4gICAgICAgICAgbWluV2lkdGggPSBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVybiBtaW5XaWR0aDtcclxuICAgIH1cclxuICAgIHJldHVybiBcIm1pbi1jb250ZW50XCI7XHJcbiAgfVxyXG4gIHB1YmxpYyBnZXQgbWluSGVpZ2h0KCk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRoaXMubW9kZWwuZHJhZ2dpbmdFbGVtZW50KSB7XHJcbiAgICAgIGlmICh0aGlzLmVsZW1lbnRzPy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgbGV0IG1heEJvdHRvbVBvaW50ID0gMDtcclxuICAgICAgICB0aGlzLmVsZW1lbnRzPy5mb3JFYWNoKChlbGVtZW50KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIShlbGVtZW50IGluc3RhbmNlb2YgU3RpRHJhZ1ByZXZpZXdFbGVtZW50KSAmJiBlbGVtZW50Lmdlb21ldHJ5LmJvdHRvbSA+IG1heEJvdHRvbVBvaW50KSB7XHJcbiAgICAgICAgICAgIG1heEJvdHRvbVBvaW50ID0gZWxlbWVudC5nZW9tZXRyeS5ib3R0b207XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudEJvdHRvbVBvaW50ICE9IG1heEJvdHRvbVBvaW50KSB7XHJcbiAgICAgICAgICB0aGlzLnJlbmRlci5pbnNlcnRFbGVtZW50KHRoaXMuZWxlbWVudCk7XHJcbiAgICAgICAgICB0aGlzLnJlbmRlci5jaGVja091dHB1dHModGhpcy5tb2RlbC5nZXRFbGVtZW50UGFnZSh0aGlzLmVsZW1lbnQpKTtcclxuICAgICAgICAgIHRoaXMuY3VycmVudEJvdHRvbVBvaW50ID0gbWF4Qm90dG9tUG9pbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBtYXhCb3R0b21Qb2ludCA+IDAgPyBtYXhCb3R0b21Qb2ludCA6IDU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIDU7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgY29uc3RydWN0b3IocHVibGljIG1vZGVsOiBTdGlNb2RlbFNlcnZpY2UsIHB1YmxpYyByZW5kZXI6IFN0aVJlY3RhbmdsZUdlb21ldHJ5TGF5b3V0KSB7fVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaXNDbG9uZSkge1xyXG4gICAgICB0aGlzLmVsZW1lbnQuZWxlbWVudCA9IHRoaXMucmVmO1xyXG4gICAgfVxyXG4gIH1cclxuICBuZ09uSW5pdCgpOiB2b2lkIHt9XHJcbn1cclxuIl19