techlify-inventory-common 18.39.0 → 18.40.0
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-basic-info/product-basic-info.component.mjs +3 -3
- package/esm2022/lib/inventory-common/product/product-list/product-list.component.mjs +28 -37
- package/esm2022/lib/inventory-common/product/product-view-page/product-view-page.component.mjs +1 -1
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-page/stock-issue-page.component.mjs +1 -1
- package/esm2022/lib/inventory-common/stock-issue/stock-issue-products-list/stock-issue-products-list.component.mjs +6 -5
- package/esm2022/lib/inventory-common/stock-receipts/stock-receipt-product-list/stock-receipt-product-list.component.mjs +3 -3
- package/fesm2022/{techlify-inventory-common-category.module-DKsak_po.mjs → techlify-inventory-common-category.module-CiZXYGS7.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-category.module-DKsak_po.mjs.map → techlify-inventory-common-category.module-CiZXYGS7.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-measure.module-CWwga0lu.mjs → techlify-inventory-common-measure.module-D9tk7RWL.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-measure.module-CWwga0lu.mjs.map → techlify-inventory-common-measure.module-D9tk7RWL.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-purchase-order-view.component-z9Sc2mFx.mjs → techlify-inventory-common-purchase-order-view.component-CsmrVmZs.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-purchase-order-view.component-z9Sc2mFx.mjs.map → techlify-inventory-common-purchase-order-view.component-CsmrVmZs.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-stock-issue-form.component-Dhqg97g0.mjs → techlify-inventory-common-stock-issue-form.component-CnjtA7Hb.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-stock-issue-form.component-Dhqg97g0.mjs.map → techlify-inventory-common-stock-issue-form.component-CnjtA7Hb.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-stock-issue-view.component-B72Eh8m5.mjs → techlify-inventory-common-stock-issue-view.component-zoK_HeFx.mjs} +2 -2
- package/fesm2022/{techlify-inventory-common-stock-issue-view.component-B72Eh8m5.mjs.map → techlify-inventory-common-stock-issue-view.component-zoK_HeFx.mjs.map} +1 -1
- package/fesm2022/{techlify-inventory-common-techlify-inventory-common-DarIleg2.mjs → techlify-inventory-common-techlify-inventory-common-CHc35QxL.mjs} +45 -53
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-CHc35QxL.mjs.map +1 -0
- package/fesm2022/techlify-inventory-common.mjs +1 -1
- package/lib/inventory-common/product/product-list/product-list.component.d.ts +0 -1
- package/lib/inventory-common/stock-issue/stock-issue-products-list/stock-issue-products-list.component.d.ts +2 -2
- package/package.json +1 -1
- package/fesm2022/techlify-inventory-common-techlify-inventory-common-DarIleg2.mjs.map +0 -1
package/esm2022/lib/inventory-common/product/product-basic-info/product-basic-info.component.mjs
CHANGED
|
@@ -43,11 +43,11 @@ export class ProductBasicInfoComponent {
|
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProductBasicInfoComponent, deps: [{ token: i1.StockSummaryService }, { token: i2.ProductService }], target: i0.ɵɵFactoryTarget.Component });
|
|
46
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProductBasicInfoComponent, selector: "app-product-basic-info", inputs: { product: "product" }, outputs: { saved: "saved", deleted: "deleted" }, ngImport: i0, template: "<mat-card *ngIf=\"product\" class=\"w-100\">\n\n <!-- Header: Image + Product Info + Actions -->\n <mat-card-content class=\"d-flex gap-3 align-items-start\">\n <div class=\"product-image-container rounded overflow-hidden flex-shrink-0\">\n <img *ngIf=\"product?.image_file_url\" [src]=\"product.image_file_url\" alt=\"{{ product?.name }}\"\n class=\"w-100 h-100 object-fit-cover\" />\n <div *ngIf=\"!product?.image_file_url\"\n class=\"w-100 h-100 bg-secondary-subtle d-flex align-items-center justify-content-center rounded\">\n <span class=\"material-symbols-outlined text-secondary\" style=\"font-size: 40px;\">inventory_2</span>\n </div>\n </div>\n\n <div class=\"flex-grow-1\">\n <div class=\"d-flex justify-content-between align-items-start\">\n <div>\n <h5 class=\"fw-semibold mb-1\">{{ product?.name }}</h5>\n <div class=\"d-flex align-items-center gap-1 text-secondary small flex-wrap\">\n <span>{{ product?.sku }}</span>\n <span> \u2022 </span>\n <span>{{ product?.type?.title }}</span>\n <span> \u2022 </span>\n <span class=\"material-symbols-outlined\" style=\"font-size: 16px;\">view_in_ar</span>\n <span>{{ product?.measure?.title }}</span>\n </div>\n </div>\n <div class=\"d-flex gap-2 flex-shrink-0 align-middle text-secondary\">\n <app-product-form-button [product]=\"product\" (saved)=\"onProductSaved($event)\"></app-product-form-button>\n <app-techlify-delete-button [model]=\"product\" [data]=\"{type: 'Product', title: product?.name}\"\n [service]=\"service\"></app-techlify-delete-button>\n </div>\n </div>\n\n <!-- Categories -->\n <div *ngIf=\"product?.categories?.length\" class=\"d-flex flex-wrap gap-1 mt-2\">\n <span class=\"badge border bg-light text-dark fw-medium\" *ngFor=\"let category of product?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </div>\n </mat-card-content>\n\n <!-- Stock Summary Row -->\n <mat-card-content class=\"d-flex flex-row justify-content-between py-3\">\n <!-- Stock Receipts -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Receipts</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_receipts_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_receipt\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_receipt?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- Stock Issues -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Issues</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_issuances_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_issue\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_issue?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- On Hand -->\n <div class=\"d-flex flex-column\">\n <small class=\"text-secondary\">On Hand</small>\n <p class=\"mb-0 fw-semibold fs-2 text-success\"\n [ngClass]=\"{ 'text-danger': product?.stock_on_hand < product?.reorder_point }\">{{ product?.stock_on_hand |\n number }}</p>\n <small *ngIf=\"product?.reorder_point\" class=\"text-secondary\">\n Reorder At {{ product?.reorder_point }}\n </small>\n </div>\n </mat-card-content>\n\n <!-- Description -->\n <mat-card-content *ngIf=\"product?.description\" class=\"pt-2\">\n <small class=\"text-secondary\">Description</small>\n <p class=\"mb-0 mt-1\">{{ product?.description }}</p>\n </mat-card-content>\n\n <div class=\"d-flex flex-row justify-content-around align-items-center w-100 mt-2\">\n <ngx-barcode6 [bc-value]=\"product?.sku\" [bc-display-value]=\"true\">\n </ngx-barcode6>\n\n <qrcode [qrdata]=\"product?.sku\" [width]=\"128\"></qrcode>\n </div>\n\n</mat-card>", styles: [".product-image-container{width:80px;height:80px}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5.QRCodeComponent, selector: "qrcode", inputs: ["allowEmptyString", "colorDark", "colorLight", "cssClass", "elementType", "errorCorrectionLevel", "imageSrc", "imageHeight", "imageWidth", "margin", "qrdata", "scale", "version", "width", "alt", "ariaLabel", "title"], outputs: ["qrCodeURL"] }, { kind: "component", type: i6.NgxBarcode6, selector: "ngx-barcode6", inputs: ["bc-element-type", "bc-class", "bc-format", "bc-line-color", "bc-width", "bc-height", "bc-display-value", "bc-font-options", "bc-font", "bc-text-align", "bc-text-position", "bc-text-margin", "bc-font-size", "bc-background", "bc-margin", "bc-margin-top", "bc-margin-bottom", "bc-margin-left", "bc-margin-right", "bc-value", "bc-valid"] }, { kind: "component", type: i7.TechlifyDeleteButtonComponent, selector: "app-techlify-delete-button", inputs: ["data", "model", "message", "service"], outputs: ["deleted"] }, { kind: "component", type: i8.ProductFormButtonComponent, selector: "app-product-form-button", inputs: ["product"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
46
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProductBasicInfoComponent, selector: "app-product-basic-info", inputs: { product: "product" }, outputs: { saved: "saved", deleted: "deleted" }, ngImport: i0, template: "<mat-card *ngIf=\"product\" class=\"w-100\">\n\n <!-- Header: Image + Product Info + Actions -->\n <mat-card-content class=\"d-flex gap-3 align-items-start\">\n <div class=\"product-image-container rounded overflow-hidden flex-shrink-0\">\n <img *ngIf=\"product?.image_file_url\" [src]=\"product.image_file_url\" alt=\"{{ product?.name }}\"\n class=\"w-100 h-100 object-fit-cover\" />\n <div *ngIf=\"!product?.image_file_url\"\n class=\"w-100 h-100 bg-secondary-subtle d-flex align-items-center justify-content-center rounded\">\n <span class=\"material-symbols-outlined text-secondary\" style=\"font-size: 40px;\">inventory_2</span>\n </div>\n </div>\n\n <div class=\"flex-grow-1\">\n <div class=\"d-flex justify-content-between align-items-start\">\n <div>\n <h5 class=\"fw-semibold mb-1\">{{ product?.name }}</h5>\n <div class=\"d-flex align-items-center gap-1 text-secondary small flex-wrap\">\n <span>{{ product?.sku }}</span>\n <span> \u2022 </span>\n <span>{{ product?.type?.title }}</span>\n <span> \u2022 </span>\n <span class=\"material-symbols-outlined\" style=\"font-size: 16px;\">view_in_ar</span>\n <span>{{ product?.measure?.title }}</span>\n </div>\n <div *ngIf=\"product?.average_cost != null\" class=\"d-flex align-items-center gap-1 text-secondary small\">\n <i class=\"fa-solid fa-money-bill\"></i>\n <span>{{ product?.average_cost | currency }}</span>\n </div>\n </div>\n <div class=\"d-flex gap-2 flex-shrink-0 align-middle text-secondary\">\n <app-product-form-button [product]=\"product\" (saved)=\"onProductSaved($event)\"></app-product-form-button>\n <app-techlify-delete-button [model]=\"product\" [data]=\"{type: 'Product', title: product?.name}\"\n [service]=\"service\"></app-techlify-delete-button>\n </div>\n </div>\n\n <!-- Categories -->\n <div *ngIf=\"product?.categories?.length\" class=\"d-flex flex-wrap gap-1 mt-2\">\n <span class=\"badge border bg-light text-dark fw-medium\" *ngFor=\"let category of product?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </div>\n </mat-card-content>\n\n <!-- Stock Summary Row -->\n <mat-card-content class=\"d-flex flex-row justify-content-between py-3\">\n <!-- Stock Receipts -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Receipts</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_receipts_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_receipt\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_receipt?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- Stock Issues -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Issues</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_issuances_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_issue\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_issue?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- On Hand -->\n <div class=\"d-flex flex-column\">\n <small class=\"text-secondary\">On Hand</small>\n <p class=\"mb-0 fw-semibold fs-2 text-success\"\n [ngClass]=\"{ 'text-danger': product?.stock_on_hand < product?.reorder_point }\">{{ product?.stock_on_hand |\n number }}</p>\n <small *ngIf=\"product?.reorder_point\" class=\"text-secondary\">\n Reorder At {{ product?.reorder_point }}\n </small>\n </div>\n </mat-card-content>\n\n <!-- Description -->\n <mat-card-content *ngIf=\"product?.description\" class=\"pt-2\">\n <small class=\"text-secondary\">Description</small>\n <p class=\"mb-0 mt-1\">{{ product?.description }}</p>\n </mat-card-content>\n\n <div class=\"d-flex flex-row justify-content-around align-items-center w-100 mt-2\">\n <ngx-barcode6 [bc-value]=\"product?.sku\" [bc-display-value]=\"true\">\n </ngx-barcode6>\n\n <qrcode [qrdata]=\"product?.sku\" [width]=\"128\"></qrcode>\n </div>\n\n</mat-card>", styles: [".product-image-container{width:80px;height:80px}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i5.QRCodeComponent, selector: "qrcode", inputs: ["allowEmptyString", "colorDark", "colorLight", "cssClass", "elementType", "errorCorrectionLevel", "imageSrc", "imageHeight", "imageWidth", "margin", "qrdata", "scale", "version", "width", "alt", "ariaLabel", "title"], outputs: ["qrCodeURL"] }, { kind: "component", type: i6.NgxBarcode6, selector: "ngx-barcode6", inputs: ["bc-element-type", "bc-class", "bc-format", "bc-line-color", "bc-width", "bc-height", "bc-display-value", "bc-font-options", "bc-font", "bc-text-align", "bc-text-position", "bc-text-margin", "bc-font-size", "bc-background", "bc-margin", "bc-margin-top", "bc-margin-bottom", "bc-margin-left", "bc-margin-right", "bc-value", "bc-valid"] }, { kind: "component", type: i7.TechlifyDeleteButtonComponent, selector: "app-techlify-delete-button", inputs: ["data", "model", "message", "service"], outputs: ["deleted"] }, { kind: "component", type: i8.ProductFormButtonComponent, selector: "app-product-form-button", inputs: ["product"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }, { kind: "pipe", type: i3.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i3.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
47
47
|
}
|
|
48
48
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProductBasicInfoComponent, decorators: [{
|
|
49
49
|
type: Component,
|
|
50
|
-
args: [{ selector: 'app-product-basic-info', template: "<mat-card *ngIf=\"product\" class=\"w-100\">\n\n <!-- Header: Image + Product Info + Actions -->\n <mat-card-content class=\"d-flex gap-3 align-items-start\">\n <div class=\"product-image-container rounded overflow-hidden flex-shrink-0\">\n <img *ngIf=\"product?.image_file_url\" [src]=\"product.image_file_url\" alt=\"{{ product?.name }}\"\n class=\"w-100 h-100 object-fit-cover\" />\n <div *ngIf=\"!product?.image_file_url\"\n class=\"w-100 h-100 bg-secondary-subtle d-flex align-items-center justify-content-center rounded\">\n <span class=\"material-symbols-outlined text-secondary\" style=\"font-size: 40px;\">inventory_2</span>\n </div>\n </div>\n\n <div class=\"flex-grow-1\">\n <div class=\"d-flex justify-content-between align-items-start\">\n <div>\n <h5 class=\"fw-semibold mb-1\">{{ product?.name }}</h5>\n <div class=\"d-flex align-items-center gap-1 text-secondary small flex-wrap\">\n <span>{{ product?.sku }}</span>\n <span> \u2022 </span>\n <span>{{ product?.type?.title }}</span>\n <span> \u2022 </span>\n <span class=\"material-symbols-outlined\" style=\"font-size: 16px;\">view_in_ar</span>\n <span>{{ product?.measure?.title }}</span>\n </div>\n </div>\n <div class=\"d-flex gap-2 flex-shrink-0 align-middle text-secondary\">\n <app-product-form-button [product]=\"product\" (saved)=\"onProductSaved($event)\"></app-product-form-button>\n <app-techlify-delete-button [model]=\"product\" [data]=\"{type: 'Product', title: product?.name}\"\n [service]=\"service\"></app-techlify-delete-button>\n </div>\n </div>\n\n <!-- Categories -->\n <div *ngIf=\"product?.categories?.length\" class=\"d-flex flex-wrap gap-1 mt-2\">\n <span class=\"badge border bg-light text-dark fw-medium\" *ngFor=\"let category of product?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </div>\n </mat-card-content>\n\n <!-- Stock Summary Row -->\n <mat-card-content class=\"d-flex flex-row justify-content-between py-3\">\n <!-- Stock Receipts -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Receipts</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_receipts_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_receipt\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_receipt?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- Stock Issues -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Issues</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_issuances_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_issue\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_issue?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- On Hand -->\n <div class=\"d-flex flex-column\">\n <small class=\"text-secondary\">On Hand</small>\n <p class=\"mb-0 fw-semibold fs-2 text-success\"\n [ngClass]=\"{ 'text-danger': product?.stock_on_hand < product?.reorder_point }\">{{ product?.stock_on_hand |\n number }}</p>\n <small *ngIf=\"product?.reorder_point\" class=\"text-secondary\">\n Reorder At {{ product?.reorder_point }}\n </small>\n </div>\n </mat-card-content>\n\n <!-- Description -->\n <mat-card-content *ngIf=\"product?.description\" class=\"pt-2\">\n <small class=\"text-secondary\">Description</small>\n <p class=\"mb-0 mt-1\">{{ product?.description }}</p>\n </mat-card-content>\n\n <div class=\"d-flex flex-row justify-content-around align-items-center w-100 mt-2\">\n <ngx-barcode6 [bc-value]=\"product?.sku\" [bc-display-value]=\"true\">\n </ngx-barcode6>\n\n <qrcode [qrdata]=\"product?.sku\" [width]=\"128\"></qrcode>\n </div>\n\n</mat-card>", styles: [".product-image-container{width:80px;height:80px}\n"] }]
|
|
50
|
+
args: [{ selector: 'app-product-basic-info', template: "<mat-card *ngIf=\"product\" class=\"w-100\">\n\n <!-- Header: Image + Product Info + Actions -->\n <mat-card-content class=\"d-flex gap-3 align-items-start\">\n <div class=\"product-image-container rounded overflow-hidden flex-shrink-0\">\n <img *ngIf=\"product?.image_file_url\" [src]=\"product.image_file_url\" alt=\"{{ product?.name }}\"\n class=\"w-100 h-100 object-fit-cover\" />\n <div *ngIf=\"!product?.image_file_url\"\n class=\"w-100 h-100 bg-secondary-subtle d-flex align-items-center justify-content-center rounded\">\n <span class=\"material-symbols-outlined text-secondary\" style=\"font-size: 40px;\">inventory_2</span>\n </div>\n </div>\n\n <div class=\"flex-grow-1\">\n <div class=\"d-flex justify-content-between align-items-start\">\n <div>\n <h5 class=\"fw-semibold mb-1\">{{ product?.name }}</h5>\n <div class=\"d-flex align-items-center gap-1 text-secondary small flex-wrap\">\n <span>{{ product?.sku }}</span>\n <span> \u2022 </span>\n <span>{{ product?.type?.title }}</span>\n <span> \u2022 </span>\n <span class=\"material-symbols-outlined\" style=\"font-size: 16px;\">view_in_ar</span>\n <span>{{ product?.measure?.title }}</span>\n </div>\n <div *ngIf=\"product?.average_cost != null\" class=\"d-flex align-items-center gap-1 text-secondary small\">\n <i class=\"fa-solid fa-money-bill\"></i>\n <span>{{ product?.average_cost | currency }}</span>\n </div>\n </div>\n <div class=\"d-flex gap-2 flex-shrink-0 align-middle text-secondary\">\n <app-product-form-button [product]=\"product\" (saved)=\"onProductSaved($event)\"></app-product-form-button>\n <app-techlify-delete-button [model]=\"product\" [data]=\"{type: 'Product', title: product?.name}\"\n [service]=\"service\"></app-techlify-delete-button>\n </div>\n </div>\n\n <!-- Categories -->\n <div *ngIf=\"product?.categories?.length\" class=\"d-flex flex-wrap gap-1 mt-2\">\n <span class=\"badge border bg-light text-dark fw-medium\" *ngFor=\"let category of product?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </div>\n </mat-card-content>\n\n <!-- Stock Summary Row -->\n <mat-card-content class=\"d-flex flex-row justify-content-between py-3\">\n <!-- Stock Receipts -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Receipts</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_receipts_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_receipt\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_receipt?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- Stock Issues -->\n <div *ngIf=\"stockSummary\" class=\"d-flex flex-column\">\n <small class=\"text-secondary\">Stock Issues</small>\n <p class=\"mb-0 fw-semibold fs-2\">{{ stockSummary?.stock_issuances_quantity_sum | number }}</p>\n <small *ngIf=\"product?.last_stock_issue\" class=\"text-secondary\">\n Last Added On {{ product?.last_stock_issue?.date | date: 'MMM d, y' }}\n </small>\n </div>\n\n <!-- On Hand -->\n <div class=\"d-flex flex-column\">\n <small class=\"text-secondary\">On Hand</small>\n <p class=\"mb-0 fw-semibold fs-2 text-success\"\n [ngClass]=\"{ 'text-danger': product?.stock_on_hand < product?.reorder_point }\">{{ product?.stock_on_hand |\n number }}</p>\n <small *ngIf=\"product?.reorder_point\" class=\"text-secondary\">\n Reorder At {{ product?.reorder_point }}\n </small>\n </div>\n </mat-card-content>\n\n <!-- Description -->\n <mat-card-content *ngIf=\"product?.description\" class=\"pt-2\">\n <small class=\"text-secondary\">Description</small>\n <p class=\"mb-0 mt-1\">{{ product?.description }}</p>\n </mat-card-content>\n\n <div class=\"d-flex flex-row justify-content-around align-items-center w-100 mt-2\">\n <ngx-barcode6 [bc-value]=\"product?.sku\" [bc-display-value]=\"true\">\n </ngx-barcode6>\n\n <qrcode [qrdata]=\"product?.sku\" [width]=\"128\"></qrcode>\n </div>\n\n</mat-card>", styles: [".product-image-container{width:80px;height:80px}\n"] }]
|
|
51
51
|
}], ctorParameters: () => [{ type: i1.StockSummaryService }, { type: i2.ProductService }], propDecorators: { product: [{
|
|
52
52
|
type: Input
|
|
53
53
|
}], saved: [{
|
|
@@ -55,4 +55,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
55
55
|
}], deleted: [{
|
|
56
56
|
type: Output
|
|
57
57
|
}] } });
|
|
58
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1iYXNpYy1pbmZvLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3Byb2R1Y3QvcHJvZHVjdC1iYXNpYy1pbmZvL3Byb2R1Y3QtYmFzaWMtaW5mby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZlbnRvcnktY29tbW9uL3NyYy9saWIvaW52ZW50b3J5LWNvbW1vbi9wcm9kdWN0L3Byb2R1Y3QtYmFzaWMtaW5mby9wcm9kdWN0LWJhc2ljLWluZm8uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7OztBQVMvRSxNQUFNLE9BQU8seUJBQXlCO0lBTWhCO0lBQ1I7SUFOSCxPQUFPLENBQU07SUFDWixLQUFLLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7SUFDbkQsT0FBTyxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO0lBQy9ELFlBQVksQ0FBTztJQUVuQixZQUFvQixtQkFBd0MsRUFDaEQsT0FBdUI7UUFEZix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ2hELFlBQU8sR0FBUCxPQUFPLENBQWdCO0lBQ2hDLENBQUM7SUFFSixRQUFRO1FBQ04sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7SUFFRCxjQUFjLENBQUMsT0FBWTtRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsd0JBQXdCO1FBQ3RCLE1BQU0sTUFBTSxHQUFRO1lBQ2xCLFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDN0IsT0FBTyxFQUFFLG1GQUFtRjtTQUM3RixDQUFDO1FBQ0YsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDakQsSUFBSSxFQUFFLENBQUMsUUFBYSxFQUFFLEVBQUU7Z0JBQ3RCLElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDO1lBQy9CLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO3dHQWxDVSx5QkFBeUI7NEZBQXpCLHlCQUF5QiwrSUNUdEMsa3VJQTJGVzs7NEZEbEZFLHlCQUF5QjtrQkFMckMsU0FBUzsrQkFDRSx3QkFBd0I7cUhBS3pCLE9BQU87c0JBQWYsS0FBSztnQkFDSSxLQUFLO3NCQUFkLE1BQU07Z0JBQ0csT0FBTztzQkFBaEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN0b2NrU3VtbWFyeVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zdG9jay1zdW1tYXJ5LnNlcnZpY2UnO1xuaW1wb3J0IHsgUHJvZHVjdFNlcnZpY2UgfSBmcm9tICcuLi9wcm9kdWN0LnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcHJvZHVjdC1iYXNpYy1pbmZvJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3Byb2R1Y3QtYmFzaWMtaW5mby5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Byb2R1Y3QtYmFzaWMtaW5mby5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBQcm9kdWN0QmFzaWNJbmZvQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgcHJvZHVjdDogYW55O1xuICBAT3V0cHV0KCkgc2F2ZWQ6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBkZWxldGVkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBzdG9ja1N1bW1hcnkhOiBhbnk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBzdG9ja1N1bW1hcnlTZXJ2aWNlOiBTdG9ja1N1bW1hcnlTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBzZXJ2aWNlOiBQcm9kdWN0U2VydmljZVxuICApIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHRoaXMucHJvZHVjdCkge1xuICAgICAgdGhpcy5sb2FkUHJvZHVjdFN0b2Nrc1N1bW1hcnkoKTtcbiAgICB9XG4gIH1cblxuICBvblByb2R1Y3RTYXZlZChwcm9kdWN0OiBhbnkpIHtcbiAgICB0aGlzLnByb2R1Y3QgPSBwcm9kdWN0O1xuICAgIHRoaXMuc2F2ZWQuZW1pdCh0aGlzLnByb2R1Y3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgcHJvZHVjdCBzdG9ja3Mgc3VtbWFyeS5cbiAgICovXG4gIGxvYWRQcm9kdWN0U3RvY2tzU3VtbWFyeSgpIHtcbiAgICBjb25zdCBwYXJhbXM6IGFueSA9IHtcbiAgICAgIHByb2R1Y3RfaWRzOiB0aGlzLnByb2R1Y3Q/LmlkLFxuICAgICAgaW5jbHVkZTogJ3N0b2NrX3JlY2VpcHRzX3F1YW50aXR5X3N1bSxzdG9ja19pc3N1YW5jZXNfcXVhbnRpdHlfc3VtLHN0b2NrX3F1YW50aXR5X3JlbWFpbmluZycsXG4gICAgfTtcbiAgICB0aGlzLnN0b2NrU3VtbWFyeVNlcnZpY2Uuc3VtbWFyeShwYXJhbXMpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzcG9uc2U6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnN0b2NrU3VtbWFyeSA9IHJlc3BvbnNlO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuIiwiPG1hdC1jYXJkICpuZ0lmPVwicHJvZHVjdFwiIGNsYXNzPVwidy0xMDBcIj5cblxuICA8IS0tIEhlYWRlcjogSW1hZ2UgKyBQcm9kdWN0IEluZm8gKyBBY3Rpb25zIC0tPlxuICA8bWF0LWNhcmQtY29udGVudCBjbGFzcz1cImQtZmxleCBnYXAtMyBhbGlnbi1pdGVtcy1zdGFydFwiPlxuICAgIDxkaXYgY2xhc3M9XCJwcm9kdWN0LWltYWdlLWNvbnRhaW5lciByb3VuZGVkIG92ZXJmbG93LWhpZGRlbiBmbGV4LXNocmluay0wXCI+XG4gICAgICA8aW1nICpuZ0lmPVwicHJvZHVjdD8uaW1hZ2VfZmlsZV91cmxcIiBbc3JjXT1cInByb2R1Y3QuaW1hZ2VfZmlsZV91cmxcIiBhbHQ9XCJ7eyBwcm9kdWN0Py5uYW1lIH19XCJcbiAgICAgICAgY2xhc3M9XCJ3LTEwMCBoLTEwMCBvYmplY3QtZml0LWNvdmVyXCIgLz5cbiAgICAgIDxkaXYgKm5nSWY9XCIhcHJvZHVjdD8uaW1hZ2VfZmlsZV91cmxcIlxuICAgICAgICBjbGFzcz1cInctMTAwIGgtMTAwIGJnLXNlY29uZGFyeS1zdWJ0bGUgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyIHJvdW5kZWRcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkIHRleHQtc2Vjb25kYXJ5XCIgc3R5bGU9XCJmb250LXNpemU6IDQwcHg7XCI+aW52ZW50b3J5XzI8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3ctMVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1zdGFydFwiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxoNSBjbGFzcz1cImZ3LXNlbWlib2xkIG1iLTFcIj57eyBwcm9kdWN0Py5uYW1lIH19PC9oNT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMSB0ZXh0LXNlY29uZGFyeSBzbWFsbCBmbGV4LXdyYXBcIj5cbiAgICAgICAgICAgIDxzcGFuPnt7IHByb2R1Y3Q/LnNrdSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPiDigKIgPC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+e3sgcHJvZHVjdD8udHlwZT8udGl0bGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8c3Bhbj4g4oCiIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiIHN0eWxlPVwiZm9udC1zaXplOiAxNnB4O1wiPnZpZXdfaW5fYXI8L3NwYW4+XG4gICAgICAgICAgICA8c3Bhbj57eyBwcm9kdWN0Py5tZWFzdXJlPy50aXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwicHJvZHVjdD8uYXZlcmFnZV9jb3N0ICE9IG51bGxcIiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTEgdGV4dC1zZWNvbmRhcnkgc21hbGxcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEtc29saWQgZmEtbW9uZXktYmlsbFwiPjwvaT5cbiAgICAgICAgICAgIDxzcGFuPnt7IHByb2R1Y3Q/LmF2ZXJhZ2VfY29zdCB8IGN1cnJlbmN5IH19PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMiBmbGV4LXNocmluay0wIGFsaWduLW1pZGRsZSB0ZXh0LXNlY29uZGFyeVwiPlxuICAgICAgICAgIDxhcHAtcHJvZHVjdC1mb3JtLWJ1dHRvbiBbcHJvZHVjdF09XCJwcm9kdWN0XCIgKHNhdmVkKT1cIm9uUHJvZHVjdFNhdmVkKCRldmVudClcIj48L2FwcC1wcm9kdWN0LWZvcm0tYnV0dG9uPlxuICAgICAgICAgIDxhcHAtdGVjaGxpZnktZGVsZXRlLWJ1dHRvbiBbbW9kZWxdPVwicHJvZHVjdFwiIFtkYXRhXT1cInt0eXBlOiAnUHJvZHVjdCcsIHRpdGxlOiBwcm9kdWN0Py5uYW1lfVwiXG4gICAgICAgICAgICBbc2VydmljZV09XCJzZXJ2aWNlXCI+PC9hcHAtdGVjaGxpZnktZGVsZXRlLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBDYXRlZ29yaWVzIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cInByb2R1Y3Q/LmNhdGVnb3JpZXM/Lmxlbmd0aFwiIGNsYXNzPVwiZC1mbGV4IGZsZXgtd3JhcCBnYXAtMSBtdC0yXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYm9yZGVyIGJnLWxpZ2h0IHRleHQtZGFyayBmdy1tZWRpdW1cIiAqbmdGb3I9XCJsZXQgY2F0ZWdvcnkgb2YgcHJvZHVjdD8uY2F0ZWdvcmllc1wiPlxuICAgICAgICAgIHt7IGNhdGVnb3J5Py50aXRsZSB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9tYXQtY2FyZC1jb250ZW50PlxuXG4gIDwhLS0gU3RvY2sgU3VtbWFyeSBSb3cgLS0+XG4gIDxtYXQtY2FyZC1jb250ZW50IGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIHB5LTNcIj5cbiAgICA8IS0tIFN0b2NrIFJlY2VpcHRzIC0tPlxuICAgIDxkaXYgKm5nSWY9XCJzdG9ja1N1bW1hcnlcIiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtblwiPlxuICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIj5TdG9jayBSZWNlaXB0czwvc21hbGw+XG4gICAgICA8cCBjbGFzcz1cIm1iLTAgZnctc2VtaWJvbGQgZnMtMlwiPnt7IHN0b2NrU3VtbWFyeT8uc3RvY2tfcmVjZWlwdHNfcXVhbnRpdHlfc3VtIHwgbnVtYmVyIH19PC9wPlxuICAgICAgPHNtYWxsICpuZ0lmPVwicHJvZHVjdD8ubGFzdF9zdG9ja19yZWNlaXB0XCIgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiPlxuICAgICAgICBMYXN0IEFkZGVkIE9uIHt7IHByb2R1Y3Q/Lmxhc3Rfc3RvY2tfcmVjZWlwdD8uZGF0ZSB8IGRhdGU6ICdNTU0gZCwgeScgfX1cbiAgICAgIDwvc21hbGw+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIFN0b2NrIElzc3VlcyAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwic3RvY2tTdW1tYXJ5XCIgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW5cIj5cbiAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCI+U3RvY2sgSXNzdWVzPC9zbWFsbD5cbiAgICAgIDxwIGNsYXNzPVwibWItMCBmdy1zZW1pYm9sZCBmcy0yXCI+e3sgc3RvY2tTdW1tYXJ5Py5zdG9ja19pc3N1YW5jZXNfcXVhbnRpdHlfc3VtIHwgbnVtYmVyIH19PC9wPlxuICAgICAgPHNtYWxsICpuZ0lmPVwicHJvZHVjdD8ubGFzdF9zdG9ja19pc3N1ZVwiIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIj5cbiAgICAgICAgTGFzdCBBZGRlZCBPbiB7eyBwcm9kdWN0Py5sYXN0X3N0b2NrX2lzc3VlPy5kYXRlIHwgZGF0ZTogJ01NTSBkLCB5JyB9fVxuICAgICAgPC9zbWFsbD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gT24gSGFuZCAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uXCI+XG4gICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiPk9uIEhhbmQ8L3NtYWxsPlxuICAgICAgPHAgY2xhc3M9XCJtYi0wIGZ3LXNlbWlib2xkIGZzLTIgdGV4dC1zdWNjZXNzXCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAndGV4dC1kYW5nZXInOiBwcm9kdWN0Py5zdG9ja19vbl9oYW5kIDwgcHJvZHVjdD8ucmVvcmRlcl9wb2ludCB9XCI+e3sgcHJvZHVjdD8uc3RvY2tfb25faGFuZCB8XG4gICAgICAgIG51bWJlciB9fTwvcD5cbiAgICAgIDxzbWFsbCAqbmdJZj1cInByb2R1Y3Q/LnJlb3JkZXJfcG9pbnRcIiBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCI+XG4gICAgICAgIFJlb3JkZXIgQXQge3sgcHJvZHVjdD8ucmVvcmRlcl9wb2ludCB9fVxuICAgICAgPC9zbWFsbD5cbiAgICA8L2Rpdj5cbiAgPC9tYXQtY2FyZC1jb250ZW50PlxuXG4gIDwhLS0gRGVzY3JpcHRpb24gLS0+XG4gIDxtYXQtY2FyZC1jb250ZW50ICpuZ0lmPVwicHJvZHVjdD8uZGVzY3JpcHRpb25cIiBjbGFzcz1cInB0LTJcIj5cbiAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiPkRlc2NyaXB0aW9uPC9zbWFsbD5cbiAgICA8cCBjbGFzcz1cIm1iLTAgbXQtMVwiPnt7IHByb2R1Y3Q/LmRlc2NyaXB0aW9uIH19PC9wPlxuICA8L21hdC1jYXJkLWNvbnRlbnQ+XG5cbiAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LXJvdyBqdXN0aWZ5LWNvbnRlbnQtYXJvdW5kIGFsaWduLWl0ZW1zLWNlbnRlciB3LTEwMCBtdC0yXCI+XG4gICAgPG5neC1iYXJjb2RlNiBbYmMtdmFsdWVdPVwicHJvZHVjdD8uc2t1XCIgW2JjLWRpc3BsYXktdmFsdWVdPVwidHJ1ZVwiPlxuICAgIDwvbmd4LWJhcmNvZGU2PlxuXG4gICAgPHFyY29kZSBbcXJkYXRhXT1cInByb2R1Y3Q/LnNrdVwiIFt3aWR0aF09XCIxMjhcIj48L3FyY29kZT5cbiAgPC9kaXY+XG5cbjwvbWF0LWNhcmQ+Il19
|
|
@@ -31,49 +31,40 @@ let ProductListComponent = class ProductListComponent extends TechlifyListCompon
|
|
|
31
31
|
productService;
|
|
32
32
|
productFormService;
|
|
33
33
|
selection = new SelectionModel(true, []);
|
|
34
|
-
// Columns to use during Excel export
|
|
35
|
-
customExportColumns = [
|
|
36
|
-
'#',
|
|
37
|
-
'name',
|
|
38
|
-
'type',
|
|
39
|
-
'sku',
|
|
40
|
-
'categories',
|
|
41
|
-
'reorder_point',
|
|
42
|
-
'stock_receipts',
|
|
43
|
-
'stock_issues',
|
|
44
|
-
'on_hand',
|
|
45
|
-
'measure',
|
|
46
|
-
'sale_price'
|
|
47
|
-
];
|
|
48
34
|
exportInProgress = false;
|
|
49
35
|
columnConfig = [
|
|
36
|
+
{ label: '#', def: '#', isSelected: true, isEditable: false },
|
|
37
|
+
{ label: 'Name', def: 'name', isSelected: true, isEditable: false },
|
|
38
|
+
{ label: 'SKU', def: 'sku', isSelected: true, isEditable: false },
|
|
39
|
+
{ label: 'Average Cost', def: 'average_cost', isSelected: false, isEditable: true },
|
|
40
|
+
{ label: 'Categories', def: 'categories', isSelected: true, isEditable: false },
|
|
41
|
+
{ label: 'Description', def: 'description', isSelected: true, isEditable: false, isExportable: false },
|
|
42
|
+
{ label: 'Reorder Point', def: 'reorder_point', isSelected: true, isEditable: false },
|
|
43
|
+
{ label: 'Stock Receipts', def: 'stock_receipts', isSelected: true, isEditable: false },
|
|
44
|
+
{ label: 'Stock Issues', def: 'stock_issues', isSelected: true, isEditable: false },
|
|
45
|
+
{ label: 'On Hand', def: 'on_hand', isSelected: true, isEditable: false },
|
|
46
|
+
{ label: 'Measure', def: 'measure', isSelected: true, isEditable: false },
|
|
47
|
+
{ label: 'Sale Price', def: 'sale_price', isSelected: true, isEditable: false },
|
|
48
|
+
{ label: 'Type', def: 'type', isSelected: false, isEditable: false, isExportable: true },
|
|
50
49
|
{ label: 'Initial Quantity', def: 'initial_quantity', isSelected: false, isEditable: true },
|
|
51
50
|
{ label: 'Income Account', def: 'income_account', isSelected: false, isEditable: true },
|
|
52
51
|
{ label: 'Expense Account', def: 'expense_account', isSelected: false, isEditable: true },
|
|
53
52
|
{ label: 'Creator', def: 'creator', isSelected: false, isEditable: true },
|
|
53
|
+
{ label: 'Actions', def: 'Actions', isSelected: true, isEditable: false, isExportable: false },
|
|
54
|
+
{ label: 'Select', def: 'Select', isSelected: true, isEditable: false, isExportable: false },
|
|
54
55
|
];
|
|
55
56
|
selectedColumns = this.columnConfig.filter((col) => col.isSelected);
|
|
56
57
|
get displayedColumns() {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
'reorder_point',
|
|
68
|
-
'stock_receipts',
|
|
69
|
-
'stock_issues',
|
|
70
|
-
'on_hand',
|
|
71
|
-
'measure',
|
|
72
|
-
'sale_price'
|
|
73
|
-
];
|
|
74
|
-
const cols = defaultCols.concat(...selectedCols);
|
|
75
|
-
cols.push('Actions', 'Select');
|
|
76
|
-
return cols;
|
|
58
|
+
const selectedDefs = new Set(this.selectedColumns.map(col => col.def));
|
|
59
|
+
return this.columnConfig.filter(col => {
|
|
60
|
+
if (this.exportInProgress) {
|
|
61
|
+
if (col.isExportable === true)
|
|
62
|
+
return true;
|
|
63
|
+
if (col.isExportable === false)
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
return selectedDefs.has(col.def);
|
|
67
|
+
}).map(col => col.def);
|
|
77
68
|
}
|
|
78
69
|
importId;
|
|
79
70
|
constructor(fb, dialog, activatedRoute, productService, productFormService) {
|
|
@@ -173,7 +164,7 @@ let ProductListComponent = class ProductListComponent extends TechlifyListCompon
|
|
|
173
164
|
this.exportInProgress = hideColumns;
|
|
174
165
|
}
|
|
175
166
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProductListComponent, deps: [{ token: i1.FormBuilder }, { token: i2.MatDialog }, { token: i3.ActivatedRoute }, { token: i4.ProductService }, { token: i5.ProductFormService }], target: i0.ɵɵFactoryTarget.Component });
|
|
176
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProductListComponent, selector: "app-product-list", usesInheritance: true, ngImport: i0, template: "<mat-card class=\"mb-3\">\n <mat-card-content>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-center align-items-center gap-2\">\n <h3 class=\"mb-0\">Products</h3>\n <app-product-form-button></app-product-form-button>\n <span matTooltip=\"Import\" routerLink=\"import\" class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n <app-export-to-excel-button tableId=\"productTable\" fileName=\"products\" (onExportStart)=\"handleExport(true)\"\n (onExportEnd)=\"handleExport(false)\">\n </app-export-to-excel-button>\n <app-column-selector mode=\"icon\" class=\"d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-form-field class='fl-md'>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Category</mat-label>\n <app-searchable-selector apiUrl=\"api/product-categories\" formControlName=\"category_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Type</mat-label>\n <app-searchable-selector apiUrl=\"api/product-types\" formControlName=\"type_ids\" titleField=\"title\"\n [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </div>\n </form>\n </mat-card-content>\n</mat-card>\n\n<div class=\"d-flex justify-content-start gap-3\">\n <mat-card [class.flex-fill]=\"!selection.isEmpty()\" [class.w-100]=\"selection.isEmpty()\">\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" infiniteScroll [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [fromRoot]=\"true\" matSort\n (matSortChange)=\"sortColumn($event)\" matSortDisableClear=\"true\" aria-describedby=\"Products List\"\n id=\"productTable\">\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\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 <!-- Name Column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\" [routerLink]=\"[element?.id, 'view']\">{{ element.name }}</a>\n <small class=\"text-secondary\" *ngIf=\"element.type && !exportInProgress\">\n {{ element.type?.title }}\n </small>\n </div>\n </td>\n </ng-container>\n\n <!-- Type Column -->\n <ng-container matColumnDef=\"type\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Type</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.type?.title }}\n </td>\n </ng-container>\n\n <!-- Categories Column -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\" style=\"max-width: 200px\">\n <div *ngIf=\"element?.categories?.length > 0\"\n class=\"d-flex justify-content-start align-items-center gap-1 flex-wrap\">\n <span class=\"badge bg-secondary\" *ngFor=\"let category of element?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.sku }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Description</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.description }}</td>\n </ng-container>\n\n <!-- Initial Quantity Column -->\n <ng-container matColumnDef=\"initial_quantity\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Initial Quantity</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element.initial_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.initial_quantity_date\">\n on {{ element?.initial_quantity_date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Receipts Column -->\n <ng-container matColumnDef=\"stock_receipts\">\n <th mat-header-cell mat-sort-header=\"stock_receipts_sum_quantity\" *matHeaderCellDef>Stock Receipts</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_receipts_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_receipt && !exportInProgress\">\n Latest on {{ element?.last_stock_receipt?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Issues Column -->\n <ng-container matColumnDef=\"stock_issues\">\n <th mat-header-cell mat-sort-header=\"stock_issues_sum_quantity\" *matHeaderCellDef>Stock Issues</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_issues_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_issue && !exportInProgress\">\n Latest on {{ element?.last_stock_issue?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- On Hand Column -->\n <ng-container matColumnDef=\"on_hand\">\n <th mat-header-cell mat-sort-header='stock_on_hand' *matHeaderCellDef>On Hand</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_on_hand }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Measure</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.measure?.title }}\n </td>\n </ng-container>\n\n <!-- Reorder Point Column -->\n <ng-container matColumnDef=\"reorder_point\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Reorder Point</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reorder_point }}\n </td>\n </ng-container>\n\n <!-- Selling Price Column -->\n <ng-container matColumnDef=\"sale_price\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Selling Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.sale_price | currency }}\n </td>\n </ng-container>\n\n <!-- Income Account Column -->\n <ng-container matColumnDef=\"income_account\">\n <th mat-header-cell *matHeaderCellDef>Income Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.income_account?.title }}\n </td>\n </ng-container>\n\n <!-- Expense Account Column -->\n <ng-container matColumnDef=\"expense_account\">\n <th mat-header-cell *matHeaderCellDef>Expense Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.expense_account?.title }}\n </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-0\">{{ 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 class=\"text-secondary d-flex gap-1\">\n <app-techlify-icon name='view' [routerLink]=\"[element.id, 'view']\"\n routerLinkActive=\"route-link-active\"></app-techlify-icon>\n\n <app-product-form-button [product]=\"element\"></app-product-form-button>\n </div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"Select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllRowsSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllRowsSelected()\" [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n <mat-card *ngIf=\"!selection.isEmpty()\" class=\"batch-update-card\">\n <mat-card-content>\n <app-product-batch-update-form [selection]=\"selection\" (updated)=\"reload()\"></app-product-batch-update-form>\n </mat-card-content>\n </mat-card>\n</div>", styles: [".batch-update-card{width:15%;min-width:300px}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: i7.SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i12.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i13.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i13.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i14.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i15.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i16.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns", "isExportWorking"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "component", type: i17.ExportToExcelButtonComponent, selector: "app-export-to-excel-button", inputs: ["tableId", "fileName"], outputs: ["onExportStart", "onExportEnd"] }, { kind: "component", type: i7.TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }, { kind: "component", type: i18.ProductFormButtonComponent, selector: "app-product-form-button", inputs: ["product"] }, { kind: "component", type: i19.ProductBatchUpdateFormComponent, selector: "app-product-batch-update-form", inputs: ["selection"], outputs: ["updated"] }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i6.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
167
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProductListComponent, selector: "app-product-list", usesInheritance: true, ngImport: i0, template: "<mat-card class=\"mb-3\">\n <mat-card-content>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-center align-items-center gap-2\">\n <h3 class=\"mb-0\">Products</h3>\n <app-product-form-button></app-product-form-button>\n <span matTooltip=\"Import\" routerLink=\"import\" class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n <app-export-to-excel-button tableId=\"productTable\" fileName=\"products\" (onExportStart)=\"handleExport(true)\"\n (onExportEnd)=\"handleExport(false)\">\n </app-export-to-excel-button>\n <app-column-selector mode=\"icon\" class=\"d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-form-field class='fl-md'>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Category</mat-label>\n <app-searchable-selector apiUrl=\"api/product-categories\" formControlName=\"category_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Type</mat-label>\n <app-searchable-selector apiUrl=\"api/product-types\" formControlName=\"type_ids\" titleField=\"title\"\n [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </div>\n </form>\n </mat-card-content>\n</mat-card>\n\n<div class=\"d-flex justify-content-start gap-3\">\n <mat-card [class.flex-fill]=\"!selection.isEmpty()\" [class.w-100]=\"selection.isEmpty()\">\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" infiniteScroll [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [fromRoot]=\"true\" matSort\n (matSortChange)=\"sortColumn($event)\" matSortDisableClear=\"true\" aria-describedby=\"Products List\"\n id=\"productTable\">\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\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 <!-- Name Column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\" [routerLink]=\"[element?.id, 'view']\">{{ element.name }}</a>\n <small class=\"text-secondary\" *ngIf=\"element.type && !exportInProgress\">\n {{ element.type?.title }}\n </small>\n </div>\n </td>\n </ng-container>\n\n <!-- Type Column -->\n <ng-container matColumnDef=\"type\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Type</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.type?.title }}\n </td>\n </ng-container>\n\n <!-- Categories Column -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\" style=\"max-width: 200px\">\n <div *ngIf=\"element?.categories?.length > 0\"\n class=\"d-flex justify-content-start align-items-center gap-1 flex-wrap\">\n <span class=\"badge bg-secondary\" *ngFor=\"let category of element?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.sku }}</td>\n </ng-container>\n\n <!-- Average Cost Column -->\n <ng-container matColumnDef=\"average_cost\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Average Cost</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.average_cost | currency }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Description</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.description }}</td>\n </ng-container>\n\n <!-- Initial Quantity Column -->\n <ng-container matColumnDef=\"initial_quantity\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Initial Quantity</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element.initial_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.initial_quantity_date\">\n on {{ element?.initial_quantity_date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Receipts Column -->\n <ng-container matColumnDef=\"stock_receipts\">\n <th mat-header-cell mat-sort-header=\"stock_receipts_sum_quantity\" *matHeaderCellDef>Stock Receipts</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_receipts_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_receipt && !exportInProgress\">\n Latest on {{ element?.last_stock_receipt?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Issues Column -->\n <ng-container matColumnDef=\"stock_issues\">\n <th mat-header-cell mat-sort-header=\"stock_issues_sum_quantity\" *matHeaderCellDef>Stock Issues</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_issues_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_issue && !exportInProgress\">\n Latest on {{ element?.last_stock_issue?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- On Hand Column -->\n <ng-container matColumnDef=\"on_hand\">\n <th mat-header-cell mat-sort-header='stock_on_hand' *matHeaderCellDef>On Hand</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_on_hand }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Measure</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.measure?.title }}\n </td>\n </ng-container>\n\n <!-- Reorder Point Column -->\n <ng-container matColumnDef=\"reorder_point\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Reorder Point</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reorder_point }}\n </td>\n </ng-container>\n\n <!-- Selling Price Column -->\n <ng-container matColumnDef=\"sale_price\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Selling Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.sale_price | currency }}\n </td>\n </ng-container>\n\n <!-- Income Account Column -->\n <ng-container matColumnDef=\"income_account\">\n <th mat-header-cell *matHeaderCellDef>Income Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.income_account?.title }}\n </td>\n </ng-container>\n\n <!-- Expense Account Column -->\n <ng-container matColumnDef=\"expense_account\">\n <th mat-header-cell *matHeaderCellDef>Expense Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.expense_account?.title }}\n </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-0\">{{ 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 class=\"text-secondary d-flex gap-1\">\n <app-techlify-icon name='view' [routerLink]=\"[element.id, 'view']\"\n routerLinkActive=\"route-link-active\"></app-techlify-icon>\n\n <app-product-form-button [product]=\"element\"></app-product-form-button>\n </div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"Select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllRowsSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllRowsSelected()\" [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n <mat-card *ngIf=\"!selection.isEmpty()\" class=\"batch-update-card\">\n <mat-card-content>\n <app-product-batch-update-form [selection]=\"selection\" (updated)=\"reload()\"></app-product-batch-update-form>\n </mat-card-content>\n </mat-card>\n</div>", styles: [".batch-update-card{width:15%;min-width:300px}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3.RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: i7.SearchableSelectorComponent, selector: "app-searchable-selector", inputs: ["valueField", "titleField", "subtitleField", "apiUrl", "multiple", "selectedValue", "enableSearch", "add", "addConfig", "edit", "editConfig", "sort", "sortBy", "searchField", "itemComponent", "items", "apiDataProperty", "cache", "perPage", "inDataSearch", "panelWidth", "focusSearchOnOpen", "isEmitInitialEvent", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "directive", type: i11.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i11.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i12.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i12.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i12.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i12.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i12.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i12.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i12.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i12.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i12.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i12.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i12.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i12.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i13.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i13.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i14.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i15.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "directive", type: i16.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns", "isExportWorking"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "component", type: i17.ExportToExcelButtonComponent, selector: "app-export-to-excel-button", inputs: ["tableId", "fileName"], outputs: ["onExportStart", "onExportEnd"] }, { kind: "component", type: i7.TechlifyIconComponent, selector: "app-techlify-icon", inputs: ["name", "size"] }, { kind: "component", type: i18.ProductFormButtonComponent, selector: "app-product-form-button", inputs: ["product"] }, { kind: "component", type: i19.ProductBatchUpdateFormComponent, selector: "app-product-batch-update-form", inputs: ["selection"], outputs: ["updated"] }, { kind: "pipe", type: i6.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i6.DatePipe, name: "date" }], preserveWhitespaces: true });
|
|
177
168
|
};
|
|
178
169
|
ProductListComponent = __decorate([
|
|
179
170
|
UntilDestroy()
|
|
@@ -181,6 +172,6 @@ ProductListComponent = __decorate([
|
|
|
181
172
|
export { ProductListComponent };
|
|
182
173
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProductListComponent, decorators: [{
|
|
183
174
|
type: Component,
|
|
184
|
-
args: [{ selector: 'app-product-list', template: "<mat-card class=\"mb-3\">\n <mat-card-content>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-center align-items-center gap-2\">\n <h3 class=\"mb-0\">Products</h3>\n <app-product-form-button></app-product-form-button>\n <span matTooltip=\"Import\" routerLink=\"import\" class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n <app-export-to-excel-button tableId=\"productTable\" fileName=\"products\" (onExportStart)=\"handleExport(true)\"\n (onExportEnd)=\"handleExport(false)\">\n </app-export-to-excel-button>\n <app-column-selector mode=\"icon\" class=\"d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-form-field class='fl-md'>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Category</mat-label>\n <app-searchable-selector apiUrl=\"api/product-categories\" formControlName=\"category_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Type</mat-label>\n <app-searchable-selector apiUrl=\"api/product-types\" formControlName=\"type_ids\" titleField=\"title\"\n [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </div>\n </form>\n </mat-card-content>\n</mat-card>\n\n<div class=\"d-flex justify-content-start gap-3\">\n <mat-card [class.flex-fill]=\"!selection.isEmpty()\" [class.w-100]=\"selection.isEmpty()\">\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" infiniteScroll [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [fromRoot]=\"true\" matSort\n (matSortChange)=\"sortColumn($event)\" matSortDisableClear=\"true\" aria-describedby=\"Products List\"\n id=\"productTable\">\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\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 <!-- Name Column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\" [routerLink]=\"[element?.id, 'view']\">{{ element.name }}</a>\n <small class=\"text-secondary\" *ngIf=\"element.type && !exportInProgress\">\n {{ element.type?.title }}\n </small>\n </div>\n </td>\n </ng-container>\n\n <!-- Type Column -->\n <ng-container matColumnDef=\"type\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Type</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.type?.title }}\n </td>\n </ng-container>\n\n <!-- Categories Column -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\" style=\"max-width: 200px\">\n <div *ngIf=\"element?.categories?.length > 0\"\n class=\"d-flex justify-content-start align-items-center gap-1 flex-wrap\">\n <span class=\"badge bg-secondary\" *ngFor=\"let category of element?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.sku }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Description</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.description }}</td>\n </ng-container>\n\n <!-- Initial Quantity Column -->\n <ng-container matColumnDef=\"initial_quantity\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Initial Quantity</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element.initial_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.initial_quantity_date\">\n on {{ element?.initial_quantity_date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Receipts Column -->\n <ng-container matColumnDef=\"stock_receipts\">\n <th mat-header-cell mat-sort-header=\"stock_receipts_sum_quantity\" *matHeaderCellDef>Stock Receipts</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_receipts_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_receipt && !exportInProgress\">\n Latest on {{ element?.last_stock_receipt?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Issues Column -->\n <ng-container matColumnDef=\"stock_issues\">\n <th mat-header-cell mat-sort-header=\"stock_issues_sum_quantity\" *matHeaderCellDef>Stock Issues</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_issues_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_issue && !exportInProgress\">\n Latest on {{ element?.last_stock_issue?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- On Hand Column -->\n <ng-container matColumnDef=\"on_hand\">\n <th mat-header-cell mat-sort-header='stock_on_hand' *matHeaderCellDef>On Hand</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_on_hand }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Measure</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.measure?.title }}\n </td>\n </ng-container>\n\n <!-- Reorder Point Column -->\n <ng-container matColumnDef=\"reorder_point\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Reorder Point</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reorder_point }}\n </td>\n </ng-container>\n\n <!-- Selling Price Column -->\n <ng-container matColumnDef=\"sale_price\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Selling Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.sale_price | currency }}\n </td>\n </ng-container>\n\n <!-- Income Account Column -->\n <ng-container matColumnDef=\"income_account\">\n <th mat-header-cell *matHeaderCellDef>Income Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.income_account?.title }}\n </td>\n </ng-container>\n\n <!-- Expense Account Column -->\n <ng-container matColumnDef=\"expense_account\">\n <th mat-header-cell *matHeaderCellDef>Expense Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.expense_account?.title }}\n </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-0\">{{ 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 class=\"text-secondary d-flex gap-1\">\n <app-techlify-icon name='view' [routerLink]=\"[element.id, 'view']\"\n routerLinkActive=\"route-link-active\"></app-techlify-icon>\n\n <app-product-form-button [product]=\"element\"></app-product-form-button>\n </div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"Select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllRowsSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllRowsSelected()\" [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n <mat-card *ngIf=\"!selection.isEmpty()\" class=\"batch-update-card\">\n <mat-card-content>\n <app-product-batch-update-form [selection]=\"selection\" (updated)=\"reload()\"></app-product-batch-update-form>\n </mat-card-content>\n </mat-card>\n</div>", styles: [".batch-update-card{width:15%;min-width:300px}\n"] }]
|
|
175
|
+
args: [{ selector: 'app-product-list', template: "<mat-card class=\"mb-3\">\n <mat-card-content>\n <form [formGroup]=\"filterForm\" class=\"d-flex justify-content-between align-items-center gap-2\">\n <div class=\"d-flex justify-content-center align-items-center gap-2\">\n <h3 class=\"mb-0\">Products</h3>\n <app-product-form-button></app-product-form-button>\n <span matTooltip=\"Import\" routerLink=\"import\" class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n <app-export-to-excel-button tableId=\"productTable\" fileName=\"products\" (onExportStart)=\"handleExport(true)\"\n (onExportEnd)=\"handleExport(false)\">\n </app-export-to-excel-button>\n <app-column-selector mode=\"icon\" class=\"d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <mat-form-field class='fl-md'>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Category</mat-label>\n <app-searchable-selector apiUrl=\"api/product-categories\" formControlName=\"category_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field class='fl-sm'>\n <mat-label>Type</mat-label>\n <app-searchable-selector apiUrl=\"api/product-types\" formControlName=\"type_ids\" titleField=\"title\"\n [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </div>\n </form>\n </mat-card-content>\n</mat-card>\n\n<div class=\"d-flex justify-content-start gap-3\">\n <mat-card [class.flex-fill]=\"!selection.isEmpty()\" [class.w-100]=\"selection.isEmpty()\">\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" infiniteScroll [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" [fromRoot]=\"true\" matSort\n (matSortChange)=\"sortColumn($event)\" matSortDisableClear=\"true\" aria-describedby=\"Products List\"\n id=\"productTable\">\n <!-- # Column -->\n <ng-container matColumnDef=\"#\">\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 <!-- Name Column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\" [routerLink]=\"[element?.id, 'view']\">{{ element.name }}</a>\n <small class=\"text-secondary\" *ngIf=\"element.type && !exportInProgress\">\n {{ element.type?.title }}\n </small>\n </div>\n </td>\n </ng-container>\n\n <!-- Type Column -->\n <ng-container matColumnDef=\"type\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Type</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.type?.title }}\n </td>\n </ng-container>\n\n <!-- Categories Column -->\n <ng-container matColumnDef=\"categories\">\n <th mat-header-cell *matHeaderCellDef>Categories</th>\n <td mat-cell *matCellDef=\"let element\" style=\"max-width: 200px\">\n <div *ngIf=\"element?.categories?.length > 0\"\n class=\"d-flex justify-content-start align-items-center gap-1 flex-wrap\">\n <span class=\"badge bg-secondary\" *ngFor=\"let category of element?.categories\">\n {{ category?.title }}\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.sku }}</td>\n </ng-container>\n\n <!-- Average Cost Column -->\n <ng-container matColumnDef=\"average_cost\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Average Cost</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.average_cost | currency }}</td>\n </ng-container>\n\n <ng-container matColumnDef=\"description\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Description</th>\n <td mat-cell *matCellDef=\"let element\">{{ element.description }}</td>\n </ng-container>\n\n <!-- Initial Quantity Column -->\n <ng-container matColumnDef=\"initial_quantity\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Initial Quantity</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element.initial_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.initial_quantity_date\">\n on {{ element?.initial_quantity_date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Receipts Column -->\n <ng-container matColumnDef=\"stock_receipts\">\n <th mat-header-cell mat-sort-header=\"stock_receipts_sum_quantity\" *matHeaderCellDef>Stock Receipts</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_receipts_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_receipt && !exportInProgress\">\n Latest on {{ element?.last_stock_receipt?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- Stock Issues Column -->\n <ng-container matColumnDef=\"stock_issues\">\n <th mat-header-cell mat-sort-header=\"stock_issues_sum_quantity\" *matHeaderCellDef>Stock Issues</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\">{{ element?.stock_issues_sum_quantity }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.last_stock_issue && !exportInProgress\">\n Latest on {{ element?.last_stock_issue?.date | date }}\n </small>\n </td>\n </ng-container>\n\n <!-- On Hand Column -->\n <ng-container matColumnDef=\"on_hand\">\n <th mat-header-cell mat-sort-header='stock_on_hand' *matHeaderCellDef>On Hand</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.stock_on_hand }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Measure</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.measure?.title }}\n </td>\n </ng-container>\n\n <!-- Reorder Point Column -->\n <ng-container matColumnDef=\"reorder_point\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Reorder Point</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reorder_point }}\n </td>\n </ng-container>\n\n <!-- Selling Price Column -->\n <ng-container matColumnDef=\"sale_price\">\n <th mat-header-cell mat-sort-header *matHeaderCellDef>Selling Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.sale_price | currency }}\n </td>\n </ng-container>\n\n <!-- Income Account Column -->\n <ng-container matColumnDef=\"income_account\">\n <th mat-header-cell *matHeaderCellDef>Income Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.income_account?.title }}\n </td>\n </ng-container>\n\n <!-- Expense Account Column -->\n <ng-container matColumnDef=\"expense_account\">\n <th mat-header-cell *matHeaderCellDef>Expense Account</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.expense_account?.title }}\n </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-0\">{{ 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 class=\"text-secondary d-flex gap-1\">\n <app-techlify-icon name='view' [routerLink]=\"[element.id, 'view']\"\n routerLinkActive=\"route-link-active\"></app-techlify-icon>\n\n <app-product-form-button [product]=\"element\"></app-product-form-button>\n </div>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"Select\">\n <th mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllRowsSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllRowsSelected()\" [aria-label]=\"checkboxLabel()\">\n </mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection.isSelected(row)\" [aria-label]=\"checkboxLabel(row)\">\n </mat-checkbox>\n </td>\n <td mat-footer-cell *matFooterCellDef></td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar mode=\"indeterminate\" *ngIf=\"isWorking\"></mat-progress-bar>\n </mat-card-content>\n </mat-card>\n <mat-card *ngIf=\"!selection.isEmpty()\" class=\"batch-update-card\">\n <mat-card-content>\n <app-product-batch-update-form [selection]=\"selection\" (updated)=\"reload()\"></app-product-batch-update-form>\n </mat-card-content>\n </mat-card>\n</div>", styles: [".batch-update-card{width:15%;min-width:300px}\n"] }]
|
|
185
176
|
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.MatDialog }, { type: i3.ActivatedRoute }, { type: i4.ProductService }, { type: i5.ProductFormService }] });
|
|
186
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3Byb2R1Y3QvcHJvZHVjdC1saXN0L3Byb2R1Y3QtbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZlbnRvcnktY29tbW9uL3NyYy9saWIvaW52ZW50b3J5LWNvbW1vbi9wcm9kdWN0L3Byb2R1Y3QtbGlzdC9wcm9kdWN0LWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFJbEQsT0FBTyxFQUFnQixxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXhFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPbkQsSUFBTSxvQkFBb0IsR0FBMUIsTUFBTSxvQkFBcUIsU0FBUSxxQkFBcUI7SUF3RG5EO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUExRFYsU0FBUyxHQUFHLElBQUksY0FBYyxDQUFNLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUU5QyxxQ0FBcUM7SUFDN0IsbUJBQW1CLEdBQWE7UUFDdEMsR0FBRztRQUNILE1BQU07UUFDTixNQUFNO1FBQ04sS0FBSztRQUNMLFlBQVk7UUFDWixlQUFlO1FBQ2YsZ0JBQWdCO1FBQ2hCLGNBQWM7UUFDZCxTQUFTO1FBQ1QsU0FBUztRQUNULFlBQVk7S0FDYixDQUFDO0lBRUYsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0lBRXpCLFlB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T007O0FEak5PLG9CQUFvQjtJQU5oQyxZQUFZLEVBQUU7R0FNRixvQkFBb0IsQ0FvS2hDOzs0RkFwS1ksb0JBQW9CO2tCQUxoQyxTQUFTOytCQUNFLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtQnVpbGRlciB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE1hdERpYWxvZyB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBDb2x1bW5Db25maWcsIFRlY2hsaWZ5TGlzdENvbXBvbmVudCB9IGZyb20gJ25neC10ZWNobGlmeS1jb3JlJztcbmltcG9ydCB7IFByb2R1Y3RTZXJ2aWNlIH0gZnJvbSAnLi4vcHJvZHVjdC5zZXJ2aWNlJztcbmltcG9ydCB7IFVudGlsRGVzdHJveSB9IGZyb20gJ0BuZ25lYXQvdW50aWwtZGVzdHJveSc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBQcm9kdWN0Rm9ybVNlcnZpY2UgfSBmcm9tICcuLi9wcm9kdWN0LWZvcm0uc2VydmljZSc7XG5pbXBvcnQgeyBTZWxlY3Rpb25Nb2RlbCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XG5AVW50aWxEZXN0cm95KClcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1wcm9kdWN0LWxpc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vcHJvZHVjdC1saXN0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcHJvZHVjdC1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFByb2R1Y3RMaXN0Q29tcG9uZW50IGV4dGVuZHMgVGVjaGxpZnlMaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBzZWxlY3Rpb24gPSBuZXcgU2VsZWN0aW9uTW9kZWw8YW55Pih0cnVlLCBbXSk7XG5cbiAgLy8gQ29sdW1ucyB0byB1c2UgZHVyaW5nIEV4Y2VsIGV4cG9ydFxuICBwcml2YXRlIGN1c3RvbUV4cG9ydENvbHVtbnM6IHN0cmluZ1tdID0gW1xuICAgICcjJyxcbiAgICAnbmFtZScsXG4gICAgJ3R5cGUnLFxuICAgICdza3UnLFxuICAgICdjYXRlZ29yaWVzJyxcbiAgICAncmVvcmRlcl9wb2ludCcsXG4gICAgJ3N0b2NrX3JlY2VpcHRzJyxcbiAgICAnc3RvY2tfaXNzdWVzJyxcbiAgICAnb25faGFuZCcsXG4gICAgJ21lYXN1cmUnLFxuICAgICdzYWxlX3ByaWNlJ1xuICBdO1xuXG4gIGV4cG9ydEluUHJvZ3Jlc3MgPSBmYWxzZTtcblxuICBjb2x1bW5Db25maWc6IENvbHVtbkNvbmZpZ1tdID0gW1xuICAgIHsgbGFiZWw6ICdJbml0aWFsIFF1YW50aXR5JywgZGVmOiAnaW5pdGlhbF9xdWFudGl0eScsIGlzU2VsZWN0ZWQ6IGZhbHNlLCBpc0VkaXRhYmxlOiB0cnVlIH0sXG4gICAgeyBsYWJlbDogJ0luY29tZSBBY2NvdW50JywgZGVmOiAnaW5jb21lX2FjY291bnQnLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdFeHBlbnNlIEFjY291bnQnLCBkZWY6ICdleHBlbnNlX2FjY291bnQnLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdDcmVhdG9yJywgZGVmOiAnY3JlYXRvcicsIGlzU2VsZWN0ZWQ6IGZhbHNlLCBpc0VkaXRhYmxlOiB0cnVlIH0sXG4gIF07XG5cbiAgc2VsZWN0ZWRDb2x1bW5zOiBDb2x1bW5Db25maWdbXSA9IHRoaXMuY29sdW1uQ29uZmlnLmZpbHRlcigoY29sKSA9PiBjb2wuaXNTZWxlY3RlZCk7XG5cbiAgZ2V0IGRpc3BsYXllZENvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIGlmICh0aGlzLmV4cG9ydEluUHJvZ3Jlc3MpIHtcbiAgICAgIHJldHVybiB0aGlzLmN1c3RvbUV4cG9ydENvbHVtbnM7XG4gICAgfVxuICAgIGNvbnN0IHNlbGVjdGVkQ29scyA9IHRoaXMuc2VsZWN0ZWRDb2x1bW5zLm1hcChjb2wgPT4gY29sLmRlZik7XG4gICAgY29uc3QgZGVmYXVsdENvbHMgPSBbXG4gICAgICAnIycsXG4gICAgICAnbmFtZScsXG4gICAgICAnc2t1JyxcbiAgICAgICdjYXRlZ29yaWVzJyxcbiAgICAgICdkZXNjcmlwdGlvbicsXG4gICAgICAncmVvcmRlcl9wb2ludCcsXG4gICAgICAnc3RvY2tfcmVjZWlwdHMnLFxuICAgICAgJ3N0b2NrX2lzc3VlcycsXG4gICAgICAnb25faGFuZCcsXG4gICAgICAnbWVhc3VyZScsXG4gICAgICAnc2FsZV9wcmljZSdcbiAgICBdO1xuICAgIGNvbnN0IGNvbHMgPSBkZWZhdWx0Q29scy5jb25jYXQoLi4uc2VsZWN0ZWRDb2xzKTtcbiAgICBjb2xzLnB1c2goJ0FjdGlvbnMnLCAnU2VsZWN0Jyk7XG4gICAgcmV0dXJuIGNvbHM7XG4gIH1cblxuICBpbXBvcnRJZCE6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGRpYWxvZzogTWF0RGlhbG9nLFxuICAgIHByaXZhdGUgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgcHJvZHVjdFNlcnZpY2U6IFByb2R1Y3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgcHJvZHVjdEZvcm1TZXJ2aWNlOiBQcm9kdWN0Rm9ybVNlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmZpbHRlckZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGNhdGVnb3J5X2lkczogWycnXSxcbiAgICAgIGV4cGVuc2VfYWNjb3VudF9pZHM6IFsnJ10sXG4gICAgICBpbmNvbWVfYWNjb3VudF9pZHM6IFsnJ10sXG4gICAgICBtZWFzdXJlX2lkczogWycnXSxcbiAgICAgIHNlYXJjaDogWycnXSxcbiAgICAgIHNvcnRfYnk6IFsnJ10sXG4gICAgICB0eXBlX2lkczogWycnXSxcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zPy5bJ2ltcG9ydF9pZCddKSB7XG4gICAgICB0aGlzLmltcG9ydElkID0gcGFyc2VJbnQodGhpcy5hY3RpdmF0ZWRSb3V0ZS5zbmFwc2hvdC5xdWVyeVBhcmFtcz8uWydpbXBvcnRfaWQnXSk7XG4gICAgfVxuICAgIC8vIHVwZGF0ZSBmb3JtIHdpdGggVVJMIHF1ZXJ5IHBhcmFtc1xuICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UudXBkYXRlRm9ybVdpdGhRdWVyeVBhcmFtcyh0aGlzLmZpbHRlckZvcm0sIHtcbiAgICAgIHR5cGVfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBjYXRlZ29yeV9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIGluY29tZV9hY2NvdW50X2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgICAgZXhwZW5zZV9hY2NvdW50X2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgIH0pO1xuICAgIC8vIFVwZGF0ZSBVUkwgcXVlcnkgcGFyYW1zIG9uIGZpbHRlciBjaGFuZ2VcbiAgICB0aGlzLmZpbHRlckZvcm0udmFsdWVDaGFuZ2VzLnBpcGUoZGVib3VuY2VUaW1lKDgwMCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLnVwZGF0ZVF1ZXJ5UGFyYW1zKFxuICAgICAgICB0aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1EYXRhKHtcbiAgICAgICAgICAuLi50aGlzLmZpbHRlckZvcm0udmFsdWUsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0pO1xuICAgIC8vIGZldGNoIHRhc2sgb24gcGFyYW1zIGNoYW5nZVxuICAgIHRoaXMuYWN0aXZhdGVkUm91dGUucXVlcnlQYXJhbXMucGlwZShkZWJvdW5jZVRpbWUoODAwKSkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVsb2FkKCkpO1xuICAgIC8vIGxpc3RlbiBmb3JtIHByb2R1Y3QgYWRkIG9yIHVwZGF0ZSBldmVudCBhbmQgcmVsb2FkLlxuICAgIHRoaXMucHJvZHVjdEZvcm1TZXJ2aWNlLmlzTGlzdFVwZGF0ZWQoKS5zdWJzY3JpYmUoKHZhbDogYm9vbGVhbikgPT4ge1xuICAgICAgaWYgKHZhbCAmJiAhdGhpcy5pc1dvcmtpbmcpIHtcbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG92ZXJyaWRlIGxvYWREYXRhKCkge1xuICAgIGxldCBwYXJhbXM6IGFueSA9IHtcbiAgICAgIC4uLnRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UuY29udmVydFRvRm9ybURhdGEodGhpcy5maWx0ZXJGb3JtLnZhbHVlKSxcbiAgICB9O1xuICAgIHBhcmFtcy5wYWdlID0gdGhpcy5wYWdlO1xuICAgIHBhcmFtcy5wZXJQYWdlID0gdGhpcy5wZXJQYWdlO1xuICAgIHBhcmFtcy53aXRoID0gJ2NhdGVnb3JpZXMsbGFzdFN0b2NrUmVjZWlwdCxsYXN0U3RvY2tJc3N1ZSxtZWFzdXJlLGNyZWF0b3InO1xuICAgIGlmICh0aGlzLmltcG9ydElkKSB7XG4gICAgICBwYXJhbXMuaW1wb3J0X2lkID0gdGhpcy5pbXBvcnRJZDtcbiAgICB9XG4gICAgdGhpcy5pc1dvcmtpbmcgPSB0cnVlO1xuXG4gICAgdGhpcy5wcm9kdWN0U2VydmljZS5pbmRleChwYXJhbXMpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5pc1dvcmtpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tb2RlbHMgPSB0aGlzLm1vZGVscy5jb25jYXQocmVzPy5kYXRhKTtcbiAgICAgICAgdGhpcy5sYXN0UGFnZSA9IHJlcz8ubGFzdF9wYWdlO1xuICAgICAgICAvLyBzdG9wIHJlbG9hZGluZyBkYXRhIG9uY2UgZGF0YSBsb2FkZWQuXG4gICAgICAgIHRoaXMucHJvZHVjdEZvcm1TZXJ2aWNlLmxpc3RVcGRhdGVkKGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4gKHRoaXMuaXNXb3JraW5nID0gZmFsc2UpLFxuICAgIH0pO1xuICB9XG5cbiAgYXNzaWduRmlsdGVyKGNvbHVtbjogYW55LCBkaXJlY3Rpb246IHN0cmluZykge1xuICAgIGlmIChjb2x1bW4pIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbHRlckZvcm0uZ2V0KCdzb3J0X2J5Jyk/LnNldFZhbHVlKGNvbHVtbiArICd8JyArIGRpcmVjdGlvbik7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGUgc29ydENvbHVtbihldmVudDogYW55KSB7XG4gICAgdmFyIGRpcmVjdGlvbiA9IGV2ZW50LmRpcmVjdGlvbi50b1N0cmluZygpLnRvVXBwZXJDYXNlKCk7XG4gICAgdGhpcy5hc3NpZ25GaWx0ZXIoZXZlbnQuYWN0aXZlLCBkaXJlY3Rpb24pO1xuICB9XG5cbiAgaXNBbGxSb3dzU2VsZWN0ZWQoKSB7XG4gICAgY29uc3QgbnVtU2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGlvbi5zZWxlY3RlZC5sZW5ndGg7XG4gICAgY29uc3QgbnVtUm93cyA9IHRoaXMubW9kZWxzLmxlbmd0aDtcbiAgICByZXR1cm4gbnVtU2VsZWN0ZWQgPT09IG51bVJvd3M7XG4gIH1cblxuICAvKiogU2VsZWN0cyBhbGwgcm93cyBpZiB0aGV5IGFyZSBub3QgYWxsIHNlbGVjdGVkOyBvdGhlcndpc2UgY2xlYXIgc2VsZWN0aW9uLiAqL1xuICB0b2dnbGVBbGxSb3dzKCkge1xuICAgIGlmICh0aGlzLmlzQWxsUm93c1NlbGVjdGVkKCkpIHtcbiAgICAgIHRoaXMuc2VsZWN0aW9uLmNsZWFyKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3Rpb24uc2VsZWN0KC4uLnRoaXMubW9kZWxzKTtcbiAgfVxuXG4gIGNoZWNrYm94TGFiZWwocm93PzogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoIXJvdykge1xuICAgICAgcmV0dXJuIGAke3RoaXMuaXNBbGxSb3dzU2VsZWN0ZWQoKSA/ICdkZXNlbGVjdCcgOiAnc2VsZWN0J30gYWxsYDtcbiAgICB9XG4gICAgcmV0dXJuIGAke3RoaXMuc2VsZWN0aW9uLmlzU2VsZWN0ZWQocm93KSA/ICdkZXNlbGVjdCcgOiAnc2VsZWN0J30gcm93ICR7cm93LnBvc2l0aW9uICsgMX1gO1xuICB9XG5cbiAgaGFuZGxlRXhwb3J0KGhpZGVDb2x1bW5zOiBib29sZWFuKSB7XG4gICAgdGhpcy5leHBvcnRJblByb2dyZXNzID0gaGlkZUNvbHVtbnM7XG4gIH1cbn1cbiIsIjxtYXQtY2FyZCBjbGFzcz1cIm1iLTNcIj5cbiAgPG1hdC1jYXJkLWNvbnRlbnQ+XG4gICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmaWx0ZXJGb3JtXCIgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgIDxoMyBjbGFzcz1cIm1iLTBcIj5Qcm9kdWN0czwvaDM+XG4gICAgICAgIDxhcHAtcHJvZHVjdC1mb3JtLWJ1dHRvbj48L2FwcC1wcm9kdWN0LWZvcm0tYnV0dG9uPlxuICAgICAgICA8c3BhbiBtYXRUb29sdGlwPVwiSW1wb3J0XCIgcm91dGVyTGluaz1cImltcG9ydFwiIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXIgbWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPlxuICAgICAgICAgIGZpbGVfdXBsb2FkXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPGFwcC1leHBvcnQtdG8tZXhjZWwtYnV0dG9uIHRhYmxlSWQ9XCJwcm9kdWN0VGFibGVcIiBmaWxlTmFtZT1cInByb2R1Y3RzXCIgKG9uRXhwb3J0U3RhcnQpPVwiaGFuZGxlRXhwb3J0KHRydWUpXCJcbiAgICAgICAgICAob25FeHBvcnRFbmQpPVwiaGFuZGxlRXhwb3J0KGZhbHNlKVwiPlxuICAgICAgICA8L2FwcC1leHBvcnQtdG8tZXhjZWwtYnV0dG9uPlxuICAgICAgICA8YXBwLWNvbHVtbi1zZWxlY3RvciBtb2RlPVwiaWNvblwiIGNsYXNzPVwiZC1wcmludC1ub25lXCIgW2NvbHVtbkNvbmZpZ3NdPVwiY29sdW1uQ29uZmlnXCJcbiAgICAgICAgICBbKHNlbGVjdGVkQ29sdW1ucyldPVwic2VsZWN0ZWRDb2x1bW5zXCI+PC9hcHAtY29sdW1uLXNlbGVjdG9yPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LXN0YXJ0IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9J2ZsLW1kJz5cbiAgICAgICAgICA8bWF0LWxhYmVsPlNlYXJjaDwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIlNlYXJjaCBwcm9kdWN0c1wiIGZvcm1Db250cm9sTmFtZT1cInNlYXJjaFwiIC8+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPSdmbC1zbSc+XG4gICAgICAgICAgPG1hdC1sYWJlbD5DYXRlZ29yeTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9XCJhcGkvcHJvZHVjdC1jYXRlZ29yaWVzXCIgZm9ybUNvbnRyb2xOYW1lPVwiY2F0ZWdvcnlfaWRzXCIgW211bHRpcGxlXT1cInRydWVcIj5cbiAgICAgICAgICA8L2FwcC1zZWFyY2hhYmxlLXNlbGVjdG9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz0nZmwtc20nPlxuICAgICAgICAgIDxtYXQtbGFiZWw+VHlwZTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9XCJhcGkvcHJvZHVjdC10eXBlc1wiIGZvcm1Db250cm9sTmFtZT1cInR5cGVfaWRzXCIgdGl0bGVGaWVsZD1cInRpdGxlXCJcbiAgICAgICAgICAgIFttdWx0aXBsZV09XCJ0cnVlXCI+XG4gICAgICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZm9ybT5cbiAgPC9tYXQtY2FyZC1jb250ZW50PlxuPC9tYXQtY2FyZD5cblxuPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtc3RhcnQgZ2FwLTNcIj5cbiAgPG1hdC1jYXJkIFtjbGFzcy5mbGV4LWZpbGxdPVwiIXNlbGVjdGlvbi5pc0VtcHR5KClcIiBbY2xhc3Mudy0xMDBdPVwic2VsZWN0aW9uLmlzRW1wdHkoKVwiPlxuICAgIDxtYXQtY2FyZC1jb250ZW50IGNsYXNzPVwicC0wXCI+XG4gICAgICA8dGFibGUgbWF0LXRhYmxlIFtkYXRhU291cmNlXT1cIm1vZGVsc1wiIGNsYXNzPVwidy0xMDBcIiBpbmZpbml0ZVNjcm9sbCBbaW5maW5pdGVTY3JvbGxEaXN0YW5jZV09XCIyXCJcbiAgICAgICAgW2luZmluaXRlU2Nyb2xsVGhyb3R0bGVdPVwiNTBcIiAoc2Nyb2xsZWQpPVwib25TY3JvbGwoKVwiIFtmcm9tUm9vdF09XCJ0cnVlXCIgbWF0U29ydFxuICAgICAgICAobWF0U29ydENoYW5nZSk9XCJzb3J0Q29sdW1uKCRldmVudClcIiBtYXRTb3J0RGlzYWJsZUNsZWFyPVwidHJ1ZVwiIGFyaWEtZGVzY3JpYmVkYnk9XCJQcm9kdWN0cyBMaXN0XCJcbiAgICAgICAgaWQ9XCJwcm9kdWN0VGFibGVcIj5cbiAgICAgICAgPCEtLSAjIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCIjXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj4jPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudDsgbGV0IGkgPSBpbmRleFwiPnt7IGkgKyAxIH19PC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBOYW1lIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJuYW1lXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXIgKm1hdEhlYWRlckNlbGxEZWY+TmFtZTwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTFcIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWRhcmtcIiBbcm91dGVyTGlua109XCJbZWxlbWVudD8uaWQsICd2aWV3J11cIj57eyBlbGVtZW50Lm5hbWUgfX08L2E+XG4gICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCIgKm5nSWY9XCJlbGVtZW50LnR5cGUgJiYgIWV4cG9ydEluUHJvZ3Jlc3NcIj5cbiAgICAgICAgICAgICAgICB7eyBlbGVtZW50LnR5cGU/LnRpdGxlIH19XG4gICAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFR5cGUgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInR5cGVcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIG1hdC1zb3J0LWhlYWRlciAqbWF0SGVhZGVyQ2VsbERlZj5UeXBlPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAge3sgZWxlbWVudD8udHlwZT8udGl0bGUgfX1cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIENhdGVnb3JpZXMgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNhdGVnb3JpZXNcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkNhdGVnb3JpZXM8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCIgc3R5bGU9XCJtYXgtd2lkdGg6IDIwMHB4XCI+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZWxlbWVudD8uY2F0ZWdvcmllcz8ubGVuZ3RoID4gMFwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1zdGFydCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTEgZmxleC13cmFwXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCIgKm5nRm9yPVwibGV0IGNhdGVnb3J5IG9mIGVsZW1lbnQ/LmNhdGVnb3JpZXNcIj5cbiAgICAgICAgICAgICAgICB7eyBjYXRlZ29yeT8udGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBTS1UgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNrdVwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPlNLVTwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50LnNrdSB9fTwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZGVzY3JpcHRpb25cIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIG1hdC1zb3J0LWhlYWRlciAqbWF0SGVhZGVyQ2VsbERlZj5EZXNjcmlwdGlvbjwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50LmRlc2NyaXB0aW9uIH19PC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBJbml0aWFsIFF1YW50aXR5IENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJpbml0aWFsX3F1YW50aXR5XCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXIgKm1hdEhlYWRlckNlbGxEZWY+SW5pdGlhbCBRdWFudGl0eTwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMFwiPnt7IGVsZW1lbnQuaW5pdGlhbF9xdWFudGl0eSB9fTwvcD5cbiAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCIgKm5nSWY9XCJlbGVtZW50Py5pbml0aWFsX3F1YW50aXR5X2RhdGVcIj5cbiAgICAgICAgICAgICAgb24ge3sgZWxlbWVudD8uaW5pdGlhbF9xdWFudGl0eV9kYXRlIHwgZGF0ZSB9fVxuICAgICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFN0b2NrIFJlY2VpcHRzIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzdG9ja19yZWNlaXB0c1wiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyPVwic3RvY2tfcmVjZWlwdHNfc3VtX3F1YW50aXR5XCIgKm1hdEhlYWRlckNlbGxEZWY+U3RvY2sgUmVjZWlwdHM8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIj57eyBlbGVtZW50Py5zdG9ja19yZWNlaXB0c19zdW1fcXVhbnRpdHkgfX08L3A+XG4gICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiICpuZ0lmPVwiZWxlbWVudD8ubGFzdF9zdG9ja19yZWNlaXB0ICYmICFleHBvcnRJblByb2dyZXNzXCI+XG4gICAgICAgICAgICAgIExhdGVzdCBvbiB7eyBlbGVtZW50Py5sYXN0X3N0b2NrX3JlY2VpcHQ/LmRhdGUgfCBkYXRlIH19XG4gICAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gU3RvY2sgSXNzdWVzIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzdG9ja19pc3N1ZXNcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIG1hdC1zb3J0LWhlYWRlcj1cInN0b2NrX2lzc3Vlc19zdW1fcXVhbnRpdHlcIiAqbWF0SGVhZGVyQ2VsbERlZj5TdG9jayBJc3N1ZXM8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIj57eyBlbGVtZW50Py5zdG9ja19pc3N1ZXNfc3VtX3F1YW50aXR5IH19PC9wPlxuICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIiAqbmdJZj1cImVsZW1lbnQ/Lmxhc3Rfc3RvY2tfaXNzdWUgJiYgIWV4cG9ydEluUHJvZ3Jlc3NcIj5cbiAgICAgICAgICAgICAgTGF0ZXN0IG9uIHt7IGVsZW1lbnQ/Lmxhc3Rfc3RvY2tfaXNzdWU/LmRhdGUgfCBkYXRlIH19XG4gICAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gT24gSGFuZCBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwib25faGFuZFwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyPSdzdG9ja19vbl9oYW5kJyAqbWF0SGVhZGVyQ2VsbERlZj5PbiBIYW5kPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAge3sgZWxlbWVudD8uc3RvY2tfb25faGFuZCB9fVxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibWVhc3VyZVwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPk1lYXN1cmU8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5tZWFzdXJlPy50aXRsZSB9fVxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gUmVvcmRlciBQb2ludCBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicmVvcmRlcl9wb2ludFwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPlJlb3JkZXIgUG9pbnQ8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50LnJlb3JkZXJfcG9pbnQgfX1cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFNlbGxpbmcgUHJpY2UgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNhbGVfcHJpY2VcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIG1hdC1zb3J0LWhlYWRlciAqbWF0SGVhZGVyQ2VsbERlZj5TZWxsaW5nIFByaWNlPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAge3sgZWxlbWVudC5zYWxlX3ByaWNlIHwgY3VycmVuY3kgfX1cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIEluY29tZSBBY2NvdW50IENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJpbmNvbWVfYWNjb3VudFwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+SW5jb21lIEFjY291bnQ8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5pbmNvbWVfYWNjb3VudD8udGl0bGUgfX1cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIEV4cGVuc2UgQWNjb3VudCBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZXhwZW5zZV9hY2NvdW50XCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5FeHBlbnNlIEFjY291bnQ8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5leHBlbnNlX2FjY291bnQ/LnRpdGxlIH19XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBDcmVhdG9yIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJjcmVhdG9yXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5DcmVhdG9yPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCI+e3sgZWxlbWVudD8uY3JlYXRvcj8ubmFtZSB9fTwvcD5cbiAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCI+e3sgZWxlbWVudD8uY3JlYXRlZF9hdCB8IGRhdGUgfX08L3NtYWxsPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gQWN0aW9ucyBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiQWN0aW9uc1wiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+QWN0aW9uczwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeSBkLWZsZXggZ2FwLTFcIj5cbiAgICAgICAgICAgICAgPGFwcC10ZWNobGlmeS1pY29uIG5hbWU9J3ZpZXcnIFtyb3V0ZXJMaW5rXT1cIltlbGVtZW50LmlkLCAndmlldyddXCJcbiAgICAgICAgICAgICAgICByb3V0ZXJMaW5rQWN0aXZlPVwicm91dGUtbGluay1hY3RpdmVcIj48L2FwcC10ZWNobGlmeS1pY29uPlxuXG4gICAgICAgICAgICAgIDxhcHAtcHJvZHVjdC1mb3JtLWJ1dHRvbiBbcHJvZHVjdF09XCJlbGVtZW50XCI+PC9hcHAtcHJvZHVjdC1mb3JtLWJ1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiU2VsZWN0XCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCIkZXZlbnQgPyB0b2dnbGVBbGxSb3dzKCkgOiBudWxsXCJcbiAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgaXNBbGxSb3dzU2VsZWN0ZWQoKVwiXG4gICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cInNlbGVjdGlvbi5oYXNWYWx1ZSgpICYmICFpc0FsbFJvd3NTZWxlY3RlZCgpXCIgW2FyaWEtbGFiZWxdPVwiY2hlY2tib3hMYWJlbCgpXCI+XG4gICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIj5cbiAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChjaGFuZ2UpPVwiJGV2ZW50ID8gc2VsZWN0aW9uLnRvZ2dsZShyb3cpIDogbnVsbFwiXG4gICAgICAgICAgICAgIFtjaGVja2VkXT1cInNlbGVjdGlvbi5pc1NlbGVjdGVkKHJvdylcIiBbYXJpYS1sYWJlbF09XCJjaGVja2JveExhYmVsKHJvdylcIj5cbiAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkIG1hdC1mb290ZXItY2VsbCAqbWF0Rm9vdGVyQ2VsbERlZj48L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPHRyIG1hdC1oZWFkZXItcm93ICptYXRIZWFkZXJSb3dEZWY9XCJkaXNwbGF5ZWRDb2x1bW5zOyBzdGlja3k6IHRydWVcIj48L3RyPlxuICAgICAgICA8dHIgbWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICA8L3RhYmxlPlxuXG4gICAgICA8bWF0LXByb2dyZXNzLWJhciBtb2RlPVwiaW5kZXRlcm1pbmF0ZVwiICpuZ0lmPVwiaXNXb3JraW5nXCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICAgIDwvbWF0LWNhcmQtY29udGVudD5cbiAgPC9tYXQtY2FyZD5cbiAgPG1hdC1jYXJkICpuZ0lmPVwiIXNlbGVjdGlvbi5pc0VtcHR5KClcIiBjbGFzcz1cImJhdGNoLXVwZGF0ZS1jYXJkXCI+XG4gICAgPG1hdC1jYXJkLWNvbnRlbnQ+XG4gICAgICA8YXBwLXByb2R1Y3QtYmF0Y2gtdXBkYXRlLWZvcm0gW3NlbGVjdGlvbl09XCJzZWxlY3Rpb25cIiAodXBkYXRlZCk9XCJyZWxvYWQoKVwiPjwvYXBwLXByb2R1Y3QtYmF0Y2gtdXBkYXRlLWZvcm0+XG4gICAgPC9tYXQtY2FyZC1jb250ZW50PlxuICA8L21hdC1jYXJkPlxuPC9kaXY+Il19
|
|
177
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZHVjdC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3Byb2R1Y3QvcHJvZHVjdC1saXN0L3Byb2R1Y3QtbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pbnZlbnRvcnktY29tbW9uL3NyYy9saWIvaW52ZW50b3J5LWNvbW1vbi9wcm9kdWN0L3Byb2R1Y3QtbGlzdC9wcm9kdWN0LWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFJbEQsT0FBTyxFQUFnQixxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXhFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPbkQsSUFBTSxvQkFBb0IsR0FBMUIsTUFBTSxvQkFBcUIsU0FBUSxxQkFBcUI7SUE0Q25EO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUE5Q1YsU0FBUyxHQUFHLElBQUksY0FBYyxDQUFNLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUU5QyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7SUFFekIsWUFBWSxHQUFtQjtRQUM3QixFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUU7UUFDN0QsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsVUFB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QUFDO0lBRUQsYUFBYSxDQUFDLEdBQVM7UUFDckIsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ1QsT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsTUFBTSxDQUFDO1FBQ25FLENBQUM7UUFDRCxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxRQUFRLEdBQUcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLENBQUM7SUFDN0YsQ0FBQztJQUVELFlBQVksQ0FBQyxXQUFvQjtRQUMvQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDO0lBQ3RDLENBQUM7d0dBdkpVLG9CQUFvQjs0RkFBcEIsb0JBQW9CLCtFQ2hCakMsODhVQXVPTTs7QUR2Tk8sb0JBQW9CO0lBTmhDLFlBQVksRUFBRTtHQU1GLG9CQUFvQixDQXdKaEM7OzRGQXhKWSxvQkFBb0I7a0JBTGhDLFNBQVM7K0JBQ0Usa0JBQWtCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IENvbHVtbkNvbmZpZywgVGVjaGxpZnlMaXN0Q29tcG9uZW50IH0gZnJvbSAnbmd4LXRlY2hsaWZ5LWNvcmUnO1xuaW1wb3J0IHsgUHJvZHVjdFNlcnZpY2UgfSBmcm9tICcuLi9wcm9kdWN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgVW50aWxEZXN0cm95IH0gZnJvbSAnQG5nbmVhdC91bnRpbC1kZXN0cm95JztcbmltcG9ydCB7IGRlYm91bmNlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFByb2R1Y3RGb3JtU2VydmljZSB9IGZyb20gJy4uL3Byb2R1Y3QtZm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IFNlbGVjdGlvbk1vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcbkBVbnRpbERlc3Ryb3koKVxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXByb2R1Y3QtbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9wcm9kdWN0LWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wcm9kdWN0LWxpc3QuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgUHJvZHVjdExpc3RDb21wb25lbnQgZXh0ZW5kcyBUZWNobGlmeUxpc3RDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25Nb2RlbDxhbnk+KHRydWUsIFtdKTtcblxuICBleHBvcnRJblByb2dyZXNzID0gZmFsc2U7XG5cbiAgY29sdW1uQ29uZmlnOiBDb2x1bW5Db25maWdbXSA9IFtcbiAgICB7IGxhYmVsOiAnIycsIGRlZjogJyMnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdOYW1lJywgZGVmOiAnbmFtZScsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1NLVScsIGRlZjogJ3NrdScsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ0F2ZXJhZ2UgQ29zdCcsIGRlZjogJ2F2ZXJhZ2VfY29zdCcsIGlzU2VsZWN0ZWQ6IGZhbHNlLCBpc0VkaXRhYmxlOiB0cnVlIH0sXG4gICAgeyBsYWJlbDogJ0NhdGVnb3JpZXMnLCBkZWY6ICdjYXRlZ29yaWVzJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnRGVzY3JpcHRpb24nLCBkZWY6ICdkZXNjcmlwdGlvbicsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlLCBpc0V4cG9ydGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1Jlb3JkZXIgUG9pbnQnLCBkZWY6ICdyZW9yZGVyX3BvaW50JywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnU3RvY2sgUmVjZWlwdHMnLCBkZWY6ICdzdG9ja19yZWNlaXB0cycsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1N0b2NrIElzc3VlcycsIGRlZjogJ3N0b2NrX2lzc3VlcycsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ09uIEhhbmQnLCBkZWY6ICdvbl9oYW5kJywgaXNTZWxlY3RlZDogdHJ1ZSwgaXNFZGl0YWJsZTogZmFsc2UgfSxcbiAgICB7IGxhYmVsOiAnTWVhc3VyZScsIGRlZjogJ21lYXN1cmUnLCBpc1NlbGVjdGVkOiB0cnVlLCBpc0VkaXRhYmxlOiBmYWxzZSB9LFxuICAgIHsgbGFiZWw6ICdTYWxlIFByaWNlJywgZGVmOiAnc2FsZV9wcmljZScsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1R5cGUnLCBkZWY6ICd0eXBlJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IGZhbHNlLCBpc0V4cG9ydGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnSW5pdGlhbCBRdWFudGl0eScsIGRlZjogJ2luaXRpYWxfcXVhbnRpdHknLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdJbmNvbWUgQWNjb3VudCcsIGRlZjogJ2luY29tZV9hY2NvdW50JywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnRXhwZW5zZSBBY2NvdW50JywgZGVmOiAnZXhwZW5zZV9hY2NvdW50JywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgICB7IGxhYmVsOiAnQ3JlYXRvcicsIGRlZjogJ2NyZWF0b3InLCBpc1NlbGVjdGVkOiBmYWxzZSwgaXNFZGl0YWJsZTogdHJ1ZSB9LFxuICAgIHsgbGFiZWw6ICdBY3Rpb25zJywgZGVmOiAnQWN0aW9ucycsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlLCBpc0V4cG9ydGFibGU6IGZhbHNlIH0sXG4gICAgeyBsYWJlbDogJ1NlbGVjdCcsIGRlZjogJ1NlbGVjdCcsIGlzU2VsZWN0ZWQ6IHRydWUsIGlzRWRpdGFibGU6IGZhbHNlLCBpc0V4cG9ydGFibGU6IGZhbHNlIH0sXG4gIF07XG5cbiAgc2VsZWN0ZWRDb2x1bW5zOiBDb2x1bW5Db25maWdbXSA9IHRoaXMuY29sdW1uQ29uZmlnLmZpbHRlcigoY29sKSA9PiBjb2wuaXNTZWxlY3RlZCk7XG5cbiAgZ2V0IGRpc3BsYXllZENvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHNlbGVjdGVkRGVmcyA9IG5ldyBTZXQodGhpcy5zZWxlY3RlZENvbHVtbnMubWFwKGNvbCA9PiBjb2wuZGVmKSk7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1uQ29uZmlnLmZpbHRlcihjb2wgPT4ge1xuICAgICAgaWYgKHRoaXMuZXhwb3J0SW5Qcm9ncmVzcykge1xuICAgICAgICBpZiAoY29sLmlzRXhwb3J0YWJsZSA9PT0gdHJ1ZSkgcmV0dXJuIHRydWU7XG4gICAgICAgIGlmIChjb2wuaXNFeHBvcnRhYmxlID09PSBmYWxzZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNlbGVjdGVkRGVmcy5oYXMoY29sLmRlZik7XG4gICAgfSkubWFwKGNvbCA9PiBjb2wuZGVmKTtcbiAgfVxuXG4gIGltcG9ydElkITogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZmI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSBwcm9kdWN0U2VydmljZTogUHJvZHVjdFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwcm9kdWN0Rm9ybVNlcnZpY2U6IFByb2R1Y3RGb3JtU2VydmljZVxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuZmlsdGVyRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgY2F0ZWdvcnlfaWRzOiBbJyddLFxuICAgICAgZXhwZW5zZV9hY2NvdW50X2lkczogWycnXSxcbiAgICAgIGluY29tZV9hY2NvdW50X2lkczogWycnXSxcbiAgICAgIG1lYXN1cmVfaWRzOiBbJyddLFxuICAgICAgc2VhcmNoOiBbJyddLFxuICAgICAgc29ydF9ieTogWycnXSxcbiAgICAgIHR5cGVfaWRzOiBbJyddLFxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWN0aXZhdGVkUm91dGUuc25hcHNob3QucXVlcnlQYXJhbXM/LlsnaW1wb3J0X2lkJ10pIHtcbiAgICAgIHRoaXMuaW1wb3J0SWQgPSBwYXJzZUludCh0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zPy5bJ2ltcG9ydF9pZCddKTtcbiAgICB9XG4gICAgLy8gdXBkYXRlIGZvcm0gd2l0aCBVUkwgcXVlcnkgcGFyYW1zXG4gICAgdGhpcy5yZXF1ZXN0SGVscGVyU2VydmljZS51cGRhdGVGb3JtV2l0aFF1ZXJ5UGFyYW1zKHRoaXMuZmlsdGVyRm9ybSwge1xuICAgICAgdHlwZV9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIGNhdGVnb3J5X2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgICAgaW5jb21lX2FjY291bnRfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBleHBlbnNlX2FjY291bnRfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgfSk7XG4gICAgLy8gVXBkYXRlIFVSTCBxdWVyeSBwYXJhbXMgb24gZmlsdGVyIGNoYW5nZVxuICAgIHRoaXMuZmlsdGVyRm9ybS52YWx1ZUNoYW5nZXMucGlwZShkZWJvdW5jZVRpbWUoODAwKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UudXBkYXRlUXVlcnlQYXJhbXMoXG4gICAgICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UuY29udmVydFRvRm9ybURhdGEoe1xuICAgICAgICAgIC4uLnRoaXMuZmlsdGVyRm9ybS52YWx1ZSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gICAgLy8gZmV0Y2ggdGFzayBvbiBwYXJhbXMgY2hhbmdlXG4gICAgdGhpcy5hY3RpdmF0ZWRSb3V0ZS5xdWVyeVBhcmFtcy5waXBlKGRlYm91bmNlVGltZSg4MDApKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5yZWxvYWQoKSk7XG4gICAgLy8gbGlzdGVuIGZvcm0gcHJvZHVjdCBhZGQgb3IgdXBkYXRlIGV2ZW50IGFuZCByZWxvYWQuXG4gICAgdGhpcy5wcm9kdWN0Rm9ybVNlcnZpY2UuaXNMaXN0VXBkYXRlZCgpLnN1YnNjcmliZSgodmFsOiBib29sZWFuKSA9PiB7XG4gICAgICBpZiAodmFsICYmICF0aGlzLmlzV29ya2luZykge1xuICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb3ZlcnJpZGUgbG9hZERhdGEoKSB7XG4gICAgbGV0IHBhcmFtczogYW55ID0ge1xuICAgICAgLi4udGhpcy5yZXF1ZXN0SGVscGVyU2VydmljZS5jb252ZXJ0VG9Gb3JtRGF0YSh0aGlzLmZpbHRlckZvcm0udmFsdWUpLFxuICAgIH07XG4gICAgcGFyYW1zLnBhZ2UgPSB0aGlzLnBhZ2U7XG4gICAgcGFyYW1zLnBlclBhZ2UgPSB0aGlzLnBlclBhZ2U7XG4gICAgcGFyYW1zLndpdGggPSAnY2F0ZWdvcmllcyxsYXN0U3RvY2tSZWNlaXB0LGxhc3RTdG9ja0lzc3VlLG1lYXN1cmUsY3JlYXRvcic7XG4gICAgaWYgKHRoaXMuaW1wb3J0SWQpIHtcbiAgICAgIHBhcmFtcy5pbXBvcnRfaWQgPSB0aGlzLmltcG9ydElkO1xuICAgIH1cbiAgICB0aGlzLmlzV29ya2luZyA9IHRydWU7XG5cbiAgICB0aGlzLnByb2R1Y3RTZXJ2aWNlLmluZGV4KHBhcmFtcykuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmlzV29ya2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm1vZGVscyA9IHRoaXMubW9kZWxzLmNvbmNhdChyZXM/LmRhdGEpO1xuICAgICAgICB0aGlzLmxhc3RQYWdlID0gcmVzPy5sYXN0X3BhZ2U7XG4gICAgICAgIC8vIHN0b3AgcmVsb2FkaW5nIGRhdGEgb25jZSBkYXRhIGxvYWRlZC5cbiAgICAgICAgdGhpcy5wcm9kdWN0Rm9ybVNlcnZpY2UubGlzdFVwZGF0ZWQoZmFsc2UpO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiAodGhpcy5pc1dvcmtpbmcgPSBmYWxzZSksXG4gICAgfSk7XG4gIH1cblxuICBhc3NpZ25GaWx0ZXIoY29sdW1uOiBhbnksIGRpcmVjdGlvbjogc3RyaW5nKSB7XG4gICAgaWYgKGNvbHVtbikge1xuICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyRm9ybS5nZXQoJ3NvcnRfYnknKT8uc2V0VmFsdWUoY29sdW1uICsgJ3wnICsgZGlyZWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZSBzb3J0Q29sdW1uKGV2ZW50OiBhbnkpIHtcbiAgICB2YXIgZGlyZWN0aW9uID0gZXZlbnQuZGlyZWN0aW9uLnRvU3RyaW5nKCkudG9VcHBlckNhc2UoKTtcbiAgICB0aGlzLmFzc2lnbkZpbHRlcihldmVudC5hY3RpdmUsIGRpcmVjdGlvbik7XG4gIH1cblxuICBpc0FsbFJvd3NTZWxlY3RlZCgpIHtcbiAgICBjb25zdCBudW1TZWxlY3RlZCA9IHRoaXMuc2VsZWN0aW9uLnNlbGVjdGVkLmxlbmd0aDtcbiAgICBjb25zdCBudW1Sb3dzID0gdGhpcy5tb2RlbHMubGVuZ3RoO1xuICAgIHJldHVybiBudW1TZWxlY3RlZCA9PT0gbnVtUm93cztcbiAgfVxuXG4gIC8qKiBTZWxlY3RzIGFsbCByb3dzIGlmIHRoZXkgYXJlIG5vdCBhbGwgc2VsZWN0ZWQ7IG90aGVyd2lzZSBjbGVhciBzZWxlY3Rpb24uICovXG4gIHRvZ2dsZUFsbFJvd3MoKSB7XG4gICAgaWYgKHRoaXMuaXNBbGxSb3dzU2VsZWN0ZWQoKSkge1xuICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGlvbi5zZWxlY3QoLi4udGhpcy5tb2RlbHMpO1xuICB9XG5cbiAgY2hlY2tib3hMYWJlbChyb3c/OiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghcm93KSB7XG4gICAgICByZXR1cm4gYCR7dGhpcy5pc0FsbFJvd3NTZWxlY3RlZCgpID8gJ2Rlc2VsZWN0JyA6ICdzZWxlY3QnfSBhbGxgO1xuICAgIH1cbiAgICByZXR1cm4gYCR7dGhpcy5zZWxlY3Rpb24uaXNTZWxlY3RlZChyb3cpID8gJ2Rlc2VsZWN0JyA6ICdzZWxlY3QnfSByb3cgJHtyb3cucG9zaXRpb24gKyAxfWA7XG4gIH1cblxuICBoYW5kbGVFeHBvcnQoaGlkZUNvbHVtbnM6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmV4cG9ydEluUHJvZ3Jlc3MgPSBoaWRlQ29sdW1ucztcbiAgfVxufVxuIiwiPG1hdC1jYXJkIGNsYXNzPVwibWItM1wiPlxuICA8bWF0LWNhcmQtY29udGVudD5cbiAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZpbHRlckZvcm1cIiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlciBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgICAgPGgzIGNsYXNzPVwibWItMFwiPlByb2R1Y3RzPC9oMz5cbiAgICAgICAgPGFwcC1wcm9kdWN0LWZvcm0tYnV0dG9uPjwvYXBwLXByb2R1Y3QtZm9ybS1idXR0b24+XG4gICAgICAgIDxzcGFuIG1hdFRvb2x0aXA9XCJJbXBvcnRcIiByb3V0ZXJMaW5rPVwiaW1wb3J0XCIgY2xhc3M9XCJjdXJzb3ItcG9pbnRlciBtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkXCI+XG4gICAgICAgICAgZmlsZV91cGxvYWRcbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8YXBwLWV4cG9ydC10by1leGNlbC1idXR0b24gdGFibGVJZD1cInByb2R1Y3RUYWJsZVwiIGZpbGVOYW1lPVwicHJvZHVjdHNcIiAob25FeHBvcnRTdGFydCk9XCJoYW5kbGVFeHBvcnQodHJ1ZSlcIlxuICAgICAgICAgIChvbkV4cG9ydEVuZCk9XCJoYW5kbGVFeHBvcnQoZmFsc2UpXCI+XG4gICAgICAgIDwvYXBwLWV4cG9ydC10by1leGNlbC1idXR0b24+XG4gICAgICAgIDxhcHAtY29sdW1uLXNlbGVjdG9yIG1vZGU9XCJpY29uXCIgY2xhc3M9XCJkLXByaW50LW5vbmVcIiBbY29sdW1uQ29uZmlnc109XCJjb2x1bW5Db25maWdcIlxuICAgICAgICAgIFsoc2VsZWN0ZWRDb2x1bW5zKV09XCJzZWxlY3RlZENvbHVtbnNcIj48L2FwcC1jb2x1bW4tc2VsZWN0b3I+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtc3RhcnQgYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz0nZmwtbWQnPlxuICAgICAgICAgIDxtYXQtbGFiZWw+U2VhcmNoPC9tYXQtbGFiZWw+XG4gICAgICAgICAgPGlucHV0IG1hdElucHV0IHBsYWNlaG9sZGVyPVwiU2VhcmNoIHByb2R1Y3RzXCIgZm9ybUNvbnRyb2xOYW1lPVwic2VhcmNoXCIgLz5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9J2ZsLXNtJz5cbiAgICAgICAgICA8bWF0LWxhYmVsPkNhdGVnb3J5PC9tYXQtbGFiZWw+XG4gICAgICAgICAgPGFwcC1zZWFyY2hhYmxlLXNlbGVjdG9yIGFwaVVybD1cImFwaS9wcm9kdWN0LWNhdGVnb3JpZXNcIiBmb3JtQ29udHJvbE5hbWU9XCJjYXRlZ29yeV9pZHNcIiBbbXVsdGlwbGVdPVwidHJ1ZVwiPlxuICAgICAgICAgIDwvYXBwLXNlYXJjaGFibGUtc2VsZWN0b3I+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPSdmbC1zbSc+XG4gICAgICAgICAgPG1hdC1sYWJlbD5UeXBlPC9tYXQtbGFiZWw+XG4gICAgICAgICAgPGFwcC1zZWFyY2hhYmxlLXNlbGVjdG9yIGFwaVVybD1cImFwaS9wcm9kdWN0LXR5cGVzXCIgZm9ybUNvbnRyb2xOYW1lPVwidHlwZV9pZHNcIiB0aXRsZUZpZWxkPVwidGl0bGVcIlxuICAgICAgICAgICAgW211bHRpcGxlXT1cInRydWVcIj5cbiAgICAgICAgICA8L2FwcC1zZWFyY2hhYmxlLXNlbGVjdG9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgPC9kaXY+XG4gICAgPC9mb3JtPlxuICA8L21hdC1jYXJkLWNvbnRlbnQ+XG48L21hdC1jYXJkPlxuXG48ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1zdGFydCBnYXAtM1wiPlxuICA8bWF0LWNhcmQgW2NsYXNzLmZsZXgtZmlsbF09XCIhc2VsZWN0aW9uLmlzRW1wdHkoKVwiIFtjbGFzcy53LTEwMF09XCJzZWxlY3Rpb24uaXNFbXB0eSgpXCI+XG4gICAgPG1hdC1jYXJkLWNvbnRlbnQgY2xhc3M9XCJwLTBcIj5cbiAgICAgIDx0YWJsZSBtYXQtdGFibGUgW2RhdGFTb3VyY2VdPVwibW9kZWxzXCIgY2xhc3M9XCJ3LTEwMFwiIGluZmluaXRlU2Nyb2xsIFtpbmZpbml0ZVNjcm9sbERpc3RhbmNlXT1cIjJcIlxuICAgICAgICBbaW5maW5pdGVTY3JvbGxUaHJvdHRsZV09XCI1MFwiIChzY3JvbGxlZCk9XCJvblNjcm9sbCgpXCIgW2Zyb21Sb290XT1cInRydWVcIiBtYXRTb3J0XG4gICAgICAgIChtYXRTb3J0Q2hhbmdlKT1cInNvcnRDb2x1bW4oJGV2ZW50KVwiIG1hdFNvcnREaXNhYmxlQ2xlYXI9XCJ0cnVlXCIgYXJpYS1kZXNjcmliZWRieT1cIlByb2R1Y3RzIExpc3RcIlxuICAgICAgICBpZD1cInByb2R1Y3RUYWJsZVwiPlxuICAgICAgICA8IS0tICMgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIiNcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPiM8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50OyBsZXQgaSA9IGluZGV4XCI+e3sgaSArIDEgfX08L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIE5hbWUgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm5hbWVcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIG1hdC1zb3J0LWhlYWRlciAqbWF0SGVhZGVyQ2VsbERlZj5OYW1lPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtbiBnYXAtMVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cInRleHQtZGVjb3JhdGlvbi1ub25lIHRleHQtZGFya1wiIFtyb3V0ZXJMaW5rXT1cIltlbGVtZW50Py5pZCwgJ3ZpZXcnXVwiPnt7IGVsZW1lbnQubmFtZSB9fTwvYT5cbiAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIiAqbmdJZj1cImVsZW1lbnQudHlwZSAmJiAhZXhwb3J0SW5Qcm9ncmVzc1wiPlxuICAgICAgICAgICAgICAgIHt7IGVsZW1lbnQudHlwZT8udGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gVHlwZSBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwidHlwZVwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPlR5cGU8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py50eXBlPy50aXRsZSB9fVxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gQ2F0ZWdvcmllcyBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiY2F0ZWdvcmllc1wiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+Q2F0ZWdvcmllczwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIiBzdHlsZT1cIm1heC13aWR0aDogMjAwcHhcIj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJlbGVtZW50Py5jYXRlZ29yaWVzPy5sZW5ndGggPiAwXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LXN0YXJ0IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMSBmbGV4LXdyYXBcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zZWNvbmRhcnlcIiAqbmdGb3I9XCJsZXQgY2F0ZWdvcnkgb2YgZWxlbWVudD8uY2F0ZWdvcmllc1wiPlxuICAgICAgICAgICAgICAgIHt7IGNhdGVnb3J5Py50aXRsZSB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFNLVSBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic2t1XCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXIgKm1hdEhlYWRlckNlbGxEZWY+U0tVPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQuc2t1IH19PC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBBdmVyYWdlIENvc3QgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImF2ZXJhZ2VfY29zdFwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPkF2ZXJhZ2UgQ29zdDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50LmF2ZXJhZ2VfY29zdCB8IGN1cnJlbmN5IH19PC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJkZXNjcmlwdGlvblwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPkRlc2NyaXB0aW9uPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQuZGVzY3JpcHRpb24gfX08L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIEluaXRpYWwgUXVhbnRpdHkgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImluaXRpYWxfcXVhbnRpdHlcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsIG1hdC1zb3J0LWhlYWRlciAqbWF0SGVhZGVyQ2VsbERlZj5Jbml0aWFsIFF1YW50aXR5PC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCI+e3sgZWxlbWVudC5pbml0aWFsX3F1YW50aXR5IH19PC9wPlxuICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIiAqbmdJZj1cImVsZW1lbnQ/LmluaXRpYWxfcXVhbnRpdHlfZGF0ZVwiPlxuICAgICAgICAgICAgICBvbiB7eyBlbGVtZW50Py5pbml0aWFsX3F1YW50aXR5X2RhdGUgfCBkYXRlIH19XG4gICAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gU3RvY2sgUmVjZWlwdHMgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInN0b2NrX3JlY2VpcHRzXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXI9XCJzdG9ja19yZWNlaXB0c19zdW1fcXVhbnRpdHlcIiAqbWF0SGVhZGVyQ2VsbERlZj5TdG9jayBSZWNlaXB0czwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMFwiPnt7IGVsZW1lbnQ/LnN0b2NrX3JlY2VpcHRzX3N1bV9xdWFudGl0eSB9fTwvcD5cbiAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCIgKm5nSWY9XCJlbGVtZW50Py5sYXN0X3N0b2NrX3JlY2VpcHQgJiYgIWV4cG9ydEluUHJvZ3Jlc3NcIj5cbiAgICAgICAgICAgICAgTGF0ZXN0IG9uIHt7IGVsZW1lbnQ/Lmxhc3Rfc3RvY2tfcmVjZWlwdD8uZGF0ZSB8IGRhdGUgfX1cbiAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBTdG9jayBJc3N1ZXMgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInN0b2NrX2lzc3Vlc1wiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyPVwic3RvY2tfaXNzdWVzX3N1bV9xdWFudGl0eVwiICptYXRIZWFkZXJDZWxsRGVmPlN0b2NrIElzc3VlczwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMFwiPnt7IGVsZW1lbnQ/LnN0b2NrX2lzc3Vlc19zdW1fcXVhbnRpdHkgfX08L3A+XG4gICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiICpuZ0lmPVwiZWxlbWVudD8ubGFzdF9zdG9ja19pc3N1ZSAmJiAhZXhwb3J0SW5Qcm9ncmVzc1wiPlxuICAgICAgICAgICAgICBMYXRlc3Qgb24ge3sgZWxlbWVudD8ubGFzdF9zdG9ja19pc3N1ZT8uZGF0ZSB8IGRhdGUgfX1cbiAgICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBPbiBIYW5kIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJvbl9oYW5kXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXI9J3N0b2NrX29uX2hhbmQnICptYXRIZWFkZXJDZWxsRGVmPk9uIEhhbmQ8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5zdG9ja19vbl9oYW5kIH19XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJtZWFzdXJlXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXIgKm1hdEhlYWRlckNlbGxEZWY+TWVhc3VyZTwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIHt7IGVsZW1lbnQ/Lm1lYXN1cmU/LnRpdGxlIH19XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBSZW9yZGVyIFBvaW50IENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJyZW9yZGVyX3BvaW50XCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCBtYXQtc29ydC1oZWFkZXIgKm1hdEhlYWRlckNlbGxEZWY+UmVvcmRlciBQb2ludDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIHt7IGVsZW1lbnQucmVvcmRlcl9wb2ludCB9fVxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gU2VsbGluZyBQcmljZSBDb2x1bW4gLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic2FsZV9wcmljZVwiPlxuICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgbWF0LXNvcnQtaGVhZGVyICptYXRIZWFkZXJDZWxsRGVmPlNlbGxpbmcgUHJpY2U8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50LnNhbGVfcHJpY2UgfCBjdXJyZW5jeSB9fVxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gSW5jb21lIEFjY291bnQgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImluY29tZV9hY2NvdW50XCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5JbmNvbWUgQWNjb3VudDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIHt7IGVsZW1lbnQ/LmluY29tZV9hY2NvdW50Py50aXRsZSB9fVxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gRXhwZW5zZSBBY2NvdW50IENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJleHBlbnNlX2FjY291bnRcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkV4cGVuc2UgQWNjb3VudDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICAgIHt7IGVsZW1lbnQ/LmV4cGVuc2VfYWNjb3VudD8udGl0bGUgfX1cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIENyZWF0b3IgQ29sdW1uIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNyZWF0b3JcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPkNyZWF0b3I8L3RoPlxuICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIj57eyBlbGVtZW50Py5jcmVhdG9yPy5uYW1lIH19PC9wPlxuICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1zZWNvbmRhcnlcIj57eyBlbGVtZW50Py5jcmVhdGVkX2F0IHwgZGF0ZSB9fTwvc21hbGw+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBBY3Rpb25zIENvbHVtbiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJBY3Rpb25zXCI+XG4gICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5BY3Rpb25zPC90aD5cbiAgICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtc2Vjb25kYXJ5IGQtZmxleCBnYXAtMVwiPlxuICAgICAgICAgICAgICA8YXBwLXRlY2hsaWZ5LWljb24gbmFtZT0ndmlldycgW3JvdXRlckxpbmtdPVwiW2VsZW1lbnQuaWQsICd2aWV3J11cIlxuICAgICAgICAgICAgICAgIHJvdXRlckxpbmtBY3RpdmU9XCJyb3V0ZS1saW5rLWFjdGl2ZVwiPjwvYXBwLXRlY2hsaWZ5LWljb24+XG5cbiAgICAgICAgICAgICAgPGFwcC1wcm9kdWN0LWZvcm0tYnV0dG9uIFtwcm9kdWN0XT1cImVsZW1lbnRcIj48L2FwcC1wcm9kdWN0LWZvcm0tYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJTZWxlY3RcIj5cbiAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlxuICAgICAgICAgICAgPG1hdC1jaGVja2JveCAoY2hhbmdlKT1cIiRldmVudCA/IHRvZ2dsZUFsbFJvd3MoKSA6IG51bGxcIlxuICAgICAgICAgICAgICBbY2hlY2tlZF09XCJzZWxlY3Rpb24uaGFzVmFsdWUoKSAmJiBpc0FsbFJvd3NTZWxlY3RlZCgpXCJcbiAgICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwic2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgIWlzQWxsUm93c1NlbGVjdGVkKClcIiBbYXJpYS1sYWJlbF09XCJjaGVja2JveExhYmVsKClcIj5cbiAgICAgICAgICAgIDwvbWF0LWNoZWNrYm94PlxuICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiPlxuICAgICAgICAgICAgPG1hdC1jaGVja2JveCAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgKGNoYW5nZSk9XCIkZXZlbnQgPyBzZWxlY3Rpb24udG9nZ2xlKHJvdykgOiBudWxsXCJcbiAgICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0aW9uLmlzU2VsZWN0ZWQocm93KVwiIFthcmlhLWxhYmVsXT1cImNoZWNrYm94TGFiZWwocm93KVwiPlxuICAgICAgICAgICAgPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQgbWF0LWZvb3Rlci1jZWxsICptYXRGb290ZXJDZWxsRGVmPjwvdGQ+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImRpc3BsYXllZENvbHVtbnM7IHN0aWNreTogdHJ1ZVwiPjwvdHI+XG4gICAgICAgIDx0ciBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBkaXNwbGF5ZWRDb2x1bW5zXCI+PC90cj5cbiAgICAgIDwvdGFibGU+XG5cbiAgICAgIDxtYXQtcHJvZ3Jlc3MtYmFyIG1vZGU9XCJpbmRldGVybWluYXRlXCIgKm5nSWY9XCJpc1dvcmtpbmdcIj48L21hdC1wcm9ncmVzcy1iYXI+XG4gICAgPC9tYXQtY2FyZC1jb250ZW50PlxuICA8L21hdC1jYXJkPlxuICA8bWF0LWNhcmQgKm5nSWY9XCIhc2VsZWN0aW9uLmlzRW1wdHkoKVwiIGNsYXNzPVwiYmF0Y2gtdXBkYXRlLWNhcmRcIj5cbiAgICA8bWF0LWNhcmQtY29udGVudD5cbiAgICAgIDxhcHAtcHJvZHVjdC1iYXRjaC11cGRhdGUtZm9ybSBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiICh1cGRhdGVkKT1cInJlbG9hZCgpXCI+PC9hcHAtcHJvZHVjdC1iYXRjaC11cGRhdGUtZm9ybT5cbiAgICA8L21hdC1jYXJkLWNvbnRlbnQ+XG4gIDwvbWF0LWNhcmQ+XG48L2Rpdj4iXX0=
|
package/esm2022/lib/inventory-common/product/product-view-page/product-view-page.component.mjs
CHANGED
|
@@ -66,7 +66,7 @@ export class ProductViewPageComponent {
|
|
|
66
66
|
this.location.back();
|
|
67
67
|
}
|
|
68
68
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProductViewPageComponent, deps: [{ token: i1.ProductService }, { token: i2.ActivatedRoute }, { token: i3.Location }], target: i0.ɵɵFactoryTarget.Component });
|
|
69
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProductViewPageComponent, selector: "app-product-view-page", viewQueries: [{ propertyName: "productLocationList", first: true, predicate: ["productLocationList"], descendants: true }, { propertyName: "stockTransferList", first: true, predicate: ["stockTransferList"], descendants: true }, { propertyName: "stockReceiptsListPage", first: true, predicate: ["stockReceiptsListPage"], descendants: true }, { propertyName: "stockIssueProductListPage", first: true, predicate: ["stockIssueProductListPage"], descendants: true }], ngImport: i0, template: "<mat-progress-bar mode=\"indeterminate\" *ngIf=\"isLoading\"></mat-progress-bar>\n\n<div *ngIf=\"product\" class=\"d-flex justify-content-start align-items-start gap-3 w-100\">\n <div *ngIf=\"product\" class=\"d-flex justify-content-start align-items-start gap-3 w-100\">\n <div style=\"width: calc(25% - 1rem)\" class=\"d-flex flex-column gap-3\">\n <app-product-basic-info [product]=\"product\" #productBasicInfoComponent (deleted)=\"onProductDeleted()\"\n (saved)=\"onProductUpdated($event)\"></app-product-basic-info>\n\n <app-product-location-list [product]=\"product\"\n (updated)=\"stockTransferList.reload(); stockIssueProductListPage.reload()\"\n #productLocationList></app-product-location-list>\n\n <app-note-list labelText=\"Notes\" viewMode=\"timeline\" modelType=\"Product\"\n [relatedModelId]=\"product.id\"></app-note-list>\n\n </div>\n <div class=\"d-flex flex-column gap-3 w-100\">\n <app-stock-receipt-product-list #stockReceiptsListPage [filters]=\"{ product_ids: product?.id }\"\n [isProductView]=\"true\" (listUpdated)=\"getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary();\n productLocationList.reload();\n \"></app-stock-receipt-product-list>\n\n <app-stock-issue-products-list #stockIssueProductListPage [isProductView]=\"true\"\n [filters]=\"{ product_ids: product?.id }\" (listUpdated)=\"\n getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary();\n productLocationList.reload();\n \"></app-stock-issue-products-list>\n\n <app-stock-transfer-list #stockTransferList *ngIf=\"product\" [productId]=\"product.id\"></app-stock-transfer-list>\n </div>\n </div>\n</div>", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.StockReceiptProductsListComponent, selector: "app-stock-receipt-product-list", inputs: ["filters", "isProductView", "selectedColumns", "exportInProgress"], outputs: ["listUpdated", "columnConfigReady"] }, { kind: "component", type: i5.StockIssueProductListComponent, selector: "app-stock-issue-products-list", inputs: ["filters", "isProductView", "selectedColumns", "exportInProgress", "issuableData"], outputs: ["listUpdated", "columnConfigReady"] }, { kind: "component", type: i6.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i7.ProductLocationListComponent, selector: "app-product-location-list", inputs: ["product"], outputs: ["updated"] }, { kind: "component", type: i8.StockTransferListComponent, selector: "app-stock-transfer-list", inputs: ["productId"] }, { kind: "component", type: i9.NoteListComponent, selector: "app-note-list", inputs: ["relatedModelId", "modelType", "readonly", "labelText", "commentsView", "viewMode"] }, { kind: "component", type: i10.ProductBasicInfoComponent, selector: "app-product-basic-info", inputs: ["product"], outputs: ["saved", "deleted"] }], preserveWhitespaces: true });
|
|
69
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ProductViewPageComponent, selector: "app-product-view-page", viewQueries: [{ propertyName: "productLocationList", first: true, predicate: ["productLocationList"], descendants: true }, { propertyName: "stockTransferList", first: true, predicate: ["stockTransferList"], descendants: true }, { propertyName: "stockReceiptsListPage", first: true, predicate: ["stockReceiptsListPage"], descendants: true }, { propertyName: "stockIssueProductListPage", first: true, predicate: ["stockIssueProductListPage"], descendants: true }], ngImport: i0, template: "<mat-progress-bar mode=\"indeterminate\" *ngIf=\"isLoading\"></mat-progress-bar>\n\n<div *ngIf=\"product\" class=\"d-flex justify-content-start align-items-start gap-3 w-100\">\n <div *ngIf=\"product\" class=\"d-flex justify-content-start align-items-start gap-3 w-100\">\n <div style=\"width: calc(25% - 1rem)\" class=\"d-flex flex-column gap-3\">\n <app-product-basic-info [product]=\"product\" #productBasicInfoComponent (deleted)=\"onProductDeleted()\"\n (saved)=\"onProductUpdated($event)\"></app-product-basic-info>\n\n <app-product-location-list [product]=\"product\"\n (updated)=\"stockTransferList.reload(); stockIssueProductListPage.reload()\"\n #productLocationList></app-product-location-list>\n\n <app-note-list labelText=\"Notes\" viewMode=\"timeline\" modelType=\"Product\"\n [relatedModelId]=\"product.id\"></app-note-list>\n\n </div>\n <div class=\"d-flex flex-column gap-3 w-100\">\n <app-stock-receipt-product-list #stockReceiptsListPage [filters]=\"{ product_ids: product?.id }\"\n [isProductView]=\"true\" (listUpdated)=\"getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary();\n productLocationList.reload();\n \"></app-stock-receipt-product-list>\n\n <app-stock-issue-products-list #stockIssueProductListPage [isProductView]=\"true\"\n [filters]=\"{ product_ids: product?.id }\" (listUpdated)=\"\n getProduct(this.id);\n productBasicInfoComponent.loadProductStocksSummary();\n productLocationList.reload();\n \"></app-stock-issue-products-list>\n\n <app-stock-transfer-list #stockTransferList *ngIf=\"product\" [productId]=\"product.id\"></app-stock-transfer-list>\n </div>\n </div>\n</div>", dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.StockReceiptProductsListComponent, selector: "app-stock-receipt-product-list", inputs: ["filters", "isProductView", "selectedColumns", "exportInProgress"], outputs: ["listUpdated", "columnConfigReady"] }, { kind: "component", type: i5.StockIssueProductListComponent, selector: "app-stock-issue-products-list", inputs: ["filters", "isProductView", "selectedColumns", "exportInProgress", "issuableData"], outputs: ["selectedColumnsChange", "listUpdated", "columnConfigReady"] }, { kind: "component", type: i6.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i7.ProductLocationListComponent, selector: "app-product-location-list", inputs: ["product"], outputs: ["updated"] }, { kind: "component", type: i8.StockTransferListComponent, selector: "app-stock-transfer-list", inputs: ["productId"] }, { kind: "component", type: i9.NoteListComponent, selector: "app-note-list", inputs: ["relatedModelId", "modelType", "readonly", "labelText", "commentsView", "viewMode"] }, { kind: "component", type: i10.ProductBasicInfoComponent, selector: "app-product-basic-info", inputs: ["product"], outputs: ["saved", "deleted"] }], preserveWhitespaces: true });
|
|
70
70
|
}
|
|
71
71
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProductViewPageComponent, decorators: [{
|
|
72
72
|
type: Component,
|