tango-app-ui-manage-billing 3.3.16 → 3.3.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/tango-manage-billing/edit-invoice/edit-invoice.component.mjs +20 -3
- package/fesm2022/tango-app-ui-manage-billing.mjs +19 -2
- package/fesm2022/tango-app-ui-manage-billing.mjs.map +1 -1
- package/lib/components/tango-manage-billing/edit-invoice/edit-invoice.component.d.ts +1 -0
- package/package.json +1 -1
|
@@ -94,6 +94,14 @@ export class EditInvoiceComponent {
|
|
|
94
94
|
onProductChange(index) {
|
|
95
95
|
const productGroup = this.products.at(index);
|
|
96
96
|
const selectedName = productGroup.get('productName')?.value;
|
|
97
|
+
// "+ Custom product" picked from the dropdown — switch this row to free-text
|
|
98
|
+
// entry (custom name + price), clearing the base-pricing selection.
|
|
99
|
+
if (selectedName === '__custom__') {
|
|
100
|
+
productGroup.patchValue({ isCustom: true, productName: '', price: 0, description: '' });
|
|
101
|
+
this.recalculate();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
productGroup.get('isCustom')?.setValue(false);
|
|
97
105
|
const product = this.availableProducts.find(p => p.productName === selectedName);
|
|
98
106
|
if (product) {
|
|
99
107
|
productGroup.get('price')?.setValue(product.price);
|
|
@@ -108,6 +116,11 @@ export class EditInvoiceComponent {
|
|
|
108
116
|
this.recalculate();
|
|
109
117
|
}
|
|
110
118
|
}
|
|
119
|
+
// Add a blank product row already in custom (free-text) mode, regardless of
|
|
120
|
+
// whether base-pricing products exist.
|
|
121
|
+
addCustomProduct() {
|
|
122
|
+
this.products.push(this.createProductGroup({ isCustom: true }));
|
|
123
|
+
}
|
|
111
124
|
formatProductName(name) {
|
|
112
125
|
if (!name)
|
|
113
126
|
return '';
|
|
@@ -201,6 +214,10 @@ export class EditInvoiceComponent {
|
|
|
201
214
|
createProductGroup(product) {
|
|
202
215
|
return this.fb.group({
|
|
203
216
|
productName: [product?.productName || '', Validators.required],
|
|
217
|
+
// When true, the name is a free-text custom product (not from the client's
|
|
218
|
+
// base-pricing list) — the template shows a text input instead of the
|
|
219
|
+
// product dropdown.
|
|
220
|
+
isCustom: [product?.isCustom || false],
|
|
204
221
|
description: [product?.description || ''],
|
|
205
222
|
month: [product?.month || ''],
|
|
206
223
|
HsnNumber: [product?.HsnNumber || '998314'],
|
|
@@ -568,11 +585,11 @@ export class EditInvoiceComponent {
|
|
|
568
585
|
});
|
|
569
586
|
}
|
|
570
587
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditInvoiceComponent, deps: [{ token: i1.NgbActiveModal }, { token: i2.FormBuilder }, { token: i3.BillingService }, { token: i0.ChangeDetectorRef }, { token: i4.ToastService }], target: i0.ɵɵFactoryTarget.Component });
|
|
571
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EditInvoiceComponent, selector: "lib-edit-invoice", inputs: { invoiceData: "invoiceData", mode: "mode", clientId: "clientId", billingGroups: "billingGroups" }, ngImport: i0, template: "<div class=\"modal-content\">\n <div class=\"p-5 px-6 pb-0\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"heading mt-2\">{{ mode === 'edit' ? 'Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Edit Estimate' : 'Create Invoice')) }}\n <span *ngIf=\"mode === 'edit'\" class=\"invoice-number\">{{ invoiceData?.invoice }}</span>\n <span *ngIf=\"mode === 'editEstimate'\" class=\"invoice-number\">{{ invoiceData?.estimate }}</span>\n </div>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\"></button>\n </div>\n\n <!-- Tabs (only in edit mode) -->\n <div class=\"tab-bar mt-3\" *ngIf=\"mode === 'edit'\">\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'edit' ? 'tab-active' : ''\"\n (click)=\"setTab('edit')\">Edit Invoice</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'creditNote' ? 'tab-active' : ''\"\n (click)=\"setTab('creditNote')\">Credit Note</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'oneTimeFee' ? 'tab-active' : ''\"\n (click)=\"setTab('oneTimeFee')\">One Time Fee</button>\n </div>\n </div>\n\n <!-- ======================== EDIT INVOICE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'edit' || mode !== 'edit'\">\n <form [formGroup]=\"invoiceForm\" class=\"form\" (ngSubmit)=\"onSubmit()\">\n\n <!-- Company Details Section -->\n <div class=\"section-title mb-3\">Company Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Name <span class=\"text-danger\">*</span></label>\n <input type=\"text\" formControlName=\"companyName\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('companyName')\"\n [readonly]=\"mode === 'edit'\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('companyName')\">Company Name is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">GST Number</label>\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Address</label>\n <input type=\"text\" formControlName=\"companyAddress\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Place of Supply</label>\n <input type=\"text\" formControlName=\"PlaceOfSupply\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Billing Group -->\n <div class=\"row\" *ngIf=\"billingGroups.length > 0\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Group <span *ngIf=\"mode !== 'edit'\" class=\"text-danger\">*</span></label>\n <select *ngIf=\"mode !== 'edit'\" class=\"form-select\" formControlName=\"groupId\"\n [class.is-invalid]=\"controlInvalid('groupId')\"\n (change)=\"onGroupChange($event)\">\n <option value=\"\">Select billing group</option>\n <option *ngFor=\"let g of billingGroups\" [value]=\"g._id\">{{ g.groupName }}</option>\n </select>\n <input *ngIf=\"mode === 'edit'\" type=\"text\" [value]=\"invoiceForm.get('groupName')?.value || 'Default Group'\" class=\"form-control\" readonly>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('groupId')\">Billing Group is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Group Name</label>\n <input type=\"text\" formControlName=\"groupName\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Invoice Details Section -->\n <div class=\"section-title mb-3 mt-2\">Invoice Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"billingDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('billingDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Due Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"dueDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('dueDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('dueDate')\">Due Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Currency <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"currency\"\n [class.is-invalid]=\"controlInvalid('currency')\">\n <option *ngFor=\"let c of currencyOptions\" [value]=\"c\">\n {{ currencyLabels[c] }}\n </option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('currency')\">Currency is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">No. of Stores</label>\n <input type=\"number\" formControlName=\"stores\" class=\"form-control\" readonly>\n </div>\n </div>\n\n <!-- Advance Invoice (create only): bill several future months upfront.\n Each month becomes its own line item server-side. -->\n <div class=\"row\" *ngIf=\"mode === 'create'\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1 d-block\">Advance Invoice</label>\n <div class=\"form-check form-switch mt-1\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"advanceInvoiceCreate\"\n formControlName=\"advanceInvoice\">\n <label class=\"form-check-label\" for=\"advanceInvoiceCreate\">Bill future months upfront</label>\n </div>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"invoiceForm.get('advanceInvoice')?.value\">\n <label class=\"headingtext mb-1\">Advance frequency</label>\n <select class=\"form-select\" formControlName=\"advancePeriod\">\n <option *ngFor=\"let opt of advancePeriodOptions\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n\n <!-- Products Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Products</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addProduct()\">\n + Add Product\n </button>\n </div>\n </div>\n\n <div formArrayName=\"products\">\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeProduct(i)\"\n *ngIf=\"products.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Product Name <span class=\"text-danger\">*</span></label>\n <select *ngIf=\"availableProducts.length > 0\" formControlName=\"productName\"\n class=\"form-select\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n (change)=\"onProductChange(i)\">\n <option value=\"\">Select product</option>\n <option *ngFor=\"let p of availableProducts\" [value]=\"p.productName\">\n {{ formatProductName(p.productName) }}\n </option>\n </select>\n <input *ngIf=\"availableProducts.length === 0\" type=\"text\" formControlName=\"productName\"\n class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n placeholder=\"e.g. tangoTraffic\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'productName')\">Product Name is required</div>\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Description</label>\n <input type=\"text\" formControlName=\"description\" class=\"form-control\"\n placeholder=\"e.g. Customer Footfall Analytics\">\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Month</label>\n <input type=\"text\" formControlName=\"month\" class=\"form-control\"\n placeholder=\"e.g. Mar 2026\">\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">HSN/SAC</label>\n <input type=\"text\" formControlName=\"HsnNumber\" class=\"form-control\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Quantity</label>\n <input type=\"number\" formControlName=\"storeCount\" class=\"form-control\"\n (input)=\"recalculate()\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Rate/Price <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"price\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'price')\">Rate/Price is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Amount</label>\n <input type=\"number\" formControlName=\"amount\" class=\"form-control\" readonly>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Period</label>\n <select class=\"form-select\" formControlName=\"period\">\n <option value=\"monthly\">Monthly</option>\n <option value=\"quarterly\">Quarterly</option>\n <option value=\"halfyearly\">Half-yearly</option>\n <option value=\"yearly\">Yearly</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tax Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Tax</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addTax()\">\n + Add Tax\n </button>\n </div>\n </div>\n\n <div formArrayName=\"tax\">\n <div *ngFor=\"let t of taxArray.controls; let j = index\" [formGroupName]=\"j\"\n class=\"tax-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Tax {{ j + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeTax(j)\"\n *ngIf=\"taxArray.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Type <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"type\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'type')\">\n <option *ngFor=\"let tt of taxTypes\" [value]=\"tt\">{{ tt }}</option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'type')\">Tax Type is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax % <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"value\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'value')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'value')\">Tax % is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Amount</label>\n <input type=\"text\" formControlName=\"taxAmount\" class=\"form-control\" readonly>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Currency Symbol</label>\n <input type=\"text\" formControlName=\"currency\" class=\"form-control\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- Summary -->\n <div class=\"summary-section p-3 mt-3\">\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Subtotal</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getSubtotal() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Total Tax</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getTotalTax() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between summary-total\">\n <span class=\"summary-label-bold\">Total Amount</span>\n <span class=\"summary-value-bold\">{{ getCurrencySymbol() }} {{ getTotalAmount() | number:'1.2-2':'en-IN'\n }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"d-flex mt-4\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button type=\"submit\" [disabled]=\"saving\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\" class=\"submit\">{{ mode === 'edit' ? 'Update Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Update Estimate' : 'Create Invoice'))\n }}</span>\n <span *ngIf=\"saving\" class=\"submit\">Saving...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== CREDIT NOTE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'creditNote' && mode === 'edit'\">\n <form [formGroup]=\"creditNoteForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Apply a credit note / discount to this invoice. Maximum 10% discount allowed.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Total Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Revised Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"revisedAmount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\" *ngIf=\"creditMoreThanTenPercent\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <g clip-path=\"url(#clip_cn_err)\">\n <path\n d=\"M7.99967 5.33301V7.99967M7.99967 10.6663H8.00634M14.6663 7.99967C14.6663 11.6816 11.6816 14.6663 7.99967 14.6663C4.31778 14.6663 1.33301 11.6816 1.33301 7.99967C1.33301 4.31778 4.31778 1.33301 7.99967 1.33301C11.6816 1.33301 14.6663 4.31778 14.6663 7.99967Z\"\n stroke=\"#F04438\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip_cn_err\">\n <rect width=\"16\" height=\"16\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n More than 10% can't be revised from total amount\n </span>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Discount</label>\n <div class=\"input-group\">\n <input type=\"text\" formControlName=\"discount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <path\n d=\"M12.667 3.33366L3.33366 12.667M6.00033 4.33366C6.00033 5.25413 5.25413 6.00033 4.33366 6.00033C3.41318 6.00033 2.66699 5.25413 2.66699 4.33366C2.66699 3.41318 3.41318 2.66699 4.33366 2.66699C5.25413 2.66699 6.00033 3.41318 6.00033 4.33366ZM13.3337 11.667C13.3337 12.5875 12.5875 13.3337 11.667 13.3337C10.7465 13.3337 10.0003 12.5875 10.0003 11.667C10.0003 10.7465 10.7465 10.0003 11.667 10.0003C12.5875 10.0003 13.3337 10.7465 13.3337 11.667Z\"\n [attr.stroke]=\"creditMoreThanTenPercent ? '#F04438' : '#98A2B3'\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n In percentage\n </span>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"creditMoreThanTenPercent || saving\" type=\"button\" (click)=\"applyCreditNote()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Credit Note</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== ONE TIME FEE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'oneTimeFee' && mode === 'edit'\">\n <form [formGroup]=\"oneTimeFeeForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Add a one-time fee (e.g. installation) to this invoice.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Current Invoice Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">One Time Fee (Installation)</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"oneTimeFee\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n placeholder=\"Enter fee amount\">\n </div>\n </div>\n </div>\n\n <div class=\"d-flex flex-stack mt-3 fee-summary p-3\">\n <div class=\"summary-label\">Selected Invoice Amount + One Time Fee</div>\n <div class=\"d-flex align-items-center\">\n <span class=\"summary-value-bold\">{{ getInvoiceCurrencySymbol() }}{{\n oneTimeFeeTotal | number:'1.2-2':'en-IN' }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"saving || !oneTimeFeeForm.get('oneTimeFee')?.value\" type=\"button\"\n (click)=\"applyOneTimeFee()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Fee</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n</div>", styles: [".heading{color:var(--Gray-900, #101828);font-family:Inter;font-size:18px;font-style:normal;font-weight:600;line-height:28px}.invoice-number{color:var(--Primary-700, #009BF3);font-weight:500;margin-left:4px}.contenttext{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.headingtext{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500;line-height:20px}.tab-bar{display:flex;gap:4px;border-bottom:1px solid var(--Gray-200, #EAECF0);padding-bottom:0}.tab-btn{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500;line-height:20px;padding:8px 16px;border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;transition:all .2s}.tab-btn:hover{color:var(--Gray-700, #344054)}.tab-btn.tab-active{color:var(--Primary-700, #009BF3);border-bottom:2px solid var(--Primary-700, #009BF3);font-weight:600}.section-title{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600;line-height:24px;padding-bottom:8px;border-bottom:1px solid var(--Gray-200, #EAECF0)}.product-row,.tax-row{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.product-label{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:600}input,.form-control{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;width:100%;padding:8px 12px;font-family:Inter;font-weight:400;line-height:24px}input:active,input:focus,input:focus-visible{border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD)!important;box-shadow:0 1px 2px #1018280d;outline:none!important;background:var(--Gray-50, #F9FAFB)}input[readonly]{background:var(--Gray-50, #F9FAFB);color:var(--Gray-500, #667085)}.form-select{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;padding:8px 12px;font-family:Inter;font-weight:400;height:auto}.cancel{color:var(--Gray-700, #344054);font-family:Inter;font-size:16px;font-style:normal;font-weight:600;line-height:24px;text-transform:capitalize;border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD);background:var(--White, #FFF)}.summary-section,.fee-summary{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.summary-label{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500}.summary-value{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500}.summary-total{padding-top:8px;border-top:1px solid var(--Gray-200, #EAECF0)}.summary-label-bold,.summary-value-bold{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600}.text-danger{color:var(--Error-500, #F04438)!important;font-family:Inter;font-size:12px!important;font-weight:400}.modal-body{max-height:70vh;overflow-y:auto}.input-group{position:relative}.input-group .dollar-sign{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:400;line-height:24px;z-index:1}.input-group .amount-input{padding-left:30px}.input-group .input-icon{position:absolute;top:50%;right:12px;transform:translateY(-50%);display:inline-flex;align-items:center}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-radius:8px!important}.input-group>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-radius:8px!important}.errorinput{border-radius:8px;border:1px solid var(--Error-300, #FDA29B)!important;background:var(--White, #FFF);box-shadow:0 1px 2px #1018280d}.errorinput:focus{border:1px solid var(--Error-300, #FDA29B)!important}.form-control.is-invalid,.form-select.is-invalid{border:1px solid var(--Error-300, #FDA29B)!important;background:#fef3f2}.form-control.is-invalid:focus,.form-control.is-invalid:active,.form-control.is-invalid:focus-visible,.form-select.is-invalid:focus,.form-select.is-invalid:active,.form-select.is-invalid:focus-visible{border:1px solid var(--Error-300, #FDA29B)!important;box-shadow:0 0 0 4px #f044381f!important;background:#fef3f2}.invalid-msg{color:#b42318;font-family:Inter;font-size:12px;font-weight:500;line-height:18px;margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }] });
|
|
588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EditInvoiceComponent, selector: "lib-edit-invoice", inputs: { invoiceData: "invoiceData", mode: "mode", clientId: "clientId", billingGroups: "billingGroups" }, ngImport: i0, template: "<div class=\"modal-content\">\n <div class=\"p-5 px-6 pb-0\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"heading mt-2\">{{ mode === 'edit' ? 'Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Edit Estimate' : 'Create Invoice')) }}\n <span *ngIf=\"mode === 'edit'\" class=\"invoice-number\">{{ invoiceData?.invoice }}</span>\n <span *ngIf=\"mode === 'editEstimate'\" class=\"invoice-number\">{{ invoiceData?.estimate }}</span>\n </div>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\"></button>\n </div>\n\n <!-- Tabs (only in edit mode) -->\n <div class=\"tab-bar mt-3\" *ngIf=\"mode === 'edit'\">\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'edit' ? 'tab-active' : ''\"\n (click)=\"setTab('edit')\">Edit Invoice</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'creditNote' ? 'tab-active' : ''\"\n (click)=\"setTab('creditNote')\">Credit Note</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'oneTimeFee' ? 'tab-active' : ''\"\n (click)=\"setTab('oneTimeFee')\">One Time Fee</button>\n </div>\n </div>\n\n <!-- ======================== EDIT INVOICE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'edit' || mode !== 'edit'\">\n <form [formGroup]=\"invoiceForm\" class=\"form\" (ngSubmit)=\"onSubmit()\">\n\n <!-- Company Details Section -->\n <div class=\"section-title mb-3\">Company Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Name <span class=\"text-danger\">*</span></label>\n <input type=\"text\" formControlName=\"companyName\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('companyName')\"\n [readonly]=\"mode === 'edit'\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('companyName')\">Company Name is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">GST Number</label>\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Address</label>\n <input type=\"text\" formControlName=\"companyAddress\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Place of Supply</label>\n <input type=\"text\" formControlName=\"PlaceOfSupply\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Billing Group -->\n <div class=\"row\" *ngIf=\"billingGroups.length > 0\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Group <span *ngIf=\"mode !== 'edit'\" class=\"text-danger\">*</span></label>\n <select *ngIf=\"mode !== 'edit'\" class=\"form-select\" formControlName=\"groupId\"\n [class.is-invalid]=\"controlInvalid('groupId')\"\n (change)=\"onGroupChange($event)\">\n <option value=\"\">Select billing group</option>\n <option *ngFor=\"let g of billingGroups\" [value]=\"g._id\">{{ g.groupName }}</option>\n </select>\n <input *ngIf=\"mode === 'edit'\" type=\"text\" [value]=\"invoiceForm.get('groupName')?.value || 'Default Group'\" class=\"form-control\" readonly>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('groupId')\">Billing Group is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Group Name</label>\n <input type=\"text\" formControlName=\"groupName\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Invoice Details Section -->\n <div class=\"section-title mb-3 mt-2\">Invoice Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"billingDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('billingDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Due Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"dueDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('dueDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('dueDate')\">Due Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Currency <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"currency\"\n [class.is-invalid]=\"controlInvalid('currency')\">\n <option *ngFor=\"let c of currencyOptions\" [value]=\"c\">\n {{ currencyLabels[c] }}\n </option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('currency')\">Currency is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">No. of Stores</label>\n <input type=\"number\" formControlName=\"stores\" class=\"form-control\" readonly>\n </div>\n </div>\n\n <!-- Advance Invoice (create only): bill several future months upfront.\n Each month becomes its own line item server-side. -->\n <div class=\"row\" *ngIf=\"mode === 'create'\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1 d-block\">Advance Invoice</label>\n <div class=\"form-check form-switch mt-1\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"advanceInvoiceCreate\"\n formControlName=\"advanceInvoice\">\n <label class=\"form-check-label\" for=\"advanceInvoiceCreate\">Bill future months upfront</label>\n </div>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"invoiceForm.get('advanceInvoice')?.value\">\n <label class=\"headingtext mb-1\">Advance frequency</label>\n <select class=\"form-select\" formControlName=\"advancePeriod\">\n <option *ngFor=\"let opt of advancePeriodOptions\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n\n <!-- Products Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Products</span>\n <div class=\"d-flex gap-2\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addProduct()\">\n + Add Product\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"addCustomProduct()\">\n + Add Custom Product\n </button>\n </div>\n </div>\n </div>\n\n <div formArrayName=\"products\">\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeProduct(i)\"\n *ngIf=\"products.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Product Name <span class=\"text-danger\">*</span></label>\n <!-- Base-pricing dropdown (with a \"+ Custom product\" choice) when\n products exist and this row isn't custom; otherwise a free-text\n name input for a custom product. -->\n <select *ngIf=\"availableProducts.length > 0 && !product.get('isCustom')?.value\" formControlName=\"productName\"\n class=\"form-select\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n (change)=\"onProductChange(i)\">\n <option value=\"\">Select product</option>\n <option *ngFor=\"let p of availableProducts\" [value]=\"p.productName\">\n {{ formatProductName(p.productName) }}\n </option>\n <option value=\"__custom__\">+ Custom product</option>\n </select>\n <input *ngIf=\"availableProducts.length === 0 || product.get('isCustom')?.value\" type=\"text\" formControlName=\"productName\"\n class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n placeholder=\"e.g. Custom Service\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'productName')\">Product Name is required</div>\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Description</label>\n <input type=\"text\" formControlName=\"description\" class=\"form-control\"\n placeholder=\"e.g. Customer Footfall Analytics\">\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Month</label>\n <input type=\"text\" formControlName=\"month\" class=\"form-control\"\n placeholder=\"e.g. Mar 2026\">\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">HSN/SAC</label>\n <input type=\"text\" formControlName=\"HsnNumber\" class=\"form-control\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Quantity</label>\n <input type=\"number\" formControlName=\"storeCount\" class=\"form-control\"\n (input)=\"recalculate()\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Rate/Price <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"price\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'price')\">Rate/Price is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Amount</label>\n <input type=\"number\" formControlName=\"amount\" class=\"form-control\" readonly>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Period</label>\n <select class=\"form-select\" formControlName=\"period\">\n <option value=\"monthly\">Monthly</option>\n <option value=\"quarterly\">Quarterly</option>\n <option value=\"halfyearly\">Half-yearly</option>\n <option value=\"yearly\">Yearly</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tax Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Tax</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addTax()\">\n + Add Tax\n </button>\n </div>\n </div>\n\n <div formArrayName=\"tax\">\n <div *ngFor=\"let t of taxArray.controls; let j = index\" [formGroupName]=\"j\"\n class=\"tax-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Tax {{ j + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeTax(j)\"\n *ngIf=\"taxArray.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Type <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"type\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'type')\">\n <option *ngFor=\"let tt of taxTypes\" [value]=\"tt\">{{ tt }}</option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'type')\">Tax Type is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax % <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"value\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'value')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'value')\">Tax % is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Amount</label>\n <input type=\"text\" formControlName=\"taxAmount\" class=\"form-control\" readonly>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Currency Symbol</label>\n <input type=\"text\" formControlName=\"currency\" class=\"form-control\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- Summary -->\n <div class=\"summary-section p-3 mt-3\">\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Subtotal</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getSubtotal() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Total Tax</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getTotalTax() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between summary-total\">\n <span class=\"summary-label-bold\">Total Amount</span>\n <span class=\"summary-value-bold\">{{ getCurrencySymbol() }} {{ getTotalAmount() | number:'1.2-2':'en-IN'\n }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"d-flex mt-4\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button type=\"submit\" [disabled]=\"saving\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\" class=\"submit\">{{ mode === 'edit' ? 'Update Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Update Estimate' : 'Create Invoice'))\n }}</span>\n <span *ngIf=\"saving\" class=\"submit\">Saving...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== CREDIT NOTE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'creditNote' && mode === 'edit'\">\n <form [formGroup]=\"creditNoteForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Apply a credit note / discount to this invoice. Maximum 10% discount allowed.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Total Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Revised Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"revisedAmount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\" *ngIf=\"creditMoreThanTenPercent\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <g clip-path=\"url(#clip_cn_err)\">\n <path\n d=\"M7.99967 5.33301V7.99967M7.99967 10.6663H8.00634M14.6663 7.99967C14.6663 11.6816 11.6816 14.6663 7.99967 14.6663C4.31778 14.6663 1.33301 11.6816 1.33301 7.99967C1.33301 4.31778 4.31778 1.33301 7.99967 1.33301C11.6816 1.33301 14.6663 4.31778 14.6663 7.99967Z\"\n stroke=\"#F04438\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip_cn_err\">\n <rect width=\"16\" height=\"16\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n More than 10% can't be revised from total amount\n </span>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Discount</label>\n <div class=\"input-group\">\n <input type=\"text\" formControlName=\"discount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <path\n d=\"M12.667 3.33366L3.33366 12.667M6.00033 4.33366C6.00033 5.25413 5.25413 6.00033 4.33366 6.00033C3.41318 6.00033 2.66699 5.25413 2.66699 4.33366C2.66699 3.41318 3.41318 2.66699 4.33366 2.66699C5.25413 2.66699 6.00033 3.41318 6.00033 4.33366ZM13.3337 11.667C13.3337 12.5875 12.5875 13.3337 11.667 13.3337C10.7465 13.3337 10.0003 12.5875 10.0003 11.667C10.0003 10.7465 10.7465 10.0003 11.667 10.0003C12.5875 10.0003 13.3337 10.7465 13.3337 11.667Z\"\n [attr.stroke]=\"creditMoreThanTenPercent ? '#F04438' : '#98A2B3'\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n In percentage\n </span>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"creditMoreThanTenPercent || saving\" type=\"button\" (click)=\"applyCreditNote()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Credit Note</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== ONE TIME FEE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'oneTimeFee' && mode === 'edit'\">\n <form [formGroup]=\"oneTimeFeeForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Add a one-time fee (e.g. installation) to this invoice.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Current Invoice Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">One Time Fee (Installation)</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"oneTimeFee\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n placeholder=\"Enter fee amount\">\n </div>\n </div>\n </div>\n\n <div class=\"d-flex flex-stack mt-3 fee-summary p-3\">\n <div class=\"summary-label\">Selected Invoice Amount + One Time Fee</div>\n <div class=\"d-flex align-items-center\">\n <span class=\"summary-value-bold\">{{ getInvoiceCurrencySymbol() }}{{\n oneTimeFeeTotal | number:'1.2-2':'en-IN' }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"saving || !oneTimeFeeForm.get('oneTimeFee')?.value\" type=\"button\"\n (click)=\"applyOneTimeFee()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Fee</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n</div>", styles: [".heading{color:var(--Gray-900, #101828);font-family:Inter;font-size:18px;font-style:normal;font-weight:600;line-height:28px}.invoice-number{color:var(--Primary-700, #009BF3);font-weight:500;margin-left:4px}.contenttext{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.headingtext{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500;line-height:20px}.tab-bar{display:flex;gap:4px;border-bottom:1px solid var(--Gray-200, #EAECF0);padding-bottom:0}.tab-btn{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500;line-height:20px;padding:8px 16px;border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;transition:all .2s}.tab-btn:hover{color:var(--Gray-700, #344054)}.tab-btn.tab-active{color:var(--Primary-700, #009BF3);border-bottom:2px solid var(--Primary-700, #009BF3);font-weight:600}.section-title{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600;line-height:24px;padding-bottom:8px;border-bottom:1px solid var(--Gray-200, #EAECF0)}.product-row,.tax-row{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.product-label{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:600}input,.form-control{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;width:100%;padding:8px 12px;font-family:Inter;font-weight:400;line-height:24px}input:active,input:focus,input:focus-visible{border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD)!important;box-shadow:0 1px 2px #1018280d;outline:none!important;background:var(--Gray-50, #F9FAFB)}input[readonly]{background:var(--Gray-50, #F9FAFB);color:var(--Gray-500, #667085)}.form-select{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;padding:8px 12px;font-family:Inter;font-weight:400;height:auto}.cancel{color:var(--Gray-700, #344054);font-family:Inter;font-size:16px;font-style:normal;font-weight:600;line-height:24px;text-transform:capitalize;border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD);background:var(--White, #FFF)}.summary-section,.fee-summary{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.summary-label{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500}.summary-value{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500}.summary-total{padding-top:8px;border-top:1px solid var(--Gray-200, #EAECF0)}.summary-label-bold,.summary-value-bold{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600}.text-danger{color:var(--Error-500, #F04438)!important;font-family:Inter;font-size:12px!important;font-weight:400}.modal-body{max-height:70vh;overflow-y:auto}.input-group{position:relative}.input-group .dollar-sign{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:400;line-height:24px;z-index:1}.input-group .amount-input{padding-left:30px}.input-group .input-icon{position:absolute;top:50%;right:12px;transform:translateY(-50%);display:inline-flex;align-items:center}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-radius:8px!important}.input-group>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-radius:8px!important}.errorinput{border-radius:8px;border:1px solid var(--Error-300, #FDA29B)!important;background:var(--White, #FFF);box-shadow:0 1px 2px #1018280d}.errorinput:focus{border:1px solid var(--Error-300, #FDA29B)!important}.form-control.is-invalid,.form-select.is-invalid{border:1px solid var(--Error-300, #FDA29B)!important;background:#fef3f2}.form-control.is-invalid:focus,.form-control.is-invalid:active,.form-control.is-invalid:focus-visible,.form-select.is-invalid:focus,.form-select.is-invalid:active,.form-select.is-invalid:focus-visible{border:1px solid var(--Error-300, #FDA29B)!important;box-shadow:0 0 0 4px #f044381f!important;background:#fef3f2}.invalid-msg{color:#b42318;font-family:Inter;font-size:12px;font-weight:500;line-height:18px;margin-top:4px}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "pipe", type: i5.DecimalPipe, name: "number" }] });
|
|
572
589
|
}
|
|
573
590
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditInvoiceComponent, decorators: [{
|
|
574
591
|
type: Component,
|
|
575
|
-
args: [{ selector: 'lib-edit-invoice', template: "<div class=\"modal-content\">\n <div class=\"p-5 px-6 pb-0\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"heading mt-2\">{{ mode === 'edit' ? 'Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Edit Estimate' : 'Create Invoice')) }}\n <span *ngIf=\"mode === 'edit'\" class=\"invoice-number\">{{ invoiceData?.invoice }}</span>\n <span *ngIf=\"mode === 'editEstimate'\" class=\"invoice-number\">{{ invoiceData?.estimate }}</span>\n </div>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\"></button>\n </div>\n\n <!-- Tabs (only in edit mode) -->\n <div class=\"tab-bar mt-3\" *ngIf=\"mode === 'edit'\">\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'edit' ? 'tab-active' : ''\"\n (click)=\"setTab('edit')\">Edit Invoice</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'creditNote' ? 'tab-active' : ''\"\n (click)=\"setTab('creditNote')\">Credit Note</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'oneTimeFee' ? 'tab-active' : ''\"\n (click)=\"setTab('oneTimeFee')\">One Time Fee</button>\n </div>\n </div>\n\n <!-- ======================== EDIT INVOICE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'edit' || mode !== 'edit'\">\n <form [formGroup]=\"invoiceForm\" class=\"form\" (ngSubmit)=\"onSubmit()\">\n\n <!-- Company Details Section -->\n <div class=\"section-title mb-3\">Company Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Name <span class=\"text-danger\">*</span></label>\n <input type=\"text\" formControlName=\"companyName\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('companyName')\"\n [readonly]=\"mode === 'edit'\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('companyName')\">Company Name is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">GST Number</label>\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Address</label>\n <input type=\"text\" formControlName=\"companyAddress\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Place of Supply</label>\n <input type=\"text\" formControlName=\"PlaceOfSupply\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Billing Group -->\n <div class=\"row\" *ngIf=\"billingGroups.length > 0\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Group <span *ngIf=\"mode !== 'edit'\" class=\"text-danger\">*</span></label>\n <select *ngIf=\"mode !== 'edit'\" class=\"form-select\" formControlName=\"groupId\"\n [class.is-invalid]=\"controlInvalid('groupId')\"\n (change)=\"onGroupChange($event)\">\n <option value=\"\">Select billing group</option>\n <option *ngFor=\"let g of billingGroups\" [value]=\"g._id\">{{ g.groupName }}</option>\n </select>\n <input *ngIf=\"mode === 'edit'\" type=\"text\" [value]=\"invoiceForm.get('groupName')?.value || 'Default Group'\" class=\"form-control\" readonly>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('groupId')\">Billing Group is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Group Name</label>\n <input type=\"text\" formControlName=\"groupName\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Invoice Details Section -->\n <div class=\"section-title mb-3 mt-2\">Invoice Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"billingDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('billingDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Due Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"dueDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('dueDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('dueDate')\">Due Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Currency <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"currency\"\n [class.is-invalid]=\"controlInvalid('currency')\">\n <option *ngFor=\"let c of currencyOptions\" [value]=\"c\">\n {{ currencyLabels[c] }}\n </option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('currency')\">Currency is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">No. of Stores</label>\n <input type=\"number\" formControlName=\"stores\" class=\"form-control\" readonly>\n </div>\n </div>\n\n <!-- Advance Invoice (create only): bill several future months upfront.\n Each month becomes its own line item server-side. -->\n <div class=\"row\" *ngIf=\"mode === 'create'\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1 d-block\">Advance Invoice</label>\n <div class=\"form-check form-switch mt-1\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"advanceInvoiceCreate\"\n formControlName=\"advanceInvoice\">\n <label class=\"form-check-label\" for=\"advanceInvoiceCreate\">Bill future months upfront</label>\n </div>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"invoiceForm.get('advanceInvoice')?.value\">\n <label class=\"headingtext mb-1\">Advance frequency</label>\n <select class=\"form-select\" formControlName=\"advancePeriod\">\n <option *ngFor=\"let opt of advancePeriodOptions\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n\n <!-- Products Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Products</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addProduct()\">\n + Add Product\n </button>\n </div>\n </div>\n\n <div formArrayName=\"products\">\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeProduct(i)\"\n *ngIf=\"products.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Product Name <span class=\"text-danger\">*</span></label>\n <select *ngIf=\"availableProducts.length > 0\" formControlName=\"productName\"\n class=\"form-select\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n (change)=\"onProductChange(i)\">\n <option value=\"\">Select product</option>\n <option *ngFor=\"let p of availableProducts\" [value]=\"p.productName\">\n {{ formatProductName(p.productName) }}\n </option>\n </select>\n <input *ngIf=\"availableProducts.length === 0\" type=\"text\" formControlName=\"productName\"\n class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n placeholder=\"e.g. tangoTraffic\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'productName')\">Product Name is required</div>\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Description</label>\n <input type=\"text\" formControlName=\"description\" class=\"form-control\"\n placeholder=\"e.g. Customer Footfall Analytics\">\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Month</label>\n <input type=\"text\" formControlName=\"month\" class=\"form-control\"\n placeholder=\"e.g. Mar 2026\">\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">HSN/SAC</label>\n <input type=\"text\" formControlName=\"HsnNumber\" class=\"form-control\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Quantity</label>\n <input type=\"number\" formControlName=\"storeCount\" class=\"form-control\"\n (input)=\"recalculate()\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Rate/Price <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"price\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'price')\">Rate/Price is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Amount</label>\n <input type=\"number\" formControlName=\"amount\" class=\"form-control\" readonly>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Period</label>\n <select class=\"form-select\" formControlName=\"period\">\n <option value=\"monthly\">Monthly</option>\n <option value=\"quarterly\">Quarterly</option>\n <option value=\"halfyearly\">Half-yearly</option>\n <option value=\"yearly\">Yearly</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tax Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Tax</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addTax()\">\n + Add Tax\n </button>\n </div>\n </div>\n\n <div formArrayName=\"tax\">\n <div *ngFor=\"let t of taxArray.controls; let j = index\" [formGroupName]=\"j\"\n class=\"tax-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Tax {{ j + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeTax(j)\"\n *ngIf=\"taxArray.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Type <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"type\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'type')\">\n <option *ngFor=\"let tt of taxTypes\" [value]=\"tt\">{{ tt }}</option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'type')\">Tax Type is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax % <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"value\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'value')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'value')\">Tax % is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Amount</label>\n <input type=\"text\" formControlName=\"taxAmount\" class=\"form-control\" readonly>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Currency Symbol</label>\n <input type=\"text\" formControlName=\"currency\" class=\"form-control\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- Summary -->\n <div class=\"summary-section p-3 mt-3\">\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Subtotal</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getSubtotal() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Total Tax</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getTotalTax() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between summary-total\">\n <span class=\"summary-label-bold\">Total Amount</span>\n <span class=\"summary-value-bold\">{{ getCurrencySymbol() }} {{ getTotalAmount() | number:'1.2-2':'en-IN'\n }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"d-flex mt-4\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button type=\"submit\" [disabled]=\"saving\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\" class=\"submit\">{{ mode === 'edit' ? 'Update Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Update Estimate' : 'Create Invoice'))\n }}</span>\n <span *ngIf=\"saving\" class=\"submit\">Saving...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== CREDIT NOTE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'creditNote' && mode === 'edit'\">\n <form [formGroup]=\"creditNoteForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Apply a credit note / discount to this invoice. Maximum 10% discount allowed.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Total Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Revised Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"revisedAmount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\" *ngIf=\"creditMoreThanTenPercent\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <g clip-path=\"url(#clip_cn_err)\">\n <path\n d=\"M7.99967 5.33301V7.99967M7.99967 10.6663H8.00634M14.6663 7.99967C14.6663 11.6816 11.6816 14.6663 7.99967 14.6663C4.31778 14.6663 1.33301 11.6816 1.33301 7.99967C1.33301 4.31778 4.31778 1.33301 7.99967 1.33301C11.6816 1.33301 14.6663 4.31778 14.6663 7.99967Z\"\n stroke=\"#F04438\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip_cn_err\">\n <rect width=\"16\" height=\"16\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n More than 10% can't be revised from total amount\n </span>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Discount</label>\n <div class=\"input-group\">\n <input type=\"text\" formControlName=\"discount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <path\n d=\"M12.667 3.33366L3.33366 12.667M6.00033 4.33366C6.00033 5.25413 5.25413 6.00033 4.33366 6.00033C3.41318 6.00033 2.66699 5.25413 2.66699 4.33366C2.66699 3.41318 3.41318 2.66699 4.33366 2.66699C5.25413 2.66699 6.00033 3.41318 6.00033 4.33366ZM13.3337 11.667C13.3337 12.5875 12.5875 13.3337 11.667 13.3337C10.7465 13.3337 10.0003 12.5875 10.0003 11.667C10.0003 10.7465 10.7465 10.0003 11.667 10.0003C12.5875 10.0003 13.3337 10.7465 13.3337 11.667Z\"\n [attr.stroke]=\"creditMoreThanTenPercent ? '#F04438' : '#98A2B3'\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n In percentage\n </span>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"creditMoreThanTenPercent || saving\" type=\"button\" (click)=\"applyCreditNote()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Credit Note</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== ONE TIME FEE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'oneTimeFee' && mode === 'edit'\">\n <form [formGroup]=\"oneTimeFeeForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Add a one-time fee (e.g. installation) to this invoice.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Current Invoice Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">One Time Fee (Installation)</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"oneTimeFee\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n placeholder=\"Enter fee amount\">\n </div>\n </div>\n </div>\n\n <div class=\"d-flex flex-stack mt-3 fee-summary p-3\">\n <div class=\"summary-label\">Selected Invoice Amount + One Time Fee</div>\n <div class=\"d-flex align-items-center\">\n <span class=\"summary-value-bold\">{{ getInvoiceCurrencySymbol() }}{{\n oneTimeFeeTotal | number:'1.2-2':'en-IN' }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"saving || !oneTimeFeeForm.get('oneTimeFee')?.value\" type=\"button\"\n (click)=\"applyOneTimeFee()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Fee</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n</div>", styles: [".heading{color:var(--Gray-900, #101828);font-family:Inter;font-size:18px;font-style:normal;font-weight:600;line-height:28px}.invoice-number{color:var(--Primary-700, #009BF3);font-weight:500;margin-left:4px}.contenttext{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.headingtext{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500;line-height:20px}.tab-bar{display:flex;gap:4px;border-bottom:1px solid var(--Gray-200, #EAECF0);padding-bottom:0}.tab-btn{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500;line-height:20px;padding:8px 16px;border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;transition:all .2s}.tab-btn:hover{color:var(--Gray-700, #344054)}.tab-btn.tab-active{color:var(--Primary-700, #009BF3);border-bottom:2px solid var(--Primary-700, #009BF3);font-weight:600}.section-title{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600;line-height:24px;padding-bottom:8px;border-bottom:1px solid var(--Gray-200, #EAECF0)}.product-row,.tax-row{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.product-label{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:600}input,.form-control{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;width:100%;padding:8px 12px;font-family:Inter;font-weight:400;line-height:24px}input:active,input:focus,input:focus-visible{border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD)!important;box-shadow:0 1px 2px #1018280d;outline:none!important;background:var(--Gray-50, #F9FAFB)}input[readonly]{background:var(--Gray-50, #F9FAFB);color:var(--Gray-500, #667085)}.form-select{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;padding:8px 12px;font-family:Inter;font-weight:400;height:auto}.cancel{color:var(--Gray-700, #344054);font-family:Inter;font-size:16px;font-style:normal;font-weight:600;line-height:24px;text-transform:capitalize;border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD);background:var(--White, #FFF)}.summary-section,.fee-summary{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.summary-label{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500}.summary-value{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500}.summary-total{padding-top:8px;border-top:1px solid var(--Gray-200, #EAECF0)}.summary-label-bold,.summary-value-bold{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600}.text-danger{color:var(--Error-500, #F04438)!important;font-family:Inter;font-size:12px!important;font-weight:400}.modal-body{max-height:70vh;overflow-y:auto}.input-group{position:relative}.input-group .dollar-sign{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:400;line-height:24px;z-index:1}.input-group .amount-input{padding-left:30px}.input-group .input-icon{position:absolute;top:50%;right:12px;transform:translateY(-50%);display:inline-flex;align-items:center}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-radius:8px!important}.input-group>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-radius:8px!important}.errorinput{border-radius:8px;border:1px solid var(--Error-300, #FDA29B)!important;background:var(--White, #FFF);box-shadow:0 1px 2px #1018280d}.errorinput:focus{border:1px solid var(--Error-300, #FDA29B)!important}.form-control.is-invalid,.form-select.is-invalid{border:1px solid var(--Error-300, #FDA29B)!important;background:#fef3f2}.form-control.is-invalid:focus,.form-control.is-invalid:active,.form-control.is-invalid:focus-visible,.form-select.is-invalid:focus,.form-select.is-invalid:active,.form-select.is-invalid:focus-visible{border:1px solid var(--Error-300, #FDA29B)!important;box-shadow:0 0 0 4px #f044381f!important;background:#fef3f2}.invalid-msg{color:#b42318;font-family:Inter;font-size:12px;font-weight:500;line-height:18px;margin-top:4px}\n"] }]
|
|
592
|
+
args: [{ selector: 'lib-edit-invoice', template: "<div class=\"modal-content\">\n <div class=\"p-5 px-6 pb-0\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <div class=\"heading mt-2\">{{ mode === 'edit' ? 'Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Edit Estimate' : 'Create Invoice')) }}\n <span *ngIf=\"mode === 'edit'\" class=\"invoice-number\">{{ invoiceData?.invoice }}</span>\n <span *ngIf=\"mode === 'editEstimate'\" class=\"invoice-number\">{{ invoiceData?.estimate }}</span>\n </div>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\"></button>\n </div>\n\n <!-- Tabs (only in edit mode) -->\n <div class=\"tab-bar mt-3\" *ngIf=\"mode === 'edit'\">\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'edit' ? 'tab-active' : ''\"\n (click)=\"setTab('edit')\">Edit Invoice</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'creditNote' ? 'tab-active' : ''\"\n (click)=\"setTab('creditNote')\">Credit Note</button>\n <button class=\"tab-btn\" [ngClass]=\"activeTab === 'oneTimeFee' ? 'tab-active' : ''\"\n (click)=\"setTab('oneTimeFee')\">One Time Fee</button>\n </div>\n </div>\n\n <!-- ======================== EDIT INVOICE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'edit' || mode !== 'edit'\">\n <form [formGroup]=\"invoiceForm\" class=\"form\" (ngSubmit)=\"onSubmit()\">\n\n <!-- Company Details Section -->\n <div class=\"section-title mb-3\">Company Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Name <span class=\"text-danger\">*</span></label>\n <input type=\"text\" formControlName=\"companyName\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('companyName')\"\n [readonly]=\"mode === 'edit'\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('companyName')\">Company Name is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">GST Number</label>\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Company Address</label>\n <input type=\"text\" formControlName=\"companyAddress\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Place of Supply</label>\n <input type=\"text\" formControlName=\"PlaceOfSupply\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Billing Group -->\n <div class=\"row\" *ngIf=\"billingGroups.length > 0\">\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Group <span *ngIf=\"mode !== 'edit'\" class=\"text-danger\">*</span></label>\n <select *ngIf=\"mode !== 'edit'\" class=\"form-select\" formControlName=\"groupId\"\n [class.is-invalid]=\"controlInvalid('groupId')\"\n (change)=\"onGroupChange($event)\">\n <option value=\"\">Select billing group</option>\n <option *ngFor=\"let g of billingGroups\" [value]=\"g._id\">{{ g.groupName }}</option>\n </select>\n <input *ngIf=\"mode === 'edit'\" type=\"text\" [value]=\"invoiceForm.get('groupName')?.value || 'Default Group'\" class=\"form-control\" readonly>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('groupId')\">Billing Group is required</div>\n </div>\n <div class=\"col-md-6 form-group mb-3\">\n <label class=\"headingtext mb-1\">Group Name</label>\n <input type=\"text\" formControlName=\"groupName\" class=\"form-control\" [readonly]=\"mode === 'edit'\">\n </div>\n </div>\n\n <!-- Invoice Details Section -->\n <div class=\"section-title mb-3 mt-2\">Invoice Details</div>\n\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Billing Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"billingDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('billingDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Due Date <span class=\"text-danger\">*</span></label>\n <input type=\"date\" formControlName=\"dueDate\" class=\"form-control\"\n [class.is-invalid]=\"controlInvalid('dueDate')\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('dueDate')\">Due Date is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">Currency <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"currency\"\n [class.is-invalid]=\"controlInvalid('currency')\">\n <option *ngFor=\"let c of currencyOptions\" [value]=\"c\">\n {{ currencyLabels[c] }}\n </option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('currency')\">Currency is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1\">No. of Stores</label>\n <input type=\"number\" formControlName=\"stores\" class=\"form-control\" readonly>\n </div>\n </div>\n\n <!-- Advance Invoice (create only): bill several future months upfront.\n Each month becomes its own line item server-side. -->\n <div class=\"row\" *ngIf=\"mode === 'create'\">\n <div class=\"col-md-3 form-group mb-3\">\n <label class=\"headingtext mb-1 d-block\">Advance Invoice</label>\n <div class=\"form-check form-switch mt-1\">\n <input class=\"form-check-input\" type=\"checkbox\" id=\"advanceInvoiceCreate\"\n formControlName=\"advanceInvoice\">\n <label class=\"form-check-label\" for=\"advanceInvoiceCreate\">Bill future months upfront</label>\n </div>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"invoiceForm.get('advanceInvoice')?.value\">\n <label class=\"headingtext mb-1\">Advance frequency</label>\n <select class=\"form-select\" formControlName=\"advancePeriod\">\n <option *ngFor=\"let opt of advancePeriodOptions\" [value]=\"opt.value\">{{ opt.label }}</option>\n </select>\n </div>\n </div>\n\n\n <!-- Products Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Products</span>\n <div class=\"d-flex gap-2\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addProduct()\">\n + Add Product\n </button>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"addCustomProduct()\">\n + Add Custom Product\n </button>\n </div>\n </div>\n </div>\n\n <div formArrayName=\"products\">\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeProduct(i)\"\n *ngIf=\"products.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Product Name <span class=\"text-danger\">*</span></label>\n <!-- Base-pricing dropdown (with a \"+ Custom product\" choice) when\n products exist and this row isn't custom; otherwise a free-text\n name input for a custom product. -->\n <select *ngIf=\"availableProducts.length > 0 && !product.get('isCustom')?.value\" formControlName=\"productName\"\n class=\"form-select\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n (change)=\"onProductChange(i)\">\n <option value=\"\">Select product</option>\n <option *ngFor=\"let p of availableProducts\" [value]=\"p.productName\">\n {{ formatProductName(p.productName) }}\n </option>\n <option value=\"__custom__\">+ Custom product</option>\n </select>\n <input *ngIf=\"availableProducts.length === 0 || product.get('isCustom')?.value\" type=\"text\" formControlName=\"productName\"\n class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'productName')\"\n placeholder=\"e.g. Custom Service\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'productName')\">Product Name is required</div>\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Description</label>\n <input type=\"text\" formControlName=\"description\" class=\"form-control\"\n placeholder=\"e.g. Customer Footfall Analytics\">\n </div>\n <div class=\"col-md-4 form-group mb-2\">\n <label class=\"headingtext mb-1\">Month</label>\n <input type=\"text\" formControlName=\"month\" class=\"form-control\"\n placeholder=\"e.g. Mar 2026\">\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">HSN/SAC</label>\n <input type=\"text\" formControlName=\"HsnNumber\" class=\"form-control\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Quantity</label>\n <input type=\"number\" formControlName=\"storeCount\" class=\"form-control\"\n (input)=\"recalculate()\">\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Rate/Price <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"price\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('products', i, 'price')\">Rate/Price is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Amount</label>\n <input type=\"number\" formControlName=\"amount\" class=\"form-control\" readonly>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Period</label>\n <select class=\"form-select\" formControlName=\"period\">\n <option value=\"monthly\">Monthly</option>\n <option value=\"quarterly\">Quarterly</option>\n <option value=\"halfyearly\">Half-yearly</option>\n <option value=\"yearly\">Yearly</option>\n </select>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tax Section -->\n <div class=\"section-title mb-3 mt-2\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <span>Tax</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"addTax()\">\n + Add Tax\n </button>\n </div>\n </div>\n\n <div formArrayName=\"tax\">\n <div *ngFor=\"let t of taxArray.controls; let j = index\" [formGroupName]=\"j\"\n class=\"tax-row mb-3 p-3\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"product-label\">Tax {{ j + 1 }}</span>\n <button type=\"button\" class=\"btn btn-sm btn-outline-danger\" (click)=\"removeTax(j)\"\n *ngIf=\"taxArray.length > 1\">\n Remove\n </button>\n </div>\n <div class=\"row\">\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Type <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"type\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'type')\">\n <option *ngFor=\"let tt of taxTypes\" [value]=\"tt\">{{ tt }}</option>\n </select>\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'type')\">Tax Type is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax % <span class=\"text-danger\">*</span></label>\n <input type=\"number\" formControlName=\"value\" class=\"form-control\"\n [class.is-invalid]=\"arrayControlInvalid('tax', j, 'value')\"\n (input)=\"recalculate()\">\n <div class=\"invalid-msg\" *ngIf=\"arrayControlInvalid('tax', j, 'value')\">Tax % is required</div>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Tax Amount</label>\n <input type=\"text\" formControlName=\"taxAmount\" class=\"form-control\" readonly>\n </div>\n <div class=\"col-md-3 form-group mb-2\">\n <label class=\"headingtext mb-1\">Currency Symbol</label>\n <input type=\"text\" formControlName=\"currency\" class=\"form-control\">\n </div>\n </div>\n </div>\n </div>\n\n <!-- Summary -->\n <div class=\"summary-section p-3 mt-3\">\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Subtotal</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getSubtotal() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\">\n <span class=\"summary-label\">Total Tax</span>\n <span class=\"summary-value\">{{ getCurrencySymbol() }} {{ getTotalTax() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between summary-total\">\n <span class=\"summary-label-bold\">Total Amount</span>\n <span class=\"summary-value-bold\">{{ getCurrencySymbol() }} {{ getTotalAmount() | number:'1.2-2':'en-IN'\n }}</span>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"d-flex mt-4\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button type=\"submit\" [disabled]=\"saving\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\" class=\"submit\">{{ mode === 'edit' ? 'Update Invoice' : (mode === 'estimate' ? 'Generate Estimate' : (mode === 'editEstimate' ? 'Update Estimate' : 'Create Invoice'))\n }}</span>\n <span *ngIf=\"saving\" class=\"submit\">Saving...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== CREDIT NOTE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'creditNote' && mode === 'edit'\">\n <form [formGroup]=\"creditNoteForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Apply a credit note / discount to this invoice. Maximum 10% discount allowed.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Total Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Revised Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"revisedAmount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\" *ngIf=\"creditMoreThanTenPercent\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <g clip-path=\"url(#clip_cn_err)\">\n <path\n d=\"M7.99967 5.33301V7.99967M7.99967 10.6663H8.00634M14.6663 7.99967C14.6663 11.6816 11.6816 14.6663 7.99967 14.6663C4.31778 14.6663 1.33301 11.6816 1.33301 7.99967C1.33301 4.31778 4.31778 1.33301 7.99967 1.33301C11.6816 1.33301 14.6663 4.31778 14.6663 7.99967Z\"\n stroke=\"#F04438\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip_cn_err\">\n <rect width=\"16\" height=\"16\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n More than 10% can't be revised from total amount\n </span>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">Discount</label>\n <div class=\"input-group\">\n <input type=\"text\" formControlName=\"discount\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n <span class=\"input-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"\n fill=\"none\">\n <path\n d=\"M12.667 3.33366L3.33366 12.667M6.00033 4.33366C6.00033 5.25413 5.25413 6.00033 4.33366 6.00033C3.41318 6.00033 2.66699 5.25413 2.66699 4.33366C2.66699 3.41318 3.41318 2.66699 4.33366 2.66699C5.25413 2.66699 6.00033 3.41318 6.00033 4.33366ZM13.3337 11.667C13.3337 12.5875 12.5875 13.3337 11.667 13.3337C10.7465 13.3337 10.0003 12.5875 10.0003 11.667C10.0003 10.7465 10.7465 10.0003 11.667 10.0003C12.5875 10.0003 13.3337 10.7465 13.3337 11.667Z\"\n [attr.stroke]=\"creditMoreThanTenPercent ? '#F04438' : '#98A2B3'\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n In percentage\n </span>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"creditMoreThanTenPercent || saving\" type=\"button\" (click)=\"applyCreditNote()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Credit Note</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n\n <!-- ======================== ONE TIME FEE TAB ======================== -->\n <div class=\"modal-body mb-4\" *ngIf=\"activeTab === 'oneTimeFee' && mode === 'edit'\">\n <form [formGroup]=\"oneTimeFeeForm\" class=\"form\">\n <div class=\"contenttext mb-3\">\n Add a one-time fee (e.g. installation) to this invoice.\n </div>\n\n <div class=\"d-flex flex-column\">\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Invoice ID</label>\n <input type=\"text\" class=\"form-control\" [value]=\"invoiceData?.invoice\" readonly>\n </div>\n\n <div class=\"form-group py-2\">\n <label class=\"headingtext mb-2\">Current Invoice Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input formControlName=\"amount\" type=\"text\" readonly class=\"form-control amount-input\">\n </div>\n </div>\n\n <div class=\"form-group mt-2\">\n <div class=\"py-2\">\n <label class=\"headingtext mb-2\">One Time Fee (Installation)</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"oneTimeFee\"\n (keypress)=\"omitSpecialChar($event)\"\n class=\"form-control amount-input\"\n placeholder=\"Enter fee amount\">\n </div>\n </div>\n </div>\n\n <div class=\"d-flex flex-stack mt-3 fee-summary p-3\">\n <div class=\"summary-label\">Selected Invoice Amount + One Time Fee</div>\n <div class=\"d-flex align-items-center\">\n <span class=\"summary-value-bold\">{{ getInvoiceCurrencySymbol() }}{{\n oneTimeFeeTotal | number:'1.2-2':'en-IN' }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex mt-5\">\n <button type=\"button\" (click)=\"activeModal.dismiss()\"\n class=\"btn-outline btn cancel me-4 w-50\">Cancel</button>\n <button [disabled]=\"saving || !oneTimeFeeForm.get('oneTimeFee')?.value\" type=\"button\"\n (click)=\"applyOneTimeFee()\"\n class=\"btn btn-primary px-4 w-50\" style=\"white-space: nowrap;\">\n <span *ngIf=\"!saving\">Apply Fee</span>\n <span *ngIf=\"saving\">Applying...</span>\n </button>\n </div>\n </form>\n </div>\n</div>", styles: [".heading{color:var(--Gray-900, #101828);font-family:Inter;font-size:18px;font-style:normal;font-weight:600;line-height:28px}.invoice-number{color:var(--Primary-700, #009BF3);font-weight:500;margin-left:4px}.contenttext{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.headingtext{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500;line-height:20px}.tab-bar{display:flex;gap:4px;border-bottom:1px solid var(--Gray-200, #EAECF0);padding-bottom:0}.tab-btn{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500;line-height:20px;padding:8px 16px;border:none;background:none;cursor:pointer;border-bottom:2px solid transparent;transition:all .2s}.tab-btn:hover{color:var(--Gray-700, #344054)}.tab-btn.tab-active{color:var(--Primary-700, #009BF3);border-bottom:2px solid var(--Primary-700, #009BF3);font-weight:600}.section-title{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600;line-height:24px;padding-bottom:8px;border-bottom:1px solid var(--Gray-200, #EAECF0)}.product-row,.tax-row{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.product-label{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:600}input,.form-control{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;width:100%;padding:8px 12px;font-family:Inter;font-weight:400;line-height:24px}input:active,input:focus,input:focus-visible{border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD)!important;box-shadow:0 1px 2px #1018280d;outline:none!important;background:var(--Gray-50, #F9FAFB)}input[readonly]{background:var(--Gray-50, #F9FAFB);color:var(--Gray-500, #667085)}.form-select{color:#101828;border:1px solid #D0D5DD!important;box-shadow:0 1px 2px #1018280d;border-radius:8px;font-size:14px;padding:8px 12px;font-family:Inter;font-weight:400;height:auto}.cancel{color:var(--Gray-700, #344054);font-family:Inter;font-size:16px;font-style:normal;font-weight:600;line-height:24px;text-transform:capitalize;border-radius:8px;border:1px solid var(--Gray-300, #D0D5DD);background:var(--White, #FFF)}.summary-section,.fee-summary{background:var(--Gray-50, #F9FAFB);border:1px solid var(--Gray-200, #EAECF0);border-radius:8px}.summary-label{color:var(--Gray-500, #667085);font-family:Inter;font-size:14px;font-weight:500}.summary-value{color:var(--Gray-700, #344054);font-family:Inter;font-size:14px;font-weight:500}.summary-total{padding-top:8px;border-top:1px solid var(--Gray-200, #EAECF0)}.summary-label-bold,.summary-value-bold{color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:600}.text-danger{color:var(--Error-500, #F04438)!important;font-family:Inter;font-size:12px!important;font-weight:400}.modal-body{max-height:70vh;overflow-y:auto}.input-group{position:relative}.input-group .dollar-sign{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--Gray-900, #101828);font-family:Inter;font-size:16px;font-weight:400;line-height:24px;z-index:1}.input-group .amount-input{padding-left:30px}.input-group .input-icon{position:absolute;top:50%;right:12px;transform:translateY(-50%);display:inline-flex;align-items:center}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){border-radius:8px!important}.input-group>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-radius:8px!important}.errorinput{border-radius:8px;border:1px solid var(--Error-300, #FDA29B)!important;background:var(--White, #FFF);box-shadow:0 1px 2px #1018280d}.errorinput:focus{border:1px solid var(--Error-300, #FDA29B)!important}.form-control.is-invalid,.form-select.is-invalid{border:1px solid var(--Error-300, #FDA29B)!important;background:#fef3f2}.form-control.is-invalid:focus,.form-control.is-invalid:active,.form-control.is-invalid:focus-visible,.form-select.is-invalid:focus,.form-select.is-invalid:active,.form-select.is-invalid:focus-visible{border:1px solid var(--Error-300, #FDA29B)!important;box-shadow:0 0 0 4px #f044381f!important;background:#fef3f2}.invalid-msg{color:#b42318;font-family:Inter;font-size:12px;font-weight:500;line-height:18px;margin-top:4px}\n"] }]
|
|
576
593
|
}], ctorParameters: () => [{ type: i1.NgbActiveModal }, { type: i2.FormBuilder }, { type: i3.BillingService }, { type: i0.ChangeDetectorRef }, { type: i4.ToastService }], propDecorators: { invoiceData: [{
|
|
577
594
|
type: Input
|
|
578
595
|
}], mode: [{
|
|
@@ -582,4 +599,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
582
599
|
}], billingGroups: [{
|
|
583
600
|
type: Input
|
|
584
601
|
}] } });
|
|
585
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFdkYsT0FBTyxFQUFxQyxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7OztBQVMxQyxNQUFNLE9BQU8sb0JBQW9CO0lBaUR0QjtJQUNDO0lBQ0E7SUFDQTtJQUNBO0lBcERELFdBQVcsQ0FBTTtJQUMxQiwwRUFBMEU7SUFDMUUsOERBQThEO0lBQ3JELElBQUksR0FBb0QsTUFBTSxDQUFDO0lBQy9ELFFBQVEsR0FBVyxFQUFFLENBQUM7SUFDdEIsYUFBYSxHQUFVLEVBQUUsQ0FBQztJQUVuQyxXQUFXLENBQWE7SUFDUCxRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUMxQyxNQUFNLEdBQVksS0FBSyxDQUFDO0lBRXhCLHVDQUF1QztJQUN2QyxTQUFTLEdBQVcsTUFBTSxDQUFDO0lBRTNCLFFBQVEsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEMsZUFBZSxHQUFHLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFB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QUM7Z0JBQ3BCLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFDM0QsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7d0dBM2xCVSxvQkFBb0I7NEZBQXBCLG9CQUFvQixvS0NaakMsZ2oxQkFpYk07OzRGRHJhTyxvQkFBb0I7a0JBTGhDLFNBQVM7K0JBQ0Usa0JBQWtCO3FNQUtuQixXQUFXO3NCQUFuQixLQUFLO2dCQUdHLElBQUk7c0JBQVosS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95LCBJbnB1dCwgQ2hhbmdlRGV0ZWN0b3JSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nYkFjdGl2ZU1vZGFsIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybUFycmF5LCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBCaWxsaW5nU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2JpbGxpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktc2hhcmVkJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLWVkaXQtaW52b2ljZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9lZGl0LWludm9pY2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5zY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBFZGl0SW52b2ljZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgaW52b2ljZURhdGE6IGFueTtcbiAgLy8gJ2VzdGltYXRlJyByZXVzZXMgdGhlIHdob2xlIGNyZWF0ZSBmb3JtIGJ1dCBzdWJtaXRzIHRvIHRoZSBlc3RpbWF0ZSBBUElcbiAgLy8gYW5kIHdyaXRlcyB0byB0aGUgZXN0aW1hdGVzIGNvbGxlY3Rpb24gaW5zdGVhZCBvZiBpbnZvaWNlcy5cbiAgQElucHV0KCkgbW9kZTogJ2VkaXQnIHwgJ2NyZWF0ZScgfCAnZXN0aW1hdGUnIHwgJ2VkaXRFc3RpbWF0ZScgPSAnZWRpdCc7XG4gIEBJbnB1dCgpIGNsaWVudElkOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgYmlsbGluZ0dyb3VwczogYW55W10gPSBbXTtcblxuICBpbnZvaWNlRm9ybSE6IEZvcm1Hcm91cDtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG4gIHNhdmluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIFRhYnM6IGVkaXQgfCBjcmVkaXROb3RlIHwgb25lVGltZUZlZVxuICBhY3RpdmVUYWI6IHN0cmluZyA9ICdlZGl0JztcblxuICB0YXhUeXBlcyA9IFsnSUdTVCcsICdDR1NUJywgJ1NHU1QnXTtcbiAgY3VycmVuY3lPcHRpb25zID0gWydpbnInLCAnZG9sbGFyJywgJ3NpbmdhcG9yZWRvbGxhcicsICdldXJvJywgJ2FlZCddO1xuICBjdXJyZW5jeUxhYmVsczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBpbnI6ICdJTlIgKOKCuSknLFxuICAgIGRvbGxhcjogJ1VTRCAoJCknLFxuICAgIHNpbmdhcG9yZWRvbGxhcjogJ1NHRCAoUyQpJyxcbiAgICBldXJvOiAnRVVSICjigqwpJyxcbiAgICBhZWQ6ICdBRUQgKEFFRCknXG4gIH07XG4gIC8vIFN5bWJvbCBtYXAgbWlycm9ycyB0aGUgYmFja2VuZCdzIENVUlJFTkNZX1NZTUJPTFMgaW4gdXRpbHMvY3VycmVuY3kuanMgc29cbiAgLy8gdGhlIG1vZGFsLCBpbnZvaWNlIGxpc3QsIGNyZWRpdC1ub3RlIGFuZCBvbmUtdGltZS1mZWUgcG9wdXBzIGFsbCByZW5kZXJcbiAgLy8gdGhlIHNhbWUgc3ltYm9sIHRoZSBQREYvZW1haWwgdXNlcy5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeVN5bWJvbHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAn4oK5JyxcbiAgICBkb2xsYXI6ICckJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdTJCcsXG4gICAgZXVybzogJ+KCrCcsXG4gICAgYWVkOiAnQUVEJyxcbiAgfTtcbiAgc3RhdHVzT3B0aW9ucyA9IFsncGVuZGluZycsICdhcHByb3ZlZCddO1xuICBwYXltZW50U3RhdHVzT3B0aW9ucyA9IFsndW5wYWlkJywgJ3BhaWQnXTtcblxuICAvLyBDcmVkaXQgTm90ZVxuICBjcmVkaXROb3RlRm9ybSE6IEZvcm1Hcm91cDtcbiAgY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50OiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gUHJvZHVjdHMgZnJvbSBiYXNlIHByaWNpbmdcbiAgYXZhaWxhYmxlUHJvZHVjdHM6IGFueVtdID0gW107XG5cbiAgLy8gT25lIFRpbWUgRmVlXG4gIG9uZVRpbWVGZWVGb3JtITogRm9ybUdyb3VwO1xuICBvbmVUaW1lRmVlVG90YWw6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGFjdGl2ZU1vZGFsOiBOZ2JBY3RpdmVNb2RhbCxcbiAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGJpbGxpbmdTZXJ2aWNlOiBCaWxsaW5nU2VydmljZSxcbiAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHRvYXN0OiBUb2FzdFNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubG9hZEJpbGxpbmdHcm91cHMoKTtcbiAgICB0aGlzLmxvYWRDbGllbnRQcm9kdWN0cygpO1xuICAgIHRoaXMuaW5pdEZvcm0oKTtcbiAgICB0aGlzLmluaXRDcmVkaXROb3RlRm9ybSgpO1xuICAgIHRoaXMuaW5pdE9uZVRpbWVGZWVGb3JtKCk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2VkaXQnICYmIHRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIHRoaXMucGF0Y2hGb3JtKCk7XG4gICAgICB0aGlzLnBhdGNoQ3JlZGl0Tm90ZURlZmF1bHRzKCk7XG4gICAgICB0aGlzLnBhdGNoT25lVGltZUZlZURlZmF1bHRzKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0RXN0aW1hdGUnICYmIHRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIC8vIEVkaXRpbmcgYW4gZXN0aW1hdGUgcmV1c2VzIHRoZSBzYW1lIGZvcm0gZmllbGRzOyB0aGUgZXN0aW1hdGUgZG9jdW1lbnRcbiAgICAgIC8vIHNoYXJlcyB0aGUgaW52b2ljZSBzaGFwZSAoY29tcGFueU5hbWUsIHByb2R1Y3RzLCB0YXgsIHN0b3Jlcywg4oCmKS5cbiAgICAgIHRoaXMucGF0Y2hGb3JtKCk7XG4gICAgfVxuICB9XG5cbiAgbG9hZENsaWVudFByb2R1Y3RzKCkge1xuICAgIGNvbnN0IGNJZCA9IHRoaXMuY2xpZW50SWQgfHwgdGhpcy5pbnZvaWNlRGF0YT8uY2xpZW50SWQ7XG4gICAgaWYgKGNJZCkge1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS5nZXRDbGllbnRCYXNlUHJpY2luZyhjSWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLmF2YWlsYWJsZVByb2R1Y3RzID0gcmVzPy5kYXRhIHx8IFtdO1xuICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYXZhaWxhYmxlUHJvZHVjdHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgb25Qcm9kdWN0Q2hhbmdlKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBwcm9kdWN0R3JvdXAgPSB0aGlzLnByb2R1Y3RzLmF0KGluZGV4KTtcbiAgICBjb25zdCBzZWxlY3RlZE5hbWUgPSBwcm9kdWN0R3JvdXAuZ2V0KCdwcm9kdWN0TmFtZScpPy52YWx1ZTtcbiAgICBjb25zdCBwcm9kdWN0ID0gdGhpcy5hdmFpbGFibGVQcm9kdWN0cy5maW5kKHAgPT4gcC5wcm9kdWN0TmFtZSA9PT0gc2VsZWN0ZWROYW1lKTtcbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgcHJvZHVjdEdyb3VwLmdldCgncHJpY2UnKT8uc2V0VmFsdWUocHJvZHVjdC5wcmljZSk7XG4gICAgICAvLyBTZXQgZGVzY3JpcHRpb24gYmFzZWQgb24gcHJvZHVjdCBuYW1lXG4gICAgICBjb25zdCBkZXNjcmlwdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgIHRhbmdvVHJhZmZpYzogJ0N1c3RvbWVyIEZvb3RmYWxsIEFuYWx5dGljcycsXG4gICAgICAgIHRhbmdvWm9uZTogJ1Byb2R1Y3QgY2F0ZWdvcnkvc2VjdGlvbiBhbmFseXRpY3MnLFxuICAgICAgICB0YW5nb1RyYXg6ICdDdXN0b21lciBKb3VybmV5IEFuYWx5dGljcycsXG4gICAgICAgIHByaW9yaXR5U3VwcG9ydDogJ1ByaW9yaXR5IFN1cHBvcnQnLFxuICAgICAgfTtcbiAgICAgIHByb2R1Y3RHcm91cC5nZXQoJ2Rlc2NyaXB0aW9uJyk/LnNldFZhbHVlKGRlc2NyaXB0aW9uc1tzZWxlY3RlZE5hbWVdIHx8ICcnKTtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgICB9XG4gIH1cblxuICBmb3JtYXRQcm9kdWN0TmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghbmFtZSkgcmV0dXJuICcnO1xuICAgIC8vIENvbnZlcnQgY2FtZWxDYXNlIHRvIFRpdGxlIENhc2Ugd2l0aCBzcGFjZXM6IHRhbmdvVHJhZmZpYyAtPiBUYW5nbyBUcmFmZmljXG4gICAgcmV0dXJuIG5hbWUucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgJyQxICQyJylcbiAgICAgIC5yZXBsYWNlKC9eLi8sIChzdHIpID0+IHN0ci50b1VwcGVyQ2FzZSgpKTtcbiAgfVxuXG4gIGxvYWRCaWxsaW5nR3JvdXBzKCkge1xuICAgIGNvbnN0IGNJZCA9IHRoaXMuY2xpZW50SWQgfHwgdGhpcy5pbnZvaWNlRGF0YT8uY2xpZW50SWQ7XG4gICAgaWYgKGNJZCkge1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS5nZXRBbGxCaWxsaW5nR3JvdXBzKGNJZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuYmlsbGluZ0dyb3VwcyA9IHJlcz8uZGF0YSB8fCBbXTtcbiAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmJpbGxpbmdHcm91cHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHNldFRhYih0YWI6IHN0cmluZykge1xuICAgIHRoaXMuYWN0aXZlVGFiID0gdGFiO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09IEVESVQgSU5WT0lDRSA9PT09PT09PT09PT09PT09PT09PT1cblxuICBpbml0Rm9ybSgpIHtcbiAgICB0aGlzLmludm9pY2VGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBjb21wYW55TmFtZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIGNvbXBhbnlBZGRyZXNzOiBbJyddLFxuICAgICAgR1NUTnVtYmVyOiBbJyddLFxuICAgICAgUGxhY2VPZlN1cHBseTogWycnXSxcbiAgICAgIGdyb3VwTmFtZTogWycnXSxcbiAgICAgIC8vIEJpbGxpbmcgR3JvdXAgaXMgcmVxdWlyZWQgd2hlbiBjcmVhdGluZyDigJQgdGhlIHJlc3Qgb2YgdGhlIGNvbXBhbnlcbiAgICAgIC8vIGZpZWxkcyBhdXRvLWZpbGwgZnJvbSB0aGUgc2VsZWN0ZWQgZ3JvdXAuXG4gICAgICBncm91cElkOiBbJycsIHRoaXMubW9kZSAhPT0gJ2VkaXQnID8gVmFsaWRhdG9ycy5yZXF1aXJlZCA6IFtdXSxcbiAgICAgIHN0b3JlczogWzAsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbigwKV1dLFxuICAgICAgYmlsbGluZ0RhdGU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBkdWVEYXRlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgY3VycmVuY3k6IFsnaW5yJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBzdGF0dXM6IFsncGVuZGluZyddLFxuICAgICAgcGF5bWVudFN0YXR1czogWyd1bnBhaWQnXSxcbiAgICAgIC8vIEFkdmFuY2UgaW52b2ljZTogd2hlbiBvbiwgdGhlIGNob3NlbiBmcmVxdWVuY3kgYmlsbHMgc2V2ZXJhbCBmdXR1cmVcbiAgICAgIC8vIG1vbnRocyB1cGZyb250IChlYWNoIG1vbnRoIGJlY29tZXMgaXRzIG93biBsaW5lIGl0ZW0gc2VydmVyLXNpZGUpLlxuICAgICAgYWR2YW5jZUludm9pY2U6IFtmYWxzZV0sXG4gICAgICBhZHZhbmNlUGVyaW9kOiBbJ21vbnRobHknXSxcbiAgICAgIHByb2R1Y3RzOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICAgIHRheDogdGhpcy5mYi5hcnJheShbXSksXG4gICAgfSk7XG4gIH1cblxuICBhZHZhbmNlUGVyaW9kT3B0aW9ucyA9IFtcbiAgICB7IHZhbHVlOiAnbW9udGhseScsIGxhYmVsOiAnTW9udGhseSAobmV4dCBtb250aCknIH0sXG4gICAgeyB2YWx1ZTogJ3F1YXJ0ZXJseScsIGxhYmVsOiAnUXVhcnRlcmx5IChuZXh0IDMgbW9udGhzKScgfSxcbiAgICB7IHZhbHVlOiAnaGFsZnllYXJseScsIGxhYmVsOiAnSGFsZi15ZWFybHkgKG5leHQgNiBtb250aHMpJyB9LFxuICAgIHsgdmFsdWU6ICd5ZWFybHknLCBsYWJlbDogJ1llYXJseSAobmV4dCAxMiBtb250aHMpJyB9LFxuICBdO1xuXG4gIC8vIFRlbXBsYXRlIGhlbHBlcnM6IHN1cmZhY2UgXCJ0b3VjaGVkICYmIGludmFsaWRcIiBzbyB0aGUgSFRNTCBjYW4gaGlnaGxpZ2h0XG4gIC8vIHRoZSBmaWVsZCBhbmQgcmVuZGVyIGFuIGlubGluZSBlcnJvci4gRGVmZW5zaXZlIGFnYWluc3QgdGhlIGZvcm0gbm90IHlldFxuICAvLyBiZWluZyBpbml0aWFsaXNlZCBkdXJpbmcgdGhlIGZpcnN0IGNoYW5nZS1kZXRlY3Rpb24gcGFzcy5cbiAgY29udHJvbEludmFsaWQobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY3RybCA9IHRoaXMuaW52b2ljZUZvcm0/LmdldChuYW1lKTtcbiAgICByZXR1cm4gISFjdHJsICYmIGN0cmwudG91Y2hlZCAmJiBjdHJsLmludmFsaWQ7XG4gIH1cblxuICBhcnJheUNvbnRyb2xJbnZhbGlkKGFycmF5TmFtZTogJ3Byb2R1Y3RzJyB8ICd0YXgnLCBpbmRleDogbnVtYmVyLCBuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBhcnIgPSB0aGlzLmludm9pY2VGb3JtPy5nZXQoYXJyYXlOYW1lKSBhcyBGb3JtQXJyYXkgfCBudWxsO1xuICAgIGNvbnN0IGN0cmwgPSBhcnI/LmF0KGluZGV4KT8uZ2V0KG5hbWUpO1xuICAgIHJldHVybiAhIWN0cmwgJiYgY3RybC50b3VjaGVkICYmIGN0cmwuaW52YWxpZDtcbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsVG9GaXJzdEludmFsaWQoKTogdm9pZCB7XG4gICAgLy8gRmluZCB0aGUgZmlyc3QgaW52YWxpZCBjb250cm9sIGluc2lkZSB0aGUgbW9kYWwgYW5kIGJyaW5nIGl0IGludG8gdmlldy5cbiAgICAvLyBTY29wZWQgdG8gLm1vZGFsLWNvbnRlbnQgc28gd2UgZG9uJ3QgZ3JhYiBmaWVsZHMgZnJvbSBvdGhlciBtb2RhbHMgb25cbiAgICAvLyB0aGUgcGFnZSBpZiBhbnkgYXJlIG9wZW4uXG4gICAgY29uc3Qgcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb2RhbC1jb250ZW50Jyk7XG4gICAgY29uc3QgZmlyc3QgPSByb290Py5xdWVyeVNlbGVjdG9yKCcuaXMtaW52YWxpZCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICBpZiAoZmlyc3QpIHtcbiAgICAgIGZpcnN0LnNjcm9sbEludG9WaWV3KHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ2NlbnRlcicgfSk7XG4gICAgICBpZiAodHlwZW9mIGZpcnN0LmZvY3VzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGZpcnN0LmZvY3VzKHsgcHJldmVudFNjcm9sbDogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgcHJvZHVjdHMoKTogRm9ybUFycmF5IHtcbiAgICByZXR1cm4gdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ3Byb2R1Y3RzJykgYXMgRm9ybUFycmF5O1xuICB9XG5cbiAgZ2V0IHRheEFycmF5KCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCd0YXgnKSBhcyBGb3JtQXJyYXk7XG4gIH1cblxuICBjcmVhdGVQcm9kdWN0R3JvdXAocHJvZHVjdD86IGFueSk6IEZvcm1Hcm91cCB7XG4gICAgcmV0dXJuIHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgcHJvZHVjdE5hbWU6IFtwcm9kdWN0Py5wcm9kdWN0TmFtZSB8fCAnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBkZXNjcmlwdGlvbjogW3Byb2R1Y3Q/LmRlc2NyaXB0aW9uIHx8ICcnXSxcbiAgICAgIG1vbnRoOiBbcHJvZHVjdD8ubW9udGggfHwgJyddLFxuICAgICAgSHNuTnVtYmVyOiBbcHJvZHVjdD8uSHNuTnVtYmVyIHx8ICc5OTgzMTQnXSxcbiAgICAgIHN0b3JlQ291bnQ6IFtwcm9kdWN0Py5zdG9yZUNvdW50IHx8IDAsIFZhbGlkYXRvcnMubWluKDApXSxcbiAgICAgIHByaWNlOiBbcHJvZHVjdD8ucHJpY2UgfHwgMCwgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWluKDApXV0sXG4gICAgICBhbW91bnQ6IFtwcm9kdWN0Py5hbW91bnQgfHwgMF0sXG4gICAgICBwZXJpb2Q6IFtwcm9kdWN0Py5wZXJpb2QgfHwgJ21vbnRobHknXSxcbiAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZVRheEdyb3VwKHRheD86IGFueSk6IEZvcm1Hcm91cCB7XG4gICAgcmV0dXJuIHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgdHlwZTogW3RheD8udHlwZSB8fCAnSUdTVCcsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgdmFsdWU6IFt0YXg/LnZhbHVlIHx8IDE4LCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCksIFZhbGlkYXRvcnMubWF4KDEwMCldXSxcbiAgICAgIHRheEFtb3VudDogW3RheD8udGF4QW1vdW50IHx8ICcwJ10sXG4gICAgICAvLyBEZWZhdWx0IHRoZSB0YXgtcm93IHN5bWJvbCB0byB0aGUgaW52b2ljZSdzIGN1cnJlbmN5ICh3YXMgaGFyZGNvZGVkXG4gICAgICAvLyB0byDigrksIHdoaWNoIGxlYWtlZCBpbnRvIHRoZSBzYXZlZCBkb2MgZm9yIG5vbi1JTlIgaW52b2ljZXMpLlxuICAgICAgY3VycmVuY3k6IFt0YXg/LmN1cnJlbmN5IHx8IHRoaXMuc3ltYm9sRm9yKHRoaXMuaW52b2ljZUZvcm0/LmdldCgnY3VycmVuY3knKT8udmFsdWUpXSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3ltYm9sRm9yKGNvZGU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbmN5U3ltYm9sc1tjb2RlIHx8ICcnXSB8fCAnJCc7XG4gIH1cblxuICBhZGRQcm9kdWN0KCkge1xuICAgIHRoaXMucHJvZHVjdHMucHVzaCh0aGlzLmNyZWF0ZVByb2R1Y3RHcm91cCgpKTtcbiAgfVxuXG4gIHJlbW92ZVByb2R1Y3QoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMucHJvZHVjdHMucmVtb3ZlQXQoaW5kZXgpO1xuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgfVxuXG4gIGFkZFRheCgpIHtcbiAgICB0aGlzLnRheEFycmF5LnB1c2godGhpcy5jcmVhdGVUYXhHcm91cCgpKTtcbiAgfVxuXG4gIHJlbW92ZVRheChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy50YXhBcnJheS5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICB9XG5cbiAgcGF0Y2hGb3JtKCkge1xuICAgIGNvbnN0IGludiA9IHRoaXMuaW52b2ljZURhdGE7XG5cbiAgICB0aGlzLmludm9pY2VGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgY29tcGFueU5hbWU6IGludi5jb21wYW55TmFtZSB8fCAnJyxcbiAgICAgIGNvbXBhbnlBZGRyZXNzOiBpbnYuY29tcGFueUFkZHJlc3MgfHwgJycsXG4gICAgICBHU1ROdW1iZXI6IGludi5HU1ROdW1iZXIgfHwgJycsXG4gICAgICBQbGFjZU9mU3VwcGx5OiBpbnYuUGxhY2VPZlN1cHBseSB8fCAnJyxcbiAgICAgIGdyb3VwTmFtZTogaW52Lmdyb3VwTmFtZSB8fCAnJyxcbiAgICAgIGdyb3VwSWQ6IGludi5ncm91cElkIHx8ICcnLFxuICAgICAgc3RvcmVzOiBpbnYuc3RvcmVzIHx8IDAsXG4gICAgICBiaWxsaW5nRGF0ZTogdGhpcy5mb3JtYXREYXRlRm9ySW5wdXQoaW52LmJpbGxpbmdEYXRlKSxcbiAgICAgIGR1ZURhdGU6IHRoaXMuZm9ybWF0RGF0ZUZvcklucHV0KGludi5kdWVEYXRlKSxcbiAgICAgIGN1cnJlbmN5OiBpbnYuY3VycmVuY3kgfHwgJ2lucicsXG4gICAgICBzdGF0dXM6IGludi5zdGF0dXMgfHwgJ3BlbmRpbmcnLFxuICAgICAgcGF5bWVudFN0YXR1czogaW52LnBheW1lbnRTdGF0dXMgfHwgJ3VucGFpZCcsXG4gICAgfSk7XG5cbiAgICAvLyBQYXRjaCBwcm9kdWN0c1xuICAgIGlmIChpbnYucHJvZHVjdHM/Lmxlbmd0aCkge1xuICAgICAgaW52LnByb2R1Y3RzLmZvckVhY2goKHA6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnByb2R1Y3RzLnB1c2godGhpcy5jcmVhdGVQcm9kdWN0R3JvdXAocCkpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWRkUHJvZHVjdCgpO1xuICAgIH1cblxuICAgIC8vIFBhdGNoIHRheFxuICAgIGlmIChpbnYudGF4Py5sZW5ndGgpIHtcbiAgICAgIGludi50YXguZm9yRWFjaCgodDogYW55KSA9PiB7XG4gICAgICAgIHRoaXMudGF4QXJyYXkucHVzaCh0aGlzLmNyZWF0ZVRheEdyb3VwKHQpKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFkZFRheCgpO1xuICAgIH1cbiAgfVxuXG4gIGZvcm1hdERhdGVGb3JJbnB1dChkYXRlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghZGF0ZSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShkYXRlPy4kZGF0ZSB8fCBkYXRlKTtcbiAgICBpZiAoaXNOYU4oZC5nZXRUaW1lKCkpKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGQudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICB9XG5cbiAgb25Hcm91cENoYW5nZShldmVudDogYW55KSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRHcm91cCA9IHRoaXMuYmlsbGluZ0dyb3Vwcy5maW5kKGcgPT4gZy5faWQgPT09IGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgaWYgKHNlbGVjdGVkR3JvdXApIHtcbiAgICAgIHRoaXMuaW52b2ljZUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgIGdyb3VwTmFtZTogc2VsZWN0ZWRHcm91cC5ncm91cE5hbWUsXG4gICAgICAgIGdyb3VwSWQ6IHNlbGVjdGVkR3JvdXAuX2lkLFxuICAgICAgICBjb21wYW55TmFtZTogc2VsZWN0ZWRHcm91cC5yZWdpc3RlcmVkQ29tcGFueU5hbWUgfHwgJycsXG4gICAgICAgIGNvbXBhbnlBZGRyZXNzOiBbc2VsZWN0ZWRHcm91cC5hZGRyZXNzTGluZU9uZSwgc2VsZWN0ZWRHcm91cC5hZGRyZXNzTGluZVR3bywgc2VsZWN0ZWRHcm91cC5jaXR5LCBzZWxlY3RlZEdyb3VwLnN0YXRlLCBzZWxlY3RlZEdyb3VwLmNvdW50cnksIHNlbGVjdGVkR3JvdXAucGluQ29kZV0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oJywgJyksXG4gICAgICAgIEdTVE51bWJlcjogc2VsZWN0ZWRHcm91cC5nc3QgfHwgJycsXG4gICAgICAgIFBsYWNlT2ZTdXBwbHk6IHNlbGVjdGVkR3JvdXAucGxhY2VPZlN1cHBseSB8fCAnJyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJlY2FsY3VsYXRlKCkge1xuICAgIGxldCBzdWJ0b3RhbCA9IDA7XG4gICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY29uc3Qgc3RvcmVDb3VudCA9IGdyb3VwLmdldCgnc3RvcmVDb3VudCcpPy52YWx1ZSB8fCAwO1xuICAgICAgY29uc3QgcHJpY2UgPSBncm91cC5nZXQoJ3ByaWNlJyk/LnZhbHVlIHx8IDA7XG4gICAgICBjb25zdCBhbW91bnQgPSBzdG9yZUNvdW50ICogcHJpY2U7XG4gICAgICBncm91cC5nZXQoJ2Ftb3VudCcpPy5zZXRWYWx1ZShwYXJzZUZsb2F0KGFtb3VudC50b0ZpeGVkKDIpKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgc3VidG90YWwgKz0gYW1vdW50O1xuICAgIH0pO1xuXG4gICAgdGhpcy50YXhBcnJheS5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBncm91cC5nZXQoJ3ZhbHVlJyk/LnZhbHVlIHx8IDA7XG4gICAgICBjb25zdCB0YXhBbW91bnQgPSAoc3VidG90YWwgKiB2YWx1ZSAvIDEwMCkudG9GaXhlZCgyKTtcbiAgICAgIGdyb3VwLmdldCgndGF4QW1vdW50Jyk/LnNldFZhbHVlKHRheEFtb3VudCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH0pO1xuXG4gICAgbGV0IHRvdGFsU3RvcmVzID0gMDtcbiAgICB0aGlzLnByb2R1Y3RzLmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICB0b3RhbFN0b3JlcyArPSBncm91cC5nZXQoJ3N0b3JlQ291bnQnKT8udmFsdWUgfHwgMDtcbiAgICB9KTtcbiAgICB0aGlzLmludm9pY2VGb3JtLmdldCgnc3RvcmVzJyk/LnNldFZhbHVlKHRvdGFsU3RvcmVzLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG5cbiAgZ2V0U3VidG90YWwoKTogbnVtYmVyIHtcbiAgICBsZXQgc3VidG90YWwgPSAwO1xuICAgIHRoaXMucHJvZHVjdHMuY29udHJvbHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgIHN1YnRvdGFsICs9IGdyb3VwLmdldCgnYW1vdW50Jyk/LnZhbHVlIHx8IDA7XG4gICAgfSk7XG4gICAgcmV0dXJuIHN1YnRvdGFsO1xuICB9XG5cbiAgZ2V0VG90YWxUYXgoKTogbnVtYmVyIHtcbiAgICBsZXQgdG90YWxUYXggPSAwO1xuICAgIHRoaXMudGF4QXJyYXkuY29udHJvbHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgIHRvdGFsVGF4ICs9IHBhcnNlRmxvYXQoZ3JvdXAuZ2V0KCd0YXhBbW91bnQnKT8udmFsdWUgfHwgJzAnKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdG90YWxUYXg7XG4gIH1cblxuICBnZXRUb3RhbEFtb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmdldFN1YnRvdGFsKCkgKyB0aGlzLmdldFRvdGFsVGF4KCk7XG4gIH1cblxuICBnZXRDdXJyZW5jeVN5bWJvbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnN5bWJvbEZvcih0aGlzLmludm9pY2VGb3JtLmdldCgnY3VycmVuY3knKT8udmFsdWUpO1xuICB9XG5cbiAgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3ltYm9sRm9yKHRoaXMuaW52b2ljZURhdGE/LmN1cnJlbmN5KTtcbiAgfVxuXG4gIG9uU3VibWl0KCkge1xuICAgIGlmICh0aGlzLmludm9pY2VGb3JtLmludmFsaWQpIHtcbiAgICAgIHRoaXMuaW52b2ljZUZvcm0ubWFya0FsbEFzVG91Y2hlZCgpO1xuICAgICAgLy8gRGVmZXIgdG8gbmV4dCB0aWNrIHNvIEFuZ3VsYXIgcmVuZGVycyB0aGUgLmlzLWludmFsaWQgY2xhc3Nlc1xuICAgICAgLy8gYmVmb3JlIHdlIHF1ZXJ5IHRoZSBET00gZm9yIHRoZSBmaXJzdCBpbnZhbGlkIGNvbnRyb2wgdG8gc2Nyb2xsIHRvLlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnNjcm9sbFRvRmlyc3RJbnZhbGlkKCksIDApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2F2aW5nID0gdHJ1ZTtcbiAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLmludm9pY2VGb3JtLmdldFJhd1ZhbHVlKCk7XG5cbiAgICBjb25zdCBwYXlsb2FkOiBhbnkgPSB7XG4gICAgICBjb21wYW55TmFtZTogZm9ybVZhbHVlLmNvbXBhbnlOYW1lLFxuICAgICAgY29tcGFueUFkZHJlc3M6IGZvcm1WYWx1ZS5jb21wYW55QWRkcmVzcyxcbiAgICAgIEdTVE51bWJlcjogZm9ybVZhbHVlLkdTVE51bWJlcixcbiAgICAgIFBsYWNlT2ZTdXBwbHk6IGZvcm1WYWx1ZS5QbGFjZU9mU3VwcGx5LFxuICAgICAgZ3JvdXBOYW1lOiBmb3JtVmFsdWUuZ3JvdXBOYW1lLFxuICAgICAgZ3JvdXBJZDogZm9ybVZhbHVlLmdyb3VwSWQsXG4gICAgICBzdG9yZXM6IGZvcm1WYWx1ZS5zdG9yZXMsXG4gICAgICBiaWxsaW5nRGF0ZTogZm9ybVZhbHVlLmJpbGxpbmdEYXRlLFxuICAgICAgZHVlRGF0ZTogZm9ybVZhbHVlLmR1ZURhdGUsXG4gICAgICBjdXJyZW5jeTogZm9ybVZhbHVlLmN1cnJlbmN5LFxuICAgICAgc3RhdHVzOiBmb3JtVmFsdWUuc3RhdHVzLFxuICAgICAgcGF5bWVudFN0YXR1czogZm9ybVZhbHVlLnBheW1lbnRTdGF0dXMsXG4gICAgICBhZHZhbmNlSW52b2ljZTogZm9ybVZhbHVlLmFkdmFuY2VJbnZvaWNlLFxuICAgICAgYWR2YW5jZVBlcmlvZDogZm9ybVZhbHVlLmFkdmFuY2VQZXJpb2QsXG4gICAgICBwcm9kdWN0czogZm9ybVZhbHVlLnByb2R1Y3RzLFxuICAgICAgdGF4OiBmb3JtVmFsdWUudGF4LFxuICAgICAgYW1vdW50OiB0aGlzLmdldFN1YnRvdGFsKCksXG4gICAgICB0b3RhbEFtb3VudDogTWF0aC5yb3VuZCh0aGlzLmdldFRvdGFsQW1vdW50KCkpLFxuICAgIH07XG5cbiAgICBpZiAodGhpcy5tb2RlID09PSAnZWRpdCcpIHtcbiAgICAgIHBheWxvYWQuX2lkID0gdGhpcy5pbnZvaWNlRGF0YS5faWQ7XG4gICAgICBwYXlsb2FkLmludm9pY2UgPSB0aGlzLmludm9pY2VEYXRhLmludm9pY2U7XG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5pbnZvaWNlRGF0YS5jbGllbnRJZDtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UudXBkYXRlSW52b2ljZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnSW52b2ljZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgndXBkYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIHVwZGF0ZSBpbnZvaWNlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZWRpdEVzdGltYXRlJykge1xuICAgICAgLy8gVXBkYXRlIGFuIGV4aXN0aW5nIGVzdGltYXRlLiBJZGVudGl0eSBmaWVsZHMgKGVzdGltYXRlICMsIGNsaWVudElkLFxuICAgICAgLy8gY3JlYXRlZERhdGUpIGFyZSBwcmVzZXJ2ZWQgc2VydmVyLXNpZGU7IHdlIHNlbmQgdGhlIGVkaXRhYmxlIGZvcm0gZGF0YS5cbiAgICAgIHBheWxvYWQuX2lkID0gdGhpcy5pbnZvaWNlRGF0YS5faWQ7XG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5pbnZvaWNlRGF0YS5jbGllbnRJZCB8fCB0aGlzLmNsaWVudElkO1xuICAgICAgcGF5bG9hZC5wZXJpb2QgPSBmb3JtVmFsdWUuYmlsbGluZ0RhdGVcbiAgICAgICAgPyBuZXcgRGF0ZShmb3JtVmFsdWUuYmlsbGluZ0RhdGUpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycsIHsgbW9udGg6ICdzaG9ydCcsIHllYXI6ICdudW1lcmljJyB9KVxuICAgICAgICA6IHRoaXMuaW52b2ljZURhdGEucGVyaW9kO1xuICAgICAgcGF5bG9hZC52YWxpZFRpbGwgPSBmb3JtVmFsdWUuZHVlRGF0ZTtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UudXBkYXRlRXN0aW1hdGUocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ0VzdGltYXRlIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCd1cGRhdGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIHVwZGF0ZSBlc3RpbWF0ZScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2VzdGltYXRlJykge1xuICAgICAgLy8gU2FtZSBmb3JtLCBzZXBhcmF0ZSBkb2N1bWVudDogcG9zdCB0byB0aGUgZXN0aW1hdGUgQVBJIHNvIGl0IGxhbmRzIGluXG4gICAgICAvLyB0aGUgZXN0aW1hdGVzIGNvbGxlY3Rpb24gd2l0aCBhbiBFU1Qt4oCmIG51bWJlciBpbnN0ZWFkIG9mIGFuIGludm9pY2UuXG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5jbGllbnRJZDtcbiAgICAgIHBheWxvYWQucGVyaW9kID0gZm9ybVZhbHVlLmJpbGxpbmdEYXRlXG4gICAgICAgID8gbmV3IERhdGUoZm9ybVZhbHVlLmJpbGxpbmdEYXRlKS50b0xvY2FsZVN0cmluZygnZW4tVVMnLCB7IG1vbnRoOiAnc2hvcnQnLCB5ZWFyOiAnbnVtZXJpYycgfSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICBwYXlsb2FkLnZhbGlkVGlsbCA9IGZvcm1WYWx1ZS5kdWVEYXRlO1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS5jcmVhdGVFc3RpbWF0ZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnRXN0aW1hdGUgZ2VuZXJhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgnY3JlYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBnZW5lcmF0ZSBlc3RpbWF0ZScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGF5bG9hZC5jbGllbnRJZCA9IHRoaXMuY2xpZW50SWQ7XG4gICAgICAvLyBGbGFnIHRoZSBiYWNrZW5kIHRvIHRha2UgdGhlIFwiY3VzdG9tIGNyZWF0ZVwiIHBhdGggdGhhdCBwZXJzaXN0cyB3aGF0XG4gICAgICAvLyB0aGUgZm9ybSBidWlsdC4gVGhlIGxlZ2FjeSAvY3JlYXRlSW52b2ljZSBjb250cmFjdCBleHBlY3RzIGVpdGhlclxuICAgICAgLy8gYWxsQ2xpZW50K2NsaWVudExpc3Qgb3IgaW52b2ljZUlkOyB3aXRob3V0IHRoaXMgZmxhZywgdGhlIHNlcnZlclxuICAgICAgLy8gc2lsZW50bHkgcmV0dXJucyAyeHggYW5kIHdyaXRlcyBub3RoaW5nLlxuICAgICAgcGF5bG9hZC5jdXN0b21JbnZvaWNlID0gdHJ1ZTtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuY3JlYXRlSW52b2ljZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnSW52b2ljZSBjcmVhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgnY3JlYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgY29uc3QgbXNnID0gZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGNyZWF0ZSBpbnZvaWNlJztcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QobXNnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09IENSRURJVCBOT1RFID09PT09PT09PT09PT09PT09PT09PVxuXG4gIGluaXRDcmVkaXROb3RlRm9ybSgpIHtcbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBhbW91bnQ6IFsnJ10sXG4gICAgICByZXZpc2VkQW1vdW50OiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgZGlzY291bnQ6IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4KDEwKV1dLFxuICAgIH0pO1xuXG4gICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgIGlmIChlKSB7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdhbW91bnQnKT8udmFsdWU7XG4gICAgICAgIGlmIChhbW91bnQpIHtcbiAgICAgICAgICBjb25zdCBkaXNjb3VudCA9ICgoYW1vdW50IC0gZSkgLyBhbW91bnQgKiAxMDApLnRvRml4ZWQoMik7XG4gICAgICAgICAgdGhpcy5jcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPSBwYXJzZUZsb2F0KGRpc2NvdW50KSA+IDEwIHx8IGlzTmFOKGUpIHx8IHBhcnNlRmxvYXQoZGlzY291bnQpIDwgMCB8fCBlIDwgMDtcbiAgICAgICAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnZGlzY291bnQnKT8uc2V0VmFsdWUoZGlzY291bnQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Rpc2NvdW50Jyk/LnNldFZhbHVlKCcnLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnZGlzY291bnQnKT8udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgIGlmIChlKSB7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdhbW91bnQnKT8udmFsdWU7XG4gICAgICAgIGNvbnN0IHJldmlzZWQgPSBwYXJzZUludCgoYW1vdW50ICogKDEgLSBlIC8gMTAwKSkudG9GaXhlZCgpKTtcbiAgICAgICAgdGhpcy5jcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPSBwYXJzZUZsb2F0KGUpID4gMTAgfHwgaXNOYU4oZSkgfHwgZSA8IDAgfHwgcmV2aXNlZCA8IDA7XG4gICAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdyZXZpc2VkQW1vdW50Jyk/LnNldFZhbHVlKHJldmlzZWQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdyZXZpc2VkQW1vdW50Jyk/LnNldFZhbHVlKCcnLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID0gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHBhdGNoQ3JlZGl0Tm90ZURlZmF1bHRzKCkge1xuICAgIGlmICh0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICBhbW91bnQ6IHRoaXMuaW52b2ljZURhdGEuYW1vdW50IHx8IHRoaXMuaW52b2ljZURhdGEudG90YWxBbW91bnQgfHwgMCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFwcGx5Q3JlZGl0Tm90ZSgpIHtcbiAgICBpZiAodGhpcy5jcmVkaXRNb3JlVGhhblRlblBlcmNlbnQpIHJldHVybjtcbiAgICBjb25zdCByZXF1ZXN0RGF0YSA9IHtcbiAgICAgIGludm9pY2U6IHRoaXMuaW52b2ljZURhdGEuaW52b2ljZSxcbiAgICAgIHJldmlzZWRBbW91bnQ6IHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdyZXZpc2VkQW1vdW50Jyk/LnZhbHVlLFxuICAgICAgZGlzY291bnQ6IHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdkaXNjb3VudCcpPy52YWx1ZSxcbiAgICB9O1xuICAgIHRoaXMuc2F2aW5nID0gdHJ1ZTtcbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmFwcGx5RGlzY291bnQocmVxdWVzdERhdGEpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChyZXMgJiYgcmVzLmNvZGUgPT0gMjAwKSB7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ0NyZWRpdCBub3RlIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgnY3JlZGl0QXBwbGllZCcpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gYXBwbHkgY3JlZGl0IG5vdGUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG9taXRTcGVjaWFsQ2hhcihldmVudDogYW55KSB7XG4gICAgY29uc3QgayA9IGV2ZW50LmNoYXJDb2RlO1xuICAgIHJldHVybiAoayA9PSA4IHx8IGsgPT0gMzIgfHwgKGsgPj0gNDggJiYgayA8PSA1NykpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09IE9ORSBUSU1FIEZFRSA9PT09PT09PT09PT09PT09PT09PT1cblxuICBpbml0T25lVGltZUZlZUZvcm0oKSB7XG4gICAgdGhpcy5vbmVUaW1lRmVlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgYW1vdW50OiBbJyddLFxuICAgICAgb25lVGltZUZlZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICB9KTtcblxuICAgIHRoaXMub25lVGltZUZlZUZvcm0udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5jYWxjdWxhdGVPbmVUaW1lRmVlVG90YWwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHBhdGNoT25lVGltZUZlZURlZmF1bHRzKCkge1xuICAgIGlmICh0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICB0aGlzLm9uZVRpbWVGZWVGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICBhbW91bnQ6IHRoaXMuaW52b2ljZURhdGEuYW1vdW50IHx8IHRoaXMuaW52b2ljZURhdGEudG90YWxBbW91bnQgfHwgMCxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYWxjdWxhdGVPbmVUaW1lRmVlVG90YWwoKTtcbiAgICB9XG4gIH1cblxuICBjYWxjdWxhdGVPbmVUaW1lRmVlVG90YWwoKSB7XG4gICAgY29uc3QgYW1vdW50ID0gcGFyc2VGbG9hdCh0aGlzLm9uZVRpbWVGZWVGb3JtLmdldCgnYW1vdW50Jyk/LnZhbHVlIHx8ICcwJyk7XG4gICAgY29uc3QgZmVlID0gcGFyc2VGbG9hdCh0aGlzLm9uZVRpbWVGZWVGb3JtLmdldCgnb25lVGltZUZlZScpPy52YWx1ZSB8fCAnMCcpO1xuICAgIHRoaXMub25lVGltZUZlZVRvdGFsID0gcGFyc2VGbG9hdCgoYW1vdW50ICsgZmVlKS50b0ZpeGVkKDIpKTtcbiAgfVxuXG4gIGFwcGx5T25lVGltZUZlZSgpIHtcbiAgICBjb25zdCBmZWVWYWx1ZSA9IHRoaXMub25lVGltZUZlZUZvcm0uZ2V0KCdvbmVUaW1lRmVlJyk/LnZhbHVlO1xuICAgIGlmICghZmVlVmFsdWUpIHJldHVybjtcbiAgICBjb25zdCByZXF1ZXN0RGF0YSA9IHtcbiAgICAgIG9uZVRpbWVGZWU6IGZlZVZhbHVlLFxuICAgIH07XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2Uub25lVGltZUZlZShyZXF1ZXN0RGF0YSwgdGhpcy5pbnZvaWNlRGF0YS5pbnZvaWNlKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAocmVzICYmIHJlcy5jb2RlID09IDIwMCkge1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdPbmUgdGltZSBmZWUgYXBwbGllZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdmZWVBcHBsaWVkJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBhcHBseSBvbmUgdGltZSBmZWUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufSIsIjxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgPGRpdiBjbGFzcz1cInAtNSBweC02IHBiLTBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkaW5nIG10LTJcIj57eyBtb2RlID09PSAnZWRpdCcgPyAnSW52b2ljZScgOiAobW9kZSA9PT0gJ2VzdGltYXRlJyA/ICdHZW5lcmF0ZSBFc3RpbWF0ZScgOiAobW9kZSA9PT0gJ2VkaXRFc3RpbWF0ZScgPyAnRWRpdCBFc3RpbWF0ZScgOiAnQ3JlYXRlIEludm9pY2UnKSkgfX1cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1vZGUgPT09ICdlZGl0J1wiIGNsYXNzPVwiaW52b2ljZS1udW1iZXJcIj57eyBpbnZvaWNlRGF0YT8uaW52b2ljZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1vZGUgPT09ICdlZGl0RXN0aW1hdGUnXCIgY2xhc3M9XCJpbnZvaWNlLW51bWJlclwiPnt7IGludm9pY2VEYXRhPy5lc3RpbWF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCI+PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gVGFicyAob25seSBpbiBlZGl0IG1vZGUpIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJhciBtdC0zXCIgKm5nSWY9XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0YWItYnRuXCIgW25nQ2xhc3NdPVwiYWN0aXZlVGFiID09PSAnZWRpdCcgPyAndGFiLWFjdGl2ZScgOiAnJ1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInNldFRhYignZWRpdCcpXCI+RWRpdCBJbnZvaWNlPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWJ0blwiIFtuZ0NsYXNzXT1cImFjdGl2ZVRhYiA9PT0gJ2NyZWRpdE5vdGUnID8gJ3RhYi1hY3RpdmUnIDogJydcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZXRUYWIoJ2NyZWRpdE5vdGUnKVwiPkNyZWRpdCBOb3RlPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWJ0blwiIFtuZ0NsYXNzXT1cImFjdGl2ZVRhYiA9PT0gJ29uZVRpbWVGZWUnID8gJ3RhYi1hY3RpdmUnIDogJydcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZXRUYWIoJ29uZVRpbWVGZWUnKVwiPk9uZSBUaW1lIEZlZTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09IEVESVQgSU5WT0lDRSBUQUIgPT09PT09PT09PT09PT09PT09PT09PT09IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IG1iLTRcIiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2VkaXQnIHx8IG1vZGUgIT09ICdlZGl0J1wiPlxuICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImludm9pY2VGb3JtXCIgY2xhc3M9XCJmb3JtXCIgKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIj5cblxuICAgICAgICAgICAgPCEtLSBDb21wYW55IERldGFpbHMgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLXRpdGxlIG1iLTNcIj5Db21wYW55IERldGFpbHM8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkNvbXBhbnkgTmFtZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJjb21wYW55TmFtZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdjb21wYW55TmFtZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnY29tcGFueU5hbWUnKVwiPkNvbXBhbnkgTmFtZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkdTVCBOdW1iZXI8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJHU1ROdW1iZXJcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Q29tcGFueSBBZGRyZXNzPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiY29tcGFueUFkZHJlc3NcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5QbGFjZSBvZiBTdXBwbHk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJQbGFjZU9mU3VwcGx5XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbcmVhZG9ubHldPVwibW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBCaWxsaW5nIEdyb3VwIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0lmPVwiYmlsbGluZ0dyb3Vwcy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+QmlsbGluZyBHcm91cCA8c3BhbiAqbmdJZj1cIm1vZGUgIT09ICdlZGl0J1wiIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgKm5nSWY9XCJtb2RlICE9PSAnZWRpdCdcIiBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZ3JvdXBJZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJjb250cm9sSW52YWxpZCgnZ3JvdXBJZCcpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Hcm91cENoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+U2VsZWN0IGJpbGxpbmcgZ3JvdXA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGcgb2YgYmlsbGluZ0dyb3Vwc1wiIFt2YWx1ZV09XCJnLl9pZFwiPnt7IGcuZ3JvdXBOYW1lIH19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJtb2RlID09PSAnZWRpdCdcIiB0eXBlPVwidGV4dFwiIFt2YWx1ZV09XCJpbnZvaWNlRm9ybS5nZXQoJ2dyb3VwTmFtZScpPy52YWx1ZSB8fCAnRGVmYXVsdCBHcm91cCdcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdncm91cElkJylcIj5CaWxsaW5nIEdyb3VwIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+R3JvdXAgTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cImdyb3VwTmFtZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gSW52b2ljZSBEZXRhaWxzIFNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi10aXRsZSBtYi0zIG10LTJcIj5JbnZvaWNlIERldGFpbHM8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkJpbGxpbmcgRGF0ZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImRhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJiaWxsaW5nRGF0ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdiaWxsaW5nRGF0ZScpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiY29udHJvbEludmFsaWQoJ2JpbGxpbmdEYXRlJylcIj5CaWxsaW5nIERhdGUgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5EdWUgRGF0ZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImRhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJkdWVEYXRlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiY29udHJvbEludmFsaWQoJ2R1ZURhdGUnKVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdkdWVEYXRlJylcIj5EdWUgRGF0ZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkN1cnJlbmN5IDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cImN1cnJlbmN5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdjdXJyZW5jeScpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjIG9mIGN1cnJlbmN5T3B0aW9uc1wiIFt2YWx1ZV09XCJjXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY3VycmVuY3lMYWJlbHNbY10gfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnY3VycmVuY3knKVwiPkN1cnJlbmN5IGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Tm8uIG9mIFN0b3JlczwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwic3RvcmVzXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEFkdmFuY2UgSW52b2ljZSAoY3JlYXRlIG9ubHkpOiBiaWxsIHNldmVyYWwgZnV0dXJlIG1vbnRocyB1cGZyb250LlxuICAgICAgICAgICAgICAgICBFYWNoIG1vbnRoIGJlY29tZXMgaXRzIG93biBsaW5lIGl0ZW0gc2VydmVyLXNpZGUuIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0lmPVwibW9kZSA9PT0gJ2NyZWF0ZSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTEgZC1ibG9ja1wiPkFkdmFuY2UgSW52b2ljZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrIGZvcm0tc3dpdGNoIG10LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImFkdmFuY2VJbnZvaWNlQ3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJhZHZhbmNlSW52b2ljZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIGZvcj1cImFkdmFuY2VJbnZvaWNlQ3JlYXRlXCI+QmlsbCBmdXR1cmUgbW9udGhzIHVwZnJvbnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCIgKm5nSWY9XCJpbnZvaWNlRm9ybS5nZXQoJ2FkdmFuY2VJbnZvaWNlJyk/LnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5BZHZhbmNlIGZyZXF1ZW5jeTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cImFkdmFuY2VQZXJpb2RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBhZHZhbmNlUGVyaW9kT3B0aW9uc1wiIFt2YWx1ZV09XCJvcHQudmFsdWVcIj57eyBvcHQubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8IS0tIFByb2R1Y3RzIFNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi10aXRsZSBtYi0zIG10LTJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Qcm9kdWN0czwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiAoY2xpY2spPVwiYWRkUHJvZHVjdCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICArIEFkZCBQcm9kdWN0XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cInByb2R1Y3RzXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgcHJvZHVjdCBvZiBwcm9kdWN0cy5jb250cm9sczsgbGV0IGkgPSBpbmRleFwiIFtmb3JtR3JvdXBOYW1lXT1cImlcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInByb2R1Y3Qtcm93IG1iLTMgcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJvZHVjdC1sYWJlbFwiPlByb2R1Y3Qge3sgaSArIDEgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtZGFuZ2VyXCIgKGNsaWNrKT1cInJlbW92ZVByb2R1Y3QoaSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicHJvZHVjdHMubGVuZ3RoID4gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbW92ZVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlByb2R1Y3QgTmFtZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgKm5nSWY9XCJhdmFpbGFibGVQcm9kdWN0cy5sZW5ndGggPiAwXCIgZm9ybUNvbnRyb2xOYW1lPVwicHJvZHVjdE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Qcm9kdWN0Q2hhbmdlKGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgcHJvZHVjdDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBwIG9mIGF2YWlsYWJsZVByb2R1Y3RzXCIgW3ZhbHVlXT1cInAucHJvZHVjdE5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGZvcm1hdFByb2R1Y3ROYW1lKHAucHJvZHVjdE5hbWUpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cImF2YWlsYWJsZVByb2R1Y3RzLmxlbmd0aCA9PT0gMFwiIHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwicHJvZHVjdE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3Byb2R1Y3ROYW1lJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImUuZy4gdGFuZ29UcmFmZmljXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJhcnJheUNvbnRyb2xJbnZhbGlkKCdwcm9kdWN0cycsIGksICdwcm9kdWN0TmFtZScpXCI+UHJvZHVjdCBOYW1lIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+RGVzY3JpcHRpb248L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cImRlc2NyaXB0aW9uXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImUuZy4gQ3VzdG9tZXIgRm9vdGZhbGwgQW5hbHl0aWNzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+TW9udGg8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIm1vbnRoXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImUuZy4gTWFyIDIwMjZcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5IU04vU0FDPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJIc25OdW1iZXJcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlF1YW50aXR5PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGZvcm1Db250cm9sTmFtZT1cInN0b3JlQ291bnRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCJyZWNhbGN1bGF0ZSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UmF0ZS9QcmljZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwicHJpY2VcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3ByaWNlJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwicmVjYWxjdWxhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJpY2UnKVwiPlJhdGUvUHJpY2UgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5BbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwiYW1vdW50XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5QZXJpb2Q8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cInBlcmlvZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwibW9udGhseVwiPk1vbnRobHk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInF1YXJ0ZXJseVwiPlF1YXJ0ZXJseTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiaGFsZnllYXJseVwiPkhhbGYteWVhcmx5PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ5ZWFybHlcIj5ZZWFybHk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIFRheCBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tdGl0bGUgbWItMyBtdC0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+VGF4PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtcHJpbWFyeVwiIChjbGljayk9XCJhZGRUYXgoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgKyBBZGQgVGF4XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cInRheFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHQgb2YgdGF4QXJyYXkuY29udHJvbHM7IGxldCBqID0gaW5kZXhcIiBbZm9ybUdyb3VwTmFtZV09XCJqXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0YXgtcm93IG1iLTMgcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJvZHVjdC1sYWJlbFwiPlRheCB7eyBqICsgMSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1kYW5nZXJcIiAoY2xpY2spPVwicmVtb3ZlVGF4KGopXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInRheEFycmF5Lmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW1vdmVcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5UYXggVHlwZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cInR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJhcnJheUNvbnRyb2xJbnZhbGlkKCd0YXgnLCBqLCAndHlwZScpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHR0IG9mIHRheFR5cGVzXCIgW3ZhbHVlXT1cInR0XCI+e3sgdHQgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImFycmF5Q29udHJvbEludmFsaWQoJ3RheCcsIGosICd0eXBlJylcIj5UYXggVHlwZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlRheCAlIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBmb3JtQ29udHJvbE5hbWU9XCJ2YWx1ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgndGF4JywgaiwgJ3ZhbHVlJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwicmVjYWxjdWxhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgndGF4JywgaiwgJ3ZhbHVlJylcIj5UYXggJSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlRheCBBbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cInRheEFtb3VudFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Q3VycmVuY3kgU3ltYm9sPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJjdXJyZW5jeVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBTdW1tYXJ5IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktc2VjdGlvbiBwLTMgbXQtM1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5TdWJ0b3RhbDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fSB7eyBnZXRTdWJ0b3RhbCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+VG90YWwgVGF4PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19IHt7IGdldFRvdGFsVGF4KCkgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gc3VtbWFyeS10b3RhbFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktbGFiZWwtYm9sZFwiPlRvdGFsIEFtb3VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlLWJvbGRcIj57eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19IHt7IGdldFRvdGFsQW1vdW50KCkgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nXG4gICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEFjdGlvbnMgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IG10LTRcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gY2FuY2VsIG1lLTQgdy01MFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIFtkaXNhYmxlZF09XCJzYXZpbmdcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBweC00IHctNTBcIiBzdHlsZT1cIndoaXRlLXNwYWNlOiBub3dyYXA7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIXNhdmluZ1wiIGNsYXNzPVwic3VibWl0XCI+e3sgbW9kZSA9PT0gJ2VkaXQnID8gJ1VwZGF0ZSBJbnZvaWNlJyA6IChtb2RlID09PSAnZXN0aW1hdGUnID8gJ0dlbmVyYXRlIEVzdGltYXRlJyA6IChtb2RlID09PSAnZWRpdEVzdGltYXRlJyA/ICdVcGRhdGUgRXN0aW1hdGUnIDogJ0NyZWF0ZSBJbnZvaWNlJykpXG4gICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzYXZpbmdcIiBjbGFzcz1cInN1Ym1pdFwiPlNhdmluZy4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvcm0+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PSBDUkVESVQgTk9URSBUQUIgPT09PT09PT09PT09PT09PT09PT09PT09IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IG1iLTRcIiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2NyZWRpdE5vdGUnICYmIG1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImNyZWRpdE5vdGVGb3JtXCIgY2xhc3M9XCJmb3JtXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudHRleHQgbWItM1wiPlxuICAgICAgICAgICAgICAgIEFwcGx5IGEgY3JlZGl0IG5vdGUgLyBkaXNjb3VudCB0byB0aGlzIGludm9pY2UuIE1heGltdW0gMTAlIGRpc2NvdW50IGFsbG93ZWQuXG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPkludm9pY2UgSUQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFt2YWx1ZV09XCJpbnZvaWNlRGF0YT8uaW52b2ljZVwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcHktMlwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+VG90YWwgQW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRvbGxhci1zaWduXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgZm9ybUNvbnRyb2xOYW1lPVwiYW1vdW50XCIgdHlwZT1cInRleHRcIiByZWFkb25seSBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+UmV2aXNlZCBBbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cInJldmlzZWRBbW91bnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwib21pdFNwZWNpYWxDaGFyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAnZXJyb3JpbnB1dCcgOiAnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtaWNvblwiICpuZ0lmPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnIGNsaXAtcGF0aD1cInVybCgjY2xpcF9jbl9lcnIpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk03Ljk5OTY3IDUuMzMzMDFWNy45OTk2N003Ljk5OTY3IDEwLjY2NjNIOC4wMDYzNE0xNC42NjYzIDcuOTk5NjdDMTQuNjY2MyAxMS42ODE2IDExLjY4MTYgMTQuNjY2MyA3Ljk5OTY3IDE0LjY2NjNDNC4zMTc3OCAxNC42NjYzIDEuMzMzMDEgMTEuNjgxNiAxLjMzMzAxIDcuOTk5NjdDMS4zMzMwMSA0LjMxNzc4IDQuMzE3NzggMS4zMzMwMSA3Ljk5OTY3IDEuMzMzMDFDMTEuNjgxNiAxLjMzMzAxIDE0LjY2NjMgNC4zMTc3OCAxNC42NjYzIDcuOTk5NjdaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiI0YwNDQzOFwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRlZnM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNsaXBQYXRoIGlkPVwiY2xpcF9jbl9lcnJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJlY3Qgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgZmlsbD1cIndoaXRlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NsaXBQYXRoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kZWZzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIFtuZ0NsYXNzXT1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA/ICd0ZXh0LWRhbmdlcicgOiAnY29udGVudHRleHQnXCIgY2xhc3M9XCJzbWFsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgTW9yZSB0aGFuIDEwJSBjYW4ndCBiZSByZXZpc2VkIGZyb20gdG90YWwgYW1vdW50XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5EaXNjb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJkaXNjb3VudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlwcmVzcyk9XCJvbWl0U3BlY2lhbENoYXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJ2Vycm9yaW5wdXQnIDogJydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWljb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgdmlld0JveD1cIjAgMCAxNiAxNlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTEyLjY2NyAzLjMzMzY2TDMuMzMzNjYgMTIuNjY3TTYuMDAwMzMgNC4zMzM2NkM2LjAwMDMzIDUuMjU0MTMgNS4yNTQxMyA2LjAwMDMzIDQuMzMzNjYgNi4wMDAzM0MzLjQxMzE4IDYuMDAwMzMgMi42NjY5OSA1LjI1NDEzIDIuNjY2OTkgNC4zMzM2NkMyLjY2Njk5IDMuNDEzMTggMy40MTMxOCAyLjY2Njk5IDQuMzMzNjYgMi42NjY5OUM1LjI1NDEzIDIuNjY2OTkgNi4wMDAzMyAzLjQxMzE4IDYuMDAwMzMgNC4zMzM2NlpNMTMuMzMzNyAxMS42NjdDMTMuMzMzNyAxMi41ODc1IDEyLjU4NzUgMTMuMzMzNyAxMS42NjcgMTMuMzMzN0MxMC43NDY1IDEzLjMzMzcgMTAuMDAwMyAxMi41ODc1IDEwLjAwMDMgMTEuNjY3QzEwLjAwMDMgMTAuNzQ2NSAxMC43NDY1IDEwLjAwMDMgMTEuNjY3IDEwLjAwMDNDMTIuNTg3NSAxMC4wMDAzIDEzLjMzMzcgMTAuNzQ2NSAxMy4zMzM3IDExLjY2N1pcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnN0cm9rZV09XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAnI0YwNDQzOCcgOiAnIzk4QTJCMydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gW25nQ2xhc3NdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJ3RleHQtZGFuZ2VyJyA6ICdjb250ZW50dGV4dCdcIiBjbGFzcz1cInNtYWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBJbiBwZXJjZW50YWdlXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IG10LTVcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gY2FuY2VsIG1lLTQgdy01MFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCB8fCBzYXZpbmdcIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFwcGx5Q3JlZGl0Tm90ZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcHgtNCB3LTUwXCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogbm93cmFwO1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzYXZpbmdcIj5BcHBseSBDcmVkaXQgTm90ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzYXZpbmdcIj5BcHBseWluZy4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvcm0+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PSBPTkUgVElNRSBGRUUgVEFCID09PT09PT09PT09PT09PT09PT09PT09PSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keSBtYi00XCIgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdvbmVUaW1lRmVlJyAmJiBtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJvbmVUaW1lRmVlRm9ybVwiIGNsYXNzPVwiZm9ybVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnR0ZXh0IG1iLTNcIj5cbiAgICAgICAgICAgICAgICBBZGQgYSBvbmUtdGltZSBmZWUgKGUuZy4gaW5zdGFsbGF0aW9uKSB0byB0aGlzIGludm9pY2UuXG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPkludm9pY2UgSUQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFt2YWx1ZV09XCJpbnZvaWNlRGF0YT8uaW52b2ljZVwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcHktMlwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+Q3VycmVudCBJbnZvaWNlIEFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGZvcm1Db250cm9sTmFtZT1cImFtb3VudFwiIHR5cGU9XCJ0ZXh0XCIgcmVhZG9ubHkgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPk9uZSBUaW1lIEZlZSAoSW5zdGFsbGF0aW9uKTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRvbGxhci1zaWduXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwib25lVGltZUZlZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlwcmVzcyk9XCJvbWl0U3BlY2lhbENoYXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sIGFtb3VudC1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRW50ZXIgZmVlIGFtb3VudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LXN0YWNrIG10LTMgZmVlLXN1bW1hcnkgcC0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+U2VsZWN0ZWQgSW52b2ljZSBBbW91bnQgKyBPbmUgVGltZSBGZWU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS12YWx1ZS1ib2xkXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX17e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uZVRpbWVGZWVUb3RhbCB8IG51bWJlcjonMS4yLTInOidlbi1JTicgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggbXQtNVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhY3RpdmVNb2RhbC5kaXNtaXNzKClcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1vdXRsaW5lIGJ0biBjYW5jZWwgbWUtNCB3LTUwXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwic2F2aW5nIHx8ICFvbmVUaW1lRmVlRm9ybS5nZXQoJ29uZVRpbWVGZWUnKT8udmFsdWVcIiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5T25lVGltZUZlZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcHgtNCB3LTUwXCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogbm93cmFwO1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzYXZpbmdcIj5BcHBseSBGZWU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic2F2aW5nXCI+QXBwbHlpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuPC9kaXY+Il19
|
|
602
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLEtBQUssRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFdkYsT0FBTyxFQUFxQyxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7OztBQVMxQyxNQUFNLE9BQU8sb0JBQW9CO0lBaUR0QjtJQUNDO0lBQ0E7SUFDQTtJQUNBO0lBcERELFdBQVcsQ0FBTTtJQUMxQiwwRUFBMEU7SUFDMUUsOERBQThEO0lBQ3JELElBQUksR0FBb0QsTUFBTSxDQUFDO0lBQy9ELFFBQVEsR0FBVyxFQUFFLENBQUM7SUFDdEIsYUFBYSxHQUFVLEVBQUUsQ0FBQztJQUVuQyxXQUFXLENBQWE7SUFDUCxRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUMxQyxNQUFNLEdBQVksS0FBSyxDQUFDO0lBRXhCLHVDQUF1QztJQUN2QyxTQUFTLEdBQVcsTUFBTSxDQUFDO0lBRTNCLFFBQVEsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEMsZUFBZSxHQUFHLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDdEUsY0FBYyxHQUEyQjtRQUN2QyxHQUFHLEVBQUUsU0FBUztRQUNkLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLGVBQWUsRUFBRSxVQUFVO1FBQzNCLElBQUksRUFBRSxTQUFTO1FBQ2YsR0FBRyxFQUFFLFdBQVc7S0FDakIsQ0FBQztJQUNGLDRFQUE0RTtJQUM1RSwwRUFBMEU7SUFDMUUsc0NBQXNDO0lBQ3JCLGVBQWUsR0FBMkI7UUFDekQsR0FBRyxFQUFFLEdBQUc7UUFDUixNQUFNLEVBQUUsR0FBRztRQUNYLGVBQWUsRUFBRSxJQUFJO1FBQ3JCLElBQUksRUFBRSxHQUFHO1FBQ1QsR0FBRyxFQUFFLEtBQUs7S0FDWCxDQUFDO0lBQ0YsYUFBYSxHQUFHLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3hDLG9CQUFvQixHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRTFDLGNBQWM7SUFDZCxjQUFjLENBQWE7SUFDM0Isd0JBQXdCLEdBQVksS0FBSyxDQUFDO0lBRTFDLDZCQUE2QjtJQUM3QixpQkFBaUIsR0FBVSxFQUFFLENBQUM7SUFFOUIsZUFBZTtJQUNmLGNBQWMsQ0FBYTtJQUMzQixlQUFlLEdBQVcsQ0FBQyxDQUFDO0lBRTVCLFlBQ1MsV0FBMkIsRUFDMUIsRUFBZSxFQUNmLGNBQThCLEVBQzlCLGNBQWlDLEVBQ2pDLEtBQW1CO1FBSnBCLGdCQUFXLEdBQVgsV0FBVyxDQUFnQjtRQUMxQixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ2YsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNqQyxVQUFLLEdBQUwsS0FBSyxDQUFjO0lBQzFCLENBQUM7SUFFSixRQUFRO1FBQ04sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2hCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUM1QyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7U0FDaEM7YUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssY0FBYyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDM0QseUVBQXlFO1lBQ3pFLG9FQUFvRTtZQUNwRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7U0FDbEI7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUM7UUFDeEQsSUFBSSxHQUFHLEVBQUU7WUFDUCxJQUFJLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUNyRixJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtvQkFDakIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDO29CQUN6QyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN0QyxDQUFDO2dCQUNELEtBQUssRUFBRSxHQUFHLEVBQUU7b0JBQ1YsSUFBSSxDQUFDLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztnQkFDOUIsQ0FBQzthQUNGLENBQUMsQ0FBQztTQUNKO0lBQ0gsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFhO1FBQzNCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdDLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxDQUFDO1FBQzVELDZFQUE2RTtRQUM3RSxvRUFBb0U7UUFDcEUsSUFBSSxZQUFZLEtBQUssWUFBWSxFQUFFO1lBQ2pDLFlBQVksQ0FBQyxVQUFVLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxXQUFXLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4RixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsT0FBTztTQUNSO1FBQ0QsWUFBWSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEtBQUssWUFBWSxDQUFDLENBQUM7UUFDakYsSUFBSSxPQUFPLEVBQUU7WUFDWCxZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbkQsd0NBQXdDO1lBQ3hDLE1BQU0sWUFBWSxHQUEyQjtnQkFDM0MsWUFBWSxFQUFFLDZCQUE2QjtnQkFDM0MsU0FBUyxFQUFFLG9DQUFvQztnQkFDL0MsU0FBUyxFQUFFLDRCQUE0QjtnQkFDdkMsZUFBZSxFQUFFLGtCQUFrQjthQUNwQyxDQUFDO1lBQ0YsWUFBWSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsRUFBRSxRQUFRLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzVFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUNwQjtJQUNILENBQUM7SUFFRCw0RUFBNEU7SUFDNUUsdUNBQXVDO0lBQ3ZDLGdCQUFnQjtRQUNkLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELGlCQUFpQixDQUFDLElBQVk7UUFDNUIsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNyQiw2RUFBNkU7UUFDN0UsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixFQUFFLE9BQU8sQ0FBQzthQUM1QyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQztRQUN4RCxJQUFJLEdBQUcsRUFBRTtZQUNQLElBQUksQ0FBQyxjQUFjLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ3BGLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO29CQUNqQixJQUFJLENBQUMsYUFBYSxHQUFHLEdBQUcsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDO29CQUNyQyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN0QyxDQUFDO2dCQUNELEtBQUssRUFBRSxHQUFHLEVBQUU7b0JBQ1YsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7Z0JBQzFCLENBQUM7YUFDRixDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsTUFBTSxDQUFDLEdBQVc7UUFDaEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUM7SUFDdkIsQ0FBQztJQUVELDJEQUEyRDtJQUUzRCxRQUFRO1FBQ04sSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUMvQixXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUN0QyxjQUFjLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDcEIsU0FBUyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2YsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ25CLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNmLG9FQUFvRTtZQUNwRSw0Q0FBNEM7WUFDNUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUQsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckQsV0FBVyxFQUFFLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDdEMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDbEMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDdEMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDO1lBQ25CLGFBQWEsRUFBRSxDQUFDLFFBQVEsQ0FBQztZQUN6QixzRUFBc0U7WUFDdEUscUVBQXFFO1lBQ3JFLGNBQWMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUN2QixhQUFhLEVBQUUsQ0FBQyxTQUFTLENBQUM7WUFDMUIsUUFBUSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQixHQUFHLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1NBQ3ZCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxvQkFBb0IsR0FBRztRQUNyQixFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLHNCQUFzQixFQUFFO1FBQ25ELEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsMkJBQTJCLEVBQUU7UUFDMUQsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSw2QkFBNkIsRUFBRTtRQUM3RCxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLHlCQUF5QixFQUFFO0tBQ3RELENBQUM7SUFFRiwyRUFBMkU7SUFDM0UsMkVBQTJFO0lBQzNFLDREQUE0RDtJQUM1RCxjQUFjLENBQUMsSUFBWTtRQUN6QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxPQUFPLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ2hELENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxTQUE2QixFQUFFLEtBQWEsRUFBRSxJQUFZO1FBQzVFLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLFNBQVMsQ0FBcUIsQ0FBQztRQUNqRSxNQUFNLElBQUksR0FBRyxHQUFHLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QyxPQUFPLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ2hELENBQUM7SUFFTyxvQkFBb0I7UUFDMUIsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSw0QkFBNEI7UUFDNUIsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sS0FBSyxHQUFHLElBQUksRUFBRSxhQUFhLENBQUMsYUFBYSxDQUF1QixDQUFDO1FBQ3ZFLElBQUksS0FBSyxFQUFFO1lBQ1QsS0FBSyxDQUFDLGNBQWMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDOUQsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLEtBQUssVUFBVSxFQUFFO2dCQUNyQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDdEM7U0FDRjtJQUNILENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBYyxDQUFDO0lBQ3ZELENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBYyxDQUFDO0lBQ2xELENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxPQUFhO1FBQzlCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDbkIsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLFdBQVcsSUFBSSxFQUFFLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUM5RCwyRUFBMkU7WUFDM0Usc0VBQXNFO1lBQ3RFLG9CQUFvQjtZQUNwQixRQUFRLEVBQUUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxJQUFJLEtBQUssQ0FBQztZQUN0QyxXQUFXLEVBQUUsQ0FBQyxPQUFPLEVBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQztZQUN6QyxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUM3QixTQUFTLEVBQUUsQ0FBQyxPQUFPLEVBQUUsU0FBUyxJQUFJLFFBQVEsQ0FBQztZQUMzQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLEVBQUUsVUFBVSxJQUFJLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pELEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEUsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUM7WUFDOUIsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sSUFBSSxTQUFTLENBQUM7U0FDdkMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGNBQWMsQ0FBQyxHQUFTO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUM7WUFDbkIsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUNoRCxLQUFLLEVBQUUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxJQUFJLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDeEYsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLFNBQVMsSUFBSSxHQUFHLENBQUM7WUFDbEMsc0VBQXNFO1lBQ3RFLCtEQUErRDtZQUMvRCxRQUFRLEVBQUUsQ0FBQyxHQUFHLEVBQUUsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDdEYsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLFNBQVMsQ0FBQyxJQUErQjtRQUMvQyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUNqRCxDQUFDO0lBRUQsVUFBVTtRQUNSLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELGFBQWEsQ0FBQyxLQUFhO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVELFNBQVM7UUFDUCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBRTdCLElBQUksQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDO1lBQzFCLFdBQVcsRUFBRSxHQUFHLENBQUMsV0FBVyxJQUFJLEVBQUU7WUFDbEMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxjQUFjLElBQUksRUFBRTtZQUN4QyxTQUFTLEVBQUUsR0FBRyxDQUFDLFNBQVMsSUFBSSxFQUFFO1lBQzlCLGFBQWEsRUFBRSxHQUFHLENBQUMsYUFBYSxJQUFJLEVBQUU7WUFDdEMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTLElBQUksRUFBRTtZQUM5QixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sSUFBSSxFQUFFO1lBQzFCLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUM7WUFDdkIsV0FBVyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1lBQ3JELE9BQU8sRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUM3QyxRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVEsSUFBSSxLQUFLO1lBQy9CLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxJQUFJLFNBQVM7WUFDL0IsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhLElBQUksUUFBUTtTQUM3QyxDQUFDLENBQUM7UUFFSCxpQkFBaUI7UUFDakIsSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRTtZQUN4QixHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO2dCQUM5QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRCxDQUFDLENBQUMsQ0FBQztTQUNKO2FBQU07WUFDTCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7U0FDbkI7UUFFRCxZQUFZO1FBQ1osSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRTtZQUNuQixHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO2dCQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0MsQ0FBQyxDQUFDLENBQUM7U0FDSjthQUFNO1lBQ0wsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQ2Y7SUFDSCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBUztRQUMxQixJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLENBQUM7UUFDeEMsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDbEMsT0FBTyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxhQUFhLENBQUMsS0FBVTtRQUN0QixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRixJQUFJLGFBQWEsRUFBRTtZQUNqQixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQztnQkFDMUIsU0FBUyxFQUFFLGFBQWEsQ0FBQyxTQUFTO2dCQUNsQyxPQUFPLEVBQUUsYUFBYSxDQUFDLEdBQUc7Z0JBQzFCLFdBQVcsRUFBRSxhQUFhLENBQUMscUJBQXFCLElBQUksRUFBRTtnQkFDdEQsY0FBYyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSxhQUFhLENBQUMsY0FBYyxFQUFFLGFBQWEsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDOUwsU0FBUyxFQUFFLGFBQWEsQ0FBQyxHQUFHLElBQUksRUFBRTtnQkFDbEMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxhQUFhLElBQUksRUFBRTthQUNqRCxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZDLE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUN2RCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7WUFDN0MsTUFBTSxNQUFNLEdBQUcsVUFBVSxHQUFHLEtBQUssQ0FBQztZQUNsQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbkYsUUFBUSxJQUFJLE1BQU0sQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZDLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQztZQUM3QyxNQUFNLFNBQVMsR0FBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3RELEtBQUssQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZDLFdBQVcsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDckQsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxRQUFRLENBQUMsV0FBVyxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFNUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBR0QsV0FBVztRQUNULElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUN2QyxRQUFRLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDdkMsUUFBUSxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQztRQUMvRCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ2pELENBQUM7SUFFRCxpQkFBaUI7UUFDZixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELHdCQUF3QjtRQUN0QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUU7WUFDNUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3BDLGdFQUFnRTtZQUNoRSxzRUFBc0U7WUFDdEUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2pELE9BQU87U0FDUjtRQUVELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ25CLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFakQsTUFBTSxPQUFPLEdBQVE7WUFDbkIsV0FBVyxFQUFFLFNBQVMsQ0FBQyxXQUFXO1lBQ2xDLGNBQWMsRUFBRSxTQUFTLENBQUMsY0FBYztZQUN4QyxTQUFTLEVBQUUsU0FBUyxDQUFDLFNBQVM7WUFDOUIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO1lBQ3RDLFNBQVMsRUFBRSxTQUFTLENBQUMsU0FBUztZQUM5QixPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87WUFDMUIsTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNO1lBQ3hCLFdBQVcsRUFBRSxTQUFTLENBQUMsV0FBVztZQUNsQyxPQUFPLEVBQUUsU0FBUyxDQUFDLE9BQU87WUFDMUIsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzVCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTTtZQUN4QixhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQWE7WUFDdEMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxjQUFjO1lBQ3hDLGFBQWEsRUFBRSxTQUFTLENBQUMsYUFBYTtZQUN0QyxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVE7WUFDNUIsR0FBRyxFQUFFLFNBQVMsQ0FBQyxHQUFHO1lBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQzFCLFdBQVcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUMvQyxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRTtZQUN4QixPQUFPLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUM7WUFDM0MsT0FBTyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQztZQUM3QyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDbEYsSUFBSSxFQUFFLENBQUMsR0FBUSxFQUFFLEVBQUU7b0JBQ2pCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO29CQUNwQixJQUFJLEdBQUcsRUFBRTt3QkFDUCxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO3dCQUMzRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDbkM7Z0JBQ0gsQ0FBQztnQkFDRCxLQUFLLEVBQUUsR0FBRyxFQUFFO29CQUNWLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO29CQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO2dCQUN2RCxDQUFDO2FBQ0YsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssY0FBYyxFQUFFO1lBQ3ZDLHNFQUFzRTtZQUN0RSwwRUFBMEU7WUFDMUUsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQztZQUNuQyxPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDOUQsT0FBTyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUMsV0FBVztnQkFDcEMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUM7Z0JBQzlGLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztZQUM1QixPQUFPLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUM7WUFDdEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ25GLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO29CQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztvQkFDcEIsSUFBSSxHQUFHLEVBQUU7d0JBQ1AsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsK0JBQStCLENBQUMsQ0FBQzt3QkFDNUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7cUJBQ25DO2dCQUNILENBQUM7Z0JBQ0QsS0FBSyxFQUFFLENBQUMsR0FBUSxFQUFFLEVBQUU7b0JBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO29CQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sSUFBSSwyQkFBMkIsQ0FBQyxDQUFDO2dCQUMvRSxDQUFDO2FBQ0YsQ0FBQyxDQUFDO1NBQ0o7YUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO1lBQ25DLHdFQUF3RTtZQUN4RSx1RUFBdUU7WUFDdkUsT0FBTyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLFdBQVc7Z0JBQ3BDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDO2dCQUM5RixDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2QsT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUNuRixJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtvQkFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7b0JBQ3BCLElBQUksR0FBRyxFQUFFO3dCQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7d0JBQzlELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO3FCQUNuQztnQkFDSCxDQUFDO2dCQUNELEtBQUssRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO29CQUNsQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztvQkFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLElBQUksNkJBQTZCLENBQUMsQ0FBQztnQkFDakYsQ0FBQzthQUNGLENBQUMsQ0FBQztTQUNKO2FBQU07WUFDTCxPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDakMsdUVBQXVFO1lBQ3ZFLG9FQUFvRTtZQUNwRSxtRUFBbUU7WUFDbkUsMkNBQTJDO1lBQzNDLE9BQU8sQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQzdCLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUNsRixJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtvQkFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7b0JBQ3BCLElBQUksR0FBRyxFQUFFO3dCQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLDhCQUE4QixDQUFDLENBQUM7d0JBQzNELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO3FCQUNuQztnQkFDSCxDQUFDO2dCQUNELEtBQUssRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO29CQUNsQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztvQkFDcEIsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFLEtBQUssRUFBRSxPQUFPLElBQUksMEJBQTBCLENBQUM7b0JBQzlELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNoQyxDQUFDO2FBQ0YsQ0FBQyxDQUFDO1NBQ0o7SUFDSCxDQUFDO0lBRUQsMERBQTBEO0lBRTFELGtCQUFrQjtRQUNoQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO1lBQ2xDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNaLGFBQWEsRUFBRSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDO1lBQ3hDLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQzFELENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3BHLElBQUksQ0FBQyxFQUFFO2dCQUNMLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLEtBQUssQ0FBQztnQkFDeEQsSUFBSSxNQUFNLEVBQUU7b0JBQ1YsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUMxRCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMzRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxRQUFRLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7aUJBQy9FO2FBQ0Y7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUN4RSxJQUFJLENBQUMsd0JBQXdCLEdBQUcsS0FBSyxDQUFDO2FBQ3ZDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMvRixJQUFJLENBQUMsRUFBRTtnQkFDTCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUM7Z0JBQ3hELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO2dCQUN2RixJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDbkY7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RSxJQUFJLENBQUMsd0JBQXdCLEdBQUcsS0FBSyxDQUFDO2FBQ3ZDO1lBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCx1QkFBdUI7UUFDckIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDO2dCQUM3QixNQUFNLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLElBQUksQ0FBQzthQUNyRSxDQUFDLENBQUM7U0FDSjtJQUNILENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxJQUFJLENBQUMsd0JBQXdCO1lBQUUsT0FBTztRQUMxQyxNQUFNLFdBQVcsR0FBRztZQUNsQixPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPO1lBQ2pDLGFBQWEsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsRUFBRSxLQUFLO1lBQzlELFFBQVEsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxLQUFLO1NBQ3JELENBQUM7UUFDRixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUN0RixJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7Z0JBQ3BCLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFFO29CQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO29CQUMvRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztpQkFDekM7WUFDSCxDQUFDO1lBQ0QsS0FBSyxFQUFFLEdBQUcsRUFBRTtnQkFDVixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztnQkFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsNkJBQTZCLENBQUMsQ0FBQztZQUMxRCxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFVO1FBQ3hCLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7UUFDekIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVELDJEQUEyRDtJQUUzRCxrQkFBa0I7UUFDaEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUNsQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDWixVQUFVLEVBQUUsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQztTQUN0QyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDN0UsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsdUJBQXVCO1FBQ3JCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNwQixJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztnQkFDN0IsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxJQUFJLENBQUM7YUFDckUsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7U0FDakM7SUFDSCxDQUFDO0lBRUQsd0JBQXdCO1FBQ3RCLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxLQUFLLElBQUksR0FBRyxDQUFDLENBQUM7UUFDM0UsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsZUFBZSxHQUFHLFVBQVUsQ0FBQyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQsZUFBZTtRQUNiLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLEtBQUssQ0FBQztRQUM5RCxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDdEIsTUFBTSxXQUFXLEdBQUc7WUFDbEIsVUFBVSxFQUFFLFFBQVE7U0FDckIsQ0FBQztRQUNGLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ25CLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQzdHLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztnQkFDcEIsSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLEVBQUU7b0JBQzFCLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7b0JBQ2hFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN0QztZQUNILENBQUM7WUFDRCxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUNWLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO2dCQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQzNELENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO3dHQTdtQlUsb0JBQW9COzRGQUFwQixvQkFBb0Isb0tDWmpDLHF3MkJBMGJNOzs0RkQ5YU8sb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNFLGtCQUFrQjtxTUFLbkIsV0FBVztzQkFBbkIsS0FBSztnQkFHRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIE9uRGVzdHJveSwgSW5wdXQsIENoYW5nZURldGVjdG9yUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ2JBY3RpdmVNb2RhbCB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIEZvcm1BcnJheSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQmlsbGluZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9iaWxsaW5nLnNlcnZpY2UnO1xuaW1wb3J0IHsgVG9hc3RTZXJ2aWNlIH0gZnJvbSAndGFuZ28tYXBwLXVpLXNoYXJlZCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1lZGl0LWludm9pY2UnLFxuICB0ZW1wbGF0ZVVybDogJy4vZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2VkaXQtaW52b2ljZS5jb21wb25lbnQuc2Nzcydcbn0pXG5leHBvcnQgY2xhc3MgRWRpdEludm9pY2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGludm9pY2VEYXRhOiBhbnk7XG4gIC8vICdlc3RpbWF0ZScgcmV1c2VzIHRoZSB3aG9sZSBjcmVhdGUgZm9ybSBidXQgc3VibWl0cyB0byB0aGUgZXN0aW1hdGUgQVBJXG4gIC8vIGFuZCB3cml0ZXMgdG8gdGhlIGVzdGltYXRlcyBjb2xsZWN0aW9uIGluc3RlYWQgb2YgaW52b2ljZXMuXG4gIEBJbnB1dCgpIG1vZGU6ICdlZGl0JyB8ICdjcmVhdGUnIHwgJ2VzdGltYXRlJyB8ICdlZGl0RXN0aW1hdGUnID0gJ2VkaXQnO1xuICBASW5wdXQoKSBjbGllbnRJZDogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGJpbGxpbmdHcm91cHM6IGFueVtdID0gW107XG5cbiAgaW52b2ljZUZvcm0hOiBGb3JtR3JvdXA7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveSQgPSBuZXcgU3ViamVjdCgpO1xuICBzYXZpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBUYWJzOiBlZGl0IHwgY3JlZGl0Tm90ZSB8IG9uZVRpbWVGZWVcbiAgYWN0aXZlVGFiOiBzdHJpbmcgPSAnZWRpdCc7XG5cbiAgdGF4VHlwZXMgPSBbJ0lHU1QnLCAnQ0dTVCcsICdTR1NUJ107XG4gIGN1cnJlbmN5T3B0aW9ucyA9IFsnaW5yJywgJ2RvbGxhcicsICdzaW5nYXBvcmVkb2xsYXInLCAnZXVybycsICdhZWQnXTtcbiAgY3VycmVuY3lMYWJlbHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAnSU5SICjigrkpJyxcbiAgICBkb2xsYXI6ICdVU0QgKCQpJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdTR0QgKFMkKScsXG4gICAgZXVybzogJ0VVUiAo4oKsKScsXG4gICAgYWVkOiAnQUVEIChBRUQpJ1xuICB9O1xuICAvLyBTeW1ib2wgbWFwIG1pcnJvcnMgdGhlIGJhY2tlbmQncyBDVVJSRU5DWV9TWU1CT0xTIGluIHV0aWxzL2N1cnJlbmN5LmpzIHNvXG4gIC8vIHRoZSBtb2RhbCwgaW52b2ljZSBsaXN0LCBjcmVkaXQtbm90ZSBhbmQgb25lLXRpbWUtZmVlIHBvcHVwcyBhbGwgcmVuZGVyXG4gIC8vIHRoZSBzYW1lIHN5bWJvbCB0aGUgUERGL2VtYWlsIHVzZXMuXG4gIHByaXZhdGUgcmVhZG9ubHkgY3VycmVuY3lTeW1ib2xzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGlucjogJ+KCuScsXG4gICAgZG9sbGFyOiAnJCcsXG4gICAgc2luZ2Fwb3JlZG9sbGFyOiAnUyQnLFxuICAgIGV1cm86ICfigqwnLFxuICAgIGFlZDogJ0FFRCcsXG4gIH07XG4gIHN0YXR1c09wdGlvbnMgPSBbJ3BlbmRpbmcnLCAnYXBwcm92ZWQnXTtcbiAgcGF5bWVudFN0YXR1c09wdGlvbnMgPSBbJ3VucGFpZCcsICdwYWlkJ107XG5cbiAgLy8gQ3JlZGl0IE5vdGVcbiAgY3JlZGl0Tm90ZUZvcm0hOiBGb3JtR3JvdXA7XG4gIGNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIFByb2R1Y3RzIGZyb20gYmFzZSBwcmljaW5nXG4gIGF2YWlsYWJsZVByb2R1Y3RzOiBhbnlbXSA9IFtdO1xuXG4gIC8vIE9uZSBUaW1lIEZlZVxuICBvbmVUaW1lRmVlRm9ybSE6IEZvcm1Hcm91cDtcbiAgb25lVGltZUZlZVRvdGFsOiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBhY3RpdmVNb2RhbDogTmdiQWN0aXZlTW9kYWwsXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSBiaWxsaW5nU2VydmljZTogQmlsbGluZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSB0b2FzdDogVG9hc3RTZXJ2aWNlXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRCaWxsaW5nR3JvdXBzKCk7XG4gICAgdGhpcy5sb2FkQ2xpZW50UHJvZHVjdHMoKTtcbiAgICB0aGlzLmluaXRGb3JtKCk7XG4gICAgdGhpcy5pbml0Q3JlZGl0Tm90ZUZvcm0oKTtcbiAgICB0aGlzLmluaXRPbmVUaW1lRmVlRm9ybSgpO1xuICAgIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0JyAmJiB0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICB0aGlzLnBhdGNoRm9ybSgpO1xuICAgICAgdGhpcy5wYXRjaENyZWRpdE5vdGVEZWZhdWx0cygpO1xuICAgICAgdGhpcy5wYXRjaE9uZVRpbWVGZWVEZWZhdWx0cygpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZWRpdEVzdGltYXRlJyAmJiB0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICAvLyBFZGl0aW5nIGFuIGVzdGltYXRlIHJldXNlcyB0aGUgc2FtZSBmb3JtIGZpZWxkczsgdGhlIGVzdGltYXRlIGRvY3VtZW50XG4gICAgICAvLyBzaGFyZXMgdGhlIGludm9pY2Ugc2hhcGUgKGNvbXBhbnlOYW1lLCBwcm9kdWN0cywgdGF4LCBzdG9yZXMsIOKApikuXG4gICAgICB0aGlzLnBhdGNoRm9ybSgpO1xuICAgIH1cbiAgfVxuXG4gIGxvYWRDbGllbnRQcm9kdWN0cygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmIChjSWQpIHtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0Q2xpZW50QmFzZVByaWNpbmcoY0lkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5hdmFpbGFibGVQcm9kdWN0cyA9IHJlcz8uZGF0YSB8fCBbXTtcbiAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmF2YWlsYWJsZVByb2R1Y3RzID0gW107XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG9uUHJvZHVjdENoYW5nZShpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgcHJvZHVjdEdyb3VwID0gdGhpcy5wcm9kdWN0cy5hdChpbmRleCk7XG4gICAgY29uc3Qgc2VsZWN0ZWROYW1lID0gcHJvZHVjdEdyb3VwLmdldCgncHJvZHVjdE5hbWUnKT8udmFsdWU7XG4gICAgLy8gXCIrIEN1c3RvbSBwcm9kdWN0XCIgcGlja2VkIGZyb20gdGhlIGRyb3Bkb3duIOKAlCBzd2l0Y2ggdGhpcyByb3cgdG8gZnJlZS10ZXh0XG4gICAgLy8gZW50cnkgKGN1c3RvbSBuYW1lICsgcHJpY2UpLCBjbGVhcmluZyB0aGUgYmFzZS1wcmljaW5nIHNlbGVjdGlvbi5cbiAgICBpZiAoc2VsZWN0ZWROYW1lID09PSAnX19jdXN0b21fXycpIHtcbiAgICAgIHByb2R1Y3RHcm91cC5wYXRjaFZhbHVlKHsgaXNDdXN0b206IHRydWUsIHByb2R1Y3ROYW1lOiAnJywgcHJpY2U6IDAsIGRlc2NyaXB0aW9uOiAnJyB9KTtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcHJvZHVjdEdyb3VwLmdldCgnaXNDdXN0b20nKT8uc2V0VmFsdWUoZmFsc2UpO1xuICAgIGNvbnN0IHByb2R1Y3QgPSB0aGlzLmF2YWlsYWJsZVByb2R1Y3RzLmZpbmQocCA9PiBwLnByb2R1Y3ROYW1lID09PSBzZWxlY3RlZE5hbWUpO1xuICAgIGlmIChwcm9kdWN0KSB7XG4gICAgICBwcm9kdWN0R3JvdXAuZ2V0KCdwcmljZScpPy5zZXRWYWx1ZShwcm9kdWN0LnByaWNlKTtcbiAgICAgIC8vIFNldCBkZXNjcmlwdGlvbiBiYXNlZCBvbiBwcm9kdWN0IG5hbWVcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgdGFuZ29UcmFmZmljOiAnQ3VzdG9tZXIgRm9vdGZhbGwgQW5hbHl0aWNzJyxcbiAgICAgICAgdGFuZ29ab25lOiAnUHJvZHVjdCBjYXRlZ29yeS9zZWN0aW9uIGFuYWx5dGljcycsXG4gICAgICAgIHRhbmdvVHJheDogJ0N1c3RvbWVyIEpvdXJuZXkgQW5hbHl0aWNzJyxcbiAgICAgICAgcHJpb3JpdHlTdXBwb3J0OiAnUHJpb3JpdHkgU3VwcG9ydCcsXG4gICAgICB9O1xuICAgICAgcHJvZHVjdEdyb3VwLmdldCgnZGVzY3JpcHRpb24nKT8uc2V0VmFsdWUoZGVzY3JpcHRpb25zW3NlbGVjdGVkTmFtZV0gfHwgJycpO1xuICAgICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFkZCBhIGJsYW5rIHByb2R1Y3Qgcm93IGFscmVhZHkgaW4gY3VzdG9tIChmcmVlLXRleHQpIG1vZGUsIHJlZ2FyZGxlc3Mgb2ZcbiAgLy8gd2hldGhlciBiYXNlLXByaWNpbmcgcHJvZHVjdHMgZXhpc3QuXG4gIGFkZEN1c3RvbVByb2R1Y3QoKSB7XG4gICAgdGhpcy5wcm9kdWN0cy5wdXNoKHRoaXMuY3JlYXRlUHJvZHVjdEdyb3VwKHsgaXNDdXN0b206IHRydWUgfSkpO1xuICB9XG5cbiAgZm9ybWF0UHJvZHVjdE5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIW5hbWUpIHJldHVybiAnJztcbiAgICAvLyBDb252ZXJ0IGNhbWVsQ2FzZSB0byBUaXRsZSBDYXNlIHdpdGggc3BhY2VzOiB0YW5nb1RyYWZmaWMgLT4gVGFuZ28gVHJhZmZpY1xuICAgIHJldHVybiBuYW1lLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpXG4gICAgICAucmVwbGFjZSgvXi4vLCAoc3RyKSA9PiBzdHIudG9VcHBlckNhc2UoKSk7XG4gIH1cblxuICBsb2FkQmlsbGluZ0dyb3VwcygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmIChjSWQpIHtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0QWxsQmlsbGluZ0dyb3VwcyhjSWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLmJpbGxpbmdHcm91cHMgPSByZXM/LmRhdGEgfHwgW107XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5iaWxsaW5nR3JvdXBzID0gW107XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBzZXRUYWIodGFiOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVRhYiA9IHRhYjtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PSBFRElUIElOVk9JQ0UgPT09PT09PT09PT09PT09PT09PT09XG5cbiAgaW5pdEZvcm0oKSB7XG4gICAgdGhpcy5pbnZvaWNlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgY29tcGFueU5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBjb21wYW55QWRkcmVzczogWycnXSxcbiAgICAgIEdTVE51bWJlcjogWycnXSxcbiAgICAgIFBsYWNlT2ZTdXBwbHk6IFsnJ10sXG4gICAgICBncm91cE5hbWU6IFsnJ10sXG4gICAgICAvLyBCaWxsaW5nIEdyb3VwIGlzIHJlcXVpcmVkIHdoZW4gY3JlYXRpbmcg4oCUIHRoZSByZXN0IG9mIHRoZSBjb21wYW55XG4gICAgICAvLyBmaWVsZHMgYXV0by1maWxsIGZyb20gdGhlIHNlbGVjdGVkIGdyb3VwLlxuICAgICAgZ3JvdXBJZDogWycnLCB0aGlzLm1vZGUgIT09ICdlZGl0JyA/IFZhbGlkYXRvcnMucmVxdWlyZWQgOiBbXV0sXG4gICAgICBzdG9yZXM6IFswLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGJpbGxpbmdEYXRlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgZHVlRGF0ZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIGN1cnJlbmN5OiBbJ2lucicsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgc3RhdHVzOiBbJ3BlbmRpbmcnXSxcbiAgICAgIHBheW1lbnRTdGF0dXM6IFsndW5wYWlkJ10sXG4gICAgICAvLyBBZHZhbmNlIGludm9pY2U6IHdoZW4gb24sIHRoZSBjaG9zZW4gZnJlcXVlbmN5IGJpbGxzIHNldmVyYWwgZnV0dXJlXG4gICAgICAvLyBtb250aHMgdXBmcm9udCAoZWFjaCBtb250aCBiZWNvbWVzIGl0cyBvd24gbGluZSBpdGVtIHNlcnZlci1zaWRlKS5cbiAgICAgIGFkdmFuY2VJbnZvaWNlOiBbZmFsc2VdLFxuICAgICAgYWR2YW5jZVBlcmlvZDogWydtb250aGx5J10sXG4gICAgICBwcm9kdWN0czogdGhpcy5mYi5hcnJheShbXSksXG4gICAgICB0YXg6IHRoaXMuZmIuYXJyYXkoW10pLFxuICAgIH0pO1xuICB9XG5cbiAgYWR2YW5jZVBlcmlvZE9wdGlvbnMgPSBbXG4gICAgeyB2YWx1ZTogJ21vbnRobHknLCBsYWJlbDogJ01vbnRobHkgKG5leHQgbW9udGgpJyB9LFxuICAgIHsgdmFsdWU6ICdxdWFydGVybHknLCBsYWJlbDogJ1F1YXJ0ZXJseSAobmV4dCAzIG1vbnRocyknIH0sXG4gICAgeyB2YWx1ZTogJ2hhbGZ5ZWFybHknLCBsYWJlbDogJ0hhbGYteWVhcmx5IChuZXh0IDYgbW9udGhzKScgfSxcbiAgICB7IHZhbHVlOiAneWVhcmx5JywgbGFiZWw6ICdZZWFybHkgKG5leHQgMTIgbW9udGhzKScgfSxcbiAgXTtcblxuICAvLyBUZW1wbGF0ZSBoZWxwZXJzOiBzdXJmYWNlIFwidG91Y2hlZCAmJiBpbnZhbGlkXCIgc28gdGhlIEhUTUwgY2FuIGhpZ2hsaWdodFxuICAvLyB0aGUgZmllbGQgYW5kIHJlbmRlciBhbiBpbmxpbmUgZXJyb3IuIERlZmVuc2l2ZSBhZ2FpbnN0IHRoZSBmb3JtIG5vdCB5ZXRcbiAgLy8gYmVpbmcgaW5pdGlhbGlzZWQgZHVyaW5nIHRoZSBmaXJzdCBjaGFuZ2UtZGV0ZWN0aW9uIHBhc3MuXG4gIGNvbnRyb2xJbnZhbGlkKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmludm9pY2VGb3JtPy5nZXQobmFtZSk7XG4gICAgcmV0dXJuICEhY3RybCAmJiBjdHJsLnRvdWNoZWQgJiYgY3RybC5pbnZhbGlkO1xuICB9XG5cbiAgYXJyYXlDb250cm9sSW52YWxpZChhcnJheU5hbWU6ICdwcm9kdWN0cycgfCAndGF4JywgaW5kZXg6IG51bWJlciwgbmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5pbnZvaWNlRm9ybT8uZ2V0KGFycmF5TmFtZSkgYXMgRm9ybUFycmF5IHwgbnVsbDtcbiAgICBjb25zdCBjdHJsID0gYXJyPy5hdChpbmRleCk/LmdldChuYW1lKTtcbiAgICByZXR1cm4gISFjdHJsICYmIGN0cmwudG91Y2hlZCAmJiBjdHJsLmludmFsaWQ7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbFRvRmlyc3RJbnZhbGlkKCk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIGZpcnN0IGludmFsaWQgY29udHJvbCBpbnNpZGUgdGhlIG1vZGFsIGFuZCBicmluZyBpdCBpbnRvIHZpZXcuXG4gICAgLy8gU2NvcGVkIHRvIC5tb2RhbC1jb250ZW50IHNvIHdlIGRvbid0IGdyYWIgZmllbGRzIGZyb20gb3RoZXIgbW9kYWxzIG9uXG4gICAgLy8gdGhlIHBhZ2UgaWYgYW55IGFyZSBvcGVuLlxuICAgIGNvbnN0IHJvb3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kYWwtY29udGVudCcpO1xuICAgIGNvbnN0IGZpcnN0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcignLmlzLWludmFsaWQnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKGZpcnN0KSB7XG4gICAgICBmaXJzdC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgaWYgKHR5cGVvZiBmaXJzdC5mb2N1cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmaXJzdC5mb2N1cyh7IHByZXZlbnRTY3JvbGw6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IHByb2R1Y3RzKCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdwcm9kdWN0cycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGdldCB0YXhBcnJheSgpOiBGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmludm9pY2VGb3JtLmdldCgndGF4JykgYXMgRm9ybUFycmF5O1xuICB9XG5cbiAgY3JlYXRlUHJvZHVjdEdyb3VwKHByb2R1Y3Q/OiBhbnkpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIHByb2R1Y3ROYW1lOiBbcHJvZHVjdD8ucHJvZHVjdE5hbWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgLy8gV2hlbiB0cnVlLCB0aGUgbmFtZSBpcyBhIGZyZWUtdGV4dCBjdXN0b20gcHJvZHVjdCAobm90IGZyb20gdGhlIGNsaWVudCdzXG4gICAgICAvLyBiYXNlLXByaWNpbmcgbGlzdCkg4oCUIHRoZSB0ZW1wbGF0ZSBzaG93cyBhIHRleHQgaW5wdXQgaW5zdGVhZCBvZiB0aGVcbiAgICAgIC8vIHByb2R1Y3QgZHJvcGRvd24uXG4gICAgICBpc0N1c3RvbTogW3Byb2R1Y3Q/LmlzQ3VzdG9tIHx8IGZhbHNlXSxcbiAgICAgIGRlc2NyaXB0aW9uOiBbcHJvZHVjdD8uZGVzY3JpcHRpb24gfHwgJyddLFxuICAgICAgbW9udGg6IFtwcm9kdWN0Py5tb250aCB8fCAnJ10sXG4gICAgICBIc25OdW1iZXI6IFtwcm9kdWN0Py5Ic25OdW1iZXIgfHwgJzk5ODMxNCddLFxuICAgICAgc3RvcmVDb3VudDogW3Byb2R1Y3Q/LnN0b3JlQ291bnQgfHwgMCwgVmFsaWRhdG9ycy5taW4oMCldLFxuICAgICAgcHJpY2U6IFtwcm9kdWN0Py5wcmljZSB8fCAwLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGFtb3VudDogW3Byb2R1Y3Q/LmFtb3VudCB8fCAwXSxcbiAgICAgIHBlcmlvZDogW3Byb2R1Y3Q/LnBlcmlvZCB8fCAnbW9udGhseSddLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlVGF4R3JvdXAodGF4PzogYW55KTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5mYi5ncm91cCh7XG4gICAgICB0eXBlOiBbdGF4Py50eXBlIHx8ICdJR1NUJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YWx1ZTogW3RheD8udmFsdWUgfHwgMTgsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbigwKSwgVmFsaWRhdG9ycy5tYXgoMTAwKV1dLFxuICAgICAgdGF4QW1vdW50OiBbdGF4Py50YXhBbW91bnQgfHwgJzAnXSxcbiAgICAgIC8vIERlZmF1bHQgdGhlIHRheC1yb3cgc3ltYm9sIHRvIHRoZSBpbnZvaWNlJ3MgY3VycmVuY3kgKHdhcyBoYXJkY29kZWRcbiAgICAgIC8vIHRvIOKCuSwgd2hpY2ggbGVha2VkIGludG8gdGhlIHNhdmVkIGRvYyBmb3Igbm9uLUlOUiBpbnZvaWNlcykuXG4gICAgICBjdXJyZW5jeTogW3RheD8uY3VycmVuY3kgfHwgdGhpcy5zeW1ib2xGb3IodGhpcy5pbnZvaWNlRm9ybT8uZ2V0KCdjdXJyZW5jeScpPy52YWx1ZSldLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW1ib2xGb3IoY29kZTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVuY3lTeW1ib2xzW2NvZGUgfHwgJyddIHx8ICckJztcbiAgfVxuXG4gIGFkZFByb2R1Y3QoKSB7XG4gICAgdGhpcy5wcm9kdWN0cy5wdXNoKHRoaXMuY3JlYXRlUHJvZHVjdEdyb3VwKCkpO1xuICB9XG5cbiAgcmVtb3ZlUHJvZHVjdChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5wcm9kdWN0cy5yZW1vdmVBdChpbmRleCk7XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICB9XG5cbiAgYWRkVGF4KCkge1xuICAgIHRoaXMudGF4QXJyYXkucHVzaCh0aGlzLmNyZWF0ZVRheEdyb3VwKCkpO1xuICB9XG5cbiAgcmVtb3ZlVGF4KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnRheEFycmF5LnJlbW92ZUF0KGluZGV4KTtcbiAgICB0aGlzLnJlY2FsY3VsYXRlKCk7XG4gIH1cblxuICBwYXRjaEZvcm0oKSB7XG4gICAgY29uc3QgaW52ID0gdGhpcy5pbnZvaWNlRGF0YTtcblxuICAgIHRoaXMuaW52b2ljZUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICBjb21wYW55TmFtZTogaW52LmNvbXBhbnlOYW1lIHx8ICcnLFxuICAgICAgY29tcGFueUFkZHJlc3M6IGludi5jb21wYW55QWRkcmVzcyB8fCAnJyxcbiAgICAgIEdTVE51bWJlcjogaW52LkdTVE51bWJlciB8fCAnJyxcbiAgICAgIFBsYWNlT2ZTdXBwbHk6IGludi5QbGFjZU9mU3VwcGx5IHx8ICcnLFxuICAgICAgZ3JvdXBOYW1lOiBpbnYuZ3JvdXBOYW1lIHx8ICcnLFxuICAgICAgZ3JvdXBJZDogaW52Lmdyb3VwSWQgfHwgJycsXG4gICAgICBzdG9yZXM6IGludi5zdG9yZXMgfHwgMCxcbiAgICAgIGJpbGxpbmdEYXRlOiB0aGlzLmZvcm1hdERhdGVGb3JJbnB1dChpbnYuYmlsbGluZ0RhdGUpLFxuICAgICAgZHVlRGF0ZTogdGhpcy5mb3JtYXREYXRlRm9ySW5wdXQoaW52LmR1ZURhdGUpLFxuICAgICAgY3VycmVuY3k6IGludi5jdXJyZW5jeSB8fCAnaW5yJyxcbiAgICAgIHN0YXR1czogaW52LnN0YXR1cyB8fCAncGVuZGluZycsXG4gICAgICBwYXltZW50U3RhdHVzOiBpbnYucGF5bWVudFN0YXR1cyB8fCAndW5wYWlkJyxcbiAgICB9KTtcblxuICAgIC8vIFBhdGNoIHByb2R1Y3RzXG4gICAgaWYgKGludi5wcm9kdWN0cz8ubGVuZ3RoKSB7XG4gICAgICBpbnYucHJvZHVjdHMuZm9yRWFjaCgocDogYW55KSA9PiB7XG4gICAgICAgIHRoaXMucHJvZHVjdHMucHVzaCh0aGlzLmNyZWF0ZVByb2R1Y3RHcm91cChwKSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGRQcm9kdWN0KCk7XG4gICAgfVxuXG4gICAgLy8gUGF0Y2ggdGF4XG4gICAgaWYgKGludi50YXg/Lmxlbmd0aCkge1xuICAgICAgaW52LnRheC5mb3JFYWNoKCh0OiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy50YXhBcnJheS5wdXNoKHRoaXMuY3JlYXRlVGF4R3JvdXAodCkpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWRkVGF4KCk7XG4gICAgfVxuICB9XG5cbiAgZm9ybWF0RGF0ZUZvcklucHV0KGRhdGU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKCFkYXRlKSByZXR1cm4gJyc7XG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKGRhdGU/LiRkYXRlIHx8IGRhdGUpO1xuICAgIGlmIChpc05hTihkLmdldFRpbWUoKSkpIHJldHVybiAnJztcbiAgICByZXR1cm4gZC50b0lTT1N0cmluZygpLnNwbGl0KCdUJylbMF07XG4gIH1cblxuICBvbkdyb3VwQ2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwID0gdGhpcy5iaWxsaW5nR3JvdXBzLmZpbmQoZyA9PiBnLl9pZCA9PT0gZXZlbnQudGFyZ2V0LnZhbHVlKTtcbiAgICBpZiAoc2VsZWN0ZWRHcm91cCkge1xuICAgICAgdGhpcy5pbnZvaWNlRm9ybS5wYXRjaFZhbHVlKHtcbiAgICAgICAgZ3JvdXBOYW1lOiBzZWxlY3RlZEdyb3VwLmdyb3VwTmFtZSxcbiAgICAgICAgZ3JvdXBJZDogc2VsZWN0ZWRHcm91cC5faWQsXG4gICAgICAgIGNvbXBhbnlOYW1lOiBzZWxlY3RlZEdyb3VwLnJlZ2lzdGVyZWRDb21wYW55TmFtZSB8fCAnJyxcbiAgICAgICAgY29tcGFueUFkZHJlc3M6IFtzZWxlY3RlZEdyb3VwLmFkZHJlc3NMaW5lT25lLCBzZWxlY3RlZEdyb3VwLmFkZHJlc3NMaW5lVHdvLCBzZWxlY3RlZEdyb3VwLmNpdHksIHNlbGVjdGVkR3JvdXAuc3RhdGUsIHNlbGVjdGVkR3JvdXAuY291bnRyeSwgc2VsZWN0ZWRHcm91cC5waW5Db2RlXS5maWx0ZXIoQm9vbGVhbikuam9pbignLCAnKSxcbiAgICAgICAgR1NUTnVtYmVyOiBzZWxlY3RlZEdyb3VwLmdzdCB8fCAnJyxcbiAgICAgICAgUGxhY2VPZlN1cHBseTogc2VsZWN0ZWRHcm91cC5wbGFjZU9mU3VwcGx5IHx8ICcnLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmVjYWxjdWxhdGUoKSB7XG4gICAgbGV0IHN1YnRvdGFsID0gMDtcbiAgICB0aGlzLnByb2R1Y3RzLmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICBjb25zdCBzdG9yZUNvdW50ID0gZ3JvdXAuZ2V0KCdzdG9yZUNvdW50Jyk/LnZhbHVlIHx8IDA7XG4gICAgICBjb25zdCBwcmljZSA9IGdyb3VwLmdldCgncHJpY2UnKT8udmFsdWUgfHwgMDtcbiAgICAgIGNvbnN0IGFtb3VudCA9IHN0b3JlQ291bnQgKiBwcmljZTtcbiAgICAgIGdyb3VwLmdldCgnYW1vdW50Jyk/LnNldFZhbHVlKHBhcnNlRmxvYXQoYW1vdW50LnRvRml4ZWQoMikpLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICBzdWJ0b3RhbCArPSBhbW91bnQ7XG4gICAgfSk7XG5cbiAgICB0aGlzLnRheEFycmF5LmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdyb3VwLmdldCgndmFsdWUnKT8udmFsdWUgfHwgMDtcbiAgICAgIGNvbnN0IHRheEFtb3VudCA9IChzdWJ0b3RhbCAqIHZhbHVlIC8gMTAwKS50b0ZpeGVkKDIpO1xuICAgICAgZ3JvdXAuZ2V0KCd0YXhBbW91bnQnKT8uc2V0VmFsdWUodGF4QW1vdW50LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSk7XG5cbiAgICBsZXQgdG90YWxTdG9yZXMgPSAwO1xuICAgIHRoaXMucHJvZHVjdHMuY29udHJvbHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgIHRvdGFsU3RvcmVzICs9IGdyb3VwLmdldCgnc3RvcmVDb3VudCcpPy52YWx1ZSB8fCAwO1xuICAgIH0pO1xuICAgIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdzdG9yZXMnKT8uc2V0VmFsdWUodG90YWxTdG9yZXMsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cblxuICBnZXRTdWJ0b3RhbCgpOiBudW1iZXIge1xuICAgIGxldCBzdWJ0b3RhbCA9IDA7XG4gICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgc3VidG90YWwgKz0gZ3JvdXAuZ2V0KCdhbW91bnQnKT8udmFsdWUgfHwgMDtcbiAgICB9KTtcbiAgICByZXR1cm4gc3VidG90YWw7XG4gIH1cblxuICBnZXRUb3RhbFRheCgpOiBudW1iZXIge1xuICAgIGxldCB0b3RhbFRheCA9IDA7XG4gICAgdGhpcy50YXhBcnJheS5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgdG90YWxUYXggKz0gcGFyc2VGbG9hdChncm91cC5nZXQoJ3RheEFtb3VudCcpPy52YWx1ZSB8fCAnMCcpO1xuICAgIH0pO1xuICAgIHJldHVybiB0b3RhbFRheDtcbiAgfVxuXG4gIGdldFRvdGFsQW1vdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0U3VidG90YWwoKSArIHRoaXMuZ2V0VG90YWxUYXgoKTtcbiAgfVxuXG4gIGdldEN1cnJlbmN5U3ltYm9sKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3ltYm9sRm9yKHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdjdXJyZW5jeScpPy52YWx1ZSk7XG4gIH1cblxuICBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zeW1ib2xGb3IodGhpcy5pbnZvaWNlRGF0YT8uY3VycmVuY3kpO1xuICB9XG5cbiAgb25TdWJtaXQoKSB7XG4gICAgaWYgKHRoaXMuaW52b2ljZUZvcm0uaW52YWxpZCkge1xuICAgICAgdGhpcy5pbnZvaWNlRm9ybS5tYXJrQWxsQXNUb3VjaGVkKCk7XG4gICAgICAvLyBEZWZlciB0byBuZXh0IHRpY2sgc28gQW5ndWxhciByZW5kZXJzIHRoZSAuaXMtaW52YWxpZCBjbGFzc2VzXG4gICAgICAvLyBiZWZvcmUgd2UgcXVlcnkgdGhlIERPTSBmb3IgdGhlIGZpcnN0IGludmFsaWQgY29udHJvbCB0byBzY3JvbGwgdG8uXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2Nyb2xsVG9GaXJzdEludmFsaWQoKSwgMCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMuaW52b2ljZUZvcm0uZ2V0UmF3VmFsdWUoKTtcblxuICAgIGNvbnN0IHBheWxvYWQ6IGFueSA9IHtcbiAgICAgIGNvbXBhbnlOYW1lOiBmb3JtVmFsdWUuY29tcGFueU5hbWUsXG4gICAgICBjb21wYW55QWRkcmVzczogZm9ybVZhbHVlLmNvbXBhbnlBZGRyZXNzLFxuICAgICAgR1NUTnVtYmVyOiBmb3JtVmFsdWUuR1NUTnVtYmVyLFxuICAgICAgUGxhY2VPZlN1cHBseTogZm9ybVZhbHVlLlBsYWNlT2ZTdXBwbHksXG4gICAgICBncm91cE5hbWU6IGZvcm1WYWx1ZS5ncm91cE5hbWUsXG4gICAgICBncm91cElkOiBmb3JtVmFsdWUuZ3JvdXBJZCxcbiAgICAgIHN0b3JlczogZm9ybVZhbHVlLnN0b3JlcyxcbiAgICAgIGJpbGxpbmdEYXRlOiBmb3JtVmFsdWUuYmlsbGluZ0RhdGUsXG4gICAgICBkdWVEYXRlOiBmb3JtVmFsdWUuZHVlRGF0ZSxcbiAgICAgIGN1cnJlbmN5OiBmb3JtVmFsdWUuY3VycmVuY3ksXG4gICAgICBzdGF0dXM6IGZvcm1WYWx1ZS5zdGF0dXMsXG4gICAgICBwYXltZW50U3RhdHVzOiBmb3JtVmFsdWUucGF5bWVudFN0YXR1cyxcbiAgICAgIGFkdmFuY2VJbnZvaWNlOiBmb3JtVmFsdWUuYWR2YW5jZUludm9pY2UsXG4gICAgICBhZHZhbmNlUGVyaW9kOiBmb3JtVmFsdWUuYWR2YW5jZVBlcmlvZCxcbiAgICAgIHByb2R1Y3RzOiBmb3JtVmFsdWUucHJvZHVjdHMsXG4gICAgICB0YXg6IGZvcm1WYWx1ZS50YXgsXG4gICAgICBhbW91bnQ6IHRoaXMuZ2V0U3VidG90YWwoKSxcbiAgICAgIHRvdGFsQW1vdW50OiBNYXRoLnJvdW5kKHRoaXMuZ2V0VG90YWxBbW91bnQoKSksXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0Jykge1xuICAgICAgcGF5bG9hZC5faWQgPSB0aGlzLmludm9pY2VEYXRhLl9pZDtcbiAgICAgIHBheWxvYWQuaW52b2ljZSA9IHRoaXMuaW52b2ljZURhdGEuaW52b2ljZTtcbiAgICAgIHBheWxvYWQuY2xpZW50SWQgPSB0aGlzLmludm9pY2VEYXRhLmNsaWVudElkO1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS51cGRhdGVJbnZvaWNlKHBheWxvYWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdJbnZvaWNlIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCd1cGRhdGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gdXBkYXRlIGludm9pY2UnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0RXN0aW1hdGUnKSB7XG4gICAgICAvLyBVcGRhdGUgYW4gZXhpc3RpbmcgZXN0aW1hdGUuIElkZW50aXR5IGZpZWxkcyAoZXN0aW1hdGUgIywgY2xpZW50SWQsXG4gICAgICAvLyBjcmVhdGVkRGF0ZSkgYXJlIHByZXNlcnZlZCBzZXJ2ZXItc2lkZTsgd2Ugc2VuZCB0aGUgZWRpdGFibGUgZm9ybSBkYXRhLlxuICAgICAgcGF5bG9hZC5faWQgPSB0aGlzLmludm9pY2VEYXRhLl9pZDtcbiAgICAgIHBheWxvYWQuY2xpZW50SWQgPSB0aGlzLmludm9pY2VEYXRhLmNsaWVudElkIHx8IHRoaXMuY2xpZW50SWQ7XG4gICAgICBwYXlsb2FkLnBlcmlvZCA9IGZvcm1WYWx1ZS5iaWxsaW5nRGF0ZVxuICAgICAgICA/IG5ldyBEYXRlKGZvcm1WYWx1ZS5iaWxsaW5nRGF0ZSkudG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJywgeyBtb250aDogJ3Nob3J0JywgeWVhcjogJ251bWVyaWMnIH0pXG4gICAgICAgIDogdGhpcy5pbnZvaWNlRGF0YS5wZXJpb2Q7XG4gICAgICBwYXlsb2FkLnZhbGlkVGlsbCA9IGZvcm1WYWx1ZS5kdWVEYXRlO1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS51cGRhdGVFc3RpbWF0ZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnRXN0aW1hdGUgdXBkYXRlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ3VwZGF0ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdChlcnI/LmVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gdXBkYXRlIGVzdGltYXRlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZXN0aW1hdGUnKSB7XG4gICAgICAvLyBTYW1lIGZvcm0sIHNlcGFyYXRlIGRvY3VtZW50OiBwb3N0IHRvIHRoZSBlc3RpbWF0ZSBBUEkgc28gaXQgbGFuZHMgaW5cbiAgICAgIC8vIHRoZSBlc3RpbWF0ZXMgY29sbGVjdGlvbiB3aXRoIGFuIEVTVC3igKYgbnVtYmVyIGluc3RlYWQgb2YgYW4gaW52b2ljZS5cbiAgICAgIHBheWxvYWQuY2xpZW50SWQgPSB0aGlzLmNsaWVudElkO1xuICAgICAgcGF5bG9hZC5wZXJpb2QgPSBmb3JtVmFsdWUuYmlsbGluZ0RhdGVcbiAgICAgICAgPyBuZXcgRGF0ZShmb3JtVmFsdWUuYmlsbGluZ0RhdGUpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycsIHsgbW9udGg6ICdzaG9ydCcsIHllYXI6ICdudW1lcmljJyB9KVxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIHBheWxvYWQudmFsaWRUaWxsID0gZm9ybVZhbHVlLmR1ZURhdGU7XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmNyZWF0ZUVzdGltYXRlKHBheWxvYWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdFc3RpbWF0ZSBnZW5lcmF0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdjcmVhdGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGdlbmVyYXRlIGVzdGltYXRlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5jbGllbnRJZDtcbiAgICAgIC8vIEZsYWcgdGhlIGJhY2tlbmQgdG8gdGFrZSB0aGUgXCJjdXN0b20gY3JlYXRlXCIgcGF0aCB0aGF0IHBlcnNpc3RzIHdoYXRcbiAgICAgIC8vIHRoZSBmb3JtIGJ1aWx0LiBUaGUgbGVnYWN5IC9jcmVhdGVJbnZvaWNlIGNvbnRyYWN0IGV4cGVjdHMgZWl0aGVyXG4gICAgICAvLyBhbGxDbGllbnQrY2xpZW50TGlzdCBvciBpbnZvaWNlSWQ7IHdpdGhvdXQgdGhpcyBmbGFnLCB0aGUgc2VydmVyXG4gICAgICAvLyBzaWxlbnRseSByZXR1cm5zIDJ4eCBhbmQgd3JpdGVzIG5vdGhpbmcuXG4gICAgICBwYXlsb2FkLmN1c3RvbUludm9pY2UgPSB0cnVlO1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS5jcmVhdGVJbnZvaWNlKHBheWxvYWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdJbnZvaWNlIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdjcmVhdGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBjb25zdCBtc2cgPSBlcnI/LmVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gY3JlYXRlIGludm9pY2UnO1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdChtc2cpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT0gQ1JFRElUIE5PVEUgPT09PT09PT09PT09PT09PT09PT09XG5cbiAgaW5pdENyZWRpdE5vdGVGb3JtKCkge1xuICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGFtb3VudDogWycnXSxcbiAgICAgIHJldmlzZWRBbW91bnQ6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBkaXNjb3VudDogWycnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5tYXgoMTApXV0sXG4gICAgfSk7XG5cbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgncmV2aXNlZEFtb3VudCcpPy52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZSkgPT4ge1xuICAgICAgaWYgKGUpIHtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Ftb3VudCcpPy52YWx1ZTtcbiAgICAgICAgaWYgKGFtb3VudCkge1xuICAgICAgICAgIGNvbnN0IGRpc2NvdW50ID0gKChhbW91bnQgLSBlKSAvIGFtb3VudCAqIDEwMCkudG9GaXhlZCgyKTtcbiAgICAgICAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IHBhcnNlRmxvYXQoZGlzY291bnQpID4gMTAgfHwgaXNOYU4oZSkgfHwgcGFyc2VGbG9hdChkaXNjb3VudCkgPCAwIHx8IGUgPCAwO1xuICAgICAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdkaXNjb3VudCcpPy5zZXRWYWx1ZShkaXNjb3VudCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnZGlzY291bnQnKT8uc2V0VmFsdWUoJycsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgdGhpcy5jcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdkaXNjb3VudCcpPy52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZSkgPT4ge1xuICAgICAgaWYgKGUpIHtcbiAgICAgICAgY29uc3QgYW1vdW50ID0gdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Ftb3VudCcpPy52YWx1ZTtcbiAgICAgICAgY29uc3QgcmV2aXNlZCA9IHBhcnNlSW50KChhbW91bnQgKiAoMSAtIGUgLyAxMDApKS50b0ZpeGVkKCkpO1xuICAgICAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IHBhcnNlRmxvYXQoZSkgPiAxMCB8fCBpc05hTihlKSB8fCBlIDwgMCB8fCByZXZpc2VkIDwgMDtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8uc2V0VmFsdWUocmV2aXNlZCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8uc2V0VmFsdWUoJycsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgdGhpcy5jcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuICB9XG5cbiAgcGF0Y2hDcmVkaXROb3RlRGVmYXVsdHMoKSB7XG4gICAgaWYgKHRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgIGFtb3VudDogdGhpcy5pbnZvaWNlRGF0YS5hbW91bnQgfHwgdGhpcy5pbnZvaWNlRGF0YS50b3RhbEFtb3VudCB8fCAwLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYXBwbHlDcmVkaXROb3RlKCkge1xuICAgIGlmICh0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCkgcmV0dXJuO1xuICAgIGNvbnN0IHJlcXVlc3REYXRhID0ge1xuICAgICAgaW52b2ljZTogdGhpcy5pbnZvaWNlRGF0YS5pbnZvaWNlLFxuICAgICAgcmV2aXNlZEFtb3VudDogdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8udmFsdWUsXG4gICAgICBkaXNjb3VudDogdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Rpc2NvdW50Jyk/LnZhbHVlLFxuICAgIH07XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuYXBwbHlEaXNjb3VudChyZXF1ZXN0RGF0YSkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKHJlcyAmJiByZXMuY29kZSA9PSAyMDApIHtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnQ3JlZGl0IG5vdGUgYXBwbGllZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdjcmVkaXRBcHBsaWVkJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBhcHBseSBjcmVkaXQgbm90ZScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb21pdFNwZWNpYWxDaGFyKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBrID0gZXZlbnQuY2hhckNvZGU7XG4gICAgcmV0dXJuIChrID09IDggfHwgayA9PSAzMiB8fCAoayA+PSA0OCAmJiBrIDw9IDU3KSk7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT0gT05FIFRJTUUgRkVFID09PT09PT09PT09PT09PT09PT09PVxuXG4gIGluaXRPbmVUaW1lRmVlRm9ybSgpIHtcbiAgICB0aGlzLm9uZVRpbWVGZWVGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBhbW91bnQ6IFsnJ10sXG4gICAgICBvbmVUaW1lRmVlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgIH0pO1xuXG4gICAgdGhpcy5vbmVUaW1lRmVlRm9ybS52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmNhbGN1bGF0ZU9uZVRpbWVGZWVUb3RhbCgpO1xuICAgIH0pO1xuICB9XG5cbiAgcGF0Y2hPbmVUaW1lRmVlRGVmYXVsdHMoKSB7XG4gICAgaWYgKHRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIHRoaXMub25lVGltZUZlZUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgIGFtb3VudDogdGhpcy5pbnZvaWNlRGF0YS5hbW91bnQgfHwgdGhpcy5pbnZvaWNlRGF0YS50b3RhbEFtb3VudCB8fCAwLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmNhbGN1bGF0ZU9uZVRpbWVGZWVUb3RhbCgpO1xuICAgIH1cbiAgfVxuXG4gIGNhbGN1bGF0ZU9uZVRpbWVGZWVUb3RhbCgpIHtcbiAgICBjb25zdCBhbW91bnQgPSBwYXJzZUZsb2F0KHRoaXMub25lVGltZUZlZUZvcm0uZ2V0KCdhbW91bnQnKT8udmFsdWUgfHwgJzAnKTtcbiAgICBjb25zdCBmZWUgPSBwYXJzZUZsb2F0KHRoaXMub25lVGltZUZlZUZvcm0uZ2V0KCdvbmVUaW1lRmVlJyk/LnZhbHVlIHx8ICcwJyk7XG4gICAgdGhpcy5vbmVUaW1lRmVlVG90YWwgPSBwYXJzZUZsb2F0KChhbW91bnQgKyBmZWUpLnRvRml4ZWQoMikpO1xuICB9XG5cbiAgYXBwbHlPbmVUaW1lRmVlKCkge1xuICAgIGNvbnN0IGZlZVZhbHVlID0gdGhpcy5vbmVUaW1lRmVlRm9ybS5nZXQoJ29uZVRpbWVGZWUnKT8udmFsdWU7XG4gICAgaWYgKCFmZWVWYWx1ZSkgcmV0dXJuO1xuICAgIGNvbnN0IHJlcXVlc3REYXRhID0ge1xuICAgICAgb25lVGltZUZlZTogZmVlVmFsdWUsXG4gICAgfTtcbiAgICB0aGlzLnNhdmluZyA9IHRydWU7XG4gICAgdGhpcy5iaWxsaW5nU2VydmljZS5vbmVUaW1lRmVlKHJlcXVlc3REYXRhLCB0aGlzLmludm9pY2VEYXRhLmludm9pY2UpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgIGlmIChyZXMgJiYgcmVzLmNvZGUgPT0gMjAwKSB7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ09uZSB0aW1lIGZlZSBhcHBsaWVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ2ZlZUFwcGxpZWQnKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGFwcGx5IG9uZSB0aW1lIGZlZScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59IiwiPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICA8ZGl2IGNsYXNzPVwicC01IHB4LTYgcGItMFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRpbmcgbXQtMlwiPnt7IG1vZGUgPT09ICdlZGl0JyA/ICdJbnZvaWNlJyA6IChtb2RlID09PSAnZXN0aW1hdGUnID8gJ0dlbmVyYXRlIEVzdGltYXRlJyA6IChtb2RlID09PSAnZWRpdEVzdGltYXRlJyA/ICdFZGl0IEVzdGltYXRlJyA6ICdDcmVhdGUgSW52b2ljZScpKSB9fVxuICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwibW9kZSA9PT0gJ2VkaXQnXCIgY2xhc3M9XCJpbnZvaWNlLW51bWJlclwiPnt7IGludm9pY2VEYXRhPy5pbnZvaWNlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwibW9kZSA9PT0gJ2VkaXRFc3RpbWF0ZSdcIiBjbGFzcz1cImludm9pY2UtbnVtYmVyXCI+e3sgaW52b2ljZURhdGE/LmVzdGltYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbG9zZVwiIChjbGljayk9XCJhY3RpdmVNb2RhbC5kaXNtaXNzKClcIj48L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBUYWJzIChvbmx5IGluIGVkaXQgbW9kZSkgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YWItYmFyIG10LTNcIiAqbmdJZj1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInRhYi1idG5cIiBbbmdDbGFzc109XCJhY3RpdmVUYWIgPT09ICdlZGl0JyA/ICd0YWItYWN0aXZlJyA6ICcnXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2V0VGFiKCdlZGl0JylcIj5FZGl0IEludm9pY2U8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0YWItYnRuXCIgW25nQ2xhc3NdPVwiYWN0aXZlVGFiID09PSAnY3JlZGl0Tm90ZScgPyAndGFiLWFjdGl2ZScgOiAnJ1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInNldFRhYignY3JlZGl0Tm90ZScpXCI+Q3JlZGl0IE5vdGU8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0YWItYnRuXCIgW25nQ2xhc3NdPVwiYWN0aXZlVGFiID09PSAnb25lVGltZUZlZScgPyAndGFiLWFjdGl2ZScgOiAnJ1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInNldFRhYignb25lVGltZUZlZScpXCI+T25lIFRpbWUgRmVlPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT0gRURJVCBJTlZPSUNFIFRBQiA9PT09PT09PT09PT09PT09PT09PT09PT0gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHkgbWItNFwiICpuZ0lmPVwiYWN0aXZlVGFiID09PSAnZWRpdCcgfHwgbW9kZSAhPT0gJ2VkaXQnXCI+XG4gICAgICAgIDxmb3JtIFtmb3JtR3JvdXBdPVwiaW52b2ljZUZvcm1cIiBjbGFzcz1cImZvcm1cIiAobmdTdWJtaXQpPVwib25TdWJtaXQoKVwiPlxuXG4gICAgICAgICAgICA8IS0tIENvbXBhbnkgRGV0YWlscyBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tdGl0bGUgbWItM1wiPkNvbXBhbnkgRGV0YWlsczwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Q29tcGFueSBOYW1lIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cImNvbXBhbnlOYW1lXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiY29udHJvbEludmFsaWQoJ2NvbXBhbnlOYW1lJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdjb21wYW55TmFtZScpXCI+Q29tcGFueSBOYW1lIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+R1NUIE51bWJlcjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIkdTVE51bWJlclwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Db21wYW55IEFkZHJlc3M8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJjb21wYW55QWRkcmVzc1wiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlBsYWNlIG9mIFN1cHBseTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIlBsYWNlT2ZTdXBwbHlcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEJpbGxpbmcgR3JvdXAgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nSWY9XCJiaWxsaW5nR3JvdXBzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5CaWxsaW5nIEdyb3VwIDxzcGFuICpuZ0lmPVwibW9kZSAhPT0gJ2VkaXQnXCIgY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCAqbmdJZj1cIm1vZGUgIT09ICdlZGl0J1wiIGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJncm91cElkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdncm91cElkJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkdyb3VwQ2hhbmdlKCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgYmlsbGluZyBncm91cDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgZyBvZiBiaWxsaW5nR3JvdXBzXCIgW3ZhbHVlXT1cImcuX2lkXCI+e3sgZy5ncm91cE5hbWUgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCAqbmdJZj1cIm1vZGUgPT09ICdlZGl0J1wiIHR5cGU9XCJ0ZXh0XCIgW3ZhbHVlXT1cImludm9pY2VGb3JtLmdldCgnZ3JvdXBOYW1lJyk/LnZhbHVlIHx8ICdEZWZhdWx0IEdyb3VwJ1wiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiY29udHJvbEludmFsaWQoJ2dyb3VwSWQnKVwiPkJpbGxpbmcgR3JvdXAgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Hcm91cCBOYW1lPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZ3JvdXBOYW1lXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbcmVhZG9ubHldPVwibW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBJbnZvaWNlIERldGFpbHMgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLXRpdGxlIG1iLTMgbXQtMlwiPkludm9pY2UgRGV0YWlsczwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+QmlsbGluZyBEYXRlIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZGF0ZVwiIGZvcm1Db250cm9sTmFtZT1cImJpbGxpbmdEYXRlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiY29udHJvbEludmFsaWQoJ2JpbGxpbmdEYXRlJylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnYmlsbGluZ0RhdGUnKVwiPkJpbGxpbmcgRGF0ZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkR1ZSBEYXRlIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiZGF0ZVwiIGZvcm1Db250cm9sTmFtZT1cImR1ZURhdGVcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJjb250cm9sSW52YWxpZCgnZHVlRGF0ZScpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiY29udHJvbEludmFsaWQoJ2R1ZURhdGUnKVwiPkR1ZSBEYXRlIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Q3VycmVuY3kgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwiY3VycmVuY3lcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiY29udHJvbEludmFsaWQoJ2N1cnJlbmN5JylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGMgb2YgY3VycmVuY3lPcHRpb25zXCIgW3ZhbHVlXT1cImNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjdXJyZW5jeUxhYmVsc1tjXSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdjdXJyZW5jeScpXCI+Q3VycmVuY3kgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Oby4gb2YgU3RvcmVzPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBmb3JtQ29udHJvbE5hbWU9XCJzdG9yZXNcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQWR2YW5jZSBJbnZvaWNlIChjcmVhdGUgb25seSk6IGJpbGwgc2V2ZXJhbCBmdXR1cmUgbW9udGhzIHVwZnJvbnQuXG4gICAgICAgICAgICAgICAgIEVhY2ggbW9udGggYmVjb21lcyBpdHMgb3duIGxpbmUgaXRlbSBzZXJ2ZXItc2lkZS4gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nSWY9XCJtb2RlID09PSAnY3JlYXRlJ1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMSBkLWJsb2NrXCI+QWR2YW5jZSBJbnZvaWNlPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2sgZm9ybS1zd2l0Y2ggbXQtMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIGlkPVwiYWR2YW5jZUludm9pY2VDcmVhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImFkdmFuY2VJbnZvaWNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsXCIgZm9yPVwiYWR2YW5jZUludm9pY2VDcmVhdGVcIj5CaWxsIGZ1dHVyZSBtb250aHMgdXBmcm9udDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIiAqbmdJZj1cImludm9pY2VGb3JtLmdldCgnYWR2YW5jZUludm9pY2UnKT8udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkFkdmFuY2UgZnJlcXVlbmN5PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwiYWR2YW5jZVBlcmlvZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgb3B0IG9mIGFkdmFuY2VQZXJpb2RPcHRpb25zXCIgW3ZhbHVlXT1cIm9wdC52YWx1ZVwiPnt7IG9wdC5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG5cbiAgICAgICAgICAgIDwhLS0gUHJvZHVjdHMgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLXRpdGxlIG1iLTMgbXQtMlwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPlByb2R1Y3RzPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtcHJpbWFyeVwiIChjbGljayk9XCJhZGRQcm9kdWN0KClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEFkZCBQcm9kdWN0XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1zZWNvbmRhcnlcIiAoY2xpY2spPVwiYWRkQ3VzdG9tUHJvZHVjdCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBBZGQgQ3VzdG9tIFByb2R1Y3RcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGZvcm1BcnJheU5hbWU9XCJwcm9kdWN0c1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHByb2R1Y3Qgb2YgcHJvZHVjdHMuY29udHJvbHM7IGxldCBpID0gaW5kZXhcIiBbZm9ybUdyb3VwTmFtZV09XCJpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJwcm9kdWN0LXJvdyBtYi0zIHAtM1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlciBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByb2R1Y3QtbGFiZWxcIj5Qcm9kdWN0IHt7IGkgKyAxIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLWRhbmdlclwiIChjbGljayk9XCJyZW1vdmVQcm9kdWN0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInByb2R1Y3RzLmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW1vdmVcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC00IGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Qcm9kdWN0IE5hbWUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEJhc2UtcHJpY2luZyBkcm9wZG93biAod2l0aCBhIFwiKyBDdXN0b20gcHJvZHVjdFwiIGNob2ljZSkgd2hlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMgZXhpc3QgYW5kIHRoaXMgcm93IGlzbid0IGN1c3RvbTsgb3RoZXJ3aXNlIGEgZnJlZS10ZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIGlucHV0IGZvciBhIGN1c3RvbSBwcm9kdWN0LiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0ICpuZ0lmPVwiYXZhaWxhYmxlUHJvZHVjdHMubGVuZ3RoID4gMCAmJiAhcHJvZHVjdC5nZXQoJ2lzQ3VzdG9tJyk/LnZhbHVlXCIgZm9ybUNvbnRyb2xOYW1lPVwicHJvZHVjdE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Qcm9kdWN0Q2hhbmdlKGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgcHJvZHVjdDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBwIG9mIGF2YWlsYWJsZVByb2R1Y3RzXCIgW3ZhbHVlXT1cInAucHJvZHVjdE5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGZvcm1hdFByb2R1Y3ROYW1lKHAucHJvZHVjdE5hbWUpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiX19jdXN0b21fX1wiPisgQ3VzdG9tIHByb2R1Y3Q8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJhdmFpbGFibGVQcm9kdWN0cy5sZW5ndGggPT09IDAgfHwgcHJvZHVjdC5nZXQoJ2lzQ3VzdG9tJyk/LnZhbHVlXCIgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJwcm9kdWN0TmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBDdXN0b20gU2VydmljZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiPlByb2R1Y3QgTmFtZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkRlc2NyaXB0aW9uPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJkZXNjcmlwdGlvblwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIEN1c3RvbWVyIEZvb3RmYWxsIEFuYWx5dGljc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPk1vbnRoPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJtb250aFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIE1hciAyMDI2XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+SFNOL1NBQzwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiSHNuTnVtYmVyXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5RdWFudGl0eTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBmb3JtQ29udHJvbE5hbWU9XCJzdG9yZUNvdW50XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwicmVjYWxjdWxhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlJhdGUvUHJpY2UgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGZvcm1Db250cm9sTmFtZT1cInByaWNlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJhcnJheUNvbnRyb2xJbnZhbGlkKCdwcm9kdWN0cycsIGksICdwcmljZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cInJlY2FsY3VsYXRlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3ByaWNlJylcIj5SYXRlL1ByaWNlIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+QW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGZvcm1Db250cm9sTmFtZT1cImFtb3VudFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UGVyaW9kPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJwZXJpb2RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIm1vbnRobHlcIj5Nb250aGx5PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJxdWFydGVybHlcIj5RdWFydGVybHk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cImhhbGZ5ZWFybHlcIj5IYWxmLXllYXJseTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwieWVhcmx5XCI+WWVhcmx5PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBUYXggU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLXRpdGxlIG1iLTMgbXQtMlwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPlRheDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiAoY2xpY2spPVwiYWRkVGF4KClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICsgQWRkIFRheFxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGZvcm1BcnJheU5hbWU9XCJ0YXhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCB0IG9mIHRheEFycmF5LmNvbnRyb2xzOyBsZXQgaiA9IGluZGV4XCIgW2Zvcm1Hcm91cE5hbWVdPVwialwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwidGF4LXJvdyBtYi0zIHAtM1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlciBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByb2R1Y3QtbGFiZWxcIj5UYXgge3sgaiArIDEgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtZGFuZ2VyXCIgKGNsaWNrKT1cInJlbW92ZVRheChqKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJ0YXhBcnJheS5sZW5ndGggPiAxXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+VGF4IFR5cGUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJ0eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgndGF4JywgaiwgJ3R5cGUnKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCB0dCBvZiB0YXhUeXBlc1wiIFt2YWx1ZV09XCJ0dFwiPnt7IHR0IH19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJhcnJheUNvbnRyb2xJbnZhbGlkKCd0YXgnLCBqLCAndHlwZScpXCI+VGF4IFR5cGUgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5UYXggJSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwidmFsdWVcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3RheCcsIGosICd2YWx1ZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cInJlY2FsY3VsYXRlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImFycmF5Q29udHJvbEludmFsaWQoJ3RheCcsIGosICd2YWx1ZScpXCI+VGF4ICUgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5UYXggQW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJ0YXhBbW91bnRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkN1cnJlbmN5IFN5bWJvbDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiY3VycmVuY3lcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gU3VtbWFyeSAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdW1tYXJ5LXNlY3Rpb24gcC0zIG10LTNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+U3VidG90YWw8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS12YWx1ZVwiPnt7IGdldEN1cnJlbmN5U3ltYm9sKCkgfX0ge3sgZ2V0U3VidG90YWwoKSB8IG51bWJlcjonMS4yLTInOidlbi1JTicgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPlRvdGFsIFRheDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fSB7eyBnZXRUb3RhbFRheCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHN1bW1hcnktdG90YWxcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LWxhYmVsLWJvbGRcIj5Ub3RhbCBBbW91bnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS12YWx1ZS1ib2xkXCI+e3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fSB7eyBnZXRUb3RhbEFtb3VudCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBBY3Rpb25zIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBtdC00XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLW91dGxpbmUgYnRuIGNhbmNlbCBtZS00IHctNTBcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwic2F2aW5nXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcHgtNCB3LTUwXCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogbm93cmFwO1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzYXZpbmdcIiBjbGFzcz1cInN1Ym1pdFwiPnt7IG1vZGUgPT09ICdlZGl0JyA/ICdVcGRhdGUgSW52b2ljZScgOiAobW9kZSA9PT0gJ2VzdGltYXRlJyA/ICdHZW5lcmF0ZSBFc3RpbWF0ZScgOiAobW9kZSA9PT0gJ2VkaXRFc3RpbWF0ZScgPyAnVXBkYXRlIEVzdGltYXRlJyA6ICdDcmVhdGUgSW52b2ljZScpKVxuICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic2F2aW5nXCIgY2xhc3M9XCJzdWJtaXRcIj5TYXZpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT0gQ1JFRElUIE5PVEUgVEFCID09PT09PT09PT09PT09PT09PT09PT09PSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keSBtYi00XCIgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdjcmVkaXROb3RlJyAmJiBtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJjcmVkaXROb3RlRm9ybVwiIGNsYXNzPVwiZm9ybVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnR0ZXh0IG1iLTNcIj5cbiAgICAgICAgICAgICAgICBBcHBseSBhIGNyZWRpdCBub3RlIC8gZGlzY291bnQgdG8gdGhpcyBpbnZvaWNlLiBNYXhpbXVtIDEwJSBkaXNjb3VudCBhbGxvd2VkLlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5JbnZvaWNlIElEPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbdmFsdWVdPVwiaW52b2ljZURhdGE/Lmludm9pY2VcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPlRvdGFsIEFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGZvcm1Db250cm9sTmFtZT1cImFtb3VudFwiIHR5cGU9XCJ0ZXh0XCIgcmVhZG9ubHkgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPlJldmlzZWQgQW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZG9sbGFyLXNpZ25cIj57eyBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJyZXZpc2VkQW1vdW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXByZXNzKT1cIm9taXRTcGVjaWFsQ2hhcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJ2Vycm9yaW5wdXQnIDogJydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWljb25cIiAqbmdJZj1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZyBjbGlwLXBhdGg9XCJ1cmwoI2NsaXBfY25fZXJyKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNNy45OTk2NyA1LjMzMzAxVjcuOTk5NjdNNy45OTk2NyAxMC42NjYzSDguMDA2MzRNMTQuNjY2MyA3Ljk5OTY3QzE0LjY2NjMgMTEuNjgxNiAxMS42ODE2IDE0LjY2NjMgNy45OTk2NyAxNC42NjYzQzQuMzE3NzggMTQuNjY2MyAxLjMzMzAxIDExLjY4MTYgMS4zMzMwMSA3Ljk5OTY3QzEuMzMzMDEgNC4zMTc3OCA0LjMxNzc4IDEuMzMzMDEgNy45OTk2NyAxLjMzMzAxQzExLjY4MTYgMS4zMzMwMSAxNC42NjYzIDQuMzE3NzggMTQuNjY2MyA3Ljk5OTY3WlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiNGMDQ0MzhcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkZWZzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjbGlwUGF0aCBpZD1cImNsaXBfY25fZXJyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxyZWN0IHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIGZpbGw9XCJ3aGl0ZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jbGlwUGF0aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGVmcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAndGV4dC1kYW5nZXInIDogJ2NvbnRlbnR0ZXh0J1wiIGNsYXNzPVwic21hbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1vcmUgdGhhbiAxMCUgY2FuJ3QgYmUgcmV2aXNlZCBmcm9tIHRvdGFsIGFtb3VudFxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+RGlzY291bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZGlzY291bnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwib21pdFNwZWNpYWxDaGFyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA/ICdlcnJvcmlucHV0JyA6ICcnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1pY29uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk0xMi42NjcgMy4zMzM2NkwzLjMzMzY2IDEyLjY2N002LjAwMDMzIDQuMzMzNjZDNi4wMDAzMyA1LjI1NDEzIDUuMjU0MTMgNi4wMDAzMyA0LjMzMzY2IDYuMDAwMzNDMy40MTMxOCA2LjAwMDMzIDIuNjY2OTkgNS4yNTQxMyAyLjY2Njk5IDQuMzMzNjZDMi42NjY5OSAzLjQxMzE4IDMuNDEzMTggMi42NjY5OSA0LjMzMzY2IDIuNjY2OTlDNS4yNTQxMyAyLjY2Njk5IDYuMDAwMzMgMy40MTMxOCA2LjAwMDMzIDQuMzMzNjZaTTEzLjMzMzcgMTEuNjY3QzEzLjMzMzcgMTIuNTg3NSAxMi41ODc1IDEzLjMzMzcgMTEuNjY3IDEzLjMzMzdDMTAuNzQ2NSAxMy4zMzM3IDEwLjAwMDMgMTIuNTg3NSAxMC4wMDAzIDExLjY2N0MxMC4wMDAzIDEwLjc0NjUgMTAuNzQ2NSAxMC4wMDAzIDExLjY2NyAxMC4wMDAzQzEyLjU4NzUgMTAuMDAwMyAxMy4zMzM3IDEwLjc0NjUgMTMuMzMzNyAxMS42NjdaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5zdHJva2VdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJyNGMDQ0MzgnIDogJyM5OEEyQjMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIFtuZ0NsYXNzXT1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA/ICd0ZXh0LWRhbmdlcicgOiAnY29udGVudHRleHQnXCIgY2xhc3M9XCJzbWFsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgSW4gcGVyY2VudGFnZVxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBtdC01XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLW91dGxpbmUgYnRuIGNhbmNlbCBtZS00IHctNTBcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgfHwgc2F2aW5nXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhcHBseUNyZWRpdE5vdGUoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IHB4LTQgdy01MFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhc2F2aW5nXCI+QXBwbHkgQ3JlZGl0IE5vdGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic2F2aW5nXCI+QXBwbHlpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT0gT05FIFRJTUUgRkVFIFRBQiA9PT09PT09PT09PT09PT09PT09PT09PT0gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHkgbWItNFwiICpuZ0lmPVwiYWN0aXZlVGFiID09PSAnb25lVGltZUZlZScgJiYgbW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgIDxmb3JtIFtmb3JtR3JvdXBdPVwib25lVGltZUZlZUZvcm1cIiBjbGFzcz1cImZvcm1cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50dGV4dCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgQWRkIGEgb25lLXRpbWUgZmVlIChlLmcuIGluc3RhbGxhdGlvbikgdG8gdGhpcyBpbnZvaWNlLlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5JbnZvaWNlIElEPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbdmFsdWVdPVwiaW52b2ljZURhdGE/Lmludm9pY2VcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPkN1cnJlbnQgSW52b2ljZSBBbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZG9sbGFyLXNpZ25cIj57eyBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBmb3JtQ29udHJvbE5hbWU9XCJhbW91bnRcIiB0eXBlPVwidGV4dFwiIHJlYWRvbmx5IGNsYXNzPVwiZm9ybS1jb250cm9sIGFtb3VudC1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5PbmUgVGltZSBGZWUgKEluc3RhbGxhdGlvbik8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIm9uZVRpbWVGZWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwib21pdFNwZWNpYWxDaGFyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkVudGVyIGZlZSBhbW91bnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1zdGFjayBtdC0zIGZlZS1zdW1tYXJ5IHAtM1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPlNlbGVjdGVkIEludm9pY2UgQW1vdW50ICsgT25lIFRpbWUgRmVlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktdmFsdWUtYm9sZFwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVUaW1lRmVlVG90YWwgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IG10LTVcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gY2FuY2VsIG1lLTQgdy01MFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cInNhdmluZyB8fCAhb25lVGltZUZlZUZvcm0uZ2V0KCdvbmVUaW1lRmVlJyk/LnZhbHVlXCIgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseU9uZVRpbWVGZWUoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IHB4LTQgdy01MFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhc2F2aW5nXCI+QXBwbHkgRmVlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInNhdmluZ1wiPkFwcGx5aW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9ybT5cbiAgICA8L2Rpdj5cbjwvZGl2PiJdfQ==
|