tango-app-ui-manage-billing 3.3.42 → 3.3.43

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.
@@ -125,7 +125,7 @@ export class EditInvoiceComponent {
125
125
  // entry (custom name + price), clearing the base-pricing selection.
126
126
  if (selectedName === '__custom__') {
127
127
  productGroup.patchValue({ isCustom: true, productName: '', price: 0, description: '' });
128
- this.recalculate();
128
+ this.recalculate(index);
129
129
  return;
130
130
  }
131
131
  productGroup.get('isCustom')?.setValue(false);
@@ -140,7 +140,7 @@ export class EditInvoiceComponent {
140
140
  prioritySupport: 'Priority Support',
141
141
  };
142
142
  productGroup.get('description')?.setValue(descriptions[selectedName] || '');
143
- this.recalculate();
143
+ this.recalculate(index);
144
144
  }
145
145
  }
146
146
  // Add a blank product row already in custom (free-text) mode, regardless of
@@ -426,8 +426,9 @@ export class EditInvoiceComponent {
426
426
  }
427
427
  // Fetch INR-per-unit rates and convert each product price from old→new:
428
428
  // newPrice = oldPrice * (rates[old] / rates[new]).
429
- // Tax-row currency symbols are refreshed and amounts recomputed. previousCurrency
430
- // is advanced only after a successful conversion.
429
+ // Each line amount is converted by the same factor (so prorated lines stay
430
+ // prorated), tax-row currency symbols are refreshed and totals recomputed.
431
+ // previousCurrency is advanced only after a successful conversion.
431
432
  convertProductCurrency(oldCurrency, newCurrency) {
432
433
  this.billingService.fxRates().pipe(takeUntil(this.destroy$)).subscribe({
433
434
  next: (res) => {
@@ -444,6 +445,10 @@ export class EditInvoiceComponent {
444
445
  const price = Number(group.get('price')?.value) || 0;
445
446
  const converted = this.roundForCurrency(price * factor, newCurrency);
446
447
  group.get('price')?.setValue(converted, { emitEvent: false });
448
+ // Convert the stored line amount directly rather than re-deriving it
449
+ // as storeCount x new price, which would drop any proration.
450
+ const amount = Number(group.get('amount')?.value) || 0;
451
+ group.get('amount')?.setValue(this.roundForCurrency(amount * factor, newCurrency), { emitEvent: false });
447
452
  });
448
453
  // Refresh each tax row's currency symbol to the new currency.
449
454
  const symbol = this.symbolFor(newCurrency);
@@ -556,16 +561,23 @@ export class EditInvoiceComponent {
556
561
  ctrl?.setValue(trimmed === '' || trimmed === '-' ? null : Number(trimmed), { emitEvent: false });
557
562
  }
558
563
  }
559
- this.recalculate();
560
- }
561
- recalculate() {
564
+ this.recalculate(i);
565
+ }
566
+ // Refresh subtotal / tax / store totals. Only the row that was just edited
567
+ // (changedIndex) has its Amount re-derived as Quantity x Rate; every other
568
+ // row keeps its stored amount. Auto-generated invoices carry PRORATED lines
569
+ // (amount = price x workingDays / monthDays, so amount != storeCount x price;
570
+ // e.g. DRAFT-26-27-00009 stored 1 x 1650 as 605). Recomputing every row on
571
+ // any keystroke silently rewrote all of those to the full-month figure.
572
+ recalculate(changedIndex) {
562
573
  let subtotal = 0;
563
- this.products.controls.forEach((group) => {
564
- const storeCount = group.get('storeCount')?.value || 0;
565
- const price = group.get('price')?.value || 0;
566
- const amount = storeCount * price;
567
- group.get('amount')?.setValue(parseFloat(amount.toFixed(2)), { emitEvent: false });
568
- subtotal += amount;
574
+ this.products.controls.forEach((group, idx) => {
575
+ if (idx === changedIndex) {
576
+ const storeCount = Number(group.get('storeCount')?.value) || 0;
577
+ const price = Number(group.get('price')?.value) || 0;
578
+ group.get('amount')?.setValue(parseFloat((storeCount * price).toFixed(2)), { emitEvent: false });
579
+ }
580
+ subtotal += Number(group.get('amount')?.value) || 0;
569
581
  });
570
582
  // Tax is charged on the DISCOUNTED amount, matching applyDiscount() on the
571
583
  // backend. Taxing the gross subtotal here would show a total that the
@@ -920,11 +932,11 @@ export class EditInvoiceComponent {
920
932
  });
921
933
  }
922
934
  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 }, { token: i0.ElementRef }, { token: i1.NgbModal }], target: i0.ɵɵFactoryTarget.Component });
923
- 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 <!-- Create mode: typing/changing the GSTIN re-derives the tax rows. -->\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\"\n (input)=\"onGstNumberInput()\">\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 (change)=\"mode === 'create' && computeDueDate()\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <!-- Create mode: choose a payment term (days); the due date is\n derived from Billing Date + term and shown read-only. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode === 'create'\">\n <label class=\"headingtext mb-1\">Payment Term <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"paymentTerm\"\n (change)=\"computeDueDate()\">\n <option [ngValue]=\"30\">30 days</option>\n <option [ngValue]=\"60\">60 days</option>\n <option [ngValue]=\"90\">90 days</option>\n <option [ngValue]=\"120\">120 days</option>\n </select>\n <div class=\"text-muted small mt-1\">Due Date: {{ invoiceForm.get('dueDate')?.value || '-' }}</div>\n </div>\n <!-- Edit / estimate modes keep the editable Due Date field. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode !== 'create'\">\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 (change)=\"onCurrencyChange($event)\"\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 <!-- Purchase Order mapping (optional). Mapping deducts this\n invoice's amount from the selected PO's remaining balance.\n Hidden for draft invoices (temporary DRAFT- number, or no\n number yet in create mode) \u2014 a PO can only be attached once\n the real invoice number is minted at finance approval. -->\n <ng-container *ngIf=\"mode !== 'estimate' && mode !== 'editEstimate'\">\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"!isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <select class=\"form-select\" formControlName=\"purchaseOrderNumber\">\n <option value=\"\">None</option>\n <option *ngFor=\"let po of purchaseOrders\" [value]=\"po.purchaseOrderNumber\">\n {{ po.purchaseOrderNumber }} ({{ getCurrencySymbol() }}{{ po.remainingAmount | number:'1.0-0':'en-IN' }} left)\n </option>\n </select>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <div class=\"text-muted small\">\n Purchase Order can be attached after finance approval (once the invoice number is finalised).\n </div>\n </div>\n </ng-container>\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 <!-- Rows can be reordered by dragging the \u22EE\u22EE handle onto another row\n (native HTML5 drag & drop \u2014 no CDK dependency). The FormArray is\n re-ordered, so numbering, totals and the saved products follow. -->\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\" data-product-row\n [class.drag-over]=\"dragOverIndex === i && dragIndex !== null && dragIndex !== i\"\n [class.dragging]=\"dragIndex === i\"\n (dragover)=\"onRowDragOver($event, i)\" (dragleave)=\"onRowDragLeave(i)\"\n (drop)=\"onRowDrop($event, i)\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"d-flex align-items-center\">\n <span class=\"drag-handle me-2\" draggable=\"true\" title=\"Drag to reorder\"\n (dragstart)=\"onRowDragStart($event, i)\" (dragend)=\"onRowDragEnd()\"\n *ngIf=\"products.length > 1\">&#8942;&#8942;</span>\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n </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 <!-- Rate/Price accepts at most 2 decimals (paise); extra digits are trimmed as typed. -->\n <input type=\"number\" formControlName=\"price\" class=\"form-control\" step=\"0.01\" min=\"0\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"onPriceInput(i)\">\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 <!-- Tax is DERIVED from the GST number (GSTIN '33\u2026' \u2192 CGST 9% + SGST 9%,\n any other GSTIN \u2192 IGST 18%, none \u2192 no tax), so there is no manual\n \"Add Tax\" and the rows are read-only; a tax line can still be\n REMOVED via each row's Remove button. -->\n <span class=\"text-muted small\">Calculated from GST Number</span>\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\" data-tax-row>\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 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 <!-- The 'type' control is created disabled (derived from the GSTIN);\n the form posts via getRawValue() so it still reaches the payload. -->\n <select class=\"form-select\" formControlName=\"type\"\n (change)=\"onTaxTypeChange(j)\"\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 readonly\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\" readonly>\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\" *ngIf=\"getAppliedDiscount() > 0\">\n <span class=\"summary-label\">Discount</span>\n <span class=\"summary-value\">- {{ getCurrencySymbol() }} {{ getAppliedDiscount() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\" *ngIf=\"getTotalTax() > 0\">\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.\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\">Discount Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"discountAmount\"\n (keypress)=\"omitSpecialCharDecimal($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n Credit value deducted from the invoice\n </span>\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)=\"omitSpecialCharDecimal($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 Enter a valid revised amount\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}.drag-handle{cursor:grab;-webkit-user-select:none;user-select:none;color:#98a2b3;font-size:16px;line-height:1;letter-spacing:-3px;padding:0 4px}.drag-handle:hover{color:#344054}.drag-handle:active{cursor:grabbing}.product-row.dragging{opacity:.5}.product-row.drag-over{outline:2px dashed #2e90fa;outline-offset:2px;background:#f5faff}\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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { 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" }] });
935
+ 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 <!-- Create mode: typing/changing the GSTIN re-derives the tax rows. -->\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\"\n (input)=\"onGstNumberInput()\">\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 (change)=\"mode === 'create' && computeDueDate()\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <!-- Create mode: choose a payment term (days); the due date is\n derived from Billing Date + term and shown read-only. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode === 'create'\">\n <label class=\"headingtext mb-1\">Payment Term <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"paymentTerm\"\n (change)=\"computeDueDate()\">\n <option [ngValue]=\"30\">30 days</option>\n <option [ngValue]=\"60\">60 days</option>\n <option [ngValue]=\"90\">90 days</option>\n <option [ngValue]=\"120\">120 days</option>\n </select>\n <div class=\"text-muted small mt-1\">Due Date: {{ invoiceForm.get('dueDate')?.value || '-' }}</div>\n </div>\n <!-- Edit / estimate modes keep the editable Due Date field. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode !== 'create'\">\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 (change)=\"onCurrencyChange($event)\"\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 <!-- Purchase Order mapping (optional). Mapping deducts this\n invoice's amount from the selected PO's remaining balance.\n Hidden for draft invoices (temporary DRAFT- number, or no\n number yet in create mode) \u2014 a PO can only be attached once\n the real invoice number is minted at finance approval. -->\n <ng-container *ngIf=\"mode !== 'estimate' && mode !== 'editEstimate'\">\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"!isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <select class=\"form-select\" formControlName=\"purchaseOrderNumber\">\n <option value=\"\">None</option>\n <option *ngFor=\"let po of purchaseOrders\" [value]=\"po.purchaseOrderNumber\">\n {{ po.purchaseOrderNumber }} ({{ getCurrencySymbol() }}{{ po.remainingAmount | number:'1.0-0':'en-IN' }} left)\n </option>\n </select>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <div class=\"text-muted small\">\n Purchase Order can be attached after finance approval (once the invoice number is finalised).\n </div>\n </div>\n </ng-container>\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 <!-- Rows can be reordered by dragging the \u22EE\u22EE handle onto another row\n (native HTML5 drag & drop \u2014 no CDK dependency). The FormArray is\n re-ordered, so numbering, totals and the saved products follow. -->\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\" data-product-row\n [class.drag-over]=\"dragOverIndex === i && dragIndex !== null && dragIndex !== i\"\n [class.dragging]=\"dragIndex === i\"\n (dragover)=\"onRowDragOver($event, i)\" (dragleave)=\"onRowDragLeave(i)\"\n (drop)=\"onRowDrop($event, i)\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"d-flex align-items-center\">\n <span class=\"drag-handle me-2\" draggable=\"true\" title=\"Drag to reorder\"\n (dragstart)=\"onRowDragStart($event, i)\" (dragend)=\"onRowDragEnd()\"\n *ngIf=\"products.length > 1\">&#8942;&#8942;</span>\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n </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(i)\">\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 <!-- Rate/Price accepts at most 2 decimals (paise); extra digits are trimmed as typed. -->\n <input type=\"number\" formControlName=\"price\" class=\"form-control\" step=\"0.01\" min=\"0\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"onPriceInput(i)\">\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 <!-- Tax is DERIVED from the GST number (GSTIN '33\u2026' \u2192 CGST 9% + SGST 9%,\n any other GSTIN \u2192 IGST 18%, none \u2192 no tax), so there is no manual\n \"Add Tax\" and the rows are read-only; a tax line can still be\n REMOVED via each row's Remove button. -->\n <span class=\"text-muted small\">Calculated from GST Number</span>\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\" data-tax-row>\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 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 <!-- The 'type' control is created disabled (derived from the GSTIN);\n the form posts via getRawValue() so it still reaches the payload. -->\n <select class=\"form-select\" formControlName=\"type\"\n (change)=\"onTaxTypeChange(j)\"\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 readonly\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\" readonly>\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\" *ngIf=\"getAppliedDiscount() > 0\">\n <span class=\"summary-label\">Discount</span>\n <span class=\"summary-value\">- {{ getCurrencySymbol() }} {{ getAppliedDiscount() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\" *ngIf=\"getTotalTax() > 0\">\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.\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\">Discount Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"discountAmount\"\n (keypress)=\"omitSpecialCharDecimal($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n Credit value deducted from the invoice\n </span>\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)=\"omitSpecialCharDecimal($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 Enter a valid revised amount\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}.drag-handle{cursor:grab;-webkit-user-select:none;user-select:none;color:#98a2b3;font-size:16px;line-height:1;letter-spacing:-3px;padding:0 4px}.drag-handle:hover{color:#344054}.drag-handle:active{cursor:grabbing}.product-row.dragging{opacity:.5}.product-row.drag-over{outline:2px dashed #2e90fa;outline-offset:2px;background:#f5faff}\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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { 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" }] });
924
936
  }
925
937
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditInvoiceComponent, decorators: [{
926
938
  type: Component,
927
- 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 <!-- Create mode: typing/changing the GSTIN re-derives the tax rows. -->\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\"\n (input)=\"onGstNumberInput()\">\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 (change)=\"mode === 'create' && computeDueDate()\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <!-- Create mode: choose a payment term (days); the due date is\n derived from Billing Date + term and shown read-only. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode === 'create'\">\n <label class=\"headingtext mb-1\">Payment Term <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"paymentTerm\"\n (change)=\"computeDueDate()\">\n <option [ngValue]=\"30\">30 days</option>\n <option [ngValue]=\"60\">60 days</option>\n <option [ngValue]=\"90\">90 days</option>\n <option [ngValue]=\"120\">120 days</option>\n </select>\n <div class=\"text-muted small mt-1\">Due Date: {{ invoiceForm.get('dueDate')?.value || '-' }}</div>\n </div>\n <!-- Edit / estimate modes keep the editable Due Date field. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode !== 'create'\">\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 (change)=\"onCurrencyChange($event)\"\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 <!-- Purchase Order mapping (optional). Mapping deducts this\n invoice's amount from the selected PO's remaining balance.\n Hidden for draft invoices (temporary DRAFT- number, or no\n number yet in create mode) \u2014 a PO can only be attached once\n the real invoice number is minted at finance approval. -->\n <ng-container *ngIf=\"mode !== 'estimate' && mode !== 'editEstimate'\">\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"!isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <select class=\"form-select\" formControlName=\"purchaseOrderNumber\">\n <option value=\"\">None</option>\n <option *ngFor=\"let po of purchaseOrders\" [value]=\"po.purchaseOrderNumber\">\n {{ po.purchaseOrderNumber }} ({{ getCurrencySymbol() }}{{ po.remainingAmount | number:'1.0-0':'en-IN' }} left)\n </option>\n </select>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <div class=\"text-muted small\">\n Purchase Order can be attached after finance approval (once the invoice number is finalised).\n </div>\n </div>\n </ng-container>\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 <!-- Rows can be reordered by dragging the \u22EE\u22EE handle onto another row\n (native HTML5 drag & drop \u2014 no CDK dependency). The FormArray is\n re-ordered, so numbering, totals and the saved products follow. -->\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\" data-product-row\n [class.drag-over]=\"dragOverIndex === i && dragIndex !== null && dragIndex !== i\"\n [class.dragging]=\"dragIndex === i\"\n (dragover)=\"onRowDragOver($event, i)\" (dragleave)=\"onRowDragLeave(i)\"\n (drop)=\"onRowDrop($event, i)\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"d-flex align-items-center\">\n <span class=\"drag-handle me-2\" draggable=\"true\" title=\"Drag to reorder\"\n (dragstart)=\"onRowDragStart($event, i)\" (dragend)=\"onRowDragEnd()\"\n *ngIf=\"products.length > 1\">&#8942;&#8942;</span>\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n </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 <!-- Rate/Price accepts at most 2 decimals (paise); extra digits are trimmed as typed. -->\n <input type=\"number\" formControlName=\"price\" class=\"form-control\" step=\"0.01\" min=\"0\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"onPriceInput(i)\">\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 <!-- Tax is DERIVED from the GST number (GSTIN '33\u2026' \u2192 CGST 9% + SGST 9%,\n any other GSTIN \u2192 IGST 18%, none \u2192 no tax), so there is no manual\n \"Add Tax\" and the rows are read-only; a tax line can still be\n REMOVED via each row's Remove button. -->\n <span class=\"text-muted small\">Calculated from GST Number</span>\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\" data-tax-row>\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 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 <!-- The 'type' control is created disabled (derived from the GSTIN);\n the form posts via getRawValue() so it still reaches the payload. -->\n <select class=\"form-select\" formControlName=\"type\"\n (change)=\"onTaxTypeChange(j)\"\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 readonly\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\" readonly>\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\" *ngIf=\"getAppliedDiscount() > 0\">\n <span class=\"summary-label\">Discount</span>\n <span class=\"summary-value\">- {{ getCurrencySymbol() }} {{ getAppliedDiscount() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\" *ngIf=\"getTotalTax() > 0\">\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.\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\">Discount Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"discountAmount\"\n (keypress)=\"omitSpecialCharDecimal($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n Credit value deducted from the invoice\n </span>\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)=\"omitSpecialCharDecimal($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 Enter a valid revised amount\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}.drag-handle{cursor:grab;-webkit-user-select:none;user-select:none;color:#98a2b3;font-size:16px;line-height:1;letter-spacing:-3px;padding:0 4px}.drag-handle:hover{color:#344054}.drag-handle:active{cursor:grabbing}.product-row.dragging{opacity:.5}.product-row.drag-over{outline:2px dashed #2e90fa;outline-offset:2px;background:#f5faff}\n"] }]
939
+ 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 <!-- Create mode: typing/changing the GSTIN re-derives the tax rows. -->\n <input type=\"text\" formControlName=\"GSTNumber\" class=\"form-control\" [readonly]=\"mode === 'edit'\"\n (input)=\"onGstNumberInput()\">\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 (change)=\"mode === 'create' && computeDueDate()\">\n <div class=\"invalid-msg\" *ngIf=\"controlInvalid('billingDate')\">Billing Date is required</div>\n </div>\n <!-- Create mode: choose a payment term (days); the due date is\n derived from Billing Date + term and shown read-only. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode === 'create'\">\n <label class=\"headingtext mb-1\">Payment Term <span class=\"text-danger\">*</span></label>\n <select class=\"form-select\" formControlName=\"paymentTerm\"\n (change)=\"computeDueDate()\">\n <option [ngValue]=\"30\">30 days</option>\n <option [ngValue]=\"60\">60 days</option>\n <option [ngValue]=\"90\">90 days</option>\n <option [ngValue]=\"120\">120 days</option>\n </select>\n <div class=\"text-muted small mt-1\">Due Date: {{ invoiceForm.get('dueDate')?.value || '-' }}</div>\n </div>\n <!-- Edit / estimate modes keep the editable Due Date field. -->\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"mode !== 'create'\">\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 (change)=\"onCurrencyChange($event)\"\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 <!-- Purchase Order mapping (optional). Mapping deducts this\n invoice's amount from the selected PO's remaining balance.\n Hidden for draft invoices (temporary DRAFT- number, or no\n number yet in create mode) \u2014 a PO can only be attached once\n the real invoice number is minted at finance approval. -->\n <ng-container *ngIf=\"mode !== 'estimate' && mode !== 'editEstimate'\">\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"!isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <select class=\"form-select\" formControlName=\"purchaseOrderNumber\">\n <option value=\"\">None</option>\n <option *ngFor=\"let po of purchaseOrders\" [value]=\"po.purchaseOrderNumber\">\n {{ po.purchaseOrderNumber }} ({{ getCurrencySymbol() }}{{ po.remainingAmount | number:'1.0-0':'en-IN' }} left)\n </option>\n </select>\n </div>\n <div class=\"col-md-3 form-group mb-3\" *ngIf=\"isDraft\">\n <label class=\"headingtext mb-1\">Purchase Order</label>\n <div class=\"text-muted small\">\n Purchase Order can be attached after finance approval (once the invoice number is finalised).\n </div>\n </div>\n </ng-container>\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 <!-- Rows can be reordered by dragging the \u22EE\u22EE handle onto another row\n (native HTML5 drag & drop \u2014 no CDK dependency). The FormArray is\n re-ordered, so numbering, totals and the saved products follow. -->\n <div *ngFor=\"let product of products.controls; let i = index\" [formGroupName]=\"i\"\n class=\"product-row mb-3 p-3\" data-product-row\n [class.drag-over]=\"dragOverIndex === i && dragIndex !== null && dragIndex !== i\"\n [class.dragging]=\"dragIndex === i\"\n (dragover)=\"onRowDragOver($event, i)\" (dragleave)=\"onRowDragLeave(i)\"\n (drop)=\"onRowDrop($event, i)\">\n <div class=\"d-flex justify-content-between align-items-center mb-2\">\n <span class=\"d-flex align-items-center\">\n <span class=\"drag-handle me-2\" draggable=\"true\" title=\"Drag to reorder\"\n (dragstart)=\"onRowDragStart($event, i)\" (dragend)=\"onRowDragEnd()\"\n *ngIf=\"products.length > 1\">&#8942;&#8942;</span>\n <span class=\"product-label\">Product {{ i + 1 }}</span>\n </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(i)\">\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 <!-- Rate/Price accepts at most 2 decimals (paise); extra digits are trimmed as typed. -->\n <input type=\"number\" formControlName=\"price\" class=\"form-control\" step=\"0.01\" min=\"0\"\n [class.is-invalid]=\"arrayControlInvalid('products', i, 'price')\"\n (input)=\"onPriceInput(i)\">\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 <!-- Tax is DERIVED from the GST number (GSTIN '33\u2026' \u2192 CGST 9% + SGST 9%,\n any other GSTIN \u2192 IGST 18%, none \u2192 no tax), so there is no manual\n \"Add Tax\" and the rows are read-only; a tax line can still be\n REMOVED via each row's Remove button. -->\n <span class=\"text-muted small\">Calculated from GST Number</span>\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\" data-tax-row>\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 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 <!-- The 'type' control is created disabled (derived from the GSTIN);\n the form posts via getRawValue() so it still reaches the payload. -->\n <select class=\"form-select\" formControlName=\"type\"\n (change)=\"onTaxTypeChange(j)\"\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 readonly\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\" readonly>\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\" *ngIf=\"getAppliedDiscount() > 0\">\n <span class=\"summary-label\">Discount</span>\n <span class=\"summary-value\">- {{ getCurrencySymbol() }} {{ getAppliedDiscount() | number:'1.2-2':'en-IN' }}</span>\n </div>\n <div class=\"d-flex justify-content-between mb-2\" *ngIf=\"getTotalTax() > 0\">\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.\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\">Discount Amount</label>\n <div class=\"input-group\">\n <span class=\"dollar-sign\">{{ getInvoiceCurrencySymbol() }}</span>\n <input type=\"text\" formControlName=\"discountAmount\"\n (keypress)=\"omitSpecialCharDecimal($event)\"\n class=\"form-control amount-input\"\n [ngClass]=\"creditMoreThanTenPercent ? 'errorinput' : ''\">\n </div>\n </div>\n <span [ngClass]=\"creditMoreThanTenPercent ? 'text-danger' : 'contenttext'\" class=\"small\">\n Credit value deducted from the invoice\n </span>\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)=\"omitSpecialCharDecimal($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 Enter a valid revised amount\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}.drag-handle{cursor:grab;-webkit-user-select:none;user-select:none;color:#98a2b3;font-size:16px;line-height:1;letter-spacing:-3px;padding:0 4px}.drag-handle:hover{color:#344054}.drag-handle:active{cursor:grabbing}.product-row.dragging{opacity:.5}.product-row.drag-over{outline:2px dashed #2e90fa;outline-offset:2px;background:#f5faff}\n"] }]
928
940
  }], ctorParameters: () => [{ type: i1.NgbActiveModal }, { type: i2.FormBuilder }, { type: i3.BillingService }, { type: i0.ChangeDetectorRef }, { type: i4.ToastService }, { type: i0.ElementRef }, { type: i1.NgbModal }], propDecorators: { invoiceData: [{
929
941
  type: Input
930
942
  }], mode: [{
@@ -934,4 +946,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
934
946
  }], billingGroups: [{
935
947
  type: Input
936
948
  }] } });
