stimulsoft-forms
Version:
Stimulsoft PDF Forms
410 lines • 57.9 kB
JavaScript
import { Component, Input } from "@angular/core";
import { StiButtonType } from "../../system/enums";
import { StiTextBoxElement } from "../../elements/StiTextBoxElement";
import { StiNumberBoxElement } from "../../elements/StiNumberBoxElement";
import { StiComboBoxElement } from "../../elements/StiComboBoxElement";
import { StiListBoxElement } from "../../elements/StiListBoxElement";
import { StiSingleSelectionElement } from "../../elements/StiSingleSelectionElement";
import { StiMultipleSelectionElement } from "../../elements/StiMultipleSelectionElement";
import { StiCheckBoxElement } from "../../elements/StiCheckBoxElement";
import { StiSignatureElement } from "../../elements/StiSignatureElement";
import { StiDateTimeBoxElement } from "../../elements/StiDateTimeBoxElement";
import { StiBarcodeElement } from "../../elements/StiBarcodeElement";
import { StiLabelElement } from "../../elements/StiLabelElement";
import { StiTableElement } from "../../elements/StiTableElement";
import { StiTextBoxCellItem } from "../../elements/table/cells/StiTextBoxCellItem";
import { StiRadioButtonCellItem } from "../../elements/table/cells/StiRadioButtonCellItem";
import { StiNumberBoxCellItem } from "../../elements/table/cells/StiNumberBoxCellItem";
import { StiComboBoxCellItem } from "../../elements/table/cells/StiComboBoxCellItem";
import { StiCheckBoxCellItem } from "../../elements/table/cells/StiCheckBoxCellItem";
import { StiAddressElement } from "../../elements/StiAddressElement";
import { catchError } from "rxjs/operators";
import { throwError } from "rxjs";
import { StiLocalizationService } from "../../services/sti-localization.service";
import { StiRadioButtonColumnItem } from "../../elements/table/columns/StiRadioButtonColumnItem";
import { StiStaticHelperService } from "../../services/sti-static-helper.service";
import * as i0 from "@angular/core";
import * as i1 from "../../services/model.service";
import * as i2 from "@angular/common/http";
import * as i3 from "../sti-component";
import * as i4 from "../sti-editable-content.component";
import * as i5 from "../sti-tooltip/sti-tooltip.directive";
export class StiButtonComponent {
constructor(model, httpClient) {
this.model = model;
this.httpClient = httpClient;
this.isClone = false;
}
ngOnDestroy() {
this.retryEvent?.unsubscribe();
}
disableDrag(event) {
this.model.canDrag = false;
}
clickEvent() {
if (this.element.buttonType == StiButtonType.ClearForm && this.model.previewMode) {
this.model.form.pages.forEach((page) => {
page.allElements.forEach((element) => {
element.setDefaultValues();
});
});
}
else if (this.element.buttonType == StiButtonType.SendForm && this.model.previewMode) {
this.model.errorWindowMessage = this.element.submissionMessage;
if (this.element.formSendURL) {
this.model.showProgress = true;
let xml = this.createXml();
let url;
if (this.element.formSendURL.trim().toLocaleLowerCase() == "stimulsoft cloud" ||
this.element.formSendURL.trim().toLocaleLowerCase() == "cloud.stimulsoft.com") {
url = "https://submit.stimulsoft.com/submit";
}
else {
url = this.element.formSendURL;
}
if (this.formHasEmptyRequiredFields()) {
let elem = this.formHasEmptyRequiredFields();
this.model.errorWindowMessage = StiLocalizationService.get("Errors", "FieldRequire").replace("{0}", elem["label"] ? elem["label"]["value"] : elem["name"]);
this.model.showErrorWindow = true;
this.model.showProgress = false;
this.scrollToRequired(elem);
return;
}
this.httpClient
.post(url, xml)
.pipe(catchError((data) => {
this.model.showProgress = false;
this.model.showError(StiLocalizationService.get("DesignerFx", "ConnectionError"), true, this.element);
this.model.interfaceEvent.next({ name: "FormSubmittedError", data: data });
return throwError("Something bad happened; please try again later.");
}))
.subscribe((data) => {
this.model.showProgress = false;
this.model.interfaceEvent.next({ name: "FormSubmitted", data: data });
if (this.element.submissionMessage != null && this.element.submissionMessage.length > 0) {
this.model.showButtonMessageWindow = true;
}
});
}
else {
this.model.interfaceEvent.next({ name: "FormSubmitted" });
if (this.element.submissionMessage != null &&
this.element.submissionMessage.length > 0 &&
this.element.formSendURL) {
this.model.showButtonMessageWindow = true;
}
}
}
else if (this.element.buttonType == StiButtonType.AttachFiles && this.model.previewMode) {
this.model.loadAttachedFile();
}
}
get selected() {
return this.model.selectedComponent?.element == this.element;
}
scrollToRequired(elem) {
let workspace = document.getElementsByTagName("sti-workspace")[0];
let domElement = document.getElementById(elem.guid);
let elementRect = this.model.getPositionRelativeToForm(domElement);
const componentHeader = 38;
let currentScrollPosition = workspace.scrollTop;
if (elementRect.top < 0) {
workspace.scrollTop = currentScrollPosition - (Math.abs(elementRect?.top) + componentHeader);
}
else {
workspace.scrollTop = currentScrollPosition + (elementRect?.top - componentHeader);
}
}
createXml() {
let string = `<?xml version="1.0" encoding="UTF-8"?>
<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">
<fields>` +
this.addXmlField({ name: "StiFormGuid", value: this.model.form.guid }) +
(this.model.form.versionKey != null && this.model.form.versionKey.length > 0
? this.addXmlField({ name: "StiVersionKey", value: this.model.form.versionKey })
: "") +
//this.addXmlField({ name: "StiUserId", value: this.model.form.userId }) +
this.createFields() +
this.addAttachedFiles() +
this.addAdditionsFormField() +
`</fields>
</xfdf>`;
return string;
}
createFields() {
let fields = "";
this.model.form.pages.forEach((page) => {
page.allElements.forEach((element) => {
if (element instanceof StiTableElement) {
this.model.removeUnusedCells(element);
fields += this.getXmlTableField(element);
}
else if (element instanceof StiAddressElement) {
fields += this.getXmlAddressField(element);
}
else {
let field = this.addXmlField(this.getValue(element));
if (field) {
fields += field;
}
}
});
});
return fields;
}
formHasEmptyRequiredFields() {
this.model.hasEmptyReuiredFields = false;
let emptyRequiredElement = null;
for (let page of this.model.form.pages) {
for (let elem of page.allElements) {
if ((!elem["value"] || elem["value"].length == 0) && elem["required"]) {
emptyRequiredElement = elem;
break;
}
}
if (emptyRequiredElement) {
break;
}
}
if (emptyRequiredElement) {
this.model.hasEmptyReuiredFields = true;
return emptyRequiredElement;
}
return null;
}
addAdditionsFormField() {
let string = "";
this.model.form.additionalFormFields.forEach((field) => {
string += this.addXmlField({ name: field.key, value: field.value });
});
return string;
}
addXmlField(elementInfo) {
if (elementInfo && (elementInfo.values != null || elementInfo.value != null)) {
let val = "";
(elementInfo.values ?? [elementInfo.value]).forEach((value) => {
val += `<value>${this.encodeHTML(value)}</value>`;
});
return `<field name="${elementInfo.name}">${val}</field>`;
}
return "";
}
encodeHTML(data) {
if (data instanceof Date) {
return StiStaticHelperService.formatDate(data, "dd-mm-yyyyTHH:mm:ss");
}
else if (typeof data == "string") {
return data.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
return data;
}
getXmlTableField(element) {
let field = `<field name="${element.name}">
` +
this.createTableFields(element) +
`</field>
`;
return field;
}
addAttachedFiles() {
let string = "";
this.model.form.attachedFiles.forEach((file, index) => {
string += this.addXmlField({ name: "AttachedFile" + index, value: file });
});
return string;
}
getXmlAddressField(element) {
let field = `<field name="${element.name}">
` +
this.createAddressField(element) +
`</field>
`;
return field;
}
createAddressField(element) {
let fields = "";
if (element.useCountry) {
fields += this.addXmlField({
name: "Country",
value: element.country,
});
}
if (element.useCity) {
fields += this.addXmlField({
name: "City",
value: element.city,
});
}
if (element.useState) {
fields += this.addXmlField({
name: "State",
value: element.state,
});
}
if (element.useStreetAddress) {
fields += this.addXmlField({
name: "StreetAddress",
value: element.streetAddress,
});
}
if (element.useStreetAddress2) {
fields += this.addXmlField({
name: "StreetAddress2",
value: element.streetAddress2,
});
}
if (element.useZipCode) {
fields += this.addXmlField({
name: "ZipCode",
value: element.zipCode,
});
}
return fields;
}
createTableFields(element) {
let fields = "";
element.columns.forEach((column, index) => {
let columnIndex = index;
column["cells"].forEach((cell, index) => {
fields += this.addXmlField(this.getTableCellValue(column, columnIndex, cell, index));
});
});
element.totalsFields.forEach((field, index) => {
fields += this.addXmlField(this.getTableFieldValue(field, index));
});
element.rowLabels.forEach((row, index) => {
element.columns.forEach((column, idx) => {
if (column instanceof StiRadioButtonColumnItem && column.cells[index].isChecked) {
fields += this.addXmlField(this.getRowValue(index, idx));
}
});
});
return fields;
}
getTableFieldValue(field, fieldIndex) {
return { name: "TotalsField" + fieldIndex, value: field.value };
}
getRowValue(rowIndex, columnIndex) {
return { name: `Row-${rowIndex}-SingleSelection`, value: `Column-${columnIndex}` };
}
getTableCellValue(column, columnIndex, cell, cellIndex) {
let name = "Cell" +
"-" +
columnIndex +
"-" +
cellIndex +
"-" +
(cell instanceof StiRadioButtonCellItem ? "SingleSelection" : column["type"].replace("Column", ""));
let value = cell;
if (cell instanceof StiTextBoxCellItem) {
value = cell.text;
}
else if (cell instanceof StiRadioButtonCellItem) {
return;
value = cell.isChecked;
}
else if (cell instanceof StiNumberBoxCellItem) {
value = cell.value;
}
else if (cell instanceof StiComboBoxCellItem) {
value = column.comboBoxOptions[cell.selectedIndex];
}
else if (cell instanceof StiCheckBoxCellItem) {
value = cell.isChecked;
}
return { name: name, value: value };
}
getValue(element) {
let name = element.name ?? element.guid;
let value, values;
if (element instanceof StiTextBoxElement) {
value = element.text;
}
else if (element instanceof StiNumberBoxElement) {
value = element.value;
}
else if (element instanceof StiComboBoxElement) {
value = element.selectedOption;
}
else if (element instanceof StiListBoxElement) {
values = element.selectedOptions;
}
else if (element instanceof StiSingleSelectionElement) {
value = element.selectedOption;
}
else if (element instanceof StiMultipleSelectionElement) {
values = element.selectedOptions;
}
else if (element instanceof StiCheckBoxElement) {
value = element.isChecked;
}
else if (element instanceof StiSignatureElement) {
value = element.value;
}
else if (element instanceof StiDateTimeBoxElement) {
value = element.dateValue;
}
else if (element instanceof StiBarcodeElement) {
value = element.img;
}
else if (element instanceof StiLabelElement) {
value = element.displayValue != undefined ? element.displayValue : element.text.value;
}
return { name: name, value: value, values: values };
}
ngOnInit() {
if ((this.model.isCloudMode || this.model.isWebView) && this.element.formSendURL?.length == 0) {
this.element.formSendURL = "cloud.stimulsoft.com";
}
this.retryEvent = this.model.retryButtonRequest.subscribe((element) => {
if (element == this.element && !this.isClone) {
this.clickEvent();
}
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiButtonComponent, deps: [{ token: i1.StiModelService }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: StiButtonComponent, selector: "sti-button-component", inputs: { element: "element", isClone: "isClone" }, ngImport: i0, template: ` <sti-component [element]="element" [isClone]="isClone" [style.align-items]="'center'" class="StiButton">
<div
class="button {{ element?.readOnly ? 'disabled' : '' }}"
[style.background-color]="element?.text.backgroundColor.toHtmlColor()"
[style.border]="'1px solid' + element?.text.backgroundColor.toHtmlColor()"
[stiTooltip]="element?.tooltip"
(click)="clickEvent()"
tooltipPosition="bottom"
showDelay="500"
>
<sti-editable-content-component
[hideEmpty]="false"
[editableContent]="element.text"
[fromButton]="true"
[active]="selected"
></sti-editable-content-component>
</div>
</sti-component>`, isInline: true, styles: [".disabled{pointer-events:none}.button{width:fit-content;padding:10px;background-color:#d3d3d3;height:100%;width:100%;display:flex;align-items:center;justify-content:center}.button:hover{opacity:.5}\n"], dependencies: [{ kind: "component", type: i3.StiComponent, selector: "sti-component", inputs: ["element", "class", "isClone", "borderArea"] }, { kind: "component", type: i4.StiEditableContentComponent, selector: "sti-editable-content-component", inputs: ["editableContent", "displayContent", "required", "eParent", "hideEmpty", "active", "alignment", "isTableTotalHeader", "disablePadding", "fromButton", "parentCursor", "isTableHeader"] }, { kind: "directive", type: i5.StiTooltipDirective, selector: "[stiTooltip]", inputs: ["tooltipPosition", "stiTooltip", "showDelay"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiButtonComponent, decorators: [{
type: Component,
args: [{ selector: "sti-button-component", template: ` <sti-component [element]="element" [isClone]="isClone" [style.align-items]="'center'" class="StiButton">
<div
class="button {{ element?.readOnly ? 'disabled' : '' }}"
[style.background-color]="element?.text.backgroundColor.toHtmlColor()"
[style.border]="'1px solid' + element?.text.backgroundColor.toHtmlColor()"
[stiTooltip]="element?.tooltip"
(click)="clickEvent()"
tooltipPosition="bottom"
showDelay="500"
>
<sti-editable-content-component
[hideEmpty]="false"
[editableContent]="element.text"
[fromButton]="true"
[active]="selected"
></sti-editable-content-component>
</div>
</sti-component>`, styles: [".disabled{pointer-events:none}.button{width:fit-content;padding:10px;background-color:#d3d3d3;height:100%;width:100%;display:flex;align-items:center;justify-content:center}.button:hover{opacity:.5}\n"] }]
}], ctorParameters: () => [{ type: i1.StiModelService }, { type: i2.HttpClient }], propDecorators: { element: [{
type: Input
}], isClone: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RpLWJ1dHRvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdGltdWxzb2Z0LWZvcm1zL3NyYy9saWIvY29tcG9uZW50cy9zdGktYnV0dG9uL3N0aS1idXR0b24uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUlwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDckYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDekYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDekUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFN0UsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUNuRixPQUFPLEVBQUUsc0JBQXNCLEVBQUUs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T0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDdEQsQ0FBQztJQUNELFFBQVE7UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDOUYsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEdBQUcsc0JBQXNCLENBQUM7UUFDcEQsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNwRSxJQUFJLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM3QyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzsrR0F4VVUsa0JBQWtCO21HQUFsQixrQkFBa0IsZ0hBeENuQjs7Ozs7Ozs7Ozs7Ozs7Ozs7bUJBaUJPOzs0RkF1Qk4sa0JBQWtCO2tCQTFDOUIsU0FBUzsrQkFDRSxzQkFBc0IsWUFDdEI7Ozs7Ozs7Ozs7Ozs7Ozs7O21CQWlCTzs2R0F5QlIsT0FBTztzQkFBZixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgU3RpTW9kZWxTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL21vZGVsLnNlcnZpY2VcIjtcclxuXHJcbmltcG9ydCB7IFN0aUJ1dHRvbkVsZW1lbnQgfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvU3RpQnV0dG9uRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlCdXR0b25UeXBlIH0gZnJvbSBcIi4uLy4uL3N5c3RlbS9lbnVtc1wiO1xyXG5pbXBvcnQgeyBTdGlUZXh0Qm94RWxlbWVudCB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy9TdGlUZXh0Qm94RWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlOdW1iZXJCb3hFbGVtZW50IH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL1N0aU51bWJlckJveEVsZW1lbnRcIjtcclxuaW1wb3J0IHsgU3RpQ29tYm9Cb3hFbGVtZW50IH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL1N0aUNvbWJvQm94RWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlMaXN0Qm94RWxlbWVudCB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy9TdGlMaXN0Qm94RWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlTaW5nbGVTZWxlY3Rpb25FbGVtZW50IH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL1N0aVNpbmdsZVNlbGVjdGlvbkVsZW1lbnRcIjtcclxuaW1wb3J0IHsgU3RpTXVsdGlwbGVTZWxlY3Rpb25FbGVtZW50IH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL1N0aU11bHRpcGxlU2VsZWN0aW9uRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlDaGVja0JveEVsZW1lbnQgfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvU3RpQ2hlY2tCb3hFbGVtZW50XCI7XHJcbmltcG9ydCB7IFN0aVNpZ25hdHVyZUVsZW1lbnQgfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvU3RpU2lnbmF0dXJlRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlEYXRlVGltZUJveEVsZW1lbnQgfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvU3RpRGF0ZVRpbWVCb3hFbGVtZW50XCI7XHJcbmltcG9ydCB7IFN0aUltYWdlRWxlbWVudCB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy9TdGlJbWFnZUVsZW1lbnRcIjtcclxuaW1wb3J0IHsgU3RpQmFyY29kZUVsZW1lbnQgfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvU3RpQmFyY29kZUVsZW1lbnRcIjtcclxuaW1wb3J0IHsgU3RpTGFiZWxFbGVtZW50IH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL1N0aUxhYmVsRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlUYWJsZUVsZW1lbnQgfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvU3RpVGFibGVFbGVtZW50XCI7XHJcbmltcG9ydCB7IFN0aVRleHRCb3hDZWxsSXRlbSB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy90YWJsZS9jZWxscy9TdGlUZXh0Qm94Q2VsbEl0ZW1cIjtcclxuaW1wb3J0IHsgU3RpUmFkaW9CdXR0b25DZWxsSXRlbSB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy90YWJsZS9jZWxscy9TdGlSYWRpb0J1dHRvbkNlbGxJdGVtXCI7XHJcbmltcG9ydCB7IFN0aU51bWJlckJveENlbGxJdGVtIH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL3RhYmxlL2NlbGxzL1N0aU51bWJlckJveENlbGxJdGVtXCI7XHJcbmltcG9ydCB7IFN0aUNvbWJvQm94Q2VsbEl0ZW0gfSBmcm9tIFwiLi4vLi4vZWxlbWVudHMvdGFibGUvY2VsbHMvU3RpQ29tYm9Cb3hDZWxsSXRlbVwiO1xyXG5pbXBvcnQgeyBTdGlDaGVja0JveENlbGxJdGVtIH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL3RhYmxlL2NlbGxzL1N0aUNoZWNrQm94Q2VsbEl0ZW1cIjtcclxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5pbXBvcnQgeyBTdGlBZGRyZXNzRWxlbWVudCB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy9TdGlBZGRyZXNzRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlGb3JtIH0gZnJvbSBcIi4uLy4uL2VsZW1lbnRzL1N0aUZvcm1cIjtcclxuaW1wb3J0IHsgY2F0Y2hFcnJvciB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQgeyBvZiwgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgdGhyb3dFcnJvciB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IFN0aUxvY2FsaXphdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vc2VydmljZXMvc3RpLWxvY2FsaXphdGlvbi5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aVJhZGlvQnV0dG9uQ29sdW1uSXRlbSB9IGZyb20gXCIuLi8uLi9lbGVtZW50cy90YWJsZS9jb2x1bW5zL1N0aVJhZGlvQnV0dG9uQ29sdW1uSXRlbVwiO1xyXG5pbXBvcnQgeyBTdGlTdGF0aWNIZWxwZXJTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL3N0aS1zdGF0aWMtaGVscGVyLnNlcnZpY2VcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcInN0aS1idXR0b24tY29tcG9uZW50XCIsXHJcbiAgdGVtcGxhdGU6IGAgPHN0aS1jb21wb25lbnQgW2VsZW1lbnRdPVwiZWxlbWVudFwiIFtpc0Nsb25lXT1cImlzQ2xvbmVcIiBbc3R5bGUuYWxpZ24taXRlbXNdPVwiJ2NlbnRlcidcIiBjbGFzcz1cIlN0aUJ1dHRvblwiPlxyXG4gICAgPGRpdlxyXG4gICAgICBjbGFzcz1cImJ1dHRvbiB7eyBlbGVtZW50Py5yZWFkT25seSA/ICdkaXNhYmxlZCcgOiAnJyB9fVwiXHJcbiAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWNvbG9yXT1cImVsZW1lbnQ/LnRleHQuYmFja2dyb3VuZENvbG9yLnRvSHRtbENvbG9yKClcIlxyXG4gICAgICBbc3R5bGUuYm9yZGVyXT1cIicxcHggc29saWQnICsgZWxlbWVudD8udGV4dC5iYWNrZ3JvdW5kQ29sb3IudG9IdG1sQ29sb3IoKVwiXHJcbiAgICAgIFtzdGlUb29sdGlwXT1cImVsZW1lbnQ/LnRvb2x0aXBcIlxyXG4gICAgICAoY2xpY2spPVwiY2xpY2tFdmVudCgpXCJcclxuICAgICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcclxuICAgICAgc2hvd0RlbGF5PVwiNTAwXCJcclxuICAgID5cclxuICAgICAgPHN0aS1lZGl0YWJsZS1jb250ZW50LWNvbXBvbmVudFxyXG4gICAgICAgIFtoaWRlRW1wdHldPVwiZmFsc2VcIlxyXG4gICAgICAgIFtlZGl0YWJsZUNvbnRlbnRdPVwiZWxlbWVudC50ZXh0XCJcclxuICAgICAgICBbZnJvbUJ1dHRvbl09XCJ0cnVlXCJcclxuICAgICAgICBbYWN0aXZlXT1cInNlbGVjdGVkXCJcclxuICAgICAgPjwvc3RpLWVkaXRhYmxlLWNvbnRlbnQtY29tcG9uZW50PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9zdGktY29tcG9uZW50PmAsXHJcbiAgc3R5bGVzOiBbXHJcbiAgICBgXHJcbiAgICAgIC5kaXNhYmxlZCB7XHJcbiAgICAgICAgcG9pbnRlci1ldmVudHM6IG5vbmU7XHJcbiAgICAgIH1cclxuICAgICAgLmJ1dHRvbiB7XHJcbiAgICAgICAgd2lkdGg6IGZpdC1jb250ZW50O1xyXG4gICAgICAgIHBhZGRpbmc6IDEwcHg7XHJcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogcmdiKDIxMSwgMjExLCAyMTEpO1xyXG4gICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgICB3aWR0aDogMTAwJTtcclxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XHJcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC5idXR0b246aG92ZXIge1xyXG4gICAgICAgIG9wYWNpdHk6IDAuNTtcclxuICAgICAgfVxyXG4gICAgYCxcclxuICBdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU3RpQnV0dG9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIHJldHJ5RXZlbnQ6IFN1YnNjcmlwdGlvbjtcclxuICBASW5wdXQoKSBlbGVtZW50OiBTdGlCdXR0b25FbGVtZW50O1xyXG4gIEBJbnB1dCgpIGlzQ2xvbmU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbW9kZWw6IFN0aU1vZGVsU2VydmljZSwgcHJpdmF0ZSBodHRwQ2xpZW50OiBIdHRwQ2xpZW50KSB7IH1cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMucmV0cnlFdmVudD8udW5zdWJzY3JpYmUoKTtcclxuICB9XHJcbiAgZGlzYWJsZURyYWcoZXZlbnQpIHtcclxuICAgIHRoaXMubW9kZWwuY2FuRHJhZyA9IGZhbHNlO1xyXG4gIH1cclxuICBjbGlja0V2ZW50KCkge1xyXG4gICAgaWYgKHRoaXMuZWxlbWVudC5idXR0b25UeXBlID09IFN0aUJ1dHRvblR5cGUuQ2xlYXJGb3JtICYmIHRoaXMubW9kZWwucHJldmlld01vZGUpIHtcclxuICAgICAgdGhpcy5tb2RlbC5mb3JtLnBhZ2VzLmZvckVhY2goKHBhZ2UpID0+IHtcclxuICAgICAgICBwYWdlLmFsbEVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQpID0+IHtcclxuICAgICAgICAgIGVsZW1lbnQuc2V0RGVmYXVsdFZhbHVlcygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5lbGVtZW50LmJ1dHRvblR5cGUgPT0gU3RpQnV0dG9uVHlwZS5TZW5kRm9ybSAmJiB0aGlzLm1vZGVsLnByZXZpZXdNb2RlKSB7XHJcbiAgICAgIHRoaXMubW9kZWwuZXJyb3JXaW5kb3dNZXNzYWdlID0gdGhpcy5lbGVtZW50LnN1Ym1pc3Npb25NZXNzYWdlO1xyXG4gICAgICBpZiAodGhpcy5lbGVtZW50LmZvcm1TZW5kVVJMKSB7XHJcbiAgICAgICAgdGhpcy5tb2RlbC5zaG93UHJvZ3Jlc3MgPSB0cnVlO1xyXG4gICAgICAgIGxldCB4bWwgPSB0aGlzLmNyZWF0ZVhtbCgpO1xyXG4gICAgICAgIGxldCB1cmw7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgdGhpcy5lbGVtZW50LmZvcm1TZW5kVVJMLnRyaW0oKS50b0xvY2FsZUxvd2VyQ2FzZSgpID09IFwic3RpbXVsc29mdCBjbG91ZFwiIHx8XHJcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuZm9ybVNlbmRVUkwudHJpbSgpLnRvTG9jYWxlTG93ZXJDYXNlKCkgPT0gXCJjbG91ZC5zdGltdWxzb2Z0LmNvbVwiXHJcbiAgICAgICAgKSB7XHJcbiAgICAgICAgICB1cmwgPSBcImh0dHBzOi8vc3VibWl0LnN0aW11bHNvZnQuY29tL3N1Ym1pdFwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB1cmwgPSB0aGlzLmVsZW1lbnQuZm9ybVNlbmRVUkw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmZvcm1IYXNFbXB0eVJlcXVpcmVkRmllbGRzKCkpIHtcclxuICAgICAgICAgIGxldCBlbGVtID0gdGhpcy5mb3JtSGFzRW1wdHlSZXF1aXJlZEZpZWxkcygpO1xyXG4gICAgICAgICAgdGhpcy5tb2RlbC5lcnJvcldpbmRvd01lc3NhZ2UgPSBTdGlMb2NhbGl6YXRpb25TZXJ2aWNlLmdldChcIkVycm9yc1wiLCBcIkZpZWxkUmVxdWlyZVwiKS5yZXBsYWNlKFxyXG4gICAgICAgICAgICBcInswfVwiLFxyXG4gICAgICAgICAgICBlbGVtW1wibGFiZWxcIl0gPyBlbGVtW1wibGFiZWxcIl1bXCJ2YWx1ZVwiXSA6IGVsZW1bXCJuYW1lXCJdXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5tb2RlbC5zaG93RXJyb3JXaW5kb3cgPSB0cnVlO1xyXG4gICAgICAgICAgdGhpcy5tb2RlbC5zaG93UHJvZ3Jlc3MgPSBmYWxzZTtcclxuICAgICAgICAgIHRoaXMuc2Nyb2xsVG9SZXF1aXJlZChlbGVtKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5odHRwQ2xpZW50XHJcbiAgICAgICAgICAucG9zdCh1cmwsIHhtbClcclxuICAgICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgICBjYXRjaEVycm9yKChkYXRhOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICB0aGlzLm1vZGVsLnNob3dQcm9ncmVzcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgIHRoaXMubW9kZWwuc2hvd0Vycm9yKFN0aUxvY2FsaXphdGlvblNlcnZpY2UuZ2V0KFwiRGVzaWduZXJGeFwiLCBcIkNvbm5lY3Rpb25FcnJvclwiKSwgdHJ1ZSwgdGhpcy5lbGVtZW50KTtcclxuICAgICAgICAgICAgICB0aGlzLm1vZGVsLmludGVyZmFjZUV2ZW50Lm5leHQoeyBuYW1lOiBcIkZvcm1TdWJtaXR0ZWRFcnJvclwiLCBkYXRhOiBkYXRhIH0pO1xyXG4gICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKFwiU29tZXRoaW5nIGJhZCBoYXBwZW5lZDsgcGxlYXNlIHRyeSBhZ2FpbiBsYXRlci5cIik7XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICApXHJcbiAgICAgICAgICAuc3Vic2NyaWJlKChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMubW9kZWwuc2hvd1Byb2dyZXNzID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMubW9kZWwuaW50ZXJmYWNlRXZlbnQubmV4dCh7IG5hbWU6IFwiRm9ybVN1Ym1pdHRlZFwiLCBkYXRhOiBkYXRhIH0pO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuZWxlbWVudC5zdWJtaXNzaW9uTWVzc2FnZSAhPSBudWxsICYmIHRoaXMuZWxlbWVudC5zdWJtaXNzaW9uTWVzc2FnZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5tb2RlbC5zaG93QnV0dG9uTWVzc2FnZVdpbmRvdyA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMubW9kZWwuaW50ZXJmYWNlRXZlbnQubmV4dCh7IG5hbWU6IFwiRm9ybVN1Ym1pdHRlZFwiIH0pO1xyXG5cclxuICAgICAgICBpZiAoXHJcbiAgICAgICAgICB0aGlzLmVsZW1lbnQuc3VibWlzc2lvbk1lc3NhZ2UgIT0gbnVsbCAmJlxyXG4gICAgICAgICAgdGhpcy5lbGVtZW50LnN1Ym1pc3Npb25NZXNzYWdlLmxlbmd0aCA+IDAgJiZcclxuICAgICAgICAgIHRoaXMuZWxlbWVudC5mb3JtU2VuZFVSTFxyXG4gICAgICAgICkge1xyXG4gICAgICAgICAgdGhpcy5tb2RlbC5zaG93QnV0dG9uTWVzc2FnZVdpbmRvdyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWxlbWVudC5idXR0b25UeXBlID09IFN0aUJ1dHRvblR5cGUuQXR0YWNoRmlsZXMgJiYgdGhpcy5tb2RlbC5wcmV2aWV3TW9kZSkge1xyXG4gICAgICB0aGlzLm1vZGVsLmxvYWRBdHRhY2hlZEZpbGUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXQgc2VsZWN0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5tb2RlbC5zZWxlY3RlZENvbXBvbmVudD8uZWxlbWVudCA9PSB0aGlzLmVsZW1lbnQ7XHJcbiAgfVxyXG4gIHB1YmxpYyBzY3JvbGxUb1JlcXVpcmVkKGVsZW0pIHtcclxuICAgIGxldCB3b3Jrc3BhY2UgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInN0aS13b3Jrc3BhY2VcIilbMF07XHJcbiAgICBsZXQgZG9tRWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW0uZ3VpZCk7XHJcbiAgICBsZXQgZWxlbWVudFJlY3QgPSB0aGlzLm1vZGVsLmdldFBvc2l0aW9uUmVsYXRpdmVUb0Zvcm0oZG9tRWxlbWVudCk7XHJcbiAgICBjb25zdCBjb21wb25lbnRIZWFkZXIgPSAzODtcclxuICAgIGxldCBjdXJyZW50U2Nyb2xsUG9zaXRpb24gPSB3b3Jrc3BhY2Uuc2Nyb2xsVG9wO1xyXG4gICAgaWYgKGVsZW1lbnRSZWN0LnRvcCA8IDApIHtcclxuICAgICAgd29ya3NwYWNlLnNjcm9sbFRvcCA9IGN1cnJlbnRTY3JvbGxQb3NpdGlvbiAtIChNYXRoLmFicyhlbGVtZW50UmVjdD8udG9wKSArIGNvbXBvbmVudEhlYWRlcik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB3b3Jrc3BhY2Uuc2Nyb2xsVG9wID0gY3VycmVudFNjcm9sbFBvc2l0aW9uICsgKGVsZW1lbnRSZWN0Py50b3AgLSBjb21wb25lbnRIZWFkZXIpO1xyXG4gICAgfVxyXG4gIH1cclxuICBwdWJsaWMgY3JlYXRlWG1sKCkge1xyXG4gICAgbGV0IHN0cmluZyA9XHJcbiAgICAgIGA8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJVVEYtOFwiPz5cclxuICAgIDx4ZmRmIHhtbG5zPVwiaHR0cDovL25zLmFkb2JlLmNvbS94ZmRmL1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+XHJcbiAgICA8ZmllbGRzPmAgK1xyXG4gICAgICB0aGlzLmFkZFhtbEZpZWxkKHsgbmFtZTogXCJTdGlGb3JtR3VpZFwiLCB2YWx1ZTogdGhpcy5tb2RlbC5mb3JtLmd1aWQgfSkgK1xyXG4gICAgICAodGhpcy5tb2RlbC5mb3JtLnZlcnNpb25LZXkgIT0gbnVsbCAmJiB0aGlzLm1vZGVsLmZvcm0udmVyc2lvbktleS5sZW5ndGggPiAwXHJcbiAgICAgICAgPyB0aGlzLmFkZFhtbEZpZWxkKHsgbmFtZTogXCJTdGlWZXJzaW9uS2V5XCIsIHZhbHVlOiB0aGlzLm1vZGVsLmZvcm0udmVyc2lvbktleSB9KVxyXG4gICAgICAgIDogXCJcIikgK1xyXG4gICAgICAvL3RoaXMuYWRkWG1sRmllbGQoeyBuYW1lOiBcIlN0aVVzZXJJZFwiLCB2YWx1ZTogdGhpcy5tb2RlbC5mb3JtLnVzZXJJZCB9KSArXHJcbiAgICAgIHRoaXMuY3JlYXRlRmllbGRzKCkgK1xyXG4gICAgICB0aGlzLmFkZEF0dGFjaGVkRmlsZXMoKSArXHJcbiAgICAgIHRoaXMuYWRkQWRkaXRpb25zRm9ybUZpZWxkKCkgK1xyXG4gICAgICBgPC9maWVsZHM+XHJcbiAgICA8L3hmZGY+YDtcclxuICAgIHJldHVybiBzdHJpbmc7XHJcbiAgfVxyXG4gIHB1YmxpYyBjcmVhdGVGaWVsZHMoKSB7XHJcbiAgICBsZXQgZmllbGRzOiBzdHJpbmcgPSBcIlwiO1xyXG5cclxuICAgIHRoaXMubW9kZWwuZm9ybS5wYWdlcy5mb3JFYWNoKChwYWdlKSA9PiB7XHJcbiAgICAgIHBhZ2UuYWxsRWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xyXG4gICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgU3RpVGFibGVFbGVtZW50KSB7XHJcbiAgICAgICAgICB0aGlzLm1vZGVsLnJlbW92ZVVudXNlZENlbGxzKGVsZW1lbnQpO1xyXG4gICAgICAgICAgZmllbGRzICs9IHRoaXMuZ2V0WG1sVGFibGVGaWVsZChlbGVtZW50KTtcclxuICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBTdGlBZGRyZXNzRWxlbWVudCkge1xyXG4gICAgICAgICAgZmllbGRzICs9IHRoaXMuZ2V0WG1sQWRkcmVzc0ZpZWxkKGVsZW1lbnQpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsZXQgZmllbGQgPSB0aGlzLmFkZFhtbEZpZWxkKHRoaXMuZ2V0VmFsdWUoZWxlbWVudCkpO1xyXG4gICAgICAgICAgaWYgKGZpZWxkKSB7XHJcbiAgICAgICAgICAgIGZpZWxkcyArPSBmaWVsZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gZmllbGRzO1xyXG4gIH1cclxuICBwdWJsaWMgZm9ybUhhc0VtcHR5UmVxdWlyZWRGaWVsZHMoKTogYm9vbGVhbiB7XHJcbiAgICB0aGlzLm1vZGVsLmhhc0VtcHR5UmV1aXJlZEZpZWxkcyA9IGZhbHNlO1xyXG4gICAgbGV0IGVtcHR5UmVxdWlyZWRFbGVtZW50ID0gbnVsbDtcclxuICAgIGZvciAobGV0IHBhZ2Ugb2YgdGhpcy5tb2RlbC5mb3JtLnBhZ2VzKSB7XHJcbiAgICAgIGZvciAobGV0IGVsZW0gb2YgcGFnZS5hbGxFbGVtZW50cykge1xyXG4gICAgICAgIGlmICgoIWVsZW1bXCJ2YWx1ZVwiXSB8fCBlbGVtW1widmFsdWVcIl0ubGVuZ3RoID09IDApICYmIGVsZW1bXCJyZXF1aXJlZFwiXSkge1xyXG4gICAgICAgICAgZW1wdHlSZXF1aXJlZEVsZW1lbnQgPSBlbGVtO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChlbXB0eVJlcXVpcmVkRWxlbWVudCkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoZW1wdHlSZXF1aXJlZEVsZW1lbnQpIHtcclxuICAgICAgdGhpcy5tb2RlbC5oYXNFbXB0eVJldWlyZWRGaWVsZHMgPSB0cnVlO1xyXG4gICAgICByZXR1cm4gZW1wdHlSZXF1aXJlZEVsZW1lbnQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbiAgcHVibGljIGFkZEFkZGl0aW9uc0Zvcm1GaWVsZCgpIHtcclxuICAgIGxldCBzdHJpbmc6IHN0cmluZyA9IFwiXCI7XHJcbiAgICB0aGlzLm1vZGVsLmZvcm0uYWRkaXRpb25hbEZvcm1GaWVsZHMuZm9yRWFjaCgoZmllbGQpID0+IHtcclxuICAgICAgc3RyaW5nICs9IHRoaXMuYWRkWG1sRmllbGQoeyBuYW1lOiBmaWVsZC5rZXksIHZhbHVlOiBmaWVsZC52YWx1ZSB9KTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHN0cmluZztcclxuICB9XHJcbiAgcHVibGljIGFkZFhtbEZpZWxkKGVsZW1lbnRJbmZvKSB7XHJcbiAgICBpZiAoZWxlbWVudEluZm8gJiYgKGVsZW1lbnRJbmZvLnZhbHVlcyAhPSBudWxsIHx8IGVsZW1lbnRJbmZvLnZhbHVlICE9IG51bGwpKSB7XHJcbiAgICAgIGxldCB2YWwgPSBcIlwiO1xyXG4gICAgICAoZWxlbWVudEluZm8udmFsdWVzID8/IFtlbGVtZW50SW5mby52YWx1ZV0pLmZvckVhY2goKHZhbHVlKSA9PiB7XHJcbiAgICAgICAgdmFsICs9IGA8dmFsdWU+JHt0aGlzLmVuY29kZUhUTUwodmFsdWUpfTwvdmFsdWU+YDtcclxuICAgICAgfSk7XHJcbiAgICAgIHJldHVybiBgPGZpZWxkIG5hbWU9XCIke2VsZW1lbnRJbmZvLm5hbWV9XCI+JHt2YWx9PC9maWVsZD5gO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFwiXCI7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZW5jb2RlSFRNTChkYXRhOiBhbnkpI