tango-app-ui-manage-billing 3.3.39 → 3.3.41

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.
@@ -165,12 +165,15 @@ export class InvoicePreviewComponent {
165
165
  euro: '€',
166
166
  aed: 'AED',
167
167
  };
168
- // Words form of each currency for the "Amount in words" line.
168
+ // Words form of each currency for the "Amount in words" line. PLURAL by
169
+ // ruling (2026-08-27) — "US Dollars Eight Hundred ... Only" — and kept in
170
+ // step with the backend PDF's CURRENCY_WORDS (utils/currency.js).
169
171
  currencyWords = {
170
- inr: 'Indian Rupee',
171
- dollar: 'US Dollar',
172
- singaporedollar: 'Singapore Dollar',
173
- euro: 'Euro',
172
+ inr: 'Indian Rupees',
173
+ dollar: 'US Dollars',
174
+ singaporedollar: 'Singapore Dollars',
175
+ euro: 'Euros',
176
+ aed: 'UAE Dirhams',
174
177
  };
175
178
  // Fractional (sub-unit) name per currency for the cents portion of the
176
179
  // "Total In Words" line. INR is whole-number only, so it has no fraction.
@@ -202,7 +205,7 @@ export class InvoicePreviewComponent {
202
205
  }
203
206
  get totalInWords() {
204
207
  const code = this.invoiceData?.currency;
205
- const words = this.currencyWords[code || ''] || 'US Dollar';
208
+ const words = this.currencyWords[code || ''] || 'US Dollars';
206
209
  const value = Number(this.invoiceData?.totalAmount || 0);
207
210
  // INR is whole-number only — render just the rupee words. Every other
208
211
  // currency keeps 2 decimals, so spell out the cents too when non-zero.
@@ -269,12 +272,12 @@ export class InvoicePreviewComponent {
269
272
  return index;
270
273
  }
271
274
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InvoicePreviewComponent, deps: [{ token: i1.NgbActiveModal }, { token: i2.BillingService }, { token: i3.ToastService }], target: i0.ɵɵFactoryTarget.Component });
272
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: InvoicePreviewComponent, selector: "lib-invoice-preview", inputs: { invoiceData: "invoiceData" }, ngImport: i0, template: "<div class=\"invoice-preview-modal\">\n <div class=\"modal-header\">\n <ul class=\"nav nav-tabs preview-tabs\" role=\"tablist\">\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'invoice'\"\n (click)=\"selectTab('invoice')\" type=\"button\">Invoice</button>\n </li>\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'annexure'\"\n (click)=\"selectTab('annexure')\" type=\"button\">Annexure</button>\n </li>\n </ul>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\" aria-label=\"Close\"></button>\n </div>\n\n <div class=\"modal-body p-0\">\n <!-- INVOICE TAB -->\n <div *ngIf=\"activeTab === 'invoice'\" class=\"invoice-page\">\n <!-- Header row -->\n <div class=\"row align-items-start\">\n <div class=\"col-7\">\n <div class=\"brand\">\n <img src=\"./assets/tango/Images/tangoeye-logo.svg\" alt=\"TangoEye\" class=\"brand-logo\" onerror=\"this.style.display='none'\">\n </div>\n <div class=\"company-block mt-3\">\n <div class=\"company-name\">TANGO IT SOLUTIONS INDIA PRIVATE LTD</div>\n <div>2nd Floor, Apeejay Business Centre, No.12/39,</div>\n <div>Haddows Road, Nungambakkam</div>\n <div>Chennai Tamil Nadu 600006, India</div>\n <div class=\"mt-1\"><strong>GSTIN 33AAGCT3124R1Z2</strong></div>\n <div class=\"mt-1\">MSME / Udyam type : Micro</div>\n <div>MSME / Udyam No. : UDYAM-TN-03-0212399</div>\n </div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"tax-invoice-label\">TAX INVOICE</div>\n <div class=\"invoice-number\"># {{ invoiceData?.invoice }}</div>\n </div>\n </div>\n\n <!-- Bill-to + totals row -->\n <div class=\"row mt-4\">\n <div class=\"col-7\">\n <div class=\"bill-to-label\">BILL TO :</div>\n <div class=\"client-name mt-1\">{{ (invoiceData?.clientName || invoiceData?.companyName) | uppercase }}</div>\n <div class=\"mt-1\" *ngIf=\"invoiceData?.billingAddressLineOne || invoiceData?.companyAddress\">\n {{ invoiceData?.billingAddressLineOne || invoiceData?.companyAddress }}\n </div>\n <div *ngIf=\"invoiceData?.billingAddressLineTwo\">{{ invoiceData?.billingAddressLineTwo }}</div>\n <div *ngIf=\"invoiceData?.billingCity || invoiceData?.billingPinCode || invoiceData?.billingState\">\n {{ invoiceData?.billingCity }}<span *ngIf=\"invoiceData?.billingPinCode\">, {{ invoiceData?.billingPinCode }}</span><span *ngIf=\"invoiceData?.billingState\">, {{ invoiceData?.billingState }}</span><span *ngIf=\"invoiceData?.billingCountry\">, {{ invoiceData?.billingCountry }}</span>\n </div>\n <div class=\"mt-2\" *ngIf=\"invoiceData?.GSTNumber\"><strong>GSTIN {{ invoiceData?.GSTNumber }}</strong></div>\n <div *ngIf=\"invoiceData?.PlaceOfSupply\">Place Of Supply: {{ invoiceData?.PlaceOfSupply }}</div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"invoice-total-label\">Invoice Total <span class=\"invoice-total-amount\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount) }}</span></div>\n <table class=\"meta-table ms-auto mt-3\">\n <tr><td class=\"meta-label\">Invoice date :</td><td class=\"meta-value\">{{ invoiceData?.billingDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr><td class=\"meta-label\">Terms :</td><td class=\"meta-value\">Term {{ paymentTermDays }}</td></tr>\n <tr><td class=\"meta-label\">Due Date :</td><td class=\"meta-value\">{{ invoiceData?.dueDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr *ngIf=\"invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber\"><td class=\"meta-label\">P.O.# :</td><td class=\"meta-value\">{{ invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber }}</td></tr>\n </table>\n </div>\n </div>\n\n <!-- Line items -->\n <table class=\"items-table mt-4\">\n <thead>\n <tr>\n <th class=\"col-index\">#</th>\n <th class=\"col-product\">Product &amp; Description</th>\n <th class=\"col-month\">Month</th>\n <th class=\"col-hsn\">HSN/SAC</th>\n <th class=\"col-count text-center\">Quantity</th>\n <th class=\"col-rate text-end\">Rate</th>\n <th class=\"col-amount text-end\">Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of visibleProducts(); let i = index; trackBy: trackByIndex\">\n <td>{{ i + 1 }}</td>\n <td>\n <div class=\"product-name\">{{ formatProductName(item?.productName) }}</div>\n <div class=\"product-desc\">{{ item?.description }}</div>\n </td>\n <!-- Month is the product's billing month stored on the line item\n (advance invoices bill a future month while billingDate is the\n creation date). Fall back to billingDate for legacy rows. -->\n <td class=\"nowrap\">{{ item?.month || (invoiceData?.billingDate | date:'MMM yyyy') }}</td>\n <td>{{ item?.hsn || item?.hsnCode || '998314' }}</td>\n <td class=\"text-center\"><strong>{{ item?.storeCount || invoiceData?.stores?.length || '' }}</strong></td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.price) }}</td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.amount) }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- Totals -->\n <div class=\"row mt-3\">\n <div class=\"col-7\"></div>\n <div class=\"col-5\">\n <table class=\"totals-table ms-auto\">\n <!-- With a discount, tell the story top-down: Original Amount minus\n Discount gives the Sub Total (the GST base). Without one, the\n Sub Total row alone suffices. -->\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Sub Total</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(originalAmount()) }}</td>\n </tr>\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Discount</td>\n <td class=\"totals-value\">- {{ currencySymbol() }} {{ formatINR(invoiceData?.discountAmount) }}</td>\n </tr>\n <tr><td class=\"totals-label\">Sub Total</td><td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.amount) }}</td></tr>\n <ng-container *ngFor=\"let t of invoiceData?.tax\">\n <tr *ngIf=\"hasTax(t)\">\n <td class=\"totals-label\">{{ t?.type || t?.taxName || t?.name }} ({{ t?.value ?? t?.taxPercentage ?? t?.percentage }}%)</td>\n <td class=\"totals-value nowrap\">{{ currencySymbol() }} {{ formatINR(t?.taxAmount) }}</td>\n </tr>\n </ng-container>\n <tr class=\"totals-total-row\">\n <td class=\"totals-label\">Total Amount</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount, true) }}</td>\n </tr>\n <tr class=\"totals-words-row\">\n <td class=\"totals-label\">Total In Words</td>\n <td class=\"totals-value words\">{{ totalInWords }}</td>\n </tr>\n </table>\n </div>\n </div>\n\n <!-- Payment details -->\n <div class=\"thanks mt-4\">Thanks for your business!</div>\n <table class=\"payment-table mt-2\">\n <tr><td class=\"payment-label\">Beneficiary Name</td><td class=\"payment-value\"><strong>{{ bankDetails?.beneficiaryName }}</strong></td></tr>\n <tr><td class=\"payment-label\">Account Number</td><td class=\"payment-value\"><strong>{{ bankDetails?.accountNumber }}</strong></td></tr>\n <tr><td class=\"payment-label\">IFSC Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.ifsc }}</strong></td></tr>\n <tr><td class=\"payment-label\">Payment Type</td><td class=\"payment-value\"><strong>{{ bankDetails?.paymentType }}</strong></td></tr>\n <tr><td class=\"payment-label\">SWIFT Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.swift }}</strong></td></tr>\n <tr><td class=\"payment-label\">Branch</td><td class=\"payment-value\"><strong>{{ bankDetails?.branch }}</strong></td></tr>\n </table>\n\n <div class=\"system-note mt-4\">This is a system generated invoice. No signature required</div>\n </div>\n\n <!-- ANNEXURE TAB -->\n <div *ngIf=\"activeTab === 'annexure'\" class=\"annexure-page\">\n <div *ngIf=\"annexureLoading\" class=\"loading-state\">\n <div class=\"spinner-border text-primary\" role=\"status\"><span class=\"visually-hidden\">Loading...</span></div>\n </div>\n <div *ngIf=\"!annexureLoading && annexureError\" class=\"error-state\">\n <p>Failed to load annexure.</p>\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"retryAnnexure()\">Retry</button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData !== null && annexureData.length === 0\" class=\"empty-state\">\n No annexure data for this invoice.\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-toolbar\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"downloadAnnexureXlsx()\">\n Export as XLSX\n </button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-scroll\">\n <table class=\"annexure-table\">\n <colgroup>\n <col class=\"col-store\" />\n <col class=\"col-product\" />\n <col class=\"col-id\" />\n <col class=\"col-date\" />\n <col class=\"col-days\" />\n <col class=\"col-qty\" />\n <col class=\"col-price\" />\n <col class=\"col-total\" />\n </colgroup>\n <thead>\n <tr>\n <th>Store Name</th>\n <th>Products</th>\n <th>Store ID</th>\n <th>Deployment Date</th>\n <th class=\"text-center\">Billing Days</th>\n <th class=\"text-center\">Qty</th>\n <th class=\"text-end\">Unit Price</th>\n <th class=\"text-end\">Price Per Month</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of annexureData; trackBy: trackByIndex\">\n <td class=\"cell-store\">{{ row?.storeName }}</td>\n <td>{{ row?.productName }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.storeId }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.edgefirstFileDate }}</td>\n <td class=\"text-center\"><strong>{{ row?.workingdays }}</strong></td>\n <td class=\"text-center\">{{ row?.units ?? 1 }}</td>\n <td class=\"text-end cell-nowrap cell-num\">\n {{ row?.currencyType }} {{ formatINR(row?.standardPrice) }}\n <div class=\"unit-basis\">{{ row?.unitBasis || 'Per Store' }}</div>\n </td>\n <td class=\"text-end cell-nowrap cell-num cell-total\">\n <strong>{{ row?.currencyType }} {{ formatINR(row?.runningCost) }}</strong>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"annexureTotal != null\">\n <tr>\n <td colspan=\"7\" class=\"text-end\"><strong>Total</strong></td>\n <td class=\"text-end cell-num cell-total\">\n <strong>{{ annexureData[0]?.currencyType }} {{ formatINR(annexureTotal) }}</strong>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-link\" (click)=\"activeModal.dismiss()\">Close</button>\n <button class=\"btn btn-outline-primary\" (click)=\"downloadPdf()\" [disabled]=\"downloading\">\n <span *ngIf=\"!downloading\">Download PDF</span>\n <span *ngIf=\"downloading\">Downloading...</span>\n </button>\n </div>\n</div>", styles: [".invoice-preview-modal{font-family:inherit;font-size:13px;color:#344054;display:flex;flex-direction:column;max-height:calc(100vh - 3.5rem)}.invoice-preview-modal .modal-header{flex:0 0 auto;padding:0 1rem;border-bottom:1px solid #EAECF0;display:flex;align-items:stretch;justify-content:space-between}.invoice-preview-modal .modal-header .preview-tabs{border-bottom:none}.invoice-preview-modal .modal-header .preview-tabs .nav-link{border:none;border-radius:0;color:#667085;padding:12px 16px;background:transparent}.invoice-preview-modal .modal-header .preview-tabs .nav-link.active{color:#00a3ff;border-bottom:2px solid #00A3FF;background:transparent}.invoice-preview-modal .modal-header .btn-close{align-self:center}.invoice-preview-modal .modal-body{background:#fff;flex:1 1 auto;overflow-y:auto;min-height:0}.invoice-preview-modal .invoice-page,.invoice-preview-modal .annexure-page{padding:32px 40px}.invoice-preview-modal .tax-invoice-label{font-size:22px;font-weight:600;color:#00a3ff}.invoice-preview-modal .invoice-number{font-size:18px;font-weight:600;color:#00a3ff}.invoice-preview-modal .company-name{font-weight:700;color:#101828}.invoice-preview-modal .bill-to-label{font-weight:600;color:#667085}.invoice-preview-modal .client-name{font-weight:700;color:#101828;font-size:15px}.invoice-preview-modal .invoice-total-label{font-weight:600;font-size:15px}.invoice-preview-modal .invoice-total-label .invoice-total-amount{color:#101828;font-weight:700;margin-left:8px}.invoice-preview-modal .meta-table td{padding:2px 8px}.invoice-preview-modal .meta-table .meta-label{color:#667085;text-align:right}.invoice-preview-modal .meta-table .meta-value{color:#101828;font-weight:600}.invoice-preview-modal .items-table{width:100%;border-collapse:collapse}.invoice-preview-modal .items-table th{background:#f2f4f7;padding:12px;font-weight:600;color:#344054;text-align:left}.invoice-preview-modal .items-table td{padding:14px 12px;border-bottom:1px solid #EAECF0;vertical-align:top}.invoice-preview-modal .items-table .product-name{font-weight:600;color:#101828}.invoice-preview-modal .items-table .product-desc{color:#667085;font-size:12px}.invoice-preview-modal .items-table .col-index{width:40px}.invoice-preview-modal .items-table .col-month,.invoice-preview-modal .items-table .col-hsn,.invoice-preview-modal .items-table .col-count{width:100px}.invoice-preview-modal .items-table .col-rate{width:110px}.invoice-preview-modal .items-table .col-amount{width:140px}.invoice-preview-modal .items-table .nowrap{white-space:nowrap}.invoice-preview-modal .totals-table{width:100%}.invoice-preview-modal .totals-table td{padding:6px 12px}.invoice-preview-modal .totals-table .totals-label{color:#667085;text-align:right}.invoice-preview-modal .totals-table .totals-value{color:#101828;font-weight:600;text-align:right}.invoice-preview-modal .totals-table .totals-total-row td{padding-top:12px}.invoice-preview-modal .totals-table .totals-total-row .totals-value{font-size:15px;font-weight:700}.invoice-preview-modal .totals-table .totals-words-row .words{font-weight:600;max-width:280px;white-space:normal;word-wrap:break-word}.invoice-preview-modal .totals-table .nowrap{white-space:nowrap}.invoice-preview-modal .thanks{font-weight:600;color:#101828}.invoice-preview-modal .payment-table{border-collapse:collapse}.invoice-preview-modal .payment-table td{padding:6px 12px}.invoice-preview-modal .payment-table .payment-label{color:#667085}.invoice-preview-modal .system-note{color:#667085;font-size:12px;font-weight:600}.invoice-preview-modal .annexure-scroll{width:100%;border:1px solid #EAECF0;border-radius:8px}.invoice-preview-modal .annexure-table{width:100%;table-layout:fixed;border-collapse:collapse;font-size:13px}.invoice-preview-modal .annexure-table .col-store{width:22%}.invoice-preview-modal .annexure-table .col-product{width:16%}.invoice-preview-modal .annexure-table .col-id{width:9%}.invoice-preview-modal .annexure-table .col-date{width:12%}.invoice-preview-modal .annexure-table .col-days{width:9%}.invoice-preview-modal .annexure-table .col-qty{width:7%}.invoice-preview-modal .annexure-table .col-price{width:12%}.invoice-preview-modal .annexure-table .col-total{width:13%}.invoice-preview-modal .annexure-table th{position:sticky;top:0;z-index:1;background:#f2f4f7;padding:10px 12px;font-weight:600;font-size:12px;color:#344054;text-align:left;border-bottom:1px solid #EAECF0}.invoice-preview-modal .annexure-table td{padding:10px 12px;border-bottom:1px solid #F2F4F7;color:#101828;vertical-align:middle}.invoice-preview-modal .annexure-table tbody tr:nth-child(2n) td{background:#fcfcfd}.invoice-preview-modal .annexure-table tbody tr:hover td{background:#f9fafb}.invoice-preview-modal .annexure-table .cell-store{font-weight:600}.invoice-preview-modal .annexure-table .cell-nowrap{white-space:nowrap}.invoice-preview-modal .annexure-table .cell-muted{color:#667085}.invoice-preview-modal .annexure-table .cell-num{font-variant-numeric:tabular-nums}.invoice-preview-modal .annexure-table .cell-total strong{color:#101828}.invoice-preview-modal .annexure-table .unit-basis{font-size:11px;color:#98a2b3;margin-top:2px}.invoice-preview-modal .annexure-table tfoot td{position:sticky;bottom:0;background:#f9fafb;border-top:2px solid #EAECF0;border-bottom:none;font-size:14px}.invoice-preview-modal .loading-state,.invoice-preview-modal .empty-state,.invoice-preview-modal .error-state{padding:40px;text-align:center;color:#667085}.invoice-preview-modal .modal-footer{flex:0 0 auto}.invoice-preview-modal .annexure-toolbar{display:flex;justify-content:flex-end;padding:8px 0 12px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i4.DatePipe, name: "date" }] });
275
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: InvoicePreviewComponent, selector: "lib-invoice-preview", inputs: { invoiceData: "invoiceData" }, ngImport: i0, template: "<div class=\"invoice-preview-modal\">\n <div class=\"modal-header\">\n <ul class=\"nav nav-tabs preview-tabs\" role=\"tablist\">\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'invoice'\"\n (click)=\"selectTab('invoice')\" type=\"button\">Invoice</button>\n </li>\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'annexure'\"\n (click)=\"selectTab('annexure')\" type=\"button\">Annexure</button>\n </li>\n </ul>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\" aria-label=\"Close\"></button>\n </div>\n\n <div class=\"modal-body p-0\">\n <!-- INVOICE TAB -->\n <div *ngIf=\"activeTab === 'invoice'\" class=\"invoice-page\">\n <!-- Header row -->\n <div class=\"row align-items-start\">\n <div class=\"col-7\">\n <div class=\"brand\">\n <img src=\"./assets/tango/Images/tangoeye-logo.svg\" alt=\"TangoEye\" class=\"brand-logo\" onerror=\"this.style.display='none'\">\n </div>\n <div class=\"company-block mt-3\">\n <div class=\"company-name\">TANGO IT SOLUTIONS INDIA PRIVATE LTD</div>\n <div>2nd Floor, Apeejay Business Centre, No.12/39,</div>\n <div>Haddows Road, Nungambakkam</div>\n <div>Chennai Tamil Nadu 600006, India</div>\n <div class=\"mt-1\"><strong>GSTIN 33AAGCT3124R1Z2</strong></div>\n <div class=\"mt-1\">MSME / Udyam type : Micro</div>\n <div>MSME / Udyam No. : UDYAM-TN-03-0212399</div>\n </div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"tax-invoice-label\">TAX INVOICE</div>\n <div class=\"invoice-number\"># {{ invoiceData?.invoice }}</div>\n </div>\n </div>\n\n <!-- Bill-to + totals row -->\n <div class=\"row mt-4\">\n <div class=\"col-7\">\n <div class=\"bill-to-label\">BILL TO :</div>\n <div class=\"client-name mt-1\">{{ (invoiceData?.clientName || invoiceData?.companyName) | uppercase }}</div>\n <div class=\"mt-1\" *ngIf=\"invoiceData?.billingAddressLineOne || invoiceData?.companyAddress\">\n {{ invoiceData?.billingAddressLineOne || invoiceData?.companyAddress }}\n </div>\n <div *ngIf=\"invoiceData?.billingAddressLineTwo\">{{ invoiceData?.billingAddressLineTwo }}</div>\n <div *ngIf=\"invoiceData?.billingCity || invoiceData?.billingPinCode || invoiceData?.billingState\">\n {{ invoiceData?.billingCity }}<span *ngIf=\"invoiceData?.billingPinCode\">, {{ invoiceData?.billingPinCode }}</span><span *ngIf=\"invoiceData?.billingState\">, {{ invoiceData?.billingState }}</span><span *ngIf=\"invoiceData?.billingCountry\">, {{ invoiceData?.billingCountry }}</span>\n </div>\n <div class=\"mt-2\" *ngIf=\"invoiceData?.GSTNumber\"><strong>GSTIN {{ invoiceData?.GSTNumber }}</strong></div>\n <div *ngIf=\"invoiceData?.PlaceOfSupply\">Place Of Supply: {{ invoiceData?.PlaceOfSupply }}</div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"invoice-total-label\">Invoice Total <span class=\"invoice-total-amount\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount) }}</span></div>\n <table class=\"meta-table ms-auto mt-3\">\n <tr><td class=\"meta-label\">Invoice date :</td><td class=\"meta-value\">{{ invoiceData?.billingDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr><td class=\"meta-label\">Terms :</td><td class=\"meta-value\">Term {{ paymentTermDays }}</td></tr>\n <tr><td class=\"meta-label\">Due Date :</td><td class=\"meta-value\">{{ invoiceData?.dueDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr *ngIf=\"invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber\"><td class=\"meta-label\">P.O.# :</td><td class=\"meta-value\">{{ invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber }}</td></tr>\n </table>\n </div>\n </div>\n\n <!-- Line items -->\n <table class=\"items-table mt-4\">\n <thead>\n <tr>\n <th class=\"col-index\">#</th>\n <th class=\"col-product\">Product &amp; Description</th>\n <th class=\"col-month\">Month</th>\n <th class=\"col-hsn\">HSN/SAC</th>\n <th class=\"col-count text-center\">Quantity</th>\n <th class=\"col-rate text-end\">Rate</th>\n <th class=\"col-amount text-end\">Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of visibleProducts(); let i = index; trackBy: trackByIndex\">\n <td>{{ i + 1 }}</td>\n <td>\n <div class=\"product-name\">{{ formatProductName(item?.productName) }}</div>\n <div class=\"product-desc\">{{ item?.description }}</div>\n </td>\n <!-- Month is the product's billing month stored on the line item\n (advance invoices bill a future month while billingDate is the\n creation date). Fall back to billingDate for legacy rows. -->\n <td class=\"nowrap\">{{ item?.month || (invoiceData?.billingDate | date:'MMM yyyy') }}</td>\n <td>{{ item?.hsn || item?.hsnCode || '998314' }}</td>\n <td class=\"text-center\"><strong>{{ item?.storeCount || invoiceData?.stores?.length || '' }}</strong></td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.price) }}</td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.amount) }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- Totals -->\n <div class=\"row mt-3\">\n <div class=\"col-7\"></div>\n <div class=\"col-5\">\n <table class=\"totals-table ms-auto\">\n <!-- With a discount, tell the story top-down: Original Amount minus\n Discount gives the Sub Total (the GST base). Without one, the\n Sub Total row alone suffices. -->\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Sub Total</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(originalAmount()) }}</td>\n </tr>\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Discount</td>\n <td class=\"totals-value\">- {{ currencySymbol() }} {{ formatINR(invoiceData?.discountAmount) }}</td>\n </tr>\n <tr><td class=\"totals-label\">Sub Total</td><td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.amount) }}</td></tr>\n <ng-container *ngFor=\"let t of invoiceData?.tax\">\n <tr *ngIf=\"hasTax(t)\">\n <td class=\"totals-label\">{{ t?.type || t?.taxName || t?.name }} ({{ t?.value ?? t?.taxPercentage ?? t?.percentage }}%)</td>\n <td class=\"totals-value nowrap\">{{ currencySymbol() }} {{ formatINR(t?.taxAmount) }}</td>\n </tr>\n </ng-container>\n <tr class=\"totals-total-row\">\n <td class=\"totals-label\">Total Amount</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount, true) }}</td>\n </tr>\n <tr class=\"totals-words-row\">\n <td class=\"totals-label\">Total In Words</td>\n <td class=\"totals-value words\">{{ totalInWords }}</td>\n </tr>\n </table>\n </div>\n </div>\n\n <!-- Payment details -->\n <div class=\"thanks mt-4\">Thanks for your business!</div>\n <table class=\"payment-table mt-2\">\n <tr><td class=\"payment-label\">Beneficiary Name</td><td class=\"payment-value\"><strong>{{ bankDetails?.beneficiaryName }}</strong></td></tr>\n <tr><td class=\"payment-label\">Account Number</td><td class=\"payment-value\"><strong>{{ bankDetails?.accountNumber }}</strong></td></tr>\n <tr><td class=\"payment-label\">IFSC Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.ifsc }}</strong></td></tr>\n <tr><td class=\"payment-label\">Payment Type</td><td class=\"payment-value\"><strong>{{ bankDetails?.paymentType }}</strong></td></tr>\n <tr><td class=\"payment-label\">SWIFT Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.swift }}</strong></td></tr>\n <tr><td class=\"payment-label\">Branch</td><td class=\"payment-value\"><strong>{{ bankDetails?.branch }}</strong></td></tr>\n </table>\n\n <div class=\"system-note mt-4\">This is a system generated invoice. No signature required</div>\n </div>\n\n <!-- ANNEXURE TAB -->\n <div *ngIf=\"activeTab === 'annexure'\" class=\"annexure-page\">\n <div *ngIf=\"annexureLoading\" class=\"loading-state\">\n <div class=\"spinner-border text-primary\" role=\"status\"><span class=\"visually-hidden\">Loading...</span></div>\n </div>\n <div *ngIf=\"!annexureLoading && annexureError\" class=\"error-state\">\n <p>Failed to load annexure.</p>\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"retryAnnexure()\">Retry</button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData !== null && annexureData.length === 0\" class=\"empty-state\">\n No annexure data for this invoice.\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-toolbar\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"downloadAnnexureXlsx()\">\n Export as XLSX\n </button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-scroll\">\n <table class=\"annexure-table\">\n <colgroup>\n <!-- S.No is preview-only (not in the PDF / XLSX export). -->\n <col class=\"col-sno\" />\n <col class=\"col-store\" />\n <col class=\"col-product\" />\n <col class=\"col-id\" />\n <col class=\"col-date\" />\n <col class=\"col-days\" />\n <col class=\"col-qty\" />\n <col class=\"col-price\" />\n <col class=\"col-total\" />\n </colgroup>\n <thead>\n <tr>\n <th class=\"text-center\">S.No</th>\n <th>Store Name</th>\n <th>Products</th>\n <th>Store ID</th>\n <th>Deployment Date</th>\n <th class=\"text-center\">Billing Days</th>\n <th class=\"text-center\">Qty</th>\n <th class=\"text-end\">Unit Price</th>\n <th class=\"text-end\">Price Per Month</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of annexureData; let i = index; trackBy: trackByIndex\">\n <td class=\"text-center cell-muted\">{{ i + 1 }}</td>\n <td class=\"cell-store\">{{ row?.storeName }}</td>\n <td>{{ row?.productName }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.storeId }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.edgefirstFileDate }}</td>\n <td class=\"text-center\"><strong>{{ row?.workingdays }}</strong></td>\n <td class=\"text-center\">{{ row?.units ?? 1 }}</td>\n <td class=\"text-end cell-nowrap cell-num\">\n {{ row?.currencyType }} {{ formatINR(row?.standardPrice) }}\n <div class=\"unit-basis\">{{ row?.unitBasis || 'Per Store' }}</div>\n </td>\n <td class=\"text-end cell-nowrap cell-num cell-total\">\n <strong>{{ row?.currencyType }} {{ formatINR(row?.runningCost) }}</strong>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"annexureTotal != null\">\n <tr>\n <td colspan=\"8\" class=\"text-end\"><strong>Total</strong></td>\n <td class=\"text-end cell-num cell-total\">\n <strong>{{ annexureData[0]?.currencyType }} {{ formatINR(annexureTotal) }}</strong>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-link\" (click)=\"activeModal.dismiss()\">Close</button>\n <button class=\"btn btn-outline-primary\" (click)=\"downloadPdf()\" [disabled]=\"downloading\">\n <span *ngIf=\"!downloading\">Download PDF</span>\n <span *ngIf=\"downloading\">Downloading...</span>\n </button>\n </div>\n</div>", styles: [".invoice-preview-modal{font-family:inherit;font-size:13px;color:#344054;display:flex;flex-direction:column;max-height:calc(100vh - 3.5rem)}.invoice-preview-modal .modal-header{flex:0 0 auto;padding:0 1rem;border-bottom:1px solid #EAECF0;display:flex;align-items:stretch;justify-content:space-between}.invoice-preview-modal .modal-header .preview-tabs{border-bottom:none}.invoice-preview-modal .modal-header .preview-tabs .nav-link{border:none;border-radius:0;color:#667085;padding:12px 16px;background:transparent}.invoice-preview-modal .modal-header .preview-tabs .nav-link.active{color:#00a3ff;border-bottom:2px solid #00A3FF;background:transparent}.invoice-preview-modal .modal-header .btn-close{align-self:center}.invoice-preview-modal .modal-body{background:#fff;flex:1 1 auto;overflow-y:auto;min-height:0}.invoice-preview-modal .invoice-page,.invoice-preview-modal .annexure-page{padding:32px 40px}.invoice-preview-modal .tax-invoice-label{font-size:22px;font-weight:600;color:#00a3ff}.invoice-preview-modal .invoice-number{font-size:18px;font-weight:600;color:#00a3ff}.invoice-preview-modal .company-name{font-weight:700;color:#101828}.invoice-preview-modal .bill-to-label{font-weight:600;color:#667085}.invoice-preview-modal .client-name{font-weight:700;color:#101828;font-size:15px}.invoice-preview-modal .invoice-total-label{font-weight:600;font-size:15px}.invoice-preview-modal .invoice-total-label .invoice-total-amount{color:#101828;font-weight:700;margin-left:8px}.invoice-preview-modal .meta-table td{padding:2px 8px}.invoice-preview-modal .meta-table .meta-label{color:#667085;text-align:right}.invoice-preview-modal .meta-table .meta-value{color:#101828;font-weight:600}.invoice-preview-modal .items-table{width:100%;border-collapse:collapse}.invoice-preview-modal .items-table th{background:#f2f4f7;padding:12px;font-weight:600;color:#344054;text-align:left}.invoice-preview-modal .items-table td{padding:14px 12px;border-bottom:1px solid #EAECF0;vertical-align:top}.invoice-preview-modal .items-table .product-name{font-weight:600;color:#101828}.invoice-preview-modal .items-table .product-desc{color:#667085;font-size:12px}.invoice-preview-modal .items-table .col-index{width:40px}.invoice-preview-modal .items-table .col-month,.invoice-preview-modal .items-table .col-hsn,.invoice-preview-modal .items-table .col-count{width:100px}.invoice-preview-modal .items-table .col-rate{width:110px}.invoice-preview-modal .items-table .col-amount{width:140px}.invoice-preview-modal .items-table .nowrap{white-space:nowrap}.invoice-preview-modal .totals-table{width:100%}.invoice-preview-modal .totals-table td{padding:6px 12px}.invoice-preview-modal .totals-table .totals-label{color:#667085;text-align:right}.invoice-preview-modal .totals-table .totals-value{color:#101828;font-weight:600;text-align:right}.invoice-preview-modal .totals-table .totals-total-row td{padding-top:12px}.invoice-preview-modal .totals-table .totals-total-row .totals-value{font-size:15px;font-weight:700}.invoice-preview-modal .totals-table .totals-words-row .words{font-weight:600;max-width:280px;white-space:normal;word-wrap:break-word}.invoice-preview-modal .totals-table .nowrap{white-space:nowrap}.invoice-preview-modal .thanks{font-weight:600;color:#101828}.invoice-preview-modal .payment-table{border-collapse:collapse}.invoice-preview-modal .payment-table td{padding:6px 12px}.invoice-preview-modal .payment-table .payment-label{color:#667085}.invoice-preview-modal .system-note{color:#667085;font-size:12px;font-weight:600}.invoice-preview-modal .annexure-scroll{width:100%;border:1px solid #EAECF0;border-radius:8px}.invoice-preview-modal .annexure-table{width:100%;table-layout:fixed;border-collapse:collapse;font-size:13px}.invoice-preview-modal .annexure-table .col-sno{width:5%}.invoice-preview-modal .annexure-table .col-store{width:17%}.invoice-preview-modal .annexure-table .col-product{width:16%}.invoice-preview-modal .annexure-table .col-id{width:9%}.invoice-preview-modal .annexure-table .col-date{width:12%}.invoice-preview-modal .annexure-table .col-days{width:9%}.invoice-preview-modal .annexure-table .col-qty{width:7%}.invoice-preview-modal .annexure-table .col-price{width:12%}.invoice-preview-modal .annexure-table .col-total{width:13%}.invoice-preview-modal .annexure-table th{position:sticky;top:0;z-index:1;background:#f2f4f7;padding:10px 12px;font-weight:600;font-size:12px;color:#344054;text-align:left;border-bottom:1px solid #EAECF0}.invoice-preview-modal .annexure-table td{padding:10px 12px;border-bottom:1px solid #F2F4F7;color:#101828;vertical-align:middle}.invoice-preview-modal .annexure-table tbody tr:nth-child(2n) td{background:#fcfcfd}.invoice-preview-modal .annexure-table tbody tr:hover td{background:#f9fafb}.invoice-preview-modal .annexure-table .cell-store{font-weight:600}.invoice-preview-modal .annexure-table .cell-nowrap{white-space:nowrap}.invoice-preview-modal .annexure-table .cell-muted{color:#667085}.invoice-preview-modal .annexure-table .cell-num{font-variant-numeric:tabular-nums}.invoice-preview-modal .annexure-table .cell-total strong{color:#101828}.invoice-preview-modal .annexure-table .unit-basis{font-size:11px;color:#98a2b3;margin-top:2px}.invoice-preview-modal .annexure-table tfoot td{position:sticky;bottom:0;background:#f9fafb;border-top:2px solid #EAECF0;border-bottom:none;font-size:14px}.invoice-preview-modal .loading-state,.invoice-preview-modal .empty-state,.invoice-preview-modal .error-state{padding:40px;text-align:center;color:#667085}.invoice-preview-modal .modal-footer{flex:0 0 auto}.invoice-preview-modal .annexure-toolbar{display:flex;justify-content:flex-end;padding:8px 0 12px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i4.DatePipe, name: "date" }] });
273
276
  }
274
277
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: InvoicePreviewComponent, decorators: [{
275
278
  type: Component,
276
- args: [{ selector: 'lib-invoice-preview', template: "<div class=\"invoice-preview-modal\">\n <div class=\"modal-header\">\n <ul class=\"nav nav-tabs preview-tabs\" role=\"tablist\">\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'invoice'\"\n (click)=\"selectTab('invoice')\" type=\"button\">Invoice</button>\n </li>\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'annexure'\"\n (click)=\"selectTab('annexure')\" type=\"button\">Annexure</button>\n </li>\n </ul>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\" aria-label=\"Close\"></button>\n </div>\n\n <div class=\"modal-body p-0\">\n <!-- INVOICE TAB -->\n <div *ngIf=\"activeTab === 'invoice'\" class=\"invoice-page\">\n <!-- Header row -->\n <div class=\"row align-items-start\">\n <div class=\"col-7\">\n <div class=\"brand\">\n <img src=\"./assets/tango/Images/tangoeye-logo.svg\" alt=\"TangoEye\" class=\"brand-logo\" onerror=\"this.style.display='none'\">\n </div>\n <div class=\"company-block mt-3\">\n <div class=\"company-name\">TANGO IT SOLUTIONS INDIA PRIVATE LTD</div>\n <div>2nd Floor, Apeejay Business Centre, No.12/39,</div>\n <div>Haddows Road, Nungambakkam</div>\n <div>Chennai Tamil Nadu 600006, India</div>\n <div class=\"mt-1\"><strong>GSTIN 33AAGCT3124R1Z2</strong></div>\n <div class=\"mt-1\">MSME / Udyam type : Micro</div>\n <div>MSME / Udyam No. : UDYAM-TN-03-0212399</div>\n </div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"tax-invoice-label\">TAX INVOICE</div>\n <div class=\"invoice-number\"># {{ invoiceData?.invoice }}</div>\n </div>\n </div>\n\n <!-- Bill-to + totals row -->\n <div class=\"row mt-4\">\n <div class=\"col-7\">\n <div class=\"bill-to-label\">BILL TO :</div>\n <div class=\"client-name mt-1\">{{ (invoiceData?.clientName || invoiceData?.companyName) | uppercase }}</div>\n <div class=\"mt-1\" *ngIf=\"invoiceData?.billingAddressLineOne || invoiceData?.companyAddress\">\n {{ invoiceData?.billingAddressLineOne || invoiceData?.companyAddress }}\n </div>\n <div *ngIf=\"invoiceData?.billingAddressLineTwo\">{{ invoiceData?.billingAddressLineTwo }}</div>\n <div *ngIf=\"invoiceData?.billingCity || invoiceData?.billingPinCode || invoiceData?.billingState\">\n {{ invoiceData?.billingCity }}<span *ngIf=\"invoiceData?.billingPinCode\">, {{ invoiceData?.billingPinCode }}</span><span *ngIf=\"invoiceData?.billingState\">, {{ invoiceData?.billingState }}</span><span *ngIf=\"invoiceData?.billingCountry\">, {{ invoiceData?.billingCountry }}</span>\n </div>\n <div class=\"mt-2\" *ngIf=\"invoiceData?.GSTNumber\"><strong>GSTIN {{ invoiceData?.GSTNumber }}</strong></div>\n <div *ngIf=\"invoiceData?.PlaceOfSupply\">Place Of Supply: {{ invoiceData?.PlaceOfSupply }}</div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"invoice-total-label\">Invoice Total <span class=\"invoice-total-amount\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount) }}</span></div>\n <table class=\"meta-table ms-auto mt-3\">\n <tr><td class=\"meta-label\">Invoice date :</td><td class=\"meta-value\">{{ invoiceData?.billingDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr><td class=\"meta-label\">Terms :</td><td class=\"meta-value\">Term {{ paymentTermDays }}</td></tr>\n <tr><td class=\"meta-label\">Due Date :</td><td class=\"meta-value\">{{ invoiceData?.dueDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr *ngIf=\"invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber\"><td class=\"meta-label\">P.O.# :</td><td class=\"meta-value\">{{ invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber }}</td></tr>\n </table>\n </div>\n </div>\n\n <!-- Line items -->\n <table class=\"items-table mt-4\">\n <thead>\n <tr>\n <th class=\"col-index\">#</th>\n <th class=\"col-product\">Product &amp; Description</th>\n <th class=\"col-month\">Month</th>\n <th class=\"col-hsn\">HSN/SAC</th>\n <th class=\"col-count text-center\">Quantity</th>\n <th class=\"col-rate text-end\">Rate</th>\n <th class=\"col-amount text-end\">Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of visibleProducts(); let i = index; trackBy: trackByIndex\">\n <td>{{ i + 1 }}</td>\n <td>\n <div class=\"product-name\">{{ formatProductName(item?.productName) }}</div>\n <div class=\"product-desc\">{{ item?.description }}</div>\n </td>\n <!-- Month is the product's billing month stored on the line item\n (advance invoices bill a future month while billingDate is the\n creation date). Fall back to billingDate for legacy rows. -->\n <td class=\"nowrap\">{{ item?.month || (invoiceData?.billingDate | date:'MMM yyyy') }}</td>\n <td>{{ item?.hsn || item?.hsnCode || '998314' }}</td>\n <td class=\"text-center\"><strong>{{ item?.storeCount || invoiceData?.stores?.length || '' }}</strong></td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.price) }}</td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.amount) }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- Totals -->\n <div class=\"row mt-3\">\n <div class=\"col-7\"></div>\n <div class=\"col-5\">\n <table class=\"totals-table ms-auto\">\n <!-- With a discount, tell the story top-down: Original Amount minus\n Discount gives the Sub Total (the GST base). Without one, the\n Sub Total row alone suffices. -->\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Sub Total</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(originalAmount()) }}</td>\n </tr>\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Discount</td>\n <td class=\"totals-value\">- {{ currencySymbol() }} {{ formatINR(invoiceData?.discountAmount) }}</td>\n </tr>\n <tr><td class=\"totals-label\">Sub Total</td><td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.amount) }}</td></tr>\n <ng-container *ngFor=\"let t of invoiceData?.tax\">\n <tr *ngIf=\"hasTax(t)\">\n <td class=\"totals-label\">{{ t?.type || t?.taxName || t?.name }} ({{ t?.value ?? t?.taxPercentage ?? t?.percentage }}%)</td>\n <td class=\"totals-value nowrap\">{{ currencySymbol() }} {{ formatINR(t?.taxAmount) }}</td>\n </tr>\n </ng-container>\n <tr class=\"totals-total-row\">\n <td class=\"totals-label\">Total Amount</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount, true) }}</td>\n </tr>\n <tr class=\"totals-words-row\">\n <td class=\"totals-label\">Total In Words</td>\n <td class=\"totals-value words\">{{ totalInWords }}</td>\n </tr>\n </table>\n </div>\n </div>\n\n <!-- Payment details -->\n <div class=\"thanks mt-4\">Thanks for your business!</div>\n <table class=\"payment-table mt-2\">\n <tr><td class=\"payment-label\">Beneficiary Name</td><td class=\"payment-value\"><strong>{{ bankDetails?.beneficiaryName }}</strong></td></tr>\n <tr><td class=\"payment-label\">Account Number</td><td class=\"payment-value\"><strong>{{ bankDetails?.accountNumber }}</strong></td></tr>\n <tr><td class=\"payment-label\">IFSC Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.ifsc }}</strong></td></tr>\n <tr><td class=\"payment-label\">Payment Type</td><td class=\"payment-value\"><strong>{{ bankDetails?.paymentType }}</strong></td></tr>\n <tr><td class=\"payment-label\">SWIFT Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.swift }}</strong></td></tr>\n <tr><td class=\"payment-label\">Branch</td><td class=\"payment-value\"><strong>{{ bankDetails?.branch }}</strong></td></tr>\n </table>\n\n <div class=\"system-note mt-4\">This is a system generated invoice. No signature required</div>\n </div>\n\n <!-- ANNEXURE TAB -->\n <div *ngIf=\"activeTab === 'annexure'\" class=\"annexure-page\">\n <div *ngIf=\"annexureLoading\" class=\"loading-state\">\n <div class=\"spinner-border text-primary\" role=\"status\"><span class=\"visually-hidden\">Loading...</span></div>\n </div>\n <div *ngIf=\"!annexureLoading && annexureError\" class=\"error-state\">\n <p>Failed to load annexure.</p>\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"retryAnnexure()\">Retry</button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData !== null && annexureData.length === 0\" class=\"empty-state\">\n No annexure data for this invoice.\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-toolbar\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"downloadAnnexureXlsx()\">\n Export as XLSX\n </button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-scroll\">\n <table class=\"annexure-table\">\n <colgroup>\n <col class=\"col-store\" />\n <col class=\"col-product\" />\n <col class=\"col-id\" />\n <col class=\"col-date\" />\n <col class=\"col-days\" />\n <col class=\"col-qty\" />\n <col class=\"col-price\" />\n <col class=\"col-total\" />\n </colgroup>\n <thead>\n <tr>\n <th>Store Name</th>\n <th>Products</th>\n <th>Store ID</th>\n <th>Deployment Date</th>\n <th class=\"text-center\">Billing Days</th>\n <th class=\"text-center\">Qty</th>\n <th class=\"text-end\">Unit Price</th>\n <th class=\"text-end\">Price Per Month</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of annexureData; trackBy: trackByIndex\">\n <td class=\"cell-store\">{{ row?.storeName }}</td>\n <td>{{ row?.productName }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.storeId }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.edgefirstFileDate }}</td>\n <td class=\"text-center\"><strong>{{ row?.workingdays }}</strong></td>\n <td class=\"text-center\">{{ row?.units ?? 1 }}</td>\n <td class=\"text-end cell-nowrap cell-num\">\n {{ row?.currencyType }} {{ formatINR(row?.standardPrice) }}\n <div class=\"unit-basis\">{{ row?.unitBasis || 'Per Store' }}</div>\n </td>\n <td class=\"text-end cell-nowrap cell-num cell-total\">\n <strong>{{ row?.currencyType }} {{ formatINR(row?.runningCost) }}</strong>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"annexureTotal != null\">\n <tr>\n <td colspan=\"7\" class=\"text-end\"><strong>Total</strong></td>\n <td class=\"text-end cell-num cell-total\">\n <strong>{{ annexureData[0]?.currencyType }} {{ formatINR(annexureTotal) }}</strong>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-link\" (click)=\"activeModal.dismiss()\">Close</button>\n <button class=\"btn btn-outline-primary\" (click)=\"downloadPdf()\" [disabled]=\"downloading\">\n <span *ngIf=\"!downloading\">Download PDF</span>\n <span *ngIf=\"downloading\">Downloading...</span>\n </button>\n </div>\n</div>", styles: [".invoice-preview-modal{font-family:inherit;font-size:13px;color:#344054;display:flex;flex-direction:column;max-height:calc(100vh - 3.5rem)}.invoice-preview-modal .modal-header{flex:0 0 auto;padding:0 1rem;border-bottom:1px solid #EAECF0;display:flex;align-items:stretch;justify-content:space-between}.invoice-preview-modal .modal-header .preview-tabs{border-bottom:none}.invoice-preview-modal .modal-header .preview-tabs .nav-link{border:none;border-radius:0;color:#667085;padding:12px 16px;background:transparent}.invoice-preview-modal .modal-header .preview-tabs .nav-link.active{color:#00a3ff;border-bottom:2px solid #00A3FF;background:transparent}.invoice-preview-modal .modal-header .btn-close{align-self:center}.invoice-preview-modal .modal-body{background:#fff;flex:1 1 auto;overflow-y:auto;min-height:0}.invoice-preview-modal .invoice-page,.invoice-preview-modal .annexure-page{padding:32px 40px}.invoice-preview-modal .tax-invoice-label{font-size:22px;font-weight:600;color:#00a3ff}.invoice-preview-modal .invoice-number{font-size:18px;font-weight:600;color:#00a3ff}.invoice-preview-modal .company-name{font-weight:700;color:#101828}.invoice-preview-modal .bill-to-label{font-weight:600;color:#667085}.invoice-preview-modal .client-name{font-weight:700;color:#101828;font-size:15px}.invoice-preview-modal .invoice-total-label{font-weight:600;font-size:15px}.invoice-preview-modal .invoice-total-label .invoice-total-amount{color:#101828;font-weight:700;margin-left:8px}.invoice-preview-modal .meta-table td{padding:2px 8px}.invoice-preview-modal .meta-table .meta-label{color:#667085;text-align:right}.invoice-preview-modal .meta-table .meta-value{color:#101828;font-weight:600}.invoice-preview-modal .items-table{width:100%;border-collapse:collapse}.invoice-preview-modal .items-table th{background:#f2f4f7;padding:12px;font-weight:600;color:#344054;text-align:left}.invoice-preview-modal .items-table td{padding:14px 12px;border-bottom:1px solid #EAECF0;vertical-align:top}.invoice-preview-modal .items-table .product-name{font-weight:600;color:#101828}.invoice-preview-modal .items-table .product-desc{color:#667085;font-size:12px}.invoice-preview-modal .items-table .col-index{width:40px}.invoice-preview-modal .items-table .col-month,.invoice-preview-modal .items-table .col-hsn,.invoice-preview-modal .items-table .col-count{width:100px}.invoice-preview-modal .items-table .col-rate{width:110px}.invoice-preview-modal .items-table .col-amount{width:140px}.invoice-preview-modal .items-table .nowrap{white-space:nowrap}.invoice-preview-modal .totals-table{width:100%}.invoice-preview-modal .totals-table td{padding:6px 12px}.invoice-preview-modal .totals-table .totals-label{color:#667085;text-align:right}.invoice-preview-modal .totals-table .totals-value{color:#101828;font-weight:600;text-align:right}.invoice-preview-modal .totals-table .totals-total-row td{padding-top:12px}.invoice-preview-modal .totals-table .totals-total-row .totals-value{font-size:15px;font-weight:700}.invoice-preview-modal .totals-table .totals-words-row .words{font-weight:600;max-width:280px;white-space:normal;word-wrap:break-word}.invoice-preview-modal .totals-table .nowrap{white-space:nowrap}.invoice-preview-modal .thanks{font-weight:600;color:#101828}.invoice-preview-modal .payment-table{border-collapse:collapse}.invoice-preview-modal .payment-table td{padding:6px 12px}.invoice-preview-modal .payment-table .payment-label{color:#667085}.invoice-preview-modal .system-note{color:#667085;font-size:12px;font-weight:600}.invoice-preview-modal .annexure-scroll{width:100%;border:1px solid #EAECF0;border-radius:8px}.invoice-preview-modal .annexure-table{width:100%;table-layout:fixed;border-collapse:collapse;font-size:13px}.invoice-preview-modal .annexure-table .col-store{width:22%}.invoice-preview-modal .annexure-table .col-product{width:16%}.invoice-preview-modal .annexure-table .col-id{width:9%}.invoice-preview-modal .annexure-table .col-date{width:12%}.invoice-preview-modal .annexure-table .col-days{width:9%}.invoice-preview-modal .annexure-table .col-qty{width:7%}.invoice-preview-modal .annexure-table .col-price{width:12%}.invoice-preview-modal .annexure-table .col-total{width:13%}.invoice-preview-modal .annexure-table th{position:sticky;top:0;z-index:1;background:#f2f4f7;padding:10px 12px;font-weight:600;font-size:12px;color:#344054;text-align:left;border-bottom:1px solid #EAECF0}.invoice-preview-modal .annexure-table td{padding:10px 12px;border-bottom:1px solid #F2F4F7;color:#101828;vertical-align:middle}.invoice-preview-modal .annexure-table tbody tr:nth-child(2n) td{background:#fcfcfd}.invoice-preview-modal .annexure-table tbody tr:hover td{background:#f9fafb}.invoice-preview-modal .annexure-table .cell-store{font-weight:600}.invoice-preview-modal .annexure-table .cell-nowrap{white-space:nowrap}.invoice-preview-modal .annexure-table .cell-muted{color:#667085}.invoice-preview-modal .annexure-table .cell-num{font-variant-numeric:tabular-nums}.invoice-preview-modal .annexure-table .cell-total strong{color:#101828}.invoice-preview-modal .annexure-table .unit-basis{font-size:11px;color:#98a2b3;margin-top:2px}.invoice-preview-modal .annexure-table tfoot td{position:sticky;bottom:0;background:#f9fafb;border-top:2px solid #EAECF0;border-bottom:none;font-size:14px}.invoice-preview-modal .loading-state,.invoice-preview-modal .empty-state,.invoice-preview-modal .error-state{padding:40px;text-align:center;color:#667085}.invoice-preview-modal .modal-footer{flex:0 0 auto}.invoice-preview-modal .annexure-toolbar{display:flex;justify-content:flex-end;padding:8px 0 12px}\n"] }]
279
+ args: [{ selector: 'lib-invoice-preview', template: "<div class=\"invoice-preview-modal\">\n <div class=\"modal-header\">\n <ul class=\"nav nav-tabs preview-tabs\" role=\"tablist\">\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'invoice'\"\n (click)=\"selectTab('invoice')\" type=\"button\">Invoice</button>\n </li>\n <li class=\"nav-item\">\n <button class=\"nav-link\" [class.active]=\"activeTab === 'annexure'\"\n (click)=\"selectTab('annexure')\" type=\"button\">Annexure</button>\n </li>\n </ul>\n <button type=\"button\" class=\"btn-close\" (click)=\"activeModal.dismiss()\" aria-label=\"Close\"></button>\n </div>\n\n <div class=\"modal-body p-0\">\n <!-- INVOICE TAB -->\n <div *ngIf=\"activeTab === 'invoice'\" class=\"invoice-page\">\n <!-- Header row -->\n <div class=\"row align-items-start\">\n <div class=\"col-7\">\n <div class=\"brand\">\n <img src=\"./assets/tango/Images/tangoeye-logo.svg\" alt=\"TangoEye\" class=\"brand-logo\" onerror=\"this.style.display='none'\">\n </div>\n <div class=\"company-block mt-3\">\n <div class=\"company-name\">TANGO IT SOLUTIONS INDIA PRIVATE LTD</div>\n <div>2nd Floor, Apeejay Business Centre, No.12/39,</div>\n <div>Haddows Road, Nungambakkam</div>\n <div>Chennai Tamil Nadu 600006, India</div>\n <div class=\"mt-1\"><strong>GSTIN 33AAGCT3124R1Z2</strong></div>\n <div class=\"mt-1\">MSME / Udyam type : Micro</div>\n <div>MSME / Udyam No. : UDYAM-TN-03-0212399</div>\n </div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"tax-invoice-label\">TAX INVOICE</div>\n <div class=\"invoice-number\"># {{ invoiceData?.invoice }}</div>\n </div>\n </div>\n\n <!-- Bill-to + totals row -->\n <div class=\"row mt-4\">\n <div class=\"col-7\">\n <div class=\"bill-to-label\">BILL TO :</div>\n <div class=\"client-name mt-1\">{{ (invoiceData?.clientName || invoiceData?.companyName) | uppercase }}</div>\n <div class=\"mt-1\" *ngIf=\"invoiceData?.billingAddressLineOne || invoiceData?.companyAddress\">\n {{ invoiceData?.billingAddressLineOne || invoiceData?.companyAddress }}\n </div>\n <div *ngIf=\"invoiceData?.billingAddressLineTwo\">{{ invoiceData?.billingAddressLineTwo }}</div>\n <div *ngIf=\"invoiceData?.billingCity || invoiceData?.billingPinCode || invoiceData?.billingState\">\n {{ invoiceData?.billingCity }}<span *ngIf=\"invoiceData?.billingPinCode\">, {{ invoiceData?.billingPinCode }}</span><span *ngIf=\"invoiceData?.billingState\">, {{ invoiceData?.billingState }}</span><span *ngIf=\"invoiceData?.billingCountry\">, {{ invoiceData?.billingCountry }}</span>\n </div>\n <div class=\"mt-2\" *ngIf=\"invoiceData?.GSTNumber\"><strong>GSTIN {{ invoiceData?.GSTNumber }}</strong></div>\n <div *ngIf=\"invoiceData?.PlaceOfSupply\">Place Of Supply: {{ invoiceData?.PlaceOfSupply }}</div>\n </div>\n <div class=\"col-5 text-end\">\n <div class=\"invoice-total-label\">Invoice Total <span class=\"invoice-total-amount\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount) }}</span></div>\n <table class=\"meta-table ms-auto mt-3\">\n <tr><td class=\"meta-label\">Invoice date :</td><td class=\"meta-value\">{{ invoiceData?.billingDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr><td class=\"meta-label\">Terms :</td><td class=\"meta-value\">Term {{ paymentTermDays }}</td></tr>\n <tr><td class=\"meta-label\">Due Date :</td><td class=\"meta-value\">{{ invoiceData?.dueDate | date:'dd/MM/yyyy' }}</td></tr>\n <tr *ngIf=\"invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber\"><td class=\"meta-label\">P.O.# :</td><td class=\"meta-value\">{{ invoiceData?.purchaseOrderNumber || invoiceData?.PoNum || invoiceData?.poNumber }}</td></tr>\n </table>\n </div>\n </div>\n\n <!-- Line items -->\n <table class=\"items-table mt-4\">\n <thead>\n <tr>\n <th class=\"col-index\">#</th>\n <th class=\"col-product\">Product &amp; Description</th>\n <th class=\"col-month\">Month</th>\n <th class=\"col-hsn\">HSN/SAC</th>\n <th class=\"col-count text-center\">Quantity</th>\n <th class=\"col-rate text-end\">Rate</th>\n <th class=\"col-amount text-end\">Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let item of visibleProducts(); let i = index; trackBy: trackByIndex\">\n <td>{{ i + 1 }}</td>\n <td>\n <div class=\"product-name\">{{ formatProductName(item?.productName) }}</div>\n <div class=\"product-desc\">{{ item?.description }}</div>\n </td>\n <!-- Month is the product's billing month stored on the line item\n (advance invoices bill a future month while billingDate is the\n creation date). Fall back to billingDate for legacy rows. -->\n <td class=\"nowrap\">{{ item?.month || (invoiceData?.billingDate | date:'MMM yyyy') }}</td>\n <td>{{ item?.hsn || item?.hsnCode || '998314' }}</td>\n <td class=\"text-center\"><strong>{{ item?.storeCount || invoiceData?.stores?.length || '' }}</strong></td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.price) }}</td>\n <td class=\"text-end nowrap\">{{ currencySymbol() }} {{ formatINR(item?.amount) }}</td>\n </tr>\n </tbody>\n </table>\n\n <!-- Totals -->\n <div class=\"row mt-3\">\n <div class=\"col-7\"></div>\n <div class=\"col-5\">\n <table class=\"totals-table ms-auto\">\n <!-- With a discount, tell the story top-down: Original Amount minus\n Discount gives the Sub Total (the GST base). Without one, the\n Sub Total row alone suffices. -->\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Sub Total</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(originalAmount()) }}</td>\n </tr>\n <tr *ngIf=\"invoiceData?.discountAmount\">\n <td class=\"totals-label\">Discount</td>\n <td class=\"totals-value\">- {{ currencySymbol() }} {{ formatINR(invoiceData?.discountAmount) }}</td>\n </tr>\n <tr><td class=\"totals-label\">Sub Total</td><td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.amount) }}</td></tr>\n <ng-container *ngFor=\"let t of invoiceData?.tax\">\n <tr *ngIf=\"hasTax(t)\">\n <td class=\"totals-label\">{{ t?.type || t?.taxName || t?.name }} ({{ t?.value ?? t?.taxPercentage ?? t?.percentage }}%)</td>\n <td class=\"totals-value nowrap\">{{ currencySymbol() }} {{ formatINR(t?.taxAmount) }}</td>\n </tr>\n </ng-container>\n <tr class=\"totals-total-row\">\n <td class=\"totals-label\">Total Amount</td>\n <td class=\"totals-value\">{{ currencySymbol() }} {{ formatINR(invoiceData?.totalAmount, true) }}</td>\n </tr>\n <tr class=\"totals-words-row\">\n <td class=\"totals-label\">Total In Words</td>\n <td class=\"totals-value words\">{{ totalInWords }}</td>\n </tr>\n </table>\n </div>\n </div>\n\n <!-- Payment details -->\n <div class=\"thanks mt-4\">Thanks for your business!</div>\n <table class=\"payment-table mt-2\">\n <tr><td class=\"payment-label\">Beneficiary Name</td><td class=\"payment-value\"><strong>{{ bankDetails?.beneficiaryName }}</strong></td></tr>\n <tr><td class=\"payment-label\">Account Number</td><td class=\"payment-value\"><strong>{{ bankDetails?.accountNumber }}</strong></td></tr>\n <tr><td class=\"payment-label\">IFSC Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.ifsc }}</strong></td></tr>\n <tr><td class=\"payment-label\">Payment Type</td><td class=\"payment-value\"><strong>{{ bankDetails?.paymentType }}</strong></td></tr>\n <tr><td class=\"payment-label\">SWIFT Code</td><td class=\"payment-value\"><strong>{{ bankDetails?.swift }}</strong></td></tr>\n <tr><td class=\"payment-label\">Branch</td><td class=\"payment-value\"><strong>{{ bankDetails?.branch }}</strong></td></tr>\n </table>\n\n <div class=\"system-note mt-4\">This is a system generated invoice. No signature required</div>\n </div>\n\n <!-- ANNEXURE TAB -->\n <div *ngIf=\"activeTab === 'annexure'\" class=\"annexure-page\">\n <div *ngIf=\"annexureLoading\" class=\"loading-state\">\n <div class=\"spinner-border text-primary\" role=\"status\"><span class=\"visually-hidden\">Loading...</span></div>\n </div>\n <div *ngIf=\"!annexureLoading && annexureError\" class=\"error-state\">\n <p>Failed to load annexure.</p>\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"retryAnnexure()\">Retry</button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData !== null && annexureData.length === 0\" class=\"empty-state\">\n No annexure data for this invoice.\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-toolbar\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-primary\" (click)=\"downloadAnnexureXlsx()\">\n Export as XLSX\n </button>\n </div>\n <div *ngIf=\"!annexureLoading && !annexureError && annexureData && annexureData.length > 0\"\n class=\"annexure-scroll\">\n <table class=\"annexure-table\">\n <colgroup>\n <!-- S.No is preview-only (not in the PDF / XLSX export). -->\n <col class=\"col-sno\" />\n <col class=\"col-store\" />\n <col class=\"col-product\" />\n <col class=\"col-id\" />\n <col class=\"col-date\" />\n <col class=\"col-days\" />\n <col class=\"col-qty\" />\n <col class=\"col-price\" />\n <col class=\"col-total\" />\n </colgroup>\n <thead>\n <tr>\n <th class=\"text-center\">S.No</th>\n <th>Store Name</th>\n <th>Products</th>\n <th>Store ID</th>\n <th>Deployment Date</th>\n <th class=\"text-center\">Billing Days</th>\n <th class=\"text-center\">Qty</th>\n <th class=\"text-end\">Unit Price</th>\n <th class=\"text-end\">Price Per Month</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of annexureData; let i = index; trackBy: trackByIndex\">\n <td class=\"text-center cell-muted\">{{ i + 1 }}</td>\n <td class=\"cell-store\">{{ row?.storeName }}</td>\n <td>{{ row?.productName }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.storeId }}</td>\n <td class=\"cell-nowrap cell-muted\">{{ row?.edgefirstFileDate }}</td>\n <td class=\"text-center\"><strong>{{ row?.workingdays }}</strong></td>\n <td class=\"text-center\">{{ row?.units ?? 1 }}</td>\n <td class=\"text-end cell-nowrap cell-num\">\n {{ row?.currencyType }} {{ formatINR(row?.standardPrice) }}\n <div class=\"unit-basis\">{{ row?.unitBasis || 'Per Store' }}</div>\n </td>\n <td class=\"text-end cell-nowrap cell-num cell-total\">\n <strong>{{ row?.currencyType }} {{ formatINR(row?.runningCost) }}</strong>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"annexureTotal != null\">\n <tr>\n <td colspan=\"8\" class=\"text-end\"><strong>Total</strong></td>\n <td class=\"text-end cell-num cell-total\">\n <strong>{{ annexureData[0]?.currencyType }} {{ formatINR(annexureTotal) }}</strong>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n </div>\n\n <div class=\"modal-footer\">\n <button class=\"btn btn-link\" (click)=\"activeModal.dismiss()\">Close</button>\n <button class=\"btn btn-outline-primary\" (click)=\"downloadPdf()\" [disabled]=\"downloading\">\n <span *ngIf=\"!downloading\">Download PDF</span>\n <span *ngIf=\"downloading\">Downloading...</span>\n </button>\n </div>\n</div>", styles: [".invoice-preview-modal{font-family:inherit;font-size:13px;color:#344054;display:flex;flex-direction:column;max-height:calc(100vh - 3.5rem)}.invoice-preview-modal .modal-header{flex:0 0 auto;padding:0 1rem;border-bottom:1px solid #EAECF0;display:flex;align-items:stretch;justify-content:space-between}.invoice-preview-modal .modal-header .preview-tabs{border-bottom:none}.invoice-preview-modal .modal-header .preview-tabs .nav-link{border:none;border-radius:0;color:#667085;padding:12px 16px;background:transparent}.invoice-preview-modal .modal-header .preview-tabs .nav-link.active{color:#00a3ff;border-bottom:2px solid #00A3FF;background:transparent}.invoice-preview-modal .modal-header .btn-close{align-self:center}.invoice-preview-modal .modal-body{background:#fff;flex:1 1 auto;overflow-y:auto;min-height:0}.invoice-preview-modal .invoice-page,.invoice-preview-modal .annexure-page{padding:32px 40px}.invoice-preview-modal .tax-invoice-label{font-size:22px;font-weight:600;color:#00a3ff}.invoice-preview-modal .invoice-number{font-size:18px;font-weight:600;color:#00a3ff}.invoice-preview-modal .company-name{font-weight:700;color:#101828}.invoice-preview-modal .bill-to-label{font-weight:600;color:#667085}.invoice-preview-modal .client-name{font-weight:700;color:#101828;font-size:15px}.invoice-preview-modal .invoice-total-label{font-weight:600;font-size:15px}.invoice-preview-modal .invoice-total-label .invoice-total-amount{color:#101828;font-weight:700;margin-left:8px}.invoice-preview-modal .meta-table td{padding:2px 8px}.invoice-preview-modal .meta-table .meta-label{color:#667085;text-align:right}.invoice-preview-modal .meta-table .meta-value{color:#101828;font-weight:600}.invoice-preview-modal .items-table{width:100%;border-collapse:collapse}.invoice-preview-modal .items-table th{background:#f2f4f7;padding:12px;font-weight:600;color:#344054;text-align:left}.invoice-preview-modal .items-table td{padding:14px 12px;border-bottom:1px solid #EAECF0;vertical-align:top}.invoice-preview-modal .items-table .product-name{font-weight:600;color:#101828}.invoice-preview-modal .items-table .product-desc{color:#667085;font-size:12px}.invoice-preview-modal .items-table .col-index{width:40px}.invoice-preview-modal .items-table .col-month,.invoice-preview-modal .items-table .col-hsn,.invoice-preview-modal .items-table .col-count{width:100px}.invoice-preview-modal .items-table .col-rate{width:110px}.invoice-preview-modal .items-table .col-amount{width:140px}.invoice-preview-modal .items-table .nowrap{white-space:nowrap}.invoice-preview-modal .totals-table{width:100%}.invoice-preview-modal .totals-table td{padding:6px 12px}.invoice-preview-modal .totals-table .totals-label{color:#667085;text-align:right}.invoice-preview-modal .totals-table .totals-value{color:#101828;font-weight:600;text-align:right}.invoice-preview-modal .totals-table .totals-total-row td{padding-top:12px}.invoice-preview-modal .totals-table .totals-total-row .totals-value{font-size:15px;font-weight:700}.invoice-preview-modal .totals-table .totals-words-row .words{font-weight:600;max-width:280px;white-space:normal;word-wrap:break-word}.invoice-preview-modal .totals-table .nowrap{white-space:nowrap}.invoice-preview-modal .thanks{font-weight:600;color:#101828}.invoice-preview-modal .payment-table{border-collapse:collapse}.invoice-preview-modal .payment-table td{padding:6px 12px}.invoice-preview-modal .payment-table .payment-label{color:#667085}.invoice-preview-modal .system-note{color:#667085;font-size:12px;font-weight:600}.invoice-preview-modal .annexure-scroll{width:100%;border:1px solid #EAECF0;border-radius:8px}.invoice-preview-modal .annexure-table{width:100%;table-layout:fixed;border-collapse:collapse;font-size:13px}.invoice-preview-modal .annexure-table .col-sno{width:5%}.invoice-preview-modal .annexure-table .col-store{width:17%}.invoice-preview-modal .annexure-table .col-product{width:16%}.invoice-preview-modal .annexure-table .col-id{width:9%}.invoice-preview-modal .annexure-table .col-date{width:12%}.invoice-preview-modal .annexure-table .col-days{width:9%}.invoice-preview-modal .annexure-table .col-qty{width:7%}.invoice-preview-modal .annexure-table .col-price{width:12%}.invoice-preview-modal .annexure-table .col-total{width:13%}.invoice-preview-modal .annexure-table th{position:sticky;top:0;z-index:1;background:#f2f4f7;padding:10px 12px;font-weight:600;font-size:12px;color:#344054;text-align:left;border-bottom:1px solid #EAECF0}.invoice-preview-modal .annexure-table td{padding:10px 12px;border-bottom:1px solid #F2F4F7;color:#101828;vertical-align:middle}.invoice-preview-modal .annexure-table tbody tr:nth-child(2n) td{background:#fcfcfd}.invoice-preview-modal .annexure-table tbody tr:hover td{background:#f9fafb}.invoice-preview-modal .annexure-table .cell-store{font-weight:600}.invoice-preview-modal .annexure-table .cell-nowrap{white-space:nowrap}.invoice-preview-modal .annexure-table .cell-muted{color:#667085}.invoice-preview-modal .annexure-table .cell-num{font-variant-numeric:tabular-nums}.invoice-preview-modal .annexure-table .cell-total strong{color:#101828}.invoice-preview-modal .annexure-table .unit-basis{font-size:11px;color:#98a2b3;margin-top:2px}.invoice-preview-modal .annexure-table tfoot td{position:sticky;bottom:0;background:#f9fafb;border-top:2px solid #EAECF0;border-bottom:none;font-size:14px}.invoice-preview-modal .loading-state,.invoice-preview-modal .empty-state,.invoice-preview-modal .error-state{padding:40px;text-align:center;color:#667085}.invoice-preview-modal .modal-footer{flex:0 0 auto}.invoice-preview-modal .annexure-toolbar{display:flex;justify-content:flex-end;padding:8px 0 12px}\n"] }]
277
280
  }], ctorParameters: () => [{ type: i1.NgbActiveModal }, { type: i2.BillingService }, { type: i3.ToastService }], propDecorators: { invoiceData: [{
278
281
  type: Input
279
282
  }] } });