937
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLEtBQUssRUFBaUMsTUFBTSxlQUFlLENBQUM7QUFFbkcsT0FBTyxFQUFxQyxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUcxQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQzs7Ozs7OztBQU90RyxNQUFNLE9BQU8sb0JBQW9CO0lBb0R0QjtJQUNDO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQXpERCxXQUFXLENBQU07SUFDMUIsMEVBQTBFO0lBQzFFLDhEQUE4RDtJQUNyRCxJQUFJLEdBQW9ELE1BQU0sQ0FBQztJQUMvRCxRQUFRLEdBQVcsRUFBRSxDQUFDO0lBQ3RCLGFBQWEsR0FBVSxFQUFFLENBQUM7SUFFbkMsV0FBVyxDQUFhO0lBQ1AsUUFBUSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7SUFDMUMsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUV4Qix1Q0FBdUM7SUFDdkMsU0FBUyxHQUFXLE1BQU0sQ0FBQztJQUUzQixRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFF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TGhDLFNBQVM7K0JBQ0Usa0JBQWtCO3FQQUtuQixXQUFXO3NCQUFuQixLQUFLO2dCQUdHLElBQUk7c0JBQVosS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95LCBJbnB1dCwgQ2hhbmdlRGV0ZWN0b3JSZWYsIEVsZW1lbnRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5nYkFjdGl2ZU1vZGFsLCBOZ2JNb2RhbCB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIEZvcm1BcnJheSwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQmlsbGluZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9iaWxsaW5nLnNlcnZpY2UnO1xuaW1wb3J0IHsgVG9hc3RTZXJ2aWNlIH0gZnJvbSAndGFuZ28tYXBwLXVpLXNoYXJlZCc7XG5pbXBvcnQgeyBSZXF1ZXN0Q29uZmlybWF0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi4vcmVxdWVzdC1jb25maXJtYXRpb24vcmVxdWVzdC1jb25maXJtYXRpb24uY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLWVkaXQtaW52b2ljZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9lZGl0LWludm9pY2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5zY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBFZGl0SW52b2ljZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgaW52b2ljZURhdGE6IGFueTtcbiAgLy8gJ2VzdGltYXRlJyByZXVzZXMgdGhlIHdob2xlIGNyZWF0ZSBmb3JtIGJ1dCBzdWJtaXRzIHRvIHRoZSBlc3RpbWF0ZSBBUElcbiAgLy8gYW5kIHdyaXRlcyB0byB0aGUgZXN0aW1hdGVzIGNvbGxlY3Rpb24gaW5zdGVhZCBvZiBpbnZvaWNlcy5cbiAgQElucHV0KCkgbW9kZTogJ2VkaXQnIHwgJ2NyZWF0ZScgfCAnZXN0aW1hdGUnIHwgJ2VkaXRFc3RpbWF0ZScgPSAnZWRpdCc7XG4gIEBJbnB1dCgpIGNsaWVudElkOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgYmlsbGluZ0dyb3VwczogYW55W10gPSBbXTtcblxuICBpbnZvaWNlRm9ybSE6IEZvcm1Hcm91cDtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG4gIHNhdmluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIFRhYnM6IGVkaXQgfCBjcmVkaXROb3RlIHwgb25lVGltZUZlZVxuICBhY3RpdmVUYWI6IHN0cmluZyA9ICdlZGl0JztcblxuICB0YXhUeXBlcyA9IFsnSUdTVCcsICdDR1NUJywgJ1NHU1QnXTtcbiAgY3VycmVuY3lPcHRpb25zID0gWydpbnInLCAnZG9sbGFyJywgJ3NpbmdhcG9yZWRvbGxhcicsICdldXJvJywgJ2FlZCddO1xuICBjdXJyZW5jeUxhYmVsczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBpbnI6ICdJTlIgKOKCuSknLFxuICAgIGRvbGxhcjogJ1VTRCAoJCknLFxuICAgIHNpbmdhcG9yZWRvbGxhcjogJ1NHRCAoUyQpJyxcbiAgICBldXJvOiAnRVVSICjigqwpJyxcbiAgICBhZWQ6ICdBRUQgKEFFRCknXG4gIH07XG4gIC8vIFN5bWJvbCBtYXAgbWlycm9ycyB0aGUgYmFja2VuZCdzIENVUlJFTkNZX1NZTUJPTFMgaW4gdXRpbHMvY3VycmVuY3kuanMgc29cbiAgLy8gdGhlIG1vZGFsLCBpbnZvaWNlIGxpc3QsIGNyZWRpdC1ub3RlIGFuZCBvbmUtdGltZS1mZWUgcG9wdXBzIGFsbCByZW5kZXJcbiAgLy8gdGhlIHNhbWUgc3ltYm9sIHRoZSBQREYvZW1haWwgdXNlcy5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeVN5bWJvbHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAn4oK5JyxcbiAgICBkb2xsYXI6ICckJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdTJCcsXG4gICAgZXVybzogJ+KCrCcsXG4gICAgYWVkOiAnQUVEJyxcbiAgfTtcbiAgc3RhdHVzT3B0aW9ucyA9IFsncGVuZGluZycsICdhcHByb3ZlZCddO1xuICBwYXltZW50U3RhdHVzT3B0aW9ucyA9IFsndW5wYWlkJywgJ3BhaWQnXTtcblxuICAvLyBDcmVkaXQgTm90ZVxuICBjcmVkaXROb3RlRm9ybSE6IEZvcm1Hcm91cDtcbiAgY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50OiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gUHJvZHVjdHMgZnJvbSBiYXNlIHByaWNpbmdcbiAgYXZhaWxhYmxlUHJvZHVjdHM6IGFueVtdID0gW107XG5cbiAgLy8gT25lIFRpbWUgRmVlXG4gIG9uZVRpbWVGZWVGb3JtITogRm9ybUdyb3VwO1xuICBvbmVUaW1lRmVlVG90YWw6IG51bWJlciA9IDA7XG5cbiAgLy8gTGFzdC1rbm93biBjdXJyZW5jeSwgc28gYSBjYW5jZWxsZWQgY3VycmVuY3kgY2hhbmdlIGNhbiByZXZlcnQgdGhlIHNlbGVjdC5cbiAgcHJpdmF0ZSBwcmV2aW91c0N1cnJlbmN5OiBzdHJpbmcgPSAnaW5yJztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYWN0aXZlTW9kYWw6IE5nYkFjdGl2ZU1vZGFsLFxuICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgYmlsbGluZ1NlcnZpY2U6IEJpbGxpbmdTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3I6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgdG9hc3Q6IFRvYXN0U2VydmljZSxcbiAgICBwcml2YXRlIGhvc3RSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsXG4gICkge31cblxuICAvLyBTY3JvbGwgdGhlIG5ld2x5LWFkZGVkIHJvdyAocHJvZHVjdHMvdGF4KSBpbnRvIHZpZXcgaW5zaWRlIHRoZSBtb2RhbCBib2R5LlxuICAvLyBzZWxlY3RvciB0YXJnZXRzIHRoZSBsYXN0IHJvdyBvZiB0aGUgZ2l2ZW4gc2VjdGlvbiBhZnRlciBpdCByZW5kZXJzLlxuICBwcml2YXRlIHNjcm9sbFRvTGFzdFJvdyhzZWN0aW9uQXR0cjogc3RyaW5nKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCBob3N0OiBIVE1MRWxlbWVudCA9IHRoaXMuaG9zdFJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IHJvd3MgPSBob3N0Py5xdWVyeVNlbGVjdG9yQWxsKGBbJHtzZWN0aW9uQXR0cn1dYCk7XG4gICAgICBjb25zdCBsYXN0ID0gcm93cyAmJiByb3dzLmxlbmd0aCA/IChyb3dzW3Jvd3MubGVuZ3RoIC0gMV0gYXMgSFRNTEVsZW1lbnQpIDogbnVsbDtcbiAgICAgIGlmIChsYXN0KSB7XG4gICAgICAgIGxhc3Quc2Nyb2xsSW50b1ZpZXcoeyBiZWhhdmlvcjogJ3Ntb290aCcsIGJsb2NrOiAnY2VudGVyJyB9KTtcbiAgICAgIH1cbiAgICB9LCAxMDApO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkQmlsbGluZ0dyb3VwcygpO1xuICAgIHRoaXMubG9hZENsaWVudFByb2R1Y3RzKCk7XG4gICAgdGhpcy5sb2FkUHVyY2hhc2VPcmRlcnMoKTtcbiAgICB0aGlzLmluaXRGb3JtKCk7XG4gICAgdGhpcy5pbml0Q3JlZGl0Tm90ZUZvcm0oKTtcbiAgICB0aGlzLmluaXRPbmVUaW1lRmVlRm9ybSgpO1xuICAgIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0JyAmJiB0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICB0aGlzLnBhdGNoRm9ybSgpO1xuICAgICAgdGhpcy5wYXRjaENyZWRpdE5vdGVEZWZhdWx0cygpO1xuICAgICAgdGhpcy5wYXRjaE9uZVRpbWVGZWVEZWZhdWx0cygpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZWRpdEVzdGltYXRlJyAmJiB0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICAvLyBFZGl0aW5nIGFuIGVzdGltYXRlIHJldXNlcyB0aGUgc2FtZSBmb3JtIGZpZWxkczsgdGhlIGVzdGltYXRlIGRvY3VtZW50XG4gICAgICAvLyBzaGFyZXMgdGhlIGludm9pY2Ugc2hhcGUgKGNvbXBhbnlOYW1lLCBwcm9kdWN0cywgdGF4LCBzdG9yZXMsIOKApikuXG4gICAgICB0aGlzLnBhdGNoRm9ybSgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnY3JlYXRlJykge1xuICAgICAgLy8gTmV3IGludm9pY2U6IGRlZmF1bHQgdGhlIGJpbGxpbmcgZGF0ZSB0byB0b2RheSBhbmQgZGVyaXZlIHRoZSBkdWUgZGF0ZVxuICAgICAgLy8gZnJvbSB0aGUgZGVmYXVsdCBwYXltZW50IHRlcm0gKDMwIGRheXMpLiBUaGUgdXNlciBjaGFuZ2VzIHRoZSB0ZXJtIHZpYVxuICAgICAgLy8gdGhlIFBheW1lbnQgVGVybSBkcm9wZG93biwgbm90IHRoZSBkdWUgZGF0ZSBkaXJlY3RseS5cbiAgICAgIHRoaXMuaW52b2ljZUZvcm0ucGF0Y2hWYWx1ZSh7IGJpbGxpbmdEYXRlOiB0aGlzLmZvcm1hdERhdGVGb3JJbnB1dChuZXcgRGF0ZSgpKSB9KTtcbiAgICAgIHRoaXMuY29tcHV0ZUR1ZURhdGUoKTtcbiAgICB9XG4gIH1cblxuICBsb2FkQ2xpZW50UHJvZHVjdHMoKSB7XG4gICAgY29uc3QgY0lkID0gdGhpcy5jbGllbnRJZCB8fCB0aGlzLmludm9pY2VEYXRhPy5jbGllbnRJZDtcbiAgICBpZiAoY0lkKSB7XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmdldENsaWVudEJhc2VQcmljaW5nKGNJZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuYXZhaWxhYmxlUHJvZHVjdHMgPSByZXM/LmRhdGEgfHwgW107XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5hdmFpbGFibGVQcm9kdWN0cyA9IFtdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvblByb2R1Y3RDaGFuZ2UoaW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IHByb2R1Y3RHcm91cCA9IHRoaXMucHJvZHVjdHMuYXQoaW5kZXgpO1xuICAgIGNvbnN0IHNlbGVjdGVkTmFtZSA9IHByb2R1Y3RHcm91cC5nZXQoJ3Byb2R1Y3ROYW1lJyk/LnZhbHVlO1xuICAgIC8vIFwiKyBDdXN0b20gcHJvZHVjdFwiIHBpY2tlZCBmcm9tIHRoZSBkcm9wZG93biDigJQgc3dpdGNoIHRoaXMgcm93IHRvIGZyZWUtdGV4dFxuICAgIC8vIGVudHJ5IChjdXN0b20gbmFtZSArIHByaWNlKSwgY2xlYXJpbmcgdGhlIGJhc2UtcHJpY2luZyBzZWxlY3Rpb24uXG4gICAgaWYgKHNlbGVjdGVkTmFtZSA9PT0gJ19fY3VzdG9tX18nKSB7XG4gICAgICBwcm9kdWN0R3JvdXAucGF0Y2hWYWx1ZSh7IGlzQ3VzdG9tOiB0cnVlLCBwcm9kdWN0TmFtZTogJycsIHByaWNlOiAwLCBkZXNjcmlwdGlvbjogJycgfSk7XG4gICAgICB0aGlzLnJlY2FsY3VsYXRlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHByb2R1Y3RHcm91cC5nZXQoJ2lzQ3VzdG9tJyk/LnNldFZhbHVlKGZhbHNlKTtcbiAgICBjb25zdCBwcm9kdWN0ID0gdGhpcy5hdmFpbGFibGVQcm9kdWN0cy5maW5kKHAgPT4gcC5wcm9kdWN0TmFtZSA9PT0gc2VsZWN0ZWROYW1lKTtcbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgcHJvZHVjdEdyb3VwLmdldCgncHJpY2UnKT8uc2V0VmFsdWUocHJvZHVjdC5wcmljZSk7XG4gICAgICAvLyBTZXQgZGVzY3JpcHRpb24gYmFzZWQgb24gcHJvZHVjdCBuYW1lXG4gICAgICBjb25zdCBkZXNjcmlwdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgIHRhbmdvVHJhZmZpYzogJ0N1c3RvbWVyIEZvb3RmYWxsIEFuYWx5dGljcycsXG4gICAgICAgIHRhbmdvWm9uZTogJ1Byb2R1Y3QgY2F0ZWdvcnkvc2VjdGlvbiBhbmFseXRpY3MnLFxuICAgICAgICB0YW5nb1RyYXg6ICdDdXN0b21lciBKb3VybmV5IEFuYWx5dGljcycsXG4gICAgICAgIHByaW9yaXR5U3VwcG9ydDogJ1ByaW9yaXR5IFN1cHBvcnQnLFxuICAgICAgfTtcbiAgICAgIHByb2R1Y3RHcm91cC5nZXQoJ2Rlc2NyaXB0aW9uJyk/LnNldFZhbHVlKGRlc2NyaXB0aW9uc1tzZWxlY3RlZE5hbWVdIHx8ICcnKTtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgICB9XG4gIH1cblxuICAvLyBBZGQgYSBibGFuayBwcm9kdWN0IHJvdyBhbHJlYWR5IGluIGN1c3RvbSAoZnJlZS10ZXh0KSBtb2RlLCByZWdhcmRsZXNzIG9mXG4gIC8vIHdoZXRoZXIgYmFzZS1wcmljaW5nIHByb2R1Y3RzIGV4aXN0LlxuICBhZGRDdXN0b21Qcm9kdWN0KCkge1xuICAgIHRoaXMucHJvZHVjdHMucHVzaCh0aGlzLmNyZWF0ZVByb2R1Y3RHcm91cCh7IGlzQ3VzdG9tOiB0cnVlIH0pKTtcbiAgICB0aGlzLnNjcm9sbFRvTGFzdFJvdygnZGF0YS1wcm9kdWN0LXJvdycpO1xuICB9XG5cbiAgZm9ybWF0UHJvZHVjdE5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIW5hbWUpIHJldHVybiAnJztcbiAgICAvLyBDb252ZXJ0IGNhbWVsQ2FzZSB0byBUaXRsZSBDYXNlIHdpdGggc3BhY2VzOiB0YW5nb1RyYWZmaWMgLT4gVGFuZ28gVHJhZmZpY1xuICAgIHJldHVybiBuYW1lLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpXG4gICAgICAucmVwbGFjZSgvXi4vLCAoc3RyKSA9PiBzdHIudG9VcHBlckNhc2UoKSk7XG4gIH1cblxuICBsb2FkQmlsbGluZ0dyb3VwcygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmIChjSWQpIHtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0QWxsQmlsbGluZ0dyb3VwcyhjSWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLmJpbGxpbmdHcm91cHMgPSByZXM/LmRhdGEgfHwgW107XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5iaWxsaW5nR3JvdXBzID0gW107XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBzZXRUYWIodGFiOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVRhYiA9IHRhYjtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PSBFRElUIElOVk9JQ0UgPT09PT09PT09PT09PT09PT09PT09XG5cbiAgaW5pdEZvcm0oKSB7XG4gICAgdGhpcy5pbnZvaWNlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgY29tcGFueU5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBjb21wYW55QWRkcmVzczogWycnXSxcbiAgICAgIEdTVE51bWJlcjogWycnXSxcbiAgICAgIFBsYWNlT2ZTdXBwbHk6IFsnJ10sXG4gICAgICBncm91cE5hbWU6IFsnJ10sXG4gICAgICAvLyBCaWxsaW5nIEdyb3VwIGlzIHJlcXVpcmVkIHdoZW4gY3JlYXRpbmcg4oCUIHRoZSByZXN0IG9mIHRoZSBjb21wYW55XG4gICAgICAvLyBmaWVsZHMgYXV0by1maWxsIGZyb20gdGhlIHNlbGVjdGVkIGdyb3VwLlxuICAgICAgZ3JvdXBJZDogWycnLCB0aGlzLm1vZGUgIT09ICdlZGl0JyA/IFZhbGlkYXRvcnMucmVxdWlyZWQgOiBbXV0sXG4gICAgICBzdG9yZXM6IFswLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGJpbGxpbmdEYXRlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgZHVlRGF0ZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIC8vIENyZWF0ZSBtb2RlOiBkdWUgZGF0ZSBpcyBkZXJpdmVkIGZyb20gYmlsbGluZ0RhdGUgKyBwYXltZW50VGVybSAoZGF5cyksXG4gICAgICAvLyBzbyB0aGUgdXNlciBwaWNrcyBhIHRlcm0gKDMwLzYwLzkwLzEyMCkgaW5zdGVhZCBvZiBhIGR1ZSBkYXRlLiBFZGl0IC9cbiAgICAgIC8vIGVzdGltYXRlIG1vZGVzIGtlZXAgdGhlIGVkaXRhYmxlIGR1ZURhdGUgZmllbGQgYW5kIGlnbm9yZSBwYXltZW50VGVybS5cbiAgICAgIHBheW1lbnRUZXJtOiBbMzBdLFxuICAgICAgY3VycmVuY3k6IFsnaW5yJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBzdGF0dXM6IFsncGVuZGluZyddLFxuICAgICAgcGF5bWVudFN0YXR1czogWyd1bnBhaWQnXSxcbiAgICAgIC8vIEFkdmFuY2UgaW52b2ljZTogd2hlbiBvbiwgdGhlIGNob3NlbiBmcmVxdWVuY3kgYmlsbHMgc2V2ZXJhbCBmdXR1cmVcbiAgICAgIC8vIG1vbnRocyB1cGZyb250IChlYWNoIG1vbnRoIGJlY29tZXMgaXRzIG93biBsaW5lIGl0ZW0gc2VydmVyLXNpZGUpLlxuICAgICAgYWR2YW5jZUludm9pY2U6IFtmYWxzZV0sXG4gICAgICBhZHZhbmNlUGVyaW9kOiBbJ21vbnRobHknXSxcbiAgICAgIC8vIE9wdGlvbmFsOiBtYXAgdGhpcyBpbnZvaWNlIHRvIGEgcHVyY2hhc2Ugb3JkZXIgKHJlZHVjZXMgdGhlIFBPIGJhbGFuY2UpLlxuICAgICAgcHVyY2hhc2VPcmRlck51bWJlcjogWycnXSxcbiAgICAgIHByb2R1Y3RzOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICAgIHRheDogdGhpcy5mYi5hcnJheShbXSksXG4gICAgfSk7XG4gIH1cblxuICAvLyBBIGRyYWZ0IGludm9pY2UgKHByZS1maW5hbmNlKSBoYXMgYSB0ZW1wb3JhcnkgRFJBRlQtIG51bWJlciBhbmQgY2Fubm90IGJlXG4gIC8vIG1hcHBlZCB0byBhIFB1cmNoYXNlIE9yZGVyIHVudGlsIHRoZSByZWFsIG51bWJlciBpcyBtaW50ZWQgYXQgZmluYW5jZVxuICAvLyBhcHByb3ZhbC4gQ3JlYXRlIG1vZGUgaGFzIG5vIGludm9pY2UgbnVtYmVyIHlldCBhdCBhbGwgKGJyYW5kLW5ldyBpbnZvaWNlKSxcbiAgLy8gc28gaXQgaXMgdHJlYXRlZCB0aGUgc2FtZSBhcyBhIGRyYWZ0IOKAlCB0aGUgUE8gcGlja2VyIHN0YXlzIGhpZGRlbiB1bnRpbFxuICAvLyB0aGVyZSBpcyBhIHJlYWwsIGVkaXRhYmxlIGludm9pY2Ugd2l0aCBhIGZpbmFsaXNlZCBudW1iZXIuXG4gIGdldCBpc0RyYWZ0KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm1vZGUgIT09ICdlZGl0Jykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IG51bSA9IHRoaXMuaW52b2ljZURhdGE/Lmludm9pY2UgfHwgJyc7XG4gICAgcmV0dXJuIHR5cGVvZiBudW0gPT09ICdzdHJpbmcnICYmIG51bS5zdGFydHNXaXRoKCdEUkFGVC0nKTtcbiAgfVxuXG4gIC8vIFB1cmNoYXNlIG9yZGVycyBhdmFpbGFibGUgZm9yIHRoaXMgY2xpZW50IChmb3IgdGhlIFBPIHBpY2tlcikuXG4gIHB1cmNoYXNlT3JkZXJzOiBhbnlbXSA9IFtdO1xuXG4gIGxvYWRQdXJjaGFzZU9yZGVycygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmICghY0lkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0UHVyY2hhc2VPcmRlcnMoY0lkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnB1cmNoYXNlT3JkZXJzID0gcmVzPy5kYXRhPy5wdXJjaGFzZU9yZGVycyB8fCBbXTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnB1cmNoYXNlT3JkZXJzID0gW107XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgYWR2YW5jZVBlcmlvZE9wdGlvbnMgPSBbXG4gICAgeyB2YWx1ZTogJ21vbnRobHknLCBsYWJlbDogJ01vbnRobHkgKG5leHQgbW9udGgpJyB9LFxuICAgIHsgdmFsdWU6ICdxdWFydGVybHknLCBsYWJlbDogJ1F1YXJ0ZXJseSAobmV4dCAzIG1vbnRocyknIH0sXG4gICAgeyB2YWx1ZTogJ2hhbGZ5ZWFybHknLCBsYWJlbDogJ0hhbGYteWVhcmx5IChuZXh0IDYgbW9udGhzKScgfSxcbiAgICB7IHZhbHVlOiAneWVhcmx5JywgbGFiZWw6ICdZZWFybHkgKG5leHQgMTIgbW9udGhzKScgfSxcbiAgXTtcblxuICAvLyBUZW1wbGF0ZSBoZWxwZXJzOiBzdXJmYWNlIFwidG91Y2hlZCAmJiBpbnZhbGlkXCIgc28gdGhlIEhUTUwgY2FuIGhpZ2hsaWdodFxuICAvLyB0aGUgZmllbGQgYW5kIHJlbmRlciBhbiBpbmxpbmUgZXJyb3IuIERlZmVuc2l2ZSBhZ2FpbnN0IHRoZSBmb3JtIG5vdCB5ZXRcbiAgLy8gYmVpbmcgaW5pdGlhbGlzZWQgZHVyaW5nIHRoZSBmaXJzdCBjaGFuZ2UtZGV0ZWN0aW9uIHBhc3MuXG4gIGNvbnRyb2xJbnZhbGlkKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmludm9pY2VGb3JtPy5nZXQobmFtZSk7XG4gICAgcmV0dXJuICEhY3RybCAmJiBjdHJsLnRvdWNoZWQgJiYgY3RybC5pbnZhbGlkO1xuICB9XG5cbiAgYXJyYXlDb250cm9sSW52YWxpZChhcnJheU5hbWU6ICdwcm9kdWN0cycgfCAndGF4JywgaW5kZXg6IG51bWJlciwgbmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5pbnZvaWNlRm9ybT8uZ2V0KGFycmF5TmFtZSkgYXMgRm9ybUFycmF5IHwgbnVsbDtcbiAgICBjb25zdCBjdHJsID0gYXJyPy5hdChpbmRleCk/LmdldChuYW1lKTtcbiAgICByZXR1cm4gISFjdHJsICYmIGN0cmwudG91Y2hlZCAmJiBjdHJsLmludmFsaWQ7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbFRvRmlyc3RJbnZhbGlkKCk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIGZpcnN0IGludmFsaWQgY29udHJvbCBpbnNpZGUgdGhlIG1vZGFsIGFuZCBicmluZyBpdCBpbnRvIHZpZXcuXG4gICAgLy8gU2NvcGVkIHRvIC5tb2RhbC1jb250ZW50IHNvIHdlIGRvbid0IGdyYWIgZmllbGRzIGZyb20gb3RoZXIgbW9kYWxzIG9uXG4gICAgLy8gdGhlIHBhZ2UgaWYgYW55IGFyZSBvcGVuLlxuICAgIGNvbnN0IHJvb3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kYWwtY29udGVudCcpO1xuICAgIGNvbnN0IGZpcnN0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcignLmlzLWludmFsaWQnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKGZpcnN0KSB7XG4gICAgICBmaXJzdC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgaWYgKHR5cGVvZiBmaXJzdC5mb2N1cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmaXJzdC5mb2N1cyh7IHByZXZlbnRTY3JvbGw6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IHByb2R1Y3RzKCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdwcm9kdWN0cycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGdldCB0YXhBcnJheSgpOiBGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmludm9pY2VGb3JtLmdldCgndGF4JykgYXMgRm9ybUFycmF5O1xuICB9XG5cbiAgY3JlYXRlUHJvZHVjdEdyb3VwKHByb2R1Y3Q/OiBhbnkpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIHByb2R1Y3ROYW1lOiBbcHJvZHVjdD8ucHJvZHVjdE5hbWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgLy8gV2hlbiB0cnVlLCB0aGUgbmFtZSBpcyBhIGZyZWUtdGV4dCBjdXN0b20gcHJvZHVjdCAobm90IGZyb20gdGhlIGNsaWVudCdzXG4gICAgICAvLyBiYXNlLXByaWNpbmcgbGlzdCkg4oCUIHRoZSB0ZW1wbGF0ZSBzaG93cyBhIHRleHQgaW5wdXQgaW5zdGVhZCBvZiB0aGVcbiAgICAgIC8vIHByb2R1Y3QgZHJvcGRvd24uXG4gICAgICBpc0N1c3RvbTogW3Byb2R1Y3Q/LmlzQ3VzdG9tIHx8IGZhbHNlXSxcbiAgICAgIGRlc2NyaXB0aW9uOiBbcHJvZHVjdD8uZGVzY3JpcHRpb24gfHwgJyddLFxuICAgICAgbW9udGg6IFtwcm9kdWN0Py5tb250aCB8fCAnJ10sXG4gICAgICBIc25OdW1iZXI6IFtwcm9kdWN0Py5Ic25OdW1iZXIgfHwgJzk5ODMxNCddLFxuICAgICAgc3RvcmVDb3VudDogW3Byb2R1Y3Q/LnN0b3JlQ291bnQgfHwgMCwgVmFsaWRhdG9ycy5taW4oMCldLFxuICAgICAgcHJpY2U6IFtwcm9kdWN0Py5wcmljZSB8fCAwLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGFtb3VudDogW3Byb2R1Y3Q/LmFtb3VudCB8fCAwXSxcbiAgICAgIHBlcmlvZDogW3Byb2R1Y3Q/LnBlcmlvZCB8fCAnbW9udGhseSddLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlVGF4R3JvdXAodGF4PzogYW55KTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5mYi5ncm91cCh7XG4gICAgICAvLyBEaXNhYmxlZDogdGF4IHJvd3MgYXJlIGRlcml2ZWQgZnJvbSB0aGUgR1NUIG51bWJlciAoYXBwbHlHcm91cEdzdFRheCksXG4gICAgICAvLyBuZXZlciBoYW5kLWVkaXRlZC4gb25TdWJtaXQgcmVhZHMgZ2V0UmF3VmFsdWUoKSwgc28gdGhlIGRpc2FibGVkIGNvbnRyb2xcbiAgICAgIC8vIHN0aWxsIHJlYWNoZXMgdGhlIHBheWxvYWQuXG4gICAgICB0eXBlOiBbeyB2YWx1ZTogdGF4Py50eXBlIHx8ICdJR1NUJywgZGlzYWJsZWQ6IHRydWUgfSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YWx1ZTogW3RheD8udmFsdWUgfHwgMTgsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbigwKSwgVmFsaWRhdG9ycy5tYXgoMTAwKV1dLFxuICAgICAgdGF4QW1vdW50OiBbdGF4Py50YXhBbW91bnQgfHwgJzAnXSxcbiAgICAgIC8vIERlZmF1bHQgdGhlIHRheC1yb3cgc3ltYm9sIHRvIHRoZSBpbnZvaWNlJ3MgY3VycmVuY3kgKHdhcyBoYXJkY29kZWRcbiAgICAgIC8vIHRvIOKCuSwgd2hpY2ggbGVha2VkIGludG8gdGhlIHNhdmVkIGRvYyBmb3Igbm9uLUlOUiBpbnZvaWNlcykuXG4gICAgICBjdXJyZW5jeTogW3RheD8uY3VycmVuY3kgfHwgdGhpcy5zeW1ib2xGb3IodGhpcy5pbnZvaWNlRm9ybT8uZ2V0KCdjdXJyZW5jeScpPy52YWx1ZSldLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW1ib2xGb3IoY29kZTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVuY3lTeW1ib2xzW2NvZGUgfHwgJyddIHx8ICckJztcbiAgfVxuXG4gIGFkZFByb2R1Y3QoKSB7XG4gICAgdGhpcy5wcm9kdWN0cy5wdXNoKHRoaXMuY3JlYXRlUHJvZHVjdEdyb3VwKCkpO1xuICAgIHRoaXMuc2Nyb2xsVG9MYXN0Um93KCdkYXRhLXByb2R1Y3Qtcm93Jyk7XG4gIH1cblxuICByZW1vdmVQcm9kdWN0KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnByb2R1Y3RzLnJlbW92ZUF0KGluZGV4KTtcbiAgICB0aGlzLnJlY2FsY3VsYXRlKCk7XG4gIH1cblxuICBhZGRUYXgoKSB7XG4gICAgdGhpcy50YXhBcnJheS5wdXNoKHRoaXMuY3JlYXRlVGF4R3JvdXAoKSk7XG4gICAgLy8gQXBwbHkgdGhlIGRlZmF1bHQgKDE4JSBJR1NUKSBhZ2FpbnN0IHRoZSBjdXJyZW50IHN1YnRvdGFsIGltbWVkaWF0ZWx5LCBzb1xuICAgIC8vIHRoZSB0YXggYW1vdW50IHBvcHVsYXRlcyBvbiBhZGQgaW5zdGVhZCBvZiBzdGF5aW5nIDAgdW50aWwgZWRpdGVkLlxuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgICB0aGlzLnNjcm9sbFRvTGFzdFJvdygnZGF0YS10YXgtcm93Jyk7XG4gIH1cblxuICByZW1vdmVUYXgoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMudGF4QXJyYXkucmVtb3ZlQXQoaW5kZXgpO1xuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgfVxuXG4gIC8vIERlZmF1bHQgcmF0ZSBwZXIgdGF4IHR5cGU6IElHU1QgaXMgYSBzaW5nbGUgMTglIGxpbmU7IENHU1QvU0dTVCBhcmUgdGhlXG4gIC8vIHNwbGl0IDklICsgOSUgaGFsdmVzLiBDaGFuZ2luZyB0aGUgdHlwZSByZXNldHMgdGhlICUgdG8gaXRzIGRlZmF1bHQgYW5kXG4gIC8vIHJlY29tcHV0ZXMgdGhlIGFtb3VudC5cbiAgb25UYXhUeXBlQ2hhbmdlKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBncm91cCA9IHRoaXMudGF4QXJyYXkuYXQoaW5kZXgpO1xuICAgIGNvbnN0IHR5cGUgPSBncm91cD8uZ2V0KCd0eXBlJyk/LnZhbHVlO1xuICAgIGNvbnN0IGRlZmF1bHRSYXRlID0gdHlwZSA9PT0gJ0NHU1QnIHx8IHR5cGUgPT09ICdTR1NUJyA/IDkgOiAxODtcbiAgICBncm91cD8uZ2V0KCd2YWx1ZScpPy5zZXRWYWx1ZShkZWZhdWx0UmF0ZSk7XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICB9XG5cbiAgcGF0Y2hGb3JtKCkge1xuICAgIGNvbnN0IGludiA9IHRoaXMuaW52b2ljZURhdGE7XG5cbiAgICB0aGlzLmludm9pY2VGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgY29tcGFueU5hbWU6IGludi5jb21wYW55TmFtZSB8fCAnJyxcbiAgICAgIGNvbXBhbnlBZGRyZXNzOiBpbnYuY29tcGFueUFkZHJlc3MgfHwgJycsXG4gICAgICBHU1ROdW1iZXI6IGludi5HU1ROdW1iZXIgfHwgJycsXG4gICAgICBQbGFjZU9mU3VwcGx5OiBpbnYuUGxhY2VPZlN1cHBseSB8fCAnJyxcbiAgICAgIGdyb3VwTmFtZTogaW52Lmdyb3VwTmFtZSB8fCAnJyxcbiAgICAgIGdyb3VwSWQ6IGludi5ncm91cElkIHx8ICcnLFxuICAgICAgc3RvcmVzOiBpbnYuc3RvcmVzIHx8IDAsXG4gICAgICBiaWxsaW5nRGF0ZTogdGhpcy5mb3JtYXREYXRlRm9ySW5wdXQoaW52LmJpbGxpbmdEYXRlKSxcbiAgICAgIGR1ZURhdGU6IHRoaXMuZm9ybWF0RGF0ZUZvcklucHV0KGludi5kdWVEYXRlKSxcbiAgICAgIGN1cnJlbmN5OiBpbnYuY3VycmVuY3kgfHwgJ2lucicsXG4gICAgICBzdGF0dXM6IGludi5zdGF0dXMgfHwgJ3BlbmRpbmcnLFxuICAgICAgcGF5bWVudFN0YXR1czogaW52LnBheW1lbnRTdGF0dXMgfHwgJ3VucGFpZCcsXG4gICAgICBwdXJjaGFzZU9yZGVyTnVtYmVyOiBpbnYucHVyY2hhc2VPcmRlck51bWJlciB8fCAnJyxcbiAgICB9KTtcbiAgICAvLyBUcmFjayB0aGUgbG9hZGVkIGN1cnJlbmN5IHNvIGEgY2FuY2VsbGVkIGNoYW5nZSBjYW4gcmV2ZXJ0IHRvIGl0LlxuICAgIHRoaXMucHJldmlvdXNDdXJyZW5jeSA9IGludi5jdXJyZW5jeSB8fCAnaW5yJztcblxuICAgIC8vIFBhdGNoIHByb2R1Y3RzXG4gICAgaWYgKGludi5wcm9kdWN0cz8ubGVuZ3RoKSB7XG4gICAgICBpbnYucHJvZHVjdHMuZm9yRWFjaCgocDogYW55KSA9PiB7XG4gICAgICAgIHRoaXMucHJvZHVjdHMucHVzaCh0aGlzLmNyZWF0ZVByb2R1Y3RHcm91cChwKSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGRQcm9kdWN0KCk7XG4gICAgfVxuXG4gICAgLy8gUGF0Y2ggdGF4LiBOb24tSU5SIGludm9pY2VzIChlLmcuIGRvbGxhciBjbGllbnRzKSBoYXZlIG5vIEdTVCwgYnV0IHRoZVxuICAgIC8vIGJhY2tlbmQgc3RpbGwgc3RvcmVzIGEgcGxhY2Vob2xkZXIgSUdTVCByb3cgd2l0aCBhIDAgYW1vdW50IOKAlCBza2lwIHRob3NlXG4gICAgLy8gc28gdGhlIHRheCBzZWN0aW9uIHN0YXJ0cyBlbXB0eS4gT25seSBsb2FkIHRheCByb3dzIHRoYXQgY2FycnkgYSByZWFsXG4gICAgLy8gKG5vbi16ZXJvKSBhbW91bnQuIFRoZSB1c2VyIGNhbiBzdGlsbCBhZGQgYSB0YXggd2l0aCB0aGUgXCJBZGQgVGF4XCIgYnV0dG9uLlxuICAgIGNvbnN0IHRheFJvd3MgPSAoaW52LnRheCB8fCBbXSkuZmlsdGVyKCh0OiBhbnkpID0+IE51bWJlcih0Py50YXhBbW91bnQpID4gMCk7XG4gICAgdGF4Um93cy5mb3JFYWNoKCh0OiBhbnkpID0+IHtcbiAgICAgIHRoaXMudGF4QXJyYXkucHVzaCh0aGlzLmNyZWF0ZVRheEdyb3VwKHQpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZvcm1hdERhdGVGb3JJbnB1dChkYXRlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghZGF0ZSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShkYXRlPy4kZGF0ZSB8fCBkYXRlKTtcbiAgICBpZiAoaXNOYU4oZC5nZXRUaW1lKCkpKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGQudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICB9XG5cbiAgLy8gQ3JlYXRlIG1vZGUgb25seTogZGVyaXZlIGR1ZURhdGUgPSBiaWxsaW5nRGF0ZSArIHBheW1lbnRUZXJtIChkYXlzKS4gQ2FsbGVkXG4gIC8vIHdoZW5ldmVyIHRoZSBiaWxsaW5nIGRhdGUgb3IgdGhlIHBheW1lbnQgdGVybSBjaGFuZ2VzLiBOby1vcCBpZiB0aGUgYmlsbGluZ1xuICAvLyBkYXRlIGlzbid0IHNldCB5ZXQuXG4gIGNvbXB1dGVEdWVEYXRlKCk6IHZvaWQge1xuICAgIGNvbnN0IGJpbGxpbmcgPSB0aGlzLmludm9pY2VGb3JtLmdldCgnYmlsbGluZ0RhdGUnKT8udmFsdWU7XG4gICAgY29uc3QgdGVybSA9IE51bWJlcih0aGlzLmludm9pY2VGb3JtLmdldCgncGF5bWVudFRlcm0nKT8udmFsdWUpIHx8IDA7XG4gICAgaWYgKCFiaWxsaW5nKSB7IHJldHVybjsgfVxuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShiaWxsaW5nKTtcbiAgICBpZiAoaXNOYU4oZC5nZXRUaW1lKCkpKSB7IHJldHVybjsgfVxuICAgIGQuc2V0RGF0ZShkLmdldERhdGUoKSArIHRlcm0pO1xuICAgIHRoaXMuaW52b2ljZUZvcm0ucGF0Y2hWYWx1ZSh7IGR1ZURhdGU6IHRoaXMuZm9ybWF0RGF0ZUZvcklucHV0KGQpIH0sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgfVxuXG4gIC8vIENoYW5naW5nIGFuIGludm9pY2UncyBjdXJyZW5jeSBjb252ZXJ0cyBldmVyeSBwcm9kdWN0IHByaWNlIGZyb20gdGhlIG9sZFxuICAvLyBjdXJyZW5jeSB0byB0aGUgbmV3IG9uZSB2aWEgbGl2ZSBGWCByYXRlcy4gQSBjb25maXJtYXRpb24gaXMgc2hvd24gZmlyc3Q7XG4gIC8vIGNhbmNlbGxpbmcgcmV2ZXJ0cyB0aGUgY3VycmVuY3kgc2VsZWN0LiBPbmx5IGFjdHMgd2hlbiB0aGUgY3VycmVuY3kgYWN0dWFsbHlcbiAgLy8gY2hhbmdlZCB0byBhIGRpZmZlcmVudCBjb2RlLlxuICBvbkN1cnJlbmN5Q2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBuZXdDdXJyZW5jeSA9IGV2ZW50Py50YXJnZXQ/LnZhbHVlO1xuICAgIGNvbnN0IG9sZEN1cnJlbmN5ID0gdGhpcy5wcmV2aW91c0N1cnJlbmN5O1xuICAgIGlmICghbmV3Q3VycmVuY3kgfHwgbmV3Q3VycmVuY3kgPT09IG9sZEN1cnJlbmN5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxhYmVsID0gKGM6IHN0cmluZykgPT4gdGhpcy5jdXJyZW5jeUxhYmVsc1tjXSB8fCBjO1xuICAgIGNvbnN0IG1vZGFsUmVmID0gdGhpcy5tb2RhbFNlcnZpY2Uub3BlbihSZXF1ZXN0Q29uZmlybWF0aW9uQ29tcG9uZW50LCB7XG4gICAgICBjZW50ZXJlZDogdHJ1ZSwgc2l6ZTogJ21kJywgc2Nyb2xsYWJsZTogdHJ1ZSxcbiAgICB9KTtcbiAgICBtb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS50aXRsZSA9ICdDaGFuZ2UgaW52b2ljZSBjdXJyZW5jeT8nO1xuICAgIG1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLmRlc2NyaXB0aW9uID1cbiAgICAgIGBUaGlzIGludm9pY2Ugd2FzIGNyZWF0ZWQgaW4gJHtsYWJlbChvbGRDdXJyZW5jeSl9LiBTd2l0Y2hpbmcgdG8gJHtsYWJlbChuZXdDdXJyZW5jeSl9IHdpbGwgY29udmVydCBhbGwgcHJvZHVjdCBhbW91bnRzIHVzaW5nIHRvZGF5J3MgZXhjaGFuZ2UgcmF0ZS4gUmV2aWV3IHRoZSBjb252ZXJ0ZWQgdmFsdWVzIGJlZm9yZSBzYXZpbmcuYDtcbiAgICBtb2RhbFJlZi5yZXN1bHQudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIGlmIChyZXN1bHQgPT09ICdZZXMnKSB7XG4gICAgICAgIHRoaXMuY29udmVydFByb2R1Y3RDdXJyZW5jeShvbGRDdXJyZW5jeSwgbmV3Q3VycmVuY3kpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ2FuY2VsbGVkIOKAlCByZXZlcnQgdGhlIHNlbGVjdCBiYWNrIHRvIHRoZSBvcmlnaW5hbCBjdXJyZW5jeS5cbiAgICAgICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKG9sZEN1cnJlbmN5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKG9sZEN1cnJlbmN5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBGZXRjaCBJTlItcGVyLXVuaXQgcmF0ZXMgYW5kIGNvbnZlcnQgZWFjaCBwcm9kdWN0IHByaWNlIGZyb20gb2xk4oaSbmV3OlxuICAvLyAgIG5ld1ByaWNlID0gb2xkUHJpY2UgKiAocmF0ZXNbb2xkXSAvIHJhdGVzW25ld10pLlxuICAvLyBUYXgtcm93IGN1cnJlbmN5IHN5bWJvbHMgYXJlIHJlZnJlc2hlZCBhbmQgYW1vdW50cyByZWNvbXB1dGVkLiBwcmV2aW91c0N1cnJlbmN5XG4gIC8vIGlzIGFkdmFuY2VkIG9ubHkgYWZ0ZXIgYSBzdWNjZXNzZnVsIGNvbnZlcnNpb24uXG4gIHByaXZhdGUgY29udmVydFByb2R1Y3RDdXJyZW5jeShvbGRDdXJyZW5jeTogc3RyaW5nLCBuZXdDdXJyZW5jeTogc3RyaW5nKSB7XG4gICAgdGhpcy5iaWxsaW5nU2VydmljZS5meFJhdGVzKCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgcmF0ZXMgPSByZXM/LmRhdGE/LnJhdGVzIHx8IHt9O1xuICAgICAgICBjb25zdCByT2xkID0gTnVtYmVyKHJhdGVzW29sZEN1cnJlbmN5XSk7XG4gICAgICAgIGNvbnN0IHJOZXcgPSBOdW1iZXIocmF0ZXNbbmV3Q3VycmVuY3ldKTtcbiAgICAgICAgaWYgKCEock9sZCA+IDApIHx8ICEock5ldyA+IDApKSB7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdFeGNoYW5nZSByYXRlIHVuYXZhaWxhYmxlIOKAlCBjdXJyZW5jeSBub3QgY29udmVydGVkLicpO1xuICAgICAgICAgIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdjdXJyZW5jeScpPy5zZXRWYWx1ZShvbGRDdXJyZW5jeSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmYWN0b3IgPSByT2xkIC8gck5ldztcbiAgICAgICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHByaWNlID0gTnVtYmVyKGdyb3VwLmdldCgncHJpY2UnKT8udmFsdWUpIHx8IDA7XG4gICAgICAgICAgY29uc3QgY29udmVydGVkID0gdGhpcy5yb3VuZEZvckN1cnJlbmN5KHByaWNlICogZmFjdG9yLCBuZXdDdXJyZW5jeSk7XG4gICAgICAgICAgZ3JvdXAuZ2V0KCdwcmljZScpPy5zZXRWYWx1ZShjb252ZXJ0ZWQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIFJlZnJlc2ggZWFjaCB0YXggcm93J3MgY3VycmVuY3kgc3ltYm9sIHRvIHRoZSBuZXcgY3VycmVuY3kuXG4gICAgICAgIGNvbnN0IHN5bWJvbCA9IHRoaXMuc3ltYm9sRm9yKG5ld0N1cnJlbmN5KTtcbiAgICAgICAgdGhpcy50YXhBcnJheS5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgICAgIGdyb3VwLmdldCgnY3VycmVuY3knKT8uc2V0VmFsdWUoc3ltYm9sLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnByZXZpb3VzQ3VycmVuY3kgPSBuZXdDdXJyZW5jeTtcbiAgICAgICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdChgQW1vdW50cyBjb252ZXJ0ZWQgdG8gJHt0aGlzLmN1cnJlbmN5TGFiZWxzW25ld0N1cnJlbmN5XSB8fCBuZXdDdXJyZW5jeX0uYCk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gZmV0Y2ggZXhjaGFuZ2UgcmF0ZSDigJQgY3VycmVuY3kgbm90IGNvbnZlcnRlZC4nKTtcbiAgICAgICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKG9sZEN1cnJlbmN5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkdyb3VwQ2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBzZWxlY3RlZEdyb3VwID0gdGhpcy5iaWxsaW5nR3JvdXBzLmZpbmQoZyA9PiBnLl9pZCA9PT0gZXZlbnQudGFyZ2V0LnZhbHVlKTtcbiAgICBpZiAoc2VsZWN0ZWRHcm91cCkge1xuICAgICAgdGhpcy5pbnZvaWNlRm9ybS5wYXRjaFZhbHVlKHtcbiAgICAgICAgZ3JvdXBOYW1lOiBzZWxlY3RlZEdyb3VwLmdyb3VwTmFtZSxcbiAgICAgICAgZ3JvdXBJZDogc2VsZWN0ZWRHcm91cC5faWQsXG4gICAgICAgIGNvbXBhbnlOYW1lOiBzZWxlY3RlZEdyb3VwLnJlZ2lzdGVyZWRDb21wYW55TmFtZSB8fCAnJyxcbiAgICAgICAgY29tcGFueUFkZHJlc3M6IFtzZWxlY3RlZEdyb3VwLmFkZHJlc3NMaW5lT25lLCBzZWxlY3RlZEdyb3VwLmFkZHJlc3NMaW5lVHdvLCBzZWxlY3RlZEdyb3VwLmNpdHksIHNlbGVjdGVkR3JvdXAuc3RhdGUsIHNlbGVjdGVkR3JvdXAuY291bnRyeSwgc2VsZWN0ZWRHcm91cC5waW5Db2RlXS5maWx0ZXIoQm9vbGVhbikuam9pbignLCAnKSxcbiAgICAgICAgR1NUTnVtYmVyOiBzZWxlY3RlZEdyb3VwLmdzdCB8fCAnJyxcbiAgICAgICAgUGxhY2VPZlN1cHBseTogc2VsZWN0ZWRHcm91cC5wbGFjZU9mU3VwcGx5IHx8ICcnLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFwcGx5R3JvdXBHc3RUYXgoc2VsZWN0ZWRHcm91cC5nc3QpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEF1dG8tcG9wdWxhdGUgdGhlIHRheCBzZWN0aW9uIGZyb20gdGhlIHNlbGVjdGVkIGdyb3VwJ3MgR1NUSU4sIG1pcnJvcmluZyB0aGVcbiAgLy8gYmFja2VuZCBpbnZvaWNlIHRheCBydWxlOiBHU1RJTiBzdGFydGluZyB3aXRoICczMycgKGludHJhLXN0YXRlLCBUYW1pbCBOYWR1KVxuICAvLyDihpIgQ0dTVCA5JSArIFNHU1QgOSU7IGFueSBvdGhlciBHU1RJTiDihpIgSUdTVCAxOCUuIE5vIEdTVCBudW1iZXIg4oaSIG5vIHRheCByb3dzLlxuICAvLyBSZWJ1aWxkcyB0aGUgdGF4IHNlY3Rpb24gZWFjaCB0aW1lIHNvIHJlLXNlbGVjdGluZyBhIGdyb3VwIGRvZXNuJ3Qgc3RhY2sgcm93cy5cbiAgcHJpdmF0ZSBhcHBseUdyb3VwR3N0VGF4KGdzdDogc3RyaW5nKSB7XG4gICAgdGhpcy50YXhBcnJheS5jbGVhcigpO1xuICAgIGNvbnN0IGdzdGluID0gU3RyaW5nKGdzdCB8fCAnJykudHJpbSgpO1xuICAgIGlmIChnc3Rpbikge1xuICAgICAgaWYgKGdzdGluLnNsaWNlKDAsIDIpID09PSAnMzMnKSB7XG4gICAgICAgIHRoaXMudGF4QXJyYXkucHVzaCh0aGlzLmNyZWF0ZVRheEdyb3VwKHsgdHlwZTogJ0NHU1QnLCB2YWx1ZTogOSB9KSk7XG4gICAgICAgIHRoaXMudGF4QXJyYXkucHVzaCh0aGlzLmNyZWF0ZVRheEdyb3VwKHsgdHlwZTogJ1NHU1QnLCB2YWx1ZTogOSB9KSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnRheEFycmF5LnB1c2godGhpcy5jcmVhdGVUYXhHcm91cCh7IHR5cGU6ICdJR1NUJywgdmFsdWU6IDE4IH0pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICB9XG5cbiAgLy8gQ3JlYXRlIG1vZGU6IHRoZSBHU1RJTiBjYW4gYmUgdHlwZWQvZWRpdGVkIGRpcmVjdGx5IOKAlCByZS1kZXJpdmUgdGhlIHRheCByb3dzXG4gIC8vIGZyb20gaXQgKHNhbWUgcnVsZSBhcyBncm91cCBzZWxlY3Rpb24pIHNvIHRheCBhbHdheXMgZm9sbG93cyB0aGUgR1NUIG51bWJlci5cbiAgLy8gSW4gZWRpdCBtb2RlIHRoZSBHU1QgTnVtYmVyIGZpZWxkIGlzIHJlYWQtb25seSwgc28gdGhpcyBpcyBhIG5vLW9wIHRoZXJlLlxuICBvbkdzdE51bWJlcklucHV0KCkge1xuICAgIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5R3JvdXBHc3RUYXgodGhpcy5pbnZvaWNlRm9ybS5nZXQoJ0dTVE51bWJlcicpPy52YWx1ZSk7XG4gIH1cblxuICAvLyAtLS0tIFByb2R1Y3Qgcm93IHJlb3JkZXJpbmcgKG5hdGl2ZSBIVE1MNSBkcmFnICYgZHJvcCkgLS0tLVxuICAvLyBkcmFnSW5kZXg6IHJvdyBiZWluZyBkcmFnZ2VkOyBkcmFnT3ZlckluZGV4OiByb3cgY3VycmVudGx5IGhvdmVyZWQgKGZvciB0aGVcbiAgLy8gZHJvcCBpbmRpY2F0b3IpLiBEcm9wcGluZyBtb3ZlcyB0aGUgRm9ybUdyb3VwIHdpdGhpbiB0aGUgRm9ybUFycmF5LCBzbyB0aGVcbiAgLy8gXCJQcm9kdWN0IE5cIiBudW1iZXJpbmcsIHRvdGFscyBhbmQgdGhlIHNhdmVkIHByb2R1Y3RzIG9yZGVyIGFsbCBmb2xsb3cuXG4gIGRyYWdJbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGRyYWdPdmVySW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIG9uUm93RHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQsIGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLmRyYWdJbmRleCA9IGluZGV4O1xuICAgIGlmIChldmVudC5kYXRhVHJhbnNmZXIpIHtcbiAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gJ21vdmUnO1xuICAgICAgLy8gU29tZSBicm93c2VycyBuZWVkIGRhdGEgc2V0IGZvciB0aGUgZHJhZyB0byBzdGFydC5cbiAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREYXRhKCd0ZXh0L3BsYWluJywgU3RyaW5nKGluZGV4KSk7XG4gICAgfVxuICB9XG5cbiAgb25Sb3dEcmFnT3ZlcihldmVudDogRHJhZ0V2ZW50LCBpbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuZHJhZ0luZGV4ID09PSBudWxsKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gYWxsb3cgZHJvcFxuICAgIGlmIChldmVudC5kYXRhVHJhbnNmZXIpIGV2ZW50LmRhdGFUcmFuc2Zlci5kcm9wRWZmZWN0ID0gJ21vdmUnO1xuICAgIHRoaXMuZHJhZ092ZXJJbmRleCA9IGluZGV4O1xuICB9XG5cbiAgb25Sb3dEcmFnTGVhdmUoaW5kZXg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmRyYWdPdmVySW5kZXggPT09IGluZGV4KSB0aGlzLmRyYWdPdmVySW5kZXggPSBudWxsO1xuICB9XG5cbiAgb25Sb3dEcm9wKGV2ZW50OiBEcmFnRXZlbnQsIHRhcmdldEluZGV4OiBudW1iZXIpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IGZyb20gPSB0aGlzLmRyYWdJbmRleDtcbiAgICB0aGlzLm9uUm93RHJhZ0VuZCgpO1xuICAgIGlmIChmcm9tID09PSBudWxsIHx8IGZyb20gPT09IHRhcmdldEluZGV4KSByZXR1cm47XG4gICAgY29uc3QgZ3JvdXAgPSB0aGlzLnByb2R1Y3RzLmF0KGZyb20pO1xuICAgIHRoaXMucHJvZHVjdHMucmVtb3ZlQXQoZnJvbSk7XG4gICAgdGhpcy5wcm9kdWN0cy5pbnNlcnQodGFyZ2V0SW5kZXgsIGdyb3VwKTtcbiAgICB0aGlzLnByb2R1Y3RzLm1hcmtBc0RpcnR5KCk7XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICB9XG5cbiAgb25Sb3dEcmFnRW5kKCkge1xuICAgIHRoaXMuZHJhZ0luZGV4ID0gbnVsbDtcbiAgICB0aGlzLmRyYWdPdmVySW5kZXggPSBudWxsO1xuICB9XG5cbiAgLy8gUmF0ZS9QcmljZTogYWxsb3cgYXQgbW9zdCAyIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC4gQW55dGhpbmcgYmV5b25kXG4gIC8vIChlLmcuIDEyLjM0NSkgaXMgdHJpbW1lZCB0byAxMi4zNCBhcyB0aGUgdXNlciB0eXBlcywgdGhlbiB0b3RhbHMgcmVjb21wdXRlLlxuICBvblByaWNlSW5wdXQoaTogbnVtYmVyKSB7XG4gICAgY29uc3QgY3RybCA9IHRoaXMucHJvZHVjdHMuYXQoaSk/LmdldCgncHJpY2UnKTtcbiAgICBjb25zdCByYXcgPSBjdHJsPy52YWx1ZTtcbiAgICBpZiAocmF3ICE9PSBudWxsICYmIHJhdyAhPT0gdW5kZWZpbmVkICYmIHJhdyAhPT0gJycpIHtcbiAgICAgIGNvbnN0IHRleHQgPSBTdHJpbmcocmF3KTtcbiAgICAgIGNvbnN0IG1hdGNoID0gdGV4dC5tYXRjaCgvXigtP1xcZCopKFxcLlxcZHswLDJ9KT8vKTtcbiAgICAgIGNvbnN0IHRyaW1tZWQgPSBtYXRjaCA/IGAke21hdGNoWzFdfSR7bWF0Y2hbMl0gPz8gJyd9YCA6IHRleHQ7XG4gICAgICBpZiAodHJpbW1lZCAhPT0gdGV4dCkge1xuICAgICAgICBjdHJsPy5zZXRWYWx1ZSh0cmltbWVkID09PSAnJyB8fCB0cmltbWVkID09PSAnLScgPyBudWxsIDogTnVtYmVyKHRyaW1tZWQpLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgfVxuXG4gIHJlY2FsY3VsYXRlKCkge1xuICAgIGxldCBzdWJ0b3RhbCA9IDA7XG4gICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY29uc3Qgc3RvcmVDb3VudCA9IGdyb3VwLmdldCgnc3RvcmVDb3VudCcpPy52YWx1ZSB8fCAwO1xuICAgICAgY29uc3QgcHJpY2UgPSBncm91cC5nZXQoJ3ByaWNlJyk/LnZhbHVlIHx8IDA7XG4gICAgICBjb25zdCBhbW91bnQgPSBzdG9yZUNvdW50ICogcHJpY2U7XG4gICAgICBncm91cC5nZXQoJ2Ftb3VudCcpPy5zZXRWYWx1ZShwYXJzZUZsb2F0KGFtb3VudC50b0ZpeGVkKDIpKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgc3VidG90YWwgKz0gYW1vdW50O1xuICAgIH0pO1xuXG4gICAgLy8gVGF4IGlzIGNoYXJnZWQgb24gdGhlIERJU0NPVU5URUQgYW1vdW50LCBtYXRjaGluZyBhcHBseURpc2NvdW50KCkgb24gdGhlXG4gICAgLy8gYmFja2VuZC4gVGF4aW5nIHRoZSBncm9zcyBzdWJ0b3RhbCBoZXJlIHdvdWxkIHNob3cgYSB0b3RhbCB0aGF0IHRoZVxuICAgIC8vIHNlcnZlciB0aGVuIHJlY29tcHV0ZXMgZGlmZmVyZW50bHkuXG4gICAgY29uc3QgdGF4YWJsZSA9IHN1YnRvdGFsIC0gdGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKTtcbiAgICB0aGlzLnRheEFycmF5LmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGdyb3VwLmdldCgndmFsdWUnKT8udmFsdWUgfHwgMDtcbiAgICAgIGNvbnN0IHRheEFtb3VudCA9ICh0YXhhYmxlICogdmFsdWUgLyAxMDApLnRvRml4ZWQoMik7XG4gICAgICBncm91cC5nZXQoJ3RheEFtb3VudCcpPy5zZXRWYWx1ZSh0YXhBbW91bnQsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB9KTtcblxuICAgIGxldCB0b3RhbFN0b3JlcyA9IDA7XG4gICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgdG90YWxTdG9yZXMgKz0gZ3JvdXAuZ2V0KCdzdG9yZUNvdW50Jyk/LnZhbHVlIHx8IDA7XG4gICAgfSk7XG4gICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ3N0b3JlcycpPy5zZXRWYWx1ZSh0b3RhbFN0b3JlcywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuXG4gICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuXG4gIGdldFN1YnRvdGFsKCk6IG51bWJlciB7XG4gICAgbGV0IHN1YnRvdGFsID0gMDtcbiAgICB0aGlzLnByb2R1Y3RzLmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICBzdWJ0b3RhbCArPSBncm91cC5nZXQoJ2Ftb3VudCcpPy52YWx1ZSB8fCAwO1xuICAgIH0pO1xuICAgIHJldHVybiBzdWJ0b3RhbDtcbiAgfVxuXG4gIGdldFRvdGFsVGF4KCk6IG51bWJlciB7XG4gICAgbGV0IHRvdGFsVGF4ID0gMDtcbiAgICB0aGlzLnRheEFycmF5LmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICB0b3RhbFRheCArPSBwYXJzZUZsb2F0KGdyb3VwLmdldCgndGF4QW1vdW50Jyk/LnZhbHVlIHx8ICcwJyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRvdGFsVGF4O1xuICB9XG5cbiAgLy8gQ3JlZGl0IG5vdGUgYWxyZWFkeSBhcHBsaWVkIHRvIHRoaXMgaW52b2ljZSAoMCB3aGVuIG5vbmUpLiBSZWFkIHN0cmFpZ2h0XG4gIC8vIG9mZiB0aGUgc2F2ZWQgaW52b2ljZSDigJQgaXQgaXMgbm90IGEgbGluZSBpdGVtLCBzbyBnZXRTdWJ0b3RhbCgpIG5ldmVyIHNlZXNcbiAgLy8gaXQgYW5kIHRoZSBzdW1tYXJ5IHdvdWxkIG90aGVyd2lzZSBzaG93IHRoZSBwcmUtZGlzY291bnQgdG90YWwuXG4gIGdldEFwcGxpZWREaXNjb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBOdW1iZXIodGhpcy5pbnZvaWNlRGF0YT8uZGlzY291bnRBbW91bnQpIHx8IDA7XG4gIH1cblxuICBnZXRUb3RhbEFtb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmdldFN1YnRvdGFsKCkgLSB0aGlzLmdldEFwcGxpZWREaXNjb3VudCgpICsgdGhpcy5nZXRUb3RhbFRheCgpO1xuICB9XG5cbiAgLy8gQ3VycmVuY3ktYXdhcmUgcm91bmRpbmc6IElOUiAtPiB3aG9sZSBudW1iZXIsIGV2ZXJ5IG90aGVyIGN1cnJlbmN5IGtlZXBzXG4gIC8vIDIgZGVjaW1hbHMuIE1pcnJvcnMgdGhlIGJhY2tlbmQgcm91bmRBbW91bnQoKSBoZWxwZXIuXG4gIHJvdW5kRm9yQ3VycmVuY3kodmFsdWU6IG51bWJlciwgY3VycmVuY3k6IHN0cmluZyk6IG51bWJlciB7XG4gICAgY29uc3QgbiA9IE51bWJlcih2YWx1ZSkgfHwgMDtcbiAgICByZXR1cm4gY3VycmVuY3kgPT09ICdpbnInID8gTWF0aC5yb3VuZChuKSA6IE1hdGgucm91bmQobiAqIDEwMCkgLyAxMDA7XG4gIH1cblxuICBnZXRDdXJyZW5jeVN5bWJvbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnN5bWJvbEZvcih0aGlzLmludm9pY2VGb3JtLmdldCgnY3VycmVuY3knKT8udmFsdWUpO1xuICB9XG5cbiAgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3ltYm9sRm9yKHRoaXMuaW52b2ljZURhdGE/LmN1cnJlbmN5KTtcbiAgfVxuXG4gIG9uU3VibWl0KCkge1xuICAgIGlmICh0aGlzLmludm9pY2VGb3JtLmludmFsaWQpIHtcbiAgICAgIHRoaXMuaW52b2ljZUZvcm0ubWFya0FsbEFzVG91Y2hlZCgpO1xuICAgICAgLy8gRGVmZXIgdG8gbmV4dCB0aWNrIHNvIEFuZ3VsYXIgcmVuZGVycyB0aGUgLmlzLWludmFsaWQgY2xhc3Nlc1xuICAgICAgLy8gYmVmb3JlIHdlIHF1ZXJ5IHRoZSBET00gZm9yIHRoZSBmaXJzdCBpbnZhbGlkIGNvbnRyb2wgdG8gc2Nyb2xsIHRvLlxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnNjcm9sbFRvRmlyc3RJbnZhbGlkKCksIDApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc2F2aW5nID0gdHJ1ZTtcbiAgICBjb25zdCBmb3JtVmFsdWUgPSB0aGlzLmludm9pY2VGb3JtLmdldFJhd1ZhbHVlKCk7XG5cbiAgICBjb25zdCBwYXlsb2FkOiBhbnkgPSB7XG4gICAgICBjb21wYW55TmFtZTogZm9ybVZhbHVlLmNvbXBhbnlOYW1lLFxuICAgICAgY29tcGFueUFkZHJlc3M6IGZvcm1WYWx1ZS5jb21wYW55QWRkcmVzcyxcbiAgICAgIEdTVE51bWJlcjogZm9ybVZhbHVlLkdTVE51bWJlcixcbiAgICAgIFBsYWNlT2ZTdXBwbHk6IGZvcm1WYWx1ZS5QbGFjZU9mU3VwcGx5LFxuICAgICAgZ3JvdXBOYW1lOiBmb3JtVmFsdWUuZ3JvdXBOYW1lLFxuICAgICAgZ3JvdXBJZDogZm9ybVZhbHVlLmdyb3VwSWQsXG4gICAgICBzdG9yZXM6IGZvcm1WYWx1ZS5zdG9yZXMsXG4gICAgICBiaWxsaW5nRGF0ZTogZm9ybVZhbHVlLmJpbGxpbmdEYXRlLFxuICAgICAgZHVlRGF0ZTogZm9ybVZhbHVlLmR1ZURhdGUsXG4gICAgICBwYXltZW50VGVybTogZm9ybVZhbHVlLnBheW1lbnRUZXJtLFxuICAgICAgY3VycmVuY3k6IGZvcm1WYWx1ZS5jdXJyZW5jeSxcbiAgICAgIHN0YXR1czogZm9ybVZhbHVlLnN0YXR1cyxcbiAgICAgIHBheW1lbnRTdGF0dXM6IGZvcm1WYWx1ZS5wYXltZW50U3RhdHVzLFxuICAgICAgYWR2YW5jZUludm9pY2U6IGZvcm1WYWx1ZS5hZHZhbmNlSW52b2ljZSxcbiAgICAgIGFkdmFuY2VQZXJpb2Q6IGZvcm1WYWx1ZS5hZHZhbmNlUGVyaW9kLFxuICAgICAgLy8gTWFwIGludm9pY2UgdG8gYSBwdXJjaGFzZSBvcmRlciAoc2VydmVyIGRlZHVjdHMgdGhlIFBPIGJhbGFuY2UpLlxuICAgICAgcHVyY2hhc2VPcmRlck51bWJlcjogZm9ybVZhbHVlLnB1cmNoYXNlT3JkZXJOdW1iZXIgfHwgdW5kZWZpbmVkLFxuICAgICAgcHJvZHVjdHM6IGZvcm1WYWx1ZS5wcm9kdWN0cyxcbiAgICAgIHRheDogZm9ybVZhbHVlLnRheCxcbiAgICAgIC8vICdhbW91bnQnIGlzIHRoZSBwb3N0LWRpc2NvdW50IHZhbHVlIHRoZSBiYWNrZW5kIHN0b3JlcyAoZ2V0U3VidG90YWwoKVxuICAgICAgLy8gaXMgdGhlIGdyb3NzIGxpbmUtaXRlbSB0b3RhbCkuIFNlbmRpbmcgdGhlIGdyb3NzIGZpZ3VyZSBoZXJlIHdpcGVkIGFuXG4gICAgICAvLyBhcHBsaWVkIGNyZWRpdCBub3RlIG9uIGV2ZXJ5IFVwZGF0ZSBJbnZvaWNlLlxuICAgICAgLy8gQ29tcG9uZW50IGZpZ3VyZXMgKHN1YnRvdGFsLCBkaXNjb3VudCkga2VlcCBleGFjdCBwYWlzZSDigJQgb25seSB0aGVcbiAgICAgIC8vIFRvdGFsIEFtb3VudCBpcyB3aG9sZS11bml0IHJvdW5kZWQgKElOUikuIFBvc3RpbmcgYSB3aG9sZS1yb3VuZGVkXG4gICAgICAvLyBzdWJ0b3RhbCBtYWRlIHRoZSBwcmludGVkIFN1YiBUb3RhbCBkaXNhZ3JlZSB3aXRoIHRoZSBsaW5lIGl0ZW1zXG4gICAgICAvLyAoZS5nLiAyNCwwNjUuMDAgdnMgbGluZXMgc3VtbWluZyB0byAyNCwwNjQuNTIpLlxuICAgICAgYW1vdW50OiB0aGlzLnJvdW5kMih0aGlzLmdldFN1YnRvdGFsKCkgLSB0aGlzLmdldEFwcGxpZWREaXNjb3VudCgpKSxcbiAgICAgIHRvdGFsQW1vdW50OiB0aGlzLnJvdW5kRm9yQ3VycmVuY3kodGhpcy5nZXRUb3RhbEFtb3VudCgpLCBmb3JtVmFsdWUuY3VycmVuY3kpLFxuICAgIH07XG5cbiAgICAvLyBDYXJyeSB0aGUgYXBwbGllZCBjcmVkaXQgbm90ZSB0aHJvdWdoIHRoZSB1cGRhdGUgc28gaXQgc3Vydml2ZXMgYW4gZWRpdC5cbiAgICBpZiAodGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKSA+IDApIHtcbiAgICAgIHBheWxvYWQuZGlzY291bnRBbW91bnQgPSB0aGlzLnJvdW5kMih0aGlzLmdldEFwcGxpZWREaXNjb3VudCgpKTtcbiAgICAgIGNvbnN0IGdyb3NzID0gdGhpcy5nZXRTdWJ0b3RhbCgpO1xuICAgICAgcGF5bG9hZC5kaXNjb3VudFBlcmNlbnRhZ2UgPSBncm9zcyA+IDBcbiAgICAgICAgPyB0aGlzLnJvdW5kMih0aGlzLmdldEFwcGxpZWREaXNjb3VudCgpIC8gZ3Jvc3MgKiAxMDApXG4gICAgICAgIDogMDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tb2RlID09PSAnZWRpdCcpIHtcbiAgICAgIHBheWxvYWQuX2lkID0gdGhpcy5pbnZvaWNlRGF0YS5faWQ7XG4gICAgICBwYXlsb2FkLmludm9pY2UgPSB0aGlzLmludm9pY2VEYXRhLmludm9pY2U7XG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5pbnZvaWNlRGF0YS5jbGllbnRJZDtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UudXBkYXRlSW52b2ljZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnSW52b2ljZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgndXBkYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIHVwZGF0ZSBpbnZvaWNlJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZWRpdEVzdGltYXRlJykge1xuICAgICAgLy8gVXBkYXRlIGFuIGV4aXN0aW5nIGVzdGltYXRlLiBJZGVudGl0eSBmaWVsZHMgKGVzdGltYXRlICMsIGNsaWVudElkLFxuICAgICAgLy8gY3JlYXRlZERhdGUpIGFyZSBwcmVzZXJ2ZWQgc2VydmVyLXNpZGU7IHdlIHNlbmQgdGhlIGVkaXRhYmxlIGZvcm0gZGF0YS5cbiAgICAgIHBheWxvYWQuX2lkID0gdGhpcy5pbnZvaWNlRGF0YS5faWQ7XG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5pbnZvaWNlRGF0YS5jbGllbnRJZCB8fCB0aGlzLmNsaWVudElkO1xuICAgICAgcGF5bG9hZC5wZXJpb2QgPSBmb3JtVmFsdWUuYmlsbGluZ0RhdGVcbiAgICAgICAgPyBuZXcgRGF0ZShmb3JtVmFsdWUuYmlsbGluZ0RhdGUpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycsIHsgbW9udGg6ICdzaG9ydCcsIHllYXI6ICdudW1lcmljJyB9KVxuICAgICAgICA6IHRoaXMuaW52b2ljZURhdGEucGVyaW9kO1xuICAgICAgcGF5bG9hZC52YWxpZFRpbGwgPSBmb3JtVmFsdWUuZHVlRGF0ZTtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UudXBkYXRlRXN0aW1hdGUocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ0VzdGltYXRlIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCd1cGRhdGVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIHVwZGF0ZSBlc3RpbWF0ZScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2VzdGltYXRlJykge1xuICAgICAgLy8gU2FtZSBmb3JtLCBzZXBhcmF0ZSBkb2N1bWVudDogcG9zdCB0byB0aGUgZXN0aW1hdGUgQVBJIHNvIGl0IGxhbmRzIGluXG4gICAgICAvLyB0aGUgZXN0aW1hdGVzIGNvbGxlY3Rpb24gd2l0aCBhbiBFU1Qt4oCmIG51bWJlciBpbnN0ZWFkIG9mIGFuIGludm9pY2UuXG4gICAgICBwYXlsb2FkLmNsaWVudElkID0gdGhpcy5jbGllbnRJZDtcbiAgICAgIHBheWxvYWQucGVyaW9kID0gZm9ybVZhbHVlLmJpbGxpbmdEYXRlXG4gICAgICAgID8gbmV3IERhdGUoZm9ybVZhbHVlLmJpbGxpbmdEYXRlKS50b0xvY2FsZVN0cmluZygnZW4tVVMnLCB7IG1vbnRoOiAnc2hvcnQnLCB5ZWFyOiAnbnVtZXJpYycgfSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICBwYXlsb2FkLnZhbGlkVGlsbCA9IGZvcm1WYWx1ZS5kdWVEYXRlO1xuICAgICAgdGhpcy5iaWxsaW5nU2VydmljZS5jcmVhdGVFc3RpbWF0ZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnRXN0aW1hdGUgZ2VuZXJhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgnY3JlYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBnZW5lcmF0ZSBlc3RpbWF0ZScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcGF5bG9hZC5jbGllbnRJZCA9IHRoaXMuY2xpZW50SWQ7XG4gICAgICAvLyBGbGFnIHRoZSBiYWNrZW5kIHRvIHRha2UgdGhlIFwiY3VzdG9tIGNyZWF0ZVwiIHBhdGggdGhhdCBwZXJzaXN0cyB3aGF0XG4gICAgICAvLyB0aGUgZm9ybSBidWlsdC4gVGhlIGxlZ2FjeSAvY3JlYXRlSW52b2ljZSBjb250cmFjdCBleHBlY3RzIGVpdGhlclxuICAgICAgLy8gYWxsQ2xpZW50K2NsaWVudExpc3Qgb3IgaW52b2ljZUlkOyB3aXRob3V0IHRoaXMgZmxhZywgdGhlIHNlcnZlclxuICAgICAgLy8gc2lsZW50bHkgcmV0dXJucyAyeHggYW5kIHdyaXRlcyBub3RoaW5nLlxuICAgICAgcGF5bG9hZC5jdXN0b21JbnZvaWNlID0gdHJ1ZTtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuY3JlYXRlSW52b2ljZShwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnSW52b2ljZSBjcmVhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgnY3JlYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgY29uc3QgbXNnID0gZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGNyZWF0ZSBpbnZvaWNlJztcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QobXNnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09IENSRURJVCBOT1RFID09PT09PT09PT09PT09PT09PT09PVxuXG4gIGluaXRDcmVkaXROb3RlRm9ybSgpIHtcbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICBhbW91bnQ6IFsnJ10sXG4gICAgICByZXZpc2VkQW1vdW50OiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgZGlzY291bnRBbW91bnQ6IFsnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICB9KTtcblxuICAgIC8vIERpc2NvdW50IEFtb3VudCBhbmQgUmV2aXNlZCBBbW91bnQgYXJlIHR3byB2aWV3cyBvZiBvbmUgbnVtYmVyIOKAlCBlZGl0aW5nXG4gICAgLy8gZWl0aGVyIHJlY29tcHV0ZXMgdGhlIG90aGVyICh7IGVtaXRFdmVudDogZmFsc2UgfSBzdG9wcyB0aGUgZmVlZGJhY2tcbiAgICAvLyBsb29wKS4gVGhlIGRpc2NvdW50IFBFUkNFTlRBR0UgaXMgbm8gbG9uZ2VyIGFuIGlucHV0OiBpdCdzIGRlcml2ZWQgb25jZVxuICAgIC8vIG9uIHN1Ym1pdCwgc28gYSAyIGRwIHBlcmNlbnRhZ2UgY2FuIG5ldmVyIHJvdW5kIHRoZSBlbnRlcmVkIGFtb3VudC5cbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnZGlzY291bnRBbW91bnQnKT8udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgIGlmIChlID09PSAnJyB8fCBlID09PSBudWxsIHx8IGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgncmV2aXNlZEFtb3VudCcpPy5zZXRWYWx1ZSgnJywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgYW1vdW50ID0gdGhpcy50b051bWJlcih0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnYW1vdW50Jyk/LnZhbHVlKTtcbiAgICAgIGNvbnN0IGRpc2NvdW50QW1vdW50ID0gdGhpcy50b051bWJlcihlKTtcbiAgICAgIGlmIChhbW91bnQgPiAwKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID0gaXNOYU4oZGlzY291bnRBbW91bnQpIHx8IGRpc2NvdW50QW1vdW50IDwgMCB8fCBkaXNjb3VudEFtb3VudCA+IGFtb3VudDtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8uc2V0VmFsdWUodGhpcy5yb3VuZDIoYW1vdW50IC0gZGlzY291bnRBbW91bnQpLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdyZXZpc2VkQW1vdW50Jyk/LnZhbHVlQ2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChlKSA9PiB7XG4gICAgICBpZiAoZSA9PT0gJycgfHwgZSA9PT0gbnVsbCB8fCBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Rpc2NvdW50QW1vdW50Jyk/LnNldFZhbHVlKCcnLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBhbW91bnQgPSB0aGlzLnRvTnVtYmVyKHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdhbW91bnQnKT8udmFsdWUpO1xuICAgICAgY29uc3QgcmV2aXNlZCA9IHRoaXMudG9OdW1iZXIoZSk7XG4gICAgICBpZiAoYW1vdW50ID4gMCkge1xuICAgICAgICAvLyBJbnZhbGlkIHdoZW4gbm90IGEgbnVtYmVyLCBuZWdhdGl2ZSwgb3IgY3JlZGl0aW5nIG1vcmUgdGhhbiB0aGUgdG90YWwuXG4gICAgICAgIHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID0gaXNOYU4ocmV2aXNlZCkgfHwgcmV2aXNlZCA8IDAgfHwgcmV2aXNlZCA+IGFtb3VudDtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Rpc2NvdW50QW1vdW50Jyk/LnNldFZhbHVlKHRoaXMucm91bmQyKGFtb3VudCAtIHJldmlzZWQpLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFBhcnNlIGEgZm9ybSB2YWx1ZSB0aGF0IG1heSBiZSBhIHN0cmluZyAoJzEyMzQuNTYnKSBvciBhIG51bWJlci5cbiAgcHJpdmF0ZSB0b051bWJlcih2OiBhbnkpOiBudW1iZXIge1xuICAgIGlmICh2ID09PSAnJyB8fCB2ID09PSBudWxsIHx8IHYgPT09IHVuZGVmaW5lZCkgcmV0dXJuIE5hTjtcbiAgICByZXR1cm4gTnVtYmVyKHYpO1xuICB9XG5cbiAgLy8gUm91bmQgdG8gMiBkZWNpbWFsIHBsYWNlcywgYXZvaWRpbmcgZmxvYXQgYXJ0ZWZhY3RzICgwLjErMC4yIHN0eWxlKS5cbiAgcHJpdmF0ZSByb3VuZDIobjogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoIWlzRmluaXRlKG4pKSByZXR1cm4gTmFOO1xuICAgIHJldHVybiBNYXRoLnJvdW5kKChuICsgTnVtYmVyLkVQU0lMT04pICogMTAwKSAvIDEwMDtcbiAgfVxuXG4gIHBhdGNoQ3JlZGl0Tm90ZURlZmF1bHRzKCkge1xuICAgIGlmICghdGhpcy5pbnZvaWNlRGF0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBpbnZvaWNlRGF0YS5hbW91bnQgaXMgdGhlIENVUlJFTlQgKGFscmVhZHkgZGlzY291bnRlZCkgYW1vdW50LCBzbyBhZGQgYW55XG4gICAgLy8gYXBwbGllZCBkaXNjb3VudCBiYWNrIHRvIHNob3cgdGhlIG9yaWdpbmFsIGludm9pY2UgdmFsdWUgaW4gVG90YWwgQW1vdW50LlxuICAgIGNvbnN0IGFwcGxpZWQgPSB0aGlzLmdldEFwcGxpZWREaXNjb3VudCgpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBOdW1iZXIodGhpcy5pbnZvaWNlRGF0YS5hbW91bnQgPz8gdGhpcy5pbnZvaWNlRGF0YS50b3RhbEFtb3VudCkgfHwgMDtcbiAgICBjb25zdCBvcmlnaW5hbCA9IHRoaXMucm91bmQyKGN1cnJlbnQgKyBhcHBsaWVkKTtcblxuICAgIC8vIFByZS1wb3B1bGF0ZSB3aXRoIHRoZSBkaXNjb3VudCBhbHJlYWR5IG9uIHRoaXMgaW52b2ljZSBzbyByZS1vcGVuaW5nIHRoZVxuICAgIC8vIHRhYiBzaG93cyB3aGF0IHdhcyBhcHBsaWVkIHJhdGhlciB0aGFuIGFuIGVtcHR5IGZvcm0uIGVtaXRFdmVudDogZmFsc2Ug4oCUXG4gICAgLy8gdGhlIHZhbHVlQ2hhbmdlcyBwYWlyIHdvdWxkIG90aGVyd2lzZSByZWNvbXB1dGUgZnJvbSBhIGhhbGYtcGF0Y2hlZCBmb3JtLlxuICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICBhbW91bnQ6IG9yaWdpbmFsLFxuICAgICAgZGlzY291bnRBbW91bnQ6IGFwcGxpZWQgPiAwID8gYXBwbGllZCA6ICcnLFxuICAgICAgcmV2aXNlZEFtb3VudDogYXBwbGllZCA+IDAgPyB0aGlzLnJvdW5kMihvcmlnaW5hbCAtIGFwcGxpZWQpIDogJycsXG4gICAgfSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID0gZmFsc2U7XG4gIH1cblxuICBhcHBseUNyZWRpdE5vdGUoKSB7XG4gICAgaWYgKHRoaXMuY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50KSByZXR1cm47XG4gICAgLy8gZGlzY291bnRBbW91bnQgaXMgd2hhdCB0aGUgdXNlciB0eXBlZCBhbmQgaXMgYXV0aG9yaXRhdGl2ZS4gVGhlXG4gICAgLy8gcGVyY2VudGFnZSBpcyBkZXJpdmVkIGZyb20gaXQgaGVyZSBwdXJlbHkgc28gdGhlIGJhY2tlbmQgY2FuIGtlZXAgc3RvcmluZ1xuICAgIC8vIGRpc2NvdW50UGVyY2VudGFnZSDigJQgaXQgaXMgbmV2ZXIgdXNlZCB0byBjb21wdXRlIHRoZSBjcmVkaXRlZCB2YWx1ZS5cbiAgICBjb25zdCBhbW91bnQgPSB0aGlzLnRvTnVtYmVyKHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdhbW91bnQnKT8udmFsdWUpO1xuICAgIGNvbnN0IGRpc2NvdW50QW1vdW50ID0gdGhpcy50b051bWJlcih0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnZGlzY291bnRBbW91bnQnKT8udmFsdWUpO1xuICAgIGNvbnN0IHJlcXVlc3REYXRhID0ge1xuICAgICAgaW52b2ljZTogdGhpcy5pbnZvaWNlRGF0YS5pbnZvaWNlLFxuICAgICAgcmV2aXNlZEFtb3VudDogdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8udmFsdWUsXG4gICAgICBkaXNjb3VudDogYW1vdW50ID4gMCA/IHRoaXMucm91bmQyKGRpc2NvdW50QW1vdW50IC8gYW1vdW50ICogMTAwKSA6IDAsXG4gICAgICBkaXNjb3VudEFtb3VudDogZGlzY291bnRBbW91bnQsXG4gICAgfTtcbiAgICB0aGlzLnNhdmluZyA9IHRydWU7XG4gICAgdGhpcy5iaWxsaW5nU2VydmljZS5hcHBseURpc2NvdW50KHJlcXVlc3REYXRhKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAocmVzICYmIHJlcy5jb2RlID09IDIwMCkge1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdDcmVkaXQgbm90ZSBhcHBsaWVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ2NyZWRpdEFwcGxpZWQnKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGFwcGx5IGNyZWRpdCBub3RlJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbWl0U3BlY2lhbENoYXIoZXZlbnQ6IGFueSkge1xuICAgIGNvbnN0IGsgPSBldmVudC5jaGFyQ29kZTtcbiAgICByZXR1cm4gKGsgPT0gOCB8fCBrID09IDMyIHx8IChrID49IDQ4ICYmIGsgPD0gNTcpKTtcbiAgfVxuXG4gIC8vIEFtb3VudC9wZXJjZW50YWdlIGtleXByZXNzIGZpbHRlcjogZGlnaXRzIHBsdXMgYSBzaW5nbGUgZGVjaW1hbCBwb2ludC5cbiAgLy8gb21pdFNwZWNpYWxDaGFyIChhYm92ZSkgYmxvY2tzICcuJywgd2hpY2ggd291bGQgbWFrZSB0aGVzZSBmaWVsZHNcbiAgLy8gaW50ZWdlci1vbmx5IOKAlCBrZXB0IHNlcGFyYXRlIHNvIG90aGVyIGlucHV0cyB1c2luZyBpdCBhcmUgdW5hZmZlY3RlZC5cbiAgb21pdFNwZWNpYWxDaGFyRGVjaW1hbChldmVudDogYW55KSB7XG4gICAgY29uc3QgayA9IGV2ZW50LmNoYXJDb2RlO1xuICAgIGlmIChrID09IDggfHwgayA9PSAzMiB8fCAoayA+PSA0OCAmJiBrIDw9IDU3KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIEFsbG93ICcuJyBvbmx5IG9uY2UsIGFuZCBub3QgYXMgdGhlIHZlcnkgZmlyc3QgY2hhcmFjdGVyLlxuICAgIGlmIChrID09IDQ2KSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IFN0cmluZyhldmVudD8udGFyZ2V0Py52YWx1ZSA/PyAnJyk7XG4gICAgICByZXR1cm4gdmFsdWUubGVuZ3RoID4gMCAmJiAhdmFsdWUuaW5jbHVkZXMoJy4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09IE9ORSBUSU1FIEZFRSA9PT09PT09PT09PT09PT09PT09PT1cblxuICBpbml0T25lVGltZUZlZUZvcm0oKSB7XG4gICAgdGhpcy5vbmVUaW1lRmVlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgYW1vdW50OiBbJyddLFxuICAgICAgb25lVGltZUZlZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICB9KTtcblxuICAgIHRoaXMub25lVGltZUZlZUZvcm0udmFsdWVDaGFuZ2VzLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5jYWxjdWxhdGVPbmVUaW1lRmVlVG90YWwoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHBhdGNoT25lVGltZUZlZURlZmF1bHRzKCkge1xuICAgIGlmICh0aGlzLmludm9pY2VEYXRhKSB7XG4gICAgICB0aGlzLm9uZVRpbWVGZWVGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgICBhbW91bnQ6IHRoaXMuaW52b2ljZURhdGEuYW1vdW50IHx8IHRoaXMuaW52b2ljZURhdGEudG90YWxBbW91bnQgfHwgMCxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5jYWxjdWxhdGVPbmVUaW1lRmVlVG90YWwoKTtcbiAgICB9XG4gIH1cblxuICBjYWxjdWxhdGVPbmVUaW1lRmVlVG90YWwoKSB7XG4gICAgY29uc3QgYW1vdW50ID0gcGFyc2VGbG9hdCh0aGlzLm9uZVRpbWVGZWVGb3JtLmdldCgnYW1vdW50Jyk/LnZhbHVlIHx8ICcwJyk7XG4gICAgY29uc3QgZmVlID0gcGFyc2VGbG9hdCh0aGlzLm9uZVRpbWVGZWVGb3JtLmdldCgnb25lVGltZUZlZScpPy52YWx1ZSB8fCAnMCcpO1xuICAgIHRoaXMub25lVGltZUZlZVRvdGFsID0gcGFyc2VGbG9hdCgoYW1vdW50ICsgZmVlKS50b0ZpeGVkKDIpKTtcbiAgfVxuXG4gIGFwcGx5T25lVGltZUZlZSgpIHtcbiAgICBjb25zdCBmZWVWYWx1ZSA9IHRoaXMub25lVGltZUZlZUZvcm0uZ2V0KCdvbmVUaW1lRmVlJyk/LnZhbHVlO1xuICAgIGlmICghZmVlVmFsdWUpIHJldHVybjtcbiAgICBjb25zdCByZXF1ZXN0RGF0YSA9IHtcbiAgICAgIG9uZVRpbWVGZWU6IGZlZVZhbHVlLFxuICAgIH07XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2Uub25lVGltZUZlZShyZXF1ZXN0RGF0YSwgdGhpcy5pbnZvaWNlRGF0YS5pbnZvaWNlKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICBpZiAocmVzICYmIHJlcy5jb2RlID09IDIwMCkge1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdPbmUgdGltZSBmZWUgYXBwbGllZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdmZWVBcHBsaWVkJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBhcHBseSBvbmUgdGltZSBmZWUnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufSIsIjxkaXYgY2xhc3M9XCJtb2RhbC1jb250ZW50XCI+XG4gICAgPGRpdiBjbGFzcz1cInAtNSBweC02IHBiLTBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkaW5nIG10LTJcIj57eyBtb2RlID09PSAnZWRpdCcgPyAnSW52b2ljZScgOiAobW9kZSA9PT0gJ2VzdGltYXRlJyA/ICdHZW5lcmF0ZSBFc3RpbWF0ZScgOiAobW9kZSA9PT0gJ2VkaXRFc3RpbWF0ZScgPyAnRWRpdCBFc3RpbWF0ZScgOiAnQ3JlYXRlIEludm9pY2UnKSkgfX1cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1vZGUgPT09ICdlZGl0J1wiIGNsYXNzPVwiaW52b2ljZS1udW1iZXJcIj57eyBpbnZvaWNlRGF0YT8uaW52b2ljZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1vZGUgPT09ICdlZGl0RXN0aW1hdGUnXCIgY2xhc3M9XCJpbnZvaWNlLW51bWJlclwiPnt7IGludm9pY2VEYXRhPy5lc3RpbWF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCI+PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gVGFicyAob25seSBpbiBlZGl0IG1vZGUpIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJhciBtdC0zXCIgKm5nSWY9XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJ0YWItYnRuXCIgW25nQ2xhc3NdPVwiYWN0aXZlVGFiID09PSAnZWRpdCcgPyAndGFiLWFjdGl2ZScgOiAnJ1wiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInNldFRhYignZWRpdCcpXCI+RWRpdCBJbnZvaWNlPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWJ0blwiIFtuZ0NsYXNzXT1cImFjdGl2ZVRhYiA9PT0gJ2NyZWRpdE5vdGUnID8gJ3RhYi1hY3RpdmUnIDogJydcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZXRUYWIoJ2NyZWRpdE5vdGUnKVwiPkNyZWRpdCBOb3RlPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWJ0blwiIFtuZ0NsYXNzXT1cImFjdGl2ZVRhYiA9PT0gJ29uZVRpbWVGZWUnID8gJ3RhYi1hY3RpdmUnIDogJydcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZXRUYWIoJ29uZVRpbWVGZWUnKVwiPk9uZSBUaW1lIEZlZTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09IEVESVQgSU5WT0lDRSBUQUIgPT09PT09PT09PT09PT09PT09PT09PT09IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IG1iLTRcIiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2VkaXQnIHx8IG1vZGUgIT09ICdlZGl0J1wiPlxuICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImludm9pY2VGb3JtXCIgY2xhc3M9XCJmb3JtXCIgKG5nU3VibWl0KT1cIm9uU3VibWl0KClcIj5cblxuICAgICAgICAgICAgPCEtLSBDb21wYW55IERldGFpbHMgU2VjdGlvbiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZWN0aW9uLXRpdGxlIG1iLTNcIj5Db21wYW55IERldGFpbHM8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkNvbXBhbnkgTmFtZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJjb21wYW55TmFtZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdjb21wYW55TmFtZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnY29tcGFueU5hbWUnKVwiPkNvbXBhbnkgTmFtZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkdTVCBOdW1iZXI8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIENyZWF0ZSBtb2RlOiB0eXBpbmcvY2hhbmdpbmcgdGhlIEdTVElOIHJlLWRlcml2ZXMgdGhlIHRheCByb3dzLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiR1NUTnVtYmVyXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbcmVhZG9ubHldPVwibW9kZSA9PT0gJ2VkaXQnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCJvbkdzdE51bWJlcklucHV0KClcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Q29tcGFueSBBZGRyZXNzPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiY29tcGFueUFkZHJlc3NcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5QbGFjZSBvZiBTdXBwbHk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJQbGFjZU9mU3VwcGx5XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbcmVhZG9ubHldPVwibW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBCaWxsaW5nIEdyb3VwIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0lmPVwiYmlsbGluZ0dyb3Vwcy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+QmlsbGluZyBHcm91cCA8c3BhbiAqbmdJZj1cIm1vZGUgIT09ICdlZGl0J1wiIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgKm5nSWY9XCJtb2RlICE9PSAnZWRpdCdcIiBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZ3JvdXBJZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJjb250cm9sSW52YWxpZCgnZ3JvdXBJZCcpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Hcm91cENoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+U2VsZWN0IGJpbGxpbmcgZ3JvdXA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGcgb2YgYmlsbGluZ0dyb3Vwc1wiIFt2YWx1ZV09XCJnLl9pZFwiPnt7IGcuZ3JvdXBOYW1lIH19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJtb2RlID09PSAnZWRpdCdcIiB0eXBlPVwidGV4dFwiIFt2YWx1ZV09XCJpbnZvaWNlRm9ybS5nZXQoJ2dyb3VwTmFtZScpPy52YWx1ZSB8fCAnRGVmYXVsdCBHcm91cCdcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdncm91cElkJylcIj5CaWxsaW5nIEdyb3VwIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+R3JvdXAgTmFtZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cImdyb3VwTmFtZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gSW52b2ljZSBEZXRhaWxzIFNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi10aXRsZSBtYi0zIG10LTJcIj5JbnZvaWNlIERldGFpbHM8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkJpbGxpbmcgRGF0ZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImRhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJiaWxsaW5nRGF0ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdiaWxsaW5nRGF0ZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwibW9kZSA9PT0gJ2NyZWF0ZScgJiYgY29tcHV0ZUR1ZURhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdiaWxsaW5nRGF0ZScpXCI+QmlsbGluZyBEYXRlIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBDcmVhdGUgbW9kZTogY2hvb3NlIGEgcGF5bWVudCB0ZXJtIChkYXlzKTsgdGhlIGR1ZSBkYXRlIGlzXG4gICAgICAgICAgICAgICAgICAgICBkZXJpdmVkIGZyb20gQmlsbGluZyBEYXRlICsgdGVybSBhbmQgc2hvd24gcmVhZC1vbmx5LiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCIgKm5nSWY9XCJtb2RlID09PSAnY3JlYXRlJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UGF5bWVudCBUZXJtIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cInBheW1lbnRUZXJtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwiY29tcHV0ZUR1ZURhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCIzMFwiPjMwIGRheXM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiNjBcIj42MCBkYXlzPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cIjkwXCI+OTAgZGF5czwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCIxMjBcIj4xMjAgZGF5czwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGwgbXQtMVwiPkR1ZSBEYXRlOiB7eyBpbnZvaWNlRm9ybS5nZXQoJ2R1ZURhdGUnKT8udmFsdWUgfHwgJy0nIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBFZGl0IC8gZXN0aW1hdGUgbW9kZXMga2VlcCB0aGUgZWRpdGFibGUgRHVlIERhdGUgZmllbGQuIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIiAqbmdJZj1cIm1vZGUgIT09ICdjcmVhdGUnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5EdWUgRGF0ZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImRhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJkdWVEYXRlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiY29udHJvbEludmFsaWQoJ2R1ZURhdGUnKVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImNvbnRyb2xJbnZhbGlkKCdkdWVEYXRlJylcIj5EdWUgRGF0ZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkN1cnJlbmN5IDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cImN1cnJlbmN5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25DdXJyZW5jeUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdjdXJyZW5jeScpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjIG9mIGN1cnJlbmN5T3B0aW9uc1wiIFt2YWx1ZV09XCJjXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgY3VycmVuY3lMYWJlbHNbY10gfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnY3VycmVuY3knKVwiPkN1cnJlbmN5IGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Tm8uIG9mIFN0b3JlczwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwic3RvcmVzXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8IS0tIFB1cmNoYXNlIE9yZGVyIG1hcHBpbmcgKG9wdGlvbmFsKS4gTWFwcGluZyBkZWR1Y3RzIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgIGludm9pY2UncyBhbW91bnQgZnJvbSB0aGUgc2VsZWN0ZWQgUE8ncyByZW1haW5pbmcgYmFsYW5jZS5cbiAgICAgICAgICAgICAgICAgICAgIEhpZGRlbiBmb3IgZHJhZnQgaW52b2ljZXMgKHRlbXBvcmFyeSBEUkFGVC0gbnVtYmVyLCBvciBub1xuICAgICAgICAgICAgICAgICAgICAgbnVtYmVyIHlldCBpbiBjcmVhdGUgbW9kZSkg4oCUIGEgUE8gY2FuIG9ubHkgYmUgYXR0YWNoZWQgb25jZVxuICAgICAgICAgICAgICAgICAgICAgdGhlIHJlYWwgaW52b2ljZSBudW1iZXIgaXMgbWludGVkIGF0IGZpbmFuY2UgYXBwcm92YWwuIC0tPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJtb2RlICE9PSAnZXN0aW1hdGUnICYmIG1vZGUgIT09ICdlZGl0RXN0aW1hdGUnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIiAqbmdJZj1cIiFpc0RyYWZ0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UHVyY2hhc2UgT3JkZXI8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwicHVyY2hhc2VPcmRlck51bWJlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5Ob25lPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgcG8gb2YgcHVyY2hhc2VPcmRlcnNcIiBbdmFsdWVdPVwicG8ucHVyY2hhc2VPcmRlck51bWJlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBwby5wdXJjaGFzZU9yZGVyTnVtYmVyIH19ICh7eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19e3sgcG8ucmVtYWluaW5nQW1vdW50IHwgbnVtYmVyOicxLjAtMCc6J2VuLUlOJyB9fSBsZWZ0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCIgKm5nSWY9XCJpc0RyYWZ0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UHVyY2hhc2UgT3JkZXI8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQdXJjaGFzZSBPcmRlciBjYW4gYmUgYXR0YWNoZWQgYWZ0ZXIgZmluYW5jZSBhcHByb3ZhbCAob25jZSB0aGUgaW52b2ljZSBudW1iZXIgaXMgZmluYWxpc2VkKS5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEFkdmFuY2UgSW52b2ljZSAoY3JlYXRlIG9ubHkpOiBiaWxsIHNldmVyYWwgZnV0dXJlIG1vbnRocyB1cGZyb250LlxuICAgICAgICAgICAgICAgICBFYWNoIG1vbnRoIGJlY29tZXMgaXRzIG93biBsaW5lIGl0ZW0gc2VydmVyLXNpZGUuIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0lmPVwibW9kZSA9PT0gJ2NyZWF0ZSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTEgZC1ibG9ja1wiPkFkdmFuY2UgSW52b2ljZTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrIGZvcm0tc3dpdGNoIG10LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImFkdmFuY2VJbnZvaWNlQ3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJhZHZhbmNlSW52b2ljZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIGZvcj1cImFkdmFuY2VJbnZvaWNlQ3JlYXRlXCI+QmlsbCBmdXR1cmUgbW9udGhzIHVwZnJvbnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCIgKm5nSWY9XCJpbnZvaWNlRm9ybS5nZXQoJ2FkdmFuY2VJbnZvaWNlJyk/LnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5BZHZhbmNlIGZyZXF1ZW5jeTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cImFkdmFuY2VQZXJpb2RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IG9wdCBvZiBhZHZhbmNlUGVyaW9kT3B0aW9uc1wiIFt2YWx1ZV09XCJvcHQudmFsdWVcIj57eyBvcHQubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuXG4gICAgICAgICAgICA8IS0tIFByb2R1Y3RzIFNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi10aXRsZSBtYi0zIG10LTJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Qcm9kdWN0czwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiAoY2xpY2spPVwiYWRkUHJvZHVjdCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBBZGQgUHJvZHVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImFkZEN1c3RvbVByb2R1Y3QoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQWRkIEN1c3RvbSBQcm9kdWN0XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBmb3JtQXJyYXlOYW1lPVwicHJvZHVjdHNcIj5cbiAgICAgICAgICAgICAgICA8IS0tIFJvd3MgY2FuIGJlIHJlb3JkZXJlZCBieSBkcmFnZ2luZyB0aGUg4ouu4ouuIGhhbmRsZSBvbnRvIGFub3RoZXIgcm93XG4gICAgICAgICAgICAgICAgICAgICAobmF0aXZlIEhUTUw1IGRyYWcgJiBkcm9wIOKAlCBubyBDREsgZGVwZW5kZW5jeSkuIFRoZSBGb3JtQXJyYXkgaXNcbiAgICAgICAgICAgICAgICAgICAgIHJlLW9yZGVyZWQsIHNvIG51bWJlcmluZywgdG90YWxzIGFuZCB0aGUgc2F2ZWQgcHJvZHVjdHMgZm9sbG93LiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBwcm9kdWN0IG9mIHByb2R1Y3RzLmNvbnRyb2xzOyBsZXQgaSA9IGluZGV4XCIgW2Zvcm1Hcm91cE5hbWVdPVwiaVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicHJvZHVjdC1yb3cgbWItMyBwLTNcIiBkYXRhLXByb2R1Y3Qtcm93XG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kcmFnLW92ZXJdPVwiZHJhZ092ZXJJbmRleCA9PT0gaSAmJiBkcmFnSW5kZXggIT09IG51bGwgJiYgZHJhZ0luZGV4ICE9PSBpXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmRyYWdnaW5nXT1cImRyYWdJbmRleCA9PT0gaVwiXG4gICAgICAgICAgICAgICAgICAgIChkcmFnb3Zlcik9XCJvblJvd0RyYWdPdmVyKCRldmVudCwgaSlcIiAoZHJhZ2xlYXZlKT1cIm9uUm93RHJhZ0xlYXZlKGkpXCJcbiAgICAgICAgICAgICAgICAgICAgKGRyb3ApPVwib25Sb3dEcm9wKCRldmVudCwgaSlcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkcmFnLWhhbmRsZSBtZS0yXCIgZHJhZ2dhYmxlPVwidHJ1ZVwiIHRpdGxlPVwiRHJhZyB0byByZW9yZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGRyYWdzdGFydCk9XCJvblJvd0RyYWdTdGFydCgkZXZlbnQsIGkpXCIgKGRyYWdlbmQpPVwib25Sb3dEcmFnRW5kKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInByb2R1Y3RzLmxlbmd0aCA+IDFcIj4mIzg5NDI7JiM4OTQyOzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByb2R1Y3QtbGFiZWxcIj5Qcm9kdWN0IHt7IGkgKyAxIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLWRhbmdlclwiIChjbGljayk9XCJyZW1vdmVQcm9kdWN0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInByb2R1Y3RzLmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZW1vdmVcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC00IGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Qcm9kdWN0IE5hbWUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEJhc2UtcHJpY2luZyBkcm9wZG93biAod2l0aCBhIFwiKyBDdXN0b20gcHJvZHVjdFwiIGNob2ljZSkgd2hlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZHVjdHMgZXhpc3QgYW5kIHRoaXMgcm93IGlzbid0IGN1c3RvbTsgb3RoZXJ3aXNlIGEgZnJlZS10ZXh0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lIGlucHV0IGZvciBhIGN1c3RvbSBwcm9kdWN0LiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0ICpuZ0lmPVwiYXZhaWxhYmxlUHJvZHVjdHMubGVuZ3RoID4gMCAmJiAhcHJvZHVjdC5nZXQoJ2lzQ3VzdG9tJyk/LnZhbHVlXCIgZm9ybUNvbnRyb2xOYW1lPVwicHJvZHVjdE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tc2VsZWN0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwib25Qcm9kdWN0Q2hhbmdlKGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5TZWxlY3QgcHJvZHVjdDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBwIG9mIGF2YWlsYWJsZVByb2R1Y3RzXCIgW3ZhbHVlXT1cInAucHJvZHVjdE5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGZvcm1hdFByb2R1Y3ROYW1lKHAucHJvZHVjdE5hbWUpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiX19jdXN0b21fX1wiPisgQ3VzdG9tIHByb2R1Y3Q8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgKm5nSWY9XCJhdmFpbGFibGVQcm9kdWN0cy5sZW5ndGggPT09IDAgfHwgcHJvZHVjdC5nZXQoJ2lzQ3VzdG9tJyk/LnZhbHVlXCIgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJwcm9kdWN0TmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBDdXN0b20gU2VydmljZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJvZHVjdE5hbWUnKVwiPlByb2R1Y3QgTmFtZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkRlc2NyaXB0aW9uPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJkZXNjcmlwdGlvblwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIEN1c3RvbWVyIEZvb3RmYWxsIEFuYWx5dGljc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTQgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPk1vbnRoPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJtb250aFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJlLmcuIE1hciAyMDI2XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+SFNOL1NBQzwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiSHNuTnVtYmVyXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5RdWFudGl0eTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBmb3JtQ29udHJvbE5hbWU9XCJzdG9yZUNvdW50XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwicmVjYWxjdWxhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlJhdGUvUHJpY2UgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFJhdGUvUHJpY2UgYWNjZXB0cyBhdCBtb3N0IDIgZGVjaW1hbHMgKHBhaXNlKTsgZXh0cmEgZGlnaXRzIGFyZSB0cmltbWVkIGFzIHR5cGVkLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGZvcm1Db250cm9sTmFtZT1cInByaWNlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBzdGVwPVwiMC4wMVwiIG1pbj1cIjBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJhcnJheUNvbnRyb2xJbnZhbGlkKCdwcm9kdWN0cycsIGksICdwcmljZScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uUHJpY2VJbnB1dChpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgncHJvZHVjdHMnLCBpLCAncHJpY2UnKVwiPlJhdGUvUHJpY2UgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5BbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwiYW1vdW50XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5QZXJpb2Q8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cInBlcmlvZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwibW9udGhseVwiPk1vbnRobHk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInF1YXJ0ZXJseVwiPlF1YXJ0ZXJseTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiaGFsZnllYXJseVwiPkhhbGYteWVhcmx5PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJ5ZWFybHlcIj5ZZWFybHk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIFRheCBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tdGl0bGUgbWItMyBtdC0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+VGF4PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIFRheCBpcyBERVJJVkVEIGZyb20gdGhlIEdTVCBudW1iZXIgKEdTVElOICczM+KApicg4oaSIENHU1QgOSUgKyBTR1NUIDklLFxuICAgICAgICAgICAgICAgICAgICAgICAgIGFueSBvdGhlciBHU1RJTiDihpIgSUdTVCAxOCUsIG5vbmUg4oaSIG5vIHRheCksIHNvIHRoZXJlIGlzIG5vIG1hbnVhbFxuICAgICAgICAgICAgICAgICAgICAgICAgIFwiQWRkIFRheFwiIGFuZCB0aGUgcm93cyBhcmUgcmVhZC1vbmx5OyBhIHRheCBsaW5lIGNhbiBzdGlsbCBiZVxuICAgICAgICAgICAgICAgICAgICAgICAgIFJFTU9WRUQgdmlhIGVhY2ggcm93J3MgUmVtb3ZlIGJ1dHRvbi4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiPkNhbGN1bGF0ZWQgZnJvbSBHU1QgTnVtYmVyPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cInRheFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHQgb2YgdGF4QXJyYXkuY29udHJvbHM7IGxldCBqID0gaW5kZXhcIiBbZm9ybUdyb3VwTmFtZV09XCJqXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJ0YXgtcm93IG1iLTMgcC0zXCIgZGF0YS10YXgtcm93PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlciBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInByb2R1Y3QtbGFiZWxcIj5UYXgge3sgaiArIDEgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtZGFuZ2VyXCIgKGNsaWNrKT1cInJlbW92ZVRheChqKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlbW92ZVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlRheCBUeXBlIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBUaGUgJ3R5cGUnIGNvbnRyb2wgaXMgY3JlYXRlZCBkaXNhYmxlZCAoZGVyaXZlZCBmcm9tIHRoZSBHU1RJTik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgZm9ybSBwb3N0cyB2aWEgZ2V0UmF3VmFsdWUoKSBzbyBpdCBzdGlsbCByZWFjaGVzIHRoZSBwYXlsb2FkLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJ0eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvblRheFR5cGVDaGFuZ2UoailcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJhcnJheUNvbnRyb2xJbnZhbGlkKCd0YXgnLCBqLCAndHlwZScpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHR0IG9mIHRheFR5cGVzXCIgW3ZhbHVlXT1cInR0XCI+e3sgdHQgfX08L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImFycmF5Q29udHJvbEludmFsaWQoJ3RheCcsIGosICd0eXBlJylcIj5UYXggVHlwZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlRheCAlIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBmb3JtQ29udHJvbE5hbWU9XCJ2YWx1ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZG9ubHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiYXJyYXlDb250cm9sSW52YWxpZCgndGF4JywgaiwgJ3ZhbHVlJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwicmVjYWxjdWxhdGUoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgndGF4JywgaiwgJ3ZhbHVlJylcIj5UYXggJSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlRheCBBbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cInRheEFtb3VudFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+Q3VycmVuY3kgU3ltYm9sPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJjdXJyZW5jeVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBTdW1tYXJ5IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktc2VjdGlvbiBwLTMgbXQtM1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5TdWJ0b3RhbDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fSB7eyBnZXRTdWJ0b3RhbCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIG1iLTJcIiAqbmdJZj1cImdldEFwcGxpZWREaXNjb3VudCgpID4gMFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5EaXNjb3VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+LSB7eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19IHt7IGdldEFwcGxpZWREaXNjb3VudCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIG1iLTJcIiAqbmdJZj1cImdldFRvdGFsVGF4KCkgPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPlRvdGFsIFRheDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlXCI+e3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fSB7eyBnZXRUb3RhbFRheCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHN1bW1hcnktdG90YWxcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LWxhYmVsLWJvbGRcIj5Ub3RhbCBBbW91bnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS12YWx1ZS1ib2xkXCI+e3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fSB7eyBnZXRUb3RhbEFtb3VudCgpIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBBY3Rpb25zIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBtdC00XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLW91dGxpbmUgYnRuIGNhbmNlbCBtZS00IHctNTBcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBbZGlzYWJsZWRdPVwic2F2aW5nXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgcHgtNCB3LTUwXCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTogbm93cmFwO1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzYXZpbmdcIiBjbGFzcz1cInN1Ym1pdFwiPnt7IG1vZGUgPT09ICdlZGl0JyA/ICdVcGRhdGUgSW52b2ljZScgOiAobW9kZSA9PT0gJ2VzdGltYXRlJyA/ICdHZW5lcmF0ZSBFc3RpbWF0ZScgOiAobW9kZSA9PT0gJ2VkaXRFc3RpbWF0ZScgPyAnVXBkYXRlIEVzdGltYXRlJyA6ICdDcmVhdGUgSW52b2ljZScpKVxuICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic2F2aW5nXCIgY2xhc3M9XCJzdWJtaXRcIj5TYXZpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT0gQ1JFRElUIE5PVEUgVEFCID09PT09PT09PT09PT09PT09PT09PT09PSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keSBtYi00XCIgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdjcmVkaXROb3RlJyAmJiBtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJjcmVkaXROb3RlRm9ybVwiIGNsYXNzPVwiZm9ybVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnR0ZXh0IG1iLTNcIj5cbiAgICAgICAgICAgICAgICBBcHBseSBhIGNyZWRpdCBub3RlIC8gZGlzY291bnQgdG8gdGhpcyBpbnZvaWNlLlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5JbnZvaWNlIElEPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbdmFsdWVdPVwiaW52b2ljZURhdGE/Lmludm9pY2VcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPlRvdGFsIEFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGZvcm1Db250cm9sTmFtZT1cImFtb3VudFwiIHR5cGU9XCJ0ZXh0XCIgcmVhZG9ubHkgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCI+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgbXQtMlwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHktMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPkRpc2NvdW50IEFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRvbGxhci1zaWduXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZGlzY291bnRBbW91bnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwib21pdFNwZWNpYWxDaGFyRGVjaW1hbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJ2Vycm9yaW5wdXQnIDogJydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gW25nQ2xhc3NdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJ3RleHQtZGFuZ2VyJyA6ICdjb250ZW50dGV4dCdcIiBjbGFzcz1cInNtYWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBDcmVkaXQgdmFsdWUgZGVkdWN0ZWQgZnJvbSB0aGUgaW52b2ljZVxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+UmV2aXNlZCBBbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cInJldmlzZWRBbW91bnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwib21pdFNwZWNpYWxDaGFyRGVjaW1hbCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50ID8gJ2Vycm9yaW5wdXQnIDogJydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWljb25cIiAqbmdJZj1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGw9XCJub25lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZyBjbGlwLXBhdGg9XCJ1cmwoI2NsaXBfY25fZXJyKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQ9XCJNNy45OTk2NyA1LjMzMzAxVjcuOTk5NjdNNy45OTk2NyAxMC42NjYzSDguMDA2MzRNMTQuNjY2MyA3Ljk5OTY3QzE0LjY2NjMgMTEuNjgxNiAxMS42ODE2IDE0LjY2NjMgNy45OTk2NyAxNC42NjYzQzQuMzE3NzggMTQuNjY2MyAxLjMzMzAxIDExLjY4MTYgMS4zMzMwMSA3Ljk5OTY3QzEuMzMzMDEgNC4zMTc3OCA0LjMxNzc4IDEuMzMzMDEgNy45OTk2NyAxLjMzMzAxQzExLjY4MTYgMS4zMzMwMSAxNC42NjYzIDQuMzE3NzggMTQuNjY2MyA3Ljk5OTY3WlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZT1cIiNGMDQ0MzhcIiBzdHJva2Utd2lkdGg9XCIxLjMzMzMzXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkZWZzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjbGlwUGF0aCBpZD1cImNsaXBfY25fZXJyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxyZWN0IHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIGZpbGw9XCJ3aGl0ZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9jbGlwUGF0aD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGVmcz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAndGV4dC1kYW5nZXInIDogJ2NvbnRlbnR0ZXh0J1wiIGNsYXNzPVwic21hbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEVudGVyIGEgdmFsaWQgcmV2aXNlZCBhbW91bnRcbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggbXQtNVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhY3RpdmVNb2RhbC5kaXNtaXNzKClcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1vdXRsaW5lIGJ0biBjYW5jZWwgbWUtNCB3LTUwXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50IHx8IHNhdmluZ1wiIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYXBwbHlDcmVkaXROb3RlKClcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBweC00IHctNTBcIiBzdHlsZT1cIndoaXRlLXNwYWNlOiBub3dyYXA7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIXNhdmluZ1wiPkFwcGx5IENyZWRpdCBOb3RlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInNhdmluZ1wiPkFwcGx5aW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9ybT5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gPT09PT09PT09PT09PT09PT09PT09PT09IE9ORSBUSU1FIEZFRSBUQUIgPT09PT09PT09PT09PT09PT09PT09PT09IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IG1iLTRcIiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ29uZVRpbWVGZWUnICYmIG1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cIm9uZVRpbWVGZWVGb3JtXCIgY2xhc3M9XCJmb3JtXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudHRleHQgbWItM1wiPlxuICAgICAgICAgICAgICAgIEFkZCBhIG9uZS10aW1lIGZlZSAoZS5nLiBpbnN0YWxsYXRpb24pIHRvIHRoaXMgaW52b2ljZS5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcHktMlwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+SW52b2ljZSBJRDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3ZhbHVlXT1cImludm9pY2VEYXRhPy5pbnZvaWNlXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5DdXJyZW50IEludm9pY2UgQW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRvbGxhci1zaWduXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgZm9ybUNvbnRyb2xOYW1lPVwiYW1vdW50XCIgdHlwZT1cInRleHRcIiByZWFkb25seSBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+T25lIFRpbWUgRmVlIChJbnN0YWxsYXRpb24pPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZG9sbGFyLXNpZ25cIj57eyBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJvbmVUaW1lRmVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGtleXByZXNzKT1cIm9taXRTcGVjaWFsQ2hhcigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgYW1vdW50LWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJFbnRlciBmZWUgYW1vdW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtc3RhY2sgbXQtMyBmZWUtc3VtbWFyeSBwLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1bW1hcnktbGFiZWxcIj5TZWxlY3RlZCBJbnZvaWNlIEFtb3VudCArIE9uZSBUaW1lIEZlZTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlLWJvbGRcIj57eyBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKSB9fXt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25lVGltZUZlZVRvdGFsIHwgbnVtYmVyOicxLjItMic6J2VuLUlOJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBtdC01XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLW91dGxpbmUgYnRuIGNhbmNlbCBtZS00IHctNTBcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCJzYXZpbmcgfHwgIW9uZVRpbWVGZWVGb3JtLmdldCgnb25lVGltZUZlZScpPy52YWx1ZVwiIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlPbmVUaW1lRmVlKClcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBweC00IHctNTBcIiBzdHlsZT1cIndoaXRlLXNwYWNlOiBub3dyYXA7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIXNhdmluZ1wiPkFwcGx5IEZlZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzYXZpbmdcIj5BcHBseWluZy4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvcm0+XG4gICAgPC9kaXY+XG48L2Rpdj4iXX0=
949
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1tYW5hZ2UtYmlsbGluZy9lZGl0LWludm9pY2UvZWRpdC1pbnZvaWNlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQXFCLEtBQUssRUFBaUMsTUFBTSxlQUFlLENBQUM7QUFFbkcsT0FBTyxFQUFxQyxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUcxQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQzs7Ozs7OztBQU90RyxNQUFNLE9BQU8sb0JBQW9CO0lBb0R0QjtJQUNDO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQXpERCxXQUFXLENBQU07SUFDMUIsMEVBQTBFO0lBQzFFLDhEQUE4RDtJQUNyRCxJQUFJLEdBQW9ELE1BQU0sQ0FBQztJQUMvRCxRQUFRLEdBQVcsRUFBRSxDQUFDO0lBQ3RCLGFBQWEsR0FBVSxFQUFFLENBQUM7SUFFbkMsV0FBVyxDQUFhO0lBQ1AsUUFBUSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7SUFDMUMsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUV4Qix1Q0FBdUM7SUFDdkMsU0FBUyxHQUFXLE1BQU0sQ0FBQztJQUUzQixRQUFRLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFF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QUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUM3RyxJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDakIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7Z0JBQ3BCLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxFQUFFO29CQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO29CQUNoRSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztpQkFDdEM7WUFDSCxDQUFDO1lBQ0QsS0FBSyxFQUFFLEdBQUcsRUFBRTtnQkFDVixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztnQkFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsOEJBQThCLENBQUMsQ0FBQztZQUMzRCxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzt3R0FwOUJVLG9CQUFvQjs0RkFBcEIsb0JBQW9CLG9LQ2JqQyx5ditCQWdmTTs7NEZEbmVPLG9CQUFvQjtrQkFMaEMsU0FBUzsrQkFDRSxrQkFBa0I7cVBBS25CLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0csSUFBSTtzQkFBWixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBPbkRlc3Ryb3ksIElucHV0LCBDaGFuZ2VEZXRlY3RvclJlZiwgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdiQWN0aXZlTW9kYWwsIE5nYk1vZGFsIH0gZnJvbSAnQG5nLWJvb3RzdHJhcC9uZy1ib290c3RyYXAnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCwgRm9ybUFycmF5LCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBCaWxsaW5nU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2JpbGxpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktc2hhcmVkJztcbmltcG9ydCB7IFJlcXVlc3RDb25maXJtYXRpb25Db21wb25lbnQgfSBmcm9tICcuLi9yZXF1ZXN0LWNvbmZpcm1hdGlvbi9yZXF1ZXN0LWNvbmZpcm1hdGlvbi5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItZWRpdC1pbnZvaWNlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2VkaXQtaW52b2ljZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9lZGl0LWludm9pY2UuY29tcG9uZW50LnNjc3MnXG59KVxuZXhwb3J0IGNsYXNzIEVkaXRJbnZvaWNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBpbnZvaWNlRGF0YTogYW55O1xuICAvLyAnZXN0aW1hdGUnIHJldXNlcyB0aGUgd2hvbGUgY3JlYXRlIGZvcm0gYnV0IHN1Ym1pdHMgdG8gdGhlIGVzdGltYXRlIEFQSVxuICAvLyBhbmQgd3JpdGVzIHRvIHRoZSBlc3RpbWF0ZXMgY29sbGVjdGlvbiBpbnN0ZWFkIG9mIGludm9pY2VzLlxuICBASW5wdXQoKSBtb2RlOiAnZWRpdCcgfCAnY3JlYXRlJyB8ICdlc3RpbWF0ZScgfCAnZWRpdEVzdGltYXRlJyA9ICdlZGl0JztcbiAgQElucHV0KCkgY2xpZW50SWQ6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBiaWxsaW5nR3JvdXBzOiBhbnlbXSA9IFtdO1xuXG4gIGludm9pY2VGb3JtITogRm9ybUdyb3VwO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcbiAgc2F2aW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLy8gVGFiczogZWRpdCB8IGNyZWRpdE5vdGUgfCBvbmVUaW1lRmVlXG4gIGFjdGl2ZVRhYjogc3RyaW5nID0gJ2VkaXQnO1xuXG4gIHRheFR5cGVzID0gWydJR1NUJywgJ0NHU1QnLCAnU0dTVCddO1xuICBjdXJyZW5jeU9wdGlvbnMgPSBbJ2lucicsICdkb2xsYXInLCAnc2luZ2Fwb3JlZG9sbGFyJywgJ2V1cm8nLCAnYWVkJ107XG4gIGN1cnJlbmN5TGFiZWxzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGlucjogJ0lOUiAo4oK5KScsXG4gICAgZG9sbGFyOiAnVVNEICgkKScsXG4gICAgc2luZ2Fwb3JlZG9sbGFyOiAnU0dEIChTJCknLFxuICAgIGV1cm86ICdFVVIgKOKCrCknLFxuICAgIGFlZDogJ0FFRCAoQUVEKSdcbiAgfTtcbiAgLy8gU3ltYm9sIG1hcCBtaXJyb3JzIHRoZSBiYWNrZW5kJ3MgQ1VSUkVOQ1lfU1lNQk9MUyBpbiB1dGlscy9jdXJyZW5jeS5qcyBzb1xuICAvLyB0aGUgbW9kYWwsIGludm9pY2UgbGlzdCwgY3JlZGl0LW5vdGUgYW5kIG9uZS10aW1lLWZlZSBwb3B1cHMgYWxsIHJlbmRlclxuICAvLyB0aGUgc2FtZSBzeW1ib2wgdGhlIFBERi9lbWFpbCB1c2VzLlxuICBwcml2YXRlIHJlYWRvbmx5IGN1cnJlbmN5U3ltYm9sczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBpbnI6ICfigrknLFxuICAgIGRvbGxhcjogJyQnLFxuICAgIHNpbmdhcG9yZWRvbGxhcjogJ1MkJyxcbiAgICBldXJvOiAn4oKsJyxcbiAgICBhZWQ6ICdBRUQnLFxuICB9O1xuICBzdGF0dXNPcHRpb25zID0gWydwZW5kaW5nJywgJ2FwcHJvdmVkJ107XG4gIHBheW1lbnRTdGF0dXNPcHRpb25zID0gWyd1bnBhaWQnLCAncGFpZCddO1xuXG4gIC8vIENyZWRpdCBOb3RlXG4gIGNyZWRpdE5vdGVGb3JtITogRm9ybUdyb3VwO1xuICBjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBQcm9kdWN0cyBmcm9tIGJhc2UgcHJpY2luZ1xuICBhdmFpbGFibGVQcm9kdWN0czogYW55W10gPSBbXTtcblxuICAvLyBPbmUgVGltZSBGZWVcbiAgb25lVGltZUZlZUZvcm0hOiBGb3JtR3JvdXA7XG4gIG9uZVRpbWVGZWVUb3RhbDogbnVtYmVyID0gMDtcblxuICAvLyBMYXN0LWtub3duIGN1cnJlbmN5LCBzbyBhIGNhbmNlbGxlZCBjdXJyZW5jeSBjaGFuZ2UgY2FuIHJldmVydCB0aGUgc2VsZWN0LlxuICBwcml2YXRlIHByZXZpb3VzQ3VycmVuY3k6IHN0cmluZyA9ICdpbnInO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBhY3RpdmVNb2RhbDogTmdiQWN0aXZlTW9kYWwsXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgcHJpdmF0ZSBiaWxsaW5nU2VydmljZTogQmlsbGluZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSB0b2FzdDogVG9hc3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgaG9zdFJlZjogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTmdiTW9kYWxcbiAgKSB7fVxuXG4gIC8vIFNjcm9sbCB0aGUgbmV3bHktYWRkZWQgcm93IChwcm9kdWN0cy90YXgpIGludG8gdmlldyBpbnNpZGUgdGhlIG1vZGFsIGJvZHkuXG4gIC8vIHNlbGVjdG9yIHRhcmdldHMgdGhlIGxhc3Qgcm93IG9mIHRoZSBnaXZlbiBzZWN0aW9uIGFmdGVyIGl0IHJlbmRlcnMuXG4gIHByaXZhdGUgc2Nyb2xsVG9MYXN0Um93KHNlY3Rpb25BdHRyOiBzdHJpbmcpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IGhvc3Q6IEhUTUxFbGVtZW50ID0gdGhpcy5ob3N0UmVmPy5uYXRpdmVFbGVtZW50O1xuICAgICAgY29uc3Qgcm93cyA9IGhvc3Q/LnF1ZXJ5U2VsZWN0b3JBbGwoYFske3NlY3Rpb25BdHRyfV1gKTtcbiAgICAgIGNvbnN0IGxhc3QgPSByb3dzICYmIHJvd3MubGVuZ3RoID8gKHJvd3Nbcm93cy5sZW5ndGggLSAxXSBhcyBIVE1MRWxlbWVudCkgOiBudWxsO1xuICAgICAgaWYgKGxhc3QpIHtcbiAgICAgICAgbGFzdC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgfVxuICAgIH0sIDEwMCk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRCaWxsaW5nR3JvdXBzKCk7XG4gICAgdGhpcy5sb2FkQ2xpZW50UHJvZHVjdHMoKTtcbiAgICB0aGlzLmxvYWRQdXJjaGFzZU9yZGVycygpO1xuICAgIHRoaXMuaW5pdEZvcm0oKTtcbiAgICB0aGlzLmluaXRDcmVkaXROb3RlRm9ybSgpO1xuICAgIHRoaXMuaW5pdE9uZVRpbWVGZWVGb3JtKCk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2VkaXQnICYmIHRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIHRoaXMucGF0Y2hGb3JtKCk7XG4gICAgICB0aGlzLnBhdGNoQ3JlZGl0Tm90ZURlZmF1bHRzKCk7XG4gICAgICB0aGlzLnBhdGNoT25lVGltZUZlZURlZmF1bHRzKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGUgPT09ICdlZGl0RXN0aW1hdGUnICYmIHRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIC8vIEVkaXRpbmcgYW4gZXN0aW1hdGUgcmV1c2VzIHRoZSBzYW1lIGZvcm0gZmllbGRzOyB0aGUgZXN0aW1hdGUgZG9jdW1lbnRcbiAgICAgIC8vIHNoYXJlcyB0aGUgaW52b2ljZSBzaGFwZSAoY29tcGFueU5hbWUsIHByb2R1Y3RzLCB0YXgsIHN0b3Jlcywg4oCmKS5cbiAgICAgIHRoaXMucGF0Y2hGb3JtKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGUgPT09ICdjcmVhdGUnKSB7XG4gICAgICAvLyBOZXcgaW52b2ljZTogZGVmYXVsdCB0aGUgYmlsbGluZyBkYXRlIHRvIHRvZGF5IGFuZCBkZXJpdmUgdGhlIGR1ZSBkYXRlXG4gICAgICAvLyBmcm9tIHRoZSBkZWZhdWx0IHBheW1lbnQgdGVybSAoMzAgZGF5cykuIFRoZSB1c2VyIGNoYW5nZXMgdGhlIHRlcm0gdmlhXG4gICAgICAvLyB0aGUgUGF5bWVudCBUZXJtIGRyb3Bkb3duLCBub3QgdGhlIGR1ZSBkYXRlIGRpcmVjdGx5LlxuICAgICAgdGhpcy5pbnZvaWNlRm9ybS5wYXRjaFZhbHVlKHsgYmlsbGluZ0RhdGU6IHRoaXMuZm9ybWF0RGF0ZUZvcklucHV0KG5ldyBEYXRlKCkpIH0pO1xuICAgICAgdGhpcy5jb21wdXRlRHVlRGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIGxvYWRDbGllbnRQcm9kdWN0cygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmIChjSWQpIHtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0Q2xpZW50QmFzZVByaWNpbmcoY0lkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgdGhpcy5hdmFpbGFibGVQcm9kdWN0cyA9IHJlcz8uZGF0YSB8fCBbXTtcbiAgICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmF2YWlsYWJsZVByb2R1Y3RzID0gW107XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG9uUHJvZHVjdENoYW5nZShpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgcHJvZHVjdEdyb3VwID0gdGhpcy5wcm9kdWN0cy5hdChpbmRleCk7XG4gICAgY29uc3Qgc2VsZWN0ZWROYW1lID0gcHJvZHVjdEdyb3VwLmdldCgncHJvZHVjdE5hbWUnKT8udmFsdWU7XG4gICAgLy8gXCIrIEN1c3RvbSBwcm9kdWN0XCIgcGlja2VkIGZyb20gdGhlIGRyb3Bkb3duIOKAlCBzd2l0Y2ggdGhpcyByb3cgdG8gZnJlZS10ZXh0XG4gICAgLy8gZW50cnkgKGN1c3RvbSBuYW1lICsgcHJpY2UpLCBjbGVhcmluZyB0aGUgYmFzZS1wcmljaW5nIHNlbGVjdGlvbi5cbiAgICBpZiAoc2VsZWN0ZWROYW1lID09PSAnX19jdXN0b21fXycpIHtcbiAgICAgIHByb2R1Y3RHcm91cC5wYXRjaFZhbHVlKHsgaXNDdXN0b206IHRydWUsIHByb2R1Y3ROYW1lOiAnJywgcHJpY2U6IDAsIGRlc2NyaXB0aW9uOiAnJyB9KTtcbiAgICAgIHRoaXMucmVjYWxjdWxhdGUoaW5kZXgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBwcm9kdWN0R3JvdXAuZ2V0KCdpc0N1c3RvbScpPy5zZXRWYWx1ZShmYWxzZSk7XG4gICAgY29uc3QgcHJvZHVjdCA9IHRoaXMuYXZhaWxhYmxlUHJvZHVjdHMuZmluZChwID0+IHAucHJvZHVjdE5hbWUgPT09IHNlbGVjdGVkTmFtZSk7XG4gICAgaWYgKHByb2R1Y3QpIHtcbiAgICAgIHByb2R1Y3RHcm91cC5nZXQoJ3ByaWNlJyk/LnNldFZhbHVlKHByb2R1Y3QucHJpY2UpO1xuICAgICAgLy8gU2V0IGRlc2NyaXB0aW9uIGJhc2VkIG9uIHByb2R1Y3QgbmFtZVxuICAgICAgY29uc3QgZGVzY3JpcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgICB0YW5nb1RyYWZmaWM6ICdDdXN0b21lciBGb290ZmFsbCBBbmFseXRpY3MnLFxuICAgICAgICB0YW5nb1pvbmU6ICdQcm9kdWN0IGNhdGVnb3J5L3NlY3Rpb24gYW5hbHl0aWNzJyxcbiAgICAgICAgdGFuZ29UcmF4OiAnQ3VzdG9tZXIgSm91cm5leSBBbmFseXRpY3MnLFxuICAgICAgICBwcmlvcml0eVN1cHBvcnQ6ICdQcmlvcml0eSBTdXBwb3J0JyxcbiAgICAgIH07XG4gICAgICBwcm9kdWN0R3JvdXAuZ2V0KCdkZXNjcmlwdGlvbicpPy5zZXRWYWx1ZShkZXNjcmlwdGlvbnNbc2VsZWN0ZWROYW1lXSB8fCAnJyk7XG4gICAgICB0aGlzLnJlY2FsY3VsYXRlKGluZGV4KTtcbiAgICB9XG4gIH1cblxuICAvLyBBZGQgYSBibGFuayBwcm9kdWN0IHJvdyBhbHJlYWR5IGluIGN1c3RvbSAoZnJlZS10ZXh0KSBtb2RlLCByZWdhcmRsZXNzIG9mXG4gIC8vIHdoZXRoZXIgYmFzZS1wcmljaW5nIHByb2R1Y3RzIGV4aXN0LlxuICBhZGRDdXN0b21Qcm9kdWN0KCkge1xuICAgIHRoaXMucHJvZHVjdHMucHVzaCh0aGlzLmNyZWF0ZVByb2R1Y3RHcm91cCh7IGlzQ3VzdG9tOiB0cnVlIH0pKTtcbiAgICB0aGlzLnNjcm9sbFRvTGFzdFJvdygnZGF0YS1wcm9kdWN0LXJvdycpO1xuICB9XG5cbiAgZm9ybWF0UHJvZHVjdE5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIW5hbWUpIHJldHVybiAnJztcbiAgICAvLyBDb252ZXJ0IGNhbWVsQ2FzZSB0byBUaXRsZSBDYXNlIHdpdGggc3BhY2VzOiB0YW5nb1RyYWZmaWMgLT4gVGFuZ28gVHJhZmZpY1xuICAgIHJldHVybiBuYW1lLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpXG4gICAgICAucmVwbGFjZSgvXi4vLCAoc3RyKSA9PiBzdHIudG9VcHBlckNhc2UoKSk7XG4gIH1cblxuICBsb2FkQmlsbGluZ0dyb3VwcygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmIChjSWQpIHtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0QWxsQmlsbGluZ0dyb3VwcyhjSWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLmJpbGxpbmdHcm91cHMgPSByZXM/LmRhdGEgfHwgW107XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5iaWxsaW5nR3JvdXBzID0gW107XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCh0cnVlKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBzZXRUYWIodGFiOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVRhYiA9IHRhYjtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PSBFRElUIElOVk9JQ0UgPT09PT09PT09PT09PT09PT09PT09XG5cbiAgaW5pdEZvcm0oKSB7XG4gICAgdGhpcy5pbnZvaWNlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgY29tcGFueU5hbWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBjb21wYW55QWRkcmVzczogWycnXSxcbiAgICAgIEdTVE51bWJlcjogWycnXSxcbiAgICAgIFBsYWNlT2ZTdXBwbHk6IFsnJ10sXG4gICAgICBncm91cE5hbWU6IFsnJ10sXG4gICAgICAvLyBCaWxsaW5nIEdyb3VwIGlzIHJlcXVpcmVkIHdoZW4gY3JlYXRpbmcg4oCUIHRoZSByZXN0IG9mIHRoZSBjb21wYW55XG4gICAgICAvLyBmaWVsZHMgYXV0by1maWxsIGZyb20gdGhlIHNlbGVjdGVkIGdyb3VwLlxuICAgICAgZ3JvdXBJZDogWycnLCB0aGlzLm1vZGUgIT09ICdlZGl0JyA/IFZhbGlkYXRvcnMucmVxdWlyZWQgOiBbXV0sXG4gICAgICBzdG9yZXM6IFswLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGJpbGxpbmdEYXRlOiBbJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgZHVlRGF0ZTogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIC8vIENyZWF0ZSBtb2RlOiBkdWUgZGF0ZSBpcyBkZXJpdmVkIGZyb20gYmlsbGluZ0RhdGUgKyBwYXltZW50VGVybSAoZGF5cyksXG4gICAgICAvLyBzbyB0aGUgdXNlciBwaWNrcyBhIHRlcm0gKDMwLzYwLzkwLzEyMCkgaW5zdGVhZCBvZiBhIGR1ZSBkYXRlLiBFZGl0IC9cbiAgICAgIC8vIGVzdGltYXRlIG1vZGVzIGtlZXAgdGhlIGVkaXRhYmxlIGR1ZURhdGUgZmllbGQgYW5kIGlnbm9yZSBwYXltZW50VGVybS5cbiAgICAgIHBheW1lbnRUZXJtOiBbMzBdLFxuICAgICAgY3VycmVuY3k6IFsnaW5yJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICBzdGF0dXM6IFsncGVuZGluZyddLFxuICAgICAgcGF5bWVudFN0YXR1czogWyd1bnBhaWQnXSxcbiAgICAgIC8vIEFkdmFuY2UgaW52b2ljZTogd2hlbiBvbiwgdGhlIGNob3NlbiBmcmVxdWVuY3kgYmlsbHMgc2V2ZXJhbCBmdXR1cmVcbiAgICAgIC8vIG1vbnRocyB1cGZyb250IChlYWNoIG1vbnRoIGJlY29tZXMgaXRzIG93biBsaW5lIGl0ZW0gc2VydmVyLXNpZGUpLlxuICAgICAgYWR2YW5jZUludm9pY2U6IFtmYWxzZV0sXG4gICAgICBhZHZhbmNlUGVyaW9kOiBbJ21vbnRobHknXSxcbiAgICAgIC8vIE9wdGlvbmFsOiBtYXAgdGhpcyBpbnZvaWNlIHRvIGEgcHVyY2hhc2Ugb3JkZXIgKHJlZHVjZXMgdGhlIFBPIGJhbGFuY2UpLlxuICAgICAgcHVyY2hhc2VPcmRlck51bWJlcjogWycnXSxcbiAgICAgIHByb2R1Y3RzOiB0aGlzLmZiLmFycmF5KFtdKSxcbiAgICAgIHRheDogdGhpcy5mYi5hcnJheShbXSksXG4gICAgfSk7XG4gIH1cblxuICAvLyBBIGRyYWZ0IGludm9pY2UgKHByZS1maW5hbmNlKSBoYXMgYSB0ZW1wb3JhcnkgRFJBRlQtIG51bWJlciBhbmQgY2Fubm90IGJlXG4gIC8vIG1hcHBlZCB0byBhIFB1cmNoYXNlIE9yZGVyIHVudGlsIHRoZSByZWFsIG51bWJlciBpcyBtaW50ZWQgYXQgZmluYW5jZVxuICAvLyBhcHByb3ZhbC4gQ3JlYXRlIG1vZGUgaGFzIG5vIGludm9pY2UgbnVtYmVyIHlldCBhdCBhbGwgKGJyYW5kLW5ldyBpbnZvaWNlKSxcbiAgLy8gc28gaXQgaXMgdHJlYXRlZCB0aGUgc2FtZSBhcyBhIGRyYWZ0IOKAlCB0aGUgUE8gcGlja2VyIHN0YXlzIGhpZGRlbiB1bnRpbFxuICAvLyB0aGVyZSBpcyBhIHJlYWwsIGVkaXRhYmxlIGludm9pY2Ugd2l0aCBhIGZpbmFsaXNlZCBudW1iZXIuXG4gIGdldCBpc0RyYWZ0KCk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm1vZGUgIT09ICdlZGl0Jykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IG51bSA9IHRoaXMuaW52b2ljZURhdGE/Lmludm9pY2UgfHwgJyc7XG4gICAgcmV0dXJuIHR5cGVvZiBudW0gPT09ICdzdHJpbmcnICYmIG51bS5zdGFydHNXaXRoKCdEUkFGVC0nKTtcbiAgfVxuXG4gIC8vIFB1cmNoYXNlIG9yZGVycyBhdmFpbGFibGUgZm9yIHRoaXMgY2xpZW50IChmb3IgdGhlIFBPIHBpY2tlcikuXG4gIHB1cmNoYXNlT3JkZXJzOiBhbnlbXSA9IFtdO1xuXG4gIGxvYWRQdXJjaGFzZU9yZGVycygpIHtcbiAgICBjb25zdCBjSWQgPSB0aGlzLmNsaWVudElkIHx8IHRoaXMuaW52b2ljZURhdGE/LmNsaWVudElkO1xuICAgIGlmICghY0lkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0UHVyY2hhc2VPcmRlcnMoY0lkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnB1cmNoYXNlT3JkZXJzID0gcmVzPy5kYXRhPy5wdXJjaGFzZU9yZGVycyB8fCBbXTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnB1cmNoYXNlT3JkZXJzID0gW107XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgYWR2YW5jZVBlcmlvZE9wdGlvbnMgPSBbXG4gICAgeyB2YWx1ZTogJ21vbnRobHknLCBsYWJlbDogJ01vbnRobHkgKG5leHQgbW9udGgpJyB9LFxuICAgIHsgdmFsdWU6ICdxdWFydGVybHknLCBsYWJlbDogJ1F1YXJ0ZXJseSAobmV4dCAzIG1vbnRocyknIH0sXG4gICAgeyB2YWx1ZTogJ2hhbGZ5ZWFybHknLCBsYWJlbDogJ0hhbGYteWVhcmx5IChuZXh0IDYgbW9udGhzKScgfSxcbiAgICB7IHZhbHVlOiAneWVhcmx5JywgbGFiZWw6ICdZZWFybHkgKG5leHQgMTIgbW9udGhzKScgfSxcbiAgXTtcblxuICAvLyBUZW1wbGF0ZSBoZWxwZXJzOiBzdXJmYWNlIFwidG91Y2hlZCAmJiBpbnZhbGlkXCIgc28gdGhlIEhUTUwgY2FuIGhpZ2hsaWdodFxuICAvLyB0aGUgZmllbGQgYW5kIHJlbmRlciBhbiBpbmxpbmUgZXJyb3IuIERlZmVuc2l2ZSBhZ2FpbnN0IHRoZSBmb3JtIG5vdCB5ZXRcbiAgLy8gYmVpbmcgaW5pdGlhbGlzZWQgZHVyaW5nIHRoZSBmaXJzdCBjaGFuZ2UtZGV0ZWN0aW9uIHBhc3MuXG4gIGNvbnRyb2xJbnZhbGlkKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmludm9pY2VGb3JtPy5nZXQobmFtZSk7XG4gICAgcmV0dXJuICEhY3RybCAmJiBjdHJsLnRvdWNoZWQgJiYgY3RybC5pbnZhbGlkO1xuICB9XG5cbiAgYXJyYXlDb250cm9sSW52YWxpZChhcnJheU5hbWU6ICdwcm9kdWN0cycgfCAndGF4JywgaW5kZXg6IG51bWJlciwgbmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5pbnZvaWNlRm9ybT8uZ2V0KGFycmF5TmFtZSkgYXMgRm9ybUFycmF5IHwgbnVsbDtcbiAgICBjb25zdCBjdHJsID0gYXJyPy5hdChpbmRleCk/LmdldChuYW1lKTtcbiAgICByZXR1cm4gISFjdHJsICYmIGN0cmwudG91Y2hlZCAmJiBjdHJsLmludmFsaWQ7XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbFRvRmlyc3RJbnZhbGlkKCk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIGZpcnN0IGludmFsaWQgY29udHJvbCBpbnNpZGUgdGhlIG1vZGFsIGFuZCBicmluZyBpdCBpbnRvIHZpZXcuXG4gICAgLy8gU2NvcGVkIHRvIC5tb2RhbC1jb250ZW50IHNvIHdlIGRvbid0IGdyYWIgZmllbGRzIGZyb20gb3RoZXIgbW9kYWxzIG9uXG4gICAgLy8gdGhlIHBhZ2UgaWYgYW55IGFyZSBvcGVuLlxuICAgIGNvbnN0IHJvb3QgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcubW9kYWwtY29udGVudCcpO1xuICAgIGNvbnN0IGZpcnN0ID0gcm9vdD8ucXVlcnlTZWxlY3RvcignLmlzLWludmFsaWQnKSBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKGZpcnN0KSB7XG4gICAgICBmaXJzdC5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICdjZW50ZXInIH0pO1xuICAgICAgaWYgKHR5cGVvZiBmaXJzdC5mb2N1cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmaXJzdC5mb2N1cyh7IHByZXZlbnRTY3JvbGw6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IHByb2R1Y3RzKCk6IEZvcm1BcnJheSB7XG4gICAgcmV0dXJuIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdwcm9kdWN0cycpIGFzIEZvcm1BcnJheTtcbiAgfVxuXG4gIGdldCB0YXhBcnJheSgpOiBGb3JtQXJyYXkge1xuICAgIHJldHVybiB0aGlzLmludm9pY2VGb3JtLmdldCgndGF4JykgYXMgRm9ybUFycmF5O1xuICB9XG5cbiAgY3JlYXRlUHJvZHVjdEdyb3VwKHByb2R1Y3Q/OiBhbnkpOiBGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIHByb2R1Y3ROYW1lOiBbcHJvZHVjdD8ucHJvZHVjdE5hbWUgfHwgJycsIFZhbGlkYXRvcnMucmVxdWlyZWRdLFxuICAgICAgLy8gV2hlbiB0cnVlLCB0aGUgbmFtZSBpcyBhIGZyZWUtdGV4dCBjdXN0b20gcHJvZHVjdCAobm90IGZyb20gdGhlIGNsaWVudCdzXG4gICAgICAvLyBiYXNlLXByaWNpbmcgbGlzdCkg4oCUIHRoZSB0ZW1wbGF0ZSBzaG93cyBhIHRleHQgaW5wdXQgaW5zdGVhZCBvZiB0aGVcbiAgICAgIC8vIHByb2R1Y3QgZHJvcGRvd24uXG4gICAgICBpc0N1c3RvbTogW3Byb2R1Y3Q/LmlzQ3VzdG9tIHx8IGZhbHNlXSxcbiAgICAgIGRlc2NyaXB0aW9uOiBbcHJvZHVjdD8uZGVzY3JpcHRpb24gfHwgJyddLFxuICAgICAgbW9udGg6IFtwcm9kdWN0Py5tb250aCB8fCAnJ10sXG4gICAgICBIc25OdW1iZXI6IFtwcm9kdWN0Py5Ic25OdW1iZXIgfHwgJzk5ODMxNCddLFxuICAgICAgc3RvcmVDb3VudDogW3Byb2R1Y3Q/LnN0b3JlQ291bnQgfHwgMCwgVmFsaWRhdG9ycy5taW4oMCldLFxuICAgICAgcHJpY2U6IFtwcm9kdWN0Py5wcmljZSB8fCAwLCBbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5taW4oMCldXSxcbiAgICAgIGFtb3VudDogW3Byb2R1Y3Q/LmFtb3VudCB8fCAwXSxcbiAgICAgIHBlcmlvZDogW3Byb2R1Y3Q/LnBlcmlvZCB8fCAnbW9udGhseSddLFxuICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlVGF4R3JvdXAodGF4PzogYW55KTogRm9ybUdyb3VwIHtcbiAgICByZXR1cm4gdGhpcy5mYi5ncm91cCh7XG4gICAgICAvLyBEaXNhYmxlZDogdGF4IHJvd3MgYXJlIGRlcml2ZWQgZnJvbSB0aGUgR1NUIG51bWJlciAoYXBwbHlHcm91cEdzdFRheCksXG4gICAgICAvLyBuZXZlciBoYW5kLWVkaXRlZC4gb25TdWJtaXQgcmVhZHMgZ2V0UmF3VmFsdWUoKSwgc28gdGhlIGRpc2FibGVkIGNvbnRyb2xcbiAgICAgIC8vIHN0aWxsIHJlYWNoZXMgdGhlIHBheWxvYWQuXG4gICAgICB0eXBlOiBbeyB2YWx1ZTogdGF4Py50eXBlIHx8ICdJR1NUJywgZGlzYWJsZWQ6IHRydWUgfSwgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICB2YWx1ZTogW3RheD8udmFsdWUgfHwgMTgsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1pbigwKSwgVmFsaWRhdG9ycy5tYXgoMTAwKV1dLFxuICAgICAgdGF4QW1vdW50OiBbdGF4Py50YXhBbW91bnQgfHwgJzAnXSxcbiAgICAgIC8vIERlZmF1bHQgdGhlIHRheC1yb3cgc3ltYm9sIHRvIHRoZSBpbnZvaWNlJ3MgY3VycmVuY3kgKHdhcyBoYXJkY29kZWRcbiAgICAgIC8vIHRvIOKCuSwgd2hpY2ggbGVha2VkIGludG8gdGhlIHNhdmVkIGRvYyBmb3Igbm9uLUlOUiBpbnZvaWNlcykuXG4gICAgICBjdXJyZW5jeTogW3RheD8uY3VycmVuY3kgfHwgdGhpcy5zeW1ib2xGb3IodGhpcy5pbnZvaWNlRm9ybT8uZ2V0KCdjdXJyZW5jeScpPy52YWx1ZSldLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW1ib2xGb3IoY29kZTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVuY3lTeW1ib2xzW2NvZGUgfHwgJyddIHx8ICckJztcbiAgfVxuXG4gIGFkZFByb2R1Y3QoKSB7XG4gICAgdGhpcy5wcm9kdWN0cy5wdXNoKHRoaXMuY3JlYXRlUHJvZHVjdEdyb3VwKCkpO1xuICAgIHRoaXMuc2Nyb2xsVG9MYXN0Um93KCdkYXRhLXByb2R1Y3Qtcm93Jyk7XG4gIH1cblxuICByZW1vdmVQcm9kdWN0KGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnByb2R1Y3RzLnJlbW92ZUF0KGluZGV4KTtcbiAgICB0aGlzLnJlY2FsY3VsYXRlKCk7XG4gIH1cblxuICBhZGRUYXgoKSB7XG4gICAgdGhpcy50YXhBcnJheS5wdXNoKHRoaXMuY3JlYXRlVGF4R3JvdXAoKSk7XG4gICAgLy8gQXBwbHkgdGhlIGRlZmF1bHQgKDE4JSBJR1NUKSBhZ2FpbnN0IHRoZSBjdXJyZW50IHN1YnRvdGFsIGltbWVkaWF0ZWx5LCBzb1xuICAgIC8vIHRoZSB0YXggYW1vdW50IHBvcHVsYXRlcyBvbiBhZGQgaW5zdGVhZCBvZiBzdGF5aW5nIDAgdW50aWwgZWRpdGVkLlxuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgICB0aGlzLnNjcm9sbFRvTGFzdFJvdygnZGF0YS10YXgtcm93Jyk7XG4gIH1cblxuICByZW1vdmVUYXgoaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMudGF4QXJyYXkucmVtb3ZlQXQoaW5kZXgpO1xuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgfVxuXG4gIC8vIERlZmF1bHQgcmF0ZSBwZXIgdGF4IHR5cGU6IElHU1QgaXMgYSBzaW5nbGUgMTglIGxpbmU7IENHU1QvU0dTVCBhcmUgdGhlXG4gIC8vIHNwbGl0IDklICsgOSUgaGFsdmVzLiBDaGFuZ2luZyB0aGUgdHlwZSByZXNldHMgdGhlICUgdG8gaXRzIGRlZmF1bHQgYW5kXG4gIC8vIHJlY29tcHV0ZXMgdGhlIGFtb3VudC5cbiAgb25UYXhUeXBlQ2hhbmdlKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBncm91cCA9IHRoaXMudGF4QXJyYXkuYXQoaW5kZXgpO1xuICAgIGNvbnN0IHR5cGUgPSBncm91cD8uZ2V0KCd0eXBlJyk/LnZhbHVlO1xuICAgIGNvbnN0IGRlZmF1bHRSYXRlID0gdHlwZSA9PT0gJ0NHU1QnIHx8IHR5cGUgPT09ICdTR1NUJyA/IDkgOiAxODtcbiAgICBncm91cD8uZ2V0KCd2YWx1ZScpPy5zZXRWYWx1ZShkZWZhdWx0UmF0ZSk7XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSgpO1xuICB9XG5cbiAgcGF0Y2hGb3JtKCkge1xuICAgIGNvbnN0IGludiA9IHRoaXMuaW52b2ljZURhdGE7XG5cbiAgICB0aGlzLmludm9pY2VGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgY29tcGFueU5hbWU6IGludi5jb21wYW55TmFtZSB8fCAnJyxcbiAgICAgIGNvbXBhbnlBZGRyZXNzOiBpbnYuY29tcGFueUFkZHJlc3MgfHwgJycsXG4gICAgICBHU1ROdW1iZXI6IGludi5HU1ROdW1iZXIgfHwgJycsXG4gICAgICBQbGFjZU9mU3VwcGx5OiBpbnYuUGxhY2VPZlN1cHBseSB8fCAnJyxcbiAgICAgIGdyb3VwTmFtZTogaW52Lmdyb3VwTmFtZSB8fCAnJyxcbiAgICAgIGdyb3VwSWQ6IGludi5ncm91cElkIHx8ICcnLFxuICAgICAgc3RvcmVzOiBpbnYuc3RvcmVzIHx8IDAsXG4gICAgICBiaWxsaW5nRGF0ZTogdGhpcy5mb3JtYXREYXRlRm9ySW5wdXQoaW52LmJpbGxpbmdEYXRlKSxcbiAgICAgIGR1ZURhdGU6IHRoaXMuZm9ybWF0RGF0ZUZvcklucHV0KGludi5kdWVEYXRlKSxcbiAgICAgIGN1cnJlbmN5OiBpbnYuY3VycmVuY3kgfHwgJ2lucicsXG4gICAgICBzdGF0dXM6IGludi5zdGF0dXMgfHwgJ3BlbmRpbmcnLFxuICAgICAgcGF5bWVudFN0YXR1czogaW52LnBheW1lbnRTdGF0dXMgfHwgJ3VucGFpZCcsXG4gICAgICBwdXJjaGFzZU9yZGVyTnVtYmVyOiBpbnYucHVyY2hhc2VPcmRlck51bWJlciB8fCAnJyxcbiAgICB9KTtcbiAgICAvLyBUcmFjayB0aGUgbG9hZGVkIGN1cnJlbmN5IHNvIGEgY2FuY2VsbGVkIGNoYW5nZSBjYW4gcmV2ZXJ0IHRvIGl0LlxuICAgIHRoaXMucHJldmlvdXNDdXJyZW5jeSA9IGludi5jdXJyZW5jeSB8fCAnaW5yJztcblxuICAgIC8vIFBhdGNoIHByb2R1Y3RzXG4gICAgaWYgKGludi5wcm9kdWN0cz8ubGVuZ3RoKSB7XG4gICAgICBpbnYucHJvZHVjdHMuZm9yRWFjaCgocDogYW55KSA9PiB7XG4gICAgICAgIHRoaXMucHJvZHVjdHMucHVzaCh0aGlzLmNyZWF0ZVByb2R1Y3RHcm91cChwKSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGRQcm9kdWN0KCk7XG4gICAgfVxuXG4gICAgLy8gUGF0Y2ggdGF4LiBOb24tSU5SIGludm9pY2VzIChlLmcuIGRvbGxhciBjbGllbnRzKSBoYXZlIG5vIEdTVCwgYnV0IHRoZVxuICAgIC8vIGJhY2tlbmQgc3RpbGwgc3RvcmVzIGEgcGxhY2Vob2xkZXIgSUdTVCByb3cgd2l0aCBhIDAgYW1vdW50IOKAlCBza2lwIHRob3NlXG4gICAgLy8gc28gdGhlIHRheCBzZWN0aW9uIHN0YXJ0cyBlbXB0eS4gT25seSBsb2FkIHRheCByb3dzIHRoYXQgY2FycnkgYSByZWFsXG4gICAgLy8gKG5vbi16ZXJvKSBhbW91bnQuIFRoZSB1c2VyIGNhbiBzdGlsbCBhZGQgYSB0YXggd2l0aCB0aGUgXCJBZGQgVGF4XCIgYnV0dG9uLlxuICAgIGNvbnN0IHRheFJvd3MgPSAoaW52LnRheCB8fCBbXSkuZmlsdGVyKCh0OiBhbnkpID0+IE51bWJlcih0Py50YXhBbW91bnQpID4gMCk7XG4gICAgdGF4Um93cy5mb3JFYWNoKCh0OiBhbnkpID0+IHtcbiAgICAgIHRoaXMudGF4QXJyYXkucHVzaCh0aGlzLmNyZWF0ZVRheEdyb3VwKHQpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZvcm1hdERhdGVGb3JJbnB1dChkYXRlOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghZGF0ZSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShkYXRlPy4kZGF0ZSB8fCBkYXRlKTtcbiAgICBpZiAoaXNOYU4oZC5nZXRUaW1lKCkpKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGQudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xuICB9XG5cbiAgLy8gQ3JlYXRlIG1vZGUgb25seTogZGVyaXZlIGR1ZURhdGUgPSBiaWxsaW5nRGF0ZSArIHBheW1lbnRUZXJtIChkYXlzKS4gQ2FsbGVkXG4gIC8vIHdoZW5ldmVyIHRoZSBiaWxsaW5nIGRhdGUgb3IgdGhlIHBheW1lbnQgdGVybSBjaGFuZ2VzLiBOby1vcCBpZiB0aGUgYmlsbGluZ1xuICAvLyBkYXRlIGlzbid0IHNldCB5ZXQuXG4gIGNvbXB1dGVEdWVEYXRlKCk6IHZvaWQge1xuICAgIGNvbnN0IGJpbGxpbmcgPSB0aGlzLmludm9pY2VGb3JtLmdldCgnYmlsbGluZ0RhdGUnKT8udmFsdWU7XG4gICAgY29uc3QgdGVybSA9IE51bWJlcih0aGlzLmludm9pY2VGb3JtLmdldCgncGF5bWVudFRlcm0nKT8udmFsdWUpIHx8IDA7XG4gICAgaWYgKCFiaWxsaW5nKSB7IHJldHVybjsgfVxuICAgIGNvbnN0IGQgPSBuZXcgRGF0ZShiaWxsaW5nKTtcbiAgICBpZiAoaXNOYU4oZC5nZXRUaW1lKCkpKSB7IHJldHVybjsgfVxuICAgIGQuc2V0RGF0ZShkLmdldERhdGUoKSArIHRlcm0pO1xuICAgIHRoaXMuaW52b2ljZUZvcm0ucGF0Y2hWYWx1ZSh7IGR1ZURhdGU6IHRoaXMuZm9ybWF0RGF0ZUZvcklucHV0KGQpIH0sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgfVxuXG4gIC8vIENoYW5naW5nIGFuIGludm9pY2UncyBjdXJyZW5jeSBjb252ZXJ0cyBldmVyeSBwcm9kdWN0IHByaWNlIGZyb20gdGhlIG9sZFxuICAvLyBjdXJyZW5jeSB0byB0aGUgbmV3IG9uZSB2aWEgbGl2ZSBGWCByYXRlcy4gQSBjb25maXJtYXRpb24gaXMgc2hvd24gZmlyc3Q7XG4gIC8vIGNhbmNlbGxpbmcgcmV2ZXJ0cyB0aGUgY3VycmVuY3kgc2VsZWN0LiBPbmx5IGFjdHMgd2hlbiB0aGUgY3VycmVuY3kgYWN0dWFsbHlcbiAgLy8gY2hhbmdlZCB0byBhIGRpZmZlcmVudCBjb2RlLlxuICBvbkN1cnJlbmN5Q2hhbmdlKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBuZXdDdXJyZW5jeSA9IGV2ZW50Py50YXJnZXQ/LnZhbHVlO1xuICAgIGNvbnN0IG9sZEN1cnJlbmN5ID0gdGhpcy5wcmV2aW91c0N1cnJlbmN5O1xuICAgIGlmICghbmV3Q3VycmVuY3kgfHwgbmV3Q3VycmVuY3kgPT09IG9sZEN1cnJlbmN5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxhYmVsID0gKGM6IHN0cmluZykgPT4gdGhpcy5jdXJyZW5jeUxhYmVsc1tjXSB8fCBjO1xuICAgIGNvbnN0IG1vZGFsUmVmID0gdGhpcy5tb2RhbFNlcnZpY2Uub3BlbihSZXF1ZXN0Q29uZmlybWF0aW9uQ29tcG9uZW50LCB7XG4gICAgICBjZW50ZXJlZDogdHJ1ZSwgc2l6ZTogJ21kJywgc2Nyb2xsYWJsZTogdHJ1ZSxcbiAgICB9KTtcbiAgICBtb2RhbFJlZi5jb21wb25lbnRJbnN0YW5jZS50aXRsZSA9ICdDaGFuZ2UgaW52b2ljZSBjdXJyZW5jeT8nO1xuICAgIG1vZGFsUmVmLmNvbXBvbmVudEluc3RhbmNlLmRlc2NyaXB0aW9uID1cbiAgICAgIGBUaGlzIGludm9pY2Ugd2FzIGNyZWF0ZWQgaW4gJHtsYWJlbChvbGRDdXJyZW5jeSl9LiBTd2l0Y2hpbmcgdG8gJHtsYWJlbChuZXdDdXJyZW5jeSl9IHdpbGwgY29udmVydCBhbGwgcHJvZHVjdCBhbW91bnRzIHVzaW5nIHRvZGF5J3MgZXhjaGFuZ2UgcmF0ZS4gUmV2aWV3IHRoZSBjb252ZXJ0ZWQgdmFsdWVzIGJlZm9yZSBzYXZpbmcuYDtcbiAgICBtb2RhbFJlZi5yZXN1bHQudGhlbigocmVzdWx0OiBhbnkpID0+IHtcbiAgICAgIGlmIChyZXN1bHQgPT09ICdZZXMnKSB7XG4gICAgICAgIHRoaXMuY29udmVydFByb2R1Y3RDdXJyZW5jeShvbGRDdXJyZW5jeSwgbmV3Q3VycmVuY3kpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ2FuY2VsbGVkIOKAlCByZXZlcnQgdGhlIHNlbGVjdCBiYWNrIHRvIHRoZSBvcmlnaW5hbCBjdXJyZW5jeS5cbiAgICAgICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKG9sZEN1cnJlbmN5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfSkuY2F0Y2goKCkgPT4ge1xuICAgICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKG9sZEN1cnJlbmN5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBGZXRjaCBJTlItcGVyLXVuaXQgcmF0ZXMgYW5kIGNvbnZlcnQgZWFjaCBwcm9kdWN0IHByaWNlIGZyb20gb2xk4oaSbmV3OlxuICAvLyAgIG5ld1ByaWNlID0gb2xkUHJpY2UgKiAocmF0ZXNbb2xkXSAvIHJhdGVzW25ld10pLlxuICAvLyBFYWNoIGxpbmUgYW1vdW50IGlzIGNvbnZlcnRlZCBieSB0aGUgc2FtZSBmYWN0b3IgKHNvIHByb3JhdGVkIGxpbmVzIHN0YXlcbiAgLy8gcHJvcmF0ZWQpLCB0YXgtcm93IGN1cnJlbmN5IHN5bWJvbHMgYXJlIHJlZnJlc2hlZCBhbmQgdG90YWxzIHJlY29tcHV0ZWQuXG4gIC8vIHByZXZpb3VzQ3VycmVuY3kgaXMgYWR2YW5jZWQgb25seSBhZnRlciBhIHN1Y2Nlc3NmdWwgY29udmVyc2lvbi5cbiAgcHJpdmF0ZSBjb252ZXJ0UHJvZHVjdEN1cnJlbmN5KG9sZEN1cnJlbmN5OiBzdHJpbmcsIG5ld0N1cnJlbmN5OiBzdHJpbmcpIHtcbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmZ4UmF0ZXMoKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCByYXRlcyA9IHJlcz8uZGF0YT8ucmF0ZXMgfHwge307XG4gICAgICAgIGNvbnN0IHJPbGQgPSBOdW1iZXIocmF0ZXNbb2xkQ3VycmVuY3ldKTtcbiAgICAgICAgY29uc3Qgck5ldyA9IE51bWJlcihyYXRlc1tuZXdDdXJyZW5jeV0pO1xuICAgICAgICBpZiAoIShyT2xkID4gMCkgfHwgIShyTmV3ID4gMCkpIHtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0V4Y2hhbmdlIHJhdGUgdW5hdmFpbGFibGUg4oCUIGN1cnJlbmN5IG5vdCBjb252ZXJ0ZWQuJyk7XG4gICAgICAgICAgdGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKG9sZEN1cnJlbmN5LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZhY3RvciA9IHJPbGQgLyByTmV3O1xuICAgICAgICB0aGlzLnByb2R1Y3RzLmNvbnRyb2xzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICAgICAgY29uc3QgcHJpY2UgPSBOdW1iZXIoZ3JvdXAuZ2V0KCdwcmljZScpPy52YWx1ZSkgfHwgMDtcbiAgICAgICAgICBjb25zdCBjb252ZXJ0ZWQgPSB0aGlzLnJvdW5kRm9yQ3VycmVuY3kocHJpY2UgKiBmYWN0b3IsIG5ld0N1cnJlbmN5KTtcbiAgICAgICAgICBncm91cC5nZXQoJ3ByaWNlJyk/LnNldFZhbHVlKGNvbnZlcnRlZCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHN0b3JlZCBsaW5lIGFtb3VudCBkaXJlY3RseSByYXRoZXIgdGhhbiByZS1kZXJpdmluZyBpdFxuICAgICAgICAgIC8vIGFzIHN0b3JlQ291bnQgeCBuZXcgcHJpY2UsIHdoaWNoIHdvdWxkIGRyb3AgYW55IHByb3JhdGlvbi5cbiAgICAgICAgICBjb25zdCBhbW91bnQgPSBOdW1iZXIoZ3JvdXAuZ2V0KCdhbW91bnQnKT8udmFsdWUpIHx8IDA7XG4gICAgICAgICAgZ3JvdXAuZ2V0KCdhbW91bnQnKT8uc2V0VmFsdWUodGhpcy5yb3VuZEZvckN1cnJlbmN5KGFtb3VudCAqIGZhY3RvciwgbmV3Q3VycmVuY3kpLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBSZWZyZXNoIGVhY2ggdGF4IHJvdydzIGN1cnJlbmN5IHN5bWJvbCB0byB0aGUgbmV3IGN1cnJlbmN5LlxuICAgICAgICBjb25zdCBzeW1ib2wgPSB0aGlzLnN5bWJvbEZvcihuZXdDdXJyZW5jeSk7XG4gICAgICAgIHRoaXMudGF4QXJyYXkuY29udHJvbHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgICAgICBncm91cC5nZXQoJ2N1cnJlbmN5Jyk/LnNldFZhbHVlKHN5bWJvbCwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wcmV2aW91c0N1cnJlbmN5ID0gbmV3Q3VycmVuY3k7XG4gICAgICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoYEFtb3VudHMgY29udmVydGVkIHRvICR7dGhpcy5jdXJyZW5jeUxhYmVsc1tuZXdDdXJyZW5jeV0gfHwgbmV3Q3VycmVuY3l9LmApO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGZldGNoIGV4Y2hhbmdlIHJhdGUg4oCUIGN1cnJlbmN5IG5vdCBjb252ZXJ0ZWQuJyk7XG4gICAgICAgIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdjdXJyZW5jeScpPy5zZXRWYWx1ZShvbGRDdXJyZW5jeSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb25Hcm91cENoYW5nZShldmVudDogYW55KSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRHcm91cCA9IHRoaXMuYmlsbGluZ0dyb3Vwcy5maW5kKGcgPT4gZy5faWQgPT09IGV2ZW50LnRhcmdldC52YWx1ZSk7XG4gICAgaWYgKHNlbGVjdGVkR3JvdXApIHtcbiAgICAgIHRoaXMuaW52b2ljZUZvcm0ucGF0Y2hWYWx1ZSh7XG4gICAgICAgIGdyb3VwTmFtZTogc2VsZWN0ZWRHcm91cC5ncm91cE5hbWUsXG4gICAgICAgIGdyb3VwSWQ6IHNlbGVjdGVkR3JvdXAuX2lkLFxuICAgICAgICBjb21wYW55TmFtZTogc2VsZWN0ZWRHcm91cC5yZWdpc3RlcmVkQ29tcGFueU5hbWUgfHwgJycsXG4gICAgICAgIGNvbXBhbnlBZGRyZXNzOiBbc2VsZWN0ZWRHcm91cC5hZGRyZXNzTGluZU9uZSwgc2VsZWN0ZWRHcm91cC5hZGRyZXNzTGluZVR3bywgc2VsZWN0ZWRHcm91cC5jaXR5LCBzZWxlY3RlZEdyb3VwLnN0YXRlLCBzZWxlY3RlZEdyb3VwLmNvdW50cnksIHNlbGVjdGVkR3JvdXAucGluQ29kZV0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oJywgJyksXG4gICAgICAgIEdTVE51bWJlcjogc2VsZWN0ZWRHcm91cC5nc3QgfHwgJycsXG4gICAgICAgIFBsYWNlT2ZTdXBwbHk6IHNlbGVjdGVkR3JvdXAucGxhY2VPZlN1cHBseSB8fCAnJyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hcHBseUdyb3VwR3N0VGF4KHNlbGVjdGVkR3JvdXAuZ3N0KTtcbiAgICB9XG4gIH1cblxuICAvLyBBdXRvLXBvcHVsYXRlIHRoZSB0YXggc2VjdGlvbiBmcm9tIHRoZSBzZWxlY3RlZCBncm91cCdzIEdTVElOLCBtaXJyb3JpbmcgdGhlXG4gIC8vIGJhY2tlbmQgaW52b2ljZSB0YXggcnVsZTogR1NUSU4gc3RhcnRpbmcgd2l0aCAnMzMnIChpbnRyYS1zdGF0ZSwgVGFtaWwgTmFkdSlcbiAgLy8g4oaSIENHU1QgOSUgKyBTR1NUIDklOyBhbnkgb3RoZXIgR1NUSU4g4oaSIElHU1QgMTglLiBObyBHU1QgbnVtYmVyIOKGkiBubyB0YXggcm93cy5cbiAgLy8gUmVidWlsZHMgdGhlIHRheCBzZWN0aW9uIGVhY2ggdGltZSBzbyByZS1zZWxlY3RpbmcgYSBncm91cCBkb2Vzbid0IHN0YWNrIHJvd3MuXG4gIHByaXZhdGUgYXBwbHlHcm91cEdzdFRheChnc3Q6IHN0cmluZykge1xuICAgIHRoaXMudGF4QXJyYXkuY2xlYXIoKTtcbiAgICBjb25zdCBnc3RpbiA9IFN0cmluZyhnc3QgfHwgJycpLnRyaW0oKTtcbiAgICBpZiAoZ3N0aW4pIHtcbiAgICAgIGlmIChnc3Rpbi5zbGljZSgwLCAyKSA9PT0gJzMzJykge1xuICAgICAgICB0aGlzLnRheEFycmF5LnB1c2godGhpcy5jcmVhdGVUYXhHcm91cCh7IHR5cGU6ICdDR1NUJywgdmFsdWU6IDkgfSkpO1xuICAgICAgICB0aGlzLnRheEFycmF5LnB1c2godGhpcy5jcmVhdGVUYXhHcm91cCh7IHR5cGU6ICdTR1NUJywgdmFsdWU6IDkgfSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy50YXhBcnJheS5wdXNoKHRoaXMuY3JlYXRlVGF4R3JvdXAoeyB0eXBlOiAnSUdTVCcsIHZhbHVlOiAxOCB9KSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBtb2RlOiB0aGUgR1NUSU4gY2FuIGJlIHR5cGVkL2VkaXRlZCBkaXJlY3RseSDigJQgcmUtZGVyaXZlIHRoZSB0YXggcm93c1xuICAvLyBmcm9tIGl0IChzYW1lIHJ1bGUgYXMgZ3JvdXAgc2VsZWN0aW9uKSBzbyB0YXggYWx3YXlzIGZvbGxvd3MgdGhlIEdTVCBudW1iZXIuXG4gIC8vIEluIGVkaXQgbW9kZSB0aGUgR1NUIE51bWJlciBmaWVsZCBpcyByZWFkLW9ubHksIHNvIHRoaXMgaXMgYSBuby1vcCB0aGVyZS5cbiAgb25Hc3ROdW1iZXJJbnB1dCgpIHtcbiAgICBpZiAodGhpcy5tb2RlID09PSAnZWRpdCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hcHBseUdyb3VwR3N0VGF4KHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdHU1ROdW1iZXInKT8udmFsdWUpO1xuICB9XG5cbiAgLy8gLS0tLSBQcm9kdWN0IHJvdyByZW9yZGVyaW5nIChuYXRpdmUgSFRNTDUgZHJhZyAmIGRyb3ApIC0tLS1cbiAgLy8gZHJhZ0luZGV4OiByb3cgYmVpbmcgZHJhZ2dlZDsgZHJhZ092ZXJJbmRleDogcm93IGN1cnJlbnRseSBob3ZlcmVkIChmb3IgdGhlXG4gIC8vIGRyb3AgaW5kaWNhdG9yKS4gRHJvcHBpbmcgbW92ZXMgdGhlIEZvcm1Hcm91cCB3aXRoaW4gdGhlIEZvcm1BcnJheSwgc28gdGhlXG4gIC8vIFwiUHJvZHVjdCBOXCIgbnVtYmVyaW5nLCB0b3RhbHMgYW5kIHRoZSBzYXZlZCBwcm9kdWN0cyBvcmRlciBhbGwgZm9sbG93LlxuICBkcmFnSW5kZXg6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBkcmFnT3ZlckluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBvblJvd0RyYWdTdGFydChldmVudDogRHJhZ0V2ZW50LCBpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5kcmFnSW5kZXggPSBpbmRleDtcbiAgICBpZiAoZXZlbnQuZGF0YVRyYW5zZmVyKSB7XG4gICAgICBldmVudC5kYXRhVHJhbnNmZXIuZWZmZWN0QWxsb3dlZCA9ICdtb3ZlJztcbiAgICAgIC8vIFNvbWUgYnJvd3NlcnMgbmVlZCBkYXRhIHNldCBmb3IgdGhlIGRyYWcgdG8gc3RhcnQuXG4gICAgICBldmVudC5kYXRhVHJhbnNmZXIuc2V0RGF0YSgndGV4dC9wbGFpbicsIFN0cmluZyhpbmRleCkpO1xuICAgIH1cbiAgfVxuXG4gIG9uUm93RHJhZ092ZXIoZXZlbnQ6IERyYWdFdmVudCwgaW5kZXg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmRyYWdJbmRleCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIGFsbG93IGRyb3BcbiAgICBpZiAoZXZlbnQuZGF0YVRyYW5zZmVyKSBldmVudC5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdtb3ZlJztcbiAgICB0aGlzLmRyYWdPdmVySW5kZXggPSBpbmRleDtcbiAgfVxuXG4gIG9uUm93RHJhZ0xlYXZlKGluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5kcmFnT3ZlckluZGV4ID09PSBpbmRleCkgdGhpcy5kcmFnT3ZlckluZGV4ID0gbnVsbDtcbiAgfVxuXG4gIG9uUm93RHJvcChldmVudDogRHJhZ0V2ZW50LCB0YXJnZXRJbmRleDogbnVtYmVyKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBmcm9tID0gdGhpcy5kcmFnSW5kZXg7XG4gICAgdGhpcy5vblJvd0RyYWdFbmQoKTtcbiAgICBpZiAoZnJvbSA9PT0gbnVsbCB8fCBmcm9tID09PSB0YXJnZXRJbmRleCkgcmV0dXJuO1xuICAgIGNvbnN0IGdyb3VwID0gdGhpcy5wcm9kdWN0cy5hdChmcm9tKTtcbiAgICB0aGlzLnByb2R1Y3RzLnJlbW92ZUF0KGZyb20pO1xuICAgIHRoaXMucHJvZHVjdHMuaW5zZXJ0KHRhcmdldEluZGV4LCBncm91cCk7XG4gICAgdGhpcy5wcm9kdWN0cy5tYXJrQXNEaXJ0eSgpO1xuICAgIHRoaXMucmVjYWxjdWxhdGUoKTtcbiAgfVxuXG4gIG9uUm93RHJhZ0VuZCgpIHtcbiAgICB0aGlzLmRyYWdJbmRleCA9IG51bGw7XG4gICAgdGhpcy5kcmFnT3ZlckluZGV4ID0gbnVsbDtcbiAgfVxuXG4gIC8vIFJhdGUvUHJpY2U6IGFsbG93IGF0IG1vc3QgMiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuIEFueXRoaW5nIGJleW9uZFxuICAvLyAoZS5nLiAxMi4zNDUpIGlzIHRyaW1tZWQgdG8gMTIuMzQgYXMgdGhlIHVzZXIgdHlwZXMsIHRoZW4gdG90YWxzIHJlY29tcHV0ZS5cbiAgb25QcmljZUlucHV0KGk6IG51bWJlcikge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLnByb2R1Y3RzLmF0KGkpPy5nZXQoJ3ByaWNlJyk7XG4gICAgY29uc3QgcmF3ID0gY3RybD8udmFsdWU7XG4gICAgaWYgKHJhdyAhPT0gbnVsbCAmJiByYXcgIT09IHVuZGVmaW5lZCAmJiByYXcgIT09ICcnKSB7XG4gICAgICBjb25zdCB0ZXh0ID0gU3RyaW5nKHJhdyk7XG4gICAgICBjb25zdCBtYXRjaCA9IHRleHQubWF0Y2goL14oLT9cXGQqKShcXC5cXGR7MCwyfSk/Lyk7XG4gICAgICBjb25zdCB0cmltbWVkID0gbWF0Y2ggPyBgJHttYXRjaFsxXX0ke21hdGNoWzJdID8/ICcnfWAgOiB0ZXh0O1xuICAgICAgaWYgKHRyaW1tZWQgIT09IHRleHQpIHtcbiAgICAgICAgY3RybD8uc2V0VmFsdWUodHJpbW1lZCA9PT0gJycgfHwgdHJpbW1lZCA9PT0gJy0nID8gbnVsbCA6IE51bWJlcih0cmltbWVkKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnJlY2FsY3VsYXRlKGkpO1xuICB9XG5cbiAgLy8gUmVmcmVzaCBzdWJ0b3RhbCAvIHRheCAvIHN0b3JlIHRvdGFscy4gT25seSB0aGUgcm93IHRoYXQgd2FzIGp1c3QgZWRpdGVkXG4gIC8vIChjaGFuZ2VkSW5kZXgpIGhhcyBpdHMgQW1vdW50IHJlLWRlcml2ZWQgYXMgUXVhbnRpdHkgeCBSYXRlOyBldmVyeSBvdGhlclxuICAvLyByb3cga2VlcHMgaXRzIHN0b3JlZCBhbW91bnQuIEF1dG8tZ2VuZXJhdGVkIGludm9pY2VzIGNhcnJ5IFBST1JBVEVEIGxpbmVzXG4gIC8vIChhbW91bnQgPSBwcmljZSB4IHdvcmtpbmdEYXlzIC8gbW9udGhEYXlzLCBzbyBhbW91bnQgIT0gc3RvcmVDb3VudCB4IHByaWNlO1xuICAvLyBlLmcuIERSQUZULTI2LTI3LTAwMDA5IHN0b3JlZCAxIHggMTY1MCBhcyA2MDUpLiBSZWNvbXB1dGluZyBldmVyeSByb3cgb25cbiAgLy8gYW55IGtleXN0cm9rZSBzaWxlbnRseSByZXdyb3RlIGFsbCBvZiB0aG9zZSB0byB0aGUgZnVsbC1tb250aCBmaWd1cmUuXG4gIHJlY2FsY3VsYXRlKGNoYW5nZWRJbmRleD86IG51bWJlcikge1xuICAgIGxldCBzdWJ0b3RhbCA9IDA7XG4gICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCwgaWR4KSA9PiB7XG4gICAgICBpZiAoaWR4ID09PSBjaGFuZ2VkSW5kZXgpIHtcbiAgICAgICAgY29uc3Qgc3RvcmVDb3VudCA9IE51bWJlcihncm91cC5nZXQoJ3N0b3JlQ291bnQnKT8udmFsdWUpIHx8IDA7XG4gICAgICAgIGNvbnN0IHByaWNlID0gTnVtYmVyKGdyb3VwLmdldCgncHJpY2UnKT8udmFsdWUpIHx8IDA7XG4gICAgICAgIGdyb3VwLmdldCgnYW1vdW50Jyk/LnNldFZhbHVlKHBhcnNlRmxvYXQoKHN0b3JlQ291bnQgKiBwcmljZSkudG9GaXhlZCgyKSksIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgIH1cbiAgICAgIHN1YnRvdGFsICs9IE51bWJlcihncm91cC5nZXQoJ2Ftb3VudCcpPy52YWx1ZSkgfHwgMDtcbiAgICB9KTtcblxuICAgIC8vIFRheCBpcyBjaGFyZ2VkIG9uIHRoZSBESVNDT1VOVEVEIGFtb3VudCwgbWF0Y2hpbmcgYXBwbHlEaXNjb3VudCgpIG9uIHRoZVxuICAgIC8vIGJhY2tlbmQuIFRheGluZyB0aGUgZ3Jvc3Mgc3VidG90YWwgaGVyZSB3b3VsZCBzaG93IGEgdG90YWwgdGhhdCB0aGVcbiAgICAvLyBzZXJ2ZXIgdGhlbiByZWNvbXB1dGVzIGRpZmZlcmVudGx5LlxuICAgIGNvbnN0IHRheGFibGUgPSBzdWJ0b3RhbCAtIHRoaXMuZ2V0QXBwbGllZERpc2NvdW50KCk7XG4gICAgdGhpcy50YXhBcnJheS5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBncm91cC5nZXQoJ3ZhbHVlJyk/LnZhbHVlIHx8IDA7XG4gICAgICBjb25zdCB0YXhBbW91bnQgPSAodGF4YWJsZSAqIHZhbHVlIC8gMTAwKS50b0ZpeGVkKDIpO1xuICAgICAgZ3JvdXAuZ2V0KCd0YXhBbW91bnQnKT8uc2V0VmFsdWUodGF4QW1vdW50LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgfSk7XG5cbiAgICBsZXQgdG90YWxTdG9yZXMgPSAwO1xuICAgIHRoaXMucHJvZHVjdHMuY29udHJvbHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgIHRvdGFsU3RvcmVzICs9IGdyb3VwLmdldCgnc3RvcmVDb3VudCcpPy52YWx1ZSB8fCAwO1xuICAgIH0pO1xuICAgIHRoaXMuaW52b2ljZUZvcm0uZ2V0KCdzdG9yZXMnKT8uc2V0VmFsdWUodG90YWxTdG9yZXMsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cblxuICBnZXRTdWJ0b3RhbCgpOiBudW1iZXIge1xuICAgIGxldCBzdWJ0b3RhbCA9IDA7XG4gICAgdGhpcy5wcm9kdWN0cy5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgc3VidG90YWwgKz0gZ3JvdXAuZ2V0KCdhbW91bnQnKT8udmFsdWUgfHwgMDtcbiAgICB9KTtcbiAgICByZXR1cm4gc3VidG90YWw7XG4gIH1cblxuICBnZXRUb3RhbFRheCgpOiBudW1iZXIge1xuICAgIGxldCB0b3RhbFRheCA9IDA7XG4gICAgdGhpcy50YXhBcnJheS5jb250cm9scy5mb3JFYWNoKChncm91cCkgPT4ge1xuICAgICAgdG90YWxUYXggKz0gcGFyc2VGbG9hdChncm91cC5nZXQoJ3RheEFtb3VudCcpPy52YWx1ZSB8fCAnMCcpO1xuICAgIH0pO1xuICAgIHJldHVybiB0b3RhbFRheDtcbiAgfVxuXG4gIC8vIENyZWRpdCBub3RlIGFscmVhZHkgYXBwbGllZCB0byB0aGlzIGludm9pY2UgKDAgd2hlbiBub25lKS4gUmVhZCBzdHJhaWdodFxuICAvLyBvZmYgdGhlIHNhdmVkIGludm9pY2Ug4oCUIGl0IGlzIG5vdCBhIGxpbmUgaXRlbSwgc28gZ2V0U3VidG90YWwoKSBuZXZlciBzZWVzXG4gIC8vIGl0IGFuZCB0aGUgc3VtbWFyeSB3b3VsZCBvdGhlcndpc2Ugc2hvdyB0aGUgcHJlLWRpc2NvdW50IHRvdGFsLlxuICBnZXRBcHBsaWVkRGlzY291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTnVtYmVyKHRoaXMuaW52b2ljZURhdGE/LmRpc2NvdW50QW1vdW50KSB8fCAwO1xuICB9XG5cbiAgZ2V0VG90YWxBbW91bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdWJ0b3RhbCgpIC0gdGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKSArIHRoaXMuZ2V0VG90YWxUYXgoKTtcbiAgfVxuXG4gIC8vIEN1cnJlbmN5LWF3YXJlIHJvdW5kaW5nOiBJTlIgLT4gd2hvbGUgbnVtYmVyLCBldmVyeSBvdGhlciBjdXJyZW5jeSBrZWVwc1xuICAvLyAyIGRlY2ltYWxzLiBNaXJyb3JzIHRoZSBiYWNrZW5kIHJvdW5kQW1vdW50KCkgaGVscGVyLlxuICByb3VuZEZvckN1cnJlbmN5KHZhbHVlOiBudW1iZXIsIGN1cnJlbmN5OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGNvbnN0IG4gPSBOdW1iZXIodmFsdWUpIHx8IDA7XG4gICAgcmV0dXJuIGN1cnJlbmN5ID09PSAnaW5yJyA/IE1hdGgucm91bmQobikgOiBNYXRoLnJvdW5kKG4gKiAxMDApIC8gMTAwO1xuICB9XG5cbiAgZ2V0Q3VycmVuY3lTeW1ib2woKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zeW1ib2xGb3IodGhpcy5pbnZvaWNlRm9ybS5nZXQoJ2N1cnJlbmN5Jyk/LnZhbHVlKTtcbiAgfVxuXG4gIGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnN5bWJvbEZvcih0aGlzLmludm9pY2VEYXRhPy5jdXJyZW5jeSk7XG4gIH1cblxuICBvblN1Ym1pdCgpIHtcbiAgICBpZiAodGhpcy5pbnZvaWNlRm9ybS5pbnZhbGlkKSB7XG4gICAgICB0aGlzLmludm9pY2VGb3JtLm1hcmtBbGxBc1RvdWNoZWQoKTtcbiAgICAgIC8vIERlZmVyIHRvIG5leHQgdGljayBzbyBBbmd1bGFyIHJlbmRlcnMgdGhlIC5pcy1pbnZhbGlkIGNsYXNzZXNcbiAgICAgIC8vIGJlZm9yZSB3ZSBxdWVyeSB0aGUgRE9NIGZvciB0aGUgZmlyc3QgaW52YWxpZCBjb250cm9sIHRvIHNjcm9sbCB0by5cbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxUb0ZpcnN0SW52YWxpZCgpLCAwKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNhdmluZyA9IHRydWU7XG4gICAgY29uc3QgZm9ybVZhbHVlID0gdGhpcy5pbnZvaWNlRm9ybS5nZXRSYXdWYWx1ZSgpO1xuXG4gICAgY29uc3QgcGF5bG9hZDogYW55ID0ge1xuICAgICAgY29tcGFueU5hbWU6IGZvcm1WYWx1ZS5jb21wYW55TmFtZSxcbiAgICAgIGNvbXBhbnlBZGRyZXNzOiBmb3JtVmFsdWUuY29tcGFueUFkZHJlc3MsXG4gICAgICBHU1ROdW1iZXI6IGZvcm1WYWx1ZS5HU1ROdW1iZXIsXG4gICAgICBQbGFjZU9mU3VwcGx5OiBmb3JtVmFsdWUuUGxhY2VPZlN1cHBseSxcbiAgICAgIGdyb3VwTmFtZTogZm9ybVZhbHVlLmdyb3VwTmFtZSxcbiAgICAgIGdyb3VwSWQ6IGZvcm1WYWx1ZS5ncm91cElkLFxuICAgICAgc3RvcmVzOiBmb3JtVmFsdWUuc3RvcmVzLFxuICAgICAgYmlsbGluZ0RhdGU6IGZvcm1WYWx1ZS5iaWxsaW5nRGF0ZSxcbiAgICAgIGR1ZURhdGU6IGZvcm1WYWx1ZS5kdWVEYXRlLFxuICAgICAgcGF5bWVudFRlcm06IGZvcm1WYWx1ZS5wYXltZW50VGVybSxcbiAgICAgIGN1cnJlbmN5OiBmb3JtVmFsdWUuY3VycmVuY3ksXG4gICAgICBzdGF0dXM6IGZvcm1WYWx1ZS5zdGF0dXMsXG4gICAgICBwYXltZW50U3RhdHVzOiBmb3JtVmFsdWUucGF5bWVudFN0YXR1cyxcbiAgICAgIGFkdmFuY2VJbnZvaWNlOiBmb3JtVmFsdWUuYWR2YW5jZUludm9pY2UsXG4gICAgICBhZHZhbmNlUGVyaW9kOiBmb3JtVmFsdWUuYWR2YW5jZVBlcmlvZCxcbiAgICAgIC8vIE1hcCBpbnZvaWNlIHRvIGEgcHVyY2hhc2Ugb3JkZXIgKHNlcnZlciBkZWR1Y3RzIHRoZSBQTyBiYWxhbmNlKS5cbiAgICAgIHB1cmNoYXNlT3JkZXJOdW1iZXI6IGZvcm1WYWx1ZS5wdXJjaGFzZU9yZGVyTnVtYmVyIHx8IHVuZGVmaW5lZCxcbiAgICAgIHByb2R1Y3RzOiBmb3JtVmFsdWUucHJvZHVjdHMsXG4gICAgICB0YXg6IGZvcm1WYWx1ZS50YXgsXG4gICAgICAvLyAnYW1vdW50JyBpcyB0aGUgcG9zdC1kaXNjb3VudCB2YWx1ZSB0aGUgYmFja2VuZCBzdG9yZXMgKGdldFN1YnRvdGFsKClcbiAgICAgIC8vIGlzIHRoZSBncm9zcyBsaW5lLWl0ZW0gdG90YWwpLiBTZW5kaW5nIHRoZSBncm9zcyBmaWd1cmUgaGVyZSB3aXBlZCBhblxuICAgICAgLy8gYXBwbGllZCBjcmVkaXQgbm90ZSBvbiBldmVyeSBVcGRhdGUgSW52b2ljZS5cbiAgICAgIC8vIENvbXBvbmVudCBmaWd1cmVzIChzdWJ0b3RhbCwgZGlzY291bnQpIGtlZXAgZXhhY3QgcGFpc2Ug4oCUIG9ubHkgdGhlXG4gICAgICAvLyBUb3RhbCBBbW91bnQgaXMgd2hvbGUtdW5pdCByb3VuZGVkIChJTlIpLiBQb3N0aW5nIGEgd2hvbGUtcm91bmRlZFxuICAgICAgLy8gc3VidG90YWwgbWFkZSB0aGUgcHJpbnRlZCBTdWIgVG90YWwgZGlzYWdyZWUgd2l0aCB0aGUgbGluZSBpdGVtc1xuICAgICAgLy8gKGUuZy4gMjQsMDY1LjAwIHZzIGxpbmVzIHN1bW1pbmcgdG8gMjQsMDY0LjUyKS5cbiAgICAgIGFtb3VudDogdGhpcy5yb3VuZDIodGhpcy5nZXRTdWJ0b3RhbCgpIC0gdGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKSksXG4gICAgICB0b3RhbEFtb3VudDogdGhpcy5yb3VuZEZvckN1cnJlbmN5KHRoaXMuZ2V0VG90YWxBbW91bnQoKSwgZm9ybVZhbHVlLmN1cnJlbmN5KSxcbiAgICB9O1xuXG4gICAgLy8gQ2FycnkgdGhlIGFwcGxpZWQgY3JlZGl0IG5vdGUgdGhyb3VnaCB0aGUgdXBkYXRlIHNvIGl0IHN1cnZpdmVzIGFuIGVkaXQuXG4gICAgaWYgKHRoaXMuZ2V0QXBwbGllZERpc2NvdW50KCkgPiAwKSB7XG4gICAgICBwYXlsb2FkLmRpc2NvdW50QW1vdW50ID0gdGhpcy5yb3VuZDIodGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKSk7XG4gICAgICBjb25zdCBncm9zcyA9IHRoaXMuZ2V0U3VidG90YWwoKTtcbiAgICAgIHBheWxvYWQuZGlzY291bnRQZXJjZW50YWdlID0gZ3Jvc3MgPiAwXG4gICAgICAgID8gdGhpcy5yb3VuZDIodGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKSAvIGdyb3NzICogMTAwKVxuICAgICAgICA6IDA7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2VkaXQnKSB7XG4gICAgICBwYXlsb2FkLl9pZCA9IHRoaXMuaW52b2ljZURhdGEuX2lkO1xuICAgICAgcGF5bG9hZC5pbnZvaWNlID0gdGhpcy5pbnZvaWNlRGF0YS5pbnZvaWNlO1xuICAgICAgcGF5bG9hZC5jbGllbnRJZCA9IHRoaXMuaW52b2ljZURhdGEuY2xpZW50SWQ7XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLnVwZGF0ZUludm9pY2UocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ0ludm9pY2UgdXBkYXRlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ3VwZGF0ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byB1cGRhdGUgaW52b2ljZScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2VkaXRFc3RpbWF0ZScpIHtcbiAgICAgIC8vIFVwZGF0ZSBhbiBleGlzdGluZyBlc3RpbWF0ZS4gSWRlbnRpdHkgZmllbGRzIChlc3RpbWF0ZSAjLCBjbGllbnRJZCxcbiAgICAgIC8vIGNyZWF0ZWREYXRlKSBhcmUgcHJlc2VydmVkIHNlcnZlci1zaWRlOyB3ZSBzZW5kIHRoZSBlZGl0YWJsZSBmb3JtIGRhdGEuXG4gICAgICBwYXlsb2FkLl9pZCA9IHRoaXMuaW52b2ljZURhdGEuX2lkO1xuICAgICAgcGF5bG9hZC5jbGllbnRJZCA9IHRoaXMuaW52b2ljZURhdGEuY2xpZW50SWQgfHwgdGhpcy5jbGllbnRJZDtcbiAgICAgIHBheWxvYWQucGVyaW9kID0gZm9ybVZhbHVlLmJpbGxpbmdEYXRlXG4gICAgICAgID8gbmV3IERhdGUoZm9ybVZhbHVlLmJpbGxpbmdEYXRlKS50b0xvY2FsZVN0cmluZygnZW4tVVMnLCB7IG1vbnRoOiAnc2hvcnQnLCB5ZWFyOiAnbnVtZXJpYycgfSlcbiAgICAgICAgOiB0aGlzLmludm9pY2VEYXRhLnBlcmlvZDtcbiAgICAgIHBheWxvYWQudmFsaWRUaWxsID0gZm9ybVZhbHVlLmR1ZURhdGU7XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLnVwZGF0ZUVzdGltYXRlKHBheWxvYWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgIHRoaXMudG9hc3QuZ2V0UHJpbWFyeVRvYXN0KCdFc3RpbWF0ZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgndXBkYXRlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byB1cGRhdGUgZXN0aW1hdGUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm1vZGUgPT09ICdlc3RpbWF0ZScpIHtcbiAgICAgIC8vIFNhbWUgZm9ybSwgc2VwYXJhdGUgZG9jdW1lbnQ6IHBvc3QgdG8gdGhlIGVzdGltYXRlIEFQSSBzbyBpdCBsYW5kcyBpblxuICAgICAgLy8gdGhlIGVzdGltYXRlcyBjb2xsZWN0aW9uIHdpdGggYW4gRVNULeKApiBudW1iZXIgaW5zdGVhZCBvZiBhbiBpbnZvaWNlLlxuICAgICAgcGF5bG9hZC5jbGllbnRJZCA9IHRoaXMuY2xpZW50SWQ7XG4gICAgICBwYXlsb2FkLnBlcmlvZCA9IGZvcm1WYWx1ZS5iaWxsaW5nRGF0ZVxuICAgICAgICA/IG5ldyBEYXRlKGZvcm1WYWx1ZS5iaWxsaW5nRGF0ZSkudG9Mb2NhbGVTdHJpbmcoJ2VuLVVTJywgeyBtb250aDogJ3Nob3J0JywgeWVhcjogJ251bWVyaWMnIH0pXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgcGF5bG9hZC52YWxpZFRpbGwgPSBmb3JtVmFsdWUuZHVlRGF0ZTtcbiAgICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuY3JlYXRlRXN0aW1hdGUocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ0VzdGltYXRlIGdlbmVyYXRlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ2NyZWF0ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdChlcnI/LmVycm9yPy5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gZ2VuZXJhdGUgZXN0aW1hdGUnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBheWxvYWQuY2xpZW50SWQgPSB0aGlzLmNsaWVudElkO1xuICAgICAgLy8gRmxhZyB0aGUgYmFja2VuZCB0byB0YWtlIHRoZSBcImN1c3RvbSBjcmVhdGVcIiBwYXRoIHRoYXQgcGVyc2lzdHMgd2hhdFxuICAgICAgLy8gdGhlIGZvcm0gYnVpbHQuIFRoZSBsZWdhY3kgL2NyZWF0ZUludm9pY2UgY29udHJhY3QgZXhwZWN0cyBlaXRoZXJcbiAgICAgIC8vIGFsbENsaWVudCtjbGllbnRMaXN0IG9yIGludm9pY2VJZDsgd2l0aG91dCB0aGlzIGZsYWcsIHRoZSBzZXJ2ZXJcbiAgICAgIC8vIHNpbGVudGx5IHJldHVybnMgMnh4IGFuZCB3cml0ZXMgbm90aGluZy5cbiAgICAgIHBheWxvYWQuY3VzdG9tSW52b2ljZSA9IHRydWU7XG4gICAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLmNyZWF0ZUludm9pY2UocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgdGhpcy50b2FzdC5nZXRQcmltYXJ5VG9hc3QoJ0ludm9pY2UgY3JlYXRlZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlTW9kYWwuY2xvc2UoJ2NyZWF0ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcbiAgICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBjcmVhdGUgaW52b2ljZSc7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KG1zZyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PSBDUkVESVQgTk9URSA9PT09PT09PT09PT09PT09PT09PT1cblxuICBpbml0Q3JlZGl0Tm90ZUZvcm0oKSB7XG4gICAgdGhpcy5jcmVkaXROb3RlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgYW1vdW50OiBbJyddLFxuICAgICAgcmV2aXNlZEFtb3VudDogWycnLCBWYWxpZGF0b3JzLnJlcXVpcmVkXSxcbiAgICAgIGRpc2NvdW50QW1vdW50OiBbJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgfSk7XG5cbiAgICAvLyBEaXNjb3VudCBBbW91bnQgYW5kIFJldmlzZWQgQW1vdW50IGFyZSB0d28gdmlld3Mgb2Ygb25lIG51bWJlciDigJQgZWRpdGluZ1xuICAgIC8vIGVpdGhlciByZWNvbXB1dGVzIHRoZSBvdGhlciAoeyBlbWl0RXZlbnQ6IGZhbHNlIH0gc3RvcHMgdGhlIGZlZWRiYWNrXG4gICAgLy8gbG9vcCkuIFRoZSBkaXNjb3VudCBQRVJDRU5UQUdFIGlzIG5vIGxvbmdlciBhbiBpbnB1dDogaXQncyBkZXJpdmVkIG9uY2VcbiAgICAvLyBvbiBzdWJtaXQsIHNvIGEgMiBkcCBwZXJjZW50YWdlIGNhbiBuZXZlciByb3VuZCB0aGUgZW50ZXJlZCBhbW91bnQuXG4gICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Rpc2NvdW50QW1vdW50Jyk/LnZhbHVlQ2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChlKSA9PiB7XG4gICAgICBpZiAoZSA9PT0gJycgfHwgZSA9PT0gbnVsbCB8fCBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ3JldmlzZWRBbW91bnQnKT8uc2V0VmFsdWUoJycsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgdGhpcy5jcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFtb3VudCA9IHRoaXMudG9OdW1iZXIodGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Ftb3VudCcpPy52YWx1ZSk7XG4gICAgICBjb25zdCBkaXNjb3VudEFtb3VudCA9IHRoaXMudG9OdW1iZXIoZSk7XG4gICAgICBpZiAoYW1vdW50ID4gMCkge1xuICAgICAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IGlzTmFOKGRpc2NvdW50QW1vdW50KSB8fCBkaXNjb3VudEFtb3VudCA8IDAgfHwgZGlzY291bnRBbW91bnQgPiBhbW91bnQ7XG4gICAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdyZXZpc2VkQW1vdW50Jyk/LnNldFZhbHVlKHRoaXMucm91bmQyKGFtb3VudCAtIGRpc2NvdW50QW1vdW50KSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgncmV2aXNlZEFtb3VudCcpPy52YWx1ZUNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoZSkgPT4ge1xuICAgICAgaWYgKGUgPT09ICcnIHx8IGUgPT09IG51bGwgfHwgZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdkaXNjb3VudEFtb3VudCcpPy5zZXRWYWx1ZSgnJywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgYW1vdW50ID0gdGhpcy50b051bWJlcih0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnYW1vdW50Jyk/LnZhbHVlKTtcbiAgICAgIGNvbnN0IHJldmlzZWQgPSB0aGlzLnRvTnVtYmVyKGUpO1xuICAgICAgaWYgKGFtb3VudCA+IDApIHtcbiAgICAgICAgLy8gSW52YWxpZCB3aGVuIG5vdCBhIG51bWJlciwgbmVnYXRpdmUsIG9yIGNyZWRpdGluZyBtb3JlIHRoYW4gdGhlIHRvdGFsLlxuICAgICAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IGlzTmFOKHJldmlzZWQpIHx8IHJldmlzZWQgPCAwIHx8IHJldmlzZWQgPiBhbW91bnQ7XG4gICAgICAgIHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdkaXNjb3VudEFtb3VudCcpPy5zZXRWYWx1ZSh0aGlzLnJvdW5kMihhbW91bnQgLSByZXZpc2VkKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3Rvci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBQYXJzZSBhIGZvcm0gdmFsdWUgdGhhdCBtYXkgYmUgYSBzdHJpbmcgKCcxMjM0LjU2Jykgb3IgYSBudW1iZXIuXG4gIHByaXZhdGUgdG9OdW1iZXIodjogYW55KTogbnVtYmVyIHtcbiAgICBpZiAodiA9PT0gJycgfHwgdiA9PT0gbnVsbCB8fCB2ID09PSB1bmRlZmluZWQpIHJldHVybiBOYU47XG4gICAgcmV0dXJuIE51bWJlcih2KTtcbiAgfVxuXG4gIC8vIFJvdW5kIHRvIDIgZGVjaW1hbCBwbGFjZXMsIGF2b2lkaW5nIGZsb2F0IGFydGVmYWN0cyAoMC4xKzAuMiBzdHlsZSkuXG4gIHByaXZhdGUgcm91bmQyKG46IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKCFpc0Zpbml0ZShuKSkgcmV0dXJuIE5hTjtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCgobiArIE51bWJlci5FUFNJTE9OKSAqIDEwMCkgLyAxMDA7XG4gIH1cblxuICBwYXRjaENyZWRpdE5vdGVEZWZhdWx0cygpIHtcbiAgICBpZiAoIXRoaXMuaW52b2ljZURhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gaW52b2ljZURhdGEuYW1vdW50IGlzIHRoZSBDVVJSRU5UIChhbHJlYWR5IGRpc2NvdW50ZWQpIGFtb3VudCwgc28gYWRkIGFueVxuICAgIC8vIGFwcGxpZWQgZGlzY291bnQgYmFjayB0byBzaG93IHRoZSBvcmlnaW5hbCBpbnZvaWNlIHZhbHVlIGluIFRvdGFsIEFtb3VudC5cbiAgICBjb25zdCBhcHBsaWVkID0gdGhpcy5nZXRBcHBsaWVkRGlzY291bnQoKTtcbiAgICBjb25zdCBjdXJyZW50ID0gTnVtYmVyKHRoaXMuaW52b2ljZURhdGEuYW1vdW50ID8/IHRoaXMuaW52b2ljZURhdGEudG90YWxBbW91bnQpIHx8IDA7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSB0aGlzLnJvdW5kMihjdXJyZW50ICsgYXBwbGllZCk7XG5cbiAgICAvLyBQcmUtcG9wdWxhdGUgd2l0aCB0aGUgZGlzY291bnQgYWxyZWFkeSBvbiB0aGlzIGludm9pY2Ugc28gcmUtb3BlbmluZyB0aGVcbiAgICAvLyB0YWIgc2hvd3Mgd2hhdCB3YXMgYXBwbGllZCByYXRoZXIgdGhhbiBhbiBlbXB0eSBmb3JtLiBlbWl0RXZlbnQ6IGZhbHNlIOKAlFxuICAgIC8vIHRoZSB2YWx1ZUNoYW5nZXMgcGFpciB3b3VsZCBvdGhlcndpc2UgcmVjb21wdXRlIGZyb20gYSBoYWxmLXBhdGNoZWQgZm9ybS5cbiAgICB0aGlzLmNyZWRpdE5vdGVGb3JtLnBhdGNoVmFsdWUoe1xuICAgICAgYW1vdW50OiBvcmlnaW5hbCxcbiAgICAgIGRpc2NvdW50QW1vdW50OiBhcHBsaWVkID4gMCA/IGFwcGxpZWQgOiAnJyxcbiAgICAgIHJldmlzZWRBbW91bnQ6IGFwcGxpZWQgPiAwID8gdGhpcy5yb3VuZDIob3JpZ2luYWwgLSBhcHBsaWVkKSA6ICcnLFxuICAgIH0sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICB0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA9IGZhbHNlO1xuICB9XG5cbiAgYXBwbHlDcmVkaXROb3RlKCkge1xuICAgIGlmICh0aGlzLmNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCkgcmV0dXJuO1xuICAgIC8vIGRpc2NvdW50QW1vdW50IGlzIHdoYXQgdGhlIHVzZXIgdHlwZWQgYW5kIGlzIGF1dGhvcml0YXRpdmUuIFRoZVxuICAgIC8vIHBlcmNlbnRhZ2UgaXMgZGVyaXZlZCBmcm9tIGl0IGhlcmUgcHVyZWx5IHNvIHRoZSBiYWNrZW5kIGNhbiBrZWVwIHN0b3JpbmdcbiAgICAvLyBkaXNjb3VudFBlcmNlbnRhZ2Ug4oCUIGl0IGlzIG5ldmVyIHVzZWQgdG8gY29tcHV0ZSB0aGUgY3JlZGl0ZWQgdmFsdWUuXG4gICAgY29uc3QgYW1vdW50ID0gdGhpcy50b051bWJlcih0aGlzLmNyZWRpdE5vdGVGb3JtLmdldCgnYW1vdW50Jyk/LnZhbHVlKTtcbiAgICBjb25zdCBkaXNjb3VudEFtb3VudCA9IHRoaXMudG9OdW1iZXIodGhpcy5jcmVkaXROb3RlRm9ybS5nZXQoJ2Rpc2NvdW50QW1vdW50Jyk/LnZhbHVlKTtcbiAgICBjb25zdCByZXF1ZXN0RGF0YSA9IHtcbiAgICAgIGludm9pY2U6IHRoaXMuaW52b2ljZURhdGEuaW52b2ljZSxcbiAgICAgIHJldmlzZWRBbW91bnQ6IHRoaXMuY3JlZGl0Tm90ZUZvcm0uZ2V0KCdyZXZpc2VkQW1vdW50Jyk/LnZhbHVlLFxuICAgICAgZGlzY291bnQ6IGFtb3VudCA+IDAgPyB0aGlzLnJvdW5kMihkaXNjb3VudEFtb3VudCAvIGFtb3VudCAqIDEwMCkgOiAwLFxuICAgICAgZGlzY291bnRBbW91bnQ6IGRpc2NvdW50QW1vdW50LFxuICAgIH07XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuYXBwbHlEaXNjb3VudChyZXF1ZXN0RGF0YSkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKHJlcyAmJiByZXMuY29kZSA9PSAyMDApIHtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnQ3JlZGl0IG5vdGUgYXBwbGllZCBzdWNjZXNzZnVsbHknKTtcbiAgICAgICAgICB0aGlzLmFjdGl2ZU1vZGFsLmNsb3NlKCdjcmVkaXRBcHBsaWVkJyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvYXN0LmdldEVycm9yVG9hc3QoJ0ZhaWxlZCB0byBhcHBseSBjcmVkaXQgbm90ZScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb21pdFNwZWNpYWxDaGFyKGV2ZW50OiBhbnkpIHtcbiAgICBjb25zdCBrID0gZXZlbnQuY2hhckNvZGU7XG4gICAgcmV0dXJuIChrID09IDggfHwgayA9PSAzMiB8fCAoayA+PSA0OCAmJiBrIDw9IDU3KSk7XG4gIH1cblxuICAvLyBBbW91bnQvcGVyY2VudGFnZSBrZXlwcmVzcyBmaWx0ZXI6IGRpZ2l0cyBwbHVzIGEgc2luZ2xlIGRlY2ltYWwgcG9pbnQuXG4gIC8vIG9taXRTcGVjaWFsQ2hhciAoYWJvdmUpIGJsb2NrcyAnLicsIHdoaWNoIHdvdWxkIG1ha2UgdGhlc2UgZmllbGRzXG4gIC8vIGludGVnZXItb25seSDigJQga2VwdCBzZXBhcmF0ZSBzbyBvdGhlciBpbnB1dHMgdXNpbmcgaXQgYXJlIHVuYWZmZWN0ZWQuXG4gIG9taXRTcGVjaWFsQ2hhckRlY2ltYWwoZXZlbnQ6IGFueSkge1xuICAgIGNvbnN0IGsgPSBldmVudC5jaGFyQ29kZTtcbiAgICBpZiAoayA9PSA4IHx8IGsgPT0gMzIgfHwgKGsgPj0gNDggJiYgayA8PSA1NykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBBbGxvdyAnLicgb25seSBvbmNlLCBhbmQgbm90IGFzIHRoZSB2ZXJ5IGZpcnN0IGNoYXJhY3Rlci5cbiAgICBpZiAoayA9PSA0Nikge1xuICAgICAgY29uc3QgdmFsdWUgPSBTdHJpbmcoZXZlbnQ/LnRhcmdldD8udmFsdWUgPz8gJycpO1xuICAgICAgcmV0dXJuIHZhbHVlLmxlbmd0aCA+IDAgJiYgIXZhbHVlLmluY2x1ZGVzKCcuJyk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PSBPTkUgVElNRSBGRUUgPT09PT09PT09PT09PT09PT09PT09XG5cbiAgaW5pdE9uZVRpbWVGZWVGb3JtKCkge1xuICAgIHRoaXMub25lVGltZUZlZUZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGFtb3VudDogWycnXSxcbiAgICAgIG9uZVRpbWVGZWU6IFsnJywgVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgfSk7XG5cbiAgICB0aGlzLm9uZVRpbWVGZWVGb3JtLnZhbHVlQ2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMuY2FsY3VsYXRlT25lVGltZUZlZVRvdGFsKCk7XG4gICAgfSk7XG4gIH1cblxuICBwYXRjaE9uZVRpbWVGZWVEZWZhdWx0cygpIHtcbiAgICBpZiAodGhpcy5pbnZvaWNlRGF0YSkge1xuICAgICAgdGhpcy5vbmVUaW1lRmVlRm9ybS5wYXRjaFZhbHVlKHtcbiAgICAgICAgYW1vdW50OiB0aGlzLmludm9pY2VEYXRhLmFtb3VudCB8fCB0aGlzLmludm9pY2VEYXRhLnRvdGFsQW1vdW50IHx8IDAsXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2FsY3VsYXRlT25lVGltZUZlZVRvdGFsKCk7XG4gICAgfVxuICB9XG5cbiAgY2FsY3VsYXRlT25lVGltZUZlZVRvdGFsKCkge1xuICAgIGNvbnN0IGFtb3VudCA9IHBhcnNlRmxvYXQodGhpcy5vbmVUaW1lRmVlRm9ybS5nZXQoJ2Ftb3VudCcpPy52YWx1ZSB8fCAnMCcpO1xuICAgIGNvbnN0IGZlZSA9IHBhcnNlRmxvYXQodGhpcy5vbmVUaW1lRmVlRm9ybS5nZXQoJ29uZVRpbWVGZWUnKT8udmFsdWUgfHwgJzAnKTtcbiAgICB0aGlzLm9uZVRpbWVGZWVUb3RhbCA9IHBhcnNlRmxvYXQoKGFtb3VudCArIGZlZSkudG9GaXhlZCgyKSk7XG4gIH1cblxuICBhcHBseU9uZVRpbWVGZWUoKSB7XG4gICAgY29uc3QgZmVlVmFsdWUgPSB0aGlzLm9uZVRpbWVGZWVGb3JtLmdldCgnb25lVGltZUZlZScpPy52YWx1ZTtcbiAgICBpZiAoIWZlZVZhbHVlKSByZXR1cm47XG4gICAgY29uc3QgcmVxdWVzdERhdGEgPSB7XG4gICAgICBvbmVUaW1lRmVlOiBmZWVWYWx1ZSxcbiAgICB9O1xuICAgIHRoaXMuc2F2aW5nID0gdHJ1ZTtcbiAgICB0aGlzLmJpbGxpbmdTZXJ2aWNlLm9uZVRpbWVGZWUocmVxdWVzdERhdGEsIHRoaXMuaW52b2ljZURhdGEuaW52b2ljZSkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKHJlcyAmJiByZXMuY29kZSA9PSAyMDApIHtcbiAgICAgICAgICB0aGlzLnRvYXN0LmdldFByaW1hcnlUb2FzdCgnT25lIHRpbWUgZmVlIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5Jyk7XG4gICAgICAgICAgdGhpcy5hY3RpdmVNb2RhbC5jbG9zZSgnZmVlQXBwbGllZCcpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy5zYXZpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gYXBwbHkgb25lIHRpbWUgZmVlJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn0iLCI8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgIDxkaXYgY2xhc3M9XCJwLTUgcHgtNiBwYi0wXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGluZyBtdC0yXCI+e3sgbW9kZSA9PT0gJ2VkaXQnID8gJ0ludm9pY2UnIDogKG1vZGUgPT09ICdlc3RpbWF0ZScgPyAnR2VuZXJhdGUgRXN0aW1hdGUnIDogKG1vZGUgPT09ICdlZGl0RXN0aW1hdGUnID8gJ0VkaXQgRXN0aW1hdGUnIDogJ0NyZWF0ZSBJbnZvaWNlJykpIH19XG4gICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJtb2RlID09PSAnZWRpdCdcIiBjbGFzcz1cImludm9pY2UtbnVtYmVyXCI+e3sgaW52b2ljZURhdGE/Lmludm9pY2UgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJtb2RlID09PSAnZWRpdEVzdGltYXRlJ1wiIGNsYXNzPVwiaW52b2ljZS1udW1iZXJcIj57eyBpbnZvaWNlRGF0YT8uZXN0aW1hdGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiPjwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFRhYnMgKG9ubHkgaW4gZWRpdCBtb2RlKSAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1iYXIgbXQtM1wiICpuZ0lmPVwibW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWJ0blwiIFtuZ0NsYXNzXT1cImFjdGl2ZVRhYiA9PT0gJ2VkaXQnID8gJ3RhYi1hY3RpdmUnIDogJydcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZXRUYWIoJ2VkaXQnKVwiPkVkaXQgSW52b2ljZTwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInRhYi1idG5cIiBbbmdDbGFzc109XCJhY3RpdmVUYWIgPT09ICdjcmVkaXROb3RlJyA/ICd0YWItYWN0aXZlJyA6ICcnXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2V0VGFiKCdjcmVkaXROb3RlJylcIj5DcmVkaXQgTm90ZTwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInRhYi1idG5cIiBbbmdDbGFzc109XCJhY3RpdmVUYWIgPT09ICdvbmVUaW1lRmVlJyA/ICd0YWItYWN0aXZlJyA6ICcnXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2V0VGFiKCdvbmVUaW1lRmVlJylcIj5PbmUgVGltZSBGZWU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PSBFRElUIElOVk9JQ0UgVEFCID09PT09PT09PT09PT09PT09PT09PT09PSAtLT5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keSBtYi00XCIgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdlZGl0JyB8fCBtb2RlICE9PSAnZWRpdCdcIj5cbiAgICAgICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJpbnZvaWNlRm9ybVwiIGNsYXNzPVwiZm9ybVwiIChuZ1N1Ym1pdCk9XCJvblN1Ym1pdCgpXCI+XG5cbiAgICAgICAgICAgIDwhLS0gQ29tcGFueSBEZXRhaWxzIFNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi10aXRsZSBtYi0zXCI+Q29tcGFueSBEZXRhaWxzPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Db21wYW55IE5hbWUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiY29tcGFueU5hbWVcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJjb250cm9sSW52YWxpZCgnY29tcGFueU5hbWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwibW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiY29udHJvbEludmFsaWQoJ2NvbXBhbnlOYW1lJylcIj5Db21wYW55IE5hbWUgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5HU1QgTnVtYmVyPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBDcmVhdGUgbW9kZTogdHlwaW5nL2NoYW5naW5nIHRoZSBHU1RJTiByZS1kZXJpdmVzIHRoZSB0YXggcm93cy4gLS0+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIkdTVE51bWJlclwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwib25Hc3ROdW1iZXJJbnB1dCgpXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkNvbXBhbnkgQWRkcmVzczwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cImNvbXBhbnlBZGRyZXNzXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbcmVhZG9ubHldPVwibW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UGxhY2Ugb2YgU3VwcGx5PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiUGxhY2VPZlN1cHBseVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cIm1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQmlsbGluZyBHcm91cCAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdJZj1cImJpbGxpbmdHcm91cHMubGVuZ3RoID4gMFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkJpbGxpbmcgR3JvdXAgPHNwYW4gKm5nSWY9XCJtb2RlICE9PSAnZWRpdCdcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8c2VsZWN0ICpuZ0lmPVwibW9kZSAhPT0gJ2VkaXQnXCIgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cImdyb3VwSWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWludmFsaWRdPVwiY29udHJvbEludmFsaWQoJ2dyb3VwSWQnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uR3JvdXBDaGFuZ2UoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPlNlbGVjdCBiaWxsaW5nIGdyb3VwPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBnIG9mIGJpbGxpbmdHcm91cHNcIiBbdmFsdWVdPVwiZy5faWRcIj57eyBnLmdyb3VwTmFtZSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwibW9kZSA9PT0gJ2VkaXQnXCIgdHlwZT1cInRleHRcIiBbdmFsdWVdPVwiaW52b2ljZUZvcm0uZ2V0KCdncm91cE5hbWUnKT8udmFsdWUgfHwgJ0RlZmF1bHQgR3JvdXAnXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnZ3JvdXBJZCcpXCI+QmlsbGluZyBHcm91cCBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkdyb3VwIE5hbWU8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJncm91cE5hbWVcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJtb2RlID09PSAnZWRpdCdcIj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEludm9pY2UgRGV0YWlscyBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tdGl0bGUgbWItMyBtdC0yXCI+SW52b2ljZSBEZXRhaWxzPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5CaWxsaW5nIERhdGUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJkYXRlXCIgZm9ybUNvbnRyb2xOYW1lPVwiYmlsbGluZ0RhdGVcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJjb250cm9sSW52YWxpZCgnYmlsbGluZ0RhdGUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm1vZGUgPT09ICdjcmVhdGUnICYmIGNvbXB1dGVEdWVEYXRlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnYmlsbGluZ0RhdGUnKVwiPkJpbGxpbmcgRGF0ZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwhLS0gQ3JlYXRlIG1vZGU6IGNob29zZSBhIHBheW1lbnQgdGVybSAoZGF5cyk7IHRoZSBkdWUgZGF0ZSBpc1xuICAgICAgICAgICAgICAgICAgICAgZGVyaXZlZCBmcm9tIEJpbGxpbmcgRGF0ZSArIHRlcm0gYW5kIHNob3duIHJlYWQtb25seS4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiICpuZ0lmPVwibW9kZSA9PT0gJ2NyZWF0ZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlBheW1lbnQgVGVybSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJwYXltZW50VGVybVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cImNvbXB1dGVEdWVEYXRlKClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiMzBcIj4zMCBkYXlzPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIFtuZ1ZhbHVlXT1cIjYwXCI+NjAgZGF5czwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiBbbmdWYWx1ZV09XCI5MFwiPjkwIGRheXM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gW25nVmFsdWVdPVwiMTIwXCI+MTIwIGRheXM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG10LTFcIj5EdWUgRGF0ZToge3sgaW52b2ljZUZvcm0uZ2V0KCdkdWVEYXRlJyk/LnZhbHVlIHx8ICctJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwhLS0gRWRpdCAvIGVzdGltYXRlIG1vZGVzIGtlZXAgdGhlIGVkaXRhYmxlIER1ZSBEYXRlIGZpZWxkLiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCIgKm5nSWY9XCJtb2RlICE9PSAnY3JlYXRlJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+RHVlIERhdGUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJkYXRlXCIgZm9ybUNvbnRyb2xOYW1lPVwiZHVlRGF0ZVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImNvbnRyb2xJbnZhbGlkKCdkdWVEYXRlJylcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJjb250cm9sSW52YWxpZCgnZHVlRGF0ZScpXCI+RHVlIERhdGUgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5DdXJyZW5jeSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJjdXJyZW5jeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uQ3VycmVuY3lDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJjb250cm9sSW52YWxpZCgnY3VycmVuY3knKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgYyBvZiBjdXJyZW5jeU9wdGlvbnNcIiBbdmFsdWVdPVwiY1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGN1cnJlbmN5TGFiZWxzW2NdIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiY29udHJvbEludmFsaWQoJ2N1cnJlbmN5JylcIj5DdXJyZW5jeSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPk5vLiBvZiBTdG9yZXM8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGZvcm1Db250cm9sTmFtZT1cInN0b3Jlc1wiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcmVhZG9ubHk+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPCEtLSBQdXJjaGFzZSBPcmRlciBtYXBwaW5nIChvcHRpb25hbCkuIE1hcHBpbmcgZGVkdWN0cyB0aGlzXG4gICAgICAgICAgICAgICAgICAgICBpbnZvaWNlJ3MgYW1vdW50IGZyb20gdGhlIHNlbGVjdGVkIFBPJ3MgcmVtYWluaW5nIGJhbGFuY2UuXG4gICAgICAgICAgICAgICAgICAgICBIaWRkZW4gZm9yIGRyYWZ0IGludm9pY2VzICh0ZW1wb3JhcnkgRFJBRlQtIG51bWJlciwgb3Igbm9cbiAgICAgICAgICAgICAgICAgICAgIG51bWJlciB5ZXQgaW4gY3JlYXRlIG1vZGUpIOKAlCBhIFBPIGNhbiBvbmx5IGJlIGF0dGFjaGVkIG9uY2VcbiAgICAgICAgICAgICAgICAgICAgIHRoZSByZWFsIGludm9pY2UgbnVtYmVyIGlzIG1pbnRlZCBhdCBmaW5hbmNlIGFwcHJvdmFsLiAtLT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibW9kZSAhPT0gJ2VzdGltYXRlJyAmJiBtb2RlICE9PSAnZWRpdEVzdGltYXRlJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0zXCIgKm5nSWY9XCIhaXNEcmFmdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlB1cmNoYXNlIE9yZGVyPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cInB1cmNoYXNlT3JkZXJOdW1iZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+Tm9uZTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IHBvIG9mIHB1cmNoYXNlT3JkZXJzXCIgW3ZhbHVlXT1cInBvLnB1cmNoYXNlT3JkZXJOdW1iZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcG8ucHVyY2hhc2VPcmRlck51bWJlciB9fSAoe3sgZ2V0Q3VycmVuY3lTeW1ib2woKSB9fXt7IHBvLnJlbWFpbmluZ0Ftb3VudCB8IG51bWJlcjonMS4wLTAnOidlbi1JTicgfX0gbGVmdClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiICpuZ0lmPVwiaXNEcmFmdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlB1cmNoYXNlIE9yZGVyPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUHVyY2hhc2UgT3JkZXIgY2FuIGJlIGF0dGFjaGVkIGFmdGVyIGZpbmFuY2UgYXBwcm92YWwgKG9uY2UgdGhlIGludm9pY2UgbnVtYmVyIGlzIGZpbmFsaXNlZCkuXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBBZHZhbmNlIEludm9pY2UgKGNyZWF0ZSBvbmx5KTogYmlsbCBzZXZlcmFsIGZ1dHVyZSBtb250aHMgdXBmcm9udC5cbiAgICAgICAgICAgICAgICAgRWFjaCBtb250aCBiZWNvbWVzIGl0cyBvd24gbGluZSBpdGVtIHNlcnZlci1zaWRlLiAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdJZj1cIm1vZGUgPT09ICdjcmVhdGUnXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xIGQtYmxvY2tcIj5BZHZhbmNlIEludm9pY2U8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVjayBmb3JtLXN3aXRjaCBtdC0xXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgaWQ9XCJhZHZhbmNlSW52b2ljZUNyZWF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiYWR2YW5jZUludm9pY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJhZHZhbmNlSW52b2ljZUNyZWF0ZVwiPkJpbGwgZnV0dXJlIG1vbnRocyB1cGZyb250PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItM1wiICpuZ0lmPVwiaW52b2ljZUZvcm0uZ2V0KCdhZHZhbmNlSW52b2ljZScpPy52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+QWR2YW5jZSBmcmVxdWVuY3k8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJhZHZhbmNlUGVyaW9kXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBvcHQgb2YgYWR2YW5jZVBlcmlvZE9wdGlvbnNcIiBbdmFsdWVdPVwib3B0LnZhbHVlXCI+e3sgb3B0LmxhYmVsIH19PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cblxuICAgICAgICAgICAgPCEtLSBQcm9kdWN0cyBTZWN0aW9uIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlY3Rpb24tdGl0bGUgbWItMyBtdC0yXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+UHJvZHVjdHM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1wcmltYXJ5XCIgKGNsaWNrKT1cImFkZFByb2R1Y3QoKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgQWRkIFByb2R1Y3RcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXNlY29uZGFyeVwiIChjbGljayk9XCJhZGRDdXN0b21Qcm9kdWN0KClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICArIEFkZCBDdXN0b20gUHJvZHVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgZm9ybUFycmF5TmFtZT1cInByb2R1Y3RzXCI+XG4gICAgICAgICAgICAgICAgPCEtLSBSb3dzIGNhbiBiZSByZW9yZGVyZWQgYnkgZHJhZ2dpbmcgdGhlIOKLruKLriBoYW5kbGUgb250byBhbm90aGVyIHJvd1xuICAgICAgICAgICAgICAgICAgICAgKG5hdGl2ZSBIVE1MNSBkcmFnICYgZHJvcCDigJQgbm8gQ0RLIGRlcGVuZGVuY3kpLiBUaGUgRm9ybUFycmF5IGlzXG4gICAgICAgICAgICAgICAgICAgICByZS1vcmRlcmVkLCBzbyBudW1iZXJpbmcsIHRvdGFscyBhbmQgdGhlIHNhdmVkIHByb2R1Y3RzIGZvbGxvdy4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgcHJvZHVjdCBvZiBwcm9kdWN0cy5jb250cm9sczsgbGV0IGkgPSBpbmRleFwiIFtmb3JtR3JvdXBOYW1lXT1cImlcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInByb2R1Y3Qtcm93IG1iLTMgcC0zXCIgZGF0YS1wcm9kdWN0LXJvd1xuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZHJhZy1vdmVyXT1cImRyYWdPdmVySW5kZXggPT09IGkgJiYgZHJhZ0luZGV4ICE9PSBudWxsICYmIGRyYWdJbmRleCAhPT0gaVwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5kcmFnZ2luZ109XCJkcmFnSW5kZXggPT09IGlcIlxuICAgICAgICAgICAgICAgICAgICAoZHJhZ292ZXIpPVwib25Sb3dEcmFnT3ZlcigkZXZlbnQsIGkpXCIgKGRyYWdsZWF2ZSk9XCJvblJvd0RyYWdMZWF2ZShpKVwiXG4gICAgICAgICAgICAgICAgICAgIChkcm9wKT1cIm9uUm93RHJvcCgkZXZlbnQsIGkpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZHJhZy1oYW5kbGUgbWUtMlwiIGRyYWdnYWJsZT1cInRydWVcIiB0aXRsZT1cIkRyYWcgdG8gcmVvcmRlclwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChkcmFnc3RhcnQpPVwib25Sb3dEcmFnU3RhcnQoJGV2ZW50LCBpKVwiIChkcmFnZW5kKT1cIm9uUm93RHJhZ0VuZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwcm9kdWN0cy5sZW5ndGggPiAxXCI+JiM4OTQyOyYjODk0Mjs8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcm9kdWN0LWxhYmVsXCI+UHJvZHVjdCB7eyBpICsgMSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1kYW5nZXJcIiAoY2xpY2spPVwicmVtb3ZlUHJvZHVjdChpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwcm9kdWN0cy5sZW5ndGggPiAxXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNCBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UHJvZHVjdCBOYW1lIDxzcGFuIGNsYXNzPVwidGV4dC1kYW5nZXJcIj4qPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBCYXNlLXByaWNpbmcgZHJvcGRvd24gKHdpdGggYSBcIisgQ3VzdG9tIHByb2R1Y3RcIiBjaG9pY2UpIHdoZW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3RzIGV4aXN0IGFuZCB0aGlzIHJvdyBpc24ndCBjdXN0b207IG90aGVyd2lzZSBhIGZyZWUtdGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSBpbnB1dCBmb3IgYSBjdXN0b20gcHJvZHVjdC4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCAqbmdJZj1cImF2YWlsYWJsZVByb2R1Y3RzLmxlbmd0aCA+IDAgJiYgIXByb2R1Y3QuZ2V0KCdpc0N1c3RvbScpPy52YWx1ZVwiIGZvcm1Db250cm9sTmFtZT1cInByb2R1Y3ROYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3Byb2R1Y3ROYW1lJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uUHJvZHVjdENoYW5nZShpKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+U2VsZWN0IHByb2R1Y3Q8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgcCBvZiBhdmFpbGFibGVQcm9kdWN0c1wiIFt2YWx1ZV09XCJwLnByb2R1Y3ROYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBmb3JtYXRQcm9kdWN0TmFtZShwLnByb2R1Y3ROYW1lKSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIl9fY3VzdG9tX19cIj4rIEN1c3RvbSBwcm9kdWN0PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0ICpuZ0lmPVwiYXZhaWxhYmxlUHJvZHVjdHMubGVuZ3RoID09PSAwIHx8IHByb2R1Y3QuZ2V0KCdpc0N1c3RvbScpPy52YWx1ZVwiIHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwicHJvZHVjdE5hbWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3Byb2R1Y3ROYW1lJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImUuZy4gQ3VzdG9tIFNlcnZpY2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1tc2dcIiAqbmdJZj1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3Byb2R1Y3ROYW1lJylcIj5Qcm9kdWN0IE5hbWUgaXMgcmVxdWlyZWQ8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC00IGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5EZXNjcmlwdGlvbjwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwiZGVzY3JpcHRpb25cIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBDdXN0b21lciBGb290ZmFsbCBBbmFseXRpY3NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC00IGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5Nb250aDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwibW9udGhcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBNYXIgMjAyNlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkhTTi9TQUM8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIkhzbk51bWJlclwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UXVhbnRpdHk8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwic3RvcmVDb3VudFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0KT1cInJlY2FsY3VsYXRlKGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+UmF0ZS9QcmljZSA8c3BhbiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+Kjwvc3Bhbj48L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gUmF0ZS9QcmljZSBhY2NlcHRzIGF0IG1vc3QgMiBkZWNpbWFscyAocGFpc2UpOyBleHRyYSBkaWdpdHMgYXJlIHRyaW1tZWQgYXMgdHlwZWQuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgZm9ybUNvbnRyb2xOYW1lPVwicHJpY2VcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHN0ZXA9XCIwLjAxXCIgbWluPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3Byb2R1Y3RzJywgaSwgJ3ByaWNlJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwib25QcmljZUlucHV0KGkpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJhcnJheUNvbnRyb2xJbnZhbGlkKCdwcm9kdWN0cycsIGksICdwcmljZScpXCI+UmF0ZS9QcmljZSBpcyByZXF1aXJlZDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPkFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBmb3JtQ29udHJvbE5hbWU9XCJhbW91bnRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTMgZm9ybS1ncm91cCBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMVwiPlBlcmlvZDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwicGVyaW9kXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJtb250aGx5XCI+TW9udGhseTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwicXVhcnRlcmx5XCI+UXVhcnRlcmx5PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJoYWxmeWVhcmx5XCI+SGFsZi15ZWFybHk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInllYXJseVwiPlllYXJseTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gVGF4IFNlY3Rpb24gLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VjdGlvbi10aXRsZSBtYi0zIG10LTJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5UYXg8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gVGF4IGlzIERFUklWRUQgZnJvbSB0aGUgR1NUIG51bWJlciAoR1NUSU4gJzMz4oCmJyDihpIgQ0dTVCA5JSArIFNHU1QgOSUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgYW55IG90aGVyIEdTVElOIOKGkiBJR1NUIDE4JSwgbm9uZSDihpIgbm8gdGF4KSwgc28gdGhlcmUgaXMgbm8gbWFudWFsXG4gICAgICAgICAgICAgICAgICAgICAgICAgXCJBZGQgVGF4XCIgYW5kIHRoZSByb3dzIGFyZSByZWFkLW9ubHk7IGEgdGF4IGxpbmUgY2FuIHN0aWxsIGJlXG4gICAgICAgICAgICAgICAgICAgICAgICAgUkVNT1ZFRCB2aWEgZWFjaCByb3cncyBSZW1vdmUgYnV0dG9uLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsXCI+Q2FsY3VsYXRlZCBmcm9tIEdTVCBOdW1iZXI8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBmb3JtQXJyYXlOYW1lPVwidGF4XCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdCBvZiB0YXhBcnJheS5jb250cm9sczsgbGV0IGogPSBpbmRleFwiIFtmb3JtR3JvdXBOYW1lXT1cImpcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInRheC1yb3cgbWItMyBwLTNcIiBkYXRhLXRheC1yb3c+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJvZHVjdC1sYWJlbFwiPlRheCB7eyBqICsgMSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1kYW5nZXJcIiAoY2xpY2spPVwicmVtb3ZlVGF4KGopXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtb3ZlXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+VGF4IFR5cGUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFRoZSAndHlwZScgY29udHJvbCBpcyBjcmVhdGVkIGRpc2FibGVkIChkZXJpdmVkIGZyb20gdGhlIEdTVElOKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBmb3JtIHBvc3RzIHZpYSBnZXRSYXdWYWx1ZSgpIHNvIGl0IHN0aWxsIHJlYWNoZXMgdGhlIHBheWxvYWQuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiIGZvcm1Db250cm9sTmFtZT1cInR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uVGF4VHlwZUNoYW5nZShqKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cImFycmF5Q29udHJvbEludmFsaWQoJ3RheCcsIGosICd0eXBlJylcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiAqbmdGb3I9XCJsZXQgdHQgb2YgdGF4VHlwZXNcIiBbdmFsdWVdPVwidHRcIj57eyB0dCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLW1zZ1wiICpuZ0lmPVwiYXJyYXlDb250cm9sSW52YWxpZCgndGF4JywgaiwgJ3R5cGUnKVwiPlRheCBUeXBlIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+VGF4ICUgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cIm51bWJlclwiIGZvcm1Db250cm9sTmFtZT1cInZhbHVlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkb25seVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJhcnJheUNvbnRyb2xJbnZhbGlkKCd0YXgnLCBqLCAndmFsdWUnKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dCk9XCJyZWNhbGN1bGF0ZSgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtbXNnXCIgKm5nSWY9XCJhcnJheUNvbnRyb2xJbnZhbGlkKCd0YXgnLCBqLCAndmFsdWUnKVwiPlRheCAlIGlzIHJlcXVpcmVkPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMyBmb3JtLWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0xXCI+VGF4IEFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwidGF4QW1vdW50XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC0zIGZvcm0tZ3JvdXAgbWItMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTFcIj5DdXJyZW5jeSBTeW1ib2w8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cImN1cnJlbmN5XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIFN1bW1hcnkgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1zZWN0aW9uIHAtMyBtdC0zXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPlN1YnRvdGFsPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19IHt7IGdldFN1YnRvdGFsKCkgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gbWItMlwiICpuZ0lmPVwiZ2V0QXBwbGllZERpc2NvdW50KCkgPiAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPkRpc2NvdW50PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj4tIHt7IGdldEN1cnJlbmN5U3ltYm9sKCkgfX0ge3sgZ2V0QXBwbGllZERpc2NvdW50KCkgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gbWItMlwiICpuZ0lmPVwiZ2V0VG90YWxUYXgoKSA+IDBcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LWxhYmVsXCI+VG90YWwgVGF4PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktdmFsdWVcIj57eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19IHt7IGdldFRvdGFsVGF4KCkgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gc3VtbWFyeS10b3RhbFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktbGFiZWwtYm9sZFwiPlRvdGFsIEFtb3VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdW1tYXJ5LXZhbHVlLWJvbGRcIj57eyBnZXRDdXJyZW5jeVN5bWJvbCgpIH19IHt7IGdldFRvdGFsQW1vdW50KCkgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nXG4gICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8IS0tIEFjdGlvbnMgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IG10LTRcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gY2FuY2VsIG1lLTQgdy01MFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIFtkaXNhYmxlZF09XCJzYXZpbmdcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBweC00IHctNTBcIiBzdHlsZT1cIndoaXRlLXNwYWNlOiBub3dyYXA7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiIXNhdmluZ1wiIGNsYXNzPVwic3VibWl0XCI+e3sgbW9kZSA9PT0gJ2VkaXQnID8gJ1VwZGF0ZSBJbnZvaWNlJyA6IChtb2RlID09PSAnZXN0aW1hdGUnID8gJ0dlbmVyYXRlIEVzdGltYXRlJyA6IChtb2RlID09PSAnZWRpdEVzdGltYXRlJyA/ICdVcGRhdGUgRXN0aW1hdGUnIDogJ0NyZWF0ZSBJbnZvaWNlJykpXG4gICAgICAgICAgICAgICAgICAgICAgICB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzYXZpbmdcIiBjbGFzcz1cInN1Ym1pdFwiPlNhdmluZy4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zvcm0+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tID09PT09PT09PT09PT09PT09PT09PT09PSBDUkVESVQgTk9URSBUQUIgPT09PT09PT09PT09PT09PT09PT09PT09IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IG1iLTRcIiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2NyZWRpdE5vdGUnICYmIG1vZGUgPT09ICdlZGl0J1wiPlxuICAgICAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImNyZWRpdE5vdGVGb3JtXCIgY2xhc3M9XCJmb3JtXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudHRleHQgbWItM1wiPlxuICAgICAgICAgICAgICAgIEFwcGx5IGEgY3JlZGl0IG5vdGUgLyBkaXNjb3VudCB0byB0aGlzIGludm9pY2UuXG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPkludm9pY2UgSUQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFt2YWx1ZV09XCJpbnZvaWNlRGF0YT8uaW52b2ljZVwiIHJlYWRvbmx5PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXAgcHktMlwiPlxuICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+VG90YWwgQW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRvbGxhci1zaWduXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgZm9ybUNvbnRyb2xOYW1lPVwiYW1vdW50XCIgdHlwZT1cInRleHRcIiByZWFkb25seSBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBtdC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJoZWFkaW5ndGV4dCBtYi0yXCI+RGlzY291bnQgQW1vdW50PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZG9sbGFyLXNpZ25cIj57eyBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBmb3JtQ29udHJvbE5hbWU9XCJkaXNjb3VudEFtb3VudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlwcmVzcyk9XCJvbWl0U3BlY2lhbENoYXJEZWNpbWFsKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAnZXJyb3JpbnB1dCcgOiAnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBbbmdDbGFzc109XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAndGV4dC1kYW5nZXInIDogJ2NvbnRlbnR0ZXh0J1wiIGNsYXNzPVwic21hbGxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIENyZWRpdCB2YWx1ZSBkZWR1Y3RlZCBmcm9tIHRoZSBpbnZvaWNlXG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5SZXZpc2VkIEFtb3VudDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRvbGxhci1zaWduXCI+e3sgZ2V0SW52b2ljZUN1cnJlbmN5U3ltYm9sKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgZm9ybUNvbnRyb2xOYW1lPVwicmV2aXNlZEFtb3VudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChrZXlwcmVzcyk9XCJvbWl0U3BlY2lhbENoYXJEZWNpbWFsKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgPyAnZXJyb3JpbnB1dCcgOiAnJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtaWNvblwiICpuZ0lmPVwiY3JlZGl0TW9yZVRoYW5UZW5QZXJjZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxnIGNsaXAtcGF0aD1cInVybCgjY2xpcF9jbl9lcnIpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZD1cIk03Ljk5OTY3IDUuMzMzMDFWNy45OTk2N003Ljk5OTY3IDEwLjY2NjNIOC4wMDYzNE0xNC42NjYzIDcuOTk5NjdDMTQuNjY2MyAxMS42ODE2IDExLjY4MTYgMTQuNjY2MyA3Ljk5OTY3IDE0LjY2NjNDNC4zMTc3OCAxNC42NjYzIDEuMzMzMDEgMTEuNjgxNiAxLjMzMzAxIDcuOTk5NjdDMS4zMzMwMSA0LjMxNzc4IDQuMzE3NzggMS4zMzMwMSA3Ljk5OTY3IDEuMzMzMDFDMTEuNjgxNiAxLjMzMzAxIDE0LjY2NjMgNC4zMTc3OCAxNC42NjYzIDcuOTk5NjdaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlPVwiI0YwNDQzOFwiIHN0cm9rZS13aWR0aD1cIjEuMzMzMzNcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRlZnM+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNsaXBQYXRoIGlkPVwiY2xpcF9jbl9lcnJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJlY3Qgd2lkdGg9XCIxNlwiIGhlaWdodD1cIjE2XCIgZmlsbD1cIndoaXRlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2NsaXBQYXRoPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kZWZzPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIFtuZ0NsYXNzXT1cImNyZWRpdE1vcmVUaGFuVGVuUGVyY2VudCA/ICd0ZXh0LWRhbmdlcicgOiAnY29udGVudHRleHQnXCIgY2xhc3M9XCJzbWFsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgRW50ZXIgYSB2YWxpZCByZXZpc2VkIGFtb3VudFxuICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBtdC01XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLW91dGxpbmUgYnRuIGNhbmNlbCBtZS00IHctNTBcIj5DYW5jZWw8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCJjcmVkaXRNb3JlVGhhblRlblBlcmNlbnQgfHwgc2F2aW5nXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJhcHBseUNyZWRpdE5vdGUoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IHB4LTQgdy01MFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhc2F2aW5nXCI+QXBwbHkgQ3JlZGl0IE5vdGU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic2F2aW5nXCI+QXBwbHlpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9mb3JtPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSA9PT09PT09PT09PT09PT09PT09PT09PT0gT05FIFRJTUUgRkVFIFRBQiA9PT09PT09PT09PT09PT09PT09PT09PT0gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHkgbWItNFwiICpuZ0lmPVwiYWN0aXZlVGFiID09PSAnb25lVGltZUZlZScgJiYgbW9kZSA9PT0gJ2VkaXQnXCI+XG4gICAgICAgIDxmb3JtIFtmb3JtR3JvdXBdPVwib25lVGltZUZlZUZvcm1cIiBjbGFzcz1cImZvcm1cIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb250ZW50dGV4dCBtYi0zXCI+XG4gICAgICAgICAgICAgICAgQWRkIGEgb25lLXRpbWUgZmVlIChlLmcuIGluc3RhbGxhdGlvbikgdG8gdGhpcyBpbnZvaWNlLlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBweS0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5JbnZvaWNlIElEPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBbdmFsdWVdPVwiaW52b2ljZURhdGE/Lmludm9pY2VcIiByZWFkb25seT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIHB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiaGVhZGluZ3RleHQgbWItMlwiPkN1cnJlbnQgSW52b2ljZSBBbW91bnQ8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZG9sbGFyLXNpZ25cIj57eyBnZXRJbnZvaWNlQ3VycmVuY3lTeW1ib2woKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBmb3JtQ29udHJvbE5hbWU9XCJhbW91bnRcIiB0eXBlPVwidGV4dFwiIHJlYWRvbmx5IGNsYXNzPVwiZm9ybS1jb250cm9sIGFtb3VudC1pbnB1dFwiPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIG10LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInB5LTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImhlYWRpbmd0ZXh0IG1iLTJcIj5PbmUgVGltZSBGZWUgKEluc3RhbGxhdGlvbik8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkb2xsYXItc2lnblwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGZvcm1Db250cm9sTmFtZT1cIm9uZVRpbWVGZWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoa2V5cHJlc3MpPVwib21pdFNwZWNpYWxDaGFyKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBhbW91bnQtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkVudGVyIGZlZSBhbW91bnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1zdGFjayBtdC0zIGZlZS1zdW1tYXJ5IHAtM1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3VtbWFyeS1sYWJlbFwiPlNlbGVjdGVkIEludm9pY2UgQW1vdW50ICsgT25lIFRpbWUgRmVlPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN1bW1hcnktdmFsdWUtYm9sZFwiPnt7IGdldEludm9pY2VDdXJyZW5jeVN5bWJvbCgpIH19e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmVUaW1lRmVlVG90YWwgfCBudW1iZXI6JzEuMi0yJzonZW4tSU4nIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IG10LTVcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tb3V0bGluZSBidG4gY2FuY2VsIG1lLTQgdy01MFwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cInNhdmluZyB8fCAhb25lVGltZUZlZUZvcm0uZ2V0KCdvbmVUaW1lRmVlJyk/LnZhbHVlXCIgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseU9uZVRpbWVGZWUoKVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IHB4LTQgdy01MFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6IG5vd3JhcDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhc2F2aW5nXCI+QXBwbHkgRmVlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInNhdmluZ1wiPkFwcGx5aW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZm9ybT5cbiAgICA8L2Rpdj5cbjwvZGl2PiJdfQ==