techlify-inventory-common 18.36.0 → 18.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/inventory-common/product/product-list/product-list.component.mjs +15 -17
- package/esm2022/lib/inventory-common/product/product-view-page/product-view-page.component.mjs +8 -8
- package/esm2022/lib/inventory-common/product/product.module.mjs +5 -5
- package/esm2022/lib/inventory-common/product/widgets/product-category-badges/product-category-badges.component.mjs +3 -3
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-list/stock-issue-list.component.mjs +115 -70
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-page/stock-issue-page.component.mjs +96 -0
- package/esm2022/lib/inventory-common/stock-issuances/{stock-issue-list/stock-issue-list.module.mjs → stock-issue-page/stock-issue-page.module.mjs} +18 -18
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-products-list/stock-issue-products-list.component.mjs +138 -0
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue-routing.module.mjs +3 -3
- package/esm2022/lib/inventory-common/stock-issuances/stock-issue.module.mjs +5 -5
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-list/stock-receipt-list.component.mjs +153 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-product-list/stock-receipt-product-list.component.mjs +146 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts-page/stock-receipts-page.component.mjs +70 -0
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts-routing.module.mjs +3 -3
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts.module.mjs +16 -16
- package/esm2022/lib/inventory-common/supplier/supplier-view/supplier-view.component.mjs +4 -4
- package/esm2022/public-api.mjs +8 -8
- package/fesm2022/{techlify-inventory-common-category.module-CUqub2ML.mjs → techlify-inventory-common-category.module-qyYKbe_g.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-category.module-CUqub2ML.mjs.map → techlify-inventory-common-category.module-qyYKbe_g.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-measure.module-CIonhS7Z.mjs → techlify-inventory-common-measure.module-Azgdcpqu.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-measure.module-CIonhS7Z.mjs.map → techlify-inventory-common-measure.module-Azgdcpqu.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-purchase-order-view.component-5zmdBnE-.mjs → techlify-inventory-common-purchase-order-view.component-tSf0_Lj_.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-purchase-order-view.component-5zmdBnE-.mjs.map → techlify-inventory-common-purchase-order-view.component-tSf0_Lj_.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-stock-issue-batch-form.component-CnRySjgj.mjs → techlify-inventory-common-stock-issue-batch-form.component-8u8sZ4gb.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-stock-issue-batch-form.component-CnRySjgj.mjs.map → techlify-inventory-common-stock-issue-batch-form.component-8u8sZ4gb.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-stock-issue-view.component-D1sTvEWD.mjs → techlify-inventory-common-stock-issue-view.component-C-SHFxmY.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-stock-issue-view.component-D1sTvEWD.mjs.map → techlify-inventory-common-stock-issue-view.component-C-SHFxmY.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-techlify-inventory-common-DVM9NowZ.mjs → techlify-inventory-common-techlify-inventory-common-CqakmnCI.mjs} +1556 -1554
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-CqakmnCI.mjs.map +1 -0
- package/fesm2022/techlify-inventory-common.mjs +1 -1
- package/lib/inventory-common/product/product-view-page/product-view-page.component.d.ts +4 -4
- package/lib/inventory-common/product/product.module.d.ts +2 -2
- package/lib/inventory-common/stock-issuances/stock-issue-list/stock-issue-list.component.d.ts +22 -22
- package/lib/inventory-common/stock-issuances/stock-issue-page/stock-issue-page.component.d.ts +28 -0
- package/lib/inventory-common/stock-issuances/stock-issue-page/stock-issue-page.module.d.ts +21 -0
- package/lib/inventory-common/stock-issuances/{itemized-stock-issue-products-list/itemized-stock-issue-products-list.component.d.ts → stock-issue-products-list/stock-issue-products-list.component.d.ts} +3 -3
- package/lib/inventory-common/stock-issuances/stock-issue.module.d.ts +2 -2
- package/lib/inventory-common/stock-receipts/{grouped-stock-receipt-list/grouped-stock-receipt-list.component.d.ts → stock-receipt-list/stock-receipt-list.component.d.ts} +3 -3
- package/lib/inventory-common/stock-receipts/{itemized-stock-receipt-products-list/itemized-stock-receipt-products-list.component.d.ts → stock-receipt-product-list/stock-receipt-product-list.component.d.ts} +3 -3
- package/lib/inventory-common/stock-receipts/{stock-receipts-list-page/stock-receipts-list-page.component.d.ts → stock-receipts-page/stock-receipts-page.component.d.ts} +3 -3
- package/lib/inventory-common/stock-receipts/stock-receipts.module.d.ts +4 -4
- package/package.json +1 -1
- package/public-api.d.ts +7 -7
- package/esm2022/lib/inventory-common/stock-issuances/grouped-stock-issue-list/grouped-stock-issue-list.component.mjs +0 -139
- package/esm2022/lib/inventory-common/stock-issuances/itemized-stock-issue-products-list/itemized-stock-issue-products-list.component.mjs +0 -138
- package/esm2022/lib/inventory-common/stock-receipts/grouped-stock-receipt-list/grouped-stock-receipt-list.component.mjs +0 -151
- package/esm2022/lib/inventory-common/stock-receipts/itemized-stock-receipt-products-list/itemized-stock-receipt-products-list.component.mjs +0 -146
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipts-list-page/stock-receipts-list-page.component.mjs +0 -70
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-DVM9NowZ.mjs.map +0 -1
- package/lib/inventory-common/stock-issuances/grouped-stock-issue-list/grouped-stock-issue-list.component.d.ts +0 -28
- package/lib/inventory-common/stock-issuances/stock-issue-list/stock-issue-list.module.d.ts +0 -21
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { Component, effect, input, output } from "@angular/core";
|
|
3
|
+
import { TechlifyListingControllerInterface } from 'ngx-techlify-core';
|
|
4
|
+
import { UntilDestroy } from "@ngneat/until-destroy";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "../stock-receipt.service";
|
|
7
|
+
import * as i2 from "@angular/forms";
|
|
8
|
+
import * as i3 from "@angular/router";
|
|
9
|
+
import * as i4 from "ngx-techlify-core";
|
|
10
|
+
import * as i5 from "@angular/common";
|
|
11
|
+
import * as i6 from "@angular/material/card";
|
|
12
|
+
import * as i7 from "@angular/material/progress-bar";
|
|
13
|
+
import * as i8 from "@angular/material/sort";
|
|
14
|
+
import * as i9 from "@angular/material/table";
|
|
15
|
+
import * as i10 from "@angular/material/tooltip";
|
|
16
|
+
import * as i11 from "ngx-infinite-scroll";
|
|
17
|
+
import * as i12 from "../stock-receipt-form/stock-receipt-form-button/stock-receipt-form-button.component";
|
|
18
|
+
import * as i13 from "../../product/widgets/product-category-badges/product-category-badges.component";
|
|
19
|
+
let StockReceiptListComponent = class StockReceiptListComponent extends TechlifyListingControllerInterface {
|
|
20
|
+
service;
|
|
21
|
+
formBuilder;
|
|
22
|
+
router;
|
|
23
|
+
featureService;
|
|
24
|
+
filters = input({});
|
|
25
|
+
selectedColumns = input([]);
|
|
26
|
+
exportInProgress = input(false);
|
|
27
|
+
listUpdated = output();
|
|
28
|
+
columnConfigReady = output();
|
|
29
|
+
_defaultSelectedColumns = [];
|
|
30
|
+
columnConfig = [
|
|
31
|
+
{ label: '#', def: 'no', isSelected: true, isEditable: false },
|
|
32
|
+
{ label: 'Receipt #', def: 'receipt_number', isSelected: true, isEditable: false },
|
|
33
|
+
{ label: 'Product', def: 'product', isSelected: true, isEditable: false },
|
|
34
|
+
{ label: 'Product Categories', def: 'product_categories', isSelected: false, isEditable: true, isExportable: false },
|
|
35
|
+
{ label: 'Categories', def: 'categories', isSelected: false, isEditable: false, isExportable: true },
|
|
36
|
+
{ label: 'SKU', def: 'sku', isSelected: true, isEditable: false },
|
|
37
|
+
{ label: 'Date', def: 'date', isSelected: true, isEditable: false },
|
|
38
|
+
{ label: 'Quantity', def: 'quantity', isSelected: true, isEditable: false },
|
|
39
|
+
{ label: 'Measure', def: 'measure', isSelected: true, isEditable: true },
|
|
40
|
+
{ label: 'Location', def: 'location', isSelected: true, isEditable: false },
|
|
41
|
+
{ label: 'Purchase Price', def: 'purchase_price', isSelected: true, isEditable: false },
|
|
42
|
+
{ label: 'Total Value', def: 'amount', isSelected: true, isEditable: false },
|
|
43
|
+
{ label: 'Supplier', def: 'supplier', isSelected: true, isEditable: false },
|
|
44
|
+
{ label: 'Supplier Contact', def: 'supplier_contact', isSelected: false, isEditable: true },
|
|
45
|
+
{ label: 'Supplier Phone', def: 'supplier_phone', isSelected: false, isEditable: true },
|
|
46
|
+
{ label: 'Particulars', def: 'particulars', isSelected: true, isEditable: false },
|
|
47
|
+
{ label: 'Creator', def: 'creator', isSelected: false, isEditable: true },
|
|
48
|
+
{ label: 'Actions', def: 'actions', isSelected: true, isEditable: false, isExportable: false },
|
|
49
|
+
];
|
|
50
|
+
get displayedColumns() {
|
|
51
|
+
const cols = this.selectedColumns().length > 0 ? this.selectedColumns() : this._defaultSelectedColumns;
|
|
52
|
+
const selectedDefs = new Set(cols.map(col => col.def));
|
|
53
|
+
return this.columnConfig.filter(col => {
|
|
54
|
+
if (this.exportInProgress()) {
|
|
55
|
+
if (col.isExportable === true)
|
|
56
|
+
return true;
|
|
57
|
+
if (col.isExportable === false)
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return selectedDefs.has(col.def);
|
|
61
|
+
}).map(col => col.def);
|
|
62
|
+
}
|
|
63
|
+
get totalPurchasePrice() {
|
|
64
|
+
return this.models.reduce((sum, model) => {
|
|
65
|
+
const products = model?.stock_receipt_products ?? [];
|
|
66
|
+
return sum + products.reduce((productSum, product) => productSum + Number(product?.purchase_price ?? 0), 0);
|
|
67
|
+
}, 0);
|
|
68
|
+
}
|
|
69
|
+
get totalValue() {
|
|
70
|
+
return this.models.reduce((sum, model) => {
|
|
71
|
+
const products = model?.stock_receipt_products ?? [];
|
|
72
|
+
return sum + products.reduce((productSum, product) => productSum + Number(product?.amount ?? 0), 0);
|
|
73
|
+
}, 0);
|
|
74
|
+
}
|
|
75
|
+
get footerColumns() {
|
|
76
|
+
return this.displayedColumns.map(col => `footer-${col}`);
|
|
77
|
+
}
|
|
78
|
+
constructor(service, formBuilder, router, featureService) {
|
|
79
|
+
super();
|
|
80
|
+
this.service = service;
|
|
81
|
+
this.formBuilder = formBuilder;
|
|
82
|
+
this.router = router;
|
|
83
|
+
this.featureService = featureService;
|
|
84
|
+
this.lastPage = 0;
|
|
85
|
+
this.filterFormConfiguration = {
|
|
86
|
+
date_from: { date: true },
|
|
87
|
+
date_to: { date: true },
|
|
88
|
+
category_ids: { multiple: true },
|
|
89
|
+
supplier_ids: { multiple: true },
|
|
90
|
+
location_ids: { multiple: true },
|
|
91
|
+
measure_ids: { multiple: true },
|
|
92
|
+
product_ids: { multiple: true },
|
|
93
|
+
};
|
|
94
|
+
this.filterForm = this.formBuilder.group({
|
|
95
|
+
category_ids: [''],
|
|
96
|
+
date_from: [''],
|
|
97
|
+
date_to: [''],
|
|
98
|
+
duration: [''],
|
|
99
|
+
import_id: [''],
|
|
100
|
+
location_ids: [''],
|
|
101
|
+
measure_ids: [''],
|
|
102
|
+
product_ids: [''],
|
|
103
|
+
search: [''],
|
|
104
|
+
sort_by: ['date|desc'],
|
|
105
|
+
supplier_ids: [''],
|
|
106
|
+
page: this.page,
|
|
107
|
+
perPage: this.perPage,
|
|
108
|
+
with: ["creator,supplier,batch,stockReceiptProducts.product,stockReceiptProducts.product.categories,stockReceiptProducts.location,stockReceiptProducts.stockTransfer"],
|
|
109
|
+
});
|
|
110
|
+
let initialized = false;
|
|
111
|
+
effect(() => {
|
|
112
|
+
const filters = this.filters();
|
|
113
|
+
if (!initialized) {
|
|
114
|
+
initialized = true;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this.filterForm.patchValue(filters, { emitEvent: true });
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
ngOnInit() {
|
|
121
|
+
this.loadFeatures();
|
|
122
|
+
this._defaultSelectedColumns = this.columnConfig.filter(col => col.isSelected);
|
|
123
|
+
this.columnConfigReady.emit(this.columnConfig);
|
|
124
|
+
this.patchFiltersFromRoute();
|
|
125
|
+
this.listenFilterChanges();
|
|
126
|
+
this.loadData();
|
|
127
|
+
}
|
|
128
|
+
loadFeatures() {
|
|
129
|
+
if (this.featureService.isFeatureExists('product-batch-numbers')) {
|
|
130
|
+
const qtyIndex = this.columnConfig.findIndex(c => c.def === 'quantity');
|
|
131
|
+
if (qtyIndex >= 0) {
|
|
132
|
+
this.columnConfig.splice(qtyIndex + 1, 0, { label: 'Batch', def: 'batch', isSelected: true, isEditable: false });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
redirectToView(model) {
|
|
137
|
+
this.router.navigate(['/inventory/stock-receipts', model?.id, 'view']);
|
|
138
|
+
}
|
|
139
|
+
getStockReceiptDeleteTitle(model) {
|
|
140
|
+
return `#${model?.id}`;
|
|
141
|
+
}
|
|
142
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StockReceiptListComponent, deps: [{ token: i1.StockReceiptService }, { token: i2.FormBuilder }, { token: i3.Router }, { token: i4.TechlifyFeatureService }], target: i0.ɵɵFactoryTarget.Component });
|
|
143
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: StockReceiptListComponent, selector: "app-stock-receipt-list", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, selectedColumns: { classPropertyName: "selectedColumns", publicName: "selectedColumns", isSignal: true, isRequired: false, transformFunction: null }, exportInProgress: { classPropertyName: "exportInProgress", publicName: "exportInProgress", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { listUpdated: "listUpdated", columnConfigReady: "columnConfigReady" }, usesInheritance: true, ngImport: i0, template: "<mat-card>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Receipts\" infiniteScroll\n id=\"stockReceiptTable\" [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"sortColumn($event)\">\n\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"receipt_number\">\n <th mat-header-cell *matHeaderCellDef matTooltip=\"Stock Receipt ID\">Receipt #</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/stock-receipts', element?.id, 'view']\">\n {{ element?.id }}\n </a>\n </td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <ul class=\"mb-0 ps-3\">\n <li *ngFor=\"let srp of element?.stock_receipt_products\">\n {{ srp?.quantity }} {{ srp?.product?.measure?.title }} <em>of</em>\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', srp?.product?.id, 'view']\">\n {{ srp?.product?.name }}\n </a>\n </li>\n </ul>\n </td>\n </ng-container>\n\n <!-- Product Categories Column -->\n <ng-container matColumnDef=\"product_categories\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <app-product-category-badges\n [product]=\"element?.stock_receipt_products[0]?.product\"></app-product-category-badges>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt_products[0]?.product?.sku }}</td>\n </ng-container>\n\n <!-- Categories Column (export only) -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <span *ngFor=\"let category of element?.stock_receipt_products[0]?.product?.categories; let last = last\">\n {{ category?.title }}<ng-container *ngIf=\"!last\">, </ng-container>\n </span>\n </td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt_products[0]?.quantity }} {{\n element?.stock_receipt_products[0]?.product?.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.batch?.batch_number\">{{ element?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.batch?.expires_on\">\n Expires {{ element?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Measure Column -->\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt_products[0]?.product?.measure?.title }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_receipt_products[0]?.location_id, 'view']\">\n {{ element?.stock_receipt_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_receipt_products[0]?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_receipt_products[0]?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.details }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.supplier?.company_name }}</td>\n </ng-container>\n\n <!-- Supplier Contact Column -->\n <ng-container matColumnDef=\"supplier_contact\">\n <th mat-header-cell *matHeaderCellDef>Supplier Contact</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.supplier?.contact_name }}</td>\n </ng-container>\n\n <!-- Supplier Phone Column -->\n <ng-container matColumnDef=\"supplier_phone\">\n <th mat-header-cell *matHeaderCellDef>Supplier Phone</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.supplier?.phone }}</td>\n </ng-container>\n\n <!-- Creator Column -->\n <ng-container matColumnDef=\"creator\">\n <th mat-header-cell *matHeaderCellDef>Creator</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1 text-secondary\">\n <app-techlify-icon role='button' name='view' class='text-secondary'\n [routerLink]=\"['/inventory', 'stock-receipts', element?.id, 'view']\"></app-techlify-icon>\n <app-stock-receipt-form-button [product]=\"element.product\" [stockReceipt]=\"element\"\n (saved)=\"reload(); listUpdated.emit(true)\"></app-stock-receipt-form-button>\n <app-techlify-delete-button [service]=\"service\" [model]=\"element\"\n [data]=\"{ title: getStockReceiptDeleteTitle(element), type: 'Stock Receipt' }\"\n (deleted)=\"reload(); listUpdated.emit(true)\"></app-techlify-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <!-- Footer Cells for Total Row -->\n <ng-container matColumnDef=\"footer-no\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-receipt_number\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product\">\n <td mat-footer-cell *matFooterCellDef colspan=\"1\"><strong>Total</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product_categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-sku\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-date\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-quantity\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-batch\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-measure\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-location\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-purchase_price\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalPurchasePrice | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-amount\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalValue | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-particulars\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_contact\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_phone\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-creator\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-actions\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n <tr mat-footer-row *matFooterRowDef=\"footerColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [":host ::ng-deep .mat-mdc-footer-row{position:sticky;bottom:0;background-color:#fff;z-index:10;box-shadow:0 -2px 4px #0000001a}\n"], dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i6.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i7.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i8.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i9.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i9.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i9.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i11.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i12.StockReceiptFormButtonComponent, selector: "app-stock-receipt-form-button", inputs: ["product", "stockReceipt", "latestLocationId", "icon"], outputs: ["saved"] }, { kind: "component", type: i13.ProductCategoryBadgesComponent, selector: "app-product-category-badges", inputs: ["product"] }, { kind: "component", type: i4.TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }, { kind: "component", type: i4.TechlifyDeleteButtonComponent, selector: "app-techlify-delete-button", inputs: ["data", "model", "message", "service"], outputs: ["deleted"] }, { kind: "pipe", type: i5.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i5.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
144
|
+
};
|
|
145
|
+
StockReceiptListComponent = __decorate([
|
|
146
|
+
UntilDestroy()
|
|
147
|
+
], StockReceiptListComponent);
|
|
148
|
+
export { StockReceiptListComponent };
|
|
149
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StockReceiptListComponent, decorators: [{
|
|
150
|
+
type: Component,
|
|
151
|
+
args: [{ selector: 'app-stock-receipt-list', template: "<mat-card>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Receipts\" infiniteScroll\n id=\"stockReceiptTable\" [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"sortColumn($event)\">\n\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"receipt_number\">\n <th mat-header-cell *matHeaderCellDef matTooltip=\"Stock Receipt ID\">Receipt #</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/stock-receipts', element?.id, 'view']\">\n {{ element?.id }}\n </a>\n </td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <ul class=\"mb-0 ps-3\">\n <li *ngFor=\"let srp of element?.stock_receipt_products\">\n {{ srp?.quantity }} {{ srp?.product?.measure?.title }} <em>of</em>\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', srp?.product?.id, 'view']\">\n {{ srp?.product?.name }}\n </a>\n </li>\n </ul>\n </td>\n </ng-container>\n\n <!-- Product Categories Column -->\n <ng-container matColumnDef=\"product_categories\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <app-product-category-badges\n [product]=\"element?.stock_receipt_products[0]?.product\"></app-product-category-badges>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt_products[0]?.product?.sku }}</td>\n </ng-container>\n\n <!-- Categories Column (export only) -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <span *ngFor=\"let category of element?.stock_receipt_products[0]?.product?.categories; let last = last\">\n {{ category?.title }}<ng-container *ngIf=\"!last\">, </ng-container>\n </span>\n </td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt_products[0]?.quantity }} {{\n element?.stock_receipt_products[0]?.product?.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.batch?.batch_number\">{{ element?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.batch?.expires_on\">\n Expires {{ element?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Measure Column -->\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt_products[0]?.product?.measure?.title }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_receipt_products[0]?.location_id, 'view']\">\n {{ element?.stock_receipt_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_receipt_products[0]?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_receipt_products[0]?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.details }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.supplier?.company_name }}</td>\n </ng-container>\n\n <!-- Supplier Contact Column -->\n <ng-container matColumnDef=\"supplier_contact\">\n <th mat-header-cell *matHeaderCellDef>Supplier Contact</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.supplier?.contact_name }}</td>\n </ng-container>\n\n <!-- Supplier Phone Column -->\n <ng-container matColumnDef=\"supplier_phone\">\n <th mat-header-cell *matHeaderCellDef>Supplier Phone</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.supplier?.phone }}</td>\n </ng-container>\n\n <!-- Creator Column -->\n <ng-container matColumnDef=\"creator\">\n <th mat-header-cell *matHeaderCellDef>Creator</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1 text-secondary\">\n <app-techlify-icon role='button' name='view' class='text-secondary'\n [routerLink]=\"['/inventory', 'stock-receipts', element?.id, 'view']\"></app-techlify-icon>\n <app-stock-receipt-form-button [product]=\"element.product\" [stockReceipt]=\"element\"\n (saved)=\"reload(); listUpdated.emit(true)\"></app-stock-receipt-form-button>\n <app-techlify-delete-button [service]=\"service\" [model]=\"element\"\n [data]=\"{ title: getStockReceiptDeleteTitle(element), type: 'Stock Receipt' }\"\n (deleted)=\"reload(); listUpdated.emit(true)\"></app-techlify-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <!-- Footer Cells for Total Row -->\n <ng-container matColumnDef=\"footer-no\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-receipt_number\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product\">\n <td mat-footer-cell *matFooterCellDef colspan=\"1\"><strong>Total</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product_categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-sku\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-date\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-quantity\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-batch\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-measure\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-location\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-purchase_price\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalPurchasePrice | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-amount\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalValue | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-particulars\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_contact\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_phone\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-creator\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-actions\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n <tr mat-footer-row *matFooterRowDef=\"footerColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [":host ::ng-deep .mat-mdc-footer-row{position:sticky;bottom:0;background-color:#fff;z-index:10;box-shadow:0 -2px 4px #0000001a}\n"] }]
|
|
152
|
+
}], ctorParameters: () => [{ type: i1.StockReceiptService }, { type: i2.FormBuilder }, { type: i3.Router }, { type: i4.TechlifyFeatureService }] });
|
|
153
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvY2stcmVjZWlwdC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3N0b2NrLXJlY2VpcHRzL3N0b2NrLXJlY2VpcHQtbGlzdC9zdG9jay1yZWNlaXB0LWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52ZW50b3J5LWNvbW1vbi9zcmMvbGliL2ludmVudG9yeS1jb21tb24vc3RvY2stcmVjZWlwdHMvc3RvY2stcmVjZWlwdC1saXN0L3N0b2NrLXJlY2VpcHQtbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RSxPQUFPLEVBRUwsa0NBQWtDLEVBQ25DLE1BQU0sbUJBQW1CLENBQUM7QUFHM0IsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7QUFTOUMsSUFBTSx5QkFBeUIsR0FBL0IsTUFBTSx5QkFBMEIsU0FBUSxrQ0FBa0M7SUErRDFEO0lBQ1g7SUFDQTtJQUNBO0lBakVWLE9BQU8sR0FBRyxLQUFLLENBQU0sRUFBRSxDQUFDLENBQUM7SUFDekIsZUFBZSxHQUFHLEtBQUssQ0FBaUIsRUFBRSxDQUFDLENBQUM7SUFDNUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLFdBQVcsR0FBRyxNQUFNLEVBQU8sQ0FBQztJQUM1QixpQkFBaUIsR0FBRyxNQUFNLEVBQWtCLENBQUM7SUFFckMsdUJBQXVCLEdBQW1CLEVBQUUsQ0FBQztJQUVyRCxZQUFZLEdBQW1CO1FBQzdCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxH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O0lBTnJDLFlBQVksRUFBRTtHQU1GLHlCQUF5QixDQXNJckM7OzRGQXRJWSx5QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0Usd0JBQXdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIGVmZmVjdCwgaW5wdXQsIG91dHB1dCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQge1xuICBDb2x1bW5Db25maWcsIFRlY2hsaWZ5RmVhdHVyZVNlcnZpY2UsXG4gIFRlY2hsaWZ5TGlzdGluZ0NvbnRyb2xsZXJJbnRlcmZhY2Vcbn0gZnJvbSAnbmd4LXRlY2hsaWZ5LWNvcmUnO1xuaW1wb3J0IHsgU3RvY2tSZWNlaXB0U2VydmljZSB9IGZyb20gXCIuLi9zdG9jay1yZWNlaXB0LnNlcnZpY2VcIjtcbmltcG9ydCB7IEZvcm1CdWlsZGVyIH0gZnJvbSBcIkBhbmd1bGFyL2Zvcm1zXCI7XG5pbXBvcnQgeyBVbnRpbERlc3Ryb3kgfSBmcm9tIFwiQG5nbmVhdC91bnRpbC1kZXN0cm95XCI7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5AVW50aWxEZXN0cm95KClcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1zdG9jay1yZWNlaXB0LWxpc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vc3RvY2stcmVjZWlwdC1saXN0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc3RvY2stcmVjZWlwdC1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFN0b2NrUmVjZWlwdExpc3RDb21wb25lbnQgZXh0ZW5kcyBUZWNobGlmeUxpc3RpbmdDb250cm9sbGVySW50ZXJmYWNlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgZmlsdGVycyA9IGlucHV0PGFueT4oe30pO1xuICBzZWxlY3RlZENvbHVtbnMgPSBpbnB1dDxDb2x1bW5Db25maWdbXT4oW10pO1xuICBleHBvcnRJblByb2dyZXNzID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuICBsaXN0VXBkYXRlZCA9IG91dHB1dDxhbnk+KCk7XG4gIGNvbHVtbkNvbmZpZ1JlYWR5ID0gb3V0cHV0PENvbHVtbkNvbmZpZ1tdPigpO1xuXG4gIHByaXZhdGUgX2RlZmF1bHRTZWxlY3RlZENvbHVtbnM6IENvbHVtbkNvbmZpZ1tdID0gW107XG5cbiAgY29sdW1uQ29uZmlnOiBDb2x1bW5Db25maWdbXSA9IFtcbiAgICB7IGxhYmVsOiAnIycsIGRlZjogJ25vJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnUmVjZWlwdCAjJywgZGVmOiAncmVjZWlwdF9udW1iZXInLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdQcm9kdWN0JywgZGVmOiAncHJvZHVjdCcsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1Byb2R1Y3QgQ2F0ZWdvcmllcycsIGRlZjogJ3Byb2R1Y3RfY2F0ZWdvcmllcycsIGlzU2VsZWN0ZWQ6IGZhbHNlLCBpc0VkaXRhYmxlOiB0cnVlLCBpc0V4cG9ydGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ0NhdGVnb3JpZXMnLCBkZWY6ICdjYXRlZ29yaWVzJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IGZhbHNlLCBpc0V4cG9ydGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnU0tVJywgZGVmOiAnc2t1JywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnRGF0ZScsIGRlZjogJ2RhdGUnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdRdWFudGl0eScsIGRlZjogJ3F1YW50aXR5JywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnTWVhc3VyZScsIGRlZjogJ21lYXN1cmUnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiB0cnVlIH0sXG4gICAgeyBsYWJlbDogJ0xvY2F0aW9uJywgZGVmOiAnbG9jYXRpb24nLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdQdXJjaGFzZSBQcmljZScsIGRlZjogJ3B1cmNoYXNlX3ByaWNlJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnVG90YWwgVmFsdWUnLCBkZWY6ICdhbW91bnQnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdTdXBwbGllcicsIGRlZjogJ3N1cHBsaWVyJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnU3VwcGxpZXIgQ29udGFjdCcsIGRlZjogJ3N1cHBsaWVyX2NvbnRhY3QnLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdTdXBwbGllciBQaG9uZScsIGRlZjogJ3N1cHBsaWVyX3Bob25lJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnUGFydGljdWxhcnMnLCBkZWY6ICdwYXJ0aWN1bGFycycsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ0NyZWF0b3InLCBkZWY6ICdjcmVhdG9yJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnQWN0aW9ucycsIGRlZjogJ2FjdGlvbnMnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSwgaXNFeHBvcnRhYmxlOiBmYWxzZSB9LFxuICBdO1xuXG4gIGdldCBkaXNwbGF5ZWRDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjb2xzID0gdGhpcy5zZWxlY3RlZENvbHVtbnMoKS5sZW5ndGggPiAwID8gdGhpcy5zZWxlY3RlZENvbHVtbnMoKSA6IHRoaXMuX2RlZmF1bHRTZWxlY3RlZENvbHVtbnM7XG4gICAgY29uc3Qgc2VsZWN0ZWREZWZzID0gbmV3IFNldChjb2xzLm1hcChjb2wgPT4gY29sLmRlZikpO1xuICAgIHJldHVybiB0aGlzLmNvbHVtbkNvbmZpZy5maWx0ZXIoY29sID0+IHtcbiAgICAgIGlmICh0aGlzLmV4cG9ydEluUHJvZ3Jlc3MoKSkge1xuICAgICAgICBpZiAoY29sLmlzRXhwb3J0YWJsZSA9PT0gdHJ1ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIGlmIChjb2wuaXNFeHBvcnRhYmxlID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNlbGVjdGVkRGVmcy5oYXMoY29sLmRlZik7XG4gICAgfSkubWFwKGNvbCA9PiBjb2wuZGVmKTtcbiAgfVxuXG4gIGdldCB0b3RhbFB1cmNoYXNlUHJpY2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbHMucmVkdWNlKChzdW0sIG1vZGVsKSA9PiB7XG4gICAgICBjb25zdCBwcm9kdWN0cyA9IG1vZGVsPy5zdG9ja19yZWNlaXB0X3Byb2R1Y3RzID8/IFtdO1xuICAgICAgcmV0dXJuIHN1bSArIHByb2R1Y3RzLnJlZHVjZSgocHJvZHVjdFN1bTogbnVtYmVyLCBwcm9kdWN0OiBhbnkpID0+XG4gICAgICAgIHByb2R1Y3RTdW0gKyBOdW1iZXIocHJvZHVjdD8ucHVyY2hhc2VfcHJpY2UgPz8gMCksIDApO1xuICAgIH0sIDApO1xuICB9XG5cbiAgZ2V0IHRvdGFsVmFsdWUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlbHMucmVkdWNlKChzdW0sIG1vZGVsKSA9PiB7XG4gICAgICBjb25zdCBwcm9kdWN0cyA9IG1vZGVsPy5zdG9ja19yZWNlaXB0X3Byb2R1Y3RzID8/IFtdO1xuICAgICAgcmV0dXJuIHN1bSArIHByb2R1Y3RzLnJlZHVjZSgocHJvZHVjdFN1bTogbnVtYmVyLCBwcm9kdWN0OiBhbnkpID0+XG4gICAgICAgIHByb2R1Y3RTdW0gKyBOdW1iZXIocHJvZHVjdD8uYW1vdW50ID8/IDApLCAwKTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIGdldCBmb290ZXJDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5ZWRDb2x1bW5zLm1hcChjb2wgPT4gYGZvb3Rlci0ke2NvbH1gKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBvdmVycmlkZSBzZXJ2aWNlOiBTdG9ja1JlY2VpcHRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSBmZWF0dXJlU2VydmljZTogVGVjaGxpZnlGZWF0dXJlU2VydmljZVxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubGFzdFBhZ2UgPSAwO1xuXG4gICAgdGhpcy5maWx0ZXJGb3JtQ29uZmlndXJhdGlvbiA9IHtcbiAgICAgIGRhdGVfZnJvbTogeyBkYXRlOiB0cnVlIH0sXG4gICAgICBkYXRlX3RvOiB7IGRhdGU6IHRydWUgfSxcbiAgICAgIGNhdGVnb3J5X2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgICAgc3VwcGxpZXJfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBsb2NhdGlvbl9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIG1lYXN1cmVfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBwcm9kdWN0X2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgIH07XG5cbiAgICB0aGlzLmZpbHRlckZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgIGNhdGVnb3J5X2lkczogWycnXSxcbiAgICAgIGRhdGVfZnJvbTogWycnXSxcbiAgICAgIGRhdGVfdG86IFsnJ10sXG4gICAgICBkdXJhdGlvbjogWycnXSxcbiAgICAgIGltcG9ydF9pZDogWycnXSxcbiAgICAgIGxvY2F0aW9uX2lkczogWycnXSxcbiAgICAgIG1lYXN1cmVfaWRzOiBbJyddLFxuICAgICAgcHJvZHVjdF9pZHM6IFsnJ10sXG4gICAgICBzZWFyY2g6IFsnJ10sXG4gICAgICBzb3J0X2J5OiBbJ2RhdGV8ZGVzYyddLFxuICAgICAgc3VwcGxpZXJfaWRzOiBbJyddLFxuICAgICAgcGFnZTogdGhpcy5wYWdlLFxuICAgICAgcGVyUGFnZTogdGhpcy5wZXJQYWdlLFxuICAgICAgd2l0aDogW1wiY3JlYXRvcixzdXBwbGllcixiYXRjaCxzdG9ja1JlY2VpcHRQcm9kdWN0cy5wcm9kdWN0LHN0b2NrUmVjZWlwdFByb2R1Y3RzLnByb2R1Y3QuY2F0ZWdvcmllcyxzdG9ja1JlY2VpcHRQcm9kdWN0cy5sb2NhdGlvbixzdG9ja1JlY2VpcHRQcm9kdWN0cy5zdG9ja1RyYW5zZmVyXCJdLFxuICAgIH0pO1xuXG4gICAgbGV0IGluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLmZpbHRlcnMoKTtcbiAgICAgIGlmICghaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmZpbHRlckZvcm0ucGF0Y2hWYWx1ZShmaWx0ZXJzLCB7IGVtaXRFdmVudDogdHJ1ZSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubG9hZEZlYXR1cmVzKCk7XG4gICAgdGhpcy5fZGVmYXVsdFNlbGVjdGVkQ29sdW1ucyA9IHRoaXMuY29sdW1uQ29uZmlnLmZpbHRlcihjb2wgPT4gY29sLmlzU2VsZWN0ZWQpO1xuICAgIHRoaXMuY29sdW1uQ29uZmlnUmVhZHkuZW1pdCh0aGlzLmNvbHVtbkNvbmZpZyk7XG4gICAgdGhpcy5wYXRjaEZpbHRlcnNGcm9tUm91dGUoKTtcbiAgICB0aGlzLmxpc3RlbkZpbHRlckNoYW5nZXMoKTtcbiAgICB0aGlzLmxvYWREYXRhKCk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGZWF0dXJlcygpIHtcbiAgICBpZiAodGhpcy5mZWF0dXJlU2VydmljZS5pc0ZlYXR1cmVFeGlzdHMoJ3Byb2R1Y3QtYmF0Y2gtbnVtYmVycycpKSB7XG4gICAgICBjb25zdCBxdHlJbmRleCA9IHRoaXMuY29sdW1uQ29uZmlnLmZpbmRJbmRleChjID0+IGMuZGVmID09PSAncXVhbnRpdHknKTtcbiAgICAgIGlmIChxdHlJbmRleCA+PSAwKSB7XG4gICAgICAgIHRoaXMuY29sdW1uQ29uZmlnLnNwbGljZShxdHlJbmRleCArIDEsIDAsIHsgbGFiZWw6ICdCYXRjaCcsIGRlZjogJ2JhdGNoJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVkaXJlY3RUb1ZpZXcobW9kZWw6IGFueSkge1xuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2ludmVudG9yeS9zdG9jay1yZWNlaXB0cycsIG1vZGVsPy5pZCwgJ3ZpZXcnXSk7XG4gIH1cblxuICBnZXRTdG9ja1JlY2VpcHREZWxldGVUaXRsZShtb2RlbDogYW55KTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCMke21vZGVsPy5pZH1gO1xuICB9XG59XG4iLCI8bWF0LWNhcmQ+XG4gIDxtYXQtY2FyZC1jb250ZW50IGNsYXNzPVwicC0wXCI+XG4gICAgPHRhYmxlIG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJtb2RlbHNcIiBjbGFzcz1cInctMTAwXCIgYXJpYS1kZXNjcmliZWRieT1cIlN0b2NrIFJlY2VpcHRzXCIgaW5maW5pdGVTY3JvbGxcbiAgICAgIGlkPVwic3RvY2tSZWNlaXB0VGFibGVcIiBbaW5maW5pdGVTY3JvbGxEaXN0YW5jZV09XCIyXCIgW2luZmluaXRlU2Nyb2xsVGhyb3R0bGVdPVwiNTBcIiAoc2Nyb2xsZWQpPVwib25TY3JvbGwoKVwiIG1hdFNvcnRcbiAgICAgIChtYXRTb3J0Q2hhbmdlKT1cInNvcnRDb2x1bW4oJGV2ZW50KVwiPlxuXG4gICAgICA8IS0tICMgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJub1wiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPiM8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudDsgbGV0IGkgPSBpbmRleFwiPnt7IGkgKyAxIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInJlY2VpcHRfbnVtYmVyXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0VG9vbHRpcD1cIlN0b2NrIFJlY2VpcHQgSURcIj5SZWNlaXB0ICM8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIDxhIGNsYXNzPVwidGV4dC1kZWNvcmF0aW9uLW5vbmUgdGV4dC1kYXJrXCJcbiAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeS9zdG9jay1yZWNlaXB0cycsIGVsZW1lbnQ/LmlkLCAndmlldyddXCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5pZCB9fVxuICAgICAgICAgIDwvYT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFByb2R1Y3QgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJwcm9kdWN0XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlByb2R1Y3Q8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIDx1bCBjbGFzcz1cIm1iLTAgcHMtM1wiPlxuICAgICAgICAgICAgPGxpICpuZ0Zvcj1cImxldCBzcnAgb2YgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1wiPlxuICAgICAgICAgICAgICB7eyBzcnA/LnF1YW50aXR5IH19IHt7IHNycD8ucHJvZHVjdD8ubWVhc3VyZT8udGl0bGUgfX0gPGVtPm9mPC9lbT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWRhcmtcIlxuICAgICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeS9wcm9kdWN0cycsIHNycD8ucHJvZHVjdD8uaWQsICd2aWV3J11cIj5cbiAgICAgICAgICAgICAgICB7eyBzcnA/LnByb2R1Y3Q/Lm5hbWUgfX1cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICA8L3VsPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gUHJvZHVjdCBDYXRlZ29yaWVzIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicHJvZHVjdF9jYXRlZ29yaWVzXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlByb2R1Y3QgQ2F0ZWdvcmllczwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGFwcC1wcm9kdWN0LWNhdGVnb3J5LWJhZGdlc1xuICAgICAgICAgICAgW3Byb2R1Y3RdPVwiZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1swXT8ucHJvZHVjdFwiPjwvYXBwLXByb2R1Y3QtY2F0ZWdvcnktYmFkZ2VzPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gU0tVIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic2t1XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlNLVTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1swXT8ucHJvZHVjdD8uc2t1IH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIENhdGVnb3JpZXMgQ29sdW1uIChleHBvcnQgb25seSkgLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNhdGVnb3JpZXNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5DYXRlZ29yaWVzPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgY2F0ZWdvcnkgb2YgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1swXT8ucHJvZHVjdD8uY2F0ZWdvcmllczsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICB7eyBjYXRlZ29yeT8udGl0bGUgfX08bmctY29udGFpbmVyICpuZ0lmPVwiIWxhc3RcIj4sIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIERhdGUgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJkYXRlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPkRhdGU8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LmRhdGUgfCBkYXRlIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFF1YW50aXR5IENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicXVhbnRpdHlcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+UXVhbnRpdHk8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnN0b2NrX3JlY2VpcHRfcHJvZHVjdHNbMF0/LnF1YW50aXR5IH19IHt7XG4gICAgICAgICAgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1swXT8ucHJvZHVjdD8ubWVhc3VyZT8udGl0bGUgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQmF0Y2ggQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJiYXRjaFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkJhdGNoPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cImVsZW1lbnQ/LmJhdGNoPy5iYXRjaF9udW1iZXJcIj57eyBlbGVtZW50Py5iYXRjaD8uYmF0Y2hfbnVtYmVyIH19PC9wPlxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCIgKm5nSWY9XCJlbGVtZW50Py5iYXRjaD8uZXhwaXJlc19vblwiPlxuICAgICAgICAgICAgRXhwaXJlcyB7eyBlbGVtZW50Py5iYXRjaD8uZXhwaXJlc19vbiB8IGRhdGUgfX1cbiAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTWVhc3VyZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm1lYXN1cmVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+TWVhc3VyZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1swXT8ucHJvZHVjdD8ubWVhc3VyZT8udGl0bGUgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTG9jYXRpb24gQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJsb2NhdGlvblwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Mb2NhdGlvbjwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWRhcmtcIlxuICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiWycvaW52ZW50b3J5L2xvY2F0aW9ucycsIGVsZW1lbnQ/LnN0b2NrX3JlY2VpcHRfcHJvZHVjdHNbMF0/LmxvY2F0aW9uX2lkLCAndmlldyddXCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5zdG9ja19yZWNlaXB0X3Byb2R1Y3RzWzBdPy5sb2NhdGlvbj8udGl0bGUgfX1cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBQdXJjaGFzZSBQcmljZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInB1cmNoYXNlX3ByaWNlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlB1cmNoYXNlIFByaWNlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICB7eyBlbGVtZW50Py5zdG9ja19yZWNlaXB0X3Byb2R1Y3RzWzBdPy5wdXJjaGFzZV9wcmljZSB8IGN1cnJlbmN5IH19XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBUb3RhbCBWYWx1ZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImFtb3VudFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Ub3RhbCBWYWx1ZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAge3sgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9wcm9kdWN0c1swXT8uYW1vdW50IHwgY3VycmVuY3kgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFBhcnRpY3VsYXJzIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicGFydGljdWxhcnNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5QYXJ0aWN1bGFyczwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uZGV0YWlscyB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBTdXBwbGllciBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInN1cHBsaWVyXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlN1cHBsaWVyPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdXBwbGllcj8uY29tcGFueV9uYW1lIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFN1cHBsaWVyIENvbnRhY3QgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzdXBwbGllcl9jb250YWN0XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+U3VwcGxpZXIgQ29udGFjdDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uc3VwcGxpZXI/LmNvbnRhY3RfbmFtZSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBTdXBwbGllciBQaG9uZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInN1cHBsaWVyX3Bob25lXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+U3VwcGxpZXIgUGhvbmU8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnN1cHBsaWVyPy5waG9uZSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBDcmVhdG9yIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiY3JlYXRvclwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkNyZWF0b3I8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIDxwIGNsYXNzPVwibWItMVwiPnt7IGVsZW1lbnQ/LmNyZWF0b3I/Lm5hbWUgfX08L3A+XG4gICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIj57eyBlbGVtZW50Py5jcmVhdGVkX2F0IHwgZGF0ZSB9fTwvc21hbGw+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBBY3Rpb25zIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiYWN0aW9uc1wiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkFjdGlvbnM8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCIhZWxlbWVudC5zdG9ja190cmFuc2ZlclwiIGNsYXNzPVwiZC1mbGV4IGdhcC0xIHRleHQtc2Vjb25kYXJ5XCI+XG4gICAgICAgICAgICA8YXBwLXRlY2hsaWZ5LWljb24gcm9sZT0nYnV0dG9uJyBuYW1lPSd2aWV3JyBjbGFzcz0ndGV4dC1zZWNvbmRhcnknXG4gICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeScsICdzdG9jay1yZWNlaXB0cycsIGVsZW1lbnQ/LmlkLCAndmlldyddXCI+PC9hcHAtdGVjaGxpZnktaWNvbj5cbiAgICAgICAgICAgIDxhcHAtc3RvY2stcmVjZWlwdC1mb3JtLWJ1dHRvbiBbcHJvZHVjdF09XCJlbGVtZW50LnByb2R1Y3RcIiBbc3RvY2tSZWNlaXB0XT1cImVsZW1lbnRcIlxuICAgICAgICAgICAgICAoc2F2ZWQpPVwicmVsb2FkKCk7IGxpc3RVcGRhdGVkLmVtaXQodHJ1ZSlcIj48L2FwcC1zdG9jay1yZWNlaXB0LWZvcm0tYnV0dG9uPlxuICAgICAgICAgICAgPGFwcC10ZWNobGlmeS1kZWxldGUtYnV0dG9uIFtzZXJ2aWNlXT1cInNlcnZpY2VcIiBbbW9kZWxdPVwiZWxlbWVudFwiXG4gICAgICAgICAgICAgIFtkYXRhXT1cInsgdGl0bGU6IGdldFN0b2NrUmVjZWlwdERlbGV0ZVRpdGxlKGVsZW1lbnQpLCB0eXBlOiAnU3RvY2sgUmVjZWlwdCcgfVwiXG4gICAgICAgICAgICAgIChkZWxldGVkKT1cInJlbG9hZCgpOyBsaXN0VXBkYXRlZC5lbWl0KHRydWUpXCI+PC9hcHAtdGVjaGxpZnktZGVsZXRlLWJ1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZWxlbWVudC5zdG9ja190cmFuc2ZlclwiIGNsYXNzPVwiYmFkZ2Ugcm91bmRlZC1waWxsIHRleHQtYmctc2Vjb25kYXJ5XCI+U3RvY2sgVHJhbnNmZXI8L3NwYW4+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBGb290ZXIgQ2VsbHMgZm9yIFRvdGFsIFJvdyAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLW5vXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1yZWNlaXB0X251bWJlclwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItcHJvZHVjdFwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmIGNvbHNwYW49XCIxXCI+PHN0cm9uZz5Ub3RhbDwvc3Ryb25nPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItcHJvZHVjdF9jYXRlZ29yaWVzXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1za3VcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLWNhdGVnb3JpZXNcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLWRhdGVcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLXF1YW50aXR5XCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1iYXRjaFwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItbWVhc3VyZVwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItbG9jYXRpb25cIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLXB1cmNoYXNlX3ByaWNlXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PHN0cm9uZz57eyB0b3RhbFB1cmNoYXNlUHJpY2UgfCBjdXJyZW5jeSB9fTwvc3Ryb25nPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItYW1vdW50XCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PHN0cm9uZz57eyB0b3RhbFZhbHVlIHwgY3VycmVuY3kgfX08L3N0cm9uZz48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLXBhcnRpY3VsYXJzXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1zdXBwbGllclwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItc3VwcGxpZXJfY29udGFjdFwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItc3VwcGxpZXJfcGhvbmVcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLWNyZWF0b3JcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLWFjdGlvbnNcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICA8dHIgbWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICA8dHIgbWF0LWZvb3Rlci1yb3cgKm1hdEZvb3RlclJvd0RlZj1cImZvb3RlckNvbHVtbnNcIj48L3RyPlxuICAgIDwvdGFibGU+XG5cbiAgICA8bWF0LXByb2dyZXNzLWJhciAqbmdJZj1cImlzV29ya2luZ1wiIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICA8L21hdC1jYXJkLWNvbnRlbnQ+XG48L21hdC1jYXJkPiJdfQ==
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { Component, effect, input, output } from "@angular/core";
|
|
3
|
+
import { TechlifyListingControllerInterface } from 'ngx-techlify-core';
|
|
4
|
+
import { UntilDestroy } from "@ngneat/until-destroy";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "../stock-receipt-product.service";
|
|
7
|
+
import * as i2 from "@angular/forms";
|
|
8
|
+
import * as i3 from "ngx-techlify-core";
|
|
9
|
+
import * as i4 from "@angular/common";
|
|
10
|
+
import * as i5 from "@angular/material/card";
|
|
11
|
+
import * as i6 from "@angular/material/progress-bar";
|
|
12
|
+
import * as i7 from "@angular/material/sort";
|
|
13
|
+
import * as i8 from "@angular/material/table";
|
|
14
|
+
import * as i9 from "@angular/material/tooltip";
|
|
15
|
+
import * as i10 from "@angular/router";
|
|
16
|
+
import * as i11 from "ngx-infinite-scroll";
|
|
17
|
+
import * as i12 from "../../product/widgets/product-category-badges/product-category-badges.component";
|
|
18
|
+
import * as i13 from "../stock-receipt-product-form/stock-receipt-product-form-button/stock-receipt-product-form-button.component";
|
|
19
|
+
let StockReceiptProductsListComponent = class StockReceiptProductsListComponent extends TechlifyListingControllerInterface {
|
|
20
|
+
service;
|
|
21
|
+
formBuilder;
|
|
22
|
+
featureService;
|
|
23
|
+
filters = input({});
|
|
24
|
+
isProductView = input(false);
|
|
25
|
+
selectedColumns = input([]);
|
|
26
|
+
exportInProgress = input(false);
|
|
27
|
+
listUpdated = output();
|
|
28
|
+
columnConfigReady = output();
|
|
29
|
+
productViewHiddenColumns = ['product', 'sku', 'measure'];
|
|
30
|
+
_defaultSelectedColumns = [];
|
|
31
|
+
columnConfig = [
|
|
32
|
+
{ label: '#', def: 'no', isSelected: true, isEditable: false },
|
|
33
|
+
{ label: 'Receipt #', def: 'receipt_number', isSelected: true, isEditable: false },
|
|
34
|
+
{ label: 'Product', def: 'product', isSelected: true, isEditable: false },
|
|
35
|
+
{ label: 'Product Categories', def: 'product_categories', isSelected: false, isEditable: true, isExportable: false },
|
|
36
|
+
{ label: 'Categories', def: 'categories', isSelected: false, isEditable: false, isExportable: true },
|
|
37
|
+
{ label: 'SKU', def: 'sku', isSelected: true, isEditable: false },
|
|
38
|
+
{ label: 'Date', def: 'date', isSelected: true, isEditable: false },
|
|
39
|
+
{ label: 'Quantity', def: 'quantity', isSelected: true, isEditable: false },
|
|
40
|
+
{ label: 'Measure', def: 'measure', isSelected: true, isEditable: true },
|
|
41
|
+
{ label: 'Location', def: 'location', isSelected: true, isEditable: false },
|
|
42
|
+
{ label: 'Purchase Price', def: 'purchase_price', isSelected: true, isEditable: false },
|
|
43
|
+
{ label: 'Total Value', def: 'amount', isSelected: true, isEditable: false },
|
|
44
|
+
{ label: 'Supplier', def: 'supplier', isSelected: true, isEditable: false },
|
|
45
|
+
{ label: 'Supplier Contact', def: 'supplier_contact', isSelected: false, isEditable: true },
|
|
46
|
+
{ label: 'Supplier Phone', def: 'supplier_phone', isSelected: false, isEditable: true },
|
|
47
|
+
{ label: 'Particulars', def: 'particulars', isSelected: true, isEditable: false },
|
|
48
|
+
{ label: 'Creator', def: 'creator', isSelected: false, isEditable: true },
|
|
49
|
+
{ label: 'Actions', def: 'actions', isSelected: true, isEditable: false, isExportable: false },
|
|
50
|
+
];
|
|
51
|
+
get displayedColumns() {
|
|
52
|
+
const cols = this.selectedColumns().length > 0 ? this.selectedColumns() : this._defaultSelectedColumns;
|
|
53
|
+
const selectedDefs = new Set(cols.map(col => col.def));
|
|
54
|
+
return this.columnConfig.filter(col => {
|
|
55
|
+
if (this.isProductView() && this.productViewHiddenColumns.includes(col.def))
|
|
56
|
+
return false;
|
|
57
|
+
if (this.exportInProgress()) {
|
|
58
|
+
if (col.isExportable === true) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
if (col.isExportable === false) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return selectedDefs.has(col.def);
|
|
66
|
+
}).map(col => col.def);
|
|
67
|
+
}
|
|
68
|
+
get totalPurchasePrice() {
|
|
69
|
+
return this.models.reduce((sum, model) => sum + Number(model?.purchase_price ?? 0), 0);
|
|
70
|
+
}
|
|
71
|
+
get totalValue() {
|
|
72
|
+
return this.models.reduce((sum, model) => sum + Number(model?.amount ?? 0), 0);
|
|
73
|
+
}
|
|
74
|
+
get footerColumns() {
|
|
75
|
+
return this.displayedColumns.map(col => `footer-${col}`);
|
|
76
|
+
}
|
|
77
|
+
constructor(service, formBuilder, featureService) {
|
|
78
|
+
super();
|
|
79
|
+
this.service = service;
|
|
80
|
+
this.formBuilder = formBuilder;
|
|
81
|
+
this.featureService = featureService;
|
|
82
|
+
this.filterFormConfiguration = {
|
|
83
|
+
date_from: { date: true },
|
|
84
|
+
date_to: { date: true },
|
|
85
|
+
category_ids: { multiple: true },
|
|
86
|
+
supplier_ids: { multiple: true },
|
|
87
|
+
location_ids: { multiple: true },
|
|
88
|
+
measure_ids: { multiple: true },
|
|
89
|
+
product_ids: { multiple: true },
|
|
90
|
+
};
|
|
91
|
+
this.filterForm = this.formBuilder.group({
|
|
92
|
+
category_ids: [''],
|
|
93
|
+
date_from: [''],
|
|
94
|
+
date_to: [''],
|
|
95
|
+
duration: [''],
|
|
96
|
+
location_ids: [''],
|
|
97
|
+
measure_ids: [''],
|
|
98
|
+
product_ids: [''],
|
|
99
|
+
search: [''],
|
|
100
|
+
sort_by: ['date|desc'],
|
|
101
|
+
supplier_ids: [''],
|
|
102
|
+
page: this.page,
|
|
103
|
+
perPage: this.perPage,
|
|
104
|
+
});
|
|
105
|
+
let initialized = false;
|
|
106
|
+
effect(() => {
|
|
107
|
+
const filters = this.filters();
|
|
108
|
+
if (!initialized) {
|
|
109
|
+
initialized = true;
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.filterForm.patchValue(filters, { emitEvent: true });
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
ngOnInit() {
|
|
116
|
+
this.loadFeatures();
|
|
117
|
+
this._defaultSelectedColumns = this.columnConfig.filter(col => col.isSelected);
|
|
118
|
+
this.columnConfigReady.emit(this.columnConfig);
|
|
119
|
+
const initialFilters = this.filters();
|
|
120
|
+
if (initialFilters) {
|
|
121
|
+
this.filterForm.patchValue(initialFilters, { emitEvent: false });
|
|
122
|
+
}
|
|
123
|
+
this.patchFiltersFromRoute();
|
|
124
|
+
this.listenFilterChanges();
|
|
125
|
+
this.loadData();
|
|
126
|
+
}
|
|
127
|
+
loadFeatures() {
|
|
128
|
+
if (this.featureService.isFeatureExists('product-batch-numbers')) {
|
|
129
|
+
const qtyIndex = this.columnConfig.findIndex(c => c.def === 'quantity');
|
|
130
|
+
if (qtyIndex >= 0) {
|
|
131
|
+
this.columnConfig.splice(qtyIndex + 1, 0, { label: 'Batch', def: 'batch', isSelected: true, isEditable: false });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StockReceiptProductsListComponent, deps: [{ token: i1.StockReceiptProductService }, { token: i2.FormBuilder }, { token: i3.TechlifyFeatureService }], target: i0.ɵɵFactoryTarget.Component });
|
|
136
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: StockReceiptProductsListComponent, selector: "app-stock-receipt-product-list", inputs: { filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, isProductView: { classPropertyName: "isProductView", publicName: "isProductView", isSignal: true, isRequired: false, transformFunction: null }, selectedColumns: { classPropertyName: "selectedColumns", publicName: "selectedColumns", isSignal: true, isRequired: false, transformFunction: null }, exportInProgress: { classPropertyName: "exportInProgress", publicName: "exportInProgress", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { listUpdated: "listUpdated", columnConfigReady: "columnConfigReady" }, usesInheritance: true, ngImport: i0, template: "<mat-card>\n <mat-card-header *ngIf=\"isProductView()\" class=\"d-flex align-items-center gap-2\">\n <mat-card-title>Stock Receipts</mat-card-title>\n <app-techlify-icon role='button' name='add' [routerLink]=\"['/inventory/stock-receipts/batch-form']\"\n class='ms-2'></app-techlify-icon>\n </mat-card-header>\n\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Receipt Products\" infiniteScroll\n id=\"stockReceiptTable\" [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"sortColumn($event)\">\n\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"receipt_number\">\n <th mat-header-cell *matHeaderCellDef matTooltip=\"Stock Receipt ID\">Receipt #</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/stock-receipts', element?.stock_receipt_id, 'view']\">\n {{ element?.stock_receipt_id }}\n </a>\n </td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.product?.id, 'view']\">\n {{ element?.product?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Product Categories Column -->\n <ng-container matColumnDef=\"product_categories\">\n <th mat-header-cell *matHeaderCellDef>Product Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <app-product-category-badges [product]=\"element?.product\"></app-product-category-badges>\n </td>\n </ng-container>\n\n <!-- Categories Column (export only) -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <span *ngFor=\"let category of element?.product?.categories; let last = last\">\n {{ category?.title }}<ng-container *ngIf=\"!last\">, </ng-container>\n </span>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.product?.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.date | date }}</td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.quantity }} {{ element?.product?.measure?.title }}\n </td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.batch?.batch_number\">{{ element?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.batch?.expires_on\">\n Expires {{ element?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Measure Column -->\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.product?.measure?.title }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.location_id, 'view']\">\n {{ element?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.purchase_price | currency }}</td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.amount | currency }}</td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.supplier?.company_name }}</td>\n </ng-container>\n\n <!-- Supplier Contact Column -->\n <ng-container matColumnDef=\"supplier_contact\">\n <th mat-header-cell *matHeaderCellDef>Supplier Contact</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.supplier?.contact_name }}</td>\n </ng-container>\n\n <!-- Supplier Phone Column -->\n <ng-container matColumnDef=\"supplier_phone\">\n <th mat-header-cell *matHeaderCellDef>Supplier Phone</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.supplier?.phone }}</td>\n </ng-container>\n\n <!-- Creator Column -->\n <ng-container matColumnDef=\"creator\">\n <th mat-header-cell *matHeaderCellDef>Creator</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-1\">{{ element?.stock_receipt?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.stock_receipt?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex gap-1 text-secondary\">\n <app-techlify-icon role='button' name='view' class='text-secondary'\n [routerLink]=\"['/inventory', 'stock-receipts', element?.id, 'view']\"></app-techlify-icon>\n <app-stock-receipt-product-form-button [stockReceiptId]=\"element?.stock_receipt_id\"\n [stockReceiptProduct]=\"element\" (saved)=\"reload(); listUpdated.emit(true)\">\n </app-stock-receipt-product-form-button>\n <app-techlify-delete-button [model]=\"element\" [service]=\"service\"\n [data]=\"{ title: element?.product?.name, type: 'Stock Receipt Product' }\"\n (deleted)=\"reload(); listUpdated.emit(true)\">\n </app-techlify-delete-button>\n </div>\n </td>\n </ng-container>\n\n <!-- Footer Cells for Total Row -->\n <ng-container matColumnDef=\"footer-no\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-receipt_number\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product\">\n <td mat-footer-cell *matFooterCellDef><strong>Total</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product_categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-sku\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-date\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-quantity\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-batch\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-measure\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-location\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-purchase_price\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalPurchasePrice | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-amount\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalValue | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-particulars\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_contact\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_phone\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-creator\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-actions\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n <tr mat-footer-row *matFooterRowDef=\"footerColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [":host ::ng-deep .mat-mdc-footer-row{position:sticky;bottom:0;background-color:#fff;z-index:10;box-shadow:0 -2px 4px #0000001a}\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: "component", type: i5.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i5.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i5.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }, { kind: "component", type: i6.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i8.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i8.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i8.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i8.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i8.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i8.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i8.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i8.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i8.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i8.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i8.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i8.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i8.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i8.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i10.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i11.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i12.ProductCategoryBadgesComponent, selector: "app-product-category-badges", inputs: ["product"] }, { kind: "component", type: i3.TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }, { kind: "component", type: i3.TechlifyDeleteButtonComponent, selector: "app-techlify-delete-button", inputs: ["data", "model", "message", "service"], outputs: ["deleted"] }, { kind: "component", type: i13.StockReceiptProductFormButtonComponent, selector: "app-stock-receipt-product-form-button", inputs: ["stockReceiptProduct", "stockReceiptId"], outputs: ["saved"] }, { kind: "pipe", type: i4.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i4.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
137
|
+
};
|
|
138
|
+
StockReceiptProductsListComponent = __decorate([
|
|
139
|
+
UntilDestroy()
|
|
140
|
+
], StockReceiptProductsListComponent);
|
|
141
|
+
export { StockReceiptProductsListComponent };
|
|
142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: StockReceiptProductsListComponent, decorators: [{
|
|
143
|
+
type: Component,
|
|
144
|
+
args: [{ selector: 'app-stock-receipt-product-list', template: "<mat-card>\n <mat-card-header *ngIf=\"isProductView()\" class=\"d-flex align-items-center gap-2\">\n <mat-card-title>Stock Receipts</mat-card-title>\n <app-techlify-icon role='button' name='add' [routerLink]=\"['/inventory/stock-receipts/batch-form']\"\n class='ms-2'></app-techlify-icon>\n </mat-card-header>\n\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Receipt Products\" infiniteScroll\n id=\"stockReceiptTable\" [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"sortColumn($event)\">\n\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"receipt_number\">\n <th mat-header-cell *matHeaderCellDef matTooltip=\"Stock Receipt ID\">Receipt #</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/stock-receipts', element?.stock_receipt_id, 'view']\">\n {{ element?.stock_receipt_id }}\n </a>\n </td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.product?.id, 'view']\">\n {{ element?.product?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Product Categories Column -->\n <ng-container matColumnDef=\"product_categories\">\n <th mat-header-cell *matHeaderCellDef>Product Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <app-product-category-badges [product]=\"element?.product\"></app-product-category-badges>\n </td>\n </ng-container>\n\n <!-- Categories Column (export only) -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\">\n <span *ngFor=\"let category of element?.product?.categories; let last = last\">\n {{ category?.title }}<ng-container *ngIf=\"!last\">, </ng-container>\n </span>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.product?.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.date | date }}</td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.quantity }} {{ element?.product?.measure?.title }}\n </td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.batch?.batch_number\">{{ element?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.batch?.expires_on\">\n Expires {{ element?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Measure Column -->\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.product?.measure?.title }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.location_id, 'view']\">\n {{ element?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.purchase_price | currency }}</td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.amount | currency }}</td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.supplier?.company_name }}</td>\n </ng-container>\n\n <!-- Supplier Contact Column -->\n <ng-container matColumnDef=\"supplier_contact\">\n <th mat-header-cell *matHeaderCellDef>Supplier Contact</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.supplier?.contact_name }}</td>\n </ng-container>\n\n <!-- Supplier Phone Column -->\n <ng-container matColumnDef=\"supplier_phone\">\n <th mat-header-cell *matHeaderCellDef>Supplier Phone</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_receipt?.supplier?.phone }}</td>\n </ng-container>\n\n <!-- Creator Column -->\n <ng-container matColumnDef=\"creator\">\n <th mat-header-cell *matHeaderCellDef>Creator</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-1\">{{ element?.stock_receipt?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.stock_receipt?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex gap-1 text-secondary\">\n <app-techlify-icon role='button' name='view' class='text-secondary'\n [routerLink]=\"['/inventory', 'stock-receipts', element?.id, 'view']\"></app-techlify-icon>\n <app-stock-receipt-product-form-button [stockReceiptId]=\"element?.stock_receipt_id\"\n [stockReceiptProduct]=\"element\" (saved)=\"reload(); listUpdated.emit(true)\">\n </app-stock-receipt-product-form-button>\n <app-techlify-delete-button [model]=\"element\" [service]=\"service\"\n [data]=\"{ title: element?.product?.name, type: 'Stock Receipt Product' }\"\n (deleted)=\"reload(); listUpdated.emit(true)\">\n </app-techlify-delete-button>\n </div>\n </td>\n </ng-container>\n\n <!-- Footer Cells for Total Row -->\n <ng-container matColumnDef=\"footer-no\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-receipt_number\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product\">\n <td mat-footer-cell *matFooterCellDef><strong>Total</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-product_categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-sku\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-categories\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-date\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-quantity\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-batch\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-measure\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-location\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-purchase_price\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalPurchasePrice | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-amount\">\n <td mat-footer-cell *matFooterCellDef><strong>{{ totalValue | currency }}</strong></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-particulars\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_contact\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-supplier_phone\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-creator\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <ng-container matColumnDef=\"footer-actions\">\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n <tr mat-footer-row *matFooterRowDef=\"footerColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [":host ::ng-deep .mat-mdc-footer-row{position:sticky;bottom:0;background-color:#fff;z-index:10;box-shadow:0 -2px 4px #0000001a}\n"] }]
|
|
145
|
+
}], ctorParameters: () => [{ type: i1.StockReceiptProductService }, { type: i2.FormBuilder }, { type: i3.TechlifyFeatureService }] });
|
|
146
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvY2stcmVjZWlwdC1wcm9kdWN0LWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52ZW50b3J5LWNvbW1vbi9zcmMvbGliL2ludmVudG9yeS1jb21tb24vc3RvY2stcmVjZWlwdHMvc3RvY2stcmVjZWlwdC1wcm9kdWN0LWxpc3Qvc3RvY2stcmVjZWlwdC1wcm9kdWN0LWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52ZW50b3J5LWNvbW1vbi9zcmMvbGliL2ludmVudG9yeS1jb21tb24vc3RvY2stcmVjZWlwdHMvc3RvY2stcmVjZWlwdC1wcm9kdWN0LWxpc3Qvc3RvY2stcmVjZWlwdC1wcm9kdWN0LWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekUsT0FBTyxFQUVMLGtDQUFrQyxFQUNuQyxNQUFNLG1CQUFtQixDQUFDO0FBRzNCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7O0FBUTlDLElBQU0saUNBQWlDLEdBQXZDLE1BQU0saUNBQWtDLFNBQVEsa0NBQWtDO0lBOERsRTtJQUNYO0lBQ0E7SUEvRFYsT0FBTyxHQUFHLEtBQUssQ0FBTSxFQUFFLENBQUMsQ0FBQztJQUN6QixhQUFhLEdBQUcsS0FBSyxDQUFVLEtBQUssQ0FBQyxDQUFDO0lBQ3RDLGVBQWUsR0FBRyxLQUFLLENBQWlCLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLGdCQUFnQixHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUN6QyxXQUFXLEdBQUcsTUFBTSxFQUFPLENBQUM7SUFDNUIsaUJBQWlCLEdBQUcsTUFBTSxFQUFrQixDQUFDO0lB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QU8sRUFBRSxDQUFDO1FBQ3RDLElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUVELElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRU8sWUFBWTtRQUNsQixJQUFJLElBQUksQ0FBQyxjQUFjLENBQUMsZUFBZSxDQUFDLHVCQUF1QixDQUFDLEVBQUUsQ0FBQztZQUNqRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssVUFBVSxDQUFDLENBQUM7WUFDeEUsSUFBSSxRQUFRLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbkgsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO3dHQTlIVSxpQ0FBaUM7NEZBQWpDLGlDQUFpQyx1dkJDZjlDLHNrVkE0UFc7O0FEN09FLGlDQUFpQztJQU43QyxZQUFZLEVBQUU7R0FNRixpQ0FBaUMsQ0ErSDdDOzs0RkEvSFksaUNBQWlDO2tCQUw3QyxTQUFTOytCQUNFLGdDQUFnQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBlZmZlY3QsIGlucHV0LCBvdXRwdXQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcbiAgQ29sdW1uQ29uZmlnLCBUZWNobGlmeUZlYXR1cmVTZXJ2aWNlLFxuICBUZWNobGlmeUxpc3RpbmdDb250cm9sbGVySW50ZXJmYWNlXG59IGZyb20gJ25neC10ZWNobGlmeS1jb3JlJztcbmltcG9ydCB7IFN0b2NrUmVjZWlwdFByb2R1Y3RTZXJ2aWNlIH0gZnJvbSBcIi4uL3N0b2NrLXJlY2VpcHQtcHJvZHVjdC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBGb3JtQnVpbGRlciB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgVW50aWxEZXN0cm95IH0gZnJvbSBcIkBuZ25lYXQvdW50aWwtZGVzdHJveVwiO1xuXG5AVW50aWxEZXN0cm95KClcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1zdG9jay1yZWNlaXB0LXByb2R1Y3QtbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdG9jay1yZWNlaXB0LXByb2R1Y3QtbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3N0b2NrLXJlY2VpcHQtcHJvZHVjdC1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFN0b2NrUmVjZWlwdFByb2R1Y3RzTGlzdENvbXBvbmVudCBleHRlbmRzIFRlY2hsaWZ5TGlzdGluZ0NvbnRyb2xsZXJJbnRlcmZhY2UgaW1wbGVtZW50cyBPbkluaXQge1xuICBmaWx0ZXJzID0gaW5wdXQ8YW55Pih7fSk7XG4gIGlzUHJvZHVjdFZpZXcgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIHNlbGVjdGVkQ29sdW1ucyA9IGlucHV0PENvbHVtbkNvbmZpZ1tdPihbXSk7XG4gIGV4cG9ydEluUHJvZ3Jlc3MgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIGxpc3RVcGRhdGVkID0gb3V0cHV0PGFueT4oKTtcbiAgY29sdW1uQ29uZmlnUmVhZHkgPSBvdXRwdXQ8Q29sdW1uQ29uZmlnW10+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBwcm9kdWN0Vmlld0hpZGRlbkNvbHVtbnMgPSBbJ3Byb2R1Y3QnLCAnc2t1JywgJ21lYXN1cmUnXTtcbiAgcHJpdmF0ZSBfZGVmYXVsdFNlbGVjdGVkQ29sdW1uczogQ29sdW1uQ29uZmlnW10gPSBbXTtcblxuICBjb2x1bW5Db25maWc6IENvbHVtbkNvbmZpZ1tdID0gW1xuICAgIHsgbGFiZWw6ICcjJywgZGVmOiAnbm8nLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdSZWNlaXB0ICMnLCBkZWY6ICdyZWNlaXB0X251bWJlcicsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1Byb2R1Y3QnLCBkZWY6ICdwcm9kdWN0JywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnUHJvZHVjdCBDYXRlZ29yaWVzJywgZGVmOiAncHJvZHVjdF9jYXRlZ29yaWVzJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUsIGlzRXhwb3J0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnQ2F0ZWdvcmllcycsIGRlZjogJ2NhdGVnb3JpZXMnLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogZmFsc2UsIGlzRXhwb3J0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdTS1UnLCBkZWY6ICdza3UnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdEYXRlJywgZGVmOiAnZGF0ZScsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1F1YW50aXR5JywgZGVmOiAncXVhbnRpdHknLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdNZWFzdXJlJywgZGVmOiAnbWVhc3VyZScsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnTG9jYXRpb24nLCBkZWY6ICdsb2NhdGlvbicsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1B1cmNoYXNlIFByaWNlJywgZGVmOiAncHVyY2hhc2VfcHJpY2UnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdUb3RhbCBWYWx1ZScsIGRlZjogJ2Ftb3VudCcsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1N1cHBsaWVyJywgZGVmOiAnc3VwcGxpZXInLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdTdXBwbGllciBDb250YWN0JywgZGVmOiAnc3VwcGxpZXJfY29udGFjdCcsIGlzU2VsZWN0ZWQ6IGZhbHNlLCBpc0VkaXRhYmxlOiB0cnVlIH0sXG4gICAgeyBsYWJlbDogJ1N1cHBsaWVyIFBob25lJywgZGVmOiAnc3VwcGxpZXJfcGhvbmUnLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdQYXJ0aWN1bGFycycsIGRlZjogJ3BhcnRpY3VsYXJzJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnQ3JlYXRvcicsIGRlZjogJ2NyZWF0b3InLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdBY3Rpb25zJywgZGVmOiAnYWN0aW9ucycsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlLCBpc0V4cG9ydGFibGU6IGZhbHNlIH0sXG4gIF07XG5cbiAgZ2V0IGRpc3BsYXllZENvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGNvbHMgPSB0aGlzLnNlbGVjdGVkQ29sdW1ucygpLmxlbmd0aCA+IDAgPyB0aGlzLnNlbGVjdGVkQ29sdW1ucygpIDogdGhpcy5fZGVmYXVsdFNlbGVjdGVkQ29sdW1ucztcbiAgICBjb25zdCBzZWxlY3RlZERlZnMgPSBuZXcgU2V0KGNvbHMubWFwKGNvbCA9PiBjb2wuZGVmKSk7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1uQ29uZmlnLmZpbHRlcihjb2wgPT4ge1xuICAgICAgaWYgKHRoaXMuaXNQcm9kdWN0VmlldygpICYmIHRoaXMucHJvZHVjdFZpZXdIaWRkZW5Db2x1bW5zLmluY2x1ZGVzKGNvbC5kZWYpKSByZXR1cm4gZmFsc2U7XG4gICAgICBpZiAodGhpcy5leHBvcnRJblByb2dyZXNzKCkpIHtcbiAgICAgICAgaWYgKGNvbC5pc0V4cG9ydGFibGUgPT09IHRydWUpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29sLmlzRXhwb3J0YWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBzZWxlY3RlZERlZnMuaGFzKGNvbC5kZWYpO1xuICAgIH0pLm1hcChjb2wgPT4gY29sLmRlZik7XG4gIH1cblxuICBnZXQgdG90YWxQdXJjaGFzZVByaWNlKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMubW9kZWxzLnJlZHVjZSgoc3VtLCBtb2RlbCkgPT4gc3VtICsgTnVtYmVyKG1vZGVsPy5wdXJjaGFzZV9wcmljZSA/PyAwKSwgMCk7XG4gIH1cblxuICBnZXQgdG90YWxWYWx1ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm1vZGVscy5yZWR1Y2UoKHN1bSwgbW9kZWwpID0+IHN1bSArIE51bWJlcihtb2RlbD8uYW1vdW50ID8/IDApLCAwKTtcbiAgfVxuXG4gIGdldCBmb290ZXJDb2x1bW5zKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5kaXNwbGF5ZWRDb2x1bW5zLm1hcChjb2wgPT4gYGZvb3Rlci0ke2NvbH1gKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBvdmVycmlkZSBzZXJ2aWNlOiBTdG9ja1JlY2VpcHRQcm9kdWN0U2VydmljZSxcbiAgICBwcml2YXRlIGZvcm1CdWlsZGVyOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGZlYXR1cmVTZXJ2aWNlOiBUZWNobGlmeUZlYXR1cmVTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLmZpbHRlckZvcm1Db25maWd1cmF0aW9uID0ge1xuICAgICAgZGF0ZV9mcm9tOiB7IGRhdGU6IHRydWUgfSxcbiAgICAgIGRhdGVfdG86IHsgZGF0ZTogdHJ1ZSB9LFxuICAgICAgY2F0ZWdvcnlfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBzdXBwbGllcl9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIGxvY2F0aW9uX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgICAgbWVhc3VyZV9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIHByb2R1Y3RfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgfTtcblxuICAgIHRoaXMuZmlsdGVyRm9ybSA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xuICAgICAgY2F0ZWdvcnlfaWRzOiBbJyddLFxuICAgICAgZGF0ZV9mcm9tOiBbJyddLFxuICAgICAgZGF0ZV90bzogWycnXSxcbiAgICAgIGR1cmF0aW9uOiBbJyddLFxuICAgICAgbG9jYXRpb25faWRzOiBbJyddLFxuICAgICAgbWVhc3VyZV9pZHM6IFsnJ10sXG4gICAgICBwcm9kdWN0X2lkczogWycnXSxcbiAgICAgIHNlYXJjaDogWycnXSxcbiAgICAgIHNvcnRfYnk6IFsnZGF0ZXxkZXNjJ10sXG4gICAgICBzdXBwbGllcl9pZHM6IFsnJ10sXG4gICAgICBwYWdlOiB0aGlzLnBhZ2UsXG4gICAgICBwZXJQYWdlOiB0aGlzLnBlclBhZ2UsXG4gICAgfSk7XG5cbiAgICBsZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuZmlsdGVycygpO1xuICAgICAgaWYgKCFpbml0aWFsaXplZCkge1xuICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlsdGVyRm9ybS5wYXRjaFZhbHVlKGZpbHRlcnMsIHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkRmVhdHVyZXMoKTtcbiAgICB0aGlzLl9kZWZhdWx0U2VsZWN0ZWRDb2x1bW5zID0gdGhpcy5jb2x1bW5Db25maWcuZmlsdGVyKGNvbCA9PiBjb2wuaXNTZWxlY3RlZCk7XG4gICAgdGhpcy5jb2x1bW5Db25maWdSZWFkeS5lbWl0KHRoaXMuY29sdW1uQ29uZmlnKTtcblxuICAgIGNvbnN0IGluaXRpYWxGaWx0ZXJzID0gdGhpcy5maWx0ZXJzKCk7XG4gICAgaWYgKGluaXRpYWxGaWx0ZXJzKSB7XG4gICAgICB0aGlzLmZpbHRlckZvcm0ucGF0Y2hWYWx1ZShpbml0aWFsRmlsdGVycywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgIH1cblxuICAgIHRoaXMucGF0Y2hGaWx0ZXJzRnJvbVJvdXRlKCk7XG4gICAgdGhpcy5saXN0ZW5GaWx0ZXJDaGFuZ2VzKCk7XG4gICAgdGhpcy5sb2FkRGF0YSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkRmVhdHVyZXMoKSB7XG4gICAgaWYgKHRoaXMuZmVhdHVyZVNlcnZpY2UuaXNGZWF0dXJlRXhpc3RzKCdwcm9kdWN0LWJhdGNoLW51bWJlcnMnKSkge1xuICAgICAgY29uc3QgcXR5SW5kZXggPSB0aGlzLmNvbHVtbkNvbmZpZy5maW5kSW5kZXgoYyA9PiBjLmRlZiA9PT0gJ3F1YW50aXR5Jyk7XG4gICAgICBpZiAocXR5SW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLmNvbHVtbkNvbmZpZy5zcGxpY2UocXR5SW5kZXggKyAxLCAwLCB7IGxhYmVsOiAnQmF0Y2gnLCBkZWY6ICdiYXRjaCcsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiPG1hdC1jYXJkPlxuICA8bWF0LWNhcmQtaGVhZGVyICpuZ0lmPVwiaXNQcm9kdWN0VmlldygpXCIgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgPG1hdC1jYXJkLXRpdGxlPlN0b2NrIFJlY2VpcHRzPC9tYXQtY2FyZC10aXRsZT5cbiAgICA8YXBwLXRlY2hsaWZ5LWljb24gcm9sZT0nYnV0dG9uJyBuYW1lPSdhZGQnIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeS9zdG9jay1yZWNlaXB0cy9iYXRjaC1mb3JtJ11cIlxuICAgICAgY2xhc3M9J21zLTInPjwvYXBwLXRlY2hsaWZ5LWljb24+XG4gIDwvbWF0LWNhcmQtaGVhZGVyPlxuXG4gIDxtYXQtY2FyZC1jb250ZW50IGNsYXNzPVwicC0wXCI+XG4gICAgPHRhYmxlIG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJtb2RlbHNcIiBjbGFzcz1cInctMTAwXCIgYXJpYS1kZXNjcmliZWRieT1cIlN0b2NrIFJlY2VpcHQgUHJvZHVjdHNcIiBpbmZpbml0ZVNjcm9sbFxuICAgICAgaWQ9XCJzdG9ja1JlY2VpcHRUYWJsZVwiIFtpbmZpbml0ZVNjcm9sbERpc3RhbmNlXT1cIjJcIiBbaW5maW5pdGVTY3JvbGxUaHJvdHRsZV09XCI1MFwiIChzY3JvbGxlZCk9XCJvblNjcm9sbCgpXCIgbWF0U29ydFxuICAgICAgKG1hdFNvcnRDaGFuZ2UpPVwic29ydENvbHVtbigkZXZlbnQpXCI+XG5cbiAgICAgIDwhLS0gIyBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm5vXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+IzwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50OyBsZXQgaSA9IGluZGV4XCI+e3sgaSArIDEgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicmVjZWlwdF9udW1iZXJcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXRUb29sdGlwPVwiU3RvY2sgUmVjZWlwdCBJRFwiPlJlY2VpcHQgIzwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWRhcmtcIlxuICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiWycvaW52ZW50b3J5L3N0b2NrLXJlY2VpcHRzJywgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9pZCwgJ3ZpZXcnXVwiPlxuICAgICAgICAgICAge3sgZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9pZCB9fVxuICAgICAgICAgIDwvYT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFByb2R1Y3QgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJwcm9kdWN0XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlByb2R1Y3Q8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIDxhIGNsYXNzPVwidGV4dC1kZWNvcmF0aW9uLW5vbmUgdGV4dC1kYXJrXCJcbiAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeS9wcm9kdWN0cycsIGVsZW1lbnQ/LnByb2R1Y3Q/LmlkLCAndmlldyddXCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5wcm9kdWN0Py5uYW1lIH19XG4gICAgICAgICAgPC9hPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gUHJvZHVjdCBDYXRlZ29yaWVzIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicHJvZHVjdF9jYXRlZ29yaWVzXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+UHJvZHVjdCBDYXRlZ29yaWVzPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8YXBwLXByb2R1Y3QtY2F0ZWdvcnktYmFkZ2VzIFtwcm9kdWN0XT1cImVsZW1lbnQ/LnByb2R1Y3RcIj48L2FwcC1wcm9kdWN0LWNhdGVnb3J5LWJhZGdlcz5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIENhdGVnb3JpZXMgQ29sdW1uIChleHBvcnQgb25seSkgLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNhdGVnb3JpZXNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5DYXRlZ29yaWVzPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgY2F0ZWdvcnkgb2YgZWxlbWVudD8ucHJvZHVjdD8uY2F0ZWdvcmllczsgbGV0IGxhc3QgPSBsYXN0XCI+XG4gICAgICAgICAgICB7eyBjYXRlZ29yeT8udGl0bGUgfX08bmctY29udGFpbmVyICpuZ0lmPVwiIWxhc3RcIj4sIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFNLVSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNrdVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5TS1U8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnByb2R1Y3Q/LnNrdSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBEYXRlIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZGF0ZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5EYXRlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdG9ja19yZWNlaXB0Py5kYXRlIHwgZGF0ZSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBRdWFudGl0eSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInF1YW50aXR5XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlF1YW50aXR5PC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICB7eyBlbGVtZW50Py5xdWFudGl0eSB9fSB7eyBlbGVtZW50Py5wcm9kdWN0Py5tZWFzdXJlPy50aXRsZSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQmF0Y2ggQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJiYXRjaFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkJhdGNoPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIiAqbmdJZj1cImVsZW1lbnQ/LmJhdGNoPy5iYXRjaF9udW1iZXJcIj57eyBlbGVtZW50Py5iYXRjaD8uYmF0Y2hfbnVtYmVyIH19PC9wPlxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCIgKm5nSWY9XCJlbGVtZW50Py5iYXRjaD8uZXhwaXJlc19vblwiPlxuICAgICAgICAgICAgRXhwaXJlcyB7eyBlbGVtZW50Py5iYXRjaD8uZXhwaXJlc19vbiB8IGRhdGUgfX1cbiAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTWVhc3VyZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm1lYXN1cmVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+TWVhc3VyZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8ucHJvZHVjdD8ubWVhc3VyZT8udGl0bGUgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTG9jYXRpb24gQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJsb2NhdGlvblwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Mb2NhdGlvbjwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWRhcmtcIlxuICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiWycvaW52ZW50b3J5L2xvY2F0aW9ucycsIGVsZW1lbnQ/LmxvY2F0aW9uX2lkLCAndmlldyddXCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5sb2NhdGlvbj8udGl0bGUgfX1cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBQdXJjaGFzZSBQcmljZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInB1cmNoYXNlX3ByaWNlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlB1cmNoYXNlIFByaWNlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5wdXJjaGFzZV9wcmljZSB8IGN1cnJlbmN5IH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFRvdGFsIFZhbHVlIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiYW1vdW50XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlRvdGFsIFZhbHVlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5hbW91bnQgfCBjdXJyZW5jeSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBQYXJ0aWN1bGFycyBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInBhcnRpY3VsYXJzXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+UGFydGljdWxhcnM8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnBhcnRpY3VsYXJzIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFN1cHBsaWVyIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic3VwcGxpZXJcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+U3VwcGxpZXI8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnN0b2NrX3JlY2VpcHQ/LnN1cHBsaWVyPy5jb21wYW55X25hbWUgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gU3VwcGxpZXIgQ29udGFjdCBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInN1cHBsaWVyX2NvbnRhY3RcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5TdXBwbGllciBDb250YWN0PC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdG9ja19yZWNlaXB0Py5zdXBwbGllcj8uY29udGFjdF9uYW1lIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFN1cHBsaWVyIFBob25lIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic3VwcGxpZXJfcGhvbmVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5TdXBwbGllciBQaG9uZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uc3RvY2tfcmVjZWlwdD8uc3VwcGxpZXI/LnBob25lIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIENyZWF0b3IgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJjcmVhdG9yXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+Q3JlYXRvcjwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPHAgY2xhc3M9XCJtYi0xXCI+e3sgZWxlbWVudD8uc3RvY2tfcmVjZWlwdD8uY3JlYXRvcj8ubmFtZSB9fTwvcD5cbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiPnt7IGVsZW1lbnQ/LnN0b2NrX3JlY2VpcHQ/LmNyZWF0ZWRfYXQgfCBkYXRlIH19PC9zbWFsbD5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIEFjdGlvbnMgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJhY3Rpb25zXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+QWN0aW9uczwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMSB0ZXh0LXNlY29uZGFyeVwiPlxuICAgICAgICAgICAgPGFwcC10ZWNobGlmeS1pY29uIHJvbGU9J2J1dHRvbicgbmFtZT0ndmlldycgY2xhc3M9J3RleHQtc2Vjb25kYXJ5J1xuICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJbJy9pbnZlbnRvcnknLCAnc3RvY2stcmVjZWlwdHMnLCBlbGVtZW50Py5pZCwgJ3ZpZXcnXVwiPjwvYXBwLXRlY2hsaWZ5LWljb24+XG4gICAgICAgICAgICA8YXBwLXN0b2NrLXJlY2VpcHQtcHJvZHVjdC1mb3JtLWJ1dHRvbiBbc3RvY2tSZWNlaXB0SWRdPVwiZWxlbWVudD8uc3RvY2tfcmVjZWlwdF9pZFwiXG4gICAgICAgICAgICAgIFtzdG9ja1JlY2VpcHRQcm9kdWN0XT1cImVsZW1lbnRcIiAoc2F2ZWQpPVwicmVsb2FkKCk7IGxpc3RVcGRhdGVkLmVtaXQodHJ1ZSlcIj5cbiAgICAgICAgICAgIDwvYXBwLXN0b2NrLXJlY2VpcHQtcHJvZHVjdC1mb3JtLWJ1dHRvbj5cbiAgICAgICAgICAgIDxhcHAtdGVjaGxpZnktZGVsZXRlLWJ1dHRvbiBbbW9kZWxdPVwiZWxlbWVudFwiIFtzZXJ2aWNlXT1cInNlcnZpY2VcIlxuICAgICAgICAgICAgICBbZGF0YV09XCJ7IHRpdGxlOiBlbGVtZW50Py5wcm9kdWN0Py5uYW1lLCB0eXBlOiAnU3RvY2sgUmVjZWlwdCBQcm9kdWN0JyB9XCJcbiAgICAgICAgICAgICAgKGRlbGV0ZWQpPVwicmVsb2FkKCk7IGxpc3RVcGRhdGVkLmVtaXQodHJ1ZSlcIj5cbiAgICAgICAgICAgIDwvYXBwLXRlY2hsaWZ5LWRlbGV0ZS1idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBGb290ZXIgQ2VsbHMgZm9yIFRvdGFsIFJvdyAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLW5vXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1yZWNlaXB0X251bWJlclwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItcHJvZHVjdFwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjxzdHJvbmc+VG90YWw8L3N0cm9uZz48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLXByb2R1Y3RfY2F0ZWdvcmllc1wiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItc2t1XCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1jYXRlZ29yaWVzXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1kYXRlXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1xdWFudGl0eVwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItYmF0Y2hcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLW1lYXN1cmVcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLWxvY2F0aW9uXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1wdXJjaGFzZV9wcmljZVwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjxzdHJvbmc+e3sgdG90YWxQdXJjaGFzZVByaWNlIHwgY3VycmVuY3kgfX08L3N0cm9uZz48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLWFtb3VudFwiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjxzdHJvbmc+e3sgdG90YWxWYWx1ZSB8IGN1cnJlbmN5IH19PC9zdHJvbmc+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1wYXJ0aWN1bGFyc1wiPlxuICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJmb290ZXItc3VwcGxpZXJcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLXN1cHBsaWVyX2NvbnRhY3RcIj5cbiAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZm9vdGVyLXN1cHBsaWVyX3Bob25lXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1jcmVhdG9yXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImZvb3Rlci1hY3Rpb25zXCI+XG4gICAgICAgIDx0ZCBtYXQtZm9vdGVyLWNlbGwgKm1hdEZvb3RlckNlbGxEZWY+PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImRpc3BsYXllZENvbHVtbnNcIj48L3RyPlxuICAgICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IGRpc3BsYXllZENvbHVtbnNcIj48L3RyPlxuICAgICAgPHRyIG1hdC1mb290ZXItcm93ICptYXRGb290ZXJSb3dEZWY9XCJmb290ZXJDb2x1bW5zXCI+PC90cj5cbiAgICA8L3RhYmxlPlxuXG4gICAgPG1hdC1wcm9ncmVzcy1iYXIgKm5nSWY9XCJpc1dvcmtpbmdcIiBtb2RlPVwiaW5kZXRlcm1pbmF0ZVwiPjwvbWF0LXByb2dyZXNzLWJhcj5cbiAgPC9tYXQtY2FyZC1jb250ZW50PlxuPC9tYXQtY2FyZD4iXX0=
|