280
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy9pbnZvaWNlLXByZXZpZXcvaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy9pbnZvaWNlLXByZXZpZXcvaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUVwRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssU0FBUyxNQUFNLFlBQVksQ0FBQztBQUd4QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7OztBQU92RCxNQUFNLE9BQU8sdUJBQXVCO0lBNEJ6QjtJQUNDO0lBQ0E7SUE3Qk8sUUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFFdkMsV0FBVyxDQUFNO0lBRTFCLFNBQVMsR0FBMkIsU0FBUyxDQUFDO0lBRTlDLFlBQVksR0FBaUIsSUFBSSxDQUFDO0lBQ2xDLDBFQUEwRTtJQUMxRSxpREFBaUQ7SUFDakQsYUFBYSxHQUFrQixJQUFJLENBQUM7SUFDcEMsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUN4QixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBRXRCLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFFcEIsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSxXQUFXLEdBQVE7UUFDakIsZUFBZSxFQUFFLDBDQUEwQztRQUMz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LE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxRSxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQWE7UUFDeEIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO3dHQW5SVSx1QkFBdUI7NEZBQXZCLHVCQUF1QixtR0NkcEMsNDFZQW1PTTs7NEZEck5PLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDRSxxQkFBcUI7MklBT3RCLFdBQVc7c0JBQW5CLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTmdiQWN0aXZlTW9kYWwgfSBmcm9tICdAbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcCc7XG5pbXBvcnQgeyBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcbmltcG9ydCAqIGFzIFhMU1ggZnJvbSAneGxzeCc7XG5pbXBvcnQgKiBhcyBGaWxlU2F2ZXIgZnJvbSAnZmlsZS1zYXZlcic7XG5pbXBvcnQgeyBCaWxsaW5nU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2JpbGxpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBUb2FzdFNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktc2hhcmVkJztcbmltcG9ydCB7IGFtb3VudEluV29yZHMgfSBmcm9tICcuL2Ftb3VudC1pbi13b3Jkcy51dGlsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLWludm9pY2UtcHJldmlldycsXG4gIHRlbXBsYXRlVXJsOiAnLi9pbnZvaWNlLXByZXZpZXcuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC5zY3NzJ1xufSlcbmV4cG9ydCBjbGFzcyBJbnZvaWNlUHJldmlld0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgQElucHV0KCkgaW52b2ljZURhdGE6IGFueTtcblxuICBhY3RpdmVUYWI6ICdpbnZvaWNlJyB8ICdhbm5leHVyZScgPSAnaW52b2ljZSc7XG5cbiAgYW5uZXh1cmVEYXRhOiBhbnlbXSB8IG51bGwgPSBudWxsO1xuICAvLyBHcmFuZCB0b3RhbCBvZiBhbGwgYW5uZXh1cmUgcm93cyAoY29tcHV0ZWQgYnkgdGhlIGJhY2tlbmQgd2l0aCB0aGUgc2FtZVxuICAvLyBwZXItY2FtZXJhIC8gcGVyLXpvbmUgcnVsZXMgdGhlIGludm9pY2UgdXNlcykuXG4gIGFubmV4dXJlVG90YWw6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBhbm5leHVyZUxvYWRpbmcgPSBmYWxzZTtcbiAgYW5uZXh1cmVFcnJvciA9IGZhbHNlO1xuXG4gIGRvd25sb2FkaW5nID0gZmFsc2U7XG5cbiAgLy8gRml4ZWQgYmVuZWZpY2lhcnkgYWNjb3VudCDigJQgaGFyZGNvZGVkIHRvIG1hdGNoIHRoZSBQREYgZXhhY3RseSAoTk9UIGZyb21cbiAgLy8gdGhlIERCKSwgc28gdGhlIHByZXZpZXcgYW5kIHRoZSBkb3dubG9hZGVkIFBERiBhbHdheXMgc2hvdyB0aGUgc2FtZSB0aGluZy5cbiAgYmFua0RldGFpbHM6IGFueSA9IHtcbiAgICBiZW5lZmljaWFyeU5hbWU6ICdUYW5nbyBJVCBTb2x1dGlvbnMgSW5kaWEgUHJpdmF0ZSBMaW1pdGVkJyxcbiAgICBhY2NvdW50TnVtYmVyOiAnNTAyMDAwMjc0NDE0MzMnLFxuICAgIGlmc2M6ICdIREZDMDAwMDM4NicsXG4gICAgc3dpZnQ6ICdIREZDSU5CQkNIRScsXG4gICAgYnJhbmNoOiAnU2FudGhvbWUsIENoZW5uYWknLFxuICAgIHBheW1lbnRUeXBlOiAnT25saW5lJyxcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYWN0aXZlTW9kYWw6IE5nYkFjdGl2ZU1vZGFsLFxuICAgIHByaXZhdGUgYmlsbGluZ1NlcnZpY2U6IEJpbGxpbmdTZXJ2aWNlLFxuICAgIHByaXZhdGUgdG9hc3Q6IFRvYXN0U2VydmljZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEJhbmsgZGV0YWlscyBhcmUgZml4ZWQgKHNlZSBiYW5rRGV0YWlscyBhYm92ZSkg4oCUIG5vdGhpbmcgdG8gZmV0Y2guXG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBzZWxlY3RUYWIodGFiOiAnaW52b2ljZScgfCAnYW5uZXh1cmUnKSB7XG4gICAgdGhpcy5hY3RpdmVUYWIgPSB0YWI7XG4gICAgaWYgKHRhYiA9PT0gJ2FubmV4dXJlJyAmJiB0aGlzLmFubmV4dXJlRGF0YSA9PT0gbnVsbCAmJiAhdGhpcy5hbm5leHVyZUxvYWRpbmcpIHtcbiAgICAgIHRoaXMubG9hZEFubmV4dXJlKCk7XG4gICAgfVxuICB9XG5cbiAgbG9hZEFubmV4dXJlKCkge1xuICAgIGlmICghdGhpcy5pbnZvaWNlRGF0YT8uX2lkKSByZXR1cm47XG4gICAgdGhpcy5hbm5leHVyZUxvYWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuYW5uZXh1cmVFcnJvciA9IGZhbHNlO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuZ2V0SW52b2ljZUFubmV4dXJlKHRoaXMuaW52b2ljZURhdGEuX2lkKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIC8vIEJhY2tlbmQgZW52ZWxvcGUgaXMgeyBjb2RlLCBzdGF0dXMsIGRhdGE6IHsgZGF0YTogWy4uLl0gfSB9IOKAlFxuICAgICAgICAgIC8vIHRoZSBjb250cm9sbGVyIGNhbGxzIHNlbmRTdWNjZXNzKHsgZGF0YTogYW5uZXh1cmVEYXRhIH0pIGFuZCB0aGVcbiAgICAgICAgICAvLyByZXNwb25zZSBtaWRkbGV3YXJlIHdyYXBzIHRoYXQgdW5kZXIgaXRzIG93biBgZGF0YWAga2V5LiBSZWFkXG4gICAgICAgICAgLy8gdGhyb3VnaCBib3RoIGxheWVycyB0byBnZXQgdGhlIHJvdyBhcnJheS5cbiAgICAgICAgICB0aGlzLmFubmV4dXJlRGF0YSA9IHJlcz8uZGF0YT8uZGF0YSB8fCBbXTtcbiAgICAgICAgICB0aGlzLmFubmV4dXJlVG90YWwgPSByZXM/LmRhdGE/LnRvdGFsQW1vdW50ID8/IG51bGw7XG4gICAgICAgICAgdGhpcy5hbm5leHVyZUxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmFubmV4dXJlRXJyb3IgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuYW5uZXh1cmVMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gRXhwb3J0IHRoZSBsb2FkZWQgYW5uZXh1cmUgcm93cyBhcyBhbiAueGxzeCBmaWxlLiBNaXJyb3JzIHRoZSBjb2x1bW5zXG4gIC8vIHNob3duIGluIHRoZSBBbm5leHVyZSB0YWIgc28gdGhlIHNwcmVhZHNoZWV0IG1hdGNoZXMgd2hhdCB0aGUgdXNlclxuICAvLyBzYXcgb24gc2NyZWVuLiBGaWxlbmFtZSBpcyBgJHtpbnZvaWNlTnVtYmVyfS1hbm5leHVyZS54bHN4YC5cbiAgZG93bmxvYWRBbm5leHVyZVhsc3goKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmFubmV4dXJlRGF0YSB8fCB0aGlzLmFubmV4dXJlRGF0YS5sZW5ndGggPT09IDApIHJldHVybjtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3ltYm9sID0gdGhpcy5jdXJyZW5jeVN5bWJvbCgpO1xuICAgICAgY29uc3Qgcm93czogYW55W10gPSB0aGlzLmFubmV4dXJlRGF0YS5tYXAoKHJvdzogYW55KSA9PiAoe1xuICAgICAgICAnU3RvcmUgTmFtZSc6IHJvdz8uc3RvcmVOYW1lIHx8ICcnLFxuICAgICAgICAnUHJvZHVjdCc6IHRoaXMuZm9ybWF0UHJvZHVjdE5hbWUocm93Py5wcm9kdWN0TmFtZSksXG4gICAgICAgICdTdG9yZSBJRCc6IHJvdz8uc3RvcmVJZCB8fCAnJyxcbiAgICAgICAgJ0RlcGxveW1lbnQgRGF0ZSc6IHJvdz8uZWRnZWZpcnN0RmlsZURhdGUgfHwgJycsXG4gICAgICAgICdQZXJpb2QnOiByb3c/LnBlcmlvZCA9PT0gJ3Byb3JhdGUnID8gJ1Byby1yYXRlJyA6ICdGdWxsIG1vbnRoJyxcbiAgICAgICAgJ1ByaWNpbmcgTWV0aG9kJzogcm93Py51bml0QmFzaXMgfHwgJ1BlciBTdG9yZScsXG4gICAgICAgICdCaWxsaW5nIERheXMnOiByb3c/LndvcmtpbmdkYXlzID8/IDAsXG4gICAgICAgICdRdHknOiByb3c/LnVuaXRzID8/IDEsXG4gICAgICAgICdVbml0IFByaWNlJzogcm93Py5zdGFuZGFyZFByaWNlICE9IG51bGxcbiAgICAgICAgICA/IGAke3N5bWJvbH0gJHt0aGlzLmZvcm1hdElOUihyb3cuc3RhbmRhcmRQcmljZSl9ICgke3Jvdz8udW5pdEJhc2lzIHx8ICdQZXIgU3RvcmUnfSlgXG4gICAgICAgICAgOiAnJyxcbiAgICAgICAgJ1ByaWNlIFBlciBNb250aCc6IHJvdz8ucnVubmluZ0Nvc3QgIT0gbnVsbFxuICAgICAgICAgID8gYCR7c3ltYm9sfSAke3RoaXMuZm9ybWF0SU5SKHJvdy5ydW5uaW5nQ29zdCl9YFxuICAgICAgICAgIDogJycsXG4gICAgICB9KSk7XG4gICAgICBpZiAodGhpcy5hbm5leHVyZVRvdGFsICE9IG51bGwpIHtcbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICAnU3RvcmUgTmFtZSc6ICcnLCAnUHJvZHVjdCc6ICcnLCAnU3RvcmUgSUQnOiAnJywgJ0RlcGxveW1lbnQgRGF0ZSc6ICcnLFxuICAgICAgICAgICdQZXJpb2QnOiAnJywgJ1ByaWNpbmcgTWV0aG9kJzogJycsXG4gICAgICAgICAgJ0JpbGxpbmcgRGF5cyc6ICcnLCAnUXR5JzogJycsICdVbml0IFByaWNlJzogJ1RvdGFsJyxcbiAgICAgICAgICAnUHJpY2UgUGVyIE1vbnRoJzogYCR7c3ltYm9sfSAke3RoaXMuZm9ybWF0SU5SKHRoaXMuYW5uZXh1cmVUb3RhbCl9YCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB3b3Jrc2hlZXQgPSBYTFNYLnV0aWxzLmpzb25fdG9fc2hlZXQocm93cyk7XG4gICAgICBjb25zdCB3b3JrYm9vayA9IHsgU2hlZXRzOiB7IEFubmV4dXJlOiB3b3Jrc2hlZXQgfSwgU2hlZXROYW1lczogWydBbm5leHVyZSddIH07XG4gICAgICBjb25zdCBidWZmZXI6IEFycmF5QnVmZmVyID0gWExTWC53cml0ZSh3b3JrYm9vaywgeyBib29rVHlwZTogJ3hsc3gnLCB0eXBlOiAnYXJyYXknIH0pO1xuICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtidWZmZXJdLCB7XG4gICAgICAgIHR5cGU6ICdhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5zaGVldDtjaGFyc2V0PVVURi04JyxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2FmZUludm9pY2VObyA9ICh0aGlzLmludm9pY2VEYXRhPy5pbnZvaWNlIHx8ICdpbnZvaWNlJykucmVwbGFjZSgvW1xcXFwvOio/XCI8PnxcXHJcXG5dL2csICcnKTtcbiAgICAgIEZpbGVTYXZlci5zYXZlQXMoYmxvYiwgYCR7c2FmZUludm9pY2VOb30tYW5uZXh1cmUueGxzeGApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGV4cG9ydCBhbm5leHVyZScpO1xuICAgIH1cbiAgfVxuXG4gIHJldHJ5QW5uZXh1cmUoKSB7XG4gICAgdGhpcy5hbm5leHVyZURhdGEgPSBudWxsO1xuICAgIHRoaXMubG9hZEFubmV4dXJlKCk7XG4gIH1cblxuICBkb3dubG9hZFBkZigpIHtcbiAgICBpZiAoIXRoaXMuaW52b2ljZURhdGE/Ll9pZCB8fCB0aGlzLmRvd25sb2FkaW5nKSByZXR1cm47XG4gICAgdGhpcy5kb3dubG9hZGluZyA9IHRydWU7XG4gICAgY29uc3QgcmVxID0geyAuLi50aGlzLmludm9pY2VEYXRhIH07XG4gICAgcmVxLmNsaWVudElkID0gW3RoaXMuaW52b2ljZURhdGEuY2xpZW50SWRdO1xuICAgIHRoaXMuYmlsbGluZ1NlcnZpY2UuaW52b2ljZURvd25sb2FkKHJlcSlcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3Jlc10sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL3BkZicgfSk7XG4gICAgICAgICAgY29uc3QgdXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgY29uc3QgbW9udGggPSB0aGlzLmludm9pY2VEYXRhPy5iaWxsaW5nRGF0ZVxuICAgICAgICAgICAgPyBuZXcgRGF0ZSh0aGlzLmludm9pY2VEYXRhLmJpbGxpbmdEYXRlKS50b0xvY2FsZVN0cmluZygnZW4tVVMnLCB7IG1vbnRoOiAnbG9uZycgfSlcbiAgICAgICAgICAgIDogJyc7XG4gICAgICAgICAgY29uc3QgYnJhbmROYW1lID0gdGhpcy5pbnZvaWNlRGF0YT8ucmVnaXN0ZXJlZENvbXBhbnlOYW1lIHx8IHRoaXMuaW52b2ljZURhdGE/LmNvbXBhbnlOYW1lIHx8ICcnO1xuICAgICAgICAgIGNvbnN0IGZpbGVuYW1lID0gYCR7dGhpcy5pbnZvaWNlRGF0YT8uaW52b2ljZSB8fCAnaW52b2ljZSd9LSR7bW9udGh9LSR7YnJhbmROYW1lfS5wZGZgXG4gICAgICAgICAgICAucmVwbGFjZSgvW1xcXFwvOio/XCI8PnxcXHJcXG5dL2csICcnKS50cmltKCk7XG4gICAgICAgICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgICAgICBsaW5rLmhyZWYgPSB1cmw7XG4gICAgICAgICAgbGluay5kb3dubG9hZCA9IGZpbGVuYW1lO1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgICAgICAgbGluay5jbGljaygpO1xuICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgICAgICAgd2luZG93LlVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgICAgdGhpcy5kb3dubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMudG9hc3QuZ2V0RXJyb3JUb2FzdCgnRmFpbGVkIHRvIGRvd25sb2FkIGludm9pY2UnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBNaXJyb3JzIHRoZSBiYWNrZW5kIENVUlJFTkNZX1NZTUJPTFMgbWFwICh1dGlscy9jdXJyZW5jeS5qcykgc28gdGhlXG4gIC8vIHByZXZpZXcgc2hvd3MgdGhlIHNhbWUgc3ltYm9sIHRoZSBQREYgd2lsbCByZW5kZXIuIEZhbGxiYWNrIGlzICckJyBmb3JcbiAgLy8gdW5rbm93biBjb2RlcyB0byBtYXRjaCB0aGUgYmFja2VuZC5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeVN5bWJvbHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAn4oK5JyxcbiAgICBkb2xsYXI6ICckJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdTJCcsXG4gICAgZXVybzogJ+KCrCcsXG4gICAgYWVkOiAnQUVEJyxcbiAgfTtcblxuICAvLyBXb3JkcyBmb3JtIG9mIGVhY2ggY3VycmVuY3kgZm9yIHRoZSBcIkFtb3VudCBpbiB3b3Jkc1wiIGxpbmUuXG4gIHByaXZhdGUgcmVhZG9ubHkgY3VycmVuY3lXb3JkczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBpbnI6ICdJbmRpYW4gUnVwZWUnLFxuICAgIGRvbGxhcjogJ1VTIERvbGxhcicsXG4gICAgc2luZ2Fwb3JlZG9sbGFyOiAnU2luZ2Fwb3JlIERvbGxhcicsXG4gICAgZXVybzogJ0V1cm8nLFxuICB9O1xuXG4gIC8vIEZyYWN0aW9uYWwgKHN1Yi11bml0KSBuYW1lIHBlciBjdXJyZW5jeSBmb3IgdGhlIGNlbnRzIHBvcnRpb24gb2YgdGhlXG4gIC8vIFwiVG90YWwgSW4gV29yZHNcIiBsaW5lLiBJTlIgaXMgd2hvbGUtbnVtYmVyIG9ubHksIHNvIGl0IGhhcyBubyBmcmFjdGlvbi5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeUZyYWN0aW9uOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGRvbGxhcjogJ0NlbnRzJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdDZW50cycsXG4gICAgZXVybzogJ0NlbnRzJyxcbiAgICBhZWQ6ICdGaWxzJyxcbiAgfTtcblxuICAvLyBMb2NhbGUgdXNlZCBmb3IgZ3JvdXBpbmcgbnVtYmVycy4gZW4tSU4gaXMgbGFraHMvY3JvcmVzOyBldmVyeXRoaW5nIGVsc2VcbiAgLy8gZ2V0cyB3ZXN0ZXJuIHRob3VzYW5kcyBncm91cGluZy5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeUxvY2FsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAnZW4tSU4nLFxuICAgIGRvbGxhcjogJ2VuLVVTJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdlbi1TRycsXG4gICAgZXVybzogJ2VuLUlFJyxcbiAgfTtcblxuICBjdXJyZW5jeVN5bWJvbCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLmludm9pY2VEYXRhPy5jdXJyZW5jeTtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW5jeVN5bWJvbHNbY29kZSB8fCAnJ10gfHwgJyQnO1xuICB9XG5cbiAgLy8gUGF5bWVudCB0ZXJtIGluIGRheXMuIFVzZSB0aGUgYmlsbGluZyBncm91cCdzIHBheW1lbnRUZXJtIOKAlCB0aGUgc2FtZSBzb3VyY2VcbiAgLy8gdGhlIFBERiBkb3dubG9hZCB1c2VzIOKAlCB3aGljaCBnZXRJbnZvaWNlIG5vdyByZXR1cm5zIG9uIGludm9pY2VEYXRhLiBUaGlzXG4gIC8vIGtlZXBzIFwiVGVybSBOXCIgaWRlbnRpY2FsIGJldHdlZW4gcHJldmlldyBhbmQgZG93bmxvYWQuIChQcmV2aW91c2x5IHRoaXMgd2FzXG4gIC8vIGRlcml2ZWQgZnJvbSBkdWVEYXRlIOKIkiBiaWxsaW5nRGF0ZSwgd2hpY2ggb3Zlci1jb3VudHMsIGUuZy4gYSAzMC1kYXkgdGVybVxuICAvLyB3aG9zZSBkdWUgZGF0ZSBsYW5kcyAzMiBjYWxlbmRhciBkYXlzIG91dC4pIEZhbGxzIGJhY2sgdG8gMzAuXG4gIGdldCBwYXltZW50VGVybURheXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTnVtYmVyKHRoaXMuaW52b2ljZURhdGE/LnBheW1lbnRUZXJtKSB8fCAzMDtcbiAgfVxuXG4gIGdldCB0b3RhbEluV29yZHMoKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5pbnZvaWNlRGF0YT8uY3VycmVuY3k7XG4gICAgY29uc3Qgd29yZHMgPSB0aGlzLmN1cnJlbmN5V29yZHNbY29kZSB8fCAnJ10gfHwgJ1VTIERvbGxhcic7XG4gICAgY29uc3QgdmFsdWUgPSBOdW1iZXIodGhpcy5pbnZvaWNlRGF0YT8udG90YWxBbW91bnQgfHwgMCk7XG4gICAgLy8gSU5SIGlzIHdob2xlLW51bWJlciBvbmx5IOKAlCByZW5kZXIganVzdCB0aGUgcnVwZWUgd29yZHMuIEV2ZXJ5IG90aGVyXG4gICAgLy8gY3VycmVuY3kga2VlcHMgMiBkZWNpbWFscywgc28gc3BlbGwgb3V0IHRoZSBjZW50cyB0b28gd2hlbiBub24temVyby5cbiAgICBpZiAoY29kZSA9PT0gJ2lucicpIHtcbiAgICAgIHJldHVybiBgJHt3b3Jkc30gJHthbW91bnRJbldvcmRzKE1hdGgucm91bmQodmFsdWUpKX0gT25seWA7XG4gICAgfVxuICAgIGNvbnN0IHdob2xlID0gTWF0aC50cnVuYyh2YWx1ZSk7XG4gICAgY29uc3QgY2VudHMgPSBNYXRoLnJvdW5kKCh2YWx1ZSAtIHdob2xlKSAqIDEwMCk7XG4gICAgY29uc3QgZnJhY3Rpb24gPSB0aGlzLmN1cnJlbmN5RnJhY3Rpb25bY29kZSB8fCAnJ10gfHwgJ0NlbnRzJztcbiAgICBpZiAoY2VudHMgPiAwKSB7XG4gICAgICByZXR1cm4gYCR7d29yZHN9ICR7YW1vdW50SW5Xb3Jkcyh3aG9sZSl9IGFuZCAke2Ftb3VudEluV29yZHMoY2VudHMpfSAke2ZyYWN0aW9ufSBPbmx5YDtcbiAgICB9XG4gICAgcmV0dXJuIGAke3dvcmRzfSAke2Ftb3VudEluV29yZHMod2hvbGUpfSBPbmx5YDtcbiAgfVxuXG4gIC8vIFByZS1kaXNjb3VudCBiYXNlOiB0aGUgc3RvcmVkIGFtb3VudCBpcyBwb3N0LWRpc2NvdW50LCBzbyB0aGUgb3JpZ2luYWwgaXNcbiAgLy8gcmVjb25zdHJ1Y3RlZCBieSBhZGRpbmcgdGhlIGFwcGxpZWQgZGlzY291bnQgYmFjay5cbiAgb3JpZ2luYWxBbW91bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKE51bWJlcih0aGlzLmludm9pY2VEYXRhPy5hbW91bnQpIHx8IDApICsgKE51bWJlcih0aGlzLmludm9pY2VEYXRhPy5kaXNjb3VudEFtb3VudCkgfHwgMCk7XG4gIH1cblxuICBmb3JtYXRJTlIodmFsdWU6IGFueSwgd2hvbGVJbnI6IGJvb2xlYW4gPSBmYWxzZSk6IHN0cmluZyB7XG4gICAgY29uc3QgY29kZSA9IHRoaXMuaW52b2ljZURhdGE/LmN1cnJlbmN5O1xuICAgIGNvbnN0IGlzSW5yID0gY29kZSA9PT0gJ2lucic7XG4gICAgY29uc3QgbiA9IE51bWJlcih2YWx1ZSk7XG4gICAgaWYgKCFpc0Zpbml0ZShuKSkgcmV0dXJuIGlzSW5yICYmIHdob2xlSW5yID8gJzAnIDogJzAuMDAnO1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuY3VycmVuY3lMb2NhbGVzW2NvZGUgfHwgJyddIHx8ICdlbi1VUyc7XG4gICAgLy8gQnVzaW5lc3MgcnVsZTogd2hvbGUtbnVtYmVyIHJvdW5kLW9mZiBhcHBsaWVzIE9OTFkgdG8gdGhlIFRvdGFsIEFtb3VudCxcbiAgICAvLyBhbmQgb25seSBmb3IgSU5SIChwYXNzIHdob2xlSW5yPXRydWUgdGhlcmUpLiBFdmVyeSBvdGhlciBmaWd1cmUg4oCUXG4gICAgLy8gc3VidG90YWwsIGRpc2NvdW50LCBHU1Qg4oCUIGtlZXBzIGV4YWN0bHkgMiBkZWNpbWFsIHBsYWNlcyBpbiBldmVyeVxuICAgIC8vIGN1cnJlbmN5LlxuICAgIGNvbnN0IGZyYWN0aW9uRGlnaXRzID0gaXNJbnIgJiYgd2hvbGVJbnIgPyAwIDogMjtcbiAgICByZXR1cm4gbi50b0xvY2FsZVN0cmluZyhsb2NhbGUsIHsgbWluaW11bUZyYWN0aW9uRGlnaXRzOiBmcmFjdGlvbkRpZ2l0cywgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiBmcmFjdGlvbkRpZ2l0cyB9KTtcbiAgfVxuXG4gIC8vIEEgdGF4IGxpbmUgKElHU1QvQ0dTVC9TR1NUKSBpcyBvbmx5IHNob3duIHdoZW4gaXQgYWN0dWFsbHkgaGFzIGEgbm9uLXplcm9cbiAgLy8gYW1vdW50IOKAlCB6ZXJvIC8gbWlzc2luZyB0YXggcm93cyBhcmUgaGlkZGVuIGluIHRoZSBwcmV2aWV3IChhbmQgUERGKS5cbiAgaGFzVGF4KHQ6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc0Zpbml0ZShOdW1iZXIodD8udGF4QW1vdW50KSkgJiYgTnVtYmVyKHQ/LnRheEFtb3VudCkgPiAwO1xuICB9XG5cbiAgLy8gTGluZSBpdGVtcyBzaG93biBpbiB0aGUgcHJldmlldywgd2l0aCB6ZXJvLXF1YW50aXR5IHJvd3MgZHJvcHBlZCBzbyB0aGVcbiAgLy8gbnVtYmVyaW5nIChpICsgMSkgc3RheXMgc2VxdWVudGlhbC4gQSByb3cgaXMgaGlkZGVuIHdoZW4gaXRzIHF1YW50aXR5IGlzIGFuXG4gIC8vIGV4cGxpY2l0IDAgd2l0aCBhIDAgYW1vdW50IOKAlCB0aGlzIGRyb3BzIGFkZGl0aW9uYWwgcHJvZHVjdHNcbiAgLy8gKEV5ZXRlc3QvUGxhbm9ncmFtL0FJIE1hbmFnZXIvVk1TLCBIU04gOTk4MzE0KSB0aGF0IHJlc29sdmVkIHRvIG5vIHN0b3Jlc1xuICAvLyBmb3IgdGhpcyBiaWxsaW5nIGdyb3VwLiBPbmx5IHNraXBzIHJvd3MgdGhhdCBjYXJyeSB0aGVpciBvd24gc3RvcmVDb3VudFxuICAvLyAoYWRkaXRpb25hbCBwcm9kdWN0cyBhbHdheXMgZG8pOyBub3JtYWwgc3RvcmUtYmFzZWQgcm93cyB3aXRob3V0IGFcbiAgLy8gc3RvcmVDb3VudCBmYWxsIGJhY2sgdG8gdGhlIGludm9pY2Ugc3RvcmUgY291bnQgYW5kIGFyZSBsZWZ0IHVudG91Y2hlZC5cbiAgdmlzaWJsZVByb2R1Y3RzKCk6IGFueVtdIHtcbiAgICBjb25zdCBwcm9kdWN0cyA9IHRoaXMuaW52b2ljZURhdGE/LnByb2R1Y3RzO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShwcm9kdWN0cykpIHJldHVybiBbXTtcbiAgICByZXR1cm4gcHJvZHVjdHMuZmlsdGVyKChpdGVtKSA9PiB7XG4gICAgICBjb25zdCBxdHkgPSBOdW1iZXIoaXRlbT8uc3RvcmVDb3VudCA/PyBpdGVtPy5xdWFudGl0eSk7XG4gICAgICBjb25zdCBhbW91bnQgPSBOdW1iZXIoaXRlbT8uYW1vdW50KTtcbiAgICAgIHJldHVybiAhKGlzRmluaXRlKHF0eSkgJiYgcXR5ID09PSAwICYmICghaXNGaW5pdGUoYW1vdW50KSB8fCBhbW91bnQgPT09IDApKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIE1pcnJvcnMgdGhlIGJhY2tlbmQgdHJhbnNmb3JtOiBgdGFuZ29UcmFmZmljYCAtPiBgVGFuZ28gVHJhZmZpY2AuXG4gIGZvcm1hdFByb2R1Y3ROYW1lKG5hbWU6IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKCFuYW1lKSByZXR1cm4gJyc7XG4gICAgY29uc3QgcGFydHMgPSBTdHJpbmcobmFtZSkucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgJyQxICQyJykuc3BsaXQoJyAnKTtcbiAgICByZXR1cm4gcGFydHMubWFwKCh3KSA9PiB3LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgdy5zbGljZSgxKSkuam9pbignICcpO1xuICB9XG5cbiAgdHJhY2tCeUluZGV4KGluZGV4OiBudW1iZXIpIHtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cbn0iLCI8ZGl2IGNsYXNzPVwiaW52b2ljZS1wcmV2aWV3LW1vZGFsXCI+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIj5cbiAgICA8dWwgY2xhc3M9XCJuYXYgbmF2LXRhYnMgcHJldmlldy10YWJzXCIgcm9sZT1cInRhYmxpc3RcIj5cbiAgICAgIDxsaSBjbGFzcz1cIm5hdi1pdGVtXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJuYXYtbGlua1wiIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlVGFiID09PSAnaW52b2ljZSdcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RUYWIoJ2ludm9pY2UnKVwiIHR5cGU9XCJidXR0b25cIj5JbnZvaWNlPC9idXR0b24+XG4gICAgICA8L2xpPlxuICAgICAgPGxpIGNsYXNzPVwibmF2LWl0ZW1cIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIm5hdi1saW5rXCIgW2NsYXNzLmFjdGl2ZV09XCJhY3RpdmVUYWIgPT09ICdhbm5leHVyZSdcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RUYWIoJ2FubmV4dXJlJylcIiB0eXBlPVwiYnV0dG9uXCI+QW5uZXh1cmU8L2J1dHRvbj5cbiAgICAgIDwvbGk+XG4gICAgPC91bD5cbiAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbG9zZVwiIChjbGljayk9XCJhY3RpdmVNb2RhbC5kaXNtaXNzKClcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIj48L2J1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHkgcC0wXCI+XG4gICAgPCEtLSBJTlZPSUNFIFRBQiAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiYWN0aXZlVGFiID09PSAnaW52b2ljZSdcIiBjbGFzcz1cImludm9pY2UtcGFnZVwiPlxuICAgICAgPCEtLSBIZWFkZXIgcm93IC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInJvdyBhbGlnbi1pdGVtcy1zdGFydFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTdcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnJhbmRcIj5cbiAgICAgICAgICAgIDxpbWcgc3JjPVwiLi9hc3NldHMvdGFuZ28vSW1hZ2VzL3RhbmdvZXllLWxvZ28uc3ZnXCIgYWx0PVwiVGFuZ29FeWVcIiBjbGFzcz1cImJyYW5kLWxvZ29cIiBvbmVycm9yPVwidGhpcy5zdHlsZS5kaXNwbGF5PSdub25lJ1wiPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wYW55LWJsb2NrIG10LTNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21wYW55LW5hbWVcIj5UQU5HTyBJVCBTT0xVVElPTlMgSU5ESUEgUFJJVkFURSBMVEQ8L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+Mm5kIEZsb29yLCBBcGVlamF5IEJ1c2luZXNzIENlbnRyZSwgTm8uMTIvMzksPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PkhhZGRvd3MgUm9hZCwgTnVuZ2FtYmFra2FtPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PkNoZW5uYWkgVGFtaWwgTmFkdSA2MDAwMDYsIEluZGlhPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiPjxzdHJvbmc+R1NUSU4gMzNBQUdDVDMxMjRSMVoyPC9zdHJvbmc+PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiPk1TTUUgLyBVZHlhbSB0eXBlIDogTWljcm88L2Rpdj5cbiAgICAgICAgICAgIDxkaXY+TVNNRSAvIFVkeWFtIE5vLiA6IFVEWUFNLVROLTAzLTAyMTIzOTk8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtNSB0ZXh0LWVuZFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0YXgtaW52b2ljZS1sYWJlbFwiPlRBWCBJTlZPSUNFPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtbnVtYmVyXCI+IyB7eyBpbnZvaWNlRGF0YT8uaW52b2ljZSB9fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIEJpbGwtdG8gKyB0b3RhbHMgcm93IC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInJvdyBtdC00XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtN1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJiaWxsLXRvLWxhYmVsXCI+QklMTCBUTyA6PC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNsaWVudC1uYW1lIG10LTFcIj57eyAoaW52b2ljZURhdGE/LmNsaWVudE5hbWUgfHwgaW52b2ljZURhdGE/LmNvbXBhbnlOYW1lKSB8IHVwcGVyY2FzZSB9fTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xXCIgKm5nSWY9XCJpbnZvaWNlRGF0YT8uYmlsbGluZ0FkZHJlc3NMaW5lT25lIHx8IGludm9pY2VEYXRhPy5jb21wYW55QWRkcmVzc1wiPlxuICAgICAgICAgICAge3sgaW52b2ljZURhdGE/LmJpbGxpbmdBZGRyZXNzTGluZU9uZSB8fCBpbnZvaWNlRGF0YT8uY29tcGFueUFkZHJlc3MgfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaW52b2ljZURhdGE/LmJpbGxpbmdBZGRyZXNzTGluZVR3b1wiPnt7IGludm9pY2VEYXRhPy5iaWxsaW5nQWRkcmVzc0xpbmVUd28gfX08L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaW52b2ljZURhdGE/LmJpbGxpbmdDaXR5IHx8IGludm9pY2VEYXRhPy5iaWxsaW5nUGluQ29kZSB8fCBpbnZvaWNlRGF0YT8uYmlsbGluZ1N0YXRlXCI+XG4gICAgICAgICAgICB7eyBpbnZvaWNlRGF0YT8uYmlsbGluZ0NpdHkgfX08c3BhbiAqbmdJZj1cImludm9pY2VEYXRhPy5iaWxsaW5nUGluQ29kZVwiPiwge3sgaW52b2ljZURhdGE/LmJpbGxpbmdQaW5Db2RlIH19PC9zcGFuPjxzcGFuICpuZ0lmPVwiaW52b2ljZURhdGE/LmJpbGxpbmdTdGF0ZVwiPiwge3sgaW52b2ljZURhdGE/LmJpbGxpbmdTdGF0ZSB9fTwvc3Bhbj48c3BhbiAqbmdJZj1cImludm9pY2VEYXRhPy5iaWxsaW5nQ291bnRyeVwiPiwge3sgaW52b2ljZURhdGE/LmJpbGxpbmdDb3VudHJ5IH19PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yXCIgKm5nSWY9XCJpbnZvaWNlRGF0YT8uR1NUTnVtYmVyXCI+PHN0cm9uZz5HU1RJTiB7eyBpbnZvaWNlRGF0YT8uR1NUTnVtYmVyIH19PC9zdHJvbmc+PC9kaXY+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImludm9pY2VEYXRhPy5QbGFjZU9mU3VwcGx5XCI+UGxhY2UgT2YgU3VwcGx5OiB7eyBpbnZvaWNlRGF0YT8uUGxhY2VPZlN1cHBseSB9fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC01IHRleHQtZW5kXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImludm9pY2UtdG90YWwtbGFiZWxcIj5JbnZvaWNlIFRvdGFsIDxzcGFuIGNsYXNzPVwiaW52b2ljZS10b3RhbC1hbW91bnRcIj57eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUihpbnZvaWNlRGF0YT8udG90YWxBbW91bnQpIH19PC9zcGFuPjwvZGl2PlxuICAgICAgICAgIDx0YWJsZSBjbGFzcz1cIm1ldGEtdGFibGUgbXMtYXV0byBtdC0zXCI+XG4gICAgICAgICAgICA8dHI+PHRkIGNsYXNzPVwibWV0YS1sYWJlbFwiPkludm9pY2UgZGF0ZSA6PC90ZD48dGQgY2xhc3M9XCJtZXRhLXZhbHVlXCI+e3sgaW52b2ljZURhdGE/LmJpbGxpbmdEYXRlIHwgZGF0ZTonZGQvTU0veXl5eScgfX08L3RkPjwvdHI+XG4gICAgICAgICAgICA8dHI+PHRkIGNsYXNzPVwibWV0YS1sYWJlbFwiPlRlcm1zIDo8L3RkPjx0ZCBjbGFzcz1cIm1ldGEtdmFsdWVcIj5UZXJtIHt7IHBheW1lbnRUZXJtRGF5cyB9fTwvdGQ+PC90cj5cbiAgICAgICAgICAgIDx0cj48dGQgY2xhc3M9XCJtZXRhLWxhYmVsXCI+RHVlIERhdGUgOjwvdGQ+PHRkIGNsYXNzPVwibWV0YS12YWx1ZVwiPnt7IGludm9pY2VEYXRhPy5kdWVEYXRlIHwgZGF0ZTonZGQvTU0veXl5eScgfX08L3RkPjwvdHI+XG4gICAgICAgICAgICA8dHIgKm5nSWY9XCJpbnZvaWNlRGF0YT8ucHVyY2hhc2VPcmRlck51bWJlciB8fCBpbnZvaWNlRGF0YT8uUG9OdW0gfHwgaW52b2ljZURhdGE/LnBvTnVtYmVyXCI+PHRkIGNsYXNzPVwibWV0YS1sYWJlbFwiPlAuTy4jIDo8L3RkPjx0ZCBjbGFzcz1cIm1ldGEtdmFsdWVcIj57eyBpbnZvaWNlRGF0YT8ucHVyY2hhc2VPcmRlck51bWJlciB8fCBpbnZvaWNlRGF0YT8uUG9OdW0gfHwgaW52b2ljZURhdGE/LnBvTnVtYmVyIH19PC90ZD48L3RyPlxuICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gTGluZSBpdGVtcyAtLT5cbiAgICAgIDx0YWJsZSBjbGFzcz1cIml0ZW1zLXRhYmxlIG10LTRcIj5cbiAgICAgICAgPHRoZWFkPlxuICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbC1pbmRleFwiPiM8L3RoPlxuICAgICAgICAgICAgPHRoIGNsYXNzPVwiY29sLXByb2R1Y3RcIj5Qcm9kdWN0ICZhbXA7IERlc2NyaXB0aW9uPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbC1tb250aFwiPk1vbnRoPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbC1oc25cIj5IU04vU0FDPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbC1jb3VudCB0ZXh0LWNlbnRlclwiPlF1YW50aXR5PC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbC1yYXRlIHRleHQtZW5kXCI+UmF0ZTwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJjb2wtYW1vdW50IHRleHQtZW5kXCI+QW1vdW50PC90aD5cbiAgICAgICAgICA8L3RyPlxuICAgICAgICA8L3RoZWFkPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHZpc2libGVQcm9kdWN0cygpOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cbiAgICAgICAgICAgIDx0ZD57eyBpICsgMSB9fTwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcm9kdWN0LW5hbWVcIj57eyBmb3JtYXRQcm9kdWN0TmFtZShpdGVtPy5wcm9kdWN0TmFtZSkgfX08L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb2R1Y3QtZGVzY1wiPnt7IGl0ZW0/LmRlc2NyaXB0aW9uIH19PC9kaXY+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPCEtLSBNb250aCBpcyB0aGUgcHJvZHVjdCdzIGJpbGxpbmcgbW9udGggc3RvcmVkIG9uIHRoZSBsaW5lIGl0ZW1cbiAgICAgICAgICAgICAgICAgKGFkdmFuY2UgaW52b2ljZXMgYmlsbCBhIGZ1dHVyZSBtb250aCB3aGlsZSBiaWxsaW5nRGF0ZSBpcyB0aGVcbiAgICAgICAgICAgICAgICAgY3JlYXRpb24gZGF0ZSkuIEZhbGwgYmFjayB0byBiaWxsaW5nRGF0ZSBmb3IgbGVnYWN5IHJvd3MuIC0tPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwibm93cmFwXCI+e3sgaXRlbT8ubW9udGggfHwgKGludm9pY2VEYXRhPy5iaWxsaW5nRGF0ZSB8IGRhdGU6J01NTSB5eXl5JykgfX08L3RkPlxuICAgICAgICAgICAgPHRkPnt7IGl0ZW0/LmhzbiB8fCBpdGVtPy5oc25Db2RlIHx8ICc5OTgzMTQnIH19PC90ZD5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyXCI+PHN0cm9uZz57eyBpdGVtPy5zdG9yZUNvdW50IHx8IGludm9pY2VEYXRhPy5zdG9yZXM/Lmxlbmd0aCB8fCAnJyB9fTwvc3Ryb25nPjwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWVuZCBub3dyYXBcIj57eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUihpdGVtPy5wcmljZSkgfX08L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1lbmQgbm93cmFwXCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIoaXRlbT8uYW1vdW50KSB9fTwvdGQ+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90Ym9keT5cbiAgICAgIDwvdGFibGU+XG5cbiAgICAgIDwhLS0gVG90YWxzIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInJvdyBtdC0zXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtN1wiPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTVcIj5cbiAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0b3RhbHMtdGFibGUgbXMtYXV0b1wiPlxuICAgICAgICAgICAgPCEtLSBXaXRoIGEgZGlzY291bnQsIHRlbGwgdGhlIHN0b3J5IHRvcC1kb3duOiBPcmlnaW5hbCBBbW91bnQgbWludXNcbiAgICAgICAgICAgICAgICAgRGlzY291bnQgZ2l2ZXMgdGhlIFN1YiBUb3RhbCAodGhlIEdTVCBiYXNlKS4gV2l0aG91dCBvbmUsIHRoZVxuICAgICAgICAgICAgICAgICBTdWIgVG90YWwgcm93IGFsb25lIHN1ZmZpY2VzLiAtLT5cbiAgICAgICAgICAgIDx0ciAqbmdJZj1cImludm9pY2VEYXRhPy5kaXNjb3VudEFtb3VudFwiPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtbGFiZWxcIj5TdWIgVG90YWw8L3RkPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtdmFsdWVcIj57eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUihvcmlnaW5hbEFtb3VudCgpKSB9fTwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyICpuZ0lmPVwiaW52b2ljZURhdGE/LmRpc2NvdW50QW1vdW50XCI+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRvdGFscy1sYWJlbFwiPkRpc2NvdW50PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLXZhbHVlXCI+LSB7eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUihpbnZvaWNlRGF0YT8uZGlzY291bnRBbW91bnQpIH19PC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8dHI+PHRkIGNsYXNzPVwidG90YWxzLWxhYmVsXCI+U3ViIFRvdGFsPC90ZD48dGQgY2xhc3M9XCJ0b3RhbHMtdmFsdWVcIj57eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUihpbnZvaWNlRGF0YT8uYW1vdW50KSB9fTwvdGQ+PC90cj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHQgb2YgaW52b2ljZURhdGE/LnRheFwiPlxuICAgICAgICAgICAgICA8dHIgKm5nSWY9XCJoYXNUYXgodClcIj5cbiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtbGFiZWxcIj57eyB0Py50eXBlIHx8IHQ/LnRheE5hbWUgfHwgdD8ubmFtZSB9fSAoe3sgdD8udmFsdWUgPz8gdD8udGF4UGVyY2VudGFnZSA/PyB0Py5wZXJjZW50YWdlIH19JSk8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRvdGFscy12YWx1ZSBub3dyYXBcIj57eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUih0Py50YXhBbW91bnQpIH19PC90ZD5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPHRyIGNsYXNzPVwidG90YWxzLXRvdGFsLXJvd1wiPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtbGFiZWxcIj5Ub3RhbCBBbW91bnQ8L3RkPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtdmFsdWVcIj57eyBjdXJyZW5jeVN5bWJvbCgpIH19IHt7IGZvcm1hdElOUihpbnZvaWNlRGF0YT8udG90YWxBbW91bnQsIHRydWUpIH19PC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8dHIgY2xhc3M9XCJ0b3RhbHMtd29yZHMtcm93XCI+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRvdGFscy1sYWJlbFwiPlRvdGFsIEluIFdvcmRzPC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLXZhbHVlIHdvcmRzXCI+e3sgdG90YWxJbldvcmRzIH19PC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBQYXltZW50IGRldGFpbHMgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwidGhhbmtzIG10LTRcIj5UaGFua3MgZm9yIHlvdXIgYnVzaW5lc3MhPC9kaXY+XG4gICAgICA8dGFibGUgY2xhc3M9XCJwYXltZW50LXRhYmxlIG10LTJcIj5cbiAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInBheW1lbnQtbGFiZWxcIj5CZW5lZmljaWFyeSBOYW1lPC90ZD48dGQgY2xhc3M9XCJwYXltZW50LXZhbHVlXCI+PHN0cm9uZz57eyBiYW5rRGV0YWlscz8uYmVuZWZpY2lhcnlOYW1lIH19PC9zdHJvbmc+PC90ZD48L3RyPlxuICAgICAgICA8dHI+PHRkIGNsYXNzPVwicGF5bWVudC1sYWJlbFwiPkFjY291bnQgTnVtYmVyPC90ZD48dGQgY2xhc3M9XCJwYXltZW50LXZhbHVlXCI+PHN0cm9uZz57eyBiYW5rRGV0YWlscz8uYWNjb3VudE51bWJlciB9fTwvc3Ryb25nPjwvdGQ+PC90cj5cbiAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInBheW1lbnQtbGFiZWxcIj5JRlNDIENvZGU8L3RkPjx0ZCBjbGFzcz1cInBheW1lbnQtdmFsdWVcIj48c3Ryb25nPnt7IGJhbmtEZXRhaWxzPy5pZnNjIH19PC9zdHJvbmc+PC90ZD48L3RyPlxuICAgICAgICA8dHI+PHRkIGNsYXNzPVwicGF5bWVudC1sYWJlbFwiPlBheW1lbnQgVHlwZTwvdGQ+PHRkIGNsYXNzPVwicGF5bWVudC12YWx1ZVwiPjxzdHJvbmc+e3sgYmFua0RldGFpbHM/LnBheW1lbnRUeXBlIH19PC9zdHJvbmc+PC90ZD48L3RyPlxuICAgICAgICA8dHI+PHRkIGNsYXNzPVwicGF5bWVudC1sYWJlbFwiPlNXSUZUIENvZGU8L3RkPjx0ZCBjbGFzcz1cInBheW1lbnQtdmFsdWVcIj48c3Ryb25nPnt7IGJhbmtEZXRhaWxzPy5zd2lmdCB9fTwvc3Ryb25nPjwvdGQ+PC90cj5cbiAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInBheW1lbnQtbGFiZWxcIj5CcmFuY2g8L3RkPjx0ZCBjbGFzcz1cInBheW1lbnQtdmFsdWVcIj48c3Ryb25nPnt7IGJhbmtEZXRhaWxzPy5icmFuY2ggfX08L3N0cm9uZz48L3RkPjwvdHI+XG4gICAgICA8L3RhYmxlPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwic3lzdGVtLW5vdGUgbXQtNFwiPlRoaXMgaXMgYSBzeXN0ZW0gZ2VuZXJhdGVkIGludm9pY2UuIE5vIHNpZ25hdHVyZSByZXF1aXJlZDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBBTk5FWFVSRSBUQUIgLS0+XG4gICAgPGRpdiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2FubmV4dXJlJ1wiIGNsYXNzPVwiYW5uZXh1cmUtcGFnZVwiPlxuICAgICAgPGRpdiAqbmdJZj1cImFubmV4dXJlTG9hZGluZ1wiIGNsYXNzPVwibG9hZGluZy1zdGF0ZVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXIgdGV4dC1wcmltYXJ5XCIgcm9sZT1cInN0YXR1c1wiPjxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+TG9hZGluZy4uLjwvc3Bhbj48L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiAqbmdJZj1cIiFhbm5leHVyZUxvYWRpbmcgJiYgYW5uZXh1cmVFcnJvclwiIGNsYXNzPVwiZXJyb3Itc3RhdGVcIj5cbiAgICAgICAgPHA+RmFpbGVkIHRvIGxvYWQgYW5uZXh1cmUuPC9wPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1wcmltYXJ5XCIgKGNsaWNrKT1cInJldHJ5QW5uZXh1cmUoKVwiPlJldHJ5PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCIhYW5uZXh1cmVMb2FkaW5nICYmICFhbm5leHVyZUVycm9yICYmIGFubmV4dXJlRGF0YSAhPT0gbnVsbCAmJiBhbm5leHVyZURhdGEubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJlbXB0eS1zdGF0ZVwiPlxuICAgICAgICBObyBhbm5leHVyZSBkYXRhIGZvciB0aGlzIGludm9pY2UuXG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCIhYW5uZXh1cmVMb2FkaW5nICYmICFhbm5leHVyZUVycm9yICYmIGFubmV4dXJlRGF0YSAmJiBhbm5leHVyZURhdGEubGVuZ3RoID4gMFwiXG4gICAgICAgICAgIGNsYXNzPVwiYW5uZXh1cmUtdG9vbGJhclwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtcHJpbWFyeVwiIChjbGljayk9XCJkb3dubG9hZEFubmV4dXJlWGxzeCgpXCI+XG4gICAgICAgICAgRXhwb3J0IGFzIFhMU1hcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCIhYW5uZXh1cmVMb2FkaW5nICYmICFhbm5leHVyZUVycm9yICYmIGFubmV4dXJlRGF0YSAmJiBhbm5leHVyZURhdGEubGVuZ3RoID4gMFwiXG4gICAgICAgICAgIGNsYXNzPVwiYW5uZXh1cmUtc2Nyb2xsXCI+XG4gICAgICAgIDx0YWJsZSBjbGFzcz1cImFubmV4dXJlLXRhYmxlXCI+XG4gICAgICAgICAgPGNvbGdyb3VwPlxuICAgICAgICAgICAgPGNvbCBjbGFzcz1cImNvbC1zdG9yZVwiIC8+XG4gICAgICAgICAgICA8Y29sIGNsYXNzPVwiY29sLXByb2R1Y3RcIiAvPlxuICAgICAgICAgICAgPGNvbCBjbGFzcz1cImNvbC1pZFwiIC8+XG4gICAgICAgICAgICA8Y29sIGNsYXNzPVwiY29sLWRhdGVcIiAvPlxuICAgICAgICAgICAgPGNvbCBjbGFzcz1cImNvbC1kYXlzXCIgLz5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtcXR5XCIgLz5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtcHJpY2VcIiAvPlxuICAgICAgICAgICAgPGNvbCBjbGFzcz1cImNvbC10b3RhbFwiIC8+XG4gICAgICAgICAgPC9jb2xncm91cD5cbiAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0aD5TdG9yZSBOYW1lPC90aD5cbiAgICAgICAgICAgICAgPHRoPlByb2R1Y3RzPC90aD5cbiAgICAgICAgICAgICAgPHRoPlN0b3JlIElEPC90aD5cbiAgICAgICAgICAgICAgPHRoPkRlcGxveW1lbnQgRGF0ZTwvdGg+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+QmlsbGluZyBEYXlzPC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIj5RdHk8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWVuZFwiPlVuaXQgUHJpY2U8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWVuZFwiPlByaWNlIFBlciBNb250aDwvdGg+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2YgYW5uZXh1cmVEYXRhOyB0cmFja0J5OiB0cmFja0J5SW5kZXhcIj5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY2VsbC1zdG9yZVwiPnt7IHJvdz8uc3RvcmVOYW1lIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkPnt7IHJvdz8ucHJvZHVjdE5hbWUgfX08L3RkPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjZWxsLW5vd3JhcCBjZWxsLW11dGVkXCI+e3sgcm93Py5zdG9yZUlkIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY2VsbC1ub3dyYXAgY2VsbC1tdXRlZFwiPnt7IHJvdz8uZWRnZWZpcnN0RmlsZURhdGUgfX08L3RkPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPjxzdHJvbmc+e3sgcm93Py53b3JraW5nZGF5cyB9fTwvc3Ryb25nPjwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyXCI+e3sgcm93Py51bml0cyA/PyAxIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1lbmQgY2VsbC1ub3dyYXAgY2VsbC1udW1cIj5cbiAgICAgICAgICAgICAgICB7eyByb3c/LmN1cnJlbmN5VHlwZSB9fSB7eyBmb3JtYXRJTlIocm93Py5zdGFuZGFyZFByaWNlKSB9fVxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ1bml0LWJhc2lzXCI+e3sgcm93Py51bml0QmFzaXMgfHwgJ1BlciBTdG9yZScgfX08L2Rpdj5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1lbmQgY2VsbC1ub3dyYXAgY2VsbC1udW0gY2VsbC10b3RhbFwiPlxuICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgcm93Py5jdXJyZW5jeVR5cGUgfX0ge3sgZm9ybWF0SU5SKHJvdz8ucnVubmluZ0Nvc3QpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgPHRmb290ICpuZ0lmPVwiYW5uZXh1cmVUb3RhbCAhPSBudWxsXCI+XG4gICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiN1wiIGNsYXNzPVwidGV4dC1lbmRcIj48c3Ryb25nPlRvdGFsPC9zdHJvbmc+PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1lbmQgY2VsbC1udW0gY2VsbC10b3RhbFwiPlxuICAgICAgICAgICAgICAgIDxzdHJvbmc+e3sgYW5uZXh1cmVEYXRhWzBdPy5jdXJyZW5jeVR5cGUgfX0ge3sgZm9ybWF0SU5SKGFubmV4dXJlVG90YWwpIH19PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGZvb3Q+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpbmtcIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCI+Q2xvc2U8L2J1dHRvbj5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiAoY2xpY2spPVwiZG93bmxvYWRQZGYoKVwiIFtkaXNhYmxlZF09XCJkb3dubG9hZGluZ1wiPlxuICAgICAgPHNwYW4gKm5nSWY9XCIhZG93bmxvYWRpbmdcIj5Eb3dubG9hZCBQREY8L3NwYW4+XG4gICAgICA8c3BhbiAqbmdJZj1cImRvd25sb2FkaW5nXCI+RG93bmxvYWRpbmcuLi48L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuPC9kaXY+Il19
283
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy9pbnZvaWNlLXByZXZpZXcvaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLW1hbmFnZS1iaWxsaW5nL3NyYy9saWIvY29tcG9uZW50cy9pbnZvaWNlLXByZXZpZXcvaW52b2ljZS1wcmV2aWV3LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUVwRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssU0FBUyxNQUFNLFlBQVksQ0FBQztBQUd4QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7OztBQU92RCxNQUFNLE9BQU8sdUJBQXVCO0lBNEJ6QjtJQUNDO0lBQ0E7SUE3Qk8sUUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFFdkMsV0FBVyxDQUFNO0lBRTFCLFNBQVMsR0FBMkIsU0FBUyxDQUFDO0lBRTlDLFlBQVksR0FBaUIsSUFBSSxDQUFDO0lBQ2xDLDBFQUEwRTtJQUMxRSxpREFBaUQ7SUFDakQsYUFBYSxHQUFrQixJQUFJLENBQUM7SUFDcEMsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUN4QixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBRXRCLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFFcEIsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSxXQUFXLEdBQVE7UUFDakIsZUFBZSxFQUFFLDBDQUEwQztRQUMz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LE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVFLENBQUM7SUFFRCxZQUFZLENBQUMsS0FBYTtRQUN4QixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7d0dBdFJVLHVCQUF1Qjs0RkFBdkIsdUJBQXVCLG1HQ2RwQyxxbFpBdU9NOzs0RkR6Tk8sdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLHFCQUFxQjsySUFPdEIsV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ2JBY3RpdmVNb2RhbCB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0ICogYXMgWExTWCBmcm9tICd4bHN4JztcbmltcG9ydCAqIGFzIEZpbGVTYXZlciBmcm9tICdmaWxlLXNhdmVyJztcbmltcG9ydCB7IEJpbGxpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYmlsbGluZy5zZXJ2aWNlJztcbmltcG9ydCB7IFRvYXN0U2VydmljZSB9IGZyb20gJ3RhbmdvLWFwcC11aS1zaGFyZWQnO1xuaW1wb3J0IHsgYW1vdW50SW5Xb3JkcyB9IGZyb20gJy4vYW1vdW50LWluLXdvcmRzLnV0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsaWItaW52b2ljZS1wcmV2aWV3JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ludm9pY2UtcHJldmlldy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsOiAnLi9pbnZvaWNlLXByZXZpZXcuY29tcG9uZW50LnNjc3MnXG59KVxuZXhwb3J0IGNsYXNzIEludm9pY2VQcmV2aWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBASW5wdXQoKSBpbnZvaWNlRGF0YTogYW55O1xuXG4gIGFjdGl2ZVRhYjogJ2ludm9pY2UnIHwgJ2FubmV4dXJlJyA9ICdpbnZvaWNlJztcblxuICBhbm5leHVyZURhdGE6IGFueVtdIHwgbnVsbCA9IG51bGw7XG4gIC8vIEdyYW5kIHRvdGFsIG9mIGFsbCBhbm5leHVyZSByb3dzIChjb21wdXRlZCBieSB0aGUgYmFja2VuZCB3aXRoIHRoZSBzYW1lXG4gIC8vIHBlci1jYW1lcmEgLyBwZXItem9uZSBydWxlcyB0aGUgaW52b2ljZSB1c2VzKS5cbiAgYW5uZXh1cmVUb3RhbDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIGFubmV4dXJlTG9hZGluZyA9IGZhbHNlO1xuICBhbm5leHVyZUVycm9yID0gZmFsc2U7XG5cbiAgZG93bmxvYWRpbmcgPSBmYWxzZTtcblxuICAvLyBGaXhlZCBiZW5lZmljaWFyeSBhY2NvdW50IOKAlCBoYXJkY29kZWQgdG8gbWF0Y2ggdGhlIFBERiBleGFjdGx5IChOT1QgZnJvbVxuICAvLyB0aGUgREIpLCBzbyB0aGUgcHJldmlldyBhbmQgdGhlIGRvd25sb2FkZWQgUERGIGFsd2F5cyBzaG93IHRoZSBzYW1lIHRoaW5nLlxuICBiYW5rRGV0YWlsczogYW55ID0ge1xuICAgIGJlbmVmaWNpYXJ5TmFtZTogJ1RhbmdvIElUIFNvbHV0aW9ucyBJbmRpYSBQcml2YXRlIExpbWl0ZWQnLFxuICAgIGFjY291bnROdW1iZXI6ICc1MDIwMDAyNzQ0MTQzMycsXG4gICAgaWZzYzogJ0hERkMwMDAwMzg2JyxcbiAgICBzd2lmdDogJ0hERkNJTkJCQ0hFJyxcbiAgICBicmFuY2g6ICdTYW50aG9tZSwgQ2hlbm5haScsXG4gICAgcGF5bWVudFR5cGU6ICdPbmxpbmUnLFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBhY3RpdmVNb2RhbDogTmdiQWN0aXZlTW9kYWwsXG4gICAgcHJpdmF0ZSBiaWxsaW5nU2VydmljZTogQmlsbGluZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSB0b2FzdDogVG9hc3RTZXJ2aWNlLFxuICApIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gQmFuayBkZXRhaWxzIGFyZSBmaXhlZCAoc2VlIGJhbmtEZXRhaWxzIGFib3ZlKSDigJQgbm90aGluZyB0byBmZXRjaC5cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHNlbGVjdFRhYih0YWI6ICdpbnZvaWNlJyB8ICdhbm5leHVyZScpIHtcbiAgICB0aGlzLmFjdGl2ZVRhYiA9IHRhYjtcbiAgICBpZiAodGFiID09PSAnYW5uZXh1cmUnICYmIHRoaXMuYW5uZXh1cmVEYXRhID09PSBudWxsICYmICF0aGlzLmFubmV4dXJlTG9hZGluZykge1xuICAgICAgdGhpcy5sb2FkQW5uZXh1cmUoKTtcbiAgICB9XG4gIH1cblxuICBsb2FkQW5uZXh1cmUoKSB7XG4gICAgaWYgKCF0aGlzLmludm9pY2VEYXRhPy5faWQpIHJldHVybjtcbiAgICB0aGlzLmFubmV4dXJlTG9hZGluZyA9IHRydWU7XG4gICAgdGhpcy5hbm5leHVyZUVycm9yID0gZmFsc2U7XG4gICAgdGhpcy5iaWxsaW5nU2VydmljZS5nZXRJbnZvaWNlQW5uZXh1cmUodGhpcy5pbnZvaWNlRGF0YS5faWQpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgLy8gQmFja2VuZCBlbnZlbG9wZSBpcyB7IGNvZGUsIHN0YXR1cywgZGF0YTogeyBkYXRhOiBbLi4uXSB9IH0g4oCUXG4gICAgICAgICAgLy8gdGhlIGNvbnRyb2xsZXIgY2FsbHMgc2VuZFN1Y2Nlc3MoeyBkYXRhOiBhbm5leHVyZURhdGEgfSkgYW5kIHRoZVxuICAgICAgICAgIC8vIHJlc3BvbnNlIG1pZGRsZXdhcmUgd3JhcHMgdGhhdCB1bmRlciBpdHMgb3duIGBkYXRhYCBrZXkuIFJlYWRcbiAgICAgICAgICAvLyB0aHJvdWdoIGJvdGggbGF5ZXJzIHRvIGdldCB0aGUgcm93IGFycmF5LlxuICAgICAgICAgIHRoaXMuYW5uZXh1cmVEYXRhID0gcmVzPy5kYXRhPy5kYXRhIHx8IFtdO1xuICAgICAgICAgIHRoaXMuYW5uZXh1cmVUb3RhbCA9IHJlcz8uZGF0YT8udG90YWxBbW91bnQgPz8gbnVsbDtcbiAgICAgICAgICB0aGlzLmFubmV4dXJlTG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICAgIHRoaXMuYW5uZXh1cmVFcnJvciA9IHRydWU7XG4gICAgICAgICAgdGhpcy5hbm5leHVyZUxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBFeHBvcnQgdGhlIGxvYWRlZCBhbm5leHVyZSByb3dzIGFzIGFuIC54bHN4IGZpbGUuIE1pcnJvcnMgdGhlIGNvbHVtbnNcbiAgLy8gc2hvd24gaW4gdGhlIEFubmV4dXJlIHRhYiBzbyB0aGUgc3ByZWFkc2hlZXQgbWF0Y2hlcyB3aGF0IHRoZSB1c2VyXG4gIC8vIHNhdyBvbiBzY3JlZW4uIEZpbGVuYW1lIGlzIGAke2ludm9pY2VOdW1iZXJ9LWFubmV4dXJlLnhsc3hgLlxuICBkb3dubG9hZEFubmV4dXJlWGxzeCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuYW5uZXh1cmVEYXRhIHx8IHRoaXMuYW5uZXh1cmVEYXRhLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzeW1ib2wgPSB0aGlzLmN1cnJlbmN5U3ltYm9sKCk7XG4gICAgICBjb25zdCByb3dzOiBhbnlbXSA9IHRoaXMuYW5uZXh1cmVEYXRhLm1hcCgocm93OiBhbnkpID0+ICh7XG4gICAgICAgICdTdG9yZSBOYW1lJzogcm93Py5zdG9yZU5hbWUgfHwgJycsXG4gICAgICAgICdQcm9kdWN0JzogdGhpcy5mb3JtYXRQcm9kdWN0TmFtZShyb3c/LnByb2R1Y3ROYW1lKSxcbiAgICAgICAgJ1N0b3JlIElEJzogcm93Py5zdG9yZUlkIHx8ICcnLFxuICAgICAgICAnRGVwbG95bWVudCBEYXRlJzogcm93Py5lZGdlZmlyc3RGaWxlRGF0ZSB8fCAnJyxcbiAgICAgICAgJ1BlcmlvZCc6IHJvdz8ucGVyaW9kID09PSAncHJvcmF0ZScgPyAnUHJvLXJhdGUnIDogJ0Z1bGwgbW9udGgnLFxuICAgICAgICAnUHJpY2luZyBNZXRob2QnOiByb3c/LnVuaXRCYXNpcyB8fCAnUGVyIFN0b3JlJyxcbiAgICAgICAgJ0JpbGxpbmcgRGF5cyc6IHJvdz8ud29ya2luZ2RheXMgPz8gMCxcbiAgICAgICAgJ1F0eSc6IHJvdz8udW5pdHMgPz8gMSxcbiAgICAgICAgJ1VuaXQgUHJpY2UnOiByb3c/LnN0YW5kYXJkUHJpY2UgIT0gbnVsbFxuICAgICAgICAgID8gYCR7c3ltYm9sfSAke3RoaXMuZm9ybWF0SU5SKHJvdy5zdGFuZGFyZFByaWNlKX0gKCR7cm93Py51bml0QmFzaXMgfHwgJ1BlciBTdG9yZSd9KWBcbiAgICAgICAgICA6ICcnLFxuICAgICAgICAnUHJpY2UgUGVyIE1vbnRoJzogcm93Py5ydW5uaW5nQ29zdCAhPSBudWxsXG4gICAgICAgICAgPyBgJHtzeW1ib2x9ICR7dGhpcy5mb3JtYXRJTlIocm93LnJ1bm5pbmdDb3N0KX1gXG4gICAgICAgICAgOiAnJyxcbiAgICAgIH0pKTtcbiAgICAgIGlmICh0aGlzLmFubmV4dXJlVG90YWwgIT0gbnVsbCkge1xuICAgICAgICByb3dzLnB1c2goe1xuICAgICAgICAgICdTdG9yZSBOYW1lJzogJycsICdQcm9kdWN0JzogJycsICdTdG9yZSBJRCc6ICcnLCAnRGVwbG95bWVudCBEYXRlJzogJycsXG4gICAgICAgICAgJ1BlcmlvZCc6ICcnLCAnUHJpY2luZyBNZXRob2QnOiAnJyxcbiAgICAgICAgICAnQmlsbGluZyBEYXlzJzogJycsICdRdHknOiAnJywgJ1VuaXQgUHJpY2UnOiAnVG90YWwnLFxuICAgICAgICAgICdQcmljZSBQZXIgTW9udGgnOiBgJHtzeW1ib2x9ICR7dGhpcy5mb3JtYXRJTlIodGhpcy5hbm5leHVyZVRvdGFsKX1gLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHdvcmtzaGVldCA9IFhMU1gudXRpbHMuanNvbl90b19zaGVldChyb3dzKTtcbiAgICAgIGNvbnN0IHdvcmtib29rID0geyBTaGVldHM6IHsgQW5uZXh1cmU6IHdvcmtzaGVldCB9LCBTaGVldE5hbWVzOiBbJ0FubmV4dXJlJ10gfTtcbiAgICAgIGNvbnN0IGJ1ZmZlcjogQXJyYXlCdWZmZXIgPSBYTFNYLndyaXRlKHdvcmtib29rLCB7IGJvb2tUeXBlOiAneGxzeCcsIHR5cGU6ICdhcnJheScgfSk7XG4gICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2J1ZmZlcl0sIHtcbiAgICAgICAgdHlwZTogJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0O2NoYXJzZXQ9VVRGLTgnLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBzYWZlSW52b2ljZU5vID0gKHRoaXMuaW52b2ljZURhdGE/Lmludm9pY2UgfHwgJ2ludm9pY2UnKS5yZXBsYWNlKC9bXFxcXC86Kj9cIjw+fFxcclxcbl0vZywgJycpO1xuICAgICAgRmlsZVNhdmVyLnNhdmVBcyhibG9iLCBgJHtzYWZlSW52b2ljZU5vfS1hbm5leHVyZS54bHN4YCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gZXhwb3J0IGFubmV4dXJlJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0cnlBbm5leHVyZSgpIHtcbiAgICB0aGlzLmFubmV4dXJlRGF0YSA9IG51bGw7XG4gICAgdGhpcy5sb2FkQW5uZXh1cmUoKTtcbiAgfVxuXG4gIGRvd25sb2FkUGRmKCkge1xuICAgIGlmICghdGhpcy5pbnZvaWNlRGF0YT8uX2lkIHx8IHRoaXMuZG93bmxvYWRpbmcpIHJldHVybjtcbiAgICB0aGlzLmRvd25sb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCByZXEgPSB7IC4uLnRoaXMuaW52b2ljZURhdGEgfTtcbiAgICByZXEuY2xpZW50SWQgPSBbdGhpcy5pbnZvaWNlRGF0YS5jbGllbnRJZF07XG4gICAgdGhpcy5iaWxsaW5nU2VydmljZS5pbnZvaWNlRG93bmxvYWQocmVxKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbcmVzXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vcGRmJyB9KTtcbiAgICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuaW52b2ljZURhdGE/LmJpbGxpbmdEYXRlXG4gICAgICAgICAgICA/IG5ldyBEYXRlKHRoaXMuaW52b2ljZURhdGEuYmlsbGluZ0RhdGUpLnRvTG9jYWxlU3RyaW5nKCdlbi1VUycsIHsgbW9udGg6ICdsb25nJyB9KVxuICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICBjb25zdCBicmFuZE5hbWUgPSB0aGlzLmludm9pY2VEYXRhPy5yZWdpc3RlcmVkQ29tcGFueU5hbWUgfHwgdGhpcy5pbnZvaWNlRGF0YT8uY29tcGFueU5hbWUgfHwgJyc7XG4gICAgICAgICAgY29uc3QgZmlsZW5hbWUgPSBgJHt0aGlzLmludm9pY2VEYXRhPy5pbnZvaWNlIHx8ICdpbnZvaWNlJ30tJHttb250aH0tJHticmFuZE5hbWV9LnBkZmBcbiAgICAgICAgICAgIC5yZXBsYWNlKC9bXFxcXC86Kj9cIjw+fFxcclxcbl0vZywgJycpLnRyaW0oKTtcbiAgICAgICAgICBjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgICAgICAgIGxpbmsuaHJlZiA9IHVybDtcbiAgICAgICAgICBsaW5rLmRvd25sb2FkID0gZmlsZW5hbWU7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsaW5rKTtcbiAgICAgICAgICBsaW5rLmNsaWNrKCk7XG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChsaW5rKTtcbiAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICAgIHRoaXMuZG93bmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLmRvd25sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy50b2FzdC5nZXRFcnJvclRvYXN0KCdGYWlsZWQgdG8gZG93bmxvYWQgaW52b2ljZScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIE1pcnJvcnMgdGhlIGJhY2tlbmQgQ1VSUkVOQ1lfU1lNQk9MUyBtYXAgKHV0aWxzL2N1cnJlbmN5LmpzKSBzbyB0aGVcbiAgLy8gcHJldmlldyBzaG93cyB0aGUgc2FtZSBzeW1ib2wgdGhlIFBERiB3aWxsIHJlbmRlci4gRmFsbGJhY2sgaXMgJyQnIGZvclxuICAvLyB1bmtub3duIGNvZGVzIHRvIG1hdGNoIHRoZSBiYWNrZW5kLlxuICBwcml2YXRlIHJlYWRvbmx5IGN1cnJlbmN5U3ltYm9sczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBpbnI6ICfigrknLFxuICAgIGRvbGxhcjogJyQnLFxuICAgIHNpbmdhcG9yZWRvbGxhcjogJ1MkJyxcbiAgICBldXJvOiAn4oKsJyxcbiAgICBhZWQ6ICdBRUQnLFxuICB9O1xuXG4gIC8vIFdvcmRzIGZvcm0gb2YgZWFjaCBjdXJyZW5jeSBmb3IgdGhlIFwiQW1vdW50IGluIHdvcmRzXCIgbGluZS4gUExVUkFMIGJ5XG4gIC8vIHJ1bGluZyAoMjAyNi0wOC0yNykg4oCUIFwiVVMgRG9sbGFycyBFaWdodCBIdW5kcmVkIC4uLiBPbmx5XCIg4oCUIGFuZCBrZXB0IGluXG4gIC8vIHN0ZXAgd2l0aCB0aGUgYmFja2VuZCBQREYncyBDVVJSRU5DWV9XT1JEUyAodXRpbHMvY3VycmVuY3kuanMpLlxuICBwcml2YXRlIHJlYWRvbmx5IGN1cnJlbmN5V29yZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAnSW5kaWFuIFJ1cGVlcycsXG4gICAgZG9sbGFyOiAnVVMgRG9sbGFycycsXG4gICAgc2luZ2Fwb3JlZG9sbGFyOiAnU2luZ2Fwb3JlIERvbGxhcnMnLFxuICAgIGV1cm86ICdFdXJvcycsXG4gICAgYWVkOiAnVUFFIERpcmhhbXMnLFxuICB9O1xuXG4gIC8vIEZyYWN0aW9uYWwgKHN1Yi11bml0KSBuYW1lIHBlciBjdXJyZW5jeSBmb3IgdGhlIGNlbnRzIHBvcnRpb24gb2YgdGhlXG4gIC8vIFwiVG90YWwgSW4gV29yZHNcIiBsaW5lLiBJTlIgaXMgd2hvbGUtbnVtYmVyIG9ubHksIHNvIGl0IGhhcyBubyBmcmFjdGlvbi5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeUZyYWN0aW9uOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIGRvbGxhcjogJ0NlbnRzJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdDZW50cycsXG4gICAgZXVybzogJ0NlbnRzJyxcbiAgICBhZWQ6ICdGaWxzJyxcbiAgfTtcblxuICAvLyBMb2NhbGUgdXNlZCBmb3IgZ3JvdXBpbmcgbnVtYmVycy4gZW4tSU4gaXMgbGFraHMvY3JvcmVzOyBldmVyeXRoaW5nIGVsc2VcbiAgLy8gZ2V0cyB3ZXN0ZXJuIHRob3VzYW5kcyBncm91cGluZy5cbiAgcHJpdmF0ZSByZWFkb25seSBjdXJyZW5jeUxvY2FsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgaW5yOiAnZW4tSU4nLFxuICAgIGRvbGxhcjogJ2VuLVVTJyxcbiAgICBzaW5nYXBvcmVkb2xsYXI6ICdlbi1TRycsXG4gICAgZXVybzogJ2VuLUlFJyxcbiAgfTtcblxuICBjdXJyZW5jeVN5bWJvbCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLmludm9pY2VEYXRhPy5jdXJyZW5jeTtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW5jeVN5bWJvbHNbY29kZSB8fCAnJ10gfHwgJyQnO1xuICB9XG5cbiAgLy8gUGF5bWVudCB0ZXJtIGluIGRheXMuIFVzZSB0aGUgYmlsbGluZyBncm91cCdzIHBheW1lbnRUZXJtIOKAlCB0aGUgc2FtZSBzb3VyY2VcbiAgLy8gdGhlIFBERiBkb3dubG9hZCB1c2VzIOKAlCB3aGljaCBnZXRJbnZvaWNlIG5vdyByZXR1cm5zIG9uIGludm9pY2VEYXRhLiBUaGlzXG4gIC8vIGtlZXBzIFwiVGVybSBOXCIgaWRlbnRpY2FsIGJldHdlZW4gcHJldmlldyBhbmQgZG93bmxvYWQuIChQcmV2aW91c2x5IHRoaXMgd2FzXG4gIC8vIGRlcml2ZWQgZnJvbSBkdWVEYXRlIOKIkiBiaWxsaW5nRGF0ZSwgd2hpY2ggb3Zlci1jb3VudHMsIGUuZy4gYSAzMC1kYXkgdGVybVxuICAvLyB3aG9zZSBkdWUgZGF0ZSBsYW5kcyAzMiBjYWxlbmRhciBkYXlzIG91dC4pIEZhbGxzIGJhY2sgdG8gMzAuXG4gIGdldCBwYXltZW50VGVybURheXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTnVtYmVyKHRoaXMuaW52b2ljZURhdGE/LnBheW1lbnRUZXJtKSB8fCAzMDtcbiAgfVxuXG4gIGdldCB0b3RhbEluV29yZHMoKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb2RlID0gdGhpcy5pbnZvaWNlRGF0YT8uY3VycmVuY3k7XG4gICAgY29uc3Qgd29yZHMgPSB0aGlzLmN1cnJlbmN5V29yZHNbY29kZSB8fCAnJ10gfHwgJ1VTIERvbGxhcnMnO1xuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyKHRoaXMuaW52b2ljZURhdGE/LnRvdGFsQW1vdW50IHx8IDApO1xuICAgIC8vIElOUiBpcyB3aG9sZS1udW1iZXIgb25seSDigJQgcmVuZGVyIGp1c3QgdGhlIHJ1cGVlIHdvcmRzLiBFdmVyeSBvdGhlclxuICAgIC8vIGN1cnJlbmN5IGtlZXBzIDIgZGVjaW1hbHMsIHNvIHNwZWxsIG91dCB0aGUgY2VudHMgdG9vIHdoZW4gbm9uLXplcm8uXG4gICAgaWYgKGNvZGUgPT09ICdpbnInKSB7XG4gICAgICByZXR1cm4gYCR7d29yZHN9ICR7YW1vdW50SW5Xb3JkcyhNYXRoLnJvdW5kKHZhbHVlKSl9IE9ubHlgO1xuICAgIH1cbiAgICBjb25zdCB3aG9sZSA9IE1hdGgudHJ1bmModmFsdWUpO1xuICAgIGNvbnN0IGNlbnRzID0gTWF0aC5yb3VuZCgodmFsdWUgLSB3aG9sZSkgKiAxMDApO1xuICAgIGNvbnN0IGZyYWN0aW9uID0gdGhpcy5jdXJyZW5jeUZyYWN0aW9uW2NvZGUgfHwgJyddIHx8ICdDZW50cyc7XG4gICAgaWYgKGNlbnRzID4gMCkge1xuICAgICAgcmV0dXJuIGAke3dvcmRzfSAke2Ftb3VudEluV29yZHMod2hvbGUpfSBhbmQgJHthbW91bnRJbldvcmRzKGNlbnRzKX0gJHtmcmFjdGlvbn0gT25seWA7XG4gICAgfVxuICAgIHJldHVybiBgJHt3b3Jkc30gJHthbW91bnRJbldvcmRzKHdob2xlKX0gT25seWA7XG4gIH1cblxuICAvLyBQcmUtZGlzY291bnQgYmFzZTogdGhlIHN0b3JlZCBhbW91bnQgaXMgcG9zdC1kaXNjb3VudCwgc28gdGhlIG9yaWdpbmFsIGlzXG4gIC8vIHJlY29uc3RydWN0ZWQgYnkgYWRkaW5nIHRoZSBhcHBsaWVkIGRpc2NvdW50IGJhY2suXG4gIG9yaWdpbmFsQW1vdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIChOdW1iZXIodGhpcy5pbnZvaWNlRGF0YT8uYW1vdW50KSB8fCAwKSArIChOdW1iZXIodGhpcy5pbnZvaWNlRGF0YT8uZGlzY291bnRBbW91bnQpIHx8IDApO1xuICB9XG5cbiAgZm9ybWF0SU5SKHZhbHVlOiBhbnksIHdob2xlSW5yOiBib29sZWFuID0gZmFsc2UpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvZGUgPSB0aGlzLmludm9pY2VEYXRhPy5jdXJyZW5jeTtcbiAgICBjb25zdCBpc0luciA9IGNvZGUgPT09ICdpbnInO1xuICAgIGNvbnN0IG4gPSBOdW1iZXIodmFsdWUpO1xuICAgIGlmICghaXNGaW5pdGUobikpIHJldHVybiBpc0luciAmJiB3aG9sZUluciA/ICcwJyA6ICcwLjAwJztcbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmN1cnJlbmN5TG9jYWxlc1tjb2RlIHx8ICcnXSB8fCAnZW4tVVMnO1xuICAgIC8vIEJ1c2luZXNzIHJ1bGU6IHdob2xlLW51bWJlciByb3VuZC1vZmYgYXBwbGllcyBPTkxZIHRvIHRoZSBUb3RhbCBBbW91bnQsXG4gICAgLy8gYW5kIG9ubHkgZm9yIElOUiAocGFzcyB3aG9sZUlucj10cnVlIHRoZXJlKS4gRXZlcnkgb3RoZXIgZmlndXJlIOKAlFxuICAgIC8vIHN1YnRvdGFsLCBkaXNjb3VudCwgR1NUIOKAlCBrZWVwcyBleGFjdGx5IDIgZGVjaW1hbCBwbGFjZXMgaW4gZXZlcnlcbiAgICAvLyBjdXJyZW5jeS5cbiAgICBjb25zdCBmcmFjdGlvbkRpZ2l0cyA9IGlzSW5yICYmIHdob2xlSW5yID8gMCA6IDI7XG4gICAgcmV0dXJuIG4udG9Mb2NhbGVTdHJpbmcobG9jYWxlLCB7IG1pbmltdW1GcmFjdGlvbkRpZ2l0czogZnJhY3Rpb25EaWdpdHMsIG1heGltdW1GcmFjdGlvbkRpZ2l0czogZnJhY3Rpb25EaWdpdHMgfSk7XG4gIH1cblxuICAvLyBBIHRheCBsaW5lIChJR1NUL0NHU1QvU0dTVCkgaXMgb25seSBzaG93biB3aGVuIGl0IGFjdHVhbGx5IGhhcyBhIG5vbi16ZXJvXG4gIC8vIGFtb3VudCDigJQgemVybyAvIG1pc3NpbmcgdGF4IHJvd3MgYXJlIGhpZGRlbiBpbiB0aGUgcHJldmlldyAoYW5kIFBERikuXG4gIGhhc1RheCh0OiBhbnkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNGaW5pdGUoTnVtYmVyKHQ/LnRheEFtb3VudCkpICYmIE51bWJlcih0Py50YXhBbW91bnQpID4gMDtcbiAgfVxuXG4gIC8vIExpbmUgaXRlbXMgc2hvd24gaW4gdGhlIHByZXZpZXcsIHdpdGggemVyby1xdWFudGl0eSByb3dzIGRyb3BwZWQgc28gdGhlXG4gIC8vIG51bWJlcmluZyAoaSArIDEpIHN0YXlzIHNlcXVlbnRpYWwuIEEgcm93IGlzIGhpZGRlbiB3aGVuIGl0cyBxdWFudGl0eSBpcyBhblxuICAvLyBleHBsaWNpdCAwIHdpdGggYSAwIGFtb3VudCDigJQgdGhpcyBkcm9wcyBhZGRpdGlvbmFsIHByb2R1Y3RzXG4gIC8vIChFeWV0ZXN0L1BsYW5vZ3JhbS9BSSBNYW5hZ2VyL1ZNUywgSFNOIDk5ODMxNCkgdGhhdCByZXNvbHZlZCB0byBubyBzdG9yZXNcbiAgLy8gZm9yIHRoaXMgYmlsbGluZyBncm91cC4gT25seSBza2lwcyByb3dzIHRoYXQgY2FycnkgdGhlaXIgb3duIHN0b3JlQ291bnRcbiAgLy8gKGFkZGl0aW9uYWwgcHJvZHVjdHMgYWx3YXlzIGRvKTsgbm9ybWFsIHN0b3JlLWJhc2VkIHJvd3Mgd2l0aG91dCBhXG4gIC8vIHN0b3JlQ291bnQgZmFsbCBiYWNrIHRvIHRoZSBpbnZvaWNlIHN0b3JlIGNvdW50IGFuZCBhcmUgbGVmdCB1bnRvdWNoZWQuXG4gIHZpc2libGVQcm9kdWN0cygpOiBhbnlbXSB7XG4gICAgY29uc3QgcHJvZHVjdHMgPSB0aGlzLmludm9pY2VEYXRhPy5wcm9kdWN0cztcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocHJvZHVjdHMpKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHByb2R1Y3RzLmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgcXR5ID0gTnVtYmVyKGl0ZW0/LnN0b3JlQ291bnQgPz8gaXRlbT8ucXVhbnRpdHkpO1xuICAgICAgY29uc3QgYW1vdW50ID0gTnVtYmVyKGl0ZW0/LmFtb3VudCk7XG4gICAgICByZXR1cm4gIShpc0Zpbml0ZShxdHkpICYmIHF0eSA9PT0gMCAmJiAoIWlzRmluaXRlKGFtb3VudCkgfHwgYW1vdW50ID09PSAwKSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBNaXJyb3JzIHRoZSBiYWNrZW5kIHRyYW5zZm9ybTogYHRhbmdvVHJhZmZpY2AgLT4gYFRhbmdvIFRyYWZmaWNgLlxuICBmb3JtYXRQcm9kdWN0TmFtZShuYW1lOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghbmFtZSkgcmV0dXJuICcnO1xuICAgIGNvbnN0IHBhcnRzID0gU3RyaW5nKG5hbWUpLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpLnNwbGl0KCcgJyk7XG4gICAgcmV0dXJuIHBhcnRzLm1hcCgodykgPT4gdy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHcuc2xpY2UoMSkpLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHRyYWNrQnlJbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG59IiwiPGRpdiBjbGFzcz1cImludm9pY2UtcHJldmlldy1tb2RhbFwiPlxuICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgPHVsIGNsYXNzPVwibmF2IG5hdi10YWJzIHByZXZpZXctdGFic1wiIHJvbGU9XCJ0YWJsaXN0XCI+XG4gICAgICA8bGkgY2xhc3M9XCJuYXYtaXRlbVwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwibmF2LWxpbmtcIiBbY2xhc3MuYWN0aXZlXT1cImFjdGl2ZVRhYiA9PT0gJ2ludm9pY2UnXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VGFiKCdpbnZvaWNlJylcIiB0eXBlPVwiYnV0dG9uXCI+SW52b2ljZTwvYnV0dG9uPlxuICAgICAgPC9saT5cbiAgICAgIDxsaSBjbGFzcz1cIm5hdi1pdGVtXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJuYXYtbGlua1wiIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlVGFiID09PSAnYW5uZXh1cmUnXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VGFiKCdhbm5leHVyZScpXCIgdHlwZT1cImJ1dHRvblwiPkFubmV4dXJlPC9idXR0b24+XG4gICAgICA8L2xpPlxuICAgIDwvdWw+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiAoY2xpY2spPVwiYWN0aXZlTW9kYWwuZGlzbWlzcygpXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+PC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5IHAtMFwiPlxuICAgIDwhLS0gSU5WT0lDRSBUQUIgLS0+XG4gICAgPGRpdiAqbmdJZj1cImFjdGl2ZVRhYiA9PT0gJ2ludm9pY2UnXCIgY2xhc3M9XCJpbnZvaWNlLXBhZ2VcIj5cbiAgICAgIDwhLS0gSGVhZGVyIHJvdyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJyb3cgYWxpZ24taXRlbXMtc3RhcnRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC03XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImJyYW5kXCI+XG4gICAgICAgICAgICA8aW1nIHNyYz1cIi4vYXNzZXRzL3RhbmdvL0ltYWdlcy90YW5nb2V5ZS1sb2dvLnN2Z1wiIGFsdD1cIlRhbmdvRXllXCIgY2xhc3M9XCJicmFuZC1sb2dvXCIgb25lcnJvcj1cInRoaXMuc3R5bGUuZGlzcGxheT0nbm9uZSdcIj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGFueS1ibG9jayBtdC0zXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tcGFueS1uYW1lXCI+VEFOR08gSVQgU09MVVRJT05TIElORElBIFBSSVZBVEUgTFREPC9kaXY+XG4gICAgICAgICAgICA8ZGl2PjJuZCBGbG9vciwgQXBlZWpheSBCdXNpbmVzcyBDZW50cmUsIE5vLjEyLzM5LDwvZGl2PlxuICAgICAgICAgICAgPGRpdj5IYWRkb3dzIFJvYWQsIE51bmdhbWJha2thbTwvZGl2PlxuICAgICAgICAgICAgPGRpdj5DaGVubmFpIFRhbWlsIE5hZHUgNjAwMDA2LCBJbmRpYTwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTFcIj48c3Ryb25nPkdTVElOIDMzQUFHQ1QzMTI0UjFaMjwvc3Ryb25nPjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTFcIj5NU01FIC8gVWR5YW0gdHlwZSA6IE1pY3JvPC9kaXY+XG4gICAgICAgICAgICA8ZGl2Pk1TTUUgLyBVZHlhbSBOby4gOiBVRFlBTS1UTi0wMy0wMjEyMzk5PC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTUgdGV4dC1lbmRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGF4LWludm9pY2UtbGFiZWxcIj5UQVggSU5WT0lDRTwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLW51bWJlclwiPiMge3sgaW52b2ljZURhdGE/Lmludm9pY2UgfX08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBCaWxsLXRvICsgdG90YWxzIHJvdyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJyb3cgbXQtNFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTdcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmlsbC10by1sYWJlbFwiPkJJTEwgVE8gOjwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjbGllbnQtbmFtZSBtdC0xXCI+e3sgKGludm9pY2VEYXRhPy5jbGllbnROYW1lIHx8IGludm9pY2VEYXRhPy5jb21wYW55TmFtZSkgfCB1cHBlcmNhc2UgfX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMVwiICpuZ0lmPVwiaW52b2ljZURhdGE/LmJpbGxpbmdBZGRyZXNzTGluZU9uZSB8fCBpbnZvaWNlRGF0YT8uY29tcGFueUFkZHJlc3NcIj5cbiAgICAgICAgICAgIHt7IGludm9pY2VEYXRhPy5iaWxsaW5nQWRkcmVzc0xpbmVPbmUgfHwgaW52b2ljZURhdGE/LmNvbXBhbnlBZGRyZXNzIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImludm9pY2VEYXRhPy5iaWxsaW5nQWRkcmVzc0xpbmVUd29cIj57eyBpbnZvaWNlRGF0YT8uYmlsbGluZ0FkZHJlc3NMaW5lVHdvIH19PC9kaXY+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImludm9pY2VEYXRhPy5iaWxsaW5nQ2l0eSB8fCBpbnZvaWNlRGF0YT8uYmlsbGluZ1BpbkNvZGUgfHwgaW52b2ljZURhdGE/LmJpbGxpbmdTdGF0ZVwiPlxuICAgICAgICAgICAge3sgaW52b2ljZURhdGE/LmJpbGxpbmdDaXR5IH19PHNwYW4gKm5nSWY9XCJpbnZvaWNlRGF0YT8uYmlsbGluZ1BpbkNvZGVcIj4sIHt7IGludm9pY2VEYXRhPy5iaWxsaW5nUGluQ29kZSB9fTwvc3Bhbj48c3BhbiAqbmdJZj1cImludm9pY2VEYXRhPy5iaWxsaW5nU3RhdGVcIj4sIHt7IGludm9pY2VEYXRhPy5iaWxsaW5nU3RhdGUgfX08L3NwYW4+PHNwYW4gKm5nSWY9XCJpbnZvaWNlRGF0YT8uYmlsbGluZ0NvdW50cnlcIj4sIHt7IGludm9pY2VEYXRhPy5iaWxsaW5nQ291bnRyeSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMlwiICpuZ0lmPVwiaW52b2ljZURhdGE/LkdTVE51bWJlclwiPjxzdHJvbmc+R1NUSU4ge3sgaW52b2ljZURhdGE/LkdTVE51bWJlciB9fTwvc3Ryb25nPjwvZGl2PlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJpbnZvaWNlRGF0YT8uUGxhY2VPZlN1cHBseVwiPlBsYWNlIE9mIFN1cHBseToge3sgaW52b2ljZURhdGE/LlBsYWNlT2ZTdXBwbHkgfX08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtNSB0ZXh0LWVuZFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZvaWNlLXRvdGFsLWxhYmVsXCI+SW52b2ljZSBUb3RhbCA8c3BhbiBjbGFzcz1cImludm9pY2UtdG90YWwtYW1vdW50XCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIoaW52b2ljZURhdGE/LnRvdGFsQW1vdW50KSB9fTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICA8dGFibGUgY2xhc3M9XCJtZXRhLXRhYmxlIG1zLWF1dG8gbXQtM1wiPlxuICAgICAgICAgICAgPHRyPjx0ZCBjbGFzcz1cIm1ldGEtbGFiZWxcIj5JbnZvaWNlIGRhdGUgOjwvdGQ+PHRkIGNsYXNzPVwibWV0YS12YWx1ZVwiPnt7IGludm9pY2VEYXRhPy5iaWxsaW5nRGF0ZSB8IGRhdGU6J2RkL01NL3l5eXknIH19PC90ZD48L3RyPlxuICAgICAgICAgICAgPHRyPjx0ZCBjbGFzcz1cIm1ldGEtbGFiZWxcIj5UZXJtcyA6PC90ZD48dGQgY2xhc3M9XCJtZXRhLXZhbHVlXCI+VGVybSB7eyBwYXltZW50VGVybURheXMgfX08L3RkPjwvdHI+XG4gICAgICAgICAgICA8dHI+PHRkIGNsYXNzPVwibWV0YS1sYWJlbFwiPkR1ZSBEYXRlIDo8L3RkPjx0ZCBjbGFzcz1cIm1ldGEtdmFsdWVcIj57eyBpbnZvaWNlRGF0YT8uZHVlRGF0ZSB8IGRhdGU6J2RkL01NL3l5eXknIH19PC90ZD48L3RyPlxuICAgICAgICAgICAgPHRyICpuZ0lmPVwiaW52b2ljZURhdGE/LnB1cmNoYXNlT3JkZXJOdW1iZXIgfHwgaW52b2ljZURhdGE/LlBvTnVtIHx8IGludm9pY2VEYXRhPy5wb051bWJlclwiPjx0ZCBjbGFzcz1cIm1ldGEtbGFiZWxcIj5QLk8uIyA6PC90ZD48dGQgY2xhc3M9XCJtZXRhLXZhbHVlXCI+e3sgaW52b2ljZURhdGE/LnB1cmNoYXNlT3JkZXJOdW1iZXIgfHwgaW52b2ljZURhdGE/LlBvTnVtIHx8IGludm9pY2VEYXRhPy5wb051bWJlciB9fTwvdGQ+PC90cj5cbiAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIExpbmUgaXRlbXMgLS0+XG4gICAgICA8dGFibGUgY2xhc3M9XCJpdGVtcy10YWJsZSBtdC00XCI+XG4gICAgICAgIDx0aGVhZD5cbiAgICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJjb2wtaW5kZXhcIj4jPC90aD5cbiAgICAgICAgICAgIDx0aCBjbGFzcz1cImNvbC1wcm9kdWN0XCI+UHJvZHVjdCAmYW1wOyBEZXNjcmlwdGlvbjwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJjb2wtbW9udGhcIj5Nb250aDwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJjb2wtaHNuXCI+SFNOL1NBQzwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJjb2wtY291bnQgdGV4dC1jZW50ZXJcIj5RdWFudGl0eTwvdGg+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJjb2wtcmF0ZSB0ZXh0LWVuZFwiPlJhdGU8L3RoPlxuICAgICAgICAgICAgPHRoIGNsYXNzPVwiY29sLWFtb3VudCB0ZXh0LWVuZFwiPkFtb3VudDwvdGg+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgaXRlbSBvZiB2aXNpYmxlUHJvZHVjdHMoKTsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUluZGV4XCI+XG4gICAgICAgICAgICA8dGQ+e3sgaSArIDEgfX08L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicHJvZHVjdC1uYW1lXCI+e3sgZm9ybWF0UHJvZHVjdE5hbWUoaXRlbT8ucHJvZHVjdE5hbWUpIH19PC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcm9kdWN0LWRlc2NcIj57eyBpdGVtPy5kZXNjcmlwdGlvbiB9fTwvZGl2PlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwhLS0gTW9udGggaXMgdGhlIHByb2R1Y3QncyBiaWxsaW5nIG1vbnRoIHN0b3JlZCBvbiB0aGUgbGluZSBpdGVtXG4gICAgICAgICAgICAgICAgIChhZHZhbmNlIGludm9pY2VzIGJpbGwgYSBmdXR1cmUgbW9udGggd2hpbGUgYmlsbGluZ0RhdGUgaXMgdGhlXG4gICAgICAgICAgICAgICAgIGNyZWF0aW9uIGRhdGUpLiBGYWxsIGJhY2sgdG8gYmlsbGluZ0RhdGUgZm9yIGxlZ2FjeSByb3dzLiAtLT5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cIm5vd3JhcFwiPnt7IGl0ZW0/Lm1vbnRoIHx8IChpbnZvaWNlRGF0YT8uYmlsbGluZ0RhdGUgfCBkYXRlOidNTU0geXl5eScpIH19PC90ZD5cbiAgICAgICAgICAgIDx0ZD57eyBpdGVtPy5oc24gfHwgaXRlbT8uaHNuQ29kZSB8fCAnOTk4MzE0JyB9fTwvdGQ+XG4gICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPjxzdHJvbmc+e3sgaXRlbT8uc3RvcmVDb3VudCB8fCBpbnZvaWNlRGF0YT8uc3RvcmVzPy5sZW5ndGggfHwgJycgfX08L3N0cm9uZz48L3RkPlxuICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1lbmQgbm93cmFwXCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIoaXRlbT8ucHJpY2UpIH19PC90ZD5cbiAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtZW5kIG5vd3JhcFwiPnt7IGN1cnJlbmN5U3ltYm9sKCkgfX0ge3sgZm9ybWF0SU5SKGl0ZW0/LmFtb3VudCkgfX08L3RkPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvdGJvZHk+XG4gICAgICA8L3RhYmxlPlxuXG4gICAgICA8IS0tIFRvdGFscyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJyb3cgbXQtM1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTdcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC01XCI+XG4gICAgICAgICAgPHRhYmxlIGNsYXNzPVwidG90YWxzLXRhYmxlIG1zLWF1dG9cIj5cbiAgICAgICAgICAgIDwhLS0gV2l0aCBhIGRpc2NvdW50LCB0ZWxsIHRoZSBzdG9yeSB0b3AtZG93bjogT3JpZ2luYWwgQW1vdW50IG1pbnVzXG4gICAgICAgICAgICAgICAgIERpc2NvdW50IGdpdmVzIHRoZSBTdWIgVG90YWwgKHRoZSBHU1QgYmFzZSkuIFdpdGhvdXQgb25lLCB0aGVcbiAgICAgICAgICAgICAgICAgU3ViIFRvdGFsIHJvdyBhbG9uZSBzdWZmaWNlcy4gLS0+XG4gICAgICAgICAgICA8dHIgKm5nSWY9XCJpbnZvaWNlRGF0YT8uZGlzY291bnRBbW91bnRcIj5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLWxhYmVsXCI+U3ViIFRvdGFsPC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLXZhbHVlXCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIob3JpZ2luYWxBbW91bnQoKSkgfX08L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDx0ciAqbmdJZj1cImludm9pY2VEYXRhPy5kaXNjb3VudEFtb3VudFwiPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtbGFiZWxcIj5EaXNjb3VudDwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRvdGFscy12YWx1ZVwiPi0ge3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIoaW52b2ljZURhdGE/LmRpc2NvdW50QW1vdW50KSB9fTwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInRvdGFscy1sYWJlbFwiPlN1YiBUb3RhbDwvdGQ+PHRkIGNsYXNzPVwidG90YWxzLXZhbHVlXCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIoaW52b2ljZURhdGE/LmFtb3VudCkgfX08L3RkPjwvdHI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB0IG9mIGludm9pY2VEYXRhPy50YXhcIj5cbiAgICAgICAgICAgICAgPHRyICpuZ0lmPVwiaGFzVGF4KHQpXCI+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLWxhYmVsXCI+e3sgdD8udHlwZSB8fCB0Py50YXhOYW1lIHx8IHQ/Lm5hbWUgfX0gKHt7IHQ/LnZhbHVlID8/IHQ/LnRheFBlcmNlbnRhZ2UgPz8gdD8ucGVyY2VudGFnZSB9fSUpPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtdmFsdWUgbm93cmFwXCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIodD8udGF4QW1vdW50KSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDx0ciBjbGFzcz1cInRvdGFscy10b3RhbC1yb3dcIj5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLWxhYmVsXCI+VG90YWwgQW1vdW50PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidG90YWxzLXZhbHVlXCI+e3sgY3VycmVuY3lTeW1ib2woKSB9fSB7eyBmb3JtYXRJTlIoaW52b2ljZURhdGE/LnRvdGFsQW1vdW50LCB0cnVlKSB9fTwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyIGNsYXNzPVwidG90YWxzLXdvcmRzLXJvd1wiPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0b3RhbHMtbGFiZWxcIj5Ub3RhbCBJbiBXb3JkczwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRvdGFscy12YWx1ZSB3b3Jkc1wiPnt7IHRvdGFsSW5Xb3JkcyB9fTwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gUGF5bWVudCBkZXRhaWxzIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInRoYW5rcyBtdC00XCI+VGhhbmtzIGZvciB5b3VyIGJ1c2luZXNzITwvZGl2PlxuICAgICAgPHRhYmxlIGNsYXNzPVwicGF5bWVudC10YWJsZSBtdC0yXCI+XG4gICAgICAgIDx0cj48dGQgY2xhc3M9XCJwYXltZW50LWxhYmVsXCI+QmVuZWZpY2lhcnkgTmFtZTwvdGQ+PHRkIGNsYXNzPVwicGF5bWVudC12YWx1ZVwiPjxzdHJvbmc+e3sgYmFua0RldGFpbHM/LmJlbmVmaWNpYXJ5TmFtZSB9fTwvc3Ryb25nPjwvdGQ+PC90cj5cbiAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInBheW1lbnQtbGFiZWxcIj5BY2NvdW50IE51bWJlcjwvdGQ+PHRkIGNsYXNzPVwicGF5bWVudC12YWx1ZVwiPjxzdHJvbmc+e3sgYmFua0RldGFpbHM/LmFjY291bnROdW1iZXIgfX08L3N0cm9uZz48L3RkPjwvdHI+XG4gICAgICAgIDx0cj48dGQgY2xhc3M9XCJwYXltZW50LWxhYmVsXCI+SUZTQyBDb2RlPC90ZD48dGQgY2xhc3M9XCJwYXltZW50LXZhbHVlXCI+PHN0cm9uZz57eyBiYW5rRGV0YWlscz8uaWZzYyB9fTwvc3Ryb25nPjwvdGQ+PC90cj5cbiAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInBheW1lbnQtbGFiZWxcIj5QYXltZW50IFR5cGU8L3RkPjx0ZCBjbGFzcz1cInBheW1lbnQtdmFsdWVcIj48c3Ryb25nPnt7IGJhbmtEZXRhaWxzPy5wYXltZW50VHlwZSB9fTwvc3Ryb25nPjwvdGQ+PC90cj5cbiAgICAgICAgPHRyPjx0ZCBjbGFzcz1cInBheW1lbnQtbGFiZWxcIj5TV0lGVCBDb2RlPC90ZD48dGQgY2xhc3M9XCJwYXltZW50LXZhbHVlXCI+PHN0cm9uZz57eyBiYW5rRGV0YWlscz8uc3dpZnQgfX08L3N0cm9uZz48L3RkPjwvdHI+XG4gICAgICAgIDx0cj48dGQgY2xhc3M9XCJwYXltZW50LWxhYmVsXCI+QnJhbmNoPC90ZD48dGQgY2xhc3M9XCJwYXltZW50LXZhbHVlXCI+PHN0cm9uZz57eyBiYW5rRGV0YWlscz8uYnJhbmNoIH19PC9zdHJvbmc+PC90ZD48L3RyPlxuICAgICAgPC90YWJsZT5cblxuICAgICAgPGRpdiBjbGFzcz1cInN5c3RlbS1ub3RlIG10LTRcIj5UaGlzIGlzIGEgc3lzdGVtIGdlbmVyYXRlZCBpbnZvaWNlLiBObyBzaWduYXR1cmUgcmVxdWlyZWQ8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gQU5ORVhVUkUgVEFCIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJhY3RpdmVUYWIgPT09ICdhbm5leHVyZSdcIiBjbGFzcz1cImFubmV4dXJlLXBhZ2VcIj5cbiAgICAgIDxkaXYgKm5nSWY9XCJhbm5leHVyZUxvYWRpbmdcIiBjbGFzcz1cImxvYWRpbmctc3RhdGVcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHRleHQtcHJpbWFyeVwiIHJvbGU9XCJzdGF0dXNcIj48c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPkxvYWRpbmcuLi48L3NwYW4+PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCIhYW5uZXh1cmVMb2FkaW5nICYmIGFubmV4dXJlRXJyb3JcIiBjbGFzcz1cImVycm9yLXN0YXRlXCI+XG4gICAgICAgIDxwPkZhaWxlZCB0byBsb2FkIGFubmV4dXJlLjwvcD5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtcHJpbWFyeVwiIChjbGljayk9XCJyZXRyeUFubmV4dXJlKClcIj5SZXRyeTwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWFubmV4dXJlTG9hZGluZyAmJiAhYW5uZXh1cmVFcnJvciAmJiBhbm5leHVyZURhdGEgIT09IG51bGwgJiYgYW5uZXh1cmVEYXRhLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZW1wdHktc3RhdGVcIj5cbiAgICAgICAgTm8gYW5uZXh1cmUgZGF0YSBmb3IgdGhpcyBpbnZvaWNlLlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWFubmV4dXJlTG9hZGluZyAmJiAhYW5uZXh1cmVFcnJvciAmJiBhbm5leHVyZURhdGEgJiYgYW5uZXh1cmVEYXRhLmxlbmd0aCA+IDBcIlxuICAgICAgICAgICBjbGFzcz1cImFubmV4dXJlLXRvb2xiYXJcIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiAoY2xpY2spPVwiZG93bmxvYWRBbm5leHVyZVhsc3goKVwiPlxuICAgICAgICAgIEV4cG9ydCBhcyBYTFNYXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWFubmV4dXJlTG9hZGluZyAmJiAhYW5uZXh1cmVFcnJvciAmJiBhbm5leHVyZURhdGEgJiYgYW5uZXh1cmVEYXRhLmxlbmd0aCA+IDBcIlxuICAgICAgICAgICBjbGFzcz1cImFubmV4dXJlLXNjcm9sbFwiPlxuICAgICAgICA8dGFibGUgY2xhc3M9XCJhbm5leHVyZS10YWJsZVwiPlxuICAgICAgICAgIDxjb2xncm91cD5cbiAgICAgICAgICAgIDwhLS0gUy5ObyBpcyBwcmV2aWV3LW9ubHkgKG5vdCBpbiB0aGUgUERGIC8gWExTWCBleHBvcnQpLiAtLT5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtc25vXCIgLz5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtc3RvcmVcIiAvPlxuICAgICAgICAgICAgPGNvbCBjbGFzcz1cImNvbC1wcm9kdWN0XCIgLz5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtaWRcIiAvPlxuICAgICAgICAgICAgPGNvbCBjbGFzcz1cImNvbC1kYXRlXCIgLz5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtZGF5c1wiIC8+XG4gICAgICAgICAgICA8Y29sIGNsYXNzPVwiY29sLXF0eVwiIC8+XG4gICAgICAgICAgICA8Y29sIGNsYXNzPVwiY29sLXByaWNlXCIgLz5cbiAgICAgICAgICAgIDxjb2wgY2xhc3M9XCJjb2wtdG90YWxcIiAvPlxuICAgICAgICAgIDwvY29sZ3JvdXA+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlMuTm88L3RoPlxuICAgICAgICAgICAgICA8dGg+U3RvcmUgTmFtZTwvdGg+XG4gICAgICAgICAgICAgIDx0aD5Qcm9kdWN0czwvdGg+XG4gICAgICAgICAgICAgIDx0aD5TdG9yZSBJRDwvdGg+XG4gICAgICAgICAgICAgIDx0aD5EZXBsb3ltZW50IERhdGU8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPkJpbGxpbmcgRGF5czwvdGg+XG4gICAgICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+UXR5PC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1lbmRcIj5Vbml0IFByaWNlPC90aD5cbiAgICAgICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1lbmRcIj5QcmljZSBQZXIgTW9udGg8L3RoPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgIDx0ciAqbmdGb3I9XCJsZXQgcm93IG9mIGFubmV4dXJlRGF0YTsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUluZGV4XCI+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtY2VudGVyIGNlbGwtbXV0ZWRcIj57eyBpICsgMSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNlbGwtc3RvcmVcIj57eyByb3c/LnN0b3JlTmFtZSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZD57eyByb3c/LnByb2R1Y3ROYW1lIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY2VsbC1ub3dyYXAgY2VsbC1tdXRlZFwiPnt7IHJvdz8uc3RvcmVJZCB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNlbGwtbm93cmFwIGNlbGwtbXV0ZWRcIj57eyByb3c/LmVkZ2VmaXJzdEZpbGVEYXRlIH19PC90ZD5cbiAgICAgICAgICAgICAgPHRkIGNsYXNzPVwidGV4dC1jZW50ZXJcIj48c3Ryb25nPnt7IHJvdz8ud29ya2luZ2RheXMgfX08L3N0cm9uZz48L3RkPlxuICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPnt7IHJvdz8udW5pdHMgPz8gMSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtZW5kIGNlbGwtbm93cmFwIGNlbGwtbnVtXCI+XG4gICAgICAgICAgICAgICAge3sgcm93Py5jdXJyZW5jeVR5cGUgfX0ge3sgZm9ybWF0SU5SKHJvdz8uc3RhbmRhcmRQcmljZSkgfX1cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidW5pdC1iYXNpc1wiPnt7IHJvdz8udW5pdEJhc2lzIHx8ICdQZXIgU3RvcmUnIH19PC9kaXY+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtZW5kIGNlbGwtbm93cmFwIGNlbGwtbnVtIGNlbGwtdG90YWxcIj5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IHJvdz8uY3VycmVuY3lUeXBlIH19IHt7IGZvcm1hdElOUihyb3c/LnJ1bm5pbmdDb3N0KSB9fTwvc3Ryb25nPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgIDx0Zm9vdCAqbmdJZj1cImFubmV4dXJlVG90YWwgIT0gbnVsbFwiPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjhcIiBjbGFzcz1cInRleHQtZW5kXCI+PHN0cm9uZz5Ub3RhbDwvc3Ryb25nPjwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInRleHQtZW5kIGNlbGwtbnVtIGNlbGwtdG90YWxcIj5cbiAgICAgICAgICAgICAgICA8c3Ryb25nPnt7IGFubmV4dXJlRGF0YVswXT8uY3VycmVuY3lUeXBlIH19IHt7IGZvcm1hdElOUihhbm5leHVyZVRvdGFsKSB9fTwvc3Ryb25nPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3Rmb290PlxuICAgICAgICA8L3RhYmxlPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rXCIgKGNsaWNrKT1cImFjdGl2ZU1vZGFsLmRpc21pc3MoKVwiPkNsb3NlPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5XCIgKGNsaWNrKT1cImRvd25sb2FkUGRmKClcIiBbZGlzYWJsZWRdPVwiZG93bmxvYWRpbmdcIj5cbiAgICAgIDxzcGFuICpuZ0lmPVwiIWRvd25sb2FkaW5nXCI+RG93bmxvYWQgUERGPC9zcGFuPlxuICAgICAgPHNwYW4gKm5nSWY9XCJkb3dubG9hZGluZ1wiPkRvd25sb2FkaW5nLi4uPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